Skip to content

Commit 2f59f06

Browse files
committed
libiberty: Fix up debug.temp.o creation if *.o has 64K+ sections [PR104617]
On #define A(n) int foo1##n(void) { return 1##n; } #define B(n) A(n##0) A(n##1) A(n##2) A(n##3) A(n##4) A(n#riscvarchive#5) A(n#riscvarchive#6) A(n#riscvarchive#7) A(n#riscvarchive#8) A(n#riscvarchive#9) #define C(n) B(n##0) B(n##1) B(n##2) B(n##3) B(n##4) B(n#riscvarchive#5) B(n#riscvarchive#6) B(n#riscvarchive#7) B(n#riscvarchive#8) B(n#riscvarchive#9) #define D(n) C(n##0) C(n##1) C(n##2) C(n##3) C(n##4) C(n#riscvarchive#5) C(n#riscvarchive#6) C(n#riscvarchive#7) C(n#riscvarchive#8) C(n#riscvarchive#9) #define E(n) D(n##0) D(n##1) D(n##2) D(n##3) D(n##4) D(n#riscvarchive#5) D(n#riscvarchive#6) D(n#riscvarchive#7) D(n#riscvarchive#8) D(n#riscvarchive#9) E(0) E(1) E(2) D(30) D(31) C(320) C(321) C(322) C(323) C(324) C(325) B(3260) B(3261) B(3262) B(3263) A(32640) A(32641) A(32642) testcase with ./xgcc -B ./ -c -g -fpic -ffat-lto-objects -flto -O0 -o foo1.o foo1.c -ffunction-sections ./xgcc -B ./ -shared -g -fpic -flto -O0 -o foo1.so foo1.o /tmp/ccTW8mBm.debug.temp.o: file not recognized: file format not recognized (testcase too slow to be included into testsuite). The problem is clearly reported by readelf: readelf: foo1.o.debug.temp.o: Warning: Section 2 has an out of range sh_link value of 65321 readelf: foo1.o.debug.temp.o: Warning: Section 5 has an out of range sh_link value of 65321 readelf: foo1.o.debug.temp.o: Warning: Section 10 has an out of range sh_link value of 65323 readelf: foo1.o.debug.temp.o: Warning: [ 2]: Link field (65321) should index a symtab section. readelf: foo1.o.debug.temp.o: Warning: [ 5]: Link field (65321) should index a symtab section. readelf: foo1.o.debug.temp.o: Warning: [10]: Link field (65323) should index a string section. because simple_object_elf_copy_lto_debug_sections doesn't adjust sh_info and sh_link fields in ElfNN_Shdr if they are in between SHN_{LO,HI}RESERVE inclusive. Not adjusting those is incorrect though, SHN_{LO,HI}RESERVE range is only relevant to the 16-bit fields, mainly st_shndx in ElfNN_Sym where if one needs >= SHN_LORESERVE section number, SHN_XINDEX should be used instead and .symtab_shndx section should contain the real section index, and in ElfNN_Ehdr e_shnum and e_shstrndx fields, where if >= SHN_LORESERVE value is needed it should put those into Shdr[0].sh_{size,link}. But, sh_{link,info} are 32-bit fields which can contain any section index. Note, as simple-object-elf.c mentions, binutils from 2.12 to 2.18 (so before 2011) used to mishandle the > 63.75K sections case and assumed there is a hole in between the sections, but what simple_object_elf_copy_lto_debug_sections does wouldn't help in that case for the debug temp object creation, we'd need to detect the case also in that routine and take it into account in the remapping etc. I think it is not worth it given that it is over 10 years, if somebody needs 63.75K or more sections, better use more recent binutils. 2022-02-22 Jakub Jelinek <[email protected]> PR lto/104617 * simple-object-elf.c (simple_object_elf_match): Fix up URL in comment. (simple_object_elf_copy_lto_debug_sections): Remap sh_info and sh_link even if they are in the SHN_LORESERVE .. SHN_HIRESERVE range (inclusive).
1 parent d44dc13 commit 2f59f06

File tree

1 file changed

+3
-7
lines changed

1 file changed

+3
-7
lines changed

libiberty/simple-object-elf.c

+3-7
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ simple_object_elf_match (unsigned char header[SIMPLE_OBJECT_MATCH_HEADER_LEN],
528528
not handle objects with more than SHN_LORESERVE sections
529529
correctly. All large section indexes were offset by
530530
0x100. There is more information at
531-
http://sourceware.org/bugzilla/show_bug.cgi?id-5900 .
531+
https://sourceware.org/PR5900 .
532532
Fortunately these object files are easy to detect, as the
533533
GNU binutils always put the section header string table
534534
near the end of the list of sections. Thus if the
@@ -1559,17 +1559,13 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
15591559
{
15601560
sh_info = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
15611561
shdr, sh_info, Elf_Word);
1562-
if (sh_info < SHN_LORESERVE
1563-
|| sh_info > SHN_HIRESERVE)
1564-
sh_info = sh_map[sh_info];
1562+
sh_info = sh_map[sh_info];
15651563
ELF_SET_FIELD (type_functions, ei_class, Shdr,
15661564
shdr, sh_info, Elf_Word, sh_info);
15671565
}
15681566
sh_link = ELF_FETCH_FIELD (type_functions, ei_class, Shdr,
15691567
shdr, sh_link, Elf_Word);
1570-
if (sh_link < SHN_LORESERVE
1571-
|| sh_link > SHN_HIRESERVE)
1572-
sh_link = sh_map[sh_link];
1568+
sh_link = sh_map[sh_link];
15731569
ELF_SET_FIELD (type_functions, ei_class, Shdr,
15741570
shdr, sh_link, Elf_Word, sh_link);
15751571
}

0 commit comments

Comments
 (0)