llvm.org GIT mirror llvm / dfa1896
[Object] Add {begin,end}_dynamic_symbols stubs and implementation for ELF. Add -D option to llvm-nm to dump dynamic symbols. Patch by David Meyer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151600 91177308-0d34-0410-b5e6-96231b3b80d8 Michael J. Spencer 8 years ago
11 changed file(s) with 168 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
151151 COFFObjectFile(MemoryBuffer *Object, error_code &ec);
152152 virtual symbol_iterator begin_symbols() const;
153153 virtual symbol_iterator end_symbols() const;
154 virtual symbol_iterator begin_dynamic_symbols() const;
155 virtual symbol_iterator end_dynamic_symbols() const;
154156 virtual section_iterator begin_sections() const;
155157 virtual section_iterator end_sections() const;
156158
294294 const Elf_Shdr *SectionHeaderTable;
295295 const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
296296 const Elf_Shdr *dot_strtab_sec; // Symbol header string table.
297 const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table.
297298 Sections_t SymbolTableSections;
298299 IndexMap_t SymbolTableSectionsIndexMap;
299300 DenseMap ExtendedSymbolTable;
318319 const Elf_Rela *getRela(DataRefImpl Rela) const;
319320 const char *getString(uint32_t section, uint32_t offset) const;
320321 const char *getString(const Elf_Shdr *section, uint32_t offset) const;
321 error_code getSymbolName(const Elf_Sym *Symb, StringRef &Res) const;
322 error_code getSymbolName(const Elf_Shdr *section,
323 const Elf_Sym *Symb,
324 StringRef &Res) const;
325 void VerifyStrTab(const Elf_Shdr *sh) const;
322326
323327 protected:
324328 const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private?
374378 ELFObjectFile(MemoryBuffer *Object, error_code &ec);
375379 virtual symbol_iterator begin_symbols() const;
376380 virtual symbol_iterator end_symbols() const;
381 virtual symbol_iterator begin_dynamic_symbols() const;
382 virtual symbol_iterator end_dynamic_symbols() const;
377383 virtual section_iterator begin_sections() const;
378384 virtual section_iterator end_sections() const;
379385
424430 // Check to see if we are at the end of this symbol table.
425431 if (Symb.d.a >= SymbolTableSection->getEntityCount()) {
426432 // We are at the end. If there are other symbol tables, jump to them.
427 ++Symb.d.b;
428 Symb.d.a = 1; // The 0th symbol in ELF is fake.
433 // If the symbol table is .dynsym, we are iterating dynamic symbols,
434 // and there is only one table of these.
435 if (Symb.d.b != 0) {
436 ++Symb.d.b;
437 Symb.d.a = 1; // The 0th symbol in ELF is fake.
438 }
429439 // Otherwise return the terminator.
430 if (Symb.d.b >= SymbolTableSections.size()) {
440 if (Symb.d.b == 0 || Symb.d.b >= SymbolTableSections.size()) {
431441 Symb.d.a = std::numeric_limits::max();
432442 Symb.d.b = std::numeric_limits::max();
433443 }
443453 StringRef &Result) const {
444454 validateSymbol(Symb);
445455 const Elf_Sym *symb = getSymbol(Symb);
446 return getSymbolName(symb, Result);
456 return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result);
447457 }
448458
449459 template
11271137 }
11281138 const Elf_Sym *symb = getEntry(sec->sh_link, symbol_index);
11291139 StringRef symname;
1130 if (error_code ec = getSymbolName(symb, symname))
1140 if (error_code ec = getSymbolName(getSection(sec->sh_link), symb, symname))
11311141 return ec;
11321142 switch (Header->e_machine) {
11331143 case ELF::EM_X86_64:
11551165 return object_error::success;
11561166 }
11571167
1168 // Verify that the last byte in the string table in a null.
1169 template
1170 void ELFObjectFile
1171 ::VerifyStrTab(const Elf_Shdr *sh) const {
1172 const char *strtab = (const char*)base() + sh->sh_offset;
1173 if (strtab[sh->sh_size - 1] != 0)
1174 // FIXME: Proper error handling.
1175 report_fatal_error("String table must end with a null terminator!");
1176 }
1177
11581178 template
11591179 ELFObjectFile::ELFObjectFile(MemoryBuffer *Object
11601180 , error_code &ec)
11621182 , isDyldELFObject(false)
11631183 , SectionHeaderTable(0)
11641184 , dot_shstrtab_sec(0)
1165 , dot_strtab_sec(0) {
1185 , dot_strtab_sec(0)
1186 , dot_dynstr_sec(0) {
11661187
11671188 const uint64_t FileSize = Data->getBufferSize();
11681189
11931214 // To find the symbol tables we walk the section table to find SHT_SYMTAB.
11941215 const Elf_Shdr* SymbolTableSectionHeaderIndex = 0;
11951216 const Elf_Shdr* sh = SectionHeaderTable;
1217
1218 // Reserve SymbolTableSections[0] for .dynsym
1219 SymbolTableSections.push_back(NULL);
1220
11961221 for (uint64_t i = 0, e = getNumSections(); i != e; ++i) {
11971222 if (sh->sh_type == ELF::SHT_SYMTAB_SHNDX) {
11981223 if (SymbolTableSectionHeaderIndex)
12041229 SymbolTableSectionsIndexMap[i] = SymbolTableSections.size();
12051230 SymbolTableSections.push_back(sh);
12061231 }
1232 if (sh->sh_type == ELF::SHT_DYNSYM) {
1233 if (SymbolTableSections[0] != NULL)
1234 // FIXME: Proper error handling.
1235 report_fatal_error("More than one .dynsym!");
1236 SymbolTableSectionsIndexMap[i] = 0;
1237 SymbolTableSections[0] = sh;
1238 }
12071239 if (sh->sh_type == ELF::SHT_REL || sh->sh_type == ELF::SHT_RELA) {
12081240 SectionRelocMap[getSection(sh->sh_info)].push_back(i);
12091241 }
12201252 dot_shstrtab_sec = getSection(getStringTableIndex());
12211253 if (dot_shstrtab_sec) {
12221254 // Verify that the last byte in the string table in a null.
1223 if (((const char*)base() + dot_shstrtab_sec->sh_offset)
1224 [dot_shstrtab_sec->sh_size - 1] != 0)
1225 // FIXME: Proper error handling.
1226 report_fatal_error("String table must end with a null terminator!");
1255 VerifyStrTab(dot_shstrtab_sec);
12271256 }
12281257
12291258 // Merge this into the above loop.
12381267 // FIXME: Proper error handling.
12391268 report_fatal_error("Already found section named .strtab!");
12401269 dot_strtab_sec = sh;
1241 const char *dot_strtab = (const char*)base() + sh->sh_offset;
1242 if (dot_strtab[sh->sh_size - 1] != 0)
1243 // FIXME: Proper error handling.
1244 report_fatal_error("String table must end with a null terminator!");
1270 VerifyStrTab(dot_strtab_sec);
1271 } else if (SectionName == ".dynstr") {
1272 if (dot_dynstr_sec != 0)
1273 // FIXME: Proper error handling.
1274 report_fatal_error("Already found section named .dynstr!");
1275 dot_dynstr_sec = sh;
1276 VerifyStrTab(dot_dynstr_sec);
12451277 }
12461278 }
12471279 }
12671299 ::begin_symbols() const {
12681300 DataRefImpl SymbolData;
12691301 memset(&SymbolData, 0, sizeof(SymbolData));
1270 if (SymbolTableSections.size() == 0) {
1302 if (SymbolTableSections.size() <= 1) {
12711303 SymbolData.d.a = std::numeric_limits::max();
12721304 SymbolData.d.b = std::numeric_limits::max();
12731305 } else {
12741306 SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
1275 SymbolData.d.b = 0;
1307 SymbolData.d.b = 1; // The 0th table is .dynsym
12761308 }
12771309 return symbol_iterator(SymbolRef(SymbolData, this));
12781310 }
12801312 template
12811313 symbol_iterator ELFObjectFile
12821314 ::end_symbols() const {
1315 DataRefImpl SymbolData;
1316 memset(&SymbolData, 0, sizeof(SymbolData));
1317 SymbolData.d.a = std::numeric_limits::max();
1318 SymbolData.d.b = std::numeric_limits::max();
1319 return symbol_iterator(SymbolRef(SymbolData, this));
1320 }
1321
1322 template
1323 symbol_iterator ELFObjectFile
1324 ::begin_dynamic_symbols() const {
1325 DataRefImpl SymbolData;
1326 memset(&SymbolData, 0, sizeof(SymbolData));
1327 if (SymbolTableSections[0] == NULL) {
1328 SymbolData.d.a = std::numeric_limits::max();
1329 SymbolData.d.b = std::numeric_limits::max();
1330 } else {
1331 SymbolData.d.a = 1; // The 0th symbol in ELF is fake.
1332 SymbolData.d.b = 0; // The 0th table is .dynsym
1333 }
1334 return symbol_iterator(SymbolRef(SymbolData, this));
1335 }
1336
1337 template
1338 symbol_iterator ELFObjectFile
1339 ::end_dynamic_symbols() const {
12831340 DataRefImpl SymbolData;
12841341 memset(&SymbolData, 0, sizeof(SymbolData));
12851342 SymbolData.d.a = std::numeric_limits::max();
14601517
14611518 template
14621519 error_code ELFObjectFile
1463 ::getSymbolName(const Elf_Sym *symb,
1520 ::getSymbolName(const Elf_Shdr *section,
1521 const Elf_Sym *symb,
14641522 StringRef &Result) const {
14651523 if (symb->st_name == 0) {
14661524 const Elf_Shdr *section = getSection(symb);
14711529 return object_error::success;
14721530 }
14731531
1474 // Use the default symbol table name section.
1475 Result = getString(dot_strtab_sec, symb->st_name);
1532 if (section == SymbolTableSections[0]) {
1533 // Symbol is in .dynsym, use .dynstr string table
1534 Result = getString(dot_dynstr_sec, symb->st_name);
1535 } else {
1536 // Use the default symbol table name section.
1537 Result = getString(dot_strtab_sec, symb->st_name);
1538 }
14761539 return object_error::success;
14771540 }
14781541
3131
3232 virtual symbol_iterator begin_symbols() const;
3333 virtual symbol_iterator end_symbols() const;
34 virtual symbol_iterator begin_dynamic_symbols() const;
35 virtual symbol_iterator end_dynamic_symbols() const;
3436 virtual section_iterator begin_sections() const;
3537 virtual section_iterator end_sections() const;
3638
312312 virtual symbol_iterator begin_symbols() const = 0;
313313 virtual symbol_iterator end_symbols() const = 0;
314314
315 virtual symbol_iterator begin_dynamic_symbols() const = 0;
316 virtual symbol_iterator end_dynamic_symbols() const = 0;
317
315318 virtual section_iterator begin_sections() const = 0;
316319 virtual section_iterator end_sections() const = 0;
317320
505505 std::memset(&ret, 0, sizeof(DataRefImpl));
506506 ret.p = reinterpret_cast(StringTable);
507507 return symbol_iterator(SymbolRef(ret, this));
508 }
509
510 symbol_iterator COFFObjectFile::begin_dynamic_symbols() const {
511 // TODO: implement
512 report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile");
513 }
514
515 symbol_iterator COFFObjectFile::end_dynamic_symbols() const {
516 // TODO: implement
517 report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile");
508518 }
509519
510520 section_iterator COFFObjectFile::begin_sections() const {
387387 return symbol_iterator(SymbolRef(DRI, this));
388388 }
389389
390 symbol_iterator MachOObjectFile::begin_dynamic_symbols() const {
391 // TODO: implement
392 report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
393 }
394
395 symbol_iterator MachOObjectFile::end_dynamic_symbols() const {
396 // TODO: implement
397 report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
398 }
390399
391400 /*===-- Sections ----------------------------------------------------------===*/
392401
0 ; How to make the shared objects from this file:
1 ;
2 ; X86-32 ELF:
3 ; llc -mtriple=i386-linux-gnu shared.ll -filetype=obj -o tmp32.o -relocation-model=pic
4 ; ld -melf_i386 -shared tmp32.o -o shared-object-test.elf-i386 --unresolved-symbols=ignore-all
5 ;
6 ; X86-64 ELF:
7 ; llc -mtriple=x86_64-linux-gnu shared.ll -filetype=obj -o tmp64.o -relocation-model=pic
8 ; ld -melf_x86_64 -shared tmp64.o -o shared-object-test.elf-x86-64 --unresolved-symbols=ignore-all
9
10 @defined_sym = global i32 1, align 4
11
12 @tls_sym = thread_local global i32 2, align 4
13
14 @undef_sym = external global i32
15
16 @undef_tls_sym = external thread_local global i32
17
18 @common_sym = common global i32 0, align 4
19
20 define i32 @global_func() nounwind uwtable {
21 entry:
22 ret i32 0
23 }
24
25 declare i32 @undef_func(...)
26
27 define internal i32 @local_func() nounwind uwtable {
28 entry:
29 ret i32 0
30 }
0 RUN: llvm-nm -D %p/Inputs/shared-object-test.elf-i386 \
1 RUN: | FileCheck %s -check-prefix ELF
2 RUN: llvm-nm -D %p/Inputs/shared-object-test.elf-x86-64 \
3 RUN: | FileCheck %s -check-prefix ELF
4
5 ; Note: tls_sym should be 'D' (not '?'), but TLS is not
6 ; yet recognized by ObjectFile.
7
8 ELF: {{[0-9a-f]+}} A __bss_start
9 ELF: {{[0-9a-f]+}} A _edata
10 ELF: {{[0-9a-f]+}} A _end
11 ELF: {{[0-9a-f]+}} B common_sym
12 ELF: {{[0-9a-f]+}} D defined_sym
13 ELF: {{[0-9a-f]+}} T global_func
14 ELF: ? tls_sym
6060 cl::alias UndefinedOnly2("u", cl::desc("Alias for --undefined-only"),
6161 cl::aliasopt(UndefinedOnly));
6262
63 cl::opt DynamicSyms("dynamic",
64 cl::desc("Display the dynamic symbols instead "
65 "of normal symbols."));
66 cl::alias DynamicSyms2("D", cl::desc("Alias for --dynamic"),
67 cl::aliasopt(DynamicSyms));
68
6369 cl::opt DefinedOnly("defined-only",
6470 cl::desc("Show only defined symbols"));
6571
276282
277283 static void DumpSymbolNamesFromObject(ObjectFile *obj) {
278284 error_code ec;
279 for (symbol_iterator i = obj->begin_symbols(),
280 e = obj->end_symbols();
281 i != e; i.increment(ec)) {
285 symbol_iterator ibegin = obj->begin_symbols();
286 symbol_iterator iend = obj->end_symbols();
287 if (DynamicSyms) {
288 ibegin = obj->begin_dynamic_symbols();
289 iend = obj->end_dynamic_symbols();
290 }
291 for (symbol_iterator i = ibegin; i != iend; i.increment(ec)) {
282292 if (error(ec)) break;
283293 bool internal;
284294 if (error(i->isInternal(internal))) break;