Class: Rubycc::Link::LinkerScript

Inherits:
Object
  • Object
show all
Defined in:
lib/rubycc/link/library_resolver.rb

Overview

A deliberately small reader for the sliver of GNU-ld linker-script syntax that a library search actually meets: the file-list commands GROUP and INPUT (with AS_NEEDED nested inside), and OUTPUT_FORMAT, which is skipped. glibc's libc.so is exactly such a script — /* GNU ld script */ GROUP ( … ) — and this recovers the real files it points at.

It is not a linker-script language: SECTIONS, PROVIDE, MEMORY, symbol assignments and the rest are not modelled. Only the recognized commands act; every other token outside a file list is ignored, so an unfamiliar directive passes by without derailing the scan rather than being half-interpreted. AS_NEEDED contents are treated as ordinary inputs here — the "only if used" trimming is the DT_NEEDED as-needed logic SharedLinker already applies.

Constant Summary collapse

FILE_LIST_COMMANDS =

The commands that introduce a parenthesized list of input files. AS_NEEDED appears nested within GROUP/INPUT but is itself just another such list.

%w[GROUP INPUT AS_NEEDED].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(text) ⇒ LinkerScript

Returns a new instance of LinkerScript.



356
357
358
# File 'lib/rubycc/link/library_resolver.rb', line 356

def initialize(text)
  @tokens = tokenize(strip_comments(text))
end

Class Method Details

.parse(text) ⇒ Object

Parses text and returns the ordered file tokens its GROUP/INPUT lists name (absolute paths or -l requests), for the caller to resolve.



351
352
353
# File 'lib/rubycc/link/library_resolver.rb', line 351

def parse(text)
  new(text).parse
end

Instance Method Details

#parseObject



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/rubycc/link/library_resolver.rb', line 360

def parse
  files = []
  i = 0
  while i < @tokens.length
    token = @tokens[i]
    if FILE_LIST_COMMANDS.include?(token) && @tokens[i + 1] == "("
      i = collect(i + 1, files)
    elsif token == "OUTPUT_FORMAT" && @tokens[i + 1] == "("
      i = skip_parens(i + 1)
    else
      i += 1
    end
  end
  files
end