&& filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
}
+/* Return true if NDX is a special defined section index. */
+
+static bool
+special_defined_section_index (Filedata *filedata, size_t ndx)
+{
+ if (ndx == SHN_ABS || ndx == SHN_COMMON)
+ return true;
+
+ if (filedata != NULL)
+ switch (filedata->file_header.e_machine)
+ {
+ case EM_MIPS:
+ if (ndx == SHN_MIPS_SCOMMON)
+ return true;
+ break;
+
+ case EM_TI_C6000:
+ if (ndx == SHN_TIC6X_SCOMMON)
+ return true;
+ break;
+
+ case EM_X86_64:
+ case EM_L1OM:
+ case EM_K1OM:
+ if (ndx == SHN_X86_64_LCOMMON)
+ return true;
+ break;
+
+ case EM_IA_64:
+ if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
+ && ndx == SHN_IA_64_ANSI_COMMON)
+ return true;
+
+ if (is_ia64_vms (filedata) && ndx == SHN_IA_64_VMS_SYMVEC)
+ return true;
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
static const char *
printable_section_name_from_index (Filedata * filedata,
size_t ndx,
internal->sh_info = BYTE_GET (shdrs[i].sh_info);
internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
- if (!probe && internal->sh_link > num)
+ if (!probe
+ && internal->sh_link >= num
+ && !special_defined_section_index (filedata,
+ internal->sh_link))
warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
internal->sh_info = BYTE_GET (shdrs[i].sh_info);
internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
- if (!probe && internal->sh_link > num)
+ if (!probe
+ && internal->sh_link >= num
+ && !special_defined_section_index (filedata,
+ internal->sh_link))
warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
printf (do_wide ? " %-15s " : " %-15.15s ",
get_section_type_name (filedata, section->sh_type));
+ bool special_defined_section
+ = special_defined_section_index (filedata, section->sh_link);
+
if (is_32bit_elf)
{
const char * link_too_big = NULL;
else
printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
- if (section->sh_link >= filedata->file_header.e_shnum)
+ if (!special_defined_section
+ && section->sh_link >= filedata->file_header.e_shnum)
{
link_too_big = "";
/* The sh_link value is out of range. Normally this indicates
}
}
+ if (special_defined_section)
+ printf ("%2s ",
+ printable_section_name_from_index (filedata,
+ section->sh_link,
+ NULL));
+
if (do_section_details)
{
- if (link_too_big != NULL && * link_too_big)
- printf ("<%s> ", link_too_big);
- else
- printf ("%2u ", section->sh_link);
- printf ("%3u %2lu\n", section->sh_info,
- (unsigned long) section->sh_addralign);
+ if (!special_defined_section)
+ {
+ if (link_too_big != NULL && * link_too_big)
+ printf ("<%s> ", link_too_big);
+ else
+ printf ("%2u ", section->sh_link);
+ }
}
- else
- printf ("%2u %3u %2lu\n",
- section->sh_link,
- section->sh_info,
- (unsigned long) section->sh_addralign);
+ else if (!special_defined_section)
+ printf ("%2u ", section->sh_link);
+
+ printf ("%3u %2lu\n", section->sh_info,
+ (unsigned long) section->sh_addralign);
if (link_too_big && ! * link_too_big)
warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
if (do_section_details)
fputs (" ", stdout);
else
- printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
-
- printf ("%2u %3u ", section->sh_link, section->sh_info);
+ printf (" %3s ", get_elf_section_flags (filedata,
+ section->sh_flags));
+
+ if (special_defined_section)
+ printf ("%2s ",
+ printable_section_name_from_index (filedata,
+ section->sh_link,
+ NULL));
+ else
+ printf ("%2u ", section->sh_link);
+ printf ("%3u ", section->sh_info);
if ((unsigned long) section->sh_addralign == section->sh_addralign)
printf ("%2lu\n", (unsigned long) section->sh_addralign);
printf (" ");
print_vma (section->sh_offset, LONG_HEX);
}
- printf (" %u\n ", section->sh_link);
+ if (special_defined_section)
+ printf (" %s\n ",
+ printable_section_name_from_index (filedata,
+ section->sh_link,
+ NULL));
+ else
+ printf (" %u\n ", section->sh_link);
print_vma (section->sh_size, LONG_HEX);
putchar (' ');
print_vma (section->sh_entsize, LONG_HEX);
printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
- printf (" %2u %3u %lu\n",
- section->sh_link,
+ if (special_defined_section)
+ printf (" %2s",
+ printable_section_name_from_index (filedata,
+ section->sh_link,
+ NULL));
+ else
+ printf (" %2u",
+ section->sh_link);
+ printf (" %3u %lu\n",
section->sh_info,
(unsigned long) section->sh_addralign);
}
run_dump_test "section28"
run_dump_test "section29"
run_dump_test "section30" $dump_opts
+ run_dump_test "sh-link-abs-1"
+ run_dump_test "sh-link-abs-2"
+ run_dump_test "sh-link-common-1"
+ run_dump_test "sh-link-common-2"
+ if [is_elf64 tmpdir/section30.o] {
+ run_dump_test "sh-link-abs-3-64"
+ run_dump_test "sh-link-abs-4-64"
+ run_dump_test "sh-link-common-3-64"
+ run_dump_test "sh-link-common-4-64"
+ run_dump_test "sh-link-large-common-1"
+ run_dump_test "sh-link-large-common-2"
+ run_dump_test "sh-link-large-common-3"
+ run_dump_test "sh-link-large-common-4"
+ } else {
+ run_dump_test "sh-link-abs-3-32"
+ run_dump_test "sh-link-abs-4-32"
+ run_dump_test "sh-link-common-3-32"
+ run_dump_test "sh-link-common-4-32"
+ }
run_dump_test "sh-link-zero"
run_dump_test "string"
run_dump_test "size"