blob: 0dc2b6bd7c187e6d8970b2d5b7cbfa200c6206fb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 QNX Software Systems and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.utils.spawner.ProcessFactory;
/**
*/
public class NM {
public class AddressNamePair {
public String name;
public long address;
public AddressNamePair(String n, long a) {
name = n;
address = a;
}
@Override
public String toString() {
return (name + "@" + Long.toHexString(address)); //$NON-NLS-1$
}
}
private static Pattern undef_pattern = null;
private static Pattern normal_pattern = null;
/**
* @since 5.1
*/
protected List<String> undef_symbols;
/**
* @since 5.1
*/
protected List<AddressNamePair> text_symbols;
/**
* @since 5.1
*/
protected List<AddressNamePair> bss_symbols;
/**
* @since 5.1
*/
protected List<AddressNamePair> data_symbols;
private void parseOutput(InputStream stream) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
// See matcher.java for regular expression string data definitions.
if (undef_pattern == null) {
undef_pattern = Pattern.compile("^\\s+U\\s+(\\S+)"); //$NON-NLS-1$
}
if (normal_pattern == null) {
normal_pattern = Pattern.compile("^(\\S+)\\s+([AaTtBbDd])\\s+(\\S+)"); //$NON-NLS-1$
}
while ((line = reader.readLine()) != null) {
Matcher undef_matcher = undef_pattern.matcher(line);
Matcher normal_matcher = normal_pattern.matcher(line);
try {
if (undef_matcher.matches()) {
undef_symbols.add(undef_matcher.group(1));
} else if (normal_matcher.matches()) {
char type = normal_matcher.group(2).charAt(0);
String name = normal_matcher.group(3);
long address = Long.parseLong(normal_matcher.group(1), 16);
AddressNamePair val = new AddressNamePair(name, address);
switch (type) {
case 'T':
case 't':
text_symbols.add(val);
break;
case 'B':
case 'b':
bss_symbols.add(val);
break;
case 'D':
case 'd':
data_symbols.add(val);
break;
}
}
} catch (NumberFormatException e) {
// ignore.
} catch (IndexOutOfBoundsException e) {
// ignore
}
}
}
public NM(String file, boolean dynamic_only) throws IOException {
this("nm", file, dynamic_only); //$NON-NLS-1$
}
public NM(String command, String file, boolean dynamic_only) throws IOException {
this(command, (dynamic_only) ? new String[] { "-C", "-D" } : null, file); //$NON-NLS-1$ //$NON-NLS-2$
}
public NM(String command, String param, String file) throws IOException {
String[] params;
if (param == null || param.length() == 0) {
params = new String[0];
} else {
// FIXME: This is wrong we have to check for quoted strings.
params = param.split("\\s"); //$NON-NLS-1$
}
init(command, params, file);
}
public NM(String command, String[] params, String file) throws IOException {
init(command, params, file);
}
protected void init(String command, String[] params, String file) throws IOException {
String[] args = null;
if (params == null || params.length == 0) {
args = new String[] { command, "-C", file }; //$NON-NLS-1$
} else {
args = new String[params.length + 2];
args[0] = command;
System.arraycopy(params, 0, args, 1, params.length);
args[params.length + 1] = file;
}
undef_symbols = new ArrayList<>();
text_symbols = new ArrayList<>();
data_symbols = new ArrayList<>();
bss_symbols = new ArrayList<>();
Process process = ProcessFactory.getFactory().exec(args);
parseOutput(process.getInputStream());
process.destroy();
}
public String[] getUndefSymbols() {
return undef_symbols.toArray(new String[0]);
}
public AddressNamePair[] getTextSymbols() {
return text_symbols.toArray(new AddressNamePair[0]);
}
public AddressNamePair[] getDataSymbols() {
return data_symbols.toArray(new AddressNamePair[0]);
}
public AddressNamePair[] getBSSSymbols() {
return bss_symbols.toArray(new AddressNamePair[0]);
}
}