diff --git a/erlang/apps/lib/include/pdp10_elf36.hrl b/erlang/apps/lib/include/pdp10_elf36.hrl index 75a0754..e388345 100644 --- a/erlang/apps/lib/include/pdp10_elf36.hrl +++ b/erlang/apps/lib/include/pdp10_elf36.hrl @@ -478,6 +478,7 @@ -record(elf36_Shdr, { sh_name :: elf36_Word() % Section name, index in string tbl + | string() % Name (in-core only) , sh_type :: elf36_Word() % Type of section , sh_flags :: elf36_Word() % Miscellaneous section attributes , sh_addr :: elf36_Addr() % Section virtual addr at execution @@ -610,6 +611,7 @@ -record(elf36_Sym, { st_name :: elf36_Word() % Symbol name, index in string tbl + | string() % Name (in-core only) , st_value :: elf36_Addr() % Value of the symbol , st_size :: elf36_Word() % Associated symbol size , st_info :: elf36_Uchar() % Type and binding attributes diff --git a/erlang/apps/lib/src/pdp10_elf36.erl b/erlang/apps/lib/src/pdp10_elf36.erl index a7cb778..7a5df3f 100644 --- a/erlang/apps/lib/src/pdp10_elf36.erl +++ b/erlang/apps/lib/src/pdp10_elf36.erl @@ -227,13 +227,13 @@ check_Ehdr_e_shentsize(Ehdr) -> %% I/O of ShTab ================================================================ -spec read_ShTab(pdp10_stdio:file(), #elf36_Ehdr{}) - -> {ok, {[#elf36_Shdr{}], term()}} | {error, {module(), term()}}. + -> {ok, [#elf36_Shdr{}]} | {error, {module(), term()}}. read_ShTab(FP, Ehdr) -> #elf36_Ehdr{ e_shoff = ShOff , e_shnum = ShNum0 , e_shstrndx = ShStrNdx } = Ehdr, case ShOff of - 0 -> {ok, {[], []}}; + 0 -> {ok, []}; _ -> case pdp10_stdio:fseek(FP, {bof, ShOff}) of ok -> @@ -243,9 +243,7 @@ read_ShTab(FP, Ehdr) -> case read_ShTab(FP, ShNum - 1, [Shdr0]) of {ok, ShTab} -> case read_ShStrTab(FP, ShTab, ShStrNdx, Shdr0) of - {ok, ShStrTab} -> - %% TODO; now change the sh_names in ShTab to be strings - {ok, {ShTab, ShStrTab}}; + {ok, ShStrTab} -> read_ShTab_names(ShTab, ShStrTab); {error, _Reason} = Error -> Error end; {error, _Reason} = Error -> Error @@ -266,6 +264,22 @@ read_ShTab(FP, ShNum, Shdrs) -> {error, _Reason} = Error -> Error end. +read_ShTab_names(ShTab, ShStrTab) -> + read_ShTab_names(ShTab, ShStrTab, []). + +read_ShTab_names([], _ShStrTab, Acc) -> {ok, lists:reverse(Acc)}; +read_ShTab_names([Shdr | ShTab], ShStrTab, Acc) -> + case read_Shdr_name(Shdr, ShStrTab) of + {ok, NewShdr} -> read_ShTab_names(ShTab, ShStrTab, [NewShdr | Acc]); + {error, _Reason} = Error -> Error + end. + +read_Shdr_name(Shdr = #elf36_Shdr{sh_name = ShName}, ShStrTab) -> + case get_name(ShStrTab, ShName) of + {ok, Name} -> {ok, Shdr#elf36_Shdr{sh_name = Name}}; + {error, _Reason} = Error -> Error + end. + %% I/O of ShStrTab ============================================================= read_ShStrTab(FP, ShTab, ShStrNdx, Shdr0) -> @@ -300,11 +314,27 @@ read_StrTab(FP, ShTab, Index) -> false -> {error, {?MODULE, {wrong_strtab_index, Index}}} end. +%% reading a name from a StrTab ================================================ + +get_name(_StrTab, 0) -> {ok, ""}; % TODO: or some marker for "absent" +get_name(StrTab, Index) -> + try lists:nthtail(Index, StrTab) of + [C | Tail] -> get_name(C, Tail, []) + catch _C:_R -> + {error, {?MODULE, {wrong_index_in_strtab, Index}}} + end. + +get_name(0, _Tail, Acc) -> {ok, lists:reverse(Acc)}; +get_name(C1, [C2 | Tail], Acc) -> get_name(C2, Tail, [C1 | Acc]); +get_name(_C, [], _Acc) -> {error, {?MODULE, strtab_not_nul_terminated}}. + %% I/O of SymTab =============================================================== +-spec read_SymTab(pdp10_stdio:file(), [#elf36_Shdr{}]) + -> {ok, [#elf36_Sym{}]} | {error, {module(), term()}}. read_SymTab(FP, ShTab) -> case find_SymTab(ShTab) of - false -> {ok, {[], []}}; + false -> {ok, []}; {ok, Shdr} -> #elf36_Shdr{ sh_link = ShLink , sh_entsize = ShEntSize @@ -320,12 +350,12 @@ read_SymTab(FP, ShTab) -> {ok, StrTab} -> SymNum = ShSize div ?ELF36_SYM_SIZEOF, case SymNum of - 0 -> {ok, {[], StrTab}}; + 0 -> {ok, []}; _ -> case pdp10_stdio:fseek(FP, {bof, ShOffset}) of ok -> case read_SymTab(FP, SymNum, []) of - {ok, SymTab} -> {ok, {SymTab, StrTab}}; + {ok, SymTab} -> read_SymTab_names(SymTab, StrTab); {error, _Reason} = Error -> Error end; {error, _Reason} = Error -> Error @@ -347,6 +377,22 @@ find_SymTab([]) -> false; find_SymTab([#elf36_Shdr{sh_type = ?SHT_SYMTAB} = Shdr | _]) -> {ok, Shdr}; find_SymTab([_Shdr | ShTab]) -> find_SymTab(ShTab). +read_SymTab_names(SymTab, StrTab) -> + read_SymTab_names(SymTab, StrTab, []). + +read_SymTab_names([], _StrTab, Acc) -> {ok, lists:reverse(Acc)}; +read_SymTab_names([Sym | SymTab], StrTab, Acc) -> + case read_Sym_name(Sym, StrTab) of + {ok, NewSym} -> read_SymTab_names(SymTab, StrTab, [NewSym | Acc]); + {error, _Reason} = Error -> Error + end. + +read_Sym_name(Sym = #elf36_Sym{st_name = StName}, StrTab) -> + case get_name(StrTab, StName) of + {ok, Name} -> {ok, Sym#elf36_Sym{st_name = Name}}; + {error, _Reason} = Error -> Error + end. + %% I/O of #elf36_Shdr{} ======================================================== read_Shdr(FP) -> read_record(FP, elf36_Shdr_desc()). @@ -456,6 +502,10 @@ format_error(Reason) -> io_lib:format("wrong sh_size ~p in symtab section header", [ShSize]); eof -> "premature EOF"; + {wrong_index_in_strtab, Index} -> + io_lib:format("out of range index ~p in string table", [Index]); + strtab_not_nul_terminated -> + "string table not NUL-terminated"; _ -> io_lib:format("~p", [Reason]) end. diff --git a/erlang/apps/nm/src/nm.erl b/erlang/apps/nm/src/nm.erl index 6eea536..518de0f 100644 --- a/erlang/apps/nm/src/nm.erl +++ b/erlang/apps/nm/src/nm.erl @@ -165,9 +165,9 @@ nm1(Opts, PrintFile, File) -> nm1(Opts, PrintFile, File, FP) -> Ehdr = read_ehdr(File, FP), - {ShTab, _ShStrTab} = read_shtab(File, FP, Ehdr), - {SymTab, StrTab} = read_symtab(File, FP, ShTab), - print_symtab(Opts, PrintFile, File, ShTab, SymTab, StrTab). + ShTab = read_shtab(File, FP, Ehdr), + SymTab = read_symtab(File, FP, ShTab), + print_symtab(Opts, PrintFile, File, ShTab, SymTab). read_ehdr(File, FP) -> case pdp10_elf36:read_Ehdr(FP) of @@ -180,7 +180,7 @@ read_ehdr(File, FP) -> read_shtab(File, FP, Ehdr) -> case pdp10_elf36:read_ShTab(FP, Ehdr) of - {ok, {ShTab, ShStrTab}} -> {ShTab, ShStrTab}; + {ok, ShTab} -> ShTab; {error, Reason} -> escript_runtime:fatal("failed to read section header table in ~s: ~s\n", [File, error:format(Reason)]) @@ -188,22 +188,22 @@ read_shtab(File, FP, Ehdr) -> read_symtab(File, FP, ShTab) -> case pdp10_elf36:read_SymTab(FP, ShTab) of - {ok, {SymTab, StrTab}} -> {SymTab, StrTab}; + {ok, SymTab} -> SymTab; {error, Reason} -> escript_runtime:fatal("failed to read symbol table table in ~s: ~s\n", [File, error:format(Reason)]) end. -print_symtab(Opts, PrintFile, File, ShTab, SymTab, StrTab) -> +print_symtab(Opts, PrintFile, File, ShTab, SymTab) -> case PrintFile of true -> io:format("\n~s:\n", [File]); false -> ok end, [sym_print(Opts, File, ShTab, Sym) - || Sym <- syms_sort(Opts, syms_assemble(ShTab, SymTab, StrTab))], + || Sym <- syms_sort(Opts, syms_assemble(ShTab, SymTab))], ok. -sym_print(Opts, File, ShTab, {Sym, Value, Name}) -> +sym_print(Opts, File, ShTab, {Sym = #elf36_Sym{st_name = Name}, Value}) -> case sym_type_letter(ShTab, Sym) of 0 -> ok; % ignored Type -> @@ -309,30 +309,16 @@ syms_cmpfn(Opts) -> end end. -sym_cmp_value({_, Val1, _}, {_, Val2, _}) -> Val1 =< Val2. +sym_cmp_value({_, Val1}, {_, Val2}) -> Val1 =< Val2. -sym_cmp_name({_, _, Name1}, {_, _, Name2}) -> Name1 =< Name2. +sym_cmp_name({Sym1, _}, {Sym2, _}) -> + Sym1#elf36_Sym.st_name =< Sym2#elf36_Sym.st_name. -syms_assemble(ShTab, SymTab, StrTab) -> +syms_assemble(ShTab, SymTab) -> lists:map(fun(Sym) -> - {Sym, sym_value(ShTab, Sym), sym_name(StrTab, Sym)} + {Sym, sym_value(ShTab, Sym)} end, SymTab). -sym_name(StrTab, #elf36_Sym{st_name = Index}) -> - {ok, Name} = get_name(StrTab, Index), - Name. - -get_name(StrTab, Index) -> - try lists:nthtail(Index, StrTab) of - [_|_] = Tail -> get_name2(Tail, []) - catch _C:_R -> - {error, {bad_strtab_index, Index}} - end. - -get_name2([], _Acc) -> {error, strtab_not_nul_terminated}; -get_name2([0 | _Tail], Acc) -> {ok, lists:reverse(Acc)}; -get_name2([Ch | Tail], Acc) -> get_name2(Tail, [Ch | Acc]). - sym_value(ShTab, #elf36_Sym{st_shndx = ShNdx, st_value = Value}) -> ShNum = length(ShTab), Base =