diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/amd/common/ac_rtld.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/src/amd/common/ac_rtld.c b/src/amd/common/ac_rtld.c index 57d6b0151b4..ebf64d91658 100644 --- a/src/amd/common/ac_rtld.c +++ b/src/amd/common/ac_rtld.c @@ -39,7 +39,11 @@ #define MY_EM_AMDGPU 224 #ifndef STT_AMDGPU_LDS -#define STT_AMDGPU_LDS 13 +#define STT_AMDGPU_LDS 13 // this is deprecated -- remove +#endif + +#ifndef SHN_AMDGPU_LDS +#define SHN_AMDGPU_LDS 0xff00 #endif #ifndef R_AMDGPU_NONE @@ -176,13 +180,20 @@ static bool read_private_lds_symbols(struct ac_rtld_binary *binary, Elf_Scn *section, uint32_t *lds_end_align) { -#define report_elf_if(cond) \ +#define report_if(cond) \ do { \ if ((cond)) { \ report_errorf(#cond); \ return false; \ } \ } while (false) +#define report_elf_if(cond) \ + do { \ + if ((cond)) { \ + report_elf_errorf(#cond); \ + return false; \ + } \ + } while (false) struct ac_rtld_part *part = &binary->parts[part_idx]; Elf64_Shdr *shdr = elf64_getshdr(section); @@ -194,15 +205,21 @@ static bool read_private_lds_symbols(struct ac_rtld_binary *binary, size_t num_symbols = symbols_data->d_size / sizeof(Elf64_Sym); for (size_t j = 0; j < num_symbols; ++j, ++symbol) { - if (ELF64_ST_TYPE(symbol->st_info) != STT_AMDGPU_LDS) + struct ac_rtld_symbol s = {}; + + if (ELF64_ST_TYPE(symbol->st_info) == STT_AMDGPU_LDS) { + /* old-style LDS symbols from initial prototype -- remove eventually */ + s.align = MIN2(1u << (symbol->st_other >> 3), 1u << 16); + } else if (symbol->st_shndx == SHN_AMDGPU_LDS) { + s.align = MIN2(symbol->st_value, 1u << 16); + report_if(!util_is_power_of_two_nonzero(s.align)); + } else continue; - report_elf_if(symbol->st_size > 1u << 29); + report_if(symbol->st_size > 1u << 29); - struct ac_rtld_symbol s = {}; s.name = elf_strptr(part->elf, strtabidx, symbol->st_name); s.size = symbol->st_size; - s.align = MIN2(1u << (symbol->st_other >> 3), 1u << 16); s.part_idx = part_idx; if (!strcmp(s.name, "__lds_end")) { @@ -224,6 +241,7 @@ static bool read_private_lds_symbols(struct ac_rtld_binary *binary, return true; +#undef report_if #undef report_elf_if } @@ -522,7 +540,9 @@ static bool resolve_symbol(const struct ac_rtld_upload_info *u, unsigned part_idx, const Elf64_Sym *sym, const char *name, uint64_t *value) { - if (sym->st_shndx == SHN_UNDEF) { + /* TODO: properly disentangle the undef and the LDS cases once + * STT_AMDGPU_LDS is retired. */ + if (sym->st_shndx == SHN_UNDEF || sym->st_shndx == SHN_AMDGPU_LDS) { const struct ac_rtld_symbol *lds_sym = find_symbol(&u->binary->lds_symbols, name, part_idx); |