123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- { This file is part of wasmbin - a collection of WebAssembly binary utils.
- Copyright (C) 2019, 2020 Dmitry Boyarintsev <[email protected]>
- Copyright (C) 2020 by the Free Pascal development team
- This source is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 2 of the License, or (at your option)
- any later version.
- This code is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- details.
- A copy of the GNU General Public License is available on the World Wide Web
- at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
- to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
- Boston, MA 02110-1335, USA.
- }
- unit wasmlinkchange;
- {$mode objfpc}{$H+}
- interface
- uses Classes, SysUtils, wasmlink, wasmbin, lebutils;
- type
- TSymbolType = (
- st_Nochange,
- st_Local, // 'L'
- st_Weak, // 'W'
- st_VisHidden, // 'H' visibility-local
- st_VisDefault // 'D' visibility default (not-hidden)
- );
- TSymbolTypes = set of TSymbolType;
- TSymbolConfigure = class(TObject)
- symname : string;
- needtype : TSymbolType;
- end;
- procedure ReadSymbolsConf(const fn: string; dst: TStrings);
- procedure ReadSymbolsConf(src: TStream; dst: TStrings);
- procedure ProcessLinkingSection(st: TStream; syms: TStrings);
- implementation
- procedure ReadSymbolsConf(const fn: string; dst: TStrings);
- var
- fs: TFileStream;
- begin
- fs:=TFileStream.Create(fn, fmOpenRead or fmShareDenyNone);
- try
- ReadSymbolsConf(fs, dst);
- finally
- fs.Free;
- end;
- end;
- function StrToSymType(const s: string): TSymbolType;
- begin
- if length(s)=0 then
- Result:=st_Nochange
- else
- case upCase(s[1]) of
- 'L': Result:=st_Local;
- 'H': Result:=st_VisHidden;
- 'W': Result:=st_Weak;
- 'D': Result:=st_VisDefault;
- else
- Result:=st_Nochange;
- end;
- end;
- function StrToSymTypes(const s: string): TSymbolTypes;
- var
- i: integer;
- tt : TSymbolType;
- begin
- Result := [];
- for i:=1 to length(s) do begin
- tt := StrToSymType(s[i]);
- if tt <> st_Nochange then
- Include(Result, tt);
- end;
- end;
- procedure ReadSymbolsConf(src: TStream; dst: TStrings);
- begin
- dst.LoadFromStream(src);
- end;
- procedure ProcessLinkingSection(st: TStream; syms: TStrings);
- var
- mt : TLinkingMetadata;
- //en : Int64;
- sub : TLinkingSubSection;
- cnt : LongWord;
- nx : Int64;
- i : integer;
- si : TSymInfo;
- ofs : Int64;
- v : string;
- tt : TSymbolType;
- tts : TSymbolTypes;
- fl : LongWord;
- begin
- //en := st.Position+secsize;
- ReadMetadata(st, mt);
- writeln('version: ', mt.version);
- //while st.Position<en do begin
- ReadLinkSubSect(st, sub);
- nx := st.Position+sub.length;
- writeln('subsec=',SubSecTypeToStr(sub.sectype),' ',sub.sectype);
- cnt := ReadU(st);
- writeln('- symbol table [count=', cnt,']');
- for i:=0 to cnt-1 do begin
- write(' - ',i,' ');
- ofs := st.Position;
- ReadSymInfo(st, si);
- //write(SymKindToStr(si.kind),' ',IntToHex(si.flags,8));
- //if si.hasSymName then write(' ',si.symname);
- //writeln;
- if si.hasSymName then begin
- v := syms.Values[si.symname];
- fl := si.flags;
- tts := StrToSymTypes(v);
- for tt:=Low(TSymbolType) to High(TSymbolType) do begin
- if not (tt in tts) then continue;
- writeln(tt);
- case tt of
- st_Local:
- si.flags := (si.flags or WASM_SYM_BINDING_LOCAL) and (not WASM_SYM_BINDING_WEAK) and (not WASM_SYM_UNDEFINED);
- st_VisDefault:
- si.flags := (si.flags and not WASM_SYM_VISIBILITY_HIDDEN);
- st_VisHidden:
- si.flags := (si.flags or WASM_SYM_VISIBILITY_HIDDEN);
- st_Weak:
- si.flags := (si.flags or WASM_SYM_BINDING_WEAK) and (not WASM_SYM_BINDING_LOCAL)
- end;
- end;
- if fl <> si.flags then begin
- st.Position := ofs;
- WriteSymInfo(st, si);
- end;
- end;
- //writeln(si.symname);
- end;
- st.Position:=nx;
- //end;
- end;
- end.
|