Merge "Revised the superstructure queue."
diff --git a/frc971/control_loops/BUILD b/frc971/control_loops/BUILD
index b6f6317..4737927 100644
--- a/frc971/control_loops/BUILD
+++ b/frc971/control_loops/BUILD
@@ -103,6 +103,19 @@
   ],
 )
 
+# TODO(austin): Select isn't working right.  We should be able to remove
+# logging conditionally with select and have CPU constraints work correctly.
+cc_library(
+  name = 'state_feedback_loop_uc',
+  hdrs = [
+    'state_feedback_loop.h',
+  ],
+  deps = [
+    '//aos/common:macros',
+    '//third_party/eigen',
+  ],
+  restricted_to = ['//tools:cortex-m4f'],
+)
 cc_library(
   name = 'state_feedback_loop',
   hdrs = [
diff --git a/frc971/control_loops/drivetrain/BUILD b/frc971/control_loops/drivetrain/BUILD
index 05fc4a3..c499243 100644
--- a/frc971/control_loops/drivetrain/BUILD
+++ b/frc971/control_loops/drivetrain/BUILD
@@ -160,3 +160,62 @@
     '//y2016/control_loops/drivetrain:polydrivetrain_plants',
   ],
 )
+
+genrule(
+  name = 'genrule_haptic_wheel',
+  visibility = ['//visibility:private'],
+  cmd = '$(location //frc971/control_loops/python:haptic_wheel) $(OUTS)',
+  tools = [
+    '//frc971/control_loops/python:haptic_wheel',
+  ],
+  outs = [
+    'haptic_wheel.h',
+    'haptic_wheel.cc',
+    'integral_haptic_wheel.h',
+    'integral_haptic_wheel.cc',
+    'haptic_trigger.h',
+    'haptic_trigger.cc',
+    'integral_haptic_trigger.h',
+    'integral_haptic_trigger.cc',
+  ],
+  restricted_to = ["//tools:k8", "//tools:roborio", "//tools:armhf-debian", "//tools:cortex-m4f"],
+)
+
+cc_library(
+  name = 'haptic_input_uc',
+  hdrs = [
+    'haptic_wheel.h',
+    'integral_haptic_wheel.h',
+    'haptic_trigger.h',
+    'integral_haptic_trigger.h',
+  ],
+  srcs = [
+    'haptic_wheel.cc',
+    'integral_haptic_wheel.cc',
+    'haptic_trigger.cc',
+    'integral_haptic_trigger.cc',
+  ],
+  deps = [
+    '//frc971/control_loops:state_feedback_loop_uc',
+  ],
+  restricted_to = ["//tools:cortex-m4f"],
+)
+
+cc_library(
+  name = 'haptic_wheel',
+  hdrs = [
+    'haptic_wheel.h',
+    'integral_haptic_wheel.h',
+    'haptic_trigger.h',
+    'integral_haptic_trigger.h',
+  ],
+  srcs = [
+    'haptic_wheel.cc',
+    'integral_haptic_wheel.cc',
+    'haptic_trigger.cc',
+    'integral_haptic_trigger.cc',
+  ],
+  deps = [
+    '//frc971/control_loops:state_feedback_loop',
+  ],
+)
diff --git a/frc971/control_loops/hybrid_state_feedback_loop_test.cc b/frc971/control_loops/hybrid_state_feedback_loop_test.cc
index 401be44..42433e9 100644
--- a/frc971/control_loops/hybrid_state_feedback_loop_test.cc
+++ b/frc971/control_loops/hybrid_state_feedback_loop_test.cc
@@ -123,7 +123,6 @@
   // compile or have assertion failures at runtime.
   const StateFeedbackPlantCoefficients<2, 4, 7> coefficients(
       Eigen::Matrix<double, 2, 2>::Identity(),
-      Eigen::Matrix<double, 2, 2>::Identity(),
       Eigen::Matrix<double, 2, 4>::Identity(),
       Eigen::Matrix<double, 7, 2>::Identity(),
       Eigen::Matrix<double, 7, 4>::Identity(),
diff --git a/frc971/control_loops/python/BUILD b/frc971/control_loops/python/BUILD
index 4b25bb4..6ece1f4 100644
--- a/frc971/control_loops/python/BUILD
+++ b/frc971/control_loops/python/BUILD
@@ -1,5 +1,18 @@
 package(default_visibility = ['//visibility:public'])
 
+py_binary(
+  name = 'haptic_wheel',
+  srcs = [
+    'haptic_wheel.py',
+  ],
+  deps = [
+    '//external:python-gflags',
+    '//external:python-glog',
+    '//frc971/control_loops/python:controls',
+  ],
+  restricted_to = ['//tools:k8'],
+)
+
 py_library(
   name = 'controls',
   srcs = [
diff --git a/frc971/control_loops/python/control_loop.py b/frc971/control_loops/python/control_loop.py
index c2fe755..e62bff9 100644
--- a/frc971/control_loops/python/control_loop.py
+++ b/frc971/control_loops/python/control_loop.py
@@ -279,6 +279,7 @@
     """
     self.L = controls.dplace(self.A.T, self.C.T, poles).T
 
+
   def Update(self, U):
     """Simulates one time step with the provided U."""
     #U = numpy.clip(U, self.U_min, self.U_max)
@@ -291,13 +292,20 @@
 
   def CorrectObserver(self, U):
     """Runs the correct step of the observer update."""
-    self.X_hat += numpy.linalg.inv(self.A) * self.L * (
-        self.Y - self.C * self.X_hat - self.D * U)
+    if hasattr(self, 'KalmanGain'):
+      KalmanGain = self.KalmanGain
+    else:
+      KalmanGain = numpy.linalg.inv(self.A) * self.L
+    self.X_hat += KalmanGain * (self.Y - self.C * self.X_hat - self.D * U)
 
   def UpdateObserver(self, U):
     """Updates the observer given the provided U."""
+    if hasattr(self, 'KalmanGain'):
+      KalmanGain = self.KalmanGain
+    else:
+      KalmanGain =  numpy.linalg.inv(self.A) * self.L
     self.X_hat = (self.A * self.X_hat + self.B * U +
-                  self.L * (self.Y - self.C * self.X_hat - self.D * U))
+                  self.A * KalmanGain * (self.Y - self.C * self.X_hat - self.D * U))
 
   def _DumpMatrix(self, matrix_name, matrix, scalar_type):
     """Dumps the provided matrix into a variable called matrix_name.
@@ -347,10 +355,9 @@
 
     if plant_coefficient_type.startswith('StateFeedbackPlant'):
       ans.append(self._DumpMatrix('A', self.A, scalar_type))
-      ans.append(self._DumpMatrix('A_inv', numpy.linalg.inv(self.A), scalar_type))
       ans.append(self._DumpMatrix('B', self.B, scalar_type))
       ans.append('  return %s'
-                 '(A, A_inv, B, C, D, U_max, U_min);\n' % (
+                 '(A, B, C, D, U_max, U_min);\n' % (
                      plant_coefficient_type))
     elif plant_coefficient_type.startswith('StateFeedbackHybridPlant'):
       ans.append(self._DumpMatrix('A_continuous', self.A_continuous, scalar_type))
@@ -433,8 +440,13 @@
            observer_coefficient_type, self.ObserverFunction())]
 
     if observer_coefficient_type.startswith('StateFeedbackObserver'):
-      ans.append(self._DumpMatrix('L', self.L, scalar_type))
-      ans.append('  return %s(L);\n' % (observer_coefficient_type,))
+      if hasattr(self, 'KalmanGain'):
+        KalmanGain = self.KalmanGain
+      else:
+        KalmanGain =  numpy.linalg.inv(self.A) * self.L
+      ans.append(self._DumpMatrix('KalmanGain', KalmanGain, scalar_type))
+      ans.append('  return %s(KalmanGain);\n' % (observer_coefficient_type,))
+
     elif observer_coefficient_type.startswith('HybridKalman'):
       ans.append(self._DumpMatrix('Q_continuous', self.Q_continuous, scalar_type))
       ans.append(self._DumpMatrix('R_continuous', self.R_continuous, scalar_type))
@@ -511,3 +523,38 @@
     self.Kv = (self.free_speed / (12.0 - self.resistance * self.free_current))
     # Torque constant
     self.Kt = self.stall_torque / self.stall_current
+
+
+class BAG(object):
+  # BAG motor specs available at http://motors.vex.com/vexpro-motors/bag-motor
+  def __init__(self):
+    # Stall Torque in (N m)
+    self.stall_torque = 0.43
+    # Stall Current in (Amps)
+    self.stall_current = 53.0
+    # Free Speed in (rad/s)
+    self.free_speed = 13180.0 / 60.0 * 2.0 * numpy.pi
+    # Free Current in (Amps)
+    self.free_current = 1.8
+    # Resistance of the motor (Ohms)
+    self.resistance = 12.0 / self.stall_current
+    # Motor velocity constant (radians / (sec * volt))
+    self.Kv = (self.free_speed / (12.0 - self.resistance * self.free_current))
+    # Torque constant (N * m / A)
+    self.Kt = self.stall_torque / self.stall_current
+
+class MN3510(object):
+  def __init__(self):
+    # http://www.robotshop.com/en/t-motor-navigator-mn3510-360kv-brushless-motor.html#Specifications
+    # Free Current in Amps
+    self.free_current = 0.0
+    # Resistance of the motor
+    self.resistance = 0.188
+    # Stall Current in Amps
+    self.stall_current = 14.0 / self.resistance
+    # Motor velocity constant
+    self.Kv = 360.0 / 60.0 * (2.0 * numpy.pi)
+    # Torque constant Nm / A
+    self.Kt = 1.0 / self.Kv
+    # Stall Torque in N m
+    self.stall_torque = self.Kt * self.stall_current
diff --git a/frc971/control_loops/python/haptic_wheel.py b/frc971/control_loops/python/haptic_wheel.py
new file mode 100755
index 0000000..6c88e15
--- /dev/null
+++ b/frc971/control_loops/python/haptic_wheel.py
@@ -0,0 +1,406 @@
+#!/usr/bin/python
+
+from frc971.control_loops.python import control_loop
+from frc971.control_loops.python import controls
+import numpy
+import sys
+import copy
+import scipy.interpolate
+from matplotlib import pylab
+
+import gflags
+import glog
+
+FLAGS = gflags.FLAGS
+
+gflags.DEFINE_bool('plot', False, 'If true, plot the loop response.')
+gflags.DEFINE_string('data', None, 'If defined, plot the provided CAN data')
+gflags.DEFINE_bool('rerun_kf', False, 'If true, rerun the KF.  The torque in the data file will be interpreted as the commanded current.')
+
+class SystemParams(object):
+  def __init__(self, J, G, kP, kD, kCompensationTimeconstant, q_pos, q_vel,
+               q_torque, current_limit):
+    self.J = J
+    self.G = G
+    self.q_pos = q_pos
+    self.q_vel = q_vel
+    self.q_torque = q_torque
+    self.kP = kP
+    self.kD = kD
+    self.kCompensationTimeconstant = kCompensationTimeconstant
+    self.r_pos = 0.001
+    self.current_limit = current_limit
+
+    #[15.0, 0.25],
+    #[10.0, 0.2],
+    #[5.0, 0.13],
+    #[3.0, 0.10],
+    #[2.0, 0.08],
+    #[1.0, 0.06],
+    #[0.5, 0.05],
+    #[0.25, 0.025],
+
+kWheel = SystemParams(J=0.0008,
+                      G=(1.25 + 0.02) / 0.35,
+                      q_pos=0.001,
+                      q_vel=0.20,
+                      q_torque=0.005,
+                      kP=7.0,
+                      kD=0.0,
+                      kCompensationTimeconstant=0.95,
+                      current_limit=4.5)
+kTrigger = SystemParams(J=0.00025,
+                        G=(0.925 * 2.0 + 0.02) / 0.35,
+                        q_pos=0.001,
+                        q_vel=0.1,
+                        q_torque=0.005,
+                        kP=120.0,
+                        kD=1.8,
+                        kCompensationTimeconstant=0.95,
+                        current_limit=3.0)
+
+class HapticInput(control_loop.ControlLoop):
+  def __init__(self, params=None, name='HapticInput'):
+    # The defaults are for the steering wheel.
+    super(HapticInput, self).__init__(name)
+    motor = self.motor = control_loop.MN3510()
+
+    # Moment of inertia of the wheel in kg m^2
+    self.J = params.J
+
+    # Control loop time step
+    self.dt = 0.001
+
+    # Gear ratio from the motor to the input.
+    self.G = params.G
+
+    self.A_continuous = numpy.matrix(numpy.zeros((2, 2)))
+    self.A_continuous[1, 1] = 0
+    self.A_continuous[0, 1] = 1
+
+    self.B_continuous = numpy.matrix(numpy.zeros((2, 1)))
+    self.B_continuous[1, 0] = motor.Kt * self.G / self.J
+
+    # State feedback matrices
+    # [position, angular velocity]
+    self.C = numpy.matrix([[1.0, 0.0]])
+    self.D = numpy.matrix([[0.0]])
+
+    self.A, self.B = self.ContinuousToDiscrete(
+        self.A_continuous, self.B_continuous, self.dt)
+
+    self.U_max = numpy.matrix([[2.5]])
+    self.U_min = numpy.matrix([[-2.5]])
+
+    self.L = numpy.matrix([[0.0], [0.0]])
+    self.K = numpy.matrix([[0.0, 0.0]])
+
+    self.InitializeState()
+
+
+class IntegralHapticInput(HapticInput):
+  def __init__(self, params=None, name="IntegralHapticInput"):
+    super(IntegralHapticInput, self).__init__(name=name, params=params)
+
+    self.A_continuous_unaugmented = self.A_continuous
+    self.B_continuous_unaugmented = self.B_continuous
+
+    self.A_continuous = numpy.matrix(numpy.zeros((3, 3)))
+    self.A_continuous[0:2, 0:2] = self.A_continuous_unaugmented
+    self.A_continuous[1, 2] = (1 / self.J)
+
+    self.B_continuous = numpy.matrix(numpy.zeros((3, 1)))
+    self.B_continuous[0:2, 0] = self.B_continuous_unaugmented
+
+    self.C_unaugmented = self.C
+    self.C = numpy.matrix(numpy.zeros((1, 3)))
+    self.C[0:1, 0:2] = self.C_unaugmented
+
+    self.A, self.B = self.ContinuousToDiscrete(
+        self.A_continuous, self.B_continuous, self.dt)
+
+    self.Q = numpy.matrix([[(params.q_pos ** 2.0), 0.0, 0.0],
+                           [0.0, (params.q_vel ** 2.0), 0.0],
+                           [0.0, 0.0, (params.q_torque ** 2.0)]])
+
+    self.R = numpy.matrix([[(params.r_pos ** 2.0)]])
+
+    self.KalmanGain, self.Q_steady = controls.kalman(
+        A=self.A, B=self.B, C=self.C, Q=self.Q, R=self.R)
+    self.L = self.A * self.KalmanGain
+
+    self.K_unaugmented = self.K
+    self.K = numpy.matrix(numpy.zeros((1, 3)))
+    self.K[0, 0:2] = self.K_unaugmented
+    self.K[0, 2] = 1.0 / (self.motor.Kt / (self.motor.resistance))
+
+    self.InitializeState()
+
+def ReadCan(filename):
+  """Reads the candump in filename and returns the 4 fields."""
+  trigger = []
+  trigger_velocity = []
+  trigger_torque = []
+  trigger_current = []
+  wheel = []
+  wheel_velocity = []
+  wheel_torque = []
+  wheel_current = []
+
+  trigger_request_time = [0.0]
+  trigger_request_current = [0.0]
+  wheel_request_time = [0.0]
+  wheel_request_current = [0.0]
+
+  with open(filename, 'r') as fd:
+    for line in fd:
+      data = line.split()
+      can_id = int(data[1], 16)
+      if can_id == 0:
+        data = [int(d, 16) for d in data[3:]]
+        trigger.append(((data[0] + (data[1] << 8)) - 32768) / 32768.0)
+        trigger_velocity.append(((data[2] + (data[3] << 8)) - 32768) / 32768.0)
+        trigger_torque.append(((data[4] + (data[5] << 8)) - 32768) / 32768.0)
+        trigger_current.append(((data[6] + ((data[7] & 0x3f) << 8)) - 8192) / 8192.0)
+      elif can_id == 1:
+        data = [int(d, 16) for d in data[3:]]
+        wheel.append(((data[0] + (data[1] << 8)) - 32768) / 32768.0)
+        wheel_velocity.append(((data[2] + (data[3] << 8)) - 32768) / 32768.0)
+        wheel_torque.append(((data[4] + (data[5] << 8)) - 32768) / 32768.0)
+        wheel_current.append(((data[6] + ((data[7] & 0x3f) << 8)) - 8192) / 8192.0)
+      elif can_id == 2:
+        data = [int(d, 16) for d in data[3:]]
+        trigger_request_current.append(((data[4] + (data[5] << 8)) - 32768) / 32768.0)
+        trigger_request_time.append(len(trigger) * 0.001)
+      elif can_id == 3:
+        data = [int(d, 16) for d in data[3:]]
+        wheel_request_current.append(((data[4] + (data[5] << 8)) - 32768) / 32768.0)
+        wheel_request_time.append(len(wheel) * 0.001)
+
+  trigger_data_time = numpy.arange(0, len(trigger)) * 0.001
+  wheel_data_time = numpy.arange(0, len(wheel)) * 0.001
+
+  # Extend out the data in the interpolation table.
+  trigger_request_time.append(trigger_data_time[-1])
+  trigger_request_current.append(trigger_request_current[-1])
+  wheel_request_time.append(wheel_data_time[-1])
+  wheel_request_current.append(wheel_request_current[-1])
+
+  return (trigger_data_time, wheel_data_time, trigger, wheel, trigger_velocity,
+          wheel_velocity, trigger_torque, wheel_torque, trigger_current,
+          wheel_current, trigger_request_time, trigger_request_current,
+          wheel_request_time, wheel_request_current)
+
+def rerun_and_plot_kf(data_time, data_radians, data_current, data_request_current,
+                      params, run_correct=True):
+  kf_velocity = []
+  dt_velocity = []
+  kf_position = []
+  adjusted_position = []
+  last_angle = None
+  haptic_observer = IntegralHapticInput(params=params)
+
+  # Parameter sweep J.
+  num_kf = 1
+  min_J = max_J = params.J
+
+  # J = 0.0022
+  #num_kf = 15
+  #min_J = min_J / 2.0
+  #max_J = max_J * 2.0
+  initial_velocity = (data_radians[1] - data_radians[0]) * 1000.0
+
+  def DupParamsWithJ(params, J):
+    p = copy.copy(params)
+    p.J = J
+    return p
+  haptic_observers = [IntegralHapticInput(params=DupParamsWithJ(params, j)) for j in
+                      numpy.logspace(numpy.log10(min_J),
+                                     numpy.log10(max_J), num=num_kf)]
+  # Initialize all the KF's.
+  haptic_observer.X_hat[1, 0] = initial_velocity
+  haptic_observer.X_hat[0, 0] = data_radians[0]
+  for observer in haptic_observers:
+    observer.X_hat[1, 0] = initial_velocity
+    observer.X_hat[0, 0] = data_radians[0]
+
+  last_request_current = data_request_current[0]
+  kf_torques = [[] for i in xrange(num_kf)]
+  for angle, current, request_current in zip(data_radians, data_current,
+                                             data_request_current):
+    # Predict and correct all the parameter swept observers.
+    for i, observer in enumerate(haptic_observers):
+      observer.Y = numpy.matrix([[angle]])
+      if run_correct:
+        observer.CorrectObserver(numpy.matrix([[current]]))
+      kf_torques[i].append(-observer.X_hat[2, 0])
+      observer.PredictObserver(numpy.matrix([[current]]))
+      observer.PredictObserver(numpy.matrix([[current]]))
+
+    # Predict and correct the main observer.
+    haptic_observer.Y = numpy.matrix([[angle]])
+    if run_correct:
+      haptic_observer.CorrectObserver(numpy.matrix([[current]]))
+    kf_position.append(haptic_observer.X_hat[0, 0])
+    adjusted_position.append(kf_position[-1] - last_request_current / params.kP)
+    last_request_current = last_request_current * params.kCompensationTimeconstant + request_current * (1.0 - params.kCompensationTimeconstant)
+    kf_velocity.append(haptic_observer.X_hat[1, 0])
+    if last_angle is None:
+      last_angle = angle
+    dt_velocity.append((angle - last_angle) / 0.001)
+
+    haptic_observer.PredictObserver(numpy.matrix([[current]]))
+    last_angle = angle
+
+  # Plot the wheel observers.
+  fig, ax1 = pylab.subplots()
+  ax1.plot(data_time, data_radians, '.', label='wheel')
+  ax1.plot(data_time, dt_velocity, '.', label='dt_velocity')
+  ax1.plot(data_time, kf_velocity, '.', label='kf_velocity')
+  ax1.plot(data_time, kf_position, '.', label='kf_position')
+  ax1.plot(data_time, adjusted_position, '.', label='adjusted_position')
+
+  ax2 = ax1.twinx()
+  ax2.plot(data_time, data_current, label='data_current')
+  ax2.plot(data_time, data_request_current, label='request_current')
+
+  for i, kf_torque in enumerate(kf_torques):
+    ax2.plot(data_time, kf_torque,
+               label='-kf_torque[%f]' % haptic_observers[i].J)
+  fig.tight_layout()
+  ax1.legend(loc=3)
+  ax2.legend(loc=4)
+
+def plot_input(data_time, data_radians, data_velocity, data_torque,
+               data_current, params, run_correct=True):
+  dt_velocity = []
+  last_angle = None
+  initial_velocity = (data_radians[1] - data_radians[0]) * 1000.0
+
+  for angle in data_radians:
+    if last_angle is None:
+      last_angle = angle
+    dt_velocity.append((angle - last_angle) / 0.001)
+
+    last_angle = angle
+
+  # Plot the wheel observers.
+  fig, ax1 = pylab.subplots()
+  ax1.plot(data_time, data_radians, '.', label='angle')
+  ax1.plot(data_time, data_velocity, '-', label='velocity')
+  ax1.plot(data_time, dt_velocity, '.', label='dt_velocity')
+
+  ax2 = ax1.twinx()
+  ax2.plot(data_time, data_torque, label='data_torque')
+  ax2.plot(data_time, data_current, label='data_current')
+  fig.tight_layout()
+  ax1.legend(loc=3)
+  ax2.legend(loc=4)
+
+def main(argv):
+  if FLAGS.plot:
+    if FLAGS.data is None:
+      haptic_wheel = HapticInput()
+      haptic_wheel_controller = IntegralHapticInput()
+      observer_haptic_wheel = IntegralHapticInput()
+      observer_haptic_wheel.X_hat[2, 0] = 0.01
+
+      R = numpy.matrix([[0.0], [0.0], [0.0]])
+
+      control_loop.TestSingleIntegralAxisSquareWave(
+          R, 1.0, haptic_wheel, haptic_wheel_controller, observer_haptic_wheel)
+    else:
+      # Read the CAN trace in.
+      trigger_data_time, wheel_data_time, trigger, wheel, trigger_velocity, \
+          wheel_velocity, trigger_torque, wheel_torque, trigger_current, \
+          wheel_current, trigger_request_time, trigger_request_current, \
+          wheel_request_time, wheel_request_current = ReadCan(FLAGS.data)
+
+      wheel_radians = [w * numpy.pi * (338.16 / 360.0) for w in wheel]
+      wheel_velocity = [w * 50.0 for w in wheel_velocity]
+      wheel_torque = [w / 2.0 for w in wheel_torque]
+      wheel_current = [w * 10.0 for w in wheel_current]
+      wheel_request_current = [w * 2.0 for w in wheel_request_current]
+      resampled_wheel_request_current = scipy.interpolate.interp1d(
+          wheel_request_time, wheel_request_current, kind="zero")(wheel_data_time)
+
+      trigger_radians = [t * numpy.pi * (45.0 / 360.0) for t in trigger]
+      trigger_velocity = [t * 50.0 for t in trigger_velocity]
+      trigger_torque = [t / 2.0 for t in trigger_torque]
+      trigger_current = [t * 10.0 for t in trigger_current]
+      trigger_request_current = [t * 2.0 for t in trigger_request_current]
+      resampled_trigger_request_current = scipy.interpolate.interp1d(
+          trigger_request_time, trigger_request_current, kind="zero")(trigger_data_time)
+
+      if FLAGS.rerun_kf:
+        rerun_and_plot_kf(trigger_data_time, trigger_radians, trigger_current,
+                          resampled_trigger_request_current, kTrigger, run_correct=True)
+        rerun_and_plot_kf(wheel_data_time, wheel_radians, wheel_current,
+                          resampled_wheel_request_current, kWheel, run_correct=True)
+      else:
+        plot_input(trigger_data_time, trigger_radians, trigger_velocity,
+                   trigger_torque, trigger_current, kTrigger)
+        plot_input(wheel_data_time, wheel_radians, wheel_velocity, wheel_torque,
+                   wheel_current, kWheel)
+      pylab.show()
+
+    return
+
+  if len(argv) != 9:
+    glog.fatal('Expected .h file name and .cc file name')
+  else:
+    namespaces = ['frc971', 'control_loops', 'drivetrain']
+    for name, params, filenames in [('HapticWheel', kWheel, argv[1:5]),
+                                    ('HapticTrigger', kTrigger, argv[5:9])]:
+      haptic_input = HapticInput(params=params, name=name)
+      loop_writer = control_loop.ControlLoopWriter(name, [haptic_input],
+                                                   namespaces=namespaces,
+                                                   scalar_type='float')
+      loop_writer.Write(filenames[0], filenames[1])
+
+      integral_haptic_input = IntegralHapticInput(params=params,
+                                                  name='Integral' + name)
+      integral_loop_writer = control_loop.ControlLoopWriter(
+          'Integral' + name, [integral_haptic_input], namespaces=namespaces,
+          scalar_type='float')
+
+      integral_loop_writer.AddConstant(
+          control_loop.Constant("k" + name + "Dt", "%f",
+                                integral_haptic_input.dt))
+      integral_loop_writer.AddConstant(
+          control_loop.Constant("k" + name + "FreeCurrent", "%f",
+                                integral_haptic_input.motor.free_current))
+      integral_loop_writer.AddConstant(
+          control_loop.Constant("k" + name + "StallTorque", "%f",
+                                integral_haptic_input.motor.stall_torque))
+      integral_loop_writer.AddConstant(
+          control_loop.Constant("k" + name + "J", "%f",
+                                integral_haptic_input.J))
+      integral_loop_writer.AddConstant(
+          control_loop.Constant("k" + name + "R", "%f",
+                                integral_haptic_input.motor.resistance))
+      integral_loop_writer.AddConstant(
+          control_loop.Constant("k" + name + "T", "%f",
+                                integral_haptic_input.motor.Kt))
+      integral_loop_writer.AddConstant(
+          control_loop.Constant("k" + name + "V", "%f",
+                                integral_haptic_input.motor.Kv))
+      integral_loop_writer.AddConstant(
+          control_loop.Constant("k" + name + "P", "%f",
+                                params.kP))
+      integral_loop_writer.AddConstant(
+          control_loop.Constant("k" + name + "D", "%f",
+                                params.kD))
+      integral_loop_writer.AddConstant(
+          control_loop.Constant("k" + name + "G", "%f",
+                                params.G))
+      integral_loop_writer.AddConstant(
+          control_loop.Constant("k" + name + "CurrentLimit", "%f",
+                                params.current_limit))
+
+      integral_loop_writer.Write(filenames[2], filenames[3])
+
+
+if __name__ == '__main__':
+  argv = FLAGS(sys.argv)
+  sys.exit(main(argv))
diff --git a/frc971/control_loops/state_feedback_loop.h b/frc971/control_loops/state_feedback_loop.h
index b9765fc..6ffc1b8 100644
--- a/frc971/control_loops/state_feedback_loop.h
+++ b/frc971/control_loops/state_feedback_loop.h
@@ -12,7 +12,9 @@
 #include "Eigen/Dense"
 #include "unsupported/Eigen/MatrixFunctions"
 
+#if defined(__linux__)
 #include "aos/common/logging/logging.h"
+#endif
 #include "aos/common/macros.h"
 
 template <int number_of_states, int number_of_inputs, int number_of_outputs,
@@ -34,7 +36,6 @@
 
   StateFeedbackPlantCoefficients(const StateFeedbackPlantCoefficients &other)
       : A(other.A),
-        A_inv(other.A_inv),
         B(other.B),
         C(other.C),
         D(other.D),
@@ -43,16 +44,14 @@
 
   StateFeedbackPlantCoefficients(
       const Eigen::Matrix<Scalar, number_of_states, number_of_states> &A,
-      const Eigen::Matrix<Scalar, number_of_states, number_of_states> &A_inv,
       const Eigen::Matrix<Scalar, number_of_states, number_of_inputs> &B,
       const Eigen::Matrix<Scalar, number_of_outputs, number_of_states> &C,
       const Eigen::Matrix<Scalar, number_of_outputs, number_of_inputs> &D,
       const Eigen::Matrix<Scalar, number_of_inputs, 1> &U_max,
       const Eigen::Matrix<Scalar, number_of_inputs, 1> &U_min)
-      : A(A), A_inv(A_inv), B(B), C(C), D(D), U_min(U_min), U_max(U_max) {}
+      : A(A), B(B), C(C), D(D), U_min(U_min), U_max(U_max) {}
 
   const Eigen::Matrix<Scalar, number_of_states, number_of_states> A;
-  const Eigen::Matrix<Scalar, number_of_states, number_of_states> A_inv;
   const Eigen::Matrix<Scalar, number_of_states, number_of_inputs> B;
   const Eigen::Matrix<Scalar, number_of_outputs, number_of_states> C;
   const Eigen::Matrix<Scalar, number_of_outputs, number_of_inputs> D;
@@ -87,10 +86,6 @@
     return coefficients().A;
   }
   Scalar A(int i, int j) const { return A()(i, j); }
-  const Eigen::Matrix<Scalar, number_of_states, number_of_states> &A_inv() const {
-    return coefficients().A_inv;
-  }
-  Scalar A_inv(int i, int j) const { return A_inv()(i, j); }
   const Eigen::Matrix<Scalar, number_of_states, number_of_inputs> &B() const {
     return coefficients().B;
   }
@@ -151,7 +146,11 @@
     for (int i = 0; i < kNumInputs; ++i) {
       if (U(i, 0) > U_max(i, 0) + static_cast<Scalar>(0.00001) ||
           U(i, 0) < U_min(i, 0) - static_cast<Scalar>(0.00001)) {
+#if defined(__linux__)
         LOG(FATAL, "U out of range\n");
+#else
+        abort();
+#endif
       }
     }
   }
@@ -276,11 +275,11 @@
 struct StateFeedbackObserverCoefficients final {
   EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
 
-  const Eigen::Matrix<Scalar, number_of_states, number_of_outputs> L;
+  const Eigen::Matrix<Scalar, number_of_states, number_of_outputs> KalmanGain;
 
   StateFeedbackObserverCoefficients(
-      const Eigen::Matrix<Scalar, number_of_states, number_of_outputs> &L)
-      : L(L) {}
+      const Eigen::Matrix<Scalar, number_of_states, number_of_outputs> &KalmanGain)
+      : KalmanGain(KalmanGain) {}
 };
 
 template <int number_of_states, int number_of_inputs, int number_of_outputs,
@@ -299,10 +298,10 @@
     ::std::swap(coefficients_, other.coefficients_);
   }
 
-  const Eigen::Matrix<Scalar, number_of_states, number_of_outputs> &L() const {
-    return coefficients().L;
+  const Eigen::Matrix<Scalar, number_of_states, number_of_outputs> &KalmanGain() const {
+    return coefficients().KalmanGain;
   }
-  Scalar L(int i, int j) const { return L()(i, j); }
+  Scalar KalmanGain(int i, int j) const { return KalmanGain()(i, j); }
 
   const Eigen::Matrix<Scalar, number_of_states, 1> &X_hat() const {
     return X_hat_;
@@ -326,7 +325,7 @@
                const Eigen::Matrix<Scalar, number_of_inputs, 1> &U,
                const Eigen::Matrix<Scalar, number_of_outputs, 1> &Y) {
     mutable_X_hat() +=
-        plant.A_inv() * L() * (Y - plant.C() * X_hat() - plant.D() * U);
+        KalmanGain() * (Y - plant.C() * X_hat() - plant.D() * U);
   }
 
   // Sets the current controller to be index, clamped to be within range.
diff --git a/motors/BUILD b/motors/BUILD
index fd53dd0..b11df45 100644
--- a/motors/BUILD
+++ b/motors/BUILD
@@ -135,3 +135,25 @@
   ],
   restricted_to = mcu_cpus,
 )
+
+cc_binary(
+  name = 'button_board.elf',
+  srcs = [
+    'button_board.cc',
+  ],
+  deps = [
+    ':util',
+    '//motors/core',
+    '//motors/peripheral:can',
+    '//motors/peripheral:adc',
+    '//motors/usb',
+    '//motors/usb:cdc',
+    '//motors/usb:hid',
+  ],
+  restricted_to = mcu_cpus,
+)
+
+hex_from_elf(
+  name = 'button_board',
+  restricted_to = mcu_cpus,
+)
diff --git a/motors/algorithms.h b/motors/algorithms.h
index d1fce7a..8b397f8 100644
--- a/motors/algorithms.h
+++ b/motors/algorithms.h
@@ -26,6 +26,19 @@
 // and the corresponding outputs will be inversely proportional to the weights.
 BalancedReadings BalanceReadings(ReadingsToBalance to_balance);
 
+inline BalancedReadings BalanceSimpleReadings(const uint16_t readings[3]) {
+  float offset = 0;
+  for (int i = 0; i < 3; ++i) {
+    offset += static_cast<float>(readings[i]);
+  }
+
+  BalancedReadings r;
+  for (int i = 0; i < 3; ++i) {
+    r.readings[i] = static_cast<float>(readings[i]) + offset / -3;
+  }
+  return r;
+}
+
 }  // namespace salsa
 }  // namespace frc971
 
diff --git a/motors/button_board.cc b/motors/button_board.cc
new file mode 100644
index 0000000..3fa3915
--- /dev/null
+++ b/motors/button_board.cc
@@ -0,0 +1,318 @@
+// This file has the main for the Teensy on the button board.
+
+#include <stdio.h>
+#include <inttypes.h>
+#include <atomic>
+
+#include "motors/core/time.h"
+#include "motors/core/kinetis.h"
+#include "motors/peripheral/adc.h"
+#include "motors/peripheral/can.h"
+#include "motors/usb/usb.h"
+#include "motors/usb/cdc.h"
+#include "motors/usb/hid.h"
+#include "motors/util.h"
+
+namespace frc971 {
+namespace motors {
+namespace {
+
+::std::atomic<teensy::AcmTty *> global_stdout{nullptr};
+
+// The HID report descriptor we use.
+constexpr char kReportDescriptor[] = {
+    0x05, 0x01,        // Usage Page (Generic Desktop),
+    0x09, 0x04,        // Usage (Joystick),
+    0xA1, 0x01,        // Collection (Application),
+    0x75, 0x08,        //     Report Size (8),
+    0x95, 0x04,        //     Report Count (4),
+    0x15, 0x00,        //     Logical Minimum (0),
+    0x26, 0xFF, 0x00,  //     Logical Maximum (255),
+    0x35, 0x00,        //     Physical Minimum (0),
+    0x46, 0xFF, 0x00,  //     Physical Maximum (255),
+    0x09, 0x30,        //     Usage (X),
+    0x09, 0x31,        //     Usage (Y),
+    0x09, 0x32,        //     Usage (Z),
+    0x09, 0x33,        //     Usage (Rz),
+    0x81, 0x02,        //     Input (Variable),
+    0x75, 0x01,        //     Report Size (1),
+    0x95, 0x14,        //     Report Count (20),
+    0x25, 0x01,        //     Logical Maximum (1),
+    0x45, 0x01,        //     Physical Maximum (1),
+    0x05, 0x09,        //     Usage Page (Button),
+    0x19, 0x01,        //     Usage Minimum (01),
+    0x29, 0x14,        //     Usage Maximum (20),
+    0x81, 0x02,        //     Input (Variable),
+    0x95, 0x04,        //     Report Count (4),
+    0x81, 0x03,        //     Input (Constant, Variable),
+    0xC0               // End Collection
+};
+
+constexpr uint16_t report_size() { return 1 * 4 + 3; }
+
+void SendJoystickData(teensy::HidFunction *joystick) {
+  uint32_t start = micros();
+  while (true) {
+    salsa::JoystickAdcReadings adc;
+    char report[report_size()];
+    {
+      DisableInterrupts disable_interrupts;
+      adc = salsa::AdcReadJoystick(disable_interrupts);
+    }
+
+    FTM0->C1V = adc.analog0 / 4;
+    FTM0->C0V = adc.analog1 / 4;
+    FTM0->C4V = adc.analog2 / 4;
+    FTM0->C3V = adc.analog3 / 4;
+    FTM0->PWMLOAD = FTM_PWMLOAD_LDOK;
+    report[0] = adc.analog0 / 16;
+    report[1] = adc.analog1 / 16;
+    report[2] = adc.analog2 / 16;
+    report[3] = adc.analog3 / 16;
+
+    report[4] = (GPIO_BITBAND(GPIOD_PDIR, 5) << 0) |
+                (GPIO_BITBAND(GPIOD_PDIR, 6) << 1) |
+                (GPIO_BITBAND(GPIOD_PDIR, 16) << 2) |
+                (GPIO_BITBAND(GPIOB_PDIR, 1) << 3) |
+                (GPIO_BITBAND(GPIOA_PDIR, 14) << 4) |
+                (GPIO_BITBAND(GPIOE_PDIR, 26) << 5) |
+                (GPIO_BITBAND(GPIOA_PDIR, 16) << 6) |
+                (GPIO_BITBAND(GPIOA_PDIR, 15) << 7);
+
+    report[5] = (GPIO_BITBAND(GPIOE_PDIR, 25) << 0) |
+                (GPIO_BITBAND(GPIOE_PDIR, 24) << 1) |
+                (GPIO_BITBAND(GPIOC_PDIR, 3) << 2) |
+                (GPIO_BITBAND(GPIOC_PDIR, 7) << 3) |
+                (GPIO_BITBAND(GPIOD_PDIR, 3) << 4) |
+                (GPIO_BITBAND(GPIOD_PDIR, 2) << 5) |
+                (GPIO_BITBAND(GPIOD_PDIR, 7) << 6) |
+                (GPIO_BITBAND(GPIOA_PDIR, 13) << 7);
+
+    report[6] = (GPIO_BITBAND(GPIOA_PDIR, 12) << 0) |
+                (GPIO_BITBAND(GPIOD_PDIR, 0) << 1) |
+                (GPIO_BITBAND(GPIOB_PDIR, 17) << 2) |
+                (GPIO_BITBAND(GPIOB_PDIR, 16) << 3);
+
+    {
+      DisableInterrupts disable_interrupts;
+      joystick->UpdateReport(report, sizeof(report), disable_interrupts);
+    }
+
+    start = delay_from(start, 1);
+  }
+}
+
+void SetupLedFtm(BigFTM *ftm) {
+  // PWMSYNC doesn't matter because we set SYNCMODE down below.
+  ftm->MODE = FTM_MODE_WPDIS;
+  ftm->MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN;
+  ftm->SC = FTM_SC_CLKS(0) /* Disable counting for now */;
+
+  // Use center-aligned high-true for all the channels.
+  ftm->C0SC = FTM_CSC_ELSB;
+  ftm->C0V = 0;
+  ftm->C1SC = FTM_CSC_ELSB;
+  ftm->C1V = 0;
+  ftm->C2SC = FTM_CSC_ELSB;
+  ftm->C2V = 0;
+  ftm->C3SC = FTM_CSC_ELSB;
+  ftm->C3V = 0;
+  ftm->C4SC = FTM_CSC_ELSB;
+  ftm->C4V = 0;
+  ftm->C5SC = FTM_CSC_ELSB;
+  ftm->C5V = 0;
+  ftm->C6SC = FTM_CSC_ELSB;
+  ftm->C6V = 0;
+  ftm->C7SC = FTM_CSC_ELSB;
+  ftm->C7V = 0;
+
+  ftm->COMBINE = FTM_COMBINE_SYNCEN3 /* Synchronize updates usefully */ |
+                 FTM_COMBINE_SYNCEN2 /* Synchronize updates usefully */ |
+                 FTM_COMBINE_SYNCEN1 /* Synchronize updates usefully */ |
+                 FTM_COMBINE_SYNCEN0 /* Synchronize updates usefully */;
+
+  ftm->CNTIN = 0;
+  ftm->CNT = 0;
+  ftm->MOD = 1024;
+  ftm->OUTINIT = 0;
+  ftm->POL = 0;
+  ftm->SYNCONF =
+      FTM_SYNCONF_HWWRBUF /* Hardware trigger flushes switching points */ |
+      FTM_SYNCONF_SWWRBUF /* Software trigger flushes switching points */ |
+      FTM_SYNCONF_SWRSTCNT /* Software trigger resets the count */ |
+      FTM_SYNCONF_SYNCMODE /* Use the new synchronization mode */;
+  // Don't want any intermediate loading points.
+  ftm->PWMLOAD = 0;
+
+  ftm->SYNC = FTM_SYNC_SWSYNC /* Flush everything out right now */;
+  // Wait for the software synchronization to finish.
+  while (ftm->SYNC & FTM_SYNC_SWSYNC) {
+  }
+  ftm->SC = FTM_SC_CPWMS /* Center-aligned PWM */ |
+            FTM_SC_CLKS(1) /* Use the system clock */ |
+            FTM_SC_PS(60) /* Prescaler */;
+
+  ftm->MODE &= ~FTM_MODE_WPDIS;
+}
+
+}  // namespace
+
+extern "C" {
+
+void *__stack_chk_guard = (void *)0x67111971;
+
+int _write(int /*file*/, char *ptr, int len) {
+  teensy::AcmTty *const tty = global_stdout.load(::std::memory_order_acquire);
+  if (tty != nullptr) {
+    return tty->Write(ptr, len);
+  }
+  return 0;
+}
+
+void __stack_chk_fail(void);
+
+}  // extern "C"
+
+extern "C" int main(void) {
+  // for background about this startup delay, please see these conversations
+  // https://forum.pjrc.com/threads/36606-startup-time-(400ms)?p=113980&viewfull=1#post113980
+  // https://forum.pjrc.com/threads/31290-Teensey-3-2-Teensey-Loader-1-24-Issues?p=87273&viewfull=1#post87273
+  delay(400);
+
+  // Set all interrupts to the second-lowest priority to start with.
+  for (int i = 0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_SANE_PRIORITY(i, 0xD);
+
+  // Now set priorities for all the ones we care about. They only have meaning
+  // relative to each other, which means centralizing them here makes it a lot
+  // more manageable.
+  NVIC_SET_SANE_PRIORITY(IRQ_USBOTG, 0x7);
+
+  // Set all the LED pins to output, slew rate controlled, high drive strength.
+  // Builtin
+  GPIO_BITBAND(GPIOC_PDOR, 5) = 1;
+  PORTC_PCR5 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(1);
+  GPIO_BITBAND(GPIOC_PDDR, 5) = 1;
+  // LED0 FTM0_CH1
+  GPIO_BITBAND(GPIOC_PDOR, 2) = 0;
+  PORTC_PCR2 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(4);
+  GPIO_BITBAND(GPIOC_PDDR, 2) = 1;
+  // LED1 FTM0_CH0
+  GPIO_BITBAND(GPIOC_PDOR, 1) = 0;
+  PORTC_PCR1 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(4);
+  GPIO_BITBAND(GPIOC_PDDR, 1) = 1;
+  // LED2 FTM0_CH4
+  GPIO_BITBAND(GPIOD_PDOR, 4) = 0;
+  PORTD_PCR4 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(4);
+  GPIO_BITBAND(GPIOD_PDDR, 4) = 1;
+  // LED3 FTM0_CH3
+  GPIO_BITBAND(GPIOC_PDOR, 4) = 0;
+  PORTC_PCR4 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(4);
+  GPIO_BITBAND(GPIOC_PDDR, 4) = 1;
+  // LED4 FTM3_CH4 yellow
+  GPIO_BITBAND(GPIOC_PDOR, 8) = 0;
+  PORTC_PCR8 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(1);
+  GPIO_BITBAND(GPIOC_PDDR, 8) = 1;
+  // LED5 FTM3_CH5 green
+  GPIO_BITBAND(GPIOC_PDOR, 9) = 0;
+  PORTC_PCR9 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(1);
+  GPIO_BITBAND(GPIOC_PDDR, 9) = 1;
+  // LED6 FTM3_CH6 red
+  GPIO_BITBAND(GPIOC_PDOR, 10) = 0;
+  PORTC_PCR10 = PORT_PCR_DSE | PORT_PCR_ODE | PORT_PCR_SRE | PORT_PCR_MUX(1);
+  GPIO_BITBAND(GPIOC_PDDR, 10) = 1;
+
+  // Set up the CAN pins.
+  PORTB_PCR18 = PORT_PCR_DSE | PORT_PCR_MUX(2);
+  PORTB_PCR19 = PORT_PCR_DSE | PORT_PCR_MUX(2);
+
+  // Set up the buttons. The LEDs pull them up to 5V, so the Teensy needs to not
+  // be set to pull up.
+  // BTN0
+  PORTD_PCR5 = PORT_PCR_MUX(1);
+  // BTN1
+  PORTD_PCR6 = PORT_PCR_MUX(1);
+  // BTN2
+  PORTD_PCR16 = PORT_PCR_MUX(1);
+  // BTN3
+  PORTB_PCR1 = PORT_PCR_MUX(1);
+  // BTN4
+  PORTA_PCR14 = PORT_PCR_MUX(1);
+  // BTN5
+  PORTE_PCR26 = PORT_PCR_MUX(1);
+  // BTN6
+  PORTA_PCR16 = PORT_PCR_MUX(1);
+  // BTN7
+  PORTA_PCR15 = PORT_PCR_MUX(1);
+  // BTN8
+  PORTE_PCR25 = PORT_PCR_MUX(1);
+  // BTN9
+  PORTE_PCR24 = PORT_PCR_MUX(1);
+  // BTN10
+  PORTC_PCR3 = PORT_PCR_MUX(1);
+  // BTN11
+  PORTC_PCR7 = PORT_PCR_MUX(1);
+  // BTN12
+  PORTD_PCR3 = PORT_PCR_MUX(1);
+  // BTN13
+  PORTD_PCR2 = PORT_PCR_MUX(1);
+  // BTN14
+  PORTD_PCR7 = PORT_PCR_MUX(1);
+  // BTN15
+  PORTA_PCR13 = PORT_PCR_MUX(1);
+  // BTN16
+  PORTA_PCR12 = PORT_PCR_MUX(1);
+  // BTN17
+  PORTD_PCR0 = PORT_PCR_MUX(1);
+  // BTN18
+  PORTB_PCR17 = PORT_PCR_MUX(1);
+  // BTN19
+  PORTB_PCR16 = PORT_PCR_MUX(1);
+
+  delay(100);
+
+  teensy::UsbDevice usb_device(0, 0x16c0, 0x0492);
+  usb_device.SetManufacturer("FRC 971 Spartan Robotics");
+  usb_device.SetProduct("Spartan Joystick Board");
+  teensy::HidFunction joystick(&usb_device, report_size());
+  joystick.set_report_descriptor(
+      ::std::string(kReportDescriptor, sizeof(kReportDescriptor)));
+  teensy::AcmTty tty1(&usb_device);
+  global_stdout.store(&tty1, ::std::memory_order_release);
+  usb_device.Initialize();
+
+  can_init(0, 1);
+  salsa::AdcInitJoystick();
+  SetupLedFtm(FTM0);
+  SetupLedFtm(FTM3);
+
+  // Leave the LEDs on for a bit longer.
+  delay(300);
+  printf("Done starting up\n");
+
+  // Done starting up, now turn all the LEDs off.
+  GPIO_BITBAND(GPIOC_PDOR, 5) = 0;
+  GPIO_BITBAND(GPIOC_PDOR, 2) = 1;
+  GPIO_BITBAND(GPIOC_PDOR, 1) = 1;
+  GPIO_BITBAND(GPIOD_PDOR, 4) = 1;
+  GPIO_BITBAND(GPIOC_PDOR, 4) = 1;
+  GPIO_BITBAND(GPIOC_PDOR, 8) = 1;
+  GPIO_BITBAND(GPIOC_PDOR, 9) = 1;
+  GPIO_BITBAND(GPIOC_PDOR, 10) = 1;
+
+  SendJoystickData(&joystick);
+
+  return 0;
+}
+
+void __stack_chk_fail(void) {
+  while (true) {
+    GPIOC_PSOR = (1 << 5);
+    printf("Stack corruption detected\n");
+    delay(1000);
+    GPIOC_PCOR = (1 << 5);
+    delay(1000);
+  }
+}
+
+}  // namespace motors
+}  // namespace frc971
diff --git a/motors/core/kinetis.h b/motors/core/kinetis.h
index 36ab5f2..2961a4f 100644
--- a/motors/core/kinetis.h
+++ b/motors/core/kinetis.h
@@ -3228,8 +3228,8 @@
 #define FTM0_CONF		(*(volatile uint32_t *)0x40038084) // Configuration
 #define FTM_CONF_GTBEOUT		0x400				// Global Time Base Output
 #define FTM_CONF_GTBEEN			0x200				// Global Time Base Enable
-#define FTM_CONF_BDMMODE		(((n) & 3) << 6)		// Behavior when in debug mode
-#define FTM_CONF_NUMTOF			(((n) & 31) << 0)		// ratio of counter overflows to TOF bit set
+#define FTM_CONF_BDMMOD(n)		(((n) & 3) << 6)		// Behavior when in debug mode
+#define FTM_CONF_NUMTOF(n)			(((n) & 31) << 0)		// ratio of counter overflows to TOF bit set
 #define FTM0_FLTPOL		(*(volatile uint32_t *)0x40038088) // FTM Fault Input Polarity
 #define FTM_FLTPOL_FLT3POL		0x08				// Fault Input 3 Polarity
 #define FTM_FLTPOL_FLT2POL		0x04				// Fault Input 2 Polarity
diff --git a/motors/deploy_joystick.sh b/motors/deploy_joystick.sh
new file mode 100755
index 0000000..db0d855
--- /dev/null
+++ b/motors/deploy_joystick.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+# Deploy to the driver station side of the pistol grip.
+
+bazel build --cpu=cortex-m4f -c opt //motors/pistol_grip:drivers_station.hex && bazel run //motors/teensy_loader_cli -- --mcu=mk64fx512 -s $(readlink -f bazel-bin/motors/pistol_grip/drivers_station.hex)
diff --git a/motors/medium_salsa.cc b/motors/medium_salsa.cc
index 2a9804a..3ac0337 100644
--- a/motors/medium_salsa.cc
+++ b/motors/medium_salsa.cc
@@ -178,7 +178,7 @@
   AdcInitMedium();
   MathInit();
   delay(1000);
-  can_init();
+  can_init(0, 1);
 
   GPIOD_PCOR = 1 << 3;
   GPIO_BITBAND(GPIOD_PDDR, 3) = 1;
@@ -243,7 +243,7 @@
   while (true) {
     unsigned char command_data[8];
     int command_length;
-    can_receive_command(command_data, &command_length);
+    can_receive_command(command_data, &command_length, 0);
     if (command_length == 4) {
       uint32_t result = command_data[0] << 24 | command_data[1] << 16 |
                         command_data[2] << 8 | command_data[3];
diff --git a/motors/motor.cc b/motors/motor.cc
index d966e6a..af7a3c7 100644
--- a/motors/motor.cc
+++ b/motors/motor.cc
@@ -10,6 +10,7 @@
 #include "motors/peripheral/can.h"
 
 extern "C" float analog_ratio(uint16_t reading);
+extern "C" float absolute_wheel(uint16_t reading);
 
 namespace frc971 {
 namespace salsa {
@@ -194,7 +195,7 @@
   // If we fire phase 2, we should go to -2.0 * PI / 3.0 radians.
   // If we fire phase 3, we should go to 2.0 * PI / 3.0 radians.
   // These numbers were confirmed by the python motor simulation.
-  static int phase_to_fire_count = -500000;
+  static int phase_to_fire_count = -300000;
   static int phase_to_fire = 0;
   ++phase_to_fire_count;
   if (phase_to_fire_count > 200000) {
@@ -217,7 +218,8 @@
   output_registers_[2][0] = 0;
   output_registers_[2][2] = phase_to_fire == 2 ? kPhaseFireWidth : 0;
 #endif
-
+  (void)balanced;
+  (void)captured_wrapped_encoder;
 #if PRINT_READINGS
   static int i = 0;
   if (i == 1000) {
@@ -227,12 +229,19 @@
       DisableInterrupts disable_interrupts;
       readings = AdcReadSmallInit(disable_interrupts);
     }
+    //printf(
+        //"enc %" PRIu32 " %d %d\n", captured_wrapped_encoder,
+        //static_cast<int>((1.0f - analog_ratio(readings.motor1_abs)) * 7000.0f),
+        //static_cast<int>(captured_wrapped_encoder * 7.0f / 4096.0f * 1000.0f));
+    float wheel_position = absolute_wheel(analog_ratio(readings.wheel_abs));
+
     printf(
-        "enc %d %d %d\n", captured_wrapped_encoder,
-        static_cast<int>((1.0f - analog_ratio(readings.motor0_abs)) * 7000.0f),
-        static_cast<int>(captured_wrapped_encoder * 7.0f / 4096.0f * 1000.0f));
+        "ecnt %" PRIu32 " arev:%d erev:%d %d\n", captured_wrapped_encoder,
+        static_cast<int>((analog_ratio(readings.motor1_abs)) * 7000.0f),
+        static_cast<int>(captured_wrapped_encoder * 7.0f / 4096.0f * 1000.0f),
+        static_cast<int>(wheel_position * 1000.0f));
   } else if (i == 200) {
-#ifdef DO_CONTROLS
+#if DO_CONTROLS
     printf("out %" PRIu32 " %" PRIu32 " %" PRIu32 "\n", switching_points[0],
            switching_points[1], switching_points[2]);
 #else
diff --git a/motors/motor.h b/motors/motor.h
index 8161f5e..c59458c 100644
--- a/motors/motor.h
+++ b/motors/motor.h
@@ -63,24 +63,50 @@
   void set_switching_divisor(int switching_divisor) {
     switching_divisor_ = switching_divisor;
   }
-  void set_encoder_offset(int encoder_offset) {
+  void set_encoder_offset(int32_t encoder_offset) {
     encoder_offset_ = encoder_offset;
+    last_wrapped_encoder_reading_ = wrapped_encoder();
+  }
+  int32_t encoder_offset() const { return encoder_offset_; }
+
+  void set_encoder_calibration_offset(int encoder_offset) {
+    encoder_calibration_offset_ = encoder_offset;
     // Add mechanical_counts_per_revolution to the offset so that when we mod
     // below, we are guaranteed to be > 0 regardless of the encoder multiplier.
     // % isn't well-defined with negative numbers.
-    while (encoder_offset_ < controls_->mechanical_counts_per_revolution()) {
-      encoder_offset_ += controls_->mechanical_counts_per_revolution();
+    while (encoder_calibration_offset_ <
+           controls_->mechanical_counts_per_revolution()) {
+      encoder_calibration_offset_ +=
+          controls_->mechanical_counts_per_revolution();
     }
   }
   void set_encoder_multiplier(int encoder_multiplier) {
     encoder_multiplier_ = encoder_multiplier;
   }
 
+  int32_t absolute_encoder(uint32_t wrapped_encoder_reading) {
+    const uint32_t counts_per_revolution =
+        controls_->mechanical_counts_per_revolution();
+    const uint32_t wrap_down = counts_per_revolution / 4;
+    const uint32_t wrap_up = wrap_down * 3;
+    if (last_wrapped_encoder_reading_ > wrap_up &&
+        wrapped_encoder_reading < wrap_down) {
+      encoder_offset_ += counts_per_revolution;
+    } else if (last_wrapped_encoder_reading_ < wrap_down &&
+               wrapped_encoder_reading > wrap_up) {
+      encoder_offset_ -= counts_per_revolution;
+    }
+
+    last_wrapped_encoder_reading_ = wrapped_encoder_reading;
+
+    return static_cast<int32_t>(wrapped_encoder_reading) + encoder_offset_;
+  }
+
   int encoder() {
     return encoder_multiplier_ * encoder_ftm_->CNT;
   }
   uint32_t wrapped_encoder() {
-    return (encoder() + encoder_offset_) %
+    return (encoder() + encoder_calibration_offset_) %
            controls_->mechanical_counts_per_revolution();
   }
 
@@ -148,8 +174,10 @@
   float goal_current_ = 0;
   uint32_t last_current_set_time_ = 0;
   int switching_divisor_ = 1;
-  int encoder_offset_ = 0;
+  int encoder_calibration_offset_ = 0;
+  int32_t encoder_offset_ = 0;
   int encoder_multiplier_ = 1;
+  uint32_t last_wrapped_encoder_reading_ = 0;
 
   teensy::AcmTty *debug_tty_ = nullptr;
 };
diff --git a/motors/peripheral/adc.cc b/motors/peripheral/adc.cc
index 0f5d947..7232a45 100644
--- a/motors/peripheral/adc.cc
+++ b/motors/peripheral/adc.cc
@@ -116,6 +116,19 @@
   PORTC_PCR9 = PORT_PCR_MUX(0);
 }
 
+void AdcInitJoystick() {
+  AdcInitCommon();
+
+  // ANALOG0 ADC0_SE5b
+  PORTD_PCR1 = PORT_PCR_MUX(0);
+  // ANALOG1 ADC0_SE14
+  PORTC_PCR0 = PORT_PCR_MUX(0);
+  // ANALOG2 ADC0_SE13
+  PORTB_PCR3 = PORT_PCR_MUX(0);
+  // ANALOG3 ADC0_SE12
+  PORTB_PCR2 = PORT_PCR_MUX(0);
+}
+
 MediumAdcReadings AdcReadMedium(const DisableInterrupts &) {
   MediumAdcReadings r;
 
@@ -212,5 +225,28 @@
   return r;
 }
 
+JoystickAdcReadings AdcReadJoystick(const DisableInterrupts &) {
+  JoystickAdcReadings r;
+
+  ADC0_SC1A = 5;
+  while (!(ADC0_SC1A & ADC_SC1_COCO)) {
+  }
+  ADC0_SC1A = 14;
+  r.analog0 = ADC0_RA;
+  while (!(ADC0_SC1A & ADC_SC1_COCO)) {
+  }
+  ADC0_SC1A = 13;
+  r.analog1 = ADC0_RA;
+  while (!(ADC0_SC1A & ADC_SC1_COCO)) {
+  }
+  ADC0_SC1A = 12;
+  r.analog2 = ADC0_RA;
+  while (!(ADC0_SC1A & ADC_SC1_COCO)) {
+  }
+  r.analog3 = ADC0_RA;
+
+  return r;
+}
+
 }  // namespace salsa
 }  // namespace frc971
diff --git a/motors/peripheral/adc.h b/motors/peripheral/adc.h
index f9ec22a..d855acf 100644
--- a/motors/peripheral/adc.h
+++ b/motors/peripheral/adc.h
@@ -24,13 +24,19 @@
   uint16_t wheel_abs;
 };
 
+struct JoystickAdcReadings {
+  uint16_t analog0, analog1, analog2, analog3;
+};
+
 void AdcInitMedium();
 void AdcInitSmall();
+void AdcInitJoystick();
 
 MediumAdcReadings AdcReadMedium(const DisableInterrupts &);
 SmallAdcReadings AdcReadSmall0(const DisableInterrupts &);
 SmallAdcReadings AdcReadSmall1(const DisableInterrupts &);
 SmallInitReadings AdcReadSmallInit(const DisableInterrupts &);
+JoystickAdcReadings AdcReadJoystick(const DisableInterrupts &);
 
 }  // namespace salsa
 }  // namespace frc971
diff --git a/motors/peripheral/can.c b/motors/peripheral/can.c
index 0e731e2..62f0398 100644
--- a/motors/peripheral/can.c
+++ b/motors/peripheral/can.c
@@ -19,7 +19,7 @@
 // 16. Using fewer means less for the CAN module (and CPU) to go through looking
 // for actual data.
 // 0 is for sending and 1 is for receiving commands.
-#define NUMBER_MESSAGE_BUFFERS 2
+#define NUMBER_MESSAGE_BUFFERS 4
 
 #if NUMBER_MESSAGE_BUFFERS > 16
 #error Only have 16 message buffers on this part.
@@ -27,11 +27,7 @@
 
 // TODO(Brian): Do something about CAN errors and warnings (enable interrupts?).
 
-// Flags for the interrupt to process which don't actually come from the
-// hardware. Currently, only used for tx buffers.
-static volatile uint32_t can_manual_flags = 0;
-
-void can_init(void) {
+void can_init(uint32_t id0, uint32_t id1) {
   printf("can_init\n");
 
   SIM_SCGC6 |= SIM_SCGC6_FLEXCAN0;
@@ -57,17 +53,29 @@
   // Initialize all the buffers and RX filters we're enabling.
 
   // Just in case this does anything...
-  CAN0_RXIMRS[0] = 0;
-  CAN0_MESSAGES[0].prio_id = 0;
+  CAN0_RXIMRS[2] = 0;
+  CAN0_MESSAGES[2].prio_id = 0;
+  CAN0_MESSAGES[2].control_timestamp =
+      CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_TX_INACTIVE);
+
+  CAN0_RXIMRS[3] = 0;
+  CAN0_MESSAGES[3].prio_id = 0;
+  CAN0_MESSAGES[3].control_timestamp =
+      CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_TX_INACTIVE);
+
+  CAN0_RXIMRS[0] = (1 << 31) /* Want to filter out RTRs. */ |
+                   (0 << 30) /* Want to only get standard frames. */ |
+                   (0x1FFC0000) /* Filter on the id. */;
+  CAN0_MESSAGES[0].prio_id = id0 << 18;
   CAN0_MESSAGES[0].control_timestamp =
-      CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_TX_INACTIVE) | CAN_MB_CONTROL_IDE;
+      CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_RX_EMPTY);
 
   CAN0_RXIMRS[1] = (1 << 31) /* Want to filter out RTRs. */ |
-                   (1 << 30) /* Want to only get extended frames. */ |
-                   0xFF /* Filter on the 1-byte VESC id. */;
-  CAN0_MESSAGES[1].prio_id = 0;
+                   (0 << 30) /* Want to only get standard frames. */ |
+                   (0x1FFC0000) /* Filter on the id. */;
+  CAN0_MESSAGES[1].prio_id = id1 << 18;
   CAN0_MESSAGES[1].control_timestamp =
-      CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_RX_EMPTY) | CAN_MB_CONTROL_IDE;
+      CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_RX_EMPTY);
 
   // Using the oscillator clock directly because it's a reasonable frequency and
   // more stable than the PLL-based peripheral clock, which matters.
@@ -84,13 +92,8 @@
                /* such a fast peripheral clock, this has lots of margin. */ |
                CAN_CTRL2_EACEN /* Match on IDE and RTR. */;
 
-  // Enable interrupts for the RX mailbox.
-  CAN0_IMASK1 = 1 << 1;
-
   // Now take it out of freeze mode.
   CAN0_MCR &= ~CAN_MCR_HALT;
-
-  //NVIC_ENABLE_IRQ(IRQ_CAN_MESSAGE);
 }
 
 static void can_vesc_process_rx(volatile CanMessageBuffer *buffer,
@@ -138,18 +141,21 @@
   (void)prio_id;
 }
 
-int can_send(uint32_t can_id, const unsigned char *data, unsigned int length) {
-  volatile CanMessageBuffer *const message_buffer = &CAN0_MESSAGES[0];
+int can_send(uint32_t can_id, const unsigned char *data, unsigned int length,
+             unsigned int mailbox) {
+  volatile CanMessageBuffer *const message_buffer = &CAN0_MESSAGES[mailbox];
 
-  if (CAN_MB_CONTROL_EXTRACT_CODE(message_buffer->control_timestamp) ==
-      CAN_MB_CODE_TX_DATA) {
-    return -1;
-  }
+  // Just inactivate the mailbox to start with. Checking if it's done being
+  // transmitted doesn't seem to work like the reference manual describes, so
+  // just take the brute force approach.
+  message_buffer->control_timestamp =
+      CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_TX_INACTIVE);
 
   // Yes, it might actually matter that we clear the interrupt flag before
   // doing stuff...
-  CAN0_IFLAG1 = 1 << (message_buffer - CAN0_MESSAGES);
-  message_buffer->prio_id = can_id;
+  CAN0_IFLAG1 = 1 << mailbox;
+
+  message_buffer->prio_id = (can_id << 18);
   // Copy only the bytes from data that we're supposed to onto the stack, and
   // then move it into the message buffer 32 bits at a time (because it might
   // get unhappy about writing individual bytes). Plus, we have to byte-swap
@@ -164,13 +170,14 @@
     message_buffer->data[0] = __builtin_bswap32(data_words[0]);
     message_buffer->data[1] = __builtin_bswap32(data_words[1]);
   }
+  // TODO(Brian): Set IDE and SRR for extended frames.
   message_buffer->control_timestamp =
-      CAN_MB_CONTROL_INSERT_DLC(length) | CAN_MB_CONTROL_SRR |
-      CAN_MB_CONTROL_IDE | CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_TX_DATA);
+      CAN_MB_CONTROL_INSERT_DLC(length) |
+      CAN_MB_CONTROL_INSERT_CODE(CAN_MB_CODE_TX_DATA);
   return 0;
 }
 
-void can_receive_command(unsigned char *data, int *length) {
+void can_receive_command(unsigned char *data, int *length, int mailbox) {
   if (0) {
     static int i = 0;
     if (i++ == 10000) {
@@ -179,9 +186,9 @@
       i = 0;
     }
   }
-  if ((CAN0_IFLAG1 & (1 << 1)) == 0) {
+  if ((CAN0_IFLAG1 & (1 << mailbox)) == 0) {
     *length = -1;
     return;
   }
-  can_vesc_process_rx(&CAN0_MESSAGES[1], data, length);
+  can_vesc_process_rx(&CAN0_MESSAGES[mailbox], data, length);
 }
diff --git a/motors/peripheral/can.h b/motors/peripheral/can.h
index acd6cce..54bdce8 100644
--- a/motors/peripheral/can.h
+++ b/motors/peripheral/can.h
@@ -10,12 +10,15 @@
 extern "C" {
 #endif
 
-void can_init(void);
+void can_init(uint32_t id0, uint32_t id1);
 
-int can_send(uint32_t can_id, const unsigned char *data, unsigned int length);
+// Mailbox is 2 or 3 for the two send mailboxes.
+int can_send(uint32_t can_id, const unsigned char *data, unsigned int length,
+             unsigned int mailbox);
 
 // Sets *length to -1 if there isn't a new piece of data to receive.
-void can_receive_command(unsigned char *data, int *length);
+// Mailbox is 0 or 1 for the two receive mailboxes.
+void can_receive_command(unsigned char *data, int *length, int mailbox);
 
 #ifdef __cplusplus
 }
diff --git a/motors/pistol_grip/BUILD b/motors/pistol_grip/BUILD
index 9eda585..503291f 100644
--- a/motors/pistol_grip/BUILD
+++ b/motors/pistol_grip/BUILD
@@ -24,6 +24,32 @@
 )
 
 cc_binary(
+  name = 'controller.elf',
+  srcs = [
+    'vtable_wheel.cc',
+    'vtable_trigger.cc',
+    'controller.cc',
+  ],
+  deps = [
+    ':motor_controls',
+    '//motors:util',
+    '//motors:motor',
+    '//motors/core',
+    '//motors/peripheral:can',
+    '//motors/peripheral:adc',
+    '//motors/usb',
+    '//motors/usb:cdc',
+    '//frc971/control_loops/drivetrain:haptic_input_uc',
+  ],
+  restricted_to = mcu_cpus,
+)
+
+hex_from_elf(
+  name = 'controller',
+  restricted_to = mcu_cpus,
+)
+
+cc_binary(
   name = 'usb_forward_linux',
   srcs = [
     'usb_forward.cc',
@@ -56,3 +82,21 @@
   ]),
   output_to_bindir = True,
 )
+
+cc_library(
+  name = 'motor_controls',
+  visibility = ['//visibility:public'],
+  hdrs = [
+    'motor_controls.h',
+  ],
+  srcs = [
+    'motor_controls.cc',
+  ],
+  deps = [
+    '//motors:math',
+    '//motors:motor',
+    '//motors/peripheral:configuration',
+    '//third_party/eigen',
+  ],
+  restricted_to = mcu_cpus,
+)
diff --git a/motors/pistol_grip/controller.cc b/motors/pistol_grip/controller.cc
new file mode 100644
index 0000000..4460355
--- /dev/null
+++ b/motors/pistol_grip/controller.cc
@@ -0,0 +1,849 @@
+#include "motors/core/kinetis.h"
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include <atomic>
+#include <cmath>
+
+#include "motors/core/time.h"
+#include "motors/motor.h"
+#include "motors/peripheral/adc.h"
+#include "motors/peripheral/can.h"
+#include "motors/pistol_grip/motor_controls.h"
+#include "motors/usb/cdc.h"
+#include "motors/usb/usb.h"
+#include "motors/util.h"
+#include "frc971/control_loops/drivetrain/integral_haptic_wheel.h"
+#include "frc971/control_loops/drivetrain/integral_haptic_trigger.h"
+
+#define MOTOR0_PWM_FTM FTM3
+#define MOTOR0_ENCODER_FTM FTM2
+#define MOTOR1_PWM_FTM FTM0
+#define MOTOR1_ENCODER_FTM FTM1
+
+extern const float kWheelCoggingTorque[4096];
+extern const float kTriggerCoggingTorque[4096];
+
+namespace frc971 {
+namespace salsa {
+namespace {
+
+using ::frc971::control_loops::drivetrain::MakeIntegralHapticTriggerPlant;
+using ::frc971::control_loops::drivetrain::MakeIntegralHapticTriggerObserver;
+using ::frc971::control_loops::drivetrain::MakeIntegralHapticWheelPlant;
+using ::frc971::control_loops::drivetrain::MakeIntegralHapticWheelObserver;
+
+constexpr float kHapticWheelCurrentLimit = static_cast<float>(
+    ::frc971::control_loops::drivetrain::kHapticWheelCurrentLimit);
+constexpr float kHapticTriggerCurrentLimit = static_cast<float>(
+    ::frc971::control_loops::drivetrain::kHapticTriggerCurrentLimit);
+
+::std::atomic<Motor *> global_motor0{nullptr}, global_motor1{nullptr};
+::std::atomic<teensy::AcmTty *> global_stdout{nullptr};
+
+// Angle last time the current loop ran.
+::std::atomic<float> global_wheel_angle{0.0f};
+::std::atomic<float> global_trigger_angle{0.0f};
+
+// Wheel observer/plant.
+::std::atomic<StateFeedbackObserver<3, 1, 1, float> *> global_wheel_observer{
+    nullptr};
+::std::atomic<StateFeedbackPlant<3, 1, 1, float> *> global_wheel_plant{nullptr};
+// Throttle observer/plant.
+::std::atomic<StateFeedbackObserver<3, 1, 1, float> *> global_trigger_observer{
+    nullptr};
+::std::atomic<StateFeedbackPlant<3, 1, 1, float> *> global_trigger_plant{
+    nullptr};
+
+// Torques for the current loop to apply.
+::std::atomic<float> global_wheel_current{0.0f};
+::std::atomic<float> global_trigger_torque{0.0f};
+
+constexpr int kSwitchingDivisor = 2;
+
+float analog_ratio(uint16_t reading) {
+  static constexpr uint16_t kMin = 260, kMax = 3812;
+  return static_cast<float>(::std::max(::std::min(reading, kMax), kMin) -
+                            kMin) /
+         static_cast<float>(kMax - kMin);
+}
+
+constexpr float InterpolateFloat(float x1, float x0, float y1, float y0, float x) {
+  return (x - x0) * (y1 - y0) / (x1 - x0) + y0;
+}
+
+float absolute_wheel(float wheel_position) {
+  if (wheel_position < 0.43f) {
+    wheel_position += 1.0f;
+  }
+  wheel_position -= 0.462f + 0.473f;
+  return wheel_position;
+}
+
+extern "C" {
+
+void *__stack_chk_guard = (void *)0x67111971;
+void __stack_chk_fail() {
+  while (true) {
+    GPIOC_PSOR = (1 << 5);
+    printf("Stack corruption detected\n");
+    delay(1000);
+    GPIOC_PCOR = (1 << 5);
+    delay(1000);
+  }
+}
+
+int _write(int /*file*/, char *ptr, int len) {
+  teensy::AcmTty *const tty = global_stdout.load(::std::memory_order_acquire);
+  if (tty != nullptr) {
+    return tty->Write(ptr, len);
+  }
+  return 0;
+}
+
+extern uint32_t __bss_ram_start__[], __bss_ram_end__[];
+extern uint32_t __data_ram_start__[], __data_ram_end__[];
+extern uint32_t __heap_start__[], __heap_end__[];
+extern uint32_t __stack_end__[];
+
+}  // extern "C"
+
+constexpr float kWheelMaxExtension = 1.0f;
+constexpr float kWheelFrictionMax = 0.2f;
+float WheelCenteringCurrent(float scalar, float angle, float velocity) {
+  float friction_goal_current = -angle * 10.0f;
+  if (friction_goal_current > kWheelFrictionMax) {
+    friction_goal_current = kWheelFrictionMax;
+  } else if (friction_goal_current < -kWheelFrictionMax) {
+    friction_goal_current = -kWheelFrictionMax;
+  }
+
+  constexpr float kWheelSpringNonlinearity = 0.45f;
+
+  float goal_current = -((1.0f - kWheelSpringNonlinearity) * angle +
+                         kWheelSpringNonlinearity * angle * angle * angle) *
+                           6.0f -
+                       velocity * 0.04f;
+  if (goal_current > 5.0f - scalar) {
+    goal_current = 5.0f - scalar;
+  } else if (goal_current < -5.0f + scalar) {
+    goal_current = -5.0f + scalar;
+  }
+
+  return goal_current * scalar + friction_goal_current;
+}
+
+extern "C" void ftm0_isr() {
+  SmallAdcReadings readings;
+  {
+    DisableInterrupts disable_interrupts;
+    readings = AdcReadSmall1(disable_interrupts);
+  }
+  uint32_t encoder =
+      global_motor1.load(::std::memory_order_relaxed)->wrapped_encoder();
+  int32_t absolute_encoder = global_motor1.load(::std::memory_order_relaxed)
+                                 ->absolute_encoder(encoder);
+
+  const float angle = absolute_encoder / static_cast<float>((15320 - 1488) / 2);
+  global_wheel_angle.store(angle);
+
+  float goal_current = -global_wheel_current.load(::std::memory_order_relaxed) +
+                       kWheelCoggingTorque[encoder];
+
+  global_motor1.load(::std::memory_order_relaxed)->SetGoalCurrent(goal_current);
+  global_motor1.load(::std::memory_order_relaxed)
+      ->HandleInterrupt(BalanceSimpleReadings(readings.currents), encoder);
+}
+
+constexpr float kTriggerMaxExtension = -1.00f;
+constexpr float kTriggerCenter = 0.0f;
+float TriggerCenteringCurrent(float trigger_angle) {
+  float goal_current = (kTriggerCenter - trigger_angle) * 3.0f;
+  if (goal_current < -1.0f) {
+    goal_current = -1.0f;
+  } else if (goal_current > 1.0f) {
+    goal_current = 1.0f;
+    if (trigger_angle < kTriggerMaxExtension) {
+      goal_current -= (30.0f * (trigger_angle - kTriggerMaxExtension));
+      if (goal_current > 2.0f) {
+        goal_current = 2.0f;
+      }
+    }
+  }
+  return goal_current;
+}
+
+extern "C" void ftm3_isr() {
+  SmallAdcReadings readings;
+  {
+    DisableInterrupts disable_interrupts;
+    readings = AdcReadSmall0(disable_interrupts);
+  }
+  uint32_t encoder =
+      global_motor0.load(::std::memory_order_relaxed)->wrapped_encoder();
+  int32_t absolute_encoder = global_motor0.load(::std::memory_order_relaxed)
+                                 ->absolute_encoder(encoder);
+
+  float trigger_angle = absolute_encoder / 1370.f;
+
+  const float goal_current =
+      -global_trigger_torque.load(::std::memory_order_relaxed) +
+      kTriggerCoggingTorque[encoder];
+
+  global_motor0.load(::std::memory_order_relaxed)->SetGoalCurrent(goal_current);
+  global_motor0.load(::std::memory_order_relaxed)
+      ->HandleInterrupt(BalanceSimpleReadings(readings.currents), encoder);
+
+
+  global_trigger_angle.store(trigger_angle);
+}
+
+
+int ConvertFloat16(float val) {
+  int result = static_cast<int>(val * 32768.0f) + 32768;
+  if (result > 0xffff) {
+    result = 0xffff;
+  } else if (result < 0) {
+    result = 0;
+  }
+  return result;
+}
+int ConvertFloat14(float val) {
+  int result = static_cast<int>(val * 8192.0f) + 8192;
+  if (result > 0x3fff) {
+    result = 0x3fff;
+  } else if (result < 0) {
+    result = 0;
+  }
+  return result;
+}
+
+extern "C" void pit3_isr() {
+  PIT_TFLG3 = 1;
+  const float absolute_trigger_angle =
+      global_trigger_angle.load(::std::memory_order_relaxed);
+  const float absolute_wheel_angle =
+      global_wheel_angle.load(::std::memory_order_relaxed);
+
+  // Force a barrier here so we sample everything guaranteed at the beginning.
+  __asm__("" ::: "memory");
+  const float absolute_wheel_angle_radians =
+      absolute_wheel_angle * static_cast<float>(M_PI) * (338.16f / 360.0f);
+  const float absolute_trigger_angle_radians =
+      absolute_trigger_angle * static_cast<float>(M_PI) * (45.0f / 360.0f);
+
+  static uint32_t last_command_time = 0;
+  static float trigger_goal_position = 0.0f;
+  static float trigger_goal_velocity = 0.0f;
+  static float trigger_haptic_current = 0.0f;
+  static bool trigger_centering = true;
+  static bool trigger_haptics = false;
+  {
+    uint8_t data[8];
+    int length;
+    can_receive_command(data, &length, 0);
+    if (length > 0) {
+      last_command_time = micros();
+      trigger_goal_position =
+          static_cast<float>(
+              static_cast<int32_t>(static_cast<uint32_t>(data[0]) |
+                                   (static_cast<uint32_t>(data[1]) << 8)) -
+              32768) /
+          32768.0f * M_PI / 8.0;
+      trigger_goal_velocity =
+          static_cast<float>(
+              static_cast<int32_t>(static_cast<uint32_t>(data[2]) |
+                                   (static_cast<uint32_t>(data[3]) << 8)) -
+              32768) /
+          32768.0f * 4.0f;
+
+      trigger_haptic_current =
+          static_cast<float>(
+              static_cast<int32_t>(static_cast<uint32_t>(data[4]) |
+                                   (static_cast<uint32_t>(data[5]) << 8)) -
+              32768) /
+          32768.0f * 2.0f;
+      if (trigger_haptic_current > kHapticTriggerCurrentLimit) {
+        trigger_haptic_current = kHapticTriggerCurrentLimit;
+      } else if (trigger_haptic_current < -kHapticTriggerCurrentLimit) {
+        trigger_haptic_current = -kHapticTriggerCurrentLimit;
+      }
+      trigger_centering = !!(data[7] & 0x01);
+      trigger_haptics = !!(data[7] & 0x02);
+    }
+  }
+
+  static float wheel_goal_position = 0.0f;
+  static float wheel_goal_velocity = 0.0f;
+  static float wheel_haptic_current = 0.0f;
+  static float wheel_kp = 0.0f;
+  static bool wheel_centering = true;
+  static float wheel_centering_scalar = 0.25f;
+  {
+    uint8_t data[8];
+    int length;
+    can_receive_command(data, &length, 1);
+    if (length == 8) {
+      last_command_time = micros();
+      wheel_goal_position =
+          static_cast<float>(
+              static_cast<int32_t>(static_cast<uint32_t>(data[0]) |
+                                   (static_cast<uint32_t>(data[1]) << 8)) -
+              32768) /
+          32768.0f * M_PI;
+      wheel_goal_velocity =
+          static_cast<float>(
+              static_cast<int32_t>(static_cast<uint32_t>(data[2]) |
+                                   (static_cast<uint32_t>(data[3]) << 8)) -
+              32768) /
+          32768.0f * 10.0f;
+
+      wheel_haptic_current =
+          static_cast<float>(
+              static_cast<int32_t>(static_cast<uint32_t>(data[4]) |
+                                   (static_cast<uint32_t>(data[5]) << 8)) -
+              32768) /
+          32768.0f * 2.0f;
+      if (wheel_haptic_current > kHapticWheelCurrentLimit) {
+        wheel_haptic_current = kHapticWheelCurrentLimit;
+      } else if (wheel_haptic_current < -kHapticWheelCurrentLimit) {
+        wheel_haptic_current = -kHapticWheelCurrentLimit;
+      }
+      wheel_kp = static_cast<float>(data[6]) * 30.0f / 255.0f;
+      wheel_centering = !!(data[7] & 0x01);
+      wheel_centering_scalar = ((data[7] >> 1) & 0x7f) / 127.0f;
+    }
+  }
+
+  static constexpr uint32_t kTimeout = 100000;
+  if (!time_after(time_add(last_command_time, kTimeout), micros())) {
+    last_command_time = time_subtract(micros(), kTimeout);
+    trigger_goal_position = 0.0f;
+    trigger_goal_velocity = 0.0f;
+    trigger_haptic_current = 0.0f;
+    trigger_centering = true;
+    trigger_haptics = false;
+
+    wheel_goal_position = 0.0f;
+    wheel_goal_velocity = 0.0f;
+    wheel_haptic_current = 0.0f;
+    wheel_centering = true;
+    wheel_centering_scalar = 0.25f;
+  }
+
+  StateFeedbackPlant<3, 1, 1, float> *const trigger_plant =
+      global_trigger_plant.load(::std::memory_order_relaxed);
+  StateFeedbackObserver<3, 1, 1, float> *const trigger_observer =
+      global_trigger_observer.load(::std::memory_order_relaxed);
+  ::Eigen::Matrix<float, 1, 1> trigger_Y;
+  trigger_Y << absolute_trigger_angle_radians;
+  trigger_observer->Correct(*trigger_plant,
+                            ::Eigen::Matrix<float, 1, 1>::Zero(), trigger_Y);
+
+  StateFeedbackPlant<3, 1, 1, float> *const wheel_plant =
+      global_wheel_plant.load(::std::memory_order_relaxed);
+  StateFeedbackObserver<3, 1, 1, float> *const wheel_observer =
+      global_wheel_observer.load(::std::memory_order_relaxed);
+  ::Eigen::Matrix<float, 1, 1> wheel_Y;
+  wheel_Y << absolute_wheel_angle_radians;
+  wheel_observer->Correct(*wheel_plant, ::Eigen::Matrix<float, 1, 1>::Zero(),
+                          wheel_Y);
+
+  float kWheelD = (wheel_kp - 10.0f) * (0.25f - 0.20f) / 5.0f + 0.20f;
+  if (wheel_kp < 0.5f) {
+    kWheelD = wheel_kp * 0.05f / 0.5f;
+  } else if (wheel_kp < 1.0f) {
+    kWheelD = InterpolateFloat(1.0f, 0.5f, 0.06f, 0.05f, wheel_kp);
+  } else if (wheel_kp < 2.0f) {
+    kWheelD = InterpolateFloat(2.0f, 1.0f, 0.08f, 0.06f, wheel_kp);
+  } else if (wheel_kp < 3.0f) {
+    kWheelD = InterpolateFloat(3.0f, 2.0f, 0.10f, 0.08f, wheel_kp);
+  } else if (wheel_kp < 5.0f) {
+    kWheelD = InterpolateFloat(5.0f, 3.0f, 0.13f, 0.10f, wheel_kp);
+  } else if (wheel_kp < 10.0f) {
+    kWheelD = InterpolateFloat(10.0f, 5.0f, 0.20f, 0.13f, wheel_kp);
+  }
+
+  float wheel_goal_current = wheel_haptic_current;
+
+  wheel_goal_current +=
+      (wheel_goal_position - absolute_wheel_angle_radians) * wheel_kp +
+      (wheel_goal_velocity - wheel_observer->X_hat()(1, 0)) * kWheelD;
+
+  // Compute the torques to apply to each motor.
+  if (wheel_centering) {
+    wheel_goal_current +=
+        WheelCenteringCurrent(wheel_centering_scalar, absolute_wheel_angle,
+                              wheel_observer->X_hat()(1, 0));
+  }
+
+  if (wheel_goal_current > kHapticWheelCurrentLimit) {
+    wheel_goal_current = kHapticWheelCurrentLimit;
+  } else if (wheel_goal_current < -kHapticWheelCurrentLimit) {
+    wheel_goal_current = -kHapticWheelCurrentLimit;
+  }
+  global_wheel_current.store(wheel_goal_current, ::std::memory_order_relaxed);
+
+  constexpr float kTriggerP =
+      static_cast<float>(::frc971::control_loops::drivetrain::kHapticTriggerP);
+  constexpr float kTriggerD =
+      static_cast<float>(::frc971::control_loops::drivetrain::kHapticTriggerD);
+  float trigger_goal_current = trigger_haptic_current;
+  if (trigger_haptics) {
+    trigger_goal_current +=
+        (trigger_goal_position - absolute_trigger_angle_radians) * kTriggerP +
+        (trigger_goal_velocity - trigger_observer->X_hat()(1, 0)) * kTriggerD;
+  }
+
+  if (trigger_centering) {
+    trigger_goal_current += TriggerCenteringCurrent(absolute_trigger_angle);
+  }
+
+  if (trigger_goal_current > kHapticTriggerCurrentLimit) {
+    trigger_goal_current = kHapticTriggerCurrentLimit;
+  } else if (trigger_goal_current < -kHapticTriggerCurrentLimit) {
+    trigger_goal_current = -kHapticTriggerCurrentLimit;
+  }
+  global_trigger_torque.store(trigger_goal_current,
+                              ::std::memory_order_relaxed);
+
+  uint8_t buttons = 0;
+  if (!GPIO_BITBAND(GPIOA_PDIR, 14)) {
+    buttons |= 0x1;
+  }
+  if (!GPIO_BITBAND(GPIOE_PDIR, 26)) {
+    buttons |= 0x2;
+  }
+  if (!GPIO_BITBAND(GPIOC_PDIR, 7)) {
+    buttons |= 0x4;
+  }
+  if (!GPIO_BITBAND(GPIOD_PDIR, 0)) {
+    buttons |= 0x8;
+  }
+
+  float trigger_angle = absolute_trigger_angle;
+
+  // Adjust the trigger range for reporting back.
+  // TODO(austin): We'll likely need to make this symmetric for the controls to
+  // work out well.
+  if (trigger_angle > kTriggerCenter) {
+    trigger_angle = (trigger_angle - kTriggerCenter) / (1.0f - kTriggerCenter);
+  } else {
+    trigger_angle = (trigger_angle - kTriggerCenter) /
+                    (kTriggerCenter - kTriggerMaxExtension);
+  }
+
+  // TODO(austin): Class + fns.  This is a mess.
+  // TODO(austin): Move this to a separate file.  It's too big.
+  int can_trigger = ConvertFloat16(absolute_trigger_angle);
+  int can_trigger_velocity =
+      ConvertFloat16(trigger_observer->X_hat()(1, 0) / 50.0f);
+  int can_trigger_torque =
+      ConvertFloat16(trigger_observer->X_hat()(2, 0) * 2.0f);
+  int can_trigger_current = ConvertFloat14(trigger_goal_current / 10.0f);
+
+  int can_wheel = ConvertFloat16(absolute_wheel_angle);
+  int can_wheel_velocity =
+      ConvertFloat16(wheel_observer->X_hat()(1, 0) / 50.0f);
+  int can_wheel_torque = ConvertFloat16(wheel_observer->X_hat()(2, 0) * 2.0f);
+  int can_wheel_current = ConvertFloat14(wheel_goal_current / 10.0f);
+
+  {
+    const uint8_t trigger_joystick_values[8] = {
+        static_cast<uint8_t>(can_trigger & 0xff),
+        static_cast<uint8_t>((can_trigger >> 8) & 0xff),
+        static_cast<uint8_t>(can_trigger_velocity & 0xff),
+        static_cast<uint8_t>((can_trigger_velocity >> 8) & 0xff),
+        static_cast<uint8_t>(can_trigger_torque & 0xff),
+        static_cast<uint8_t>((can_trigger_torque >> 8) & 0xff),
+        static_cast<uint8_t>(can_trigger_current & 0xff),
+        static_cast<uint8_t>(((buttons & 0x3) << 6) |
+                             (can_trigger_current >> 8))};
+    const uint8_t wheel_joystick_values[8] = {
+        static_cast<uint8_t>(can_wheel & 0xff),
+        static_cast<uint8_t>((can_wheel >> 8) & 0xff),
+        static_cast<uint8_t>(can_wheel_velocity & 0xff),
+        static_cast<uint8_t>((can_wheel_velocity >> 8) & 0xff),
+        static_cast<uint8_t>(can_wheel_torque & 0xff),
+        static_cast<uint8_t>((can_wheel_torque >> 8) & 0xff),
+        static_cast<uint8_t>(can_wheel_current & 0xff),
+        static_cast<uint8_t>(((buttons & 0xc) << 4) |
+                             (can_wheel_current >> 8))};
+
+    can_send(0, trigger_joystick_values, 8, 2);
+    can_send(1, wheel_joystick_values, 8, 3);
+  }
+
+  ::Eigen::Matrix<float, 1, 1> trigger_U;
+  trigger_U << trigger_goal_current;
+  ::Eigen::Matrix<float, 1, 1> wheel_U;
+  wheel_U << wheel_goal_current;
+  trigger_observer->Predict(trigger_plant, trigger_U,
+                            ::std::chrono::milliseconds(1));
+  wheel_observer->Predict(wheel_plant, wheel_U, ::std::chrono::milliseconds(1));
+}
+
+void ConfigurePwmFtm(BigFTM *pwm_ftm) {
+  // Put them all into combine active-high mode, and all the low ones staying
+  // off all the time by default. We'll then use only the low ones.
+  pwm_ftm->C0SC = FTM_CSC_ELSB;
+  pwm_ftm->C0V = 0;
+  pwm_ftm->C1SC = FTM_CSC_ELSB;
+  pwm_ftm->C1V = 0;
+  pwm_ftm->C2SC = FTM_CSC_ELSB;
+  pwm_ftm->C2V = 0;
+  pwm_ftm->C3SC = FTM_CSC_ELSB;
+  pwm_ftm->C3V = 0;
+  pwm_ftm->C4SC = FTM_CSC_ELSB;
+  pwm_ftm->C4V = 0;
+  pwm_ftm->C5SC = FTM_CSC_ELSB;
+  pwm_ftm->C5V = 0;
+  pwm_ftm->C6SC = FTM_CSC_ELSB;
+  pwm_ftm->C6V = 0;
+  pwm_ftm->C7SC = FTM_CSC_ELSB;
+  pwm_ftm->C7V = 0;
+
+  pwm_ftm->COMBINE = FTM_COMBINE_SYNCEN3 /* Synchronize updates usefully */ |
+                     FTM_COMBINE_COMP3 /* Make them complementary */ |
+                     FTM_COMBINE_COMBINE3 /* Combine the channels */ |
+                     FTM_COMBINE_SYNCEN2 /* Synchronize updates usefully */ |
+                     FTM_COMBINE_COMP2 /* Make them complementary */ |
+                     FTM_COMBINE_COMBINE2 /* Combine the channels */ |
+                     FTM_COMBINE_SYNCEN1 /* Synchronize updates usefully */ |
+                     FTM_COMBINE_COMP1 /* Make them complementary */ |
+                     FTM_COMBINE_COMBINE1 /* Combine the channels */ |
+                     FTM_COMBINE_SYNCEN0 /* Synchronize updates usefully */ |
+                     FTM_COMBINE_COMP0 /* Make them complementary */ |
+                     FTM_COMBINE_COMBINE0 /* Combine the channels */;
+}
+
+bool CountValid(uint32_t count) {
+  static constexpr int kMaxMovement = 1;
+  return count <= kMaxMovement || count >= (4096 - kMaxMovement);
+}
+
+bool ZeroMotors(uint16_t *motor0_offset, uint16_t *motor1_offset,
+                uint16_t *wheel_offset) {
+  static constexpr int kNumberSamples = 1024;
+  static_assert(UINT16_MAX * kNumberSamples <= UINT32_MAX, "Too many samples");
+  uint32_t motor0_sum = 0, motor1_sum = 0, wheel_sum = 0;
+
+  // First clear both encoders.
+  MOTOR0_ENCODER_FTM->CNT = MOTOR1_ENCODER_FTM->CNT = 0;
+  for (int i = 0; i < kNumberSamples; ++i) {
+    delay(1);
+
+    if (!CountValid(MOTOR0_ENCODER_FTM->CNT)) {
+      printf("Motor 0 moved too much\n");
+      return false;
+    }
+    if (!CountValid(MOTOR1_ENCODER_FTM->CNT)) {
+      printf("Motor 1 moved too much\n");
+      return false;
+    }
+
+    DisableInterrupts disable_interrupts;
+    const SmallInitReadings readings = AdcReadSmallInit(disable_interrupts);
+    motor0_sum += readings.motor0_abs;
+    motor1_sum += readings.motor1_abs;
+    wheel_sum += readings.wheel_abs;
+  }
+
+  *motor0_offset = (motor0_sum + kNumberSamples / 2) / kNumberSamples;
+  *motor1_offset = (motor1_sum + kNumberSamples / 2) / kNumberSamples;
+  *wheel_offset = (wheel_sum + kNumberSamples / 2) / kNumberSamples;
+
+  return true;
+}
+
+}  // namespace
+
+extern "C" int main() {
+  // for background about this startup delay, please see these conversations
+  // https://forum.pjrc.com/threads/36606-startup-time-(400ms)?p=113980&viewfull=1#post113980
+  // https://forum.pjrc.com/threads/31290-Teensey-3-2-Teensey-Loader-1-24-Issues?p=87273&viewfull=1#post87273
+  delay(400);
+
+  // Set all interrupts to the second-lowest priority to start with.
+  for (int i = 0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_SANE_PRIORITY(i, 0xD);
+
+  // Now set priorities for all the ones we care about. They only have meaning
+  // relative to each other, which means centralizing them here makes it a lot
+  // more manageable.
+  NVIC_SET_SANE_PRIORITY(IRQ_USBOTG, 0x7);
+  NVIC_SET_SANE_PRIORITY(IRQ_FTM0, 0x3);
+  NVIC_SET_SANE_PRIORITY(IRQ_FTM3, 0x3);
+  NVIC_SET_SANE_PRIORITY(IRQ_PIT_CH3, 0x5);
+
+  // Set the LED's pin to output mode.
+  GPIO_BITBAND(GPIOC_PDDR, 5) = 1;
+  PORTC_PCR5 = PORT_PCR_DSE | PORT_PCR_MUX(1);
+
+  // Set up the CAN pins.
+  PORTA_PCR12 = PORT_PCR_DSE | PORT_PCR_MUX(2);
+  PORTA_PCR13 = PORT_PCR_DSE | PORT_PCR_MUX(2);
+
+  // BTN0
+  PORTC_PCR7 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
+  // BTN1
+  PORTE_PCR26 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
+  // BTN2
+  PORTA_PCR14 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
+  // BTN3
+  PORTD_PCR0 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
+
+  PORTA_PCR5 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
+
+  DMA_CR = DMA_CR_EMLM;
+
+  teensy::UsbDevice usb_device(0, 0x16c0, 0x0490);
+  usb_device.SetManufacturer("FRC 971 Spartan Robotics");
+  usb_device.SetProduct("Pistol Grip Controller debug");
+  teensy::AcmTty tty1(&usb_device);
+  teensy::AcmTty tty2(&usb_device);
+  global_stdout.store(&tty1, ::std::memory_order_release);
+  usb_device.Initialize();
+
+  AdcInitSmall();
+  MathInit();
+  delay(100);
+  can_init(2, 3);
+
+  GPIOD_PCOR = 1 << 3;
+  GPIO_BITBAND(GPIOD_PDDR, 3) = 1;
+  PORTD_PCR3 = PORT_PCR_DSE | PORT_PCR_MUX(1);
+  GPIOD_PSOR = 1 << 3;
+
+  GPIOC_PCOR = 1 << 4;
+  GPIO_BITBAND(GPIOC_PDDR, 4) = 1;
+  PORTC_PCR4 = PORT_PCR_DSE | PORT_PCR_MUX(1);
+  GPIOC_PSOR = 1 << 4;
+
+  LittleMotorControlsImplementation controls0, controls1;
+
+  delay(100);
+
+  // M0_EA = FTM1_QD_PHB
+  PORTB_PCR19 = PORT_PCR_MUX(6);
+  // M0_EB = FTM1_QD_PHA
+  PORTB_PCR18 = PORT_PCR_MUX(6);
+
+  // M1_EA = FTM1_QD_PHA
+  PORTB_PCR0 = PORT_PCR_MUX(6);
+  // M1_EB = FTM1_QD_PHB
+  PORTB_PCR1 = PORT_PCR_MUX(6);
+
+  // M0_CH0 = FTM3_CH4
+  PORTC_PCR8 = PORT_PCR_DSE | PORT_PCR_MUX(3);
+  // M0_CH1 = FTM3_CH2
+  PORTD_PCR2 = PORT_PCR_DSE | PORT_PCR_MUX(4);
+  // M0_CH2 = FTM3_CH6
+  PORTC_PCR10 = PORT_PCR_DSE | PORT_PCR_MUX(3);
+
+  // M1_CH0 = FTM0_CH0
+  PORTC_PCR1 = PORT_PCR_DSE | PORT_PCR_MUX(4);
+  // M1_CH1 = FTM0_CH2
+  PORTC_PCR3 = PORT_PCR_DSE | PORT_PCR_MUX(4);
+  // M1_CH2 = FTM0_CH4
+  PORTD_PCR4 = PORT_PCR_DSE | PORT_PCR_MUX(4);
+
+  Motor motor0(
+      MOTOR0_PWM_FTM, MOTOR0_ENCODER_FTM, &controls0,
+      {&MOTOR0_PWM_FTM->C4V, &MOTOR0_PWM_FTM->C2V, &MOTOR0_PWM_FTM->C6V});
+  motor0.set_debug_tty(&tty2);
+  motor0.set_switching_divisor(kSwitchingDivisor);
+  Motor motor1(
+      MOTOR1_PWM_FTM, MOTOR1_ENCODER_FTM, &controls1,
+      {&MOTOR1_PWM_FTM->C0V, &MOTOR1_PWM_FTM->C2V, &MOTOR1_PWM_FTM->C4V});
+  motor1.set_debug_tty(&tty2);
+  motor1.set_switching_divisor(kSwitchingDivisor);
+  ConfigurePwmFtm(MOTOR0_PWM_FTM);
+  ConfigurePwmFtm(MOTOR1_PWM_FTM);
+  motor0.Init();
+  motor1.Init();
+  global_motor0.store(&motor0, ::std::memory_order_relaxed);
+  global_motor1.store(&motor1, ::std::memory_order_relaxed);
+
+  SIM_SCGC6 |= SIM_SCGC6_PIT;
+  PIT_MCR = 0;
+  PIT_LDVAL3 = BUS_CLOCK_FREQUENCY / 1000;
+  PIT_TCTRL3 = PIT_TCTRL_TIE | PIT_TCTRL_TEN;
+
+  // Have them both wait for the GTB signal.
+  FTM0->CONF = FTM3->CONF =
+      FTM_CONF_GTBEEN | FTM_CONF_NUMTOF(kSwitchingDivisor - 1);
+  // Make FTM3's period half of what it should be so we can get it a half-cycle
+  // out of phase.
+  const uint32_t original_mod = FTM3->MOD;
+  FTM3->MOD = ((original_mod + 1) / 2) - 1;
+  FTM3->SYNC |= FTM_SYNC_SWSYNC;
+
+  // Output triggers to things like the PDBs on initialization.
+  FTM0_EXTTRIG = FTM_EXTTRIG_INITTRIGEN;
+  FTM3_EXTTRIG = FTM_EXTTRIG_INITTRIGEN;
+  // Don't let any memory accesses sneak past here, because we actually
+  // need everything to be starting up.
+  __asm__("" ::: "memory");
+
+  // Give everything a chance to get going.
+  delay(100);
+
+  printf("BSS: %p-%p\n", __bss_ram_start__, __bss_ram_end__);
+  printf("data: %p-%p\n", __data_ram_start__, __data_ram_end__);
+  printf("heap start: %p\n", __heap_start__);
+  printf("stack start: %p\n", __stack_end__);
+
+  printf("Zeroing motors\n");
+  uint16_t motor0_offset, motor1_offset, wheel_offset;
+  while (!ZeroMotors(&motor0_offset, &motor1_offset, &wheel_offset)) {
+  }
+  printf("Done zeroing\n");
+
+  const float motor0_offset_scaled = -analog_ratio(motor0_offset);
+  const float motor1_offset_scaled = analog_ratio(motor1_offset);
+  // Good for the initial trigger.
+  {
+    constexpr float kZeroOffset0 = 0.27f;
+    const int motor0_starting_point = static_cast<int>(
+        (motor0_offset_scaled + (kZeroOffset0 / 7.0f)) * 4096.0f);
+    printf("Motor 0 starting at %d\n", motor0_starting_point);
+    motor0.set_encoder_calibration_offset(motor0_starting_point);
+    motor0.set_encoder_multiplier(-1);
+
+    // Calibrate neutral here.
+    motor0.set_encoder_offset(motor0.encoder_offset() - 2065 + 20);
+
+    uint32_t new_encoder = motor0.wrapped_encoder();
+    int32_t absolute_encoder = motor0.absolute_encoder(new_encoder);
+    printf("Motor 0 encoder %d absolute %d\n", static_cast<int>(new_encoder),
+           static_cast<int>(absolute_encoder));
+  }
+
+  {
+    constexpr float kZeroOffset1 = 0.26f;
+    const int motor1_starting_point = static_cast<int>(
+        (motor1_offset_scaled + (kZeroOffset1 / 7.0f)) * 4096.0f);
+    printf("Motor 1 starting at %d\n", motor1_starting_point);
+    motor1.set_encoder_calibration_offset(motor1_starting_point);
+    motor1.set_encoder_multiplier(-1);
+
+    float wheel_position = absolute_wheel(analog_ratio(wheel_offset));
+
+    uint32_t encoder = motor1.wrapped_encoder();
+
+    printf("Wheel starting at %d, encoder %" PRId32 "\n",
+           static_cast<int>(wheel_position * 1000.0f), encoder);
+
+    constexpr float kWheelGearRatio = (1.25f + 0.02f) / 0.35f;
+    constexpr float kWrappedWheelAtZero = 0.6586310546875f;
+
+    const int encoder_wraps =
+        static_cast<int>(lround(wheel_position * kWheelGearRatio -
+                                (encoder / 4096.f) + kWrappedWheelAtZero));
+
+    printf("Wraps: %d\n", encoder_wraps);
+    motor1.set_encoder_offset(4096 * encoder_wraps + motor1.encoder_offset() -
+                              static_cast<int>(kWrappedWheelAtZero * 4096));
+    printf("Wheel encoder now at %d\n",
+           static_cast<int>(1000.f / 4096.f *
+                            motor1.absolute_encoder(motor1.wrapped_encoder())));
+  }
+
+  // Turn an LED on for Austin.
+  GPIO_BITBAND(GPIOC_PDDR, 6) = 1;
+  GPIOC_PCOR = 1 << 6;
+  PORTC_PCR6 = PORT_PCR_DSE | PORT_PCR_MUX(1);
+
+  // M0_THW
+  PORTC_PCR11 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
+  // M0_FAULT
+  PORTD_PCR6 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
+  // M1_THW
+  PORTC_PCR2 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
+  // M1_FAULT
+  PORTD_PCR5 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
+
+  motor0.Start();
+  motor1.Start();
+  {
+    // We rely on various things happening faster than the timer period, so make
+    // sure slow USB or whatever interrupts don't prevent that.
+    DisableInterrupts disable_interrupts;
+
+    // First clear the overflow flag.
+    FTM3->SC &= ~FTM_SC_TOF;
+
+    // Now poke the GTB to actually start both timers.
+    FTM0->CONF = FTM_CONF_GTBEEN | FTM_CONF_GTBEOUT |
+                 FTM_CONF_NUMTOF(kSwitchingDivisor - 1);
+
+    // Wait for it to overflow twice. For some reason, just once doesn't work.
+    while (!(FTM3->SC & FTM_SC_TOF)) {
+    }
+    FTM3->SC &= ~FTM_SC_TOF;
+    while (!(FTM3->SC & FTM_SC_TOF)) {
+    }
+
+    // Now put the MOD value back to what it was.
+    FTM3->MOD = original_mod;
+    FTM3->PWMLOAD = FTM_PWMLOAD_LDOK;
+
+    // And then clear the overflow flags before enabling interrupts so we
+    // actually wait until the next overflow to start doing interrupts.
+    FTM0->SC &= ~FTM_SC_TOF;
+    FTM3->SC &= ~FTM_SC_TOF;
+    NVIC_ENABLE_IRQ(IRQ_FTM0);
+    NVIC_ENABLE_IRQ(IRQ_FTM3);
+  }
+  global_trigger_plant.store(
+      new StateFeedbackPlant<3, 1, 1, float>(MakeIntegralHapticTriggerPlant()));
+  global_trigger_observer.store(new StateFeedbackObserver<3, 1, 1, float>(
+      MakeIntegralHapticTriggerObserver()));
+  global_trigger_observer.load(::std::memory_order_relaxed)
+      ->Reset(global_trigger_plant.load(::std::memory_order_relaxed));
+
+  global_wheel_plant.store(
+      new StateFeedbackPlant<3, 1, 1, float>(MakeIntegralHapticWheelPlant()));
+  global_wheel_observer.store(new StateFeedbackObserver<3, 1, 1, float>(
+      MakeIntegralHapticWheelObserver()));
+  global_wheel_observer.load(::std::memory_order_relaxed)
+      ->Reset(global_wheel_plant.load(::std::memory_order_relaxed));
+
+  delay(1000);
+
+  NVIC_ENABLE_IRQ(IRQ_PIT_CH3);
+
+  // TODO(Brian): Use SLEEPONEXIT to reduce interrupt latency?
+  while (true) {
+    if (!GPIO_BITBAND(GPIOC_PDIR, 11)) {
+      if (!GPIO_BITBAND(GPIOC_PDOR, 5)) {
+        printf("M0_THW\n");
+      }
+      GPIOC_PSOR = 1 << 5;
+    }
+    if (!GPIO_BITBAND(GPIOD_PDIR, 6)) {
+      if (!GPIO_BITBAND(GPIOC_PDOR, 5)) {
+        printf("M0_FAULT\n");
+      }
+      GPIOC_PSOR = 1 << 5;
+    }
+    if (!GPIO_BITBAND(GPIOC_PDIR, 2)) {
+      if (!GPIO_BITBAND(GPIOC_PDOR, 5)) {
+        printf("M1_THW\n");
+      }
+      GPIOC_PSOR = 1 << 5;
+    }
+    if (!GPIO_BITBAND(GPIOD_PDIR, 5)) {
+      if (!GPIO_BITBAND(GPIOC_PDOR, 5)) {
+        printf("M1_FAULT\n");
+      }
+      GPIOC_PSOR = 1 << 5;
+    }
+  }
+
+  return 0;
+}
+
+}  // namespace salsa
+}  // namespace frc971
diff --git a/motors/pistol_grip/drivers_station.cc b/motors/pistol_grip/drivers_station.cc
index 4c68afc..155440a 100644
--- a/motors/pistol_grip/drivers_station.cc
+++ b/motors/pistol_grip/drivers_station.cc
@@ -99,60 +99,134 @@
   }
 }
 
-void MoveJoysticks(teensy::HidFunction *joysticks,
-                   teensy::InterruptOut *interrupt_out) {
-  static uint8_t x_axis = 0, y_axis = 97, z_axis = 5, rz_axis = 8;
-  while (true) {
-    {
-      char buffer[64];
-      if (interrupt_out->ReceiveData(buffer) > 0) {
-        if (buffer[0]) {
-          GPIOC_PCOR = 1 << 5;
-        } else {
-          GPIOC_PSOR = 1 << 5;
-        }
-      }
-
-      DisableInterrupts disable_interrupts;
-      uint8_t buttons = 0;
-      if (x_axis % 8u) {
-        buttons = 2;
-      }
-      uint8_t report[10] = {x_axis,  0, y_axis, 0,       z_axis,
-                            rz_axis, 0, 0,      buttons, 0};
-      joysticks->UpdateReport(report, 10, disable_interrupts);
-    }
-    delay(1);
-    x_axis += 1;
-    y_axis += 3;
-    z_axis += 5;
-    rz_axis += 8;
-  }
-}
-
-void ForwardJoystickData(teensy::HidFunction *joysticks) {
+void ForwardJoystickData(teensy::HidFunction *throttle_joystick,
+                         teensy::HidFunction *wheel_joystick,
+                         teensy::InterruptOut *interrupt_out) {
   uint32_t last_command_time = micros();
+  uint16_t trigger_position = 0x8000;
+  uint16_t wheel_position = 0x8000;
+  uint16_t trigger_velocity = 0x8000;
+  uint16_t wheel_velocity = 0x8000;
+  uint16_t trigger_torque = 0x8000;
+  uint16_t wheel_torque = 0x8000;
+  uint16_t buttons = 0x0080;
   while (true) {
-    uint8_t data[8];
+    bool update_report = false;
+
+    uint8_t can_data[8];
     int length;
-    can_receive_command(data, &length);
-    if (length == 3) {
+    can_receive_command(can_data, &length, 0);
+    if (length == 8) {
       last_command_time = micros();
-      DisableInterrupts disable_interrupts;
-      joysticks->UpdateReport(data, 3, disable_interrupts);
+      trigger_position =
+          static_cast<uint16_t>(static_cast<uint32_t>(can_data[0]) |
+                                (static_cast<uint32_t>(can_data[1]) << 8));
+      trigger_velocity =
+          static_cast<uint16_t>(static_cast<uint32_t>(can_data[2]) |
+                                (static_cast<uint32_t>(can_data[3]) << 8));
+      trigger_torque =
+          static_cast<uint16_t>(static_cast<uint32_t>(can_data[4]) |
+                                (static_cast<uint32_t>(can_data[5]) << 8));
+
+      buttons = static_cast<uint16_t>(
+          (buttons & 0xc) | (static_cast<uint32_t>(can_data[7] & 0xc0) >> 6));
+      update_report = true;
+    }
+
+    can_receive_command(can_data, &length, 1);
+    if (length == 8) {
+      last_command_time = micros();
+      wheel_position =
+          static_cast<uint16_t>(static_cast<uint32_t>(can_data[0]) |
+                                (static_cast<uint32_t>(can_data[1]) << 8));
+      wheel_velocity =
+          static_cast<uint16_t>(static_cast<uint32_t>(can_data[2]) |
+                                (static_cast<uint32_t>(can_data[3]) << 8));
+      wheel_torque =
+          static_cast<uint16_t>(static_cast<uint32_t>(can_data[4]) |
+                                (static_cast<uint32_t>(can_data[5]) << 8));
+
+      buttons = static_cast<uint16_t>(
+          (buttons & 0x3) | (static_cast<uint32_t>(can_data[7] & 0xc0) >> 4));
+      update_report = true;
     }
 
     static constexpr uint32_t kTimeout = 10000;
     if (!time_after(time_add(last_command_time, kTimeout), micros())) {
+      trigger_position = 0x8000;
+      wheel_position = 0x8000;
+      trigger_velocity = 0x8000;
+      wheel_velocity = 0x8000;
+      trigger_torque = 0x8000;
+      wheel_torque = 0x8000;
+      buttons = 0x0080;
+      update_report = true;
       // Avoid wrapping back into the valid range.
       last_command_time = time_subtract(micros(), kTimeout);
-      uint8_t zeros[] = {0, 0, 0x80};
+    }
+
+    if (update_report) {
       DisableInterrupts disable_interrupts;
-      joysticks->UpdateReport(zeros, 3, disable_interrupts);
+
+      const uint16_t trigger_packet[] = {
+          trigger_position,
+          trigger_velocity,
+          trigger_torque,
+          static_cast<uint16_t>((trigger_position & 0xff) << 8),
+          static_cast<uint16_t>((trigger_velocity & 0xff) << 8),
+          static_cast<uint16_t>((trigger_torque & 0xff) << 8),
+          buttons};
+      throttle_joystick->UpdateReport(trigger_packet, 14, disable_interrupts);
+
+      const uint16_t wheel_packet[] = {
+          wheel_position,
+          wheel_velocity,
+          wheel_torque,
+          static_cast<uint16_t>((wheel_position & 0xff) << 8),
+          static_cast<uint16_t>((wheel_velocity & 0xff) << 8),
+          static_cast<uint16_t>((wheel_torque & 0xff) << 8),
+          buttons};
+      wheel_joystick->UpdateReport(wheel_packet, 14, disable_interrupts);
+    }
+
+    char usb_out_data[teensy::InterruptOut::kSize];
+    const int usb_out_size = interrupt_out->ReceiveData(usb_out_data);
+    if (usb_out_size >= 16) {
+      can_send(0x2, reinterpret_cast<unsigned char *>(usb_out_data), 8, 2);
+      can_send(0x3, reinterpret_cast<unsigned char *>(usb_out_data) + 8, 8, 3);
     }
   }
 }
 
+// The HID report descriptor we use.
+constexpr char kReportDescriptor[] = {
+    0x05, 0x01,        // Usage Page (Generic Desktop),
+    0x09, 0x04,        // Usage (Joystick),
+    0xA1, 0x01,        // Collection (Application),
+    0x75, 0x10,        //     Report Size (16),
+    0x95, 0x06,        //     Report Count (6),
+    0x15, 0x00,        //     Logical Minimum (0),
+    0x26, 0xFF, 0xFF,  //     Logical Maximum (65535),
+    0x35, 0x00,        //     Physical Minimum (0),
+    0x46, 0xFF, 0xFF,  //     Physical Maximum (65535),
+    0x09, 0x30,        //     Usage (X),
+    0x09, 0x31,        //     Usage (Y),
+    0x09, 0x32,        //     Usage (Z),
+    0x09, 0x33,        //     Usage (Rz),
+    0x09, 0x34,        //     Usage (?),
+    0x09, 0x35,        //     Usage (?),
+    0x81, 0x02,        //     Input (Variable),
+    0x75, 0x01,        //     Report Size (1),
+    0x95, 0x10,        //     Report Count (16),
+    0x25, 0x01,        //     Logical Maximum (1),
+    0x45, 0x01,        //     Physical Maximum (1),
+    0x05, 0x09,        //     Usage Page (Button),
+    0x19, 0x01,        //     Usage Minimum (01),
+    0x29, 0x10,        //     Usage Maximum (16),
+    0x81, 0x02,        //     Input (Variable),
+    0xC0               // End Collection
+};
+
 }  // namespace
 
 extern "C" {
@@ -198,16 +272,21 @@
   teensy::UsbDevice usb_device(0, 0x16c0, 0x0491);
   usb_device.SetManufacturer("FRC 971 Spartan Robotics");
   usb_device.SetProduct("Pistol Grip Controller interface");
+  teensy::HidFunction throttle_joystick(&usb_device, 14);
+  throttle_joystick.set_report_descriptor(
+      ::std::string(kReportDescriptor, sizeof(kReportDescriptor)));
+  teensy::HidFunction wheel_joystick(&usb_device, 14);
+  wheel_joystick.set_report_descriptor(
+      ::std::string(kReportDescriptor, sizeof(kReportDescriptor)));
   teensy::AcmTty tty1(&usb_device);
   teensy::AcmTty tty2(&usb_device);
-  teensy::HidFunction joysticks(&usb_device, 10);
   teensy::InterruptOut interrupt_out(&usb_device, "JoystickForce");
   global_stdout.store(&tty2, ::std::memory_order_release);
   usb_device.Initialize();
 
-  can_init();
+  can_init(0, 1);
 
-  MoveJoysticks(&joysticks, &interrupt_out);
+  ForwardJoystickData(&throttle_joystick, &wheel_joystick, &interrupt_out);
 
   return 0;
 }
diff --git a/motors/pistol_grip/generate_cogging.py b/motors/pistol_grip/generate_cogging.py
new file mode 100644
index 0000000..9cecfe2
--- /dev/null
+++ b/motors/pistol_grip/generate_cogging.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+
+import sys
+from matplotlib import pylab
+
+# TODO(austin): Plot flag.
+
+def main(argv):
+  if len(argv) < 4:
+    print 'Args: input output.cc struct_name'
+    return 1
+  data_sum = [0.0] * 4096
+  data_count = [0] * 4096
+  data_list_absolute = []
+  data_list_current = []
+
+  with open(argv[1], 'r') as fd:
+    for line in fd:
+      if line.startswith('reading'):
+        split_line = line.split()
+        data_absolute = int(split_line[1])
+        data_index = int(split_line[3][2:])
+        data_current = int(split_line[2]) / 10000.0
+        data_sum[data_index] += data_current
+        data_count[data_index] += 1
+        data_list_absolute.append(data_absolute)
+        data_list_current.append(data_current)
+  data = [0.0] * 4096
+  min_zero = 4096
+  max_zero = 0
+  for i in xrange(0, 4096):
+    if data_count[i] == 0:
+      min_zero = min(i, min_zero)
+      max_zero = max(i, min_zero)
+
+  for i in xrange(0, 4096):
+    if data_count[i] != 0:
+      data[i] = data_sum[i] / data_count[i]
+  if min_zero == 0 and max_zero == 4095:
+    for i in xrange(0, 4096):
+      if data_count[i] != 0:
+        while i > 0:
+          data[i - 1] = data[i]
+          i -= 1
+        break;
+
+    for i in reversed(xrange(0, 4096)):
+      if data_count[i] != 0:
+        while i < 4095:
+          data[i + 1] = data[i]
+          i += 1
+        break;
+  else:
+    for i in xrange(0, 4096):
+      if data_count[i] == 0:
+        if i < (min_zero + max_zero) / 2:
+          data[i] = data[min_zero - 1]
+        else:
+          data[i] = data[max_zero + 1]
+
+  pylab.plot(range(0, 4096), data)
+  pylab.figure()
+  pylab.plot(data_list_absolute, data_list_current)
+  pylab.show()
+  with open(argv[2], 'w') as out_fd:
+    out_fd.write('extern const float %s[4096];\n' % argv[3])
+    out_fd.write('const float %s[4096] = {\n' % argv[3])
+    for datapoint in data:
+      out_fd.write('    %ff,\n' % datapoint)
+    out_fd.write('};')
+
+  return 0
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv))
diff --git a/motors/pistol_grip/motor_controls.cc b/motors/pistol_grip/motor_controls.cc
new file mode 100644
index 0000000..b123378
--- /dev/null
+++ b/motors/pistol_grip/motor_controls.cc
@@ -0,0 +1,212 @@
+#include "motors/pistol_grip/motor_controls.h"
+
+#include "motors/peripheral/configuration.h"
+
+namespace frc971 {
+namespace salsa {
+namespace {
+
+template <int kRows, int kCols>
+using ComplexMatrix =
+    LittleMotorControlsImplementation::ComplexMatrix<kRows, kCols>;
+
+using Complex = ::std::complex<float>;
+
+constexpr int kCountsPerRevolution =
+    LittleMotorControlsImplementation::constant_counts_per_revolution();
+constexpr int kPolesPerRevolution =
+    LittleMotorControlsImplementation::poles_per_revolution();
+
+#if 1
+constexpr double kMaxDutyCycle = 0.98;
+#elif 1
+constexpr double kMaxDutyCycle = 0.6;
+#elif 0
+constexpr double kMaxDutyCycle = 0.2;
+#endif
+
+constexpr int kPhaseBOffset = kCountsPerRevolution / 3;
+constexpr int kPhaseCOffset =
+    2 * kCountsPerRevolution / 3;
+
+// volts
+constexpr double vcc = 14.0;
+
+constexpr double Kv = 37.6;
+
+// Henries
+constexpr double L = 8e-05;
+
+constexpr double M = 8e-06;
+
+// ohms for system
+constexpr double R = 0.207393;
+
+::Eigen::Matrix<float, 3, 3> A_discrete() {
+  ::Eigen::Matrix<float, 3, 3> r;
+  static constexpr float kDiagonal = 0.87645f;
+  static constexpr float kOffDiagonal = 0.0105814f;
+  r << kDiagonal, kOffDiagonal, kOffDiagonal, kOffDiagonal, kDiagonal,
+      kOffDiagonal, kOffDiagonal, kOffDiagonal, kDiagonal;
+  return r;
+}
+
+::Eigen::Matrix<float, 3, 3> B_discrete_inverse() {
+  return ::Eigen::Matrix<float, 1, 3>::Constant(1.54618f).asDiagonal();
+}
+
+// The number to divide the product of the unit BEMF and the per phase current
+// by to get motor current.
+constexpr double kOneAmpScalar = 1.5;
+
+constexpr double kMaxOneAmpDrivingVoltage = 0.208257;
+
+// Use FluxLinkageTable() to access this with a const so you don't accidentally
+// modify it.
+float flux_linkage_table[kCountsPerRevolution];
+
+void MakeFluxLinkageTable() {
+  for (int i = 0; i < kCountsPerRevolution; ++i) {
+    const double theta = static_cast<double>(i) /
+                         static_cast<double>(kCountsPerRevolution) *
+                         static_cast<double>(kPolesPerRevolution) * 2.0 * M_PI;
+    flux_linkage_table[i] = sin(theta);
+  }
+}
+
+// theta doesn't have to be less than kCountsPerRevolution.
+::Eigen::Matrix<float, 3, 1> FluxLinkageAt(uint32_t theta) {
+  ::Eigen::Matrix<float, 3, 1> r;
+  r(0) = flux_linkage_table[theta % kCountsPerRevolution];
+  r(1) = flux_linkage_table[(theta + kPhaseBOffset) % kCountsPerRevolution];
+  r(2) = flux_linkage_table[(theta + kPhaseCOffset) % kCountsPerRevolution];
+  return r;
+}
+
+::Eigen::Matrix<float, 3, 3> MakeK() {
+  ::Eigen::Matrix<float, 3, 3> Vconv;
+  Vconv << 2.0f, -1.0f, -1.0f, -1.0f, 2.0f, -1.0f, -1.0f, -1.0f, 2.0f;
+  static constexpr float kControllerGain = 0.07f;
+  return kControllerGain * (Vconv / 3.0f);
+}
+
+ComplexMatrix<3, 1> MakeE1Unrotated() {
+  ComplexMatrix<3, 1> rotation;
+  rotation << Complex(0, -1), Complex(::std::sqrt(3) / 2, 0.5),
+      Complex(-::std::sqrt(3) / 2, 0.5);
+  return rotation;
+}
+
+ComplexMatrix<3, 3> Hn(float omega, int scalar) {
+  const Complex a(static_cast<float>(R),
+                  omega * static_cast<float>(scalar * L));
+  const Complex b(0, omega * static_cast<float>(scalar * M));
+  const Complex temp1 = a + b;
+  const Complex temp2 = -b;
+  ComplexMatrix<3, 3> matrix;
+  matrix << temp1, temp2, temp2, temp2, temp1, temp2, temp2, temp2, temp1;
+  return matrix *
+         -(omega / static_cast<float>(Kv) / (a * a + a * b - 2.0f * b * b));
+}
+
+}  // namespace
+
+LittleMotorControlsImplementation::LittleMotorControlsImplementation()
+    : E1Unrotated_(MakeE1Unrotated()) {
+  MakeFluxLinkageTable();
+}
+
+::std::array<uint32_t, 3> LittleMotorControlsImplementation::DoIteration(
+    const float raw_currents[3], const uint32_t theta_in,
+    const float command_current) {
+  static constexpr float kCurrentSlewRate = 0.05f;
+  if (command_current > filtered_current_ + kCurrentSlewRate) {
+    filtered_current_ += kCurrentSlewRate;
+  } else if (command_current < filtered_current_ - kCurrentSlewRate) {
+    filtered_current_ -= kCurrentSlewRate;
+  } else {
+    filtered_current_ = command_current;
+  }
+  const float goal_current_in = filtered_current_;
+  static constexpr float kMaxEffectiveVcc = static_cast<float>(vcc * kMaxDutyCycle);
+  const float estimated_velocity_voltage =
+      estimated_velocity_ / static_cast<float>(Kv / 2.0);
+  const float max_current = (kMaxEffectiveVcc - estimated_velocity_voltage) /
+                            static_cast<float>(kMaxOneAmpDrivingVoltage);
+  const float min_current = (-kMaxEffectiveVcc - estimated_velocity_voltage) /
+                            static_cast<float>(kMaxOneAmpDrivingVoltage);
+  const float goal_current =
+      ::std::max(min_current, ::std::min(max_current, goal_current_in));
+
+  const uint32_t theta = theta_in;
+
+  const ::Eigen::Matrix<float, 3, 1> measured_current =
+      (::Eigen::Matrix<float, 3, 1>() << scale_current_reading(raw_currents[0]),
+       scale_current_reading(raw_currents[1]),
+       scale_current_reading(raw_currents[2])).finished();
+
+  const ComplexMatrix<3, 1> E1 =
+      E1Unrotated_ *
+      ImaginaryExpInt<::std::ratio<kPolesPerRevolution, kCountsPerRevolution>>(
+          theta);
+
+  const float overall_measured_current =
+      (E1.real().transpose() * measured_current /
+       static_cast<float>(kOneAmpScalar))(0);
+  const float current_error = goal_current - overall_measured_current;
+  estimated_velocity_ += current_error * 0.1f;
+
+  const float omega = estimated_velocity_;
+
+  const ::Eigen::Matrix<float, 3, 1> I_now = I_last_;
+  const ::Eigen::Matrix<float, 3, 1> I_next =
+      FluxLinkageAt(theta) * goal_current;
+
+  const ComplexMatrix<3, 3> H1 = Hn(omega, 1);
+
+  const ComplexMatrix<3, 1> p_imaginary = H1 * E1;
+  const ComplexMatrix<3, 1> p_next_imaginary =
+      ImaginaryExpFloat(omega / SWITCHING_FREQUENCY) * p_imaginary;
+  const ::Eigen::Matrix<float, 3, 1> p = p_imaginary.real();
+  const ::Eigen::Matrix<float, 3, 1> p_next = p_next_imaginary.real();
+
+  const ::Eigen::Matrix<float, 3, 1> Vn_ff =
+      B_discrete_inverse() * (I_next - A_discrete() * (I_now - p) - p_next);
+  const ::Eigen::Matrix<float, 3, 1> Vn =
+      Vn_ff + MakeK() * (I_now - measured_current);
+
+  debug_[0] = (I_next)(0) * 100;
+  debug_[1] = (I_next)(1) * 100;
+  debug_[2] = (I_next)(2) * 100;
+
+  debug_[5] = Vn(0) * 100;
+  debug_[6] = Vn(1) * 100;
+  debug_[7] = Vn(2) * 100;
+
+  ::Eigen::Matrix<float, 3, 1> times = Vn / vcc;
+  {
+    const float min_time = times.minCoeff();
+    times -= ::Eigen::Matrix<float, 3, 1>::Constant(min_time);
+  }
+  {
+    const float max_time = times.maxCoeff();
+    const float scalar =
+        static_cast<float>(kMaxDutyCycle) /
+        ::std::max(static_cast<float>(kMaxDutyCycle), max_time);
+    times *= scalar;
+  }
+
+  I_last_ = I_next;
+
+  // TODO(Austin): Figure out why we need the min here.
+  return {static_cast<uint32_t>(::std::max(0.0f, times(0)) * 1500.0f),
+          static_cast<uint32_t>(::std::max(0.0f, times(1)) * 1500.0f),
+          static_cast<uint32_t>(::std::max(0.0f, times(2)) * 1500.0f)};
+}
+
+int16_t LittleMotorControlsImplementation::Debug(uint32_t theta) {
+  return debug_[theta];
+}
+
+}  // namespace salsa
+}  // namespace frc971
diff --git a/motors/pistol_grip/motor_controls.h b/motors/pistol_grip/motor_controls.h
new file mode 100644
index 0000000..ca965d0
--- /dev/null
+++ b/motors/pistol_grip/motor_controls.h
@@ -0,0 +1,63 @@
+#ifndef MOTORS_PISTOL_GRIP_MOTOR_CONTROLS_H_
+#define MOTORS_PISTOL_GRIP_MOTOR_CONTROLS_H_
+
+#include <array>
+#include <complex>
+
+#include "motors/math.h"
+#include "motors/motor.h"
+
+#include "Eigen/Dense"
+
+namespace frc971 {
+namespace salsa {
+
+class LittleMotorControlsImplementation : public MotorControls {
+ public:
+  template <int kRows, int kCols>
+  using ComplexMatrix = ::Eigen::Matrix<::std::complex<float>, kRows, kCols>;
+
+  LittleMotorControlsImplementation();
+  ~LittleMotorControlsImplementation() override = default;
+
+  static constexpr int constant_counts_per_revolution() { return 4096; }
+  static constexpr int poles_per_revolution() { return 7; }
+
+  int mechanical_counts_per_revolution() const override {
+    return constant_counts_per_revolution();
+  }
+  int electrical_counts_per_revolution() const override {
+    return constant_counts_per_revolution() / poles_per_revolution();
+  }
+
+  float scale_current_reading(float reading) const override {
+    return reading *
+           static_cast<float>(1.0 / 4096.0 /* Full-scale ADC reading */ *
+                              3.3 /* ADC reference voltage */ /
+                              (18.0 / (10.8 + 18.0)) /* 5V -> 3.3V divider */ /
+                              0.195 /* V/A */);
+  }
+
+  ::std::array<uint32_t, 3> DoIteration(const float raw_currents[3],
+                                        uint32_t theta,
+                                        const float command_current) override;
+
+  int16_t Debug(uint32_t theta) override;
+
+  float estimated_velocity() const override { return estimated_velocity_; }
+
+ private:
+  const ComplexMatrix<3, 1> E1Unrotated_;
+
+  float estimated_velocity_ = 0;
+  float filtered_current_ = 0;
+
+  ::Eigen::Matrix<float, 3, 1> I_last_ = ::Eigen::Matrix<float, 3, 1>::Zero();
+
+  int16_t debug_[9];
+};
+
+}  // namespace salsa
+}  // namespace frc971
+
+#endif  // MOTORS_PISTOL_GRIP_MOTOR_CONTROLS_H_
diff --git a/motors/pistol_grip/usb_forward.cc b/motors/pistol_grip/usb_forward.cc
index 830f8f7..19be857 100644
--- a/motors/pistol_grip/usb_forward.cc
+++ b/motors/pistol_grip/usb_forward.cc
@@ -111,11 +111,13 @@
 
 }  // namespace
 
-int main() {
+int main(int argc, char ** /*argv*/) {
   CHECK_LIBUSB(libusb_init(nullptr));
   libusb_set_debug(nullptr, LIBUSB_LOG_LEVEL_INFO);
 
-  libusb_set_debug(nullptr, LIBUSB_LOG_LEVEL_DEBUG);
+  if (argc > 1) {
+    libusb_set_debug(nullptr, LIBUSB_LOG_LEVEL_DEBUG);
+  }
 
 #ifdef __WINNT__
   {
diff --git a/motors/pistol_grip/vtable_trigger.cc b/motors/pistol_grip/vtable_trigger.cc
new file mode 100644
index 0000000..44306f1
--- /dev/null
+++ b/motors/pistol_grip/vtable_trigger.cc
@@ -0,0 +1,4099 @@
+extern const float kTriggerCoggingTorque[4096];
+const float kTriggerCoggingTorque[4096] = {
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.095850f,
+    0.086438f,
+    0.037663f,
+    0.004088f,
+    -0.018050f,
+    -0.037200f,
+    -0.055087f,
+    -0.067375f,
+    -0.079263f,
+    -0.090475f,
+    -0.099812f,
+    -0.108475f,
+    -0.114700f,
+    -0.121000f,
+    -0.126575f,
+    -0.131513f,
+    -0.138275f,
+    -0.140188f,
+    -0.089575f,
+    -0.090725f,
+    -0.091975f,
+    -0.093525f,
+    -0.095687f,
+    -0.085038f,
+    -0.075912f,
+    -0.038337f,
+    0.020487f,
+    0.018800f,
+    0.015163f,
+    0.021087f,
+    0.019475f,
+    0.017563f,
+    0.015663f,
+    0.013562f,
+    0.011463f,
+    0.009313f,
+    0.006513f,
+    0.004063f,
+    -0.000300f,
+    -0.005000f,
+    -0.011125f,
+    -0.015825f,
+    -0.025237f,
+    -0.033537f,
+    -0.041925f,
+    -0.049800f,
+    -0.058250f,
+    -0.063200f,
+    -0.068875f,
+    -0.075713f,
+    -0.078550f,
+    -0.081937f,
+    -0.085050f,
+    -0.087250f,
+    -0.084975f,
+    -0.086725f,
+    -0.088300f,
+    -0.083563f,
+    -0.076812f,
+    -0.045963f,
+    -0.039338f,
+    -0.033738f,
+    0.016263f,
+    0.014975f,
+    0.041362f,
+    0.071925f,
+    0.097300f,
+    0.095462f,
+    0.093775f,
+    0.128713f,
+    0.160250f,
+    0.179962f,
+    0.210862f,
+    0.209350f,
+    0.215088f,
+    0.234825f,
+    0.249500f,
+    0.284813f,
+    0.284037f,
+    0.281750f,
+    0.278487f,
+    0.287712f,
+    0.285712f,
+    0.281788f,
+    0.276450f,
+    0.271850f,
+    0.266775f,
+    0.260288f,
+    0.252338f,
+    0.243812f,
+    0.230750f,
+    0.220963f,
+    0.205525f,
+    0.191488f,
+    0.177575f,
+    0.161500f,
+    0.151337f,
+    0.138650f,
+    0.125238f,
+    0.116425f,
+    0.107787f,
+    0.099488f,
+    0.093688f,
+    0.087200f,
+    0.083525f,
+    0.080738f,
+    0.078363f,
+    0.076625f,
+    0.082588f,
+    0.081275f,
+    0.080125f,
+    0.079225f,
+    0.094587f,
+    0.119413f,
+    0.145288f,
+    0.142837f,
+    0.140788f,
+    0.162325f,
+    0.176125f,
+    0.196550f,
+    0.223712f,
+    0.225900f,
+    0.241613f,
+    0.249988f,
+    0.263437f,
+    0.285087f,
+    0.283513f,
+    0.281413f,
+    0.279313f,
+    0.277250f,
+    0.274587f,
+    0.271388f,
+    0.267250f,
+    0.263862f,
+    0.257437f,
+    0.248650f,
+    0.237338f,
+    0.220875f,
+    0.204050f,
+    0.186075f,
+    0.168587f,
+    0.152138f,
+    0.130925f,
+    0.109488f,
+    0.090725f,
+    0.069775f,
+    0.048738f,
+    0.029588f,
+    0.009537f,
+    -0.006150f,
+    -0.022812f,
+    -0.037187f,
+    -0.051350f,
+    -0.063488f,
+    -0.071962f,
+    -0.077400f,
+    -0.082212f,
+    -0.086075f,
+    -0.088587f,
+    -0.084737f,
+    -0.078788f,
+    -0.080238f,
+    -0.081325f,
+    -0.070538f,
+    -0.071813f,
+    -0.034112f,
+    -0.001700f,
+    0.011362f,
+    0.009462f,
+    0.016212f,
+    0.050000f,
+    0.057725f,
+    0.071137f,
+    0.069988f,
+    0.085550f,
+    0.112325f,
+    0.121325f,
+    0.139550f,
+    0.138637f,
+    0.136887f,
+    0.135200f,
+    0.133338f,
+    0.131300f,
+    0.128712f,
+    0.126287f,
+    0.123650f,
+    0.121213f,
+    0.116075f,
+    0.109487f,
+    0.104675f,
+    0.095062f,
+    0.089487f,
+    0.078462f,
+    0.067963f,
+    0.056787f,
+    0.045475f,
+    0.038225f,
+    0.029613f,
+    0.022287f,
+    0.015137f,
+    0.011813f,
+    0.008137f,
+    0.003500f,
+    0.000537f,
+    -0.002138f,
+    -0.004312f,
+    -0.006300f,
+    -0.004125f,
+    -0.005300f,
+    -0.001175f,
+    0.006263f,
+    0.019537f,
+    0.048550f,
+    0.053125f,
+    0.065400f,
+    0.078650f,
+    0.097363f,
+    0.109213f,
+    0.126813f,
+    0.148375f,
+    0.179625f,
+    0.187575f,
+    0.204825f,
+    0.207988f,
+    0.230262f,
+    0.254038f,
+    0.261525f,
+    0.260475f,
+    0.259050f,
+    0.264487f,
+    0.262563f,
+    0.260125f,
+    0.257362f,
+    0.254775f,
+    0.251300f,
+    0.246063f,
+    0.237525f,
+    0.228075f,
+    0.218362f,
+    0.203425f,
+    0.188587f,
+    0.172575f,
+    0.155413f,
+    0.138237f,
+    0.118150f,
+    0.100975f,
+    0.082625f,
+    0.065188f,
+    0.047250f,
+    0.030250f,
+    0.013050f,
+    0.021267f,
+    0.008389f,
+    -0.001156f,
+    -0.009322f,
+    -0.015844f,
+    -0.021689f,
+    -0.024911f,
+    -0.028489f,
+    -0.031400f,
+    -0.030633f,
+    -0.032733f,
+    -0.034544f,
+    -0.036167f,
+    -0.034833f,
+    -0.032344f,
+    -0.017200f,
+    0.022933f,
+    0.026033f,
+    0.030800f,
+    0.029389f,
+    0.028100f,
+    0.033556f,
+    0.072667f,
+    0.110722f,
+    0.114011f,
+    0.112756f,
+    0.111311f,
+    0.114944f,
+    0.113156f,
+    0.111011f,
+    0.108700f,
+    0.105811f,
+    0.102067f,
+    0.098978f,
+    0.095389f,
+    0.089022f,
+    0.081656f,
+    0.075067f,
+    0.065411f,
+    0.054156f,
+    0.039533f,
+    0.028378f,
+    0.016389f,
+    0.002178f,
+    -0.012389f,
+    -0.025756f,
+    -0.036489f,
+    -0.047878f,
+    -0.057678f,
+    -0.061489f,
+    -0.068633f,
+    -0.073333f,
+    -0.076822f,
+    -0.078844f,
+    -0.081778f,
+    -0.083989f,
+    -0.086200f,
+    -0.088478f,
+    -0.090522f,
+    -0.092333f,
+    -0.087111f,
+    -0.071678f,
+    -0.019722f,
+    -0.020311f,
+    0.009078f,
+    0.016033f,
+    0.014800f,
+    0.025644f,
+    0.031744f,
+    0.061611f,
+    0.105722f,
+    0.105589f,
+    0.125400f,
+    0.133600f,
+    0.137522f,
+    0.141978f,
+    0.140278f,
+    0.138156f,
+    0.135900f,
+    0.133022f,
+    0.129411f,
+    0.124267f,
+    0.117989f,
+    0.111867f,
+    0.101911f,
+    0.086778f,
+    0.072178f,
+    0.057489f,
+    0.038333f,
+    0.017733f,
+    -0.000589f,
+    -0.023233f,
+    -0.042589f,
+    -0.064822f,
+    -0.086356f,
+    -0.107956f,
+    -0.127911f,
+    -0.148400f,
+    -0.164389f,
+    -0.180933f,
+    -0.198878f,
+    -0.210544f,
+    -0.219044f,
+    -0.224578f,
+    -0.230256f,
+    -0.234744f,
+    -0.237422f,
+    -0.240133f,
+    -0.242733f,
+    -0.244967f,
+    -0.246367f,
+    -0.227211f,
+    -0.220067f,
+    -0.214133f,
+    -0.175744f,
+    -0.165400f,
+    -0.166856f,
+    -0.168422f,
+    -0.141333f,
+    -0.121200f,
+    -0.081567f,
+    -0.073078f,
+    -0.055167f,
+    -0.056178f,
+    -0.056889f,
+    -0.015822f,
+    -0.009767f,
+    -0.010356f,
+    -0.001033f,
+    -0.002289f,
+    -0.003911f,
+    -0.005711f,
+    -0.006200f,
+    -0.008122f,
+    -0.010767f,
+    -0.013311f,
+    -0.019389f,
+    -0.022478f,
+    -0.025167f,
+    -0.030189f,
+    -0.036000f,
+    -0.041389f,
+    -0.046122f,
+    -0.051022f,
+    -0.056489f,
+    -0.059667f,
+    -0.064511f,
+    -0.069000f,
+    -0.072100f,
+    -0.074867f,
+    -0.077222f,
+    -0.079644f,
+    -0.082122f,
+    -0.080467f,
+    -0.081700f,
+    -0.075933f,
+    -0.047489f,
+    -0.039900f,
+    -0.005811f,
+    -0.006311f,
+    0.002911f,
+    0.011711f,
+    0.024567f,
+    0.053167f,
+    0.053067f,
+    0.089644f,
+    0.118100f,
+    0.132167f,
+    0.139067f,
+    0.138278f,
+    0.150322f,
+    0.203078f,
+    0.237000f,
+    0.236322f,
+    0.234822f,
+    0.233156f,
+    0.235522f,
+    0.233556f,
+    0.231400f,
+    0.228867f,
+    0.226622f,
+    0.220889f,
+    0.212100f,
+    0.208944f,
+    0.199933f,
+    0.191333f,
+    0.181733f,
+    0.162056f,
+    0.152500f,
+    0.131122f,
+    0.109444f,
+    0.094500f,
+    0.073700f,
+    0.061667f,
+    0.045456f,
+    0.027656f,
+    0.012456f,
+    0.004033f,
+    -0.005844f,
+    -0.015900f,
+    -0.023944f,
+    -0.028744f,
+    -0.033811f,
+    -0.039256f,
+    -0.041622f,
+    -0.043900f,
+    -0.046756f,
+    -0.042889f,
+    -0.044278f,
+    -0.032956f,
+    -0.033467f,
+    -0.024533f,
+    -0.016456f,
+    0.004022f,
+    0.020544f,
+    0.024867f,
+    0.043033f,
+    0.047811f,
+    0.067222f,
+    0.087400f,
+    0.094467f,
+    0.100067f,
+    0.104956f,
+    0.103978f,
+    0.106767f,
+    0.105100f,
+    0.102789f,
+    0.104733f,
+    0.100211f,
+    0.097044f,
+    0.092833f,
+    0.088533f,
+    0.079822f,
+    0.075144f,
+    0.066511f,
+    0.054233f,
+    0.040744f,
+    0.029889f,
+    0.005089f,
+    -0.010267f,
+    -0.022122f,
+    -0.038322f,
+    -0.061789f,
+    -0.076700f,
+    -0.096778f,
+    -0.109967f,
+    -0.119511f,
+    -0.129011f,
+    -0.136044f,
+    -0.142933f,
+    -0.148989f,
+    -0.153289f,
+    -0.156922f,
+    -0.159911f,
+    -0.162022f,
+    -0.166022f,
+    -0.167700f,
+    -0.169200f,
+    -0.155044f,
+    -0.155778f,
+    -0.143989f,
+    -0.134411f,
+    -0.114233f,
+    -0.111356f,
+    -0.106989f,
+    -0.087267f,
+    -0.051256f,
+    -0.033867f,
+    -0.009789f,
+    -0.006789f,
+    0.016556f,
+    0.016122f,
+    0.034411f,
+    0.053689f,
+    0.056700f,
+    0.055800f,
+    0.054611f,
+    0.056122f,
+    0.056289f,
+    0.054244f,
+    0.052167f,
+    0.049422f,
+    0.046944f,
+    0.043400f,
+    0.037522f,
+    0.032711f,
+    0.028267f,
+    0.020489f,
+    0.013389f,
+    0.006600f,
+    -0.005867f,
+    -0.013044f,
+    -0.025333f,
+    -0.035811f,
+    -0.043167f,
+    -0.049056f,
+    -0.053400f,
+    -0.057122f,
+    -0.063100f,
+    -0.066833f,
+    -0.070300f,
+    -0.072844f,
+    -0.074956f,
+    -0.077044f,
+    -0.079167f,
+    -0.081067f,
+    -0.082567f,
+    -0.076267f,
+    -0.058244f,
+    -0.052867f,
+    -0.026878f,
+    0.008500f,
+    0.013889f,
+    0.029656f,
+    0.028200f,
+    0.037356f,
+    0.044756f,
+    0.059767f,
+    0.106800f,
+    0.117189f,
+    0.130078f,
+    0.129467f,
+    0.128100f,
+    0.126622f,
+    0.130733f,
+    0.128733f,
+    0.125789f,
+    0.123489f,
+    0.120422f,
+    0.113567f,
+    0.109289f,
+    0.101100f,
+    0.093967f,
+    0.082478f,
+    0.068222f,
+    0.052022f,
+    0.037433f,
+    0.016367f,
+    -0.004478f,
+    -0.020589f,
+    -0.040200f,
+    -0.057778f,
+    -0.077122f,
+    -0.096767f,
+    -0.114933f,
+    -0.132389f,
+    -0.145189f,
+    -0.157633f,
+    -0.164967f,
+    -0.171278f,
+    -0.176956f,
+    -0.181344f,
+    -0.185000f,
+    -0.187456f,
+    -0.190111f,
+    -0.192067f,
+    -0.194244f,
+    -0.196422f,
+    -0.200167f,
+    -0.201933f,
+    -0.193633f,
+    -0.154867f,
+    -0.139411f,
+    -0.131567f,
+    -0.112178f,
+    -0.106633f,
+    -0.096167f,
+    -0.080278f,
+    -0.072400f,
+    -0.059167f,
+    -0.036633f,
+    -0.015378f,
+    -0.016367f,
+    -0.012067f,
+    -0.010044f,
+    -0.011600f,
+    -0.013367f,
+    -0.015389f,
+    -0.016444f,
+    -0.019156f,
+    -0.022422f,
+    -0.025933f,
+    -0.029744f,
+    -0.035422f,
+    -0.043456f,
+    -0.052322f,
+    -0.062911f,
+    -0.073900f,
+    -0.083567f,
+    -0.096122f,
+    -0.110822f,
+    -0.137422f,
+    -0.138344f,
+    -0.202422f,
+    -0.145478f,
+    -0.114122f,
+    -0.122889f,
+    -0.129000f,
+    -0.134589f,
+    -0.164567f,
+    -0.133222f,
+    -0.173778f,
+    -0.107011f,
+    0.011456f,
+    -0.008111f,
+    -0.040733f,
+    0.001767f,
+    0.137378f,
+    0.089244f,
+    0.111556f,
+    0.107078f,
+    0.111367f,
+    0.159856f,
+    0.158533f,
+    0.186556f,
+    0.204511f,
+    0.218489f,
+    0.232200f,
+    0.243889f,
+    0.244356f,
+    0.241300f,
+    0.237844f,
+    0.234100f,
+    0.230767f,
+    0.228300f,
+    0.225733f,
+    0.222911f,
+    0.218133f,
+    0.213356f,
+    0.206711f,
+    0.198878f,
+    0.188178f,
+    0.175100f,
+    0.158556f,
+    0.141922f,
+    0.124556f,
+    0.107500f,
+    0.090211f,
+    0.069722f,
+    0.053956f,
+    0.035733f,
+    0.019933f,
+    0.003978f,
+    -0.006311f,
+    -0.015589f,
+    -0.023511f,
+    -0.028433f,
+    -0.033744f,
+    -0.036522f,
+    -0.039411f,
+    -0.041322f,
+    -0.038856f,
+    -0.040433f,
+    -0.041922f,
+    -0.043178f,
+    -0.038022f,
+    -0.030544f,
+    -0.018567f,
+    0.024578f,
+    0.029122f,
+    0.031011f,
+    0.045722f,
+    0.067189f,
+    0.073278f,
+    0.092700f,
+    0.096589f,
+    0.135889f,
+    0.136000f,
+    0.166200f,
+    0.175422f,
+    0.179922f,
+    0.178478f,
+    0.176867f,
+    0.175433f,
+    0.173978f,
+    0.171900f,
+    0.169822f,
+    0.167222f,
+    0.164867f,
+    0.161300f,
+    0.155678f,
+    0.151522f,
+    0.144978f,
+    0.137200f,
+    0.131789f,
+    0.123033f,
+    0.112722f,
+    0.105911f,
+    0.098778f,
+    0.094433f,
+    0.088778f,
+    0.084578f,
+    0.081922f,
+    0.078344f,
+    0.075156f,
+    0.073222f,
+    0.071633f,
+    0.072733f,
+    0.071356f,
+    0.070000f,
+    0.072211f,
+    0.080578f,
+    0.098289f,
+    0.119644f,
+    0.126411f,
+    0.148322f,
+    0.158778f,
+    0.189244f,
+    0.201022f,
+    0.208878f,
+    0.229167f,
+    0.245189f,
+    0.263267f,
+    0.297644f,
+    0.305256f,
+    0.312122f,
+    0.336344f,
+    0.364100f,
+    0.366511f,
+    0.366911f,
+    0.365411f,
+    0.363744f,
+    0.365956f,
+    0.363978f,
+    0.361333f,
+    0.356722f,
+    0.353000f,
+    0.346744f,
+    0.336456f,
+    0.331322f,
+    0.320778f,
+    0.308789f,
+    0.290522f,
+    0.275222f,
+    0.259433f,
+    0.246500f,
+    0.229689f,
+    0.212467f,
+    0.198067f,
+    0.184300f,
+    0.172944f,
+    0.161211f,
+    0.154111f,
+    0.147489f,
+    0.141922f,
+    0.139044f,
+    0.136411f,
+    0.133867f,
+    0.131456f,
+    0.129378f,
+    0.131311f,
+    0.129533f,
+    0.131000f,
+    0.132700f,
+    0.135322f,
+    0.163711f,
+    0.194578f,
+    0.200278f,
+    0.211744f,
+    0.212156f,
+    0.223467f,
+    0.229933f,
+    0.232178f,
+    0.271522f,
+    0.300856f,
+    0.300300f,
+    0.311533f,
+    0.310011f,
+    0.307722f,
+    0.305011f,
+    0.302033f,
+    0.298900f,
+    0.295656f,
+    0.290856f,
+    0.286244f,
+    0.279644f,
+    0.272100f,
+    0.262400f,
+    0.248778f,
+    0.232333f,
+    0.211367f,
+    0.193467f,
+    0.174144f,
+    0.154900f,
+    0.134567f,
+    0.114922f,
+    0.093156f,
+    0.076622f,
+    0.058656f,
+    0.039589f,
+    0.025178f,
+    0.010256f,
+    0.000000f,
+    -0.009822f,
+    -0.017011f,
+    -0.021611f,
+    -0.025867f,
+    -0.028856f,
+    -0.032022f,
+    -0.034600f,
+    -0.036889f,
+    -0.038822f,
+    -0.032822f,
+    -0.030067f,
+    -0.022944f,
+    -0.018000f,
+    0.020189f,
+    0.019178f,
+    0.022222f,
+    0.020256f,
+    0.022200f,
+    0.021444f,
+    0.069300f,
+    0.100689f,
+    0.107500f,
+    0.106200f,
+    0.103267f,
+    0.101122f,
+    0.102078f,
+    0.099800f,
+    0.097333f,
+    0.094356f,
+    0.090811f,
+    0.084789f,
+    0.080200f,
+    0.072978f,
+    0.065089f,
+    0.055722f,
+    0.040433f,
+    0.027511f,
+    0.015322f,
+    0.000267f,
+    -0.016111f,
+    -0.028744f,
+    -0.045389f,
+    -0.055944f,
+    -0.071444f,
+    -0.081378f,
+    -0.092933f,
+    -0.098378f,
+    -0.105900f,
+    -0.110444f,
+    -0.114522f,
+    -0.117200f,
+    -0.119311f,
+    -0.121322f,
+    -0.123278f,
+    -0.125222f,
+    -0.127100f,
+    -0.130144f,
+    -0.133467f,
+    -0.134611f,
+    -0.094533f,
+    -0.068278f,
+    -0.048878f,
+    -0.043689f,
+    -0.045200f,
+    -0.037078f,
+    -0.032011f,
+    -0.033067f,
+    -0.011278f,
+    0.043733f,
+    0.049433f,
+    0.058367f,
+    0.056844f,
+    0.054944f,
+    0.052844f,
+    0.050511f,
+    0.047944f,
+    0.045178f,
+    0.041144f,
+    0.036422f,
+    0.028956f,
+    0.022256f,
+    0.012822f,
+    -0.000744f,
+    -0.014300f,
+    -0.031900f,
+    -0.047544f,
+    -0.067500f,
+    -0.084967f,
+    -0.104667f,
+    -0.122133f,
+    -0.141322f,
+    -0.158400f,
+    -0.178056f,
+    -0.194256f,
+    -0.209067f,
+    -0.222778f,
+    -0.234067f,
+    -0.243211f,
+    -0.249778f,
+    -0.255311f,
+    -0.261022f,
+    -0.265578f,
+    -0.268800f,
+    -0.271400f,
+    -0.266489f,
+    -0.252733f,
+    -0.254789f,
+    -0.256133f,
+    -0.202756f,
+    -0.203667f,
+    -0.187256f,
+    -0.188267f,
+    -0.176400f,
+    -0.144522f,
+    -0.132356f,
+    -0.116289f,
+    -0.105144f,
+    -0.094544f,
+    -0.084511f,
+    -0.064478f,
+    -0.051522f,
+    -0.029800f,
+    -0.016167f,
+    -0.011344f,
+    -0.008956f,
+    -0.011122f,
+    -0.013556f,
+    -0.016089f,
+    -0.019011f,
+    -0.022278f,
+    -0.025333f,
+    -0.027989f,
+    -0.032711f,
+    -0.038044f,
+    -0.043767f,
+    -0.049589f,
+    -0.056956f,
+    -0.061244f,
+    -0.066922f,
+    -0.073500f,
+    -0.077267f,
+    -0.080856f,
+    -0.083589f,
+    -0.087444f,
+    -0.089500f,
+    -0.091722f,
+    -0.093833f,
+    -0.095644f,
+    -0.096967f,
+    -0.090300f,
+    -0.087778f,
+    -0.084256f,
+    -0.063011f,
+    -0.047833f,
+    -0.048533f,
+    -0.047289f,
+    -0.017389f,
+    -0.003900f,
+    0.015422f,
+    0.053400f,
+    0.083189f,
+    0.092222f,
+    0.105000f,
+    0.126644f,
+    0.137767f,
+    0.137111f,
+    0.148533f,
+    0.190211f,
+    0.210156f,
+    0.209033f,
+    0.207333f,
+    0.204933f,
+    0.202422f,
+    0.199044f,
+    0.194700f,
+    0.188300f,
+    0.181289f,
+    0.173078f,
+    0.160556f,
+    0.145144f,
+    0.128422f,
+    0.109433f,
+    0.090489f,
+    0.073078f,
+    0.049322f,
+    0.026233f,
+    0.002933f,
+    -0.016644f,
+    -0.039167f,
+    -0.059356f,
+    -0.079889f,
+    -0.096822f,
+    -0.116778f,
+    -0.132478f,
+    -0.146567f,
+    -0.154011f,
+    -0.161300f,
+    -0.165678f,
+    -0.168844f,
+    -0.172389f,
+    -0.174944f,
+    -0.174478f,
+    -0.176167f,
+    -0.177856f,
+    -0.175856f,
+    -0.173233f,
+    -0.157267f,
+    -0.119156f,
+    -0.119822f,
+    -0.099189f,
+    -0.083578f,
+    -0.072411f,
+    -0.059444f,
+    -0.058711f,
+    -0.047744f,
+    -0.024600f,
+    -0.025278f,
+    0.033144f,
+    0.041789f,
+    0.040556f,
+    0.039078f,
+    0.037567f,
+    0.038811f,
+    0.040811f,
+    0.038622f,
+    0.036167f,
+    0.033733f,
+    0.031344f,
+    0.025867f,
+    0.021544f,
+    0.017767f,
+    0.013256f,
+    0.006811f,
+    0.002056f,
+    -0.003767f,
+    -0.009756f,
+    -0.014156f,
+    -0.017789f,
+    -0.021100f,
+    -0.025978f,
+    -0.030100f,
+    -0.033022f,
+    -0.035333f,
+    -0.037356f,
+    -0.039256f,
+    -0.034000f,
+    -0.035511f,
+    -0.036789f,
+    -0.037744f,
+    -0.005267f,
+    0.005389f,
+    0.007611f,
+    0.022344f,
+    0.037556f,
+    0.081911f,
+    0.098700f,
+    0.114422f,
+    0.125133f,
+    0.128622f,
+    0.163000f,
+    0.187656f,
+    0.212056f,
+    0.217978f,
+    0.217722f,
+    0.224389f,
+    0.286856f,
+    0.286644f,
+    0.285922f,
+    0.287622f,
+    0.290033f,
+    0.288000f,
+    0.285689f,
+    0.283100f,
+    0.279989f,
+    0.276700f,
+    0.271622f,
+    0.263944f,
+    0.256978f,
+    0.247078f,
+    0.234011f,
+    0.220289f,
+    0.205867f,
+    0.189111f,
+    0.174056f,
+    0.158189f,
+    0.140322f,
+    0.129289f,
+    0.112756f,
+    0.102133f,
+    0.091256f,
+    0.082989f,
+    0.077189f,
+    0.071222f,
+    0.067800f,
+    0.063789f,
+    0.060300f,
+    0.063156f,
+    0.061389f,
+    0.059567f,
+    0.063056f,
+    0.061500f,
+    0.064122f,
+    0.067489f,
+    0.082311f,
+    0.109367f,
+    0.114956f,
+    0.129789f,
+    0.142978f,
+    0.141722f,
+    0.158244f,
+    0.187322f,
+    0.186233f,
+    0.184878f,
+    0.190033f,
+    0.188233f,
+    0.186189f,
+    0.187233f,
+    0.184744f,
+    0.181389f,
+    0.176422f,
+    0.171211f,
+    0.164233f,
+    0.157011f,
+    0.146489f,
+    0.130900f,
+    0.114389f,
+    0.097856f,
+    0.076933f,
+    0.057467f,
+    0.037644f,
+    0.016322f,
+    -0.004289f,
+    -0.025489f,
+    -0.044978f,
+    -0.066200f,
+    -0.083833f,
+    -0.105700f,
+    -0.117978f,
+    -0.135178f,
+    -0.146467f,
+    -0.153711f,
+    -0.161500f,
+    -0.165156f,
+    -0.170133f,
+    -0.173400f,
+    -0.176211f,
+    -0.179044f,
+    -0.182422f,
+    -0.186389f,
+    -0.188222f,
+    -0.172867f,
+    -0.172656f,
+    -0.166667f,
+    -0.114867f,
+    -0.095067f,
+    -0.082922f,
+    -0.084911f,
+    -0.075311f,
+    -0.077089f,
+    -0.068400f,
+    -0.054367f,
+    -0.016578f,
+    -0.013156f,
+    -0.008744f,
+    -0.010111f,
+    -0.011711f,
+    -0.013522f,
+    -0.015344f,
+    -0.017400f,
+    -0.015356f,
+    -0.019678f,
+    -0.023333f,
+    -0.027056f,
+    -0.030478f,
+    -0.039578f,
+    -0.046300f,
+    -0.053844f,
+    -0.065111f,
+    -0.074722f,
+    -0.083489f,
+    -0.094878f,
+    -0.102533f,
+    -0.111200f,
+    -0.116767f,
+    -0.123011f,
+    -0.126322f,
+    -0.130233f,
+    -0.134022f,
+    -0.130756f,
+    -0.132767f,
+    -0.134711f,
+    -0.129133f,
+    -0.130844f,
+    -0.126311f,
+    -0.124389f,
+    -0.112467f,
+    -0.073467f,
+    -0.074544f,
+    -0.075500f,
+    -0.045500f,
+    -0.011111f,
+    -0.000222f,
+    0.010811f,
+    0.037044f,
+    0.047811f,
+    0.059256f,
+    0.082211f,
+    0.095378f,
+    0.113922f,
+    0.127211f,
+    0.167389f,
+    0.166589f,
+    0.165544f,
+    0.163722f,
+    0.166467f,
+    0.164289f,
+    0.162044f,
+    0.159000f,
+    0.154933f,
+    0.149333f,
+    0.145344f,
+    0.137689f,
+    0.129933f,
+    0.119011f,
+    0.106411f,
+    0.091022f,
+    0.075700f,
+    0.060111f,
+    0.045956f,
+    0.028733f,
+    0.016122f,
+    0.000456f,
+    -0.008844f,
+    -0.021433f,
+    -0.027822f,
+    -0.037800f,
+    -0.043456f,
+    -0.046278f,
+    -0.050422f,
+    -0.054033f,
+    -0.056922f,
+    -0.059178f,
+    -0.061178f,
+    -0.051067f,
+    -0.052189f,
+    -0.052933f,
+    -0.036522f,
+    -0.002267f,
+    0.011256f,
+    0.016722f,
+    0.025822f,
+    0.026389f,
+    0.041378f,
+    0.063489f,
+    0.091756f,
+    0.095667f,
+    0.111178f,
+    0.110911f,
+    0.138200f,
+    0.154422f,
+    0.167322f,
+    0.166678f,
+    0.165444f,
+    0.172978f,
+    0.170989f,
+    0.168667f,
+    0.165911f,
+    0.162311f,
+    0.158300f,
+    0.154300f,
+    0.148878f,
+    0.142022f,
+    0.135111f,
+    0.128011f,
+    0.114556f,
+    0.104456f,
+    0.091233f,
+    0.081500f,
+    0.072100f,
+    0.067722f,
+    0.061144f,
+    0.056956f,
+    0.053444f,
+    0.049611f,
+    0.046044f,
+    0.048300f,
+    0.046567f,
+    0.044844f,
+    0.050533f,
+    0.054056f,
+    0.053867f,
+    0.057667f,
+    0.075333f,
+    0.092289f,
+    0.104878f,
+    0.118544f,
+    0.148133f,
+    0.164289f,
+    0.175767f,
+    0.179678f,
+    0.205100f,
+    0.240022f,
+    0.249722f,
+    0.264844f,
+    0.282267f,
+    0.308311f,
+    0.307533f,
+    0.312278f,
+    0.315011f,
+    0.317444f,
+    0.315356f,
+    0.311189f,
+    0.308800f,
+    0.305378f,
+    0.298456f,
+    0.291322f,
+    0.282078f,
+    0.269656f,
+    0.254633f,
+    0.223600f,
+    0.206937f,
+    0.186637f,
+    0.168212f,
+    0.147600f,
+    0.125762f,
+    0.106925f,
+    0.087950f,
+    0.068825f,
+    0.048275f,
+    0.033750f,
+    0.020487f,
+    0.013150f,
+    0.003463f,
+    -0.000300f,
+    -0.004688f,
+    -0.009862f,
+    -0.012937f,
+    -0.014512f,
+    -0.016362f,
+    -0.017800f,
+    -0.019025f,
+    -0.013850f,
+    -0.014350f,
+    -0.014625f,
+    0.008650f,
+    0.042788f,
+    0.042350f,
+    0.046075f,
+    0.075900f,
+    0.075612f,
+    0.104062f,
+    0.115525f,
+    0.124863f,
+    0.130425f,
+    0.153550f,
+    0.180412f,
+    0.184850f,
+    0.184150f,
+    0.188550f,
+    0.187450f,
+    0.186200f,
+    0.184375f,
+    0.182925f,
+    0.181513f,
+    0.180075f,
+    0.177537f,
+    0.174738f,
+    0.166488f,
+    0.162538f,
+    0.158687f,
+    0.151350f,
+    0.141400f,
+    0.131050f,
+    0.126537f,
+    0.118325f,
+    0.110800f,
+    0.105075f,
+    0.099450f,
+    0.095562f,
+    0.091587f,
+    0.087787f,
+    0.086038f,
+    0.083962f,
+    0.081988f,
+    0.080713f,
+    0.079387f,
+    0.092400f,
+    0.091650f,
+    0.096300f,
+    0.102363f,
+    0.130788f,
+    0.142975f,
+    0.156062f,
+    0.177737f,
+    0.181750f,
+    0.194938f,
+    0.218562f,
+    0.237150f,
+    0.241675f,
+    0.263600f,
+    0.278925f,
+    0.280550f,
+    0.285737f,
+    0.293287f,
+    0.292162f,
+    0.290687f,
+    0.288775f,
+    0.286700f,
+    0.283950f,
+    0.279587f,
+    0.273450f,
+    0.264912f,
+    0.260500f,
+    0.253000f,
+    0.242262f,
+    0.228337f,
+    0.205113f,
+    0.189350f,
+    0.167513f,
+    0.152163f,
+    0.137012f,
+    0.109750f,
+    0.090500f,
+    0.073212f,
+    0.055225f,
+    0.039313f,
+    0.030138f,
+    0.020412f,
+    0.010712f,
+    0.005900f,
+    -0.003062f,
+    -0.006125f,
+    -0.012237f,
+    -0.015137f,
+    -0.017588f,
+    -0.019413f,
+    -0.020788f,
+    -0.022250f,
+    -0.019425f,
+    -0.016475f,
+    -0.016550f,
+    -0.010287f,
+    0.007863f,
+    0.010088f,
+    0.015863f,
+    0.025475f,
+    0.054750f,
+    0.054762f,
+    0.054750f,
+    0.063125f,
+    0.061950f,
+    0.060675f,
+    0.059250f,
+    0.057775f,
+    0.055425f,
+    0.052138f,
+    0.049225f,
+    0.044250f,
+    0.041063f,
+    0.034250f,
+    0.020950f,
+    0.013100f,
+    -0.000088f,
+    -0.018775f,
+    -0.032112f,
+    -0.051988f,
+    -0.066225f,
+    -0.090050f,
+    -0.106900f,
+    -0.127850f,
+    -0.147450f,
+    -0.160662f,
+    -0.185425f,
+    -0.197650f,
+    -0.212438f,
+    -0.221537f,
+    -0.230100f,
+    -0.235375f,
+    -0.242938f,
+    -0.248425f,
+    -0.252638f,
+    -0.256400f,
+    -0.258512f,
+    -0.260412f,
+    -0.262063f,
+    -0.263437f,
+    -0.250412f,
+    -0.247262f,
+    -0.243762f,
+    -0.216513f,
+    -0.188000f,
+    -0.187738f,
+    -0.166950f,
+    -0.157925f,
+    -0.144262f,
+    -0.141987f,
+    -0.126812f,
+    -0.114813f,
+    -0.078900f,
+    -0.066388f,
+    -0.059825f,
+    -0.054700f,
+    -0.051788f,
+    -0.046537f,
+    -0.048375f,
+    -0.050350f,
+    -0.052612f,
+    -0.054575f,
+    -0.056838f,
+    -0.059225f,
+    -0.066025f,
+    -0.069225f,
+    -0.072987f,
+    -0.078925f,
+    -0.084250f,
+    -0.092325f,
+    -0.100650f,
+    -0.108437f,
+    -0.113962f,
+    -0.125875f,
+    -0.129862f,
+    -0.136650f,
+    -0.141538f,
+    -0.144613f,
+    -0.148025f,
+    -0.150888f,
+    -0.153487f,
+    -0.151950f,
+    -0.154062f,
+    -0.155637f,
+    -0.156587f,
+    -0.139875f,
+    -0.132288f,
+    -0.122637f,
+    -0.099613f,
+    -0.080550f,
+    -0.065850f,
+    -0.065825f,
+    -0.041462f,
+    -0.022937f,
+    -0.003950f,
+    0.004137f,
+    0.016862f,
+    0.031600f,
+    0.043437f,
+    0.082725f,
+    0.093387f,
+    0.093388f,
+    0.095537f,
+    0.094713f,
+    0.093700f,
+    0.092488f,
+    0.098988f,
+    0.097225f,
+    0.095450f,
+    0.089813f,
+    0.082825f,
+    0.075225f,
+    0.067675f,
+    0.055787f,
+    0.042925f,
+    0.027287f,
+    0.008050f,
+    -0.008725f,
+    -0.029712f,
+    -0.046450f,
+    -0.066787f,
+    -0.085337f,
+    -0.106137f,
+    -0.122488f,
+    -0.138212f,
+    -0.152013f,
+    -0.166063f,
+    -0.174412f,
+    -0.182100f,
+    -0.186800f,
+    -0.193225f,
+    -0.195700f,
+    -0.199112f,
+    -0.202075f,
+    -0.204363f,
+    -0.201075f,
+    -0.202300f,
+    -0.198900f,
+    -0.199625f,
+    -0.189287f,
+    -0.154800f,
+    -0.140088f,
+    -0.121388f,
+    -0.121438f,
+    -0.099450f,
+    -0.090275f,
+    -0.090938f,
+    -0.076000f,
+    -0.051950f,
+    -0.035850f,
+    -0.005587f,
+    0.001900f,
+    0.001263f,
+    0.000263f,
+    0.004600f,
+    0.003487f,
+    0.005013f,
+    0.003325f,
+    0.001587f,
+    -0.000687f,
+    -0.003950f,
+    -0.007675f,
+    -0.011225f,
+    -0.016912f,
+    -0.021625f,
+    -0.026088f,
+    -0.034425f,
+    -0.039475f,
+    -0.047012f,
+    -0.052100f,
+    -0.056488f,
+    -0.061825f,
+    -0.066187f,
+    -0.069775f,
+    -0.072862f,
+    -0.075025f,
+    -0.077150f,
+    -0.078963f,
+    -0.080587f,
+    -0.079225f,
+    -0.079563f,
+    -0.061700f,
+    -0.047800f,
+    -0.029513f,
+    -0.014063f,
+    -0.001800f,
+    -0.000688f,
+    0.033037f,
+    0.050812f,
+    0.072775f,
+    0.079725f,
+    0.098238f,
+    0.125113f,
+    0.140263f,
+    0.148400f,
+    0.177525f,
+    0.186750f,
+    0.212800f,
+    0.232737f,
+    0.233075f,
+    0.232575f,
+    0.231687f,
+    0.230262f,
+    0.231563f,
+    0.229538f,
+    0.226575f,
+    0.222437f,
+    0.219188f,
+    0.210638f,
+    0.204063f,
+    0.191300f,
+    0.174425f,
+    0.157862f,
+    0.140088f,
+    0.121700f,
+    0.102163f,
+    0.080450f,
+    0.064613f,
+    0.044737f,
+    0.023037f,
+    0.006525f,
+    -0.013575f,
+    -0.029563f,
+    -0.041750f,
+    -0.051112f,
+    -0.059325f,
+    -0.065188f,
+    -0.068837f,
+    -0.074200f,
+    -0.076050f,
+    -0.077925f,
+    -0.080325f,
+    -0.082263f,
+    -0.084050f,
+    -0.081638f,
+    -0.082762f,
+    -0.079338f,
+    -0.074625f,
+    -0.051850f,
+    -0.032313f,
+    -0.023350f,
+    -0.004000f,
+    -0.000813f,
+    0.018113f,
+    0.023000f,
+    0.029138f,
+    0.036663f,
+    0.063213f,
+    0.080213f,
+    0.079475f,
+    0.083937f,
+    0.080738f,
+    0.078775f,
+    0.076675f,
+    0.074038f,
+    0.071038f,
+    0.066175f,
+    0.063562f,
+    0.061000f,
+    0.054487f,
+    0.051287f,
+    0.042675f,
+    0.035787f,
+    0.023750f,
+    0.015000f,
+    0.003325f,
+    -0.007275f,
+    -0.015387f,
+    -0.022000f,
+    -0.027650f,
+    -0.033312f,
+    -0.038712f,
+    -0.041313f,
+    -0.044338f,
+    -0.046750f,
+    -0.048700f,
+    -0.050750f,
+    -0.044525f,
+    -0.045988f,
+    -0.047425f,
+    -0.048412f,
+    -0.043750f,
+    -0.013875f,
+    -0.006463f,
+    0.023662f,
+    0.029788f,
+    0.029213f,
+    0.036150f,
+    0.072737f,
+    0.114838f,
+    0.121875f,
+    0.121262f,
+    0.136550f,
+    0.136000f,
+    0.161687f,
+    0.176138f,
+    0.189462f,
+    0.203175f,
+    0.202125f,
+    0.200700f,
+    0.200925f,
+    0.198600f,
+    0.196275f,
+    0.192925f,
+    0.189675f,
+    0.184463f,
+    0.176425f,
+    0.171925f,
+    0.157600f,
+    0.147738f,
+    0.132038f,
+    0.121762f,
+    0.102563f,
+    0.089875f,
+    0.074962f,
+    0.056525f,
+    0.045975f,
+    0.030050f,
+    0.018488f,
+    0.006763f,
+    0.000412f,
+    -0.006663f,
+    -0.011038f,
+    -0.016600f,
+    -0.020463f,
+    -0.022750f,
+    -0.018350f,
+    -0.020437f,
+    -0.022363f,
+    -0.023750f,
+    -0.021138f,
+    -0.011175f,
+    0.008463f,
+    0.016275f,
+    0.018663f,
+    0.030888f,
+    0.057112f,
+    0.072813f,
+    0.098937f,
+    0.098625f,
+    0.110062f,
+    0.120450f,
+    0.124863f,
+    0.158075f,
+    0.174750f,
+    0.192425f,
+    0.191588f,
+    0.190075f,
+    0.187800f,
+    0.185475f,
+    0.182975f,
+    0.180788f,
+    0.178125f,
+    0.174312f,
+    0.167237f,
+    0.164225f,
+    0.153512f,
+    0.144025f,
+    0.128862f,
+    0.115825f,
+    0.099613f,
+    0.083500f,
+    0.067888f,
+    0.050450f,
+    0.035087f,
+    0.019650f,
+    0.002350f,
+    -0.010450f,
+    -0.024850f,
+    -0.032662f,
+    -0.039637f,
+    -0.045400f,
+    -0.051650f,
+    -0.054325f,
+    -0.056438f,
+    -0.058600f,
+    -0.060750f,
+    -0.062887f,
+    -0.065038f,
+    -0.067000f,
+    -0.068488f,
+    -0.069650f,
+    -0.064513f,
+    -0.017200f,
+    0.006775f,
+    0.020487f,
+    0.019225f,
+    0.023488f,
+    0.046962f,
+    0.054788f,
+    0.059300f,
+    0.084175f,
+    0.092287f,
+    0.118262f,
+    0.136662f,
+    0.138813f,
+    0.136550f,
+    0.134950f,
+    0.141637f,
+    0.139563f,
+    0.136525f,
+    0.133113f,
+    0.129725f,
+    0.126687f,
+    0.121375f,
+    0.117100f,
+    0.107187f,
+    0.101688f,
+    0.093413f,
+    0.078363f,
+    0.069425f,
+    0.055688f,
+    0.044225f,
+    0.028625f,
+    0.020200f,
+    0.011188f,
+    0.002813f,
+    -0.003375f,
+    -0.008463f,
+    -0.015050f,
+    -0.019188f,
+    -0.022775f,
+    -0.025062f,
+    -0.018350f,
+    -0.020063f,
+    -0.021425f,
+    -0.017513f,
+    -0.018125f,
+    -0.010225f,
+    -0.004325f,
+    0.023425f,
+    0.036163f,
+    0.046950f,
+    0.060050f,
+    0.070350f,
+    0.099275f,
+    0.115138f,
+    0.129988f,
+    0.143175f,
+    0.150838f,
+    0.184525f,
+    0.184575f,
+    0.216062f,
+    0.221425f,
+    0.224500f,
+    0.223413f,
+    0.222275f,
+    0.220312f,
+    0.218487f,
+    0.216062f,
+    0.213913f,
+    0.210287f,
+    0.202875f,
+    0.199200f,
+    0.190713f,
+    0.182188f,
+    0.167950f,
+    0.155375f,
+    0.137213f,
+    0.121762f,
+    0.105263f,
+    0.088688f,
+    0.072300f,
+    0.055337f,
+    0.039837f,
+    0.024125f,
+    0.009388f,
+    -0.000500f,
+    -0.014412f,
+    -0.022262f,
+    -0.027613f,
+    -0.035575f,
+    -0.038112f,
+    -0.040375f,
+    -0.042363f,
+    -0.044512f,
+    -0.041813f,
+    -0.043025f,
+    -0.044163f,
+    -0.041062f,
+    -0.034412f,
+    -0.014275f,
+    0.000012f,
+    0.005525f,
+    0.010688f,
+    0.031000f,
+    0.042688f,
+    0.073125f,
+    0.072937f,
+    0.099725f,
+    0.102700f,
+    0.112787f,
+    0.146363f,
+    0.161625f,
+    0.164212f,
+    0.163800f,
+    0.166475f,
+    0.164925f,
+    0.163288f,
+    0.161187f,
+    0.159125f,
+    0.159675f,
+    0.157300f,
+    0.155175f,
+    0.149850f,
+    0.143613f,
+    0.139025f,
+    0.134013f,
+    0.125250f,
+    0.116400f,
+    0.105912f,
+    0.096587f,
+    0.083300f,
+    0.075938f,
+    0.068475f,
+    0.061650f,
+    0.057813f,
+    0.053725f,
+    0.047625f,
+    0.043575f,
+    0.040925f,
+    0.038600f,
+    0.036337f,
+    0.034425f,
+    0.037738f,
+    0.042400f,
+    0.042875f,
+    0.058275f,
+    0.060125f,
+    0.103038f,
+    0.110363f,
+    0.115300f,
+    0.134862f,
+    0.134900f,
+    0.159350f,
+    0.180437f,
+    0.200050f,
+    0.203575f,
+    0.208737f,
+    0.249450f,
+    0.260750f,
+    0.262925f,
+    0.268087f,
+    0.266800f,
+    0.265100f,
+    0.263175f,
+    0.260988f,
+    0.258300f,
+    0.253775f,
+    0.246387f,
+    0.243275f,
+    0.230887f,
+    0.215525f,
+    0.197950f,
+    0.181237f,
+    0.160200f,
+    0.139775f,
+    0.118975f,
+    0.095188f,
+    0.075350f,
+    0.052950f,
+    0.028250f,
+    0.005338f,
+    -0.016325f,
+    -0.039600f,
+    -0.059150f,
+    -0.080138f,
+    -0.096725f,
+    -0.114687f,
+    -0.128388f,
+    -0.137050f,
+    -0.143900f,
+    -0.148650f,
+    -0.153088f,
+    -0.156762f,
+    -0.158988f,
+    -0.160900f,
+    -0.157575f,
+    -0.158950f,
+    -0.160100f,
+    -0.160963f,
+    -0.161362f,
+    -0.131887f,
+    -0.118062f,
+    -0.113050f,
+    -0.095688f,
+    -0.090425f,
+    -0.067463f,
+    -0.064038f,
+    -0.059925f,
+    -0.031637f,
+    -0.020388f,
+    -0.016300f,
+    -0.017262f,
+    -0.015462f,
+    -0.011475f,
+    -0.012987f,
+    -0.014487f,
+    -0.016350f,
+    -0.019450f,
+    -0.022912f,
+    -0.026238f,
+    -0.030000f,
+    -0.032987f,
+    -0.039638f,
+    -0.046350f,
+    -0.053213f,
+    -0.061763f,
+    -0.070675f,
+    -0.080213f,
+    -0.091487f,
+    -0.097625f,
+    -0.105812f,
+    -0.109213f,
+    -0.114425f,
+    -0.119025f,
+    -0.122312f,
+    -0.125062f,
+    -0.127488f,
+    -0.129888f,
+    -0.132537f,
+    -0.135212f,
+    -0.136800f,
+    -0.132712f,
+    -0.114687f,
+    -0.069275f,
+    -0.059112f,
+    -0.058838f,
+    -0.044100f,
+    -0.025938f,
+    -0.018613f,
+    0.007450f,
+    0.021038f,
+    0.025988f,
+    0.083925f,
+    0.084562f,
+    0.097950f,
+    0.115175f,
+    0.129750f,
+    0.136862f,
+    0.163925f,
+    0.176900f,
+    0.181975f,
+    0.186225f,
+    0.185175f,
+    0.200425f,
+    0.198412f,
+    0.195738f,
+    0.192887f,
+    0.190038f,
+    0.185062f,
+    0.176275f,
+    0.171687f,
+    0.158488f,
+    0.145875f,
+    0.132925f,
+    0.120012f,
+    0.107663f,
+    0.090800f,
+    0.083587f,
+    0.061800f,
+    0.050263f,
+    0.034325f,
+    0.022875f,
+    0.012637f,
+    0.001262f,
+    -0.003725f,
+    -0.009513f,
+    -0.013037f,
+    -0.016463f,
+    -0.019312f,
+    -0.021200f,
+    -0.022713f,
+    -0.024113f,
+    -0.025150f,
+    -0.025975f,
+    -0.020212f,
+    -0.008600f,
+    -0.008175f,
+    0.045013f,
+    0.048537f,
+    0.052350f,
+    0.058800f,
+    0.074213f,
+    0.081850f,
+    0.089987f,
+    0.112763f,
+    0.137238f,
+    0.139925f,
+    0.147663f,
+    0.153250f,
+    0.151563f,
+    0.149250f,
+    0.153425f,
+    0.150625f,
+    0.146962f,
+    0.143238f,
+    0.139437f,
+    0.129700f,
+    0.120913f,
+    0.111312f,
+    0.096125f,
+    0.080138f,
+    0.064750f,
+    0.045450f,
+    0.024738f,
+    0.005800f,
+    -0.012950f,
+    -0.033088f,
+    -0.053312f,
+    -0.072325f,
+    -0.092187f,
+    -0.110075f,
+    -0.126625f,
+    -0.143575f,
+    -0.155463f,
+    -0.163938f,
+    -0.171850f,
+    -0.176312f,
+    -0.180200f,
+    -0.185600f,
+    -0.188150f,
+    -0.190450f,
+    -0.192637f,
+    -0.194725f,
+    -0.196350f,
+    -0.197825f,
+    -0.192238f,
+    -0.185450f,
+    -0.173137f,
+    -0.127525f,
+    -0.117425f,
+    -0.107262f,
+    -0.095425f,
+    -0.092562f,
+    -0.088850f,
+    -0.076025f,
+    -0.067812f,
+    -0.018400f,
+    0.004163f,
+    0.003400f,
+    0.002600f,
+    0.001375f,
+    0.000338f,
+    0.010775f,
+    0.008925f,
+    0.006625f,
+    0.004413f,
+    0.002337f,
+    0.000038f,
+    -0.004512f,
+    -0.008838f,
+    -0.011550f,
+    -0.017475f,
+    -0.025875f,
+    -0.032712f,
+    -0.044713f,
+    -0.052850f,
+    -0.062775f,
+    -0.074038f,
+    -0.079375f,
+    -0.086413f,
+    -0.094488f,
+    -0.096963f,
+    -0.100112f,
+    -0.102950f,
+    -0.105450f,
+    -0.107088f,
+    -0.108525f,
+    -0.109625f,
+    -0.110775f,
+    -0.109063f,
+    -0.109563f,
+    -0.103688f,
+    -0.089012f,
+    -0.083550f,
+    -0.049250f,
+    -0.046087f,
+    -0.034612f,
+    -0.013375f,
+    -0.006125f,
+    0.011387f,
+    0.046050f,
+    0.057000f,
+    0.061863f,
+    0.079800f,
+    0.087550f,
+    0.136538f,
+    0.136625f,
+    0.155313f,
+    0.154575f,
+    0.157150f,
+    0.155738f,
+    0.154175f,
+    0.156938f,
+    0.155287f,
+    0.153300f,
+    0.149425f,
+    0.143537f,
+    0.139375f,
+    0.131738f,
+    0.123087f,
+    0.109700f,
+    0.097713f,
+    0.079038f,
+    0.066412f,
+    0.049200f,
+    0.030525f,
+    0.015125f,
+    -0.004813f,
+    -0.020037f,
+    -0.036187f,
+    -0.051925f,
+    -0.064075f,
+    -0.078537f,
+    -0.086975f,
+    -0.094537f,
+    -0.101650f,
+    -0.107513f,
+    -0.111175f,
+    -0.114513f,
+    -0.117425f,
+    -0.119650f,
+    -0.121525f,
+    -0.112625f,
+    -0.113513f,
+    -0.101988f,
+    -0.099850f,
+    -0.090175f,
+    -0.072737f,
+    -0.066037f,
+    -0.050200f,
+    -0.040138f,
+    -0.026650f,
+    -0.022425f,
+    0.004013f,
+    0.003850f,
+    0.039737f,
+    0.043313f,
+    0.045250f,
+    0.056850f,
+    0.055550f,
+    0.053763f,
+    0.051700f,
+    0.049287f,
+    0.047025f,
+    0.044087f,
+    0.042000f,
+    0.037225f,
+    0.032175f,
+    0.027463f,
+    0.019963f,
+    0.014612f,
+    0.007550f,
+    -0.005275f,
+    -0.016713f,
+    -0.025475f,
+    -0.039850f,
+    -0.049088f,
+    -0.057587f,
+    -0.064887f,
+    -0.068100f,
+    -0.073963f,
+    -0.076975f,
+    -0.080125f,
+    -0.082387f,
+    -0.084563f,
+    -0.086138f,
+    -0.087438f,
+    -0.082563f,
+    -0.082775f,
+    -0.081013f,
+    -0.066875f,
+    -0.047413f,
+    -0.034025f,
+    -0.017025f,
+    -0.010100f,
+    -0.007262f,
+    0.013900f,
+    0.061188f,
+    0.066925f,
+    0.069087f,
+    0.080075f,
+    0.083837f,
+    0.131162f,
+    0.158263f,
+    0.165212f,
+    0.166687f,
+    0.165125f,
+    0.163250f,
+    0.161025f,
+    0.158863f,
+    0.156537f,
+    0.154375f,
+    0.151113f,
+    0.143775f,
+    0.139937f,
+    0.129500f,
+    0.119700f,
+    0.102600f,
+    0.085450f,
+    0.069050f,
+    0.048700f,
+    0.029112f,
+    0.009163f,
+    -0.008150f,
+    -0.027475f,
+    -0.047100f,
+    -0.068700f,
+    -0.082475f,
+    -0.102462f,
+    -0.113900f,
+    -0.125312f,
+    -0.133812f,
+    -0.138500f,
+    -0.145613f,
+    -0.149400f,
+    -0.152712f,
+    -0.154688f,
+    -0.156525f,
+    -0.158163f,
+    -0.154463f,
+    -0.156025f,
+    -0.154700f,
+    -0.151437f,
+    -0.118212f,
+    -0.097475f,
+    -0.084588f,
+    -0.084762f,
+    -0.066162f,
+    -0.036838f,
+    -0.034000f,
+    -0.005913f,
+    0.014775f,
+    0.027100f,
+    0.031738f,
+    0.045937f,
+    0.078675f,
+    0.091587f,
+    0.092475f,
+    0.093200f,
+    0.092175f,
+    0.101337f,
+    0.100062f,
+    0.100387f,
+    0.098500f,
+    0.096225f,
+    0.094350f,
+    0.091987f,
+    0.088112f,
+    0.082962f,
+    0.078613f,
+    0.075412f,
+    0.070825f,
+    0.067725f,
+    0.064825f,
+    0.061775f,
+    0.058237f,
+    0.055162f,
+    0.051812f,
+    0.049713f,
+    0.047875f,
+    0.046188f,
+    0.050287f,
+    0.049362f,
+    0.048925f,
+    0.051962f,
+    0.060012f,
+    0.082500f,
+    0.095175f,
+    0.099963f,
+    0.107975f,
+    0.108400f,
+    0.167925f,
+    0.181687f,
+    0.184638f,
+    0.197625f,
+    0.206987f,
+    0.252200f,
+    0.270950f,
+    0.276888f,
+    0.292000f,
+    0.299625f,
+    0.339000f,
+    0.359450f,
+    0.359425f,
+    0.362475f,
+    0.365912f,
+    0.364663f,
+    0.362900f,
+    0.360262f,
+    0.357913f,
+    0.354112f,
+    0.350513f,
+    0.343600f,
+    0.336562f,
+    0.326425f,
+    0.318225f,
+    0.305538f,
+    0.284250f,
+    0.274000f,
+    0.249038f,
+    0.234050f,
+    0.215700f,
+    0.204187f,
+    0.184800f,
+    0.165238f,
+    0.150413f,
+    0.138900f,
+    0.125437f,
+    0.119075f,
+    0.110050f,
+    0.106763f,
+    0.101050f,
+    0.098037f,
+    0.095412f,
+    0.097737f,
+    0.095975f,
+    0.094425f,
+    0.096875f,
+    0.102287f,
+    0.101525f,
+    0.106862f,
+    0.122450f,
+    0.134000f,
+    0.159637f,
+    0.184362f,
+    0.195150f,
+    0.200075f,
+    0.199550f,
+    0.229087f,
+    0.230088f,
+    0.230637f,
+    0.229400f,
+    0.232800f,
+    0.231325f,
+    0.231725f,
+    0.229463f,
+    0.226900f,
+    0.222438f,
+    0.219350f,
+    0.210725f,
+    0.205587f,
+    0.197750f,
+    0.192213f,
+    0.181925f,
+    0.168900f,
+    0.150113f,
+    0.138662f,
+    0.123075f,
+    0.097338f,
+    0.087312f,
+    0.062512f,
+    0.048587f,
+    0.034588f,
+    0.014875f,
+    0.000638f,
+    -0.011213f,
+    -0.022638f,
+    -0.029513f,
+    -0.034750f,
+    -0.040025f,
+    -0.044163f,
+    -0.047138f,
+    -0.050100f,
+    -0.052600f,
+    -0.054600f,
+    -0.056013f,
+    -0.054087f,
+    -0.048488f,
+    -0.042362f,
+    -0.024250f,
+    0.001600f,
+    0.011725f,
+    0.022537f,
+    0.040050f,
+    0.051862f,
+    0.063113f,
+    0.075700f,
+    0.084200f,
+    0.100562f,
+    0.130488f,
+    0.147713f,
+    0.148475f,
+    0.157512f,
+    0.161175f,
+    0.160100f,
+    0.158675f,
+    0.157037f,
+    0.154938f,
+    0.152963f,
+    0.148050f,
+    0.144575f,
+    0.139588f,
+    0.132400f,
+    0.124475f,
+    0.113888f,
+    0.100175f,
+    0.092237f,
+    0.078988f,
+    0.065763f,
+    0.052600f,
+    0.037575f,
+    0.026888f,
+    0.015087f,
+    0.002125f,
+    -0.003938f,
+    -0.008188f,
+    -0.015200f,
+    -0.019975f,
+    -0.024562f,
+    -0.027237f,
+    -0.029875f,
+    -0.023762f,
+    -0.025887f,
+    -0.027537f,
+    -0.028562f,
+    -0.026150f,
+    0.000675f,
+    0.015212f,
+    0.031075f,
+    0.044213f,
+    0.046575f,
+    0.058150f,
+    0.072325f,
+    0.084112f,
+    0.116425f,
+    0.119425f,
+    0.134263f,
+    0.161775f,
+    0.164688f,
+    0.164150f,
+    0.164125f,
+    0.162625f,
+    0.160737f,
+    0.158300f,
+    0.155350f,
+    0.150800f,
+    0.144687f,
+    0.136175f,
+    0.127100f,
+    0.111775f,
+    0.095613f,
+    0.077687f,
+    0.059125f,
+    0.038837f,
+    0.016837f,
+    -0.006000f,
+    -0.028800f,
+    -0.048088f,
+    -0.069888f,
+    -0.092025f,
+    -0.109012f,
+    -0.131113f,
+    -0.147413f,
+    -0.165062f,
+    -0.177937f,
+    -0.189513f,
+    -0.200650f,
+    -0.206837f,
+    -0.212188f,
+    -0.215713f,
+    -0.217975f,
+    -0.220138f,
+    -0.221962f,
+    -0.223538f,
+    -0.224963f,
+    -0.226038f,
+    -0.227125f,
+    -0.208425f,
+    -0.208812f,
+    -0.192362f,
+    -0.168000f,
+    -0.160275f,
+    -0.127475f,
+    -0.123963f,
+    -0.121900f,
+    -0.114875f,
+    -0.088975f,
+    -0.061513f,
+    -0.050650f,
+    -0.050725f,
+    -0.049513f,
+    -0.050350f,
+    -0.051713f,
+    -0.053063f,
+    -0.054937f,
+    -0.058225f,
+    -0.062125f,
+    -0.067262f,
+    -0.073212f,
+    -0.080538f,
+    -0.088737f,
+    -0.102025f,
+    -0.111775f,
+    -0.127037f,
+    -0.140463f,
+    -0.154250f,
+    -0.165587f,
+    -0.180100f,
+    -0.189550f,
+    -0.198237f,
+    -0.206662f,
+    -0.211675f,
+    -0.214675f,
+    -0.217175f,
+    -0.219337f,
+    -0.221463f,
+    -0.222962f,
+    -0.223875f,
+    -0.203913f,
+    -0.187225f,
+    -0.177487f,
+    -0.164138f,
+    -0.154775f,
+    -0.127562f,
+    -0.108088f,
+    -0.078275f,
+    -0.068013f,
+    -0.042975f,
+    -0.034138f,
+    0.009063f,
+    0.042650f,
+    0.057725f,
+    0.064750f,
+    0.063650f,
+    0.068750f,
+    0.071000f,
+    0.069213f,
+    0.071712f,
+    0.065487f,
+    0.059387f,
+    0.050763f,
+    0.040837f,
+    0.029288f,
+    0.018363f,
+    0.002488f,
+    -0.015600f,
+    -0.039250f,
+    -0.063975f,
+    -0.094375f,
+    -0.126625f,
+    -0.164513f,
+    -0.196662f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+    -0.204700f,
+};
\ No newline at end of file
diff --git a/motors/pistol_grip/vtable_wheel.cc b/motors/pistol_grip/vtable_wheel.cc
new file mode 100644
index 0000000..92e9a19
--- /dev/null
+++ b/motors/pistol_grip/vtable_wheel.cc
@@ -0,0 +1,4099 @@
+extern const float kWheelCoggingTorque[4096];
+const float kWheelCoggingTorque[4096] = {
+    -0.161690f,
+    -0.114243f,
+    -0.106662f,
+    -0.094305f,
+    -0.064914f,
+    -0.034757f,
+    -0.009276f,
+    0.010967f,
+    0.018600f,
+    0.043138f,
+    0.048890f,
+    0.084971f,
+    0.102648f,
+    0.114095f,
+    0.122886f,
+    0.125129f,
+    0.122771f,
+    0.118814f,
+    0.114886f,
+    0.110552f,
+    0.103629f,
+    0.094795f,
+    0.082367f,
+    0.068667f,
+    0.051762f,
+    0.033810f,
+    0.011300f,
+    -0.010986f,
+    -0.034119f,
+    -0.058129f,
+    -0.082548f,
+    -0.106038f,
+    -0.128033f,
+    -0.149010f,
+    -0.167462f,
+    -0.185514f,
+    -0.201052f,
+    -0.211529f,
+    -0.219871f,
+    -0.225371f,
+    -0.229190f,
+    -0.232024f,
+    -0.235014f,
+    -0.237467f,
+    -0.238757f,
+    -0.237262f,
+    -0.236433f,
+    -0.212386f,
+    -0.160690f,
+    -0.149586f,
+    -0.136405f,
+    -0.121952f,
+    -0.106262f,
+    -0.052519f,
+    -0.032238f,
+    -0.023529f,
+    -0.000567f,
+    0.025505f,
+    0.048629f,
+    0.063214f,
+    0.069181f,
+    0.109219f,
+    0.131810f,
+    0.139257f,
+    0.138143f,
+    0.136671f,
+    0.136186f,
+    0.137005f,
+    0.134481f,
+    0.131638f,
+    0.127505f,
+    0.121157f,
+    0.114652f,
+    0.106505f,
+    0.096352f,
+    0.083719f,
+    0.069329f,
+    0.055233f,
+    0.038224f,
+    0.019833f,
+    0.005795f,
+    -0.008938f,
+    -0.020905f,
+    -0.029890f,
+    -0.036833f,
+    -0.043724f,
+    -0.049038f,
+    -0.054338f,
+    -0.057752f,
+    -0.059090f,
+    -0.061419f,
+    -0.063519f,
+    -0.065448f,
+    -0.061957f,
+    -0.055381f,
+    -0.036890f,
+    0.000819f,
+    0.028614f,
+    0.038629f,
+    0.060614f,
+    0.083195f,
+    0.093471f,
+    0.113538f,
+    0.167614f,
+    0.187786f,
+    0.186662f,
+    0.206600f,
+    0.216424f,
+    0.258176f,
+    0.286700f,
+    0.290033f,
+    0.288048f,
+    0.286048f,
+    0.285438f,
+    0.282600f,
+    0.279110f,
+    0.275219f,
+    0.269876f,
+    0.265100f,
+    0.265925f,
+    0.255825f,
+    0.243540f,
+    0.224185f,
+    0.205470f,
+    0.183840f,
+    0.160945f,
+    0.140590f,
+    0.120535f,
+    0.097710f,
+    0.077745f,
+    0.055660f,
+    0.035945f,
+    0.016470f,
+    0.002795f,
+    -0.009790f,
+    -0.018015f,
+    -0.025320f,
+    -0.031615f,
+    -0.036055f,
+    -0.040195f,
+    -0.044010f,
+    -0.047135f,
+    -0.049850f,
+    -0.051955f,
+    -0.049250f,
+    -0.040795f,
+    -0.031195f,
+    -0.002290f,
+    0.033150f,
+    0.042645f,
+    0.051995f,
+    0.050870f,
+    0.074275f,
+    0.092585f,
+    0.127065f,
+    0.140405f,
+    0.149595f,
+    0.151265f,
+    0.151855f,
+    0.149955f,
+    0.148045f,
+    0.145600f,
+    0.141665f,
+    0.139005f,
+    0.133630f,
+    0.128790f,
+    0.120410f,
+    0.113860f,
+    0.102245f,
+    0.085750f,
+    0.066745f,
+    0.048765f,
+    0.028665f,
+    0.009620f,
+    -0.015955f,
+    -0.034935f,
+    -0.062150f,
+    -0.080825f,
+    -0.100465f,
+    -0.119375f,
+    -0.135110f,
+    -0.144415f,
+    -0.157920f,
+    -0.165860f,
+    -0.170825f,
+    -0.177525f,
+    -0.180885f,
+    -0.182940f,
+    -0.183785f,
+    -0.177330f,
+    -0.174020f,
+    -0.174980f,
+    -0.154140f,
+    -0.133910f,
+    -0.119465f,
+    -0.085645f,
+    -0.078300f,
+    -0.055005f,
+    -0.004490f,
+    0.003335f,
+    0.032490f,
+    0.041960f,
+    0.074680f,
+    0.099220f,
+    0.122725f,
+    0.143985f,
+    0.152455f,
+    0.155215f,
+    0.155750f,
+    0.153865f,
+    0.152395f,
+    0.149025f,
+    0.144465f,
+    0.136965f,
+    0.131980f,
+    0.121990f,
+    0.109325f,
+    0.092865f,
+    0.076295f,
+    0.052365f,
+    0.025975f,
+    0.000455f,
+    -0.022820f,
+    -0.048995f,
+    -0.077175f,
+    -0.104570f,
+    -0.130715f,
+    -0.153295f,
+    -0.179195f,
+    -0.199070f,
+    -0.219630f,
+    -0.235055f,
+    -0.246095f,
+    -0.256785f,
+    -0.263350f,
+    -0.268475f,
+    -0.272900f,
+    -0.275370f,
+    -0.276145f,
+    -0.278065f,
+    -0.279995f,
+    -0.278880f,
+    -0.276215f,
+    -0.250900f,
+    -0.225590f,
+    -0.204910f,
+    -0.183375f,
+    -0.163775f,
+    -0.158825f,
+    -0.134700f,
+    -0.101920f,
+    -0.084435f,
+    -0.077705f,
+    -0.056910f,
+    -0.024100f,
+    -0.022545f,
+    -0.017925f,
+    -0.015300f,
+    -0.014320f,
+    -0.015475f,
+    -0.017700f,
+    -0.020125f,
+    -0.023405f,
+    -0.027925f,
+    -0.033500f,
+    -0.040375f,
+    -0.049435f,
+    -0.060735f,
+    -0.073780f,
+    -0.090535f,
+    -0.109335f,
+    -0.127635f,
+    -0.146470f,
+    -0.164470f,
+    -0.184485f,
+    -0.201540f,
+    -0.219745f,
+    -0.233830f,
+    -0.246575f,
+    -0.255500f,
+    -0.261600f,
+    -0.268060f,
+    -0.273135f,
+    -0.276510f,
+    -0.279545f,
+    -0.280050f,
+    -0.282640f,
+    -0.284870f,
+    -0.281530f,
+    -0.269085f,
+    -0.247215f,
+    -0.208655f,
+    -0.193935f,
+    -0.189310f,
+    -0.173375f,
+    -0.152370f,
+    -0.111690f,
+    -0.083280f,
+    -0.064710f,
+    -0.045010f,
+    -0.038390f,
+    -0.024820f,
+    -0.000470f,
+    0.045605f,
+    0.049470f,
+    0.049020f,
+    0.047000f,
+    0.050110f,
+    0.047855f,
+    0.045440f,
+    0.041975f,
+    0.037555f,
+    0.032220f,
+    0.023955f,
+    0.015705f,
+    0.003005f,
+    -0.013735f,
+    -0.031830f,
+    -0.051050f,
+    -0.071245f,
+    -0.091830f,
+    -0.111305f,
+    -0.131160f,
+    -0.152080f,
+    -0.170000f,
+    -0.188180f,
+    -0.203070f,
+    -0.215710f,
+    -0.225730f,
+    -0.233805f,
+    -0.238745f,
+    -0.243385f,
+    -0.247210f,
+    -0.250245f,
+    -0.250765f,
+    -0.243575f,
+    -0.242185f,
+    -0.235715f,
+    -0.222790f,
+    -0.177250f,
+    -0.176185f,
+    -0.156810f,
+    -0.137785f,
+    -0.121240f,
+    -0.087445f,
+    -0.057715f,
+    -0.042785f,
+    -0.001100f,
+    -0.000310f,
+    0.023030f,
+    0.028305f,
+    0.060015f,
+    0.098340f,
+    0.102530f,
+    0.107000f,
+    0.106095f,
+    0.102935f,
+    0.100020f,
+    0.095950f,
+    0.091595f,
+    0.086150f,
+    0.078975f,
+    0.069455f,
+    0.057685f,
+    0.037740f,
+    0.021450f,
+    0.001010f,
+    -0.020570f,
+    -0.044500f,
+    -0.067835f,
+    -0.090730f,
+    -0.113195f,
+    -0.134415f,
+    -0.156905f,
+    -0.175610f,
+    -0.193585f,
+    -0.208050f,
+    -0.218975f,
+    -0.226725f,
+    -0.233700f,
+    -0.238435f,
+    -0.241835f,
+    -0.243025f,
+    -0.245345f,
+    -0.243140f,
+    -0.245070f,
+    -0.239815f,
+    -0.235060f,
+    -0.188275f,
+    -0.157120f,
+    -0.135190f,
+    -0.136800f,
+    -0.132250f,
+    -0.087350f,
+    -0.047035f,
+    -0.019560f,
+    -0.014280f,
+    -0.007735f,
+    0.002470f,
+    0.027835f,
+    0.070310f,
+    0.092845f,
+    0.095520f,
+    0.093665f,
+    0.091425f,
+    0.089220f,
+    0.086385f,
+    0.083410f,
+    0.079145f,
+    0.073820f,
+    0.068050f,
+    0.059990f,
+    0.049040f,
+    0.034530f,
+    0.020050f,
+    0.002645f,
+    -0.014185f,
+    -0.030685f,
+    -0.049300f,
+    -0.066905f,
+    -0.082670f,
+    -0.097515f,
+    -0.109690f,
+    -0.118895f,
+    -0.126460f,
+    -0.131915f,
+    -0.135785f,
+    -0.138465f,
+    -0.139445f,
+    -0.141725f,
+    -0.143725f,
+    -0.145560f,
+    -0.143735f,
+    -0.142385f,
+    -0.120830f,
+    -0.077690f,
+    -0.061320f,
+    -0.048525f,
+    -0.049425f,
+    -0.010670f,
+    0.019640f,
+    0.034160f,
+    0.068205f,
+    0.094310f,
+    0.106605f,
+    0.127555f,
+    0.147180f,
+    0.154780f,
+    0.202710f,
+    0.222790f,
+    0.224470f,
+    0.221945f,
+    0.223605f,
+    0.221530f,
+    0.219360f,
+    0.216180f,
+    0.213070f,
+    0.207630f,
+    0.201295f,
+    0.193160f,
+    0.183085f,
+    0.169020f,
+    0.152800f,
+    0.134540f,
+    0.114160f,
+    0.094685f,
+    0.075295f,
+    0.056195f,
+    0.037555f,
+    0.019855f,
+    0.004505f,
+    -0.012150f,
+    -0.022100f,
+    -0.030225f,
+    -0.035955f,
+    -0.041530f,
+    -0.045130f,
+    -0.048035f,
+    -0.048295f,
+    -0.048115f,
+    -0.042695f,
+    -0.041460f,
+    -0.038205f,
+    -0.015325f,
+    0.016410f,
+    0.041105f,
+    0.048055f,
+    0.057445f,
+    0.099065f,
+    0.113350f,
+    0.143890f,
+    0.165120f,
+    0.179440f,
+    0.204595f,
+    0.214905f,
+    0.246815f,
+    0.264480f,
+    0.280615f,
+    0.279395f,
+    0.282745f,
+    0.284765f,
+    0.282645f,
+    0.279700f,
+    0.275515f,
+    0.271185f,
+    0.264315f,
+    0.256945f,
+    0.246300f,
+    0.234270f,
+    0.216680f,
+    0.197270f,
+    0.176170f,
+    0.155855f,
+    0.134845f,
+    0.112730f,
+    0.092345f,
+    0.071780f,
+    0.051775f,
+    0.035485f,
+    0.018435f,
+    0.007000f,
+    -0.001675f,
+    -0.008560f,
+    -0.012585f,
+    -0.016980f,
+    -0.019755f,
+    -0.022625f,
+    -0.025725f,
+    -0.028270f,
+    -0.024175f,
+    -0.011980f,
+    0.023655f,
+    0.063455f,
+    0.076430f,
+    0.085270f,
+    0.091545f,
+    0.111295f,
+    0.165320f,
+    0.186525f,
+    0.208805f,
+    0.214880f,
+    0.223635f,
+    0.261790f,
+    0.287290f,
+    0.304585f,
+    0.307115f,
+    0.314380f,
+    0.316585f,
+    0.312190f,
+    0.311815f,
+    0.306700f,
+    0.299575f,
+    0.289810f,
+    0.278190f,
+    0.261475f,
+    0.243555f,
+    0.222570f,
+    0.196865f,
+    0.170880f,
+    0.143255f,
+    0.116330f,
+    0.087710f,
+    0.058820f,
+    0.030350f,
+    0.002720f,
+    -0.024360f,
+    -0.050485f,
+    -0.074875f,
+    -0.096360f,
+    -0.115165f,
+    -0.131750f,
+    -0.142655f,
+    -0.152965f,
+    -0.160030f,
+    -0.164845f,
+    -0.168795f,
+    -0.168595f,
+    -0.171090f,
+    -0.170560f,
+    -0.169110f,
+    -0.163075f,
+    -0.147875f,
+    -0.106410f,
+    -0.085265f,
+    -0.079855f,
+    -0.051605f,
+    -0.043605f,
+    -0.021620f,
+    0.003540f,
+    0.031835f,
+    0.042510f,
+    0.060810f,
+    0.066380f,
+    0.097230f,
+    0.104695f,
+    0.106915f,
+    0.109445f,
+    0.109720f,
+    0.113085f,
+    0.110230f,
+    0.109855f,
+    0.105090f,
+    0.099375f,
+    0.091460f,
+    0.082415f,
+    0.069365f,
+    0.055495f,
+    0.040050f,
+    0.022605f,
+    0.006240f,
+    -0.011530f,
+    -0.028485f,
+    -0.044750f,
+    -0.059245f,
+    -0.073815f,
+    -0.084595f,
+    -0.093530f,
+    -0.101065f,
+    -0.106710f,
+    -0.111440f,
+    -0.114990f,
+    -0.117595f,
+    -0.114370f,
+    -0.116300f,
+    -0.118740f,
+    -0.118675f,
+    -0.109710f,
+    -0.083340f,
+    -0.052150f,
+    -0.032275f,
+    -0.024800f,
+    -0.011130f,
+    -0.000025f,
+    0.041245f,
+    0.083210f,
+    0.096405f,
+    0.107030f,
+    0.121365f,
+    0.136335f,
+    0.173510f,
+    0.197195f,
+    0.225325f,
+    0.226845f,
+    0.231170f,
+    0.229290f,
+    0.226855f,
+    0.226775f,
+    0.223795f,
+    0.219540f,
+    0.214350f,
+    0.207040f,
+    0.197025f,
+    0.185800f,
+    0.170920f,
+    0.151360f,
+    0.131020f,
+    0.108885f,
+    0.087220f,
+    0.063855f,
+    0.040565f,
+    0.016735f,
+    -0.003735f,
+    -0.022810f,
+    -0.042660f,
+    -0.061950f,
+    -0.079775f,
+    -0.093480f,
+    -0.104530f,
+    -0.112060f,
+    -0.118530f,
+    -0.123095f,
+    -0.126820f,
+    -0.127770f,
+    -0.125490f,
+    -0.127950f,
+    -0.129820f,
+    -0.113595f,
+    -0.096200f,
+    -0.048355f,
+    -0.049525f,
+    -0.039325f,
+    -0.021305f,
+    -0.006695f,
+    0.024220f,
+    0.050140f,
+    0.055810f,
+    0.079645f,
+    0.100310f,
+    0.121355f,
+    0.119890f,
+    0.117030f,
+    0.115120f,
+    0.113070f,
+    0.110655f,
+    0.107295f,
+    0.101205f,
+    0.096050f,
+    0.087330f,
+    0.077515f,
+    0.061100f,
+    0.041105f,
+    0.018785f,
+    -0.006035f,
+    -0.033085f,
+    -0.060180f,
+    -0.088620f,
+    -0.114895f,
+    -0.142945f,
+    -0.168875f,
+    -0.195390f,
+    -0.220700f,
+    -0.245685f,
+    -0.267545f,
+    -0.286180f,
+    -0.302375f,
+    -0.313470f,
+    -0.320805f,
+    -0.327160f,
+    -0.331285f,
+    -0.335015f,
+    -0.338355f,
+    -0.342140f,
+    -0.344900f,
+    -0.340800f,
+    -0.331520f,
+    -0.279400f,
+    -0.250280f,
+    -0.237615f,
+    -0.236930f,
+    -0.236625f,
+    -0.209050f,
+    -0.142935f,
+    -0.123825f,
+    -0.119085f,
+    -0.118350f,
+    -0.113565f,
+    -0.076695f,
+    -0.044160f,
+    -0.041435f,
+    -0.034970f,
+    -0.026710f,
+    -0.023750f,
+    -0.027575f,
+    -0.031105f,
+    -0.035495f,
+    -0.041020f,
+    -0.046755f,
+    -0.056595f,
+    -0.068155f,
+    -0.082065f,
+    -0.096785f,
+    -0.113350f,
+    -0.132070f,
+    -0.149280f,
+    -0.166970f,
+    -0.183470f,
+    -0.201250f,
+    -0.215540f,
+    -0.227695f,
+    -0.237240f,
+    -0.245550f,
+    -0.251345f,
+    -0.255975f,
+    -0.259715f,
+    -0.262350f,
+    -0.260645f,
+    -0.262820f,
+    -0.264545f,
+    -0.262520f,
+    -0.245250f,
+    -0.213035f,
+    -0.175700f,
+    -0.158465f,
+    -0.150145f,
+    -0.125895f,
+    -0.091195f,
+    -0.071710f,
+    -0.052160f,
+    -0.024950f,
+    0.010800f,
+    0.042900f,
+    0.063160f,
+    0.081260f,
+    0.097740f,
+    0.105305f,
+    0.149360f,
+    0.167775f,
+    0.172690f,
+    0.178720f,
+    0.174985f,
+    0.171965f,
+    0.170940f,
+    0.167510f,
+    0.162365f,
+    0.156470f,
+    0.147915f,
+    0.136835f,
+    0.122785f,
+    0.106655f,
+    0.088995f,
+    0.070195f,
+    0.049760f,
+    0.029995f,
+    0.010770f,
+    -0.008895f,
+    -0.027785f,
+    -0.044715f,
+    -0.060240f,
+    -0.074545f,
+    -0.084100f,
+    -0.091050f,
+    -0.096660f,
+    -0.100930f,
+    -0.104850f,
+    -0.107865f,
+    -0.111535f,
+    -0.114125f,
+    -0.111220f,
+    -0.104515f,
+    -0.087315f,
+    -0.057745f,
+    -0.032395f,
+    -0.021535f,
+    -0.009800f,
+    -0.006155f,
+    0.036965f,
+    0.069795f,
+    0.084715f,
+    0.092970f,
+    0.094360f,
+    0.115880f,
+    0.164110f,
+    0.175995f,
+    0.178130f,
+    0.178750f,
+    0.184790f,
+    0.184055f,
+    0.179155f,
+    0.174335f,
+    0.168730f,
+    0.162270f,
+    0.153040f,
+    0.138700f,
+    0.122365f,
+    0.104905f,
+    0.083970f,
+    0.062975f,
+    0.038470f,
+    0.015590f,
+    -0.009290f,
+    -0.032340f,
+    -0.056390f,
+    -0.077025f,
+    -0.099385f,
+    -0.118040f,
+    -0.136340f,
+    -0.150155f,
+    -0.162015f,
+    -0.171330f,
+    -0.177510f,
+    -0.182715f,
+    -0.186465f,
+    -0.188330f,
+    -0.185235f,
+    -0.178890f,
+    -0.181030f,
+    -0.158750f,
+    -0.124930f,
+    -0.106900f,
+    -0.085515f,
+    -0.084385f,
+    -0.059405f,
+    -0.030605f,
+    0.015570f,
+    0.029660f,
+    0.046600f,
+    0.057920f,
+    0.066905f,
+    0.106255f,
+    0.130620f,
+    0.151935f,
+    0.150145f,
+    0.152640f,
+    0.152040f,
+    0.149595f,
+    0.146395f,
+    0.141735f,
+    0.136405f,
+    0.128725f,
+    0.119090f,
+    0.104905f,
+    0.087775f,
+    0.068370f,
+    0.046530f,
+    0.023550f,
+    0.000335f,
+    -0.024055f,
+    -0.048540f,
+    -0.074230f,
+    -0.099780f,
+    -0.122385f,
+    -0.144050f,
+    -0.166250f,
+    -0.186800f,
+    -0.203255f,
+    -0.213675f,
+    -0.221780f,
+    -0.229280f,
+    -0.233630f,
+    -0.237140f,
+    -0.239690f,
+    -0.242180f,
+    -0.244365f,
+    -0.246395f,
+    -0.244460f,
+    -0.238350f,
+    -0.197170f,
+    -0.165165f,
+    -0.156470f,
+    -0.145305f,
+    -0.126860f,
+    -0.109040f,
+    -0.067880f,
+    -0.044700f,
+    -0.023520f,
+    -0.019740f,
+    -0.002965f,
+    0.013445f,
+    0.043260f,
+    0.069815f,
+    0.079825f,
+    0.085480f,
+    0.083600f,
+    0.081305f,
+    0.078805f,
+    0.076105f,
+    0.073215f,
+    0.068845f,
+    0.062345f,
+    0.056570f,
+    0.047355f,
+    0.034745f,
+    0.022280f,
+    0.006070f,
+    -0.011685f,
+    -0.027850f,
+    -0.045825f,
+    -0.062445f,
+    -0.079345f,
+    -0.093945f,
+    -0.107665f,
+    -0.118285f,
+    -0.127820f,
+    -0.133500f,
+    -0.139505f,
+    -0.144415f,
+    -0.147850f,
+    -0.150515f,
+    -0.153330f,
+    -0.155600f,
+    -0.153475f,
+    -0.152725f,
+    -0.142280f,
+    -0.114250f,
+    -0.096775f,
+    -0.074845f,
+    -0.071225f,
+    -0.064940f,
+    -0.014125f,
+    0.003875f,
+    0.029380f,
+    0.054825f,
+    0.064745f,
+    0.068685f,
+    0.083680f,
+    0.109000f,
+    0.145455f,
+    0.159965f,
+    0.162125f,
+    0.158940f,
+    0.155940f,
+    0.152930f,
+    0.149320f,
+    0.146180f,
+    0.140100f,
+    0.133345f,
+    0.122210f,
+    0.108600f,
+    0.091705f,
+    0.070625f,
+    0.048665f,
+    0.026750f,
+    0.002855f,
+    -0.022215f,
+    -0.047245f,
+    -0.071705f,
+    -0.096455f,
+    -0.120005f,
+    -0.141910f,
+    -0.163525f,
+    -0.182205f,
+    -0.197495f,
+    -0.209240f,
+    -0.217705f,
+    -0.224525f,
+    -0.228530f,
+    -0.230460f,
+    -0.232295f,
+    -0.234515f,
+    -0.233215f,
+    -0.235705f,
+    -0.237205f,
+    -0.216730f,
+    -0.182135f,
+    -0.162485f,
+    -0.157445f,
+    -0.147615f,
+    -0.117750f,
+    -0.089270f,
+    -0.066295f,
+    -0.048840f,
+    -0.035895f,
+    -0.034240f,
+    -0.000085f,
+    0.021555f,
+    0.027005f,
+    0.034465f,
+    0.032625f,
+    0.031315f,
+    0.028610f,
+    0.024600f,
+    0.021095f,
+    0.014395f,
+    0.005755f,
+    -0.005330f,
+    -0.018345f,
+    -0.035870f,
+    -0.055460f,
+    -0.077585f,
+    -0.102350f,
+    -0.128105f,
+    -0.150300f,
+    -0.174450f,
+    -0.198485f,
+    -0.222815f,
+    -0.245745f,
+    -0.266690f,
+    -0.285065f,
+    -0.299760f,
+    -0.309385f,
+    -0.317410f,
+    -0.323560f,
+    -0.328010f,
+    -0.331160f,
+    -0.331410f,
+    -0.333345f,
+    -0.331875f,
+    -0.333470f,
+    -0.320960f,
+    -0.294220f,
+    -0.283005f,
+    -0.242110f,
+    -0.230000f,
+    -0.216115f,
+    -0.179720f,
+    -0.155820f,
+    -0.120405f,
+    -0.093875f,
+    -0.073800f,
+    -0.044225f,
+    -0.020645f,
+    -0.006630f,
+    0.008140f,
+    0.036025f,
+    0.065815f,
+    0.079635f,
+    0.085575f,
+    0.083305f,
+    0.083800f,
+    0.081375f,
+    0.078230f,
+    0.074625f,
+    0.069575f,
+    0.063520f,
+    0.056875f,
+    0.048580f,
+    0.036960f,
+    0.024230f,
+    0.009910f,
+    -0.004245f,
+    -0.019445f,
+    -0.033165f,
+    -0.046115f,
+    -0.059310f,
+    -0.068670f,
+    -0.075745f,
+    -0.083545f,
+    -0.087965f,
+    -0.092040f,
+    -0.095440f,
+    -0.098700f,
+    -0.101505f,
+    -0.100240f,
+    -0.091190f,
+    -0.085630f,
+    -0.086485f,
+    -0.059620f,
+    -0.030065f,
+    -0.011150f,
+    0.007220f,
+    0.018015f,
+    0.064330f,
+    0.076155f,
+    0.093085f,
+    0.121510f,
+    0.166455f,
+    0.183135f,
+    0.199245f,
+    0.212325f,
+    0.217605f,
+    0.263355f,
+    0.278485f,
+    0.302175f,
+    0.305325f,
+    0.306735f,
+    0.305085f,
+    0.302760f,
+    0.302365f,
+    0.299720f,
+    0.295625f,
+    0.289465f,
+    0.280595f,
+    0.270715f,
+    0.258380f,
+    0.240975f,
+    0.221040f,
+    0.208560f,
+    0.186650f,
+    0.163535f,
+    0.142980f,
+    0.127555f,
+    0.103035f,
+    0.084325f,
+    0.070040f,
+    0.058115f,
+    0.046680f,
+    0.039275f,
+    0.032175f,
+    0.026875f,
+    0.023925f,
+    0.020225f,
+    0.018015f,
+    0.015715f,
+    0.013845f,
+    0.013370f,
+    0.016255f,
+    0.028840f,
+    0.073540f,
+    0.080680f,
+    0.098205f,
+    0.123050f,
+    0.132570f,
+    0.144750f,
+    0.175580f,
+    0.187760f,
+    0.224230f,
+    0.237660f,
+    0.248855f,
+    0.272260f,
+    0.284055f,
+    0.283685f,
+    0.287760f,
+    0.289245f,
+    0.290965f,
+    0.291975f,
+    0.287995f,
+    0.283300f,
+    0.276695f,
+    0.270275f,
+    0.263725f,
+    0.250170f,
+    0.236500f,
+    0.221260f,
+    0.202740f,
+    0.184355f,
+    0.163430f,
+    0.142490f,
+    0.124290f,
+    0.104825f,
+    0.084440f,
+    0.067995f,
+    0.051180f,
+    0.041995f,
+    0.031830f,
+    0.024200f,
+    0.015095f,
+    0.011220f,
+    0.007065f,
+    0.004110f,
+    0.001770f,
+    0.002690f,
+    0.002955f,
+    0.007645f,
+    0.019435f,
+    0.053435f,
+    0.082880f,
+    0.086875f,
+    0.094500f,
+    0.117755f,
+    0.143130f,
+    0.184200f,
+    0.218790f,
+    0.224215f,
+    0.234230f,
+    0.268895f,
+    0.278770f,
+    0.312030f,
+    0.326495f,
+    0.337885f,
+    0.340165f,
+    0.338965f,
+    0.338435f,
+    0.335830f,
+    0.331970f,
+    0.327205f,
+    0.321095f,
+    0.312975f,
+    0.304480f,
+    0.292475f,
+    0.274175f,
+    0.253450f,
+    0.230500f,
+    0.204815f,
+    0.177920f,
+    0.152390f,
+    0.126185f,
+    0.099215f,
+    0.072895f,
+    0.044995f,
+    0.020935f,
+    -0.003510f,
+    -0.026720f,
+    -0.045910f,
+    -0.063945f,
+    -0.077350f,
+    -0.088150f,
+    -0.097245f,
+    -0.102965f,
+    -0.107715f,
+    -0.111295f,
+    -0.113785f,
+    -0.114320f,
+    -0.116100f,
+    -0.113220f,
+    -0.110125f,
+    -0.095770f,
+    -0.071440f,
+    -0.047050f,
+    -0.032085f,
+    -0.017250f,
+    -0.003090f,
+    0.014530f,
+    0.013005f,
+    0.051095f,
+    0.050305f,
+    0.093015f,
+    0.111935f,
+    0.112690f,
+    0.111080f,
+    0.109070f,
+    0.107140f,
+    0.105045f,
+    0.102045f,
+    0.098055f,
+    0.093040f,
+    0.086475f,
+    0.079710f,
+    0.069575f,
+    0.057240f,
+    0.041310f,
+    0.023915f,
+    0.003510f,
+    -0.017415f,
+    -0.036215f,
+    -0.059400f,
+    -0.079160f,
+    -0.101870f,
+    -0.122595f,
+    -0.142370f,
+    -0.160375f,
+    -0.175555f,
+    -0.188360f,
+    -0.198545f,
+    -0.205615f,
+    -0.211650f,
+    -0.215670f,
+    -0.218520f,
+    -0.221325f,
+    -0.221000f,
+    -0.222975f,
+    -0.219800f,
+    -0.217870f,
+    -0.217390f,
+    -0.196680f,
+    -0.180055f,
+    -0.168845f,
+    -0.138010f,
+    -0.129685f,
+    -0.095315f,
+    -0.072410f,
+    -0.064400f,
+    -0.041920f,
+    -0.032450f,
+    -0.009600f,
+    0.011850f,
+    0.033175f,
+    0.040415f,
+    0.040860f,
+    0.041420f,
+    0.039445f,
+    0.037155f,
+    0.034225f,
+    0.031390f,
+    0.026535f,
+    0.020090f,
+    0.010520f,
+    -0.002045f,
+    -0.018130f,
+    -0.037520f,
+    -0.059430f,
+    -0.082090f,
+    -0.105400f,
+    -0.130330f,
+    -0.156130f,
+    -0.181195f,
+    -0.206070f,
+    -0.230855f,
+    -0.254090f,
+    -0.275865f,
+    -0.295820f,
+    -0.313765f,
+    -0.328455f,
+    -0.338915f,
+    -0.347595f,
+    -0.351380f,
+    -0.356855f,
+    -0.360720f,
+    -0.363105f,
+    -0.355795f,
+    -0.357475f,
+    -0.354170f,
+    -0.350235f,
+    -0.304980f,
+    -0.289430f,
+    -0.279780f,
+    -0.270830f,
+    -0.263235f,
+    -0.216440f,
+    -0.183240f,
+    -0.165085f,
+    -0.155245f,
+    -0.144025f,
+    -0.107555f,
+    -0.093250f,
+    -0.065440f,
+    -0.036865f,
+    -0.018870f,
+    -0.016520f,
+    -0.018810f,
+    -0.021850f,
+    -0.024590f,
+    -0.028505f,
+    -0.033175f,
+    -0.039595f,
+    -0.048830f,
+    -0.060285f,
+    -0.074955f,
+    -0.092635f,
+    -0.113685f,
+    -0.135000f,
+    -0.157570f,
+    -0.181085f,
+    -0.205460f,
+    -0.228700f,
+    -0.250050f,
+    -0.273690f,
+    -0.294165f,
+    -0.314645f,
+    -0.335205f,
+    -0.351705f,
+    -0.368290f,
+    -0.378855f,
+    -0.387240f,
+    -0.394880f,
+    -0.399795f,
+    -0.404605f,
+    -0.407535f,
+    -0.410480f,
+    -0.412200f,
+    -0.410485f,
+    -0.400100f,
+    -0.382070f,
+    -0.352555f,
+    -0.328120f,
+    -0.325295f,
+    -0.299072f,
+    -0.248738f,
+    -0.218213f,
+    -0.183925f,
+    -0.172625f,
+    -0.149487f,
+    -0.138950f,
+    -0.114562f,
+    -0.084131f,
+    -0.071869f,
+    -0.042269f,
+    -0.030062f,
+    -0.021125f,
+    -0.022600f,
+    -0.024250f,
+    -0.026262f,
+    -0.028419f,
+    -0.031088f,
+    -0.034150f,
+    -0.037994f,
+    -0.043700f,
+    -0.050681f,
+    -0.059125f,
+    -0.069837f,
+    -0.083131f,
+    -0.097338f,
+    -0.114425f,
+    -0.130725f,
+    -0.148087f,
+    -0.163863f,
+    -0.179962f,
+    -0.193344f,
+    -0.204819f,
+    -0.214281f,
+    -0.221269f,
+    -0.226500f,
+    -0.231131f,
+    -0.234925f,
+    -0.237581f,
+    -0.240950f,
+    -0.241275f,
+    -0.242731f,
+    -0.231331f,
+    -0.214063f,
+    -0.199656f,
+    -0.188450f,
+    -0.170031f,
+    -0.151688f,
+    -0.136181f,
+    -0.110281f,
+    -0.076400f,
+    -0.060125f,
+    -0.036350f,
+    -0.015887f,
+    0.005681f,
+    0.034537f,
+    0.066194f,
+    0.071119f,
+    0.081912f,
+    0.108575f,
+    0.138869f,
+    0.151900f,
+    0.155388f,
+    0.161519f,
+    0.162837f,
+    0.163606f,
+    0.161062f,
+    0.157150f,
+    0.153625f,
+    0.148556f,
+    0.142913f,
+    0.134550f,
+    0.124044f,
+    0.112388f,
+    0.097581f,
+    0.083400f,
+    0.065363f,
+    0.048694f,
+    0.032475f,
+    0.015219f,
+    0.001025f,
+    -0.014763f,
+    -0.029581f,
+    -0.038237f,
+    -0.046512f,
+    -0.052419f,
+    -0.056431f,
+    -0.060100f,
+    -0.062506f,
+    -0.064669f,
+    -0.066469f,
+    -0.067981f,
+    -0.061675f,
+    -0.057238f,
+    -0.048075f,
+    -0.020612f,
+    -0.002781f,
+    0.018431f,
+    0.025913f,
+    0.041194f,
+    0.061444f,
+    0.087263f,
+    0.123994f,
+    0.147969f,
+    0.155694f,
+    0.180344f,
+    0.188444f,
+    0.193325f,
+    0.235162f,
+    0.255794f,
+    0.268313f,
+    0.275044f,
+    0.273575f,
+    0.273094f,
+    0.271000f,
+    0.268706f,
+    0.265906f,
+    0.262319f,
+    0.257219f,
+    0.248694f,
+    0.242231f,
+    0.229150f,
+    0.213700f,
+    0.195944f,
+    0.178806f,
+    0.157719f,
+    0.139156f,
+    0.118875f,
+    0.099169f,
+    0.079206f,
+    0.060713f,
+    0.041794f,
+    0.026094f,
+    0.014563f,
+    0.002675f,
+    -0.004194f,
+    -0.010725f,
+    -0.015850f,
+    -0.018581f,
+    -0.021006f,
+    -0.023181f,
+    -0.023719f,
+    -0.025450f,
+    -0.026900f,
+    -0.015056f,
+    0.006062f,
+    0.052012f,
+    0.065094f,
+    0.072319f,
+    0.081969f,
+    0.106344f,
+    0.117269f,
+    0.168737f,
+    0.189944f,
+    0.195425f,
+    0.198425f,
+    0.228775f,
+    0.250406f,
+    0.274844f,
+    0.277494f,
+    0.281469f,
+    0.279537f,
+    0.277250f,
+    0.274075f,
+    0.270750f,
+    0.266738f,
+    0.259619f,
+    0.251556f,
+    0.238981f,
+    0.224906f,
+    0.204831f,
+    0.184306f,
+    0.161469f,
+    0.136181f,
+    0.109519f,
+    0.083012f,
+    0.056306f,
+    0.028619f,
+    0.001975f,
+    -0.025394f,
+    -0.050219f,
+    -0.076194f,
+    -0.099562f,
+    -0.122456f,
+    -0.142437f,
+    -0.163188f,
+    -0.178013f,
+    -0.188106f,
+    -0.195288f,
+    -0.199950f,
+    -0.206581f,
+    -0.210144f,
+    -0.212594f,
+    -0.214869f,
+    -0.216831f,
+    -0.215950f,
+    -0.205931f,
+    -0.195706f,
+    -0.159894f,
+    -0.148988f,
+    -0.138688f,
+    -0.134300f,
+    -0.112225f,
+    -0.098881f,
+    -0.071681f,
+    -0.033037f,
+    -0.033881f,
+    -0.032119f,
+    -0.007700f,
+    0.017750f,
+    0.026225f,
+    0.028281f,
+    0.028500f,
+    0.026919f,
+    0.031869f,
+    0.029769f,
+    0.027125f,
+    0.024287f,
+    0.019906f,
+    0.014287f,
+    0.007231f,
+    -0.001138f,
+    -0.011600f,
+    -0.025494f,
+    -0.041431f,
+    -0.057806f,
+    -0.075112f,
+    -0.089975f,
+    -0.107556f,
+    -0.123581f,
+    -0.139137f,
+    -0.153425f,
+    -0.165625f,
+    -0.174638f,
+    -0.182600f,
+    -0.187619f,
+    -0.193288f,
+    -0.196044f,
+    -0.199269f,
+    -0.201769f,
+    -0.204356f,
+    -0.206544f,
+    -0.208075f,
+    -0.202431f,
+    -0.186738f,
+    -0.165769f,
+    -0.145288f,
+    -0.135244f,
+    -0.122119f,
+    -0.086969f,
+    -0.065894f,
+    -0.051675f,
+    -0.035500f,
+    0.002575f,
+    0.029875f,
+    0.059269f,
+    0.070562f,
+    0.079931f,
+    0.095944f,
+    0.119719f,
+    0.153069f,
+    0.173906f,
+    0.172725f,
+    0.172769f,
+    0.170775f,
+    0.170975f,
+    0.168556f,
+    0.165200f,
+    0.161562f,
+    0.156975f,
+    0.148625f,
+    0.137444f,
+    0.125013f,
+    0.110294f,
+    0.091237f,
+    0.072062f,
+    0.052931f,
+    0.031263f,
+    0.010256f,
+    -0.010131f,
+    -0.029775f,
+    -0.049300f,
+    -0.066375f,
+    -0.085694f,
+    -0.103406f,
+    -0.117400f,
+    -0.126481f,
+    -0.134138f,
+    -0.139700f,
+    -0.143500f,
+    -0.146719f,
+    -0.149206f,
+    -0.151237f,
+    -0.153119f,
+    -0.154856f,
+    -0.156244f,
+    -0.154506f,
+    -0.144444f,
+    -0.099675f,
+    -0.078119f,
+    -0.064400f,
+    -0.063269f,
+    -0.054844f,
+    -0.018225f,
+    0.011325f,
+    0.028625f,
+    0.055306f,
+    0.064738f,
+    0.072306f,
+    0.100750f,
+    0.118056f,
+    0.137806f,
+    0.137037f,
+    0.137462f,
+    0.135856f,
+    0.134044f,
+    0.131481f,
+    0.128000f,
+    0.123275f,
+    0.117469f,
+    0.110619f,
+    0.100694f,
+    0.085900f,
+    0.068831f,
+    0.047762f,
+    0.026800f,
+    0.004981f,
+    -0.019313f,
+    -0.043019f,
+    -0.064906f,
+    -0.088762f,
+    -0.112931f,
+    -0.134231f,
+    -0.156106f,
+    -0.175450f,
+    -0.194256f,
+    -0.208106f,
+    -0.220500f,
+    -0.227913f,
+    -0.233519f,
+    -0.239063f,
+    -0.242294f,
+    -0.244988f,
+    -0.247269f,
+    -0.249156f,
+    -0.245763f,
+    -0.241731f,
+    -0.222406f,
+    -0.188537f,
+    -0.180931f,
+    -0.169181f,
+    -0.151256f,
+    -0.110538f,
+    -0.097419f,
+    -0.070337f,
+    -0.058987f,
+    -0.028131f,
+    0.003700f,
+    0.016306f,
+    0.027306f,
+    0.036831f,
+    0.063369f,
+    0.098944f,
+    0.101369f,
+    0.110600f,
+    0.112206f,
+    0.110375f,
+    0.108225f,
+    0.105769f,
+    0.102819f,
+    0.098631f,
+    0.095213f,
+    0.089356f,
+    0.082881f,
+    0.074556f,
+    0.065256f,
+    0.052275f,
+    0.039194f,
+    0.025256f,
+    0.011181f,
+    -0.003587f,
+    -0.016387f,
+    -0.027987f,
+    -0.038113f,
+    -0.046331f,
+    -0.052519f,
+    -0.056950f,
+    -0.060194f,
+    -0.063088f,
+    -0.065263f,
+    -0.067256f,
+    -0.066644f,
+    -0.068006f,
+    -0.064400f,
+    -0.057206f,
+    -0.037881f,
+    -0.025519f,
+    0.004413f,
+    0.020500f,
+    0.031325f,
+    0.059006f,
+    0.080212f,
+    0.092775f,
+    0.119569f,
+    0.151444f,
+    0.176931f,
+    0.191488f,
+    0.217394f,
+    0.235488f,
+    0.256944f,
+    0.281500f,
+    0.302756f,
+    0.321981f,
+    0.339206f,
+    0.351787f,
+    0.350788f,
+    0.353737f,
+    0.351813f,
+    0.349794f,
+    0.346869f,
+    0.343744f,
+    0.338200f,
+    0.333119f,
+    0.325994f,
+    0.315050f,
+    0.300856f,
+    0.284950f,
+    0.268700f,
+    0.249669f,
+    0.232494f,
+    0.213700f,
+    0.195394f,
+    0.177681f,
+    0.158337f,
+    0.143369f,
+    0.127263f,
+    0.113350f,
+    0.103200f,
+    0.095294f,
+    0.088737f,
+    0.084725f,
+    0.081187f,
+    0.078600f,
+    0.075831f,
+    0.073700f,
+    0.076731f,
+    0.079313f,
+    0.084663f,
+    0.096031f,
+    0.113656f,
+    0.148625f,
+    0.150556f,
+    0.169844f,
+    0.184531f,
+    0.198187f,
+    0.226919f,
+    0.228600f,
+    0.248663f,
+    0.266519f,
+    0.290119f,
+    0.308900f,
+    0.314188f,
+    0.323312f,
+    0.321625f,
+    0.319594f,
+    0.317206f,
+    0.314013f,
+    0.310256f,
+    0.305700f,
+    0.298813f,
+    0.290319f,
+    0.278619f,
+    0.261987f,
+    0.246194f,
+    0.225644f,
+    0.206063f,
+    0.182894f,
+    0.158025f,
+    0.134406f,
+    0.109450f,
+    0.085825f,
+    0.060050f,
+    0.035675f,
+    0.014069f,
+    -0.007975f,
+    -0.028906f,
+    -0.045881f,
+    -0.062644f,
+    -0.074856f,
+    -0.083038f,
+    -0.089356f,
+    -0.094431f,
+    -0.097963f,
+    -0.100581f,
+    -0.098813f,
+    -0.100544f,
+    -0.094025f,
+    -0.093981f,
+    -0.087544f,
+    -0.073444f,
+    -0.028175f,
+    -0.022963f,
+    -0.016000f,
+    -0.003769f,
+    0.028313f,
+    0.053925f,
+    0.069681f,
+    0.081306f,
+    0.104531f,
+    0.126412f,
+    0.149144f,
+    0.148388f,
+    0.156244f,
+    0.154781f,
+    0.156731f,
+    0.154550f,
+    0.151400f,
+    0.147594f,
+    0.143494f,
+    0.136175f,
+    0.127869f,
+    0.115700f,
+    0.100725f,
+    0.082094f,
+    0.061131f,
+    0.037425f,
+    0.012350f,
+    -0.014094f,
+    -0.041494f,
+    -0.068075f,
+    -0.095350f,
+    -0.122594f,
+    -0.150044f,
+    -0.175881f,
+    -0.201856f,
+    -0.226119f,
+    -0.248681f,
+    -0.267637f,
+    -0.282569f,
+    -0.296031f,
+    -0.306675f,
+    -0.312762f,
+    -0.318656f,
+    -0.322200f,
+    -0.324813f,
+    -0.327237f,
+    -0.329606f,
+    -0.331650f,
+    -0.333363f,
+    -0.323869f,
+    -0.311487f,
+    -0.264863f,
+    -0.239912f,
+    -0.229525f,
+    -0.224350f,
+    -0.209400f,
+    -0.173469f,
+    -0.155775f,
+    -0.138800f,
+    -0.114544f,
+    -0.108450f,
+    -0.088963f,
+    -0.045175f,
+    -0.040219f,
+    -0.025612f,
+    -0.024119f,
+    -0.021388f,
+    -0.023144f,
+    -0.025219f,
+    -0.027556f,
+    -0.030731f,
+    -0.034750f,
+    -0.038400f,
+    -0.043544f,
+    -0.050713f,
+    -0.058819f,
+    -0.071131f,
+    -0.082756f,
+    -0.097812f,
+    -0.113831f,
+    -0.131119f,
+    -0.146131f,
+    -0.163756f,
+    -0.177125f,
+    -0.194069f,
+    -0.209287f,
+    -0.220244f,
+    -0.229600f,
+    -0.236706f,
+    -0.241944f,
+    -0.248306f,
+    -0.251825f,
+    -0.255825f,
+    -0.258081f,
+    -0.261700f,
+    -0.261731f,
+    -0.258400f,
+    -0.256975f,
+    -0.238831f,
+    -0.230556f,
+    -0.202162f,
+    -0.185663f,
+    -0.164600f,
+    -0.146487f,
+    -0.137181f,
+    -0.121606f,
+    -0.088356f,
+    -0.064756f,
+    -0.023987f,
+    -0.017681f,
+    0.001612f,
+    0.007787f,
+    0.025625f,
+    0.048606f,
+    0.066875f,
+    0.076975f,
+    0.077169f,
+    0.075244f,
+    0.072987f,
+    0.070037f,
+    0.066756f,
+    0.061931f,
+    0.055863f,
+    0.048281f,
+    0.038537f,
+    0.023200f,
+    0.004862f,
+    -0.013406f,
+    -0.034594f,
+    -0.056919f,
+    -0.078844f,
+    -0.104119f,
+    -0.128613f,
+    -0.151425f,
+    -0.174906f,
+    -0.197669f,
+    -0.216956f,
+    -0.237531f,
+    -0.253944f,
+    -0.266625f,
+    -0.277881f,
+    -0.288769f,
+    -0.295325f,
+    -0.302300f,
+    -0.305950f,
+    -0.308844f,
+    -0.311413f,
+    -0.306375f,
+    -0.303638f,
+    -0.299531f,
+    -0.298438f,
+    -0.279106f,
+    -0.235675f,
+    -0.219356f,
+    -0.213837f,
+    -0.186863f,
+    -0.164744f,
+    -0.148994f,
+    -0.121000f,
+    -0.105237f,
+    -0.090887f,
+    -0.072087f,
+    -0.043281f,
+    -0.035581f,
+    -0.014250f,
+    -0.009869f,
+    -0.005594f,
+    -0.005638f,
+    -0.007931f,
+    -0.011781f,
+    -0.014513f,
+    -0.018606f,
+    -0.024512f,
+    -0.032162f,
+    -0.042831f,
+    -0.055469f,
+    -0.069269f,
+    -0.086594f,
+    -0.108038f,
+    -0.130919f,
+    -0.150737f,
+    -0.170575f,
+    -0.190750f,
+    -0.211388f,
+    -0.227144f,
+    -0.248938f,
+    -0.264488f,
+    -0.277738f,
+    -0.288613f,
+    -0.294700f,
+    -0.300369f,
+    -0.304950f,
+    -0.309194f,
+    -0.312506f,
+    -0.314706f,
+    -0.317056f,
+    -0.318681f,
+    -0.319912f,
+    -0.299212f,
+    -0.277856f,
+    -0.242531f,
+    -0.234369f,
+    -0.213987f,
+    -0.210981f,
+    -0.181950f,
+    -0.136594f,
+    -0.121844f,
+    -0.102781f,
+    -0.092506f,
+    -0.051881f,
+    -0.018138f,
+    -0.010281f,
+    -0.001581f,
+    0.011531f,
+    0.047875f,
+    0.077544f,
+    0.079544f,
+    0.081400f,
+    0.082869f,
+    0.081256f,
+    0.079525f,
+    0.077369f,
+    0.073206f,
+    0.069625f,
+    0.065194f,
+    0.058981f,
+    0.053413f,
+    0.045150f,
+    0.038363f,
+    0.026238f,
+    0.014519f,
+    0.000181f,
+    -0.013100f,
+    -0.023656f,
+    -0.034125f,
+    -0.041450f,
+    -0.051412f,
+    -0.055738f,
+    -0.062125f,
+    -0.065213f,
+    -0.070100f,
+    -0.073731f,
+    -0.076131f,
+    -0.077962f,
+    -0.075919f,
+    -0.077419f,
+    -0.077094f,
+    -0.067438f,
+    -0.042500f,
+    -0.004475f,
+    0.015119f,
+    0.017525f,
+    0.021412f,
+    0.044294f,
+    0.075156f,
+    0.123125f,
+    0.149706f,
+    0.156581f,
+    0.182481f,
+    0.186319f,
+    0.216937f,
+    0.237706f,
+    0.263519f,
+    0.279694f,
+    0.291881f,
+    0.292169f,
+    0.290381f,
+    0.288194f,
+    0.286856f,
+    0.283112f,
+    0.278631f,
+    0.274244f,
+    0.270069f,
+    0.260556f,
+    0.254556f,
+    0.241663f,
+    0.228950f,
+    0.214288f,
+    0.196288f,
+    0.177900f,
+    0.152881f,
+    0.136881f,
+    0.113600f,
+    0.094594f,
+    0.077044f,
+    0.058681f,
+    0.044725f,
+    0.036944f,
+    0.024044f,
+    0.017119f,
+    0.012544f,
+    0.008650f,
+    0.005962f,
+    0.000956f,
+    -0.001625f,
+    -0.004369f,
+    -0.006650f,
+    -0.008194f,
+    -0.003163f,
+    0.004106f,
+    0.014362f,
+    0.028856f,
+    0.059138f,
+    0.080756f,
+    0.098387f,
+    0.107594f,
+    0.121762f,
+    0.130244f,
+    0.157181f,
+    0.181844f,
+    0.203869f,
+    0.219081f,
+    0.223675f,
+    0.226175f,
+    0.226288f,
+    0.224881f,
+    0.223025f,
+    0.220406f,
+    0.217181f,
+    0.213300f,
+    0.205775f,
+    0.199819f,
+    0.193706f,
+    0.183525f,
+    0.172550f,
+    0.157531f,
+    0.138437f,
+    0.118250f,
+    0.100331f,
+    0.079556f,
+    0.060306f,
+    0.035138f,
+    0.018125f,
+    -0.001837f,
+    -0.018794f,
+    -0.030175f,
+    -0.044681f,
+    -0.048400f,
+    -0.056456f,
+    -0.063112f,
+    -0.066894f,
+    -0.070450f,
+    -0.073031f,
+    -0.075650f,
+    -0.077250f,
+    -0.071387f,
+    -0.068994f,
+    -0.067931f,
+    -0.023950f,
+    0.012594f,
+    0.019087f,
+    0.037812f,
+    0.048519f,
+    0.088194f,
+    0.117113f,
+    0.135963f,
+    0.151631f,
+    0.170800f,
+    0.197325f,
+    0.224094f,
+    0.260850f,
+    0.265356f,
+    0.281537f,
+    0.284294f,
+    0.282744f,
+    0.281675f,
+    0.280419f,
+    0.277675f,
+    0.272312f,
+    0.266569f,
+    0.260819f,
+    0.251394f,
+    0.241231f,
+    0.226462f,
+    0.208944f,
+    0.186900f,
+    0.162650f,
+    0.132194f,
+    0.110637f,
+    0.084812f,
+    0.060250f,
+    0.034219f,
+    0.008094f,
+    -0.020737f,
+    -0.041719f,
+    -0.059800f,
+    -0.081106f,
+    -0.100294f,
+    -0.113587f,
+    -0.121450f,
+    -0.129975f,
+    -0.134831f,
+    -0.140563f,
+    -0.143738f,
+    -0.145256f,
+    -0.144975f,
+    -0.141819f,
+    -0.139294f,
+    -0.140144f,
+    -0.129519f,
+    -0.107281f,
+    -0.075906f,
+    -0.052600f,
+    -0.052850f,
+    -0.037075f,
+    -0.007519f,
+    0.020856f,
+    0.037713f,
+    0.042819f,
+    0.057169f,
+    0.087781f,
+    0.110875f,
+    0.125937f,
+    0.130431f,
+    0.132225f,
+    0.130281f,
+    0.127925f,
+    0.125406f,
+    0.122925f,
+    0.118906f,
+    0.113306f,
+    0.107631f,
+    0.100581f,
+    0.092675f,
+    0.081806f,
+    0.067038f,
+    0.049563f,
+    0.031556f,
+    0.014100f,
+    -0.005013f,
+    -0.022900f,
+    -0.041956f,
+    -0.058981f,
+    -0.074944f,
+    -0.091194f,
+    -0.101656f,
+    -0.109656f,
+    -0.116888f,
+    -0.123500f,
+    -0.127662f,
+    -0.131363f,
+    -0.134844f,
+    -0.137894f,
+    -0.140738f,
+    -0.142963f,
+    -0.137425f,
+    -0.138644f,
+    -0.122881f,
+    -0.079581f,
+    -0.047306f,
+    -0.032056f,
+    -0.028475f,
+    -0.029169f,
+    -0.003638f,
+    0.072500f,
+    0.078881f,
+    0.083525f,
+    0.094500f,
+    0.103725f,
+    0.136275f,
+    0.163888f,
+    0.197013f,
+    0.196119f,
+    0.196056f,
+    0.192987f,
+    0.192194f,
+    0.191431f,
+    0.187387f,
+    0.182431f,
+    0.177163f,
+    0.169488f,
+    0.159231f,
+    0.146900f,
+    0.129619f,
+    0.112669f,
+    0.092269f,
+    0.068531f,
+    0.049263f,
+    0.027850f,
+    0.006244f,
+    -0.014869f,
+    -0.037387f,
+    -0.056187f,
+    -0.076088f,
+    -0.095975f,
+    -0.108800f,
+    -0.117669f,
+    -0.125706f,
+    -0.131769f,
+    -0.135531f,
+    -0.139669f,
+    -0.142388f,
+    -0.145775f,
+    -0.146237f,
+    -0.146781f,
+    -0.133969f,
+    -0.126625f,
+    -0.103444f,
+    -0.078944f,
+    -0.056825f,
+    -0.051194f,
+    -0.031113f,
+    0.001731f,
+    0.013669f,
+    0.031762f,
+    0.067819f,
+    0.086513f,
+    0.095744f,
+    0.098575f,
+    0.144675f,
+    0.169887f,
+    0.181625f,
+    0.182538f,
+    0.184000f,
+    0.181700f,
+    0.179113f,
+    0.175650f,
+    0.171756f,
+    0.165131f,
+    0.157331f,
+    0.148362f,
+    0.135513f,
+    0.117400f,
+    0.096025f,
+    0.075794f,
+    0.049750f,
+    0.027281f,
+    0.002362f,
+    -0.022263f,
+    -0.047125f,
+    -0.071450f,
+    -0.094606f,
+    -0.116219f,
+    -0.137212f,
+    -0.154700f,
+    -0.169344f,
+    -0.181987f,
+    -0.190906f,
+    -0.199313f,
+    -0.205119f,
+    -0.209444f,
+    -0.210800f,
+    -0.213313f,
+    -0.208550f,
+    -0.198006f,
+    -0.198963f,
+    -0.191019f,
+    -0.155650f,
+    -0.127944f,
+    -0.116944f,
+    -0.093850f,
+    -0.090725f,
+    -0.064675f,
+    -0.044606f,
+    -0.007169f,
+    0.011031f,
+    0.032356f,
+    0.046712f,
+    0.070844f,
+    0.078462f,
+    0.096656f,
+    0.106638f,
+    0.108544f,
+    0.106056f,
+    0.103575f,
+    0.100712f,
+    0.096706f,
+    0.092119f,
+    0.085638f,
+    0.078119f,
+    0.068769f,
+    0.057044f,
+    0.042213f,
+    0.024731f,
+    0.007244f,
+    -0.013319f,
+    -0.031987f,
+    -0.050713f,
+    -0.071331f,
+    -0.090000f,
+    -0.107419f,
+    -0.124919f,
+    -0.138956f,
+    -0.148194f,
+    -0.156188f,
+    -0.162256f,
+    -0.166594f,
+    -0.170775f,
+    -0.173956f,
+    -0.176150f,
+    -0.174450f,
+    -0.172625f,
+    -0.166725f,
+    -0.162969f,
+    -0.159125f,
+    -0.101450f,
+    -0.101656f,
+    -0.102894f,
+    -0.072912f,
+    -0.059963f,
+    -0.014494f,
+    0.014669f,
+    0.025581f,
+    0.044788f,
+    0.054700f,
+    0.073900f,
+    0.101162f,
+    0.129412f,
+    0.145888f,
+    0.152450f,
+    0.154637f,
+    0.156625f,
+    0.154500f,
+    0.152175f,
+    0.149694f,
+    0.146238f,
+    0.141287f,
+    0.135531f,
+    0.128325f,
+    0.116469f,
+    0.104038f,
+    0.088019f,
+    0.070444f,
+    0.051156f,
+    0.029863f,
+    0.009437f,
+    -0.011200f,
+    -0.031337f,
+    -0.051631f,
+    -0.070569f,
+    -0.087644f,
+    -0.102938f,
+    -0.116325f,
+    -0.125856f,
+    -0.131613f,
+    -0.137150f,
+    -0.141738f,
+    -0.145225f,
+    -0.148081f,
+    -0.147069f,
+    -0.149875f,
+    -0.152100f,
+    -0.153906f,
+    -0.132369f,
+    -0.088994f,
+    -0.069119f,
+    -0.061569f,
+    -0.049200f,
+    -0.015256f,
+    0.004400f,
+    0.036750f,
+    0.059444f,
+    0.071131f,
+    0.070031f,
+    0.077531f,
+    0.142062f,
+    0.171950f,
+    0.172831f,
+    0.176000f,
+    0.174181f,
+    0.174181f,
+    0.171662f,
+    0.168463f,
+    0.165631f,
+    0.159963f,
+    0.153544f,
+    0.145281f,
+    0.136113f,
+    0.123325f,
+    0.105850f,
+    0.085250f,
+    0.067587f,
+    0.046300f,
+    0.023975f,
+    0.000925f,
+    -0.020594f,
+    -0.041362f,
+    -0.059894f,
+    -0.078794f,
+    -0.097756f,
+    -0.110000f,
+    -0.120506f,
+    -0.128787f,
+    -0.133744f,
+    -0.138325f,
+    -0.140962f,
+    -0.140575f,
+    -0.135106f,
+    -0.136819f,
+    -0.138387f,
+    -0.139819f,
+    -0.129556f,
+    -0.089631f,
+    -0.061606f,
+    -0.038975f,
+    -0.031538f,
+    -0.007769f,
+    -0.004612f,
+    0.059831f,
+    0.079394f,
+    0.095950f,
+    0.103594f,
+    0.117988f,
+    0.139350f,
+    0.181600f,
+    0.186719f,
+    0.198825f,
+    0.196637f,
+    0.193200f,
+    0.188494f,
+    0.184769f,
+    0.180225f,
+    0.172387f,
+    0.161325f,
+    0.149438f,
+    0.132094f,
+    0.111875f,
+    0.089531f,
+    0.065287f,
+    0.036825f,
+    0.009931f,
+    -0.018200f,
+    -0.048594f,
+    -0.076800f,
+    -0.105388f,
+    -0.132406f,
+    -0.160794f,
+    -0.186469f,
+    -0.210775f,
+    -0.232338f,
+    -0.252019f,
+    -0.267619f,
+    -0.280381f,
+    -0.289644f,
+    -0.296994f,
+    -0.302706f,
+    -0.306462f,
+    -0.309881f,
+    -0.313525f,
+    -0.315750f,
+    -0.307525f,
+    -0.293944f,
+    -0.282450f,
+    -0.251212f,
+    -0.226325f,
+    -0.210987f,
+    -0.204450f,
+    -0.173231f,
+    -0.143187f,
+    -0.134844f,
+    -0.124781f,
+    -0.099100f,
+    -0.083056f,
+    -0.034987f,
+    -0.030744f,
+    -0.020162f,
+    -0.012987f,
+    -0.009969f,
+    -0.012356f,
+    -0.014894f,
+    -0.017394f,
+    -0.020219f,
+    -0.024469f,
+    -0.029319f,
+    -0.033537f,
+    -0.040644f,
+    -0.049644f,
+    -0.060381f,
+    -0.074750f,
+    -0.086688f,
+    -0.102306f,
+    -0.117188f,
+    -0.131281f,
+    -0.147531f,
+    -0.161425f,
+    -0.173375f,
+    -0.183606f,
+    -0.191769f,
+    -0.198031f,
+    -0.202662f,
+    -0.206525f,
+    -0.209394f,
+    -0.212137f,
+    -0.215525f,
+    -0.218406f,
+    -0.220694f,
+    -0.214412f,
+    -0.213237f,
+    -0.159637f,
+    -0.134744f,
+    -0.116700f,
+    -0.116344f,
+    -0.110912f,
+    -0.092840f,
+    -0.045313f,
+    -0.035827f,
+    0.000320f,
+    0.025660f,
+    0.047920f,
+    0.061213f,
+    0.076007f,
+    0.085193f,
+    0.121233f,
+    0.156607f,
+    0.155233f,
+    0.153413f,
+    0.151293f,
+    0.149040f,
+    0.149087f,
+    0.146640f,
+    0.143507f,
+    0.137667f,
+    0.132000f,
+    0.122420f,
+    0.113213f,
+    0.097900f,
+    0.079080f,
+    0.059000f,
+    0.037913f,
+    0.014693f,
+    -0.007800f,
+    -0.030120f,
+    -0.053140f,
+    -0.075453f,
+    -0.095673f,
+    -0.115587f,
+    -0.132073f,
+    -0.146687f,
+    -0.157707f,
+    -0.166227f,
+    -0.173467f,
+    -0.178547f,
+    -0.182167f,
+    -0.188507f,
+    -0.192153f,
+    -0.189907f,
+    -0.182833f,
+    -0.174747f,
+    -0.170887f,
+    -0.157240f,
+    -0.090387f,
+    -0.061893f,
+    -0.055387f,
+    -0.048353f,
+    -0.045593f,
+    -0.011773f,
+    0.015747f,
+    0.023620f,
+    0.058207f,
+    0.082733f,
+    0.099067f,
+    0.097860f,
+    0.110813f,
+    0.108400f,
+    0.104680f,
+    0.101513f,
+    0.100553f,
+    0.094180f,
+    0.086253f,
+    0.076773f,
+    0.062740f,
+    0.043800f,
+    0.023007f,
+    0.001600f,
+    -0.021553f,
+    -0.046287f,
+    -0.073020f,
+    -0.101780f,
+    -0.128440f,
+    -0.154260f,
+    -0.179153f,
+    -0.203240f,
+    -0.227460f,
+    -0.246773f,
+    -0.265313f,
+    -0.279907f,
+    -0.291047f,
+    -0.300820f,
+    -0.308360f,
+    -0.312393f,
+    -0.316340f,
+    -0.319707f,
+    -0.317220f,
+    -0.319280f,
+    -0.321233f,
+    -0.323653f,
+    -0.291420f,
+    -0.259987f,
+    -0.227320f,
+    -0.203833f,
+    -0.190133f,
+    -0.191640f,
+    -0.156520f,
+    -0.123580f,
+    -0.086180f,
+    -0.071987f,
+    -0.073913f,
+    -0.069533f,
+    -0.042840f,
+    0.011393f,
+    0.018500f,
+    0.023353f,
+    0.025253f,
+    0.022607f,
+    0.019833f,
+    0.016853f,
+    0.012693f,
+    0.009253f,
+    0.003580f,
+    -0.003193f,
+    -0.010813f,
+    -0.021360f,
+    -0.035427f,
+    -0.050813f,
+    -0.065700f,
+    -0.081780f,
+    -0.097640f,
+    -0.113353f,
+    -0.128007f,
+    -0.138673f,
+    -0.151340f,
+    -0.158993f,
+    -0.167467f,
+    -0.171553f,
+    -0.176120f,
+    -0.180680f,
+    -0.183760f,
+    -0.187340f,
+    -0.184993f,
+    -0.179213f,
+    -0.179020f,
+    -0.151513f,
+    -0.095493f,
+    -0.092187f,
+    -0.093673f,
+    -0.079760f,
+    -0.046880f,
+    -0.000753f,
+    0.029587f,
+    0.048640f,
+    0.065493f,
+    0.095260f,
+    0.145393f,
+    0.164140f,
+    0.176540f,
+    0.183180f,
+    0.201993f,
+    0.245313f,
+    0.252920f,
+    0.265713f,
+    0.278227f,
+    0.276040f,
+    0.272253f,
+    0.271847f,
+    0.268340f,
+    0.262533f,
+    0.256180f,
+    0.248640f,
+    0.236327f,
+    0.221820f,
+    0.205627f,
+    0.190560f,
+    0.170127f,
+    0.149533f,
+    0.131567f,
+    0.112393f,
+    0.093427f,
+    0.076947f,
+    0.058460f,
+    0.044907f,
+    0.030447f,
+    0.021260f,
+    0.013327f,
+    0.007393f,
+    0.002987f,
+    -0.000933f,
+    -0.004227f,
+    -0.002400f,
+    0.013607f,
+    0.022593f,
+    0.025300f,
+    0.042367f,
+    0.059540f,
+    0.092433f,
+    0.091513f,
+    0.110560f,
+    0.155500f,
+    0.167433f,
+    0.196847f,
+    0.220053f,
+    0.218833f,
+    0.228047f,
+    0.259247f,
+    0.279740f,
+    0.307887f,
+    0.306800f,
+    0.314480f,
+    0.310873f,
+    0.308100f,
+    0.305133f,
+    0.303853f,
+    0.298700f,
+    0.291567f,
+    0.282213f,
+    0.267547f,
+    0.251440f,
+    0.231267f,
+    0.211587f,
+    0.189413f,
+    0.166680f,
+    0.141913f,
+    0.117687f,
+    0.093727f,
+    0.071027f,
+    0.049280f,
+    0.028320f,
+    0.010587f,
+    -0.005347f,
+    -0.016647f,
+    -0.025473f,
+    -0.031907f,
+    -0.036533f,
+    -0.041160f,
+    -0.043893f,
+    -0.046200f,
+    -0.042467f,
+    -0.044267f,
+    -0.037273f,
+    -0.020860f,
+    0.012353f,
+    0.038260f,
+    0.058700f,
+    0.068460f,
+    0.099967f,
+    0.133227f,
+    0.147800f,
+    0.185260f,
+    0.191607f,
+    0.193707f,
+    0.221247f,
+    0.275213f,
+    0.275947f,
+    0.292947f,
+    0.290633f,
+    0.289480f,
+    0.285947f,
+    0.282413f,
+    0.278607f,
+    0.272500f,
+    0.266413f,
+    0.255333f,
+    0.240933f,
+    0.223907f,
+    0.203180f,
+    0.179953f,
+    0.156087f,
+    0.129807f,
+    0.103673f,
+    0.077320f,
+    0.049760f,
+    0.022953f,
+    -0.002580f,
+    -0.027133f,
+    -0.050447f,
+    -0.071287f,
+    -0.089493f,
+    -0.105093f,
+    -0.116627f,
+    -0.125640f,
+    -0.133440f,
+    -0.138480f,
+    -0.142093f,
+    -0.144633f,
+    -0.146933f,
+    -0.148987f,
+    -0.146147f,
+    -0.147540f,
+    -0.135653f,
+    -0.079047f,
+    -0.067220f,
+    -0.058640f,
+    -0.051533f,
+    -0.027127f,
+    0.012513f,
+    0.032360f,
+    0.042440f,
+    0.043020f,
+    0.064047f,
+    0.113027f,
+    0.140860f,
+    0.158727f,
+    0.159040f,
+    0.157140f,
+    0.155280f,
+    0.157900f,
+    0.155840f,
+    0.153720f,
+    0.149860f,
+    0.144207f,
+    0.139720f,
+    0.131593f,
+    0.123460f,
+    0.111593f,
+    0.096113f,
+    0.079907f,
+    0.063173f,
+    0.044673f,
+    0.027680f,
+    0.010220f,
+    -0.009580f,
+    -0.026127f,
+    -0.042293f,
+    -0.055753f,
+    -0.066860f,
+    -0.075933f,
+    -0.082253f,
+    -0.088033f,
+    -0.093560f,
+    -0.096840f,
+    -0.099353f,
+    -0.096307f,
+    -0.098487f,
+    -0.100287f,
+    -0.098413f,
+    -0.088347f,
+    -0.078973f,
+    -0.037447f,
+    -0.010080f,
+    0.001927f,
+    0.017447f,
+    0.029467f,
+    0.053253f,
+    0.074053f,
+    0.081007f,
+    0.114420f,
+    0.141207f,
+    0.162287f,
+    0.170207f,
+    0.172407f,
+    0.170567f,
+    0.170627f,
+    0.168033f,
+    0.165447f,
+    0.160720f,
+    0.155113f,
+    0.147587f,
+    0.138213f,
+    0.124153f,
+    0.106333f,
+    0.085567f,
+    0.062967f,
+    0.037273f,
+    0.012260f,
+    -0.013380f,
+    -0.041047f,
+    -0.069860f,
+    -0.097547f,
+    -0.124000f,
+    -0.150240f,
+    -0.174833f,
+    -0.197087f,
+    -0.218000f,
+    -0.235453f,
+    -0.248440f,
+    -0.258673f,
+    -0.264760f,
+    -0.271320f,
+    -0.276280f,
+    -0.279367f,
+    -0.274680f,
+    -0.270667f,
+    -0.273207f,
+    -0.274553f,
+    -0.271693f,
+    -0.226300f,
+    -0.210113f,
+    -0.193393f,
+    -0.181180f,
+    -0.156633f,
+    -0.143587f,
+    -0.128567f,
+    -0.111420f,
+    -0.091187f,
+    -0.052360f,
+    -0.034733f,
+    -0.036067f,
+    -0.038333f,
+    -0.040440f,
+    -0.042847f,
+    -0.045433f,
+    -0.048453f,
+    -0.053107f,
+    -0.059967f,
+    -0.067973f,
+    -0.079180f,
+    -0.094307f,
+    -0.112673f,
+    -0.135753f,
+    -0.158647f,
+    -0.183827f,
+    -0.211420f,
+    -0.236313f,
+    -0.262840f,
+    -0.289547f,
+    -0.314553f,
+    -0.340173f,
+    -0.359847f,
+    -0.380520f,
+    -0.395733f,
+    -0.409893f,
+    -0.417667f,
+    -0.424287f,
+    -0.428800f,
+    -0.432833f,
+    -0.435807f,
+    -0.434580f,
+    -0.434220f,
+    -0.431100f,
+    -0.428800f,
+    -0.396040f,
+    -0.361600f,
+    -0.362513f,
+    -0.327600f,
+    -0.314000f,
+    -0.272767f,
+    -0.266013f,
+    -0.225947f,
+    -0.189107f,
+    -0.165453f,
+    -0.141173f,
+    -0.133073f,
+    -0.131367f,
+    -0.100873f,
+    -0.052280f,
+    -0.032673f,
+    -0.034180f,
+    -0.036107f,
+    -0.038513f,
+    -0.041073f,
+    -0.043693f,
+    -0.047387f,
+    -0.051867f,
+    -0.056727f,
+    -0.063047f,
+    -0.070927f,
+    -0.081447f,
+    -0.092607f,
+    -0.109347f,
+    -0.124487f,
+    -0.140687f,
+    -0.155580f,
+    -0.168200f,
+    -0.184247f,
+    -0.194213f,
+    -0.207073f,
+    -0.215840f,
+    -0.221867f,
+    -0.226933f,
+    -0.229540f,
+    -0.233153f,
+    -0.235807f,
+    -0.233533f,
+    -0.235387f,
+    -0.229447f,
+    -0.220833f,
+    -0.191613f,
+    -0.162353f,
+    -0.151047f,
+    -0.151653f,
+    -0.110413f,
+    -0.063580f,
+    -0.056393f,
+    -0.043967f,
+    -0.033413f,
+    0.007420f,
+    0.049800f,
+    0.059087f,
+    0.063980f,
+    0.073287f,
+    0.105720f,
+    0.156160f,
+    0.157447f,
+    0.161753f,
+    0.159820f,
+    0.160320f,
+    0.160253f,
+    0.157140f,
+    0.153000f,
+    0.148947f,
+    0.140733f,
+    0.132760f,
+    0.122433f,
+    0.108840f,
+    0.094167f,
+    0.078287f,
+    0.055887f,
+    0.041520f,
+    0.015033f,
+    0.001847f,
+    -0.023147f,
+    -0.042513f,
+    -0.058040f,
+    -0.074307f,
+    -0.085493f,
+    -0.092540f,
+    -0.100493f,
+    -0.107213f,
+    -0.112980f,
+    -0.118227f,
+    -0.120900f,
+    -0.122887f,
+    -0.122847f,
+    -0.124547f,
+    -0.120353f,
+    -0.114727f,
+    -0.101233f,
+    -0.055893f,
+    -0.050460f,
+    -0.038727f,
+    -0.018993f,
+    0.003293f,
+    0.025453f,
+    0.048540f,
+    0.058213f,
+    0.077493f,
+    0.083693f,
+    0.121247f,
+    0.138167f,
+    0.139133f,
+    0.145527f,
+    0.146467f,
+    0.144427f,
+    0.142167f,
+    0.138980f,
+    0.134993f,
+    0.129600f,
+    0.125353f,
+    0.116940f,
+    0.109640f,
+    0.097773f,
+    0.083960f,
+    0.067980f,
+    0.051040f,
+    0.026920f,
+    0.011553f,
+    -0.007313f,
+    -0.025193f,
+    -0.045460f,
+    -0.057247f,
+    -0.071767f,
+    -0.081260f,
+    -0.091507f,
+    -0.098067f,
+    -0.103980f,
+    -0.107213f,
+    -0.111107f,
+    -0.113533f,
+    -0.113687f,
+    -0.115653f,
+    -0.115067f,
+    -0.102853f,
+    -0.086333f,
+    -0.046353f,
+    -0.022133f,
+    0.003067f,
+    0.015407f,
+    0.036820f,
+    0.048000f,
+    0.071607f,
+    0.115453f,
+    0.131153f,
+    0.143773f,
+    0.155687f,
+    0.166020f,
+    0.228533f,
+    0.248747f,
+    0.253667f,
+    0.251233f,
+    0.248387f,
+    0.245627f,
+    0.242720f,
+    0.240140f,
+    0.234580f,
+    0.228613f,
+    0.219353f,
+    0.209100f,
+    0.193853f,
+    0.172753f,
+    0.147620f,
+    0.126787f,
+    0.103373f,
+    0.079393f,
+    0.054967f,
+    0.025467f,
+    -0.000507f,
+    -0.024840f,
+    -0.048520f,
+    -0.073227f,
+    -0.094320f,
+    -0.111860f,
+    -0.125100f,
+    -0.135320f,
+    -0.145153f,
+    -0.152867f,
+    -0.158887f,
+    -0.162020f,
+    -0.165440f,
+    -0.167527f,
+    -0.169360f,
+    -0.171107f,
+    -0.170060f,
+    -0.168167f,
+    -0.142867f,
+    -0.093533f,
+    -0.084373f,
+    -0.068600f,
+    -0.062307f,
+    -0.047053f,
+    -0.020833f,
+    -0.021527f,
+    0.034467f,
+    0.050153f,
+    0.067513f,
+    0.072833f,
+    0.073147f,
+    0.075527f,
+    0.087020f,
+    0.085180f,
+    0.082913f,
+    0.080027f,
+    0.076273f,
+    0.071513f,
+    0.064420f,
+    0.057420f,
+    0.047687f,
+    0.035133f,
+    0.019367f,
+    0.001013f,
+    -0.017287f,
+    -0.036420f,
+    -0.056093f,
+    -0.075187f,
+    -0.095800f,
+    -0.114540f,
+    -0.132547f,
+    -0.149867f,
+    -0.163467f,
+    -0.175080f,
+    -0.183287f,
+    -0.190447f,
+    -0.195500f,
+    -0.200033f,
+    -0.203220f,
+    -0.207560f,
+    -0.211053f,
+    -0.207627f,
+    -0.187793f,
+    -0.188613f,
+    -0.167140f,
+    -0.142267f,
+    -0.134247f,
+    -0.135553f,
+    -0.108660f,
+    -0.074313f,
+    -0.048847f,
+    -0.040147f,
+    -0.029900f,
+    -0.001000f,
+    0.013620f,
+    0.041633f,
+    0.062113f,
+    0.072120f,
+    0.075407f,
+    0.074973f,
+    0.077113f,
+    0.078833f,
+    0.076287f,
+    0.073147f,
+    0.069273f,
+    0.064167f,
+    0.057400f,
+    0.048267f,
+    0.035967f,
+    0.018540f,
+    -0.002227f,
+    -0.021513f,
+    -0.043320f,
+    -0.066173f,
+    -0.090113f,
+    -0.114393f,
+    -0.133400f,
+    -0.157180f,
+    -0.179420f,
+    -0.198513f,
+    -0.216953f,
+    -0.231513f,
+    -0.242713f,
+    -0.252033f,
+    -0.258627f,
+    -0.263847f,
+    -0.267340f,
+    -0.270247f,
+    -0.273227f,
+    -0.275900f,
+    -0.275167f,
+    -0.263053f,
+    -0.232147f,
+    -0.208087f,
+    -0.206867f,
+    -0.188100f,
+    -0.145373f,
+    -0.132407f,
+    -0.089840f,
+    -0.075447f,
+    -0.059080f,
+    -0.026333f,
+    -0.009720f,
+    0.018020f,
+    0.026573f,
+    0.059567f,
+    0.079507f,
+    0.083140f,
+    0.081633f,
+    0.079833f,
+    0.077993f,
+    0.075473f,
+    0.072307f,
+    0.066933f,
+    0.062400f,
+    0.056573f,
+    0.046933f,
+    0.033407f,
+    0.016000f,
+    -0.004667f,
+    -0.025400f,
+    -0.048027f,
+    -0.071380f,
+    -0.093280f,
+    -0.117160f,
+    -0.138900f,
+    -0.160147f,
+    -0.181120f,
+    -0.198660f,
+    -0.215047f,
+    -0.228240f,
+    -0.236860f,
+    -0.243033f,
+    -0.247873f,
+    -0.251580f,
+    -0.250393f,
+    -0.250420f,
+    -0.252320f,
+    -0.254013f,
+    -0.255873f,
+    -0.252347f,
+    -0.220627f,
+    -0.188220f,
+    -0.184320f,
+    -0.143407f,
+    -0.142947f,
+    -0.095653f,
+    -0.073007f,
+    -0.048027f,
+    -0.019107f,
+    -0.007513f,
+    0.001107f,
+    0.014880f,
+    0.038327f,
+    0.090433f,
+    0.091233f,
+    0.098060f,
+    0.098153f,
+    0.102127f,
+    0.109247f,
+    0.106640f,
+    0.103667f,
+    0.103633f,
+    0.100067f,
+    0.094353f,
+    0.086087f,
+    0.076967f,
+    0.065267f,
+    0.050200f,
+    0.035547f,
+    0.018473f,
+    0.001200f,
+    -0.014467f,
+    -0.031253f,
+    -0.046953f,
+    -0.061427f,
+    -0.073320f,
+    -0.082127f,
+    -0.089027f,
+    -0.094387f,
+    -0.098600f,
+    -0.102120f,
+    -0.104493f,
+    -0.106860f,
+    -0.105887f,
+    -0.107520f,
+    -0.104380f,
+    -0.094893f,
+    -0.059420f,
+    -0.024007f,
+    -0.015293f,
+    -0.011933f,
+    0.004033f,
+    0.043580f,
+    0.069773f,
+    0.085333f,
+    0.114927f,
+    0.159247f,
+    0.183380f,
+    0.197993f,
+    0.199200f,
+    0.223687f,
+    0.236573f,
+    0.271133f,
+    0.296067f,
+    0.299927f,
+    0.300393f,
+    0.297800f,
+    0.295287f,
+    0.292800f,
+    0.289680f,
+    0.284793f,
+    0.279980f,
+    0.272860f,
+    0.262347f,
+    0.251207f,
+    0.235400f,
+    0.218660f,
+    0.200967f,
+    0.183627f,
+    0.163407f,
+    0.146053f,
+    0.127953f,
+    0.110260f,
+    0.095333f,
+    0.081320f,
+    0.071233f,
+    0.062887f,
+    0.056067f,
+    0.050820f,
+    0.046487f,
+    0.043200f,
+    0.041040f,
+    0.042827f,
+    0.041273f,
+    0.045500f,
+    0.044673f,
+    0.050520f,
+    0.088900f,
+    0.118100f,
+    0.128293f,
+    0.146340f,
+    0.155087f,
+    0.170807f,
+    0.199073f,
+    0.232267f,
+    0.245100f,
+    0.258547f,
+    0.275147f,
+    0.278620f,
+    0.325347f,
+    0.344673f,
+    0.346880f,
+    0.344987f,
+    0.342747f,
+    0.340707f,
+    0.340607f,
+    0.338307f,
+    0.334207f,
+    0.328827f,
+    0.322473f,
+    0.314373f,
+    0.302447f,
+    0.288580f,
+    0.270267f,
+    0.250553f,
+    0.230267f,
+    0.209440f,
+    0.187673f,
+    0.166347f,
+    0.144033f,
+    0.124367f,
+    0.103947f,
+    0.085760f,
+    0.068260f,
+    0.055147f,
+    0.044007f,
+    0.036233f,
+    0.029773f,
+    0.025480f,
+    0.024687f,
+    0.021273f,
+    0.028273f,
+    0.026220f,
+    0.033093f,
+    0.032007f,
+    0.051980f,
+    0.077627f,
+    0.106033f,
+    0.112640f,
+    0.111373f,
+    0.159440f,
+    0.186233f,
+    0.210953f,
+    0.232933f,
+    0.236173f,
+    0.245080f,
+    0.277173f,
+    0.287353f,
+    0.301040f,
+    0.311240f,
+    0.308833f,
+    0.314900f,
+    0.311773f,
+    0.307420f,
+    0.300940f,
+    0.291940f,
+    0.279813f,
+    0.263680f,
+    0.244493f,
+    0.222947f,
+    0.199013f,
+    0.173380f,
+    0.145793f,
+    0.116867f,
+    0.087507f,
+    0.057773f,
+    0.025547f,
+    -0.005920f,
+    -0.036727f,
+    -0.065480f,
+    -0.092827f,
+    -0.119873f,
+    -0.146487f,
+    -0.171080f,
+    -0.193427f,
+    -0.210707f,
+    -0.225573f,
+    -0.236493f,
+    -0.243500f,
+    -0.249173f,
+    -0.253087f,
+    -0.256627f,
+    -0.259227f,
+    -0.258120f,
+    -0.256773f,
+    -0.254547f,
+    -0.247673f,
+    -0.220340f,
+    -0.212100f,
+    -0.181540f,
+    -0.169607f,
+    -0.161507f,
+    -0.126847f,
+    -0.118647f,
+    -0.106473f,
+    -0.095880f,
+    -0.063627f,
+    -0.054907f,
+    -0.044480f,
+    -0.041187f,
+    -0.036360f,
+    -0.022120f,
+    -0.017373f,
+    -0.020980f,
+    -0.026427f,
+    -0.031240f,
+    -0.039233f,
+    -0.047660f,
+    -0.058060f,
+    -0.071407f,
+    -0.086780f,
+    -0.102533f,
+    -0.120720f,
+    -0.139867f,
+    -0.158860f,
+    -0.179820f,
+    -0.197313f,
+    -0.217060f,
+    -0.234560f,
+    -0.251260f,
+    -0.266127f,
+    -0.278480f,
+    -0.287327f,
+    -0.294773f,
+    -0.301353f,
+    -0.305860f,
+    -0.308947f,
+    -0.308320f,
+    -0.310520f,
+    -0.313133f,
+    -0.314693f,
+    -0.303220f,
+    -0.298807f,
+    -0.252487f,
+    -0.243347f,
+    -0.221793f,
+    -0.214260f,
+    -0.204807f,
+    -0.149567f,
+    -0.128987f,
+    -0.096120f,
+    -0.089567f,
+    -0.065927f,
+    -0.057433f,
+    -0.042340f,
+    -0.010727f,
+    0.017607f,
+    0.038953f,
+    0.041893f,
+    0.044120f,
+    0.041740f,
+    0.047720f,
+    0.045267f,
+    0.041820f,
+    0.035653f,
+    0.030220f,
+    0.023013f,
+    0.012140f,
+    -0.001987f,
+    -0.019420f,
+    -0.036947f,
+    -0.057473f,
+    -0.078180f,
+    -0.099773f,
+    -0.119260f,
+    -0.141113f,
+    -0.164080f,
+    -0.186033f,
+    -0.208040f,
+    -0.228160f,
+    -0.247347f,
+    -0.264167f,
+    -0.276847f,
+    -0.287113f,
+    -0.293933f,
+    -0.300533f,
+    -0.305800f,
+    -0.309353f,
+    -0.312233f,
+    -0.315160f,
+    -0.314653f,
+    -0.311393f,
+    -0.297193f,
+    -0.260727f,
+    -0.232020f,
+    -0.231953f,
+    -0.231127f,
+    -0.216893f,
+    -0.175380f,
+    -0.129633f,
+    -0.109093f,
+    -0.104500f,
+    -0.103160f,
+    -0.103973f,
+    -0.038213f,
+    -0.007180f,
+    -0.008213f,
+    -0.008013f,
+    -0.006260f,
+    -0.004307f,
+    -0.006827f,
+    -0.009800f,
+    -0.014107f,
+    -0.018833f,
+    -0.026167f,
+    -0.035873f,
+    -0.051127f,
+    -0.069353f,
+    -0.088473f,
+    -0.112273f,
+    -0.134147f,
+    -0.158020f,
+    -0.184247f,
+    -0.209440f,
+    -0.234980f,
+    -0.260947f,
+    -0.284300f,
+    -0.307153f,
+    -0.329767f,
+    -0.349920f,
+    -0.366093f,
+    -0.377840f,
+    -0.388973f,
+    -0.395893f,
+    -0.401793f,
+    -0.405173f,
+    -0.408153f,
+    -0.411020f,
+    -0.415200f,
+    -0.418053f,
+    -0.415653f,
+    -0.393747f,
+    -0.369660f,
+    -0.327613f,
+    -0.317300f,
+    -0.293253f,
+    -0.274180f,
+    -0.268553f,
+    -0.236080f,
+    -0.208333f,
+    -0.188460f,
+    -0.145420f,
+    -0.128287f,
+    -0.112907f,
+    -0.114267f,
+    -0.091700f,
+    -0.054933f,
+    -0.047307f,
+    -0.041120f,
+    -0.042453f,
+    -0.045180f,
+    -0.046920f,
+    -0.049233f,
+    -0.052060f,
+    -0.055020f,
+    -0.059300f,
+    -0.064307f,
+    -0.070193f,
+    -0.076653f,
+    -0.084427f,
+    -0.094900f,
+    -0.105993f,
+    -0.119367f,
+    -0.131273f,
+    -0.142960f,
+    -0.153653f,
+    -0.160940f,
+    -0.168887f,
+    -0.174787f,
+    -0.178840f,
+    -0.182447f,
+    -0.185580f,
+    -0.188080f,
+    -0.186680f,
+    -0.188560f,
+    -0.191380f,
+    -0.193460f,
+    -0.172380f,
+    -0.118407f,
+    -0.103300f,
+    -0.104347f,
+    -0.088953f,
+    -0.074933f,
+    -0.025607f,
+    0.003127f,
+    0.023100f,
+    0.058207f,
+    0.074360f,
+    0.096080f,
+    0.117273f,
+    0.146020f,
+    0.181613f,
+    0.199647f,
+    0.199313f,
+    0.222767f,
+    0.255747f,
+    0.269133f,
+    0.270593f,
+    0.272940f,
+    0.271407f,
+    0.269660f,
+    0.267540f,
+    0.264280f,
+    0.259820f,
+    0.254127f,
+    0.247413f,
+    0.239587f,
+    0.226200f,
+    0.212133f,
+    0.196740f,
+    0.179033f,
+    0.157073f,
+    0.139913f,
+    0.119480f,
+    0.099933f,
+    0.085580f,
+    0.071080f,
+    0.055867f,
+    0.044053f,
+    0.036607f,
+    0.030387f,
+    0.024367f,
+    0.019560f,
+    0.016467f,
+    0.013553f,
+    0.015887f,
+    0.018360f,
+    0.018447f,
+    0.023480f,
+    0.035227f,
+    0.061040f,
+    0.097940f,
+    0.109687f,
+    0.111180f,
+    0.134293f,
+    0.136247f,
+    0.147247f,
+    0.216740f,
+    0.215860f,
+    0.216180f,
+    0.260087f,
+    0.265967f,
+    0.274073f,
+    0.279000f,
+    0.277213f,
+    0.278847f,
+    0.276673f,
+    0.274073f,
+    0.270333f,
+    0.266080f,
+    0.260260f,
+    0.252387f,
+    0.240667f,
+    0.228560f,
+    0.211440f,
+    0.191000f,
+    0.170587f,
+    0.147160f,
+    0.124493f,
+    0.099720f,
+    0.077187f,
+    0.054040f,
+    0.031107f,
+    0.009300f,
+    -0.010193f,
+    -0.029173f,
+    -0.042947f,
+    -0.057133f,
+    -0.067873f,
+    -0.075620f,
+    -0.081007f,
+    -0.085360f,
+    -0.089827f,
+    -0.092273f,
+    -0.083667f,
+    -0.077987f,
+    -0.080440f,
+    -0.075873f,
+    -0.038447f,
+    -0.010580f,
+    0.007020f,
+    0.027313f,
+    0.033767f,
+    0.061613f,
+    0.086940f,
+    0.099593f,
+    0.115200f,
+    0.132713f,
+    0.158093f,
+    0.177113f,
+    0.201740f,
+    0.202940f,
+    0.205113f,
+    0.207053f,
+    0.204953f,
+    0.202573f,
+    0.199687f,
+    0.195220f,
+    0.189833f,
+    0.181120f,
+    0.172000f,
+    0.156713f,
+    0.137680f,
+    0.114867f,
+    0.093907f,
+    0.068713f,
+    0.042853f,
+    0.015347f,
+    -0.010947f,
+    -0.037840f,
+    -0.063827f,
+    -0.089840f,
+    -0.116347f,
+    -0.141087f,
+    -0.160813f,
+    -0.180907f,
+    -0.199767f,
+    -0.214147f,
+    -0.224840f,
+    -0.200772f,
+    -0.181829f,
+    -0.192738f,
+    -0.201057f,
+    -0.208290f,
+    -0.214395f,
+    -0.219571f,
+    -0.213576f,
+    -0.201148f,
+    -0.174829f,
+    -0.141224f,
+    -0.131505f,
+    -0.123110f,
+    -0.124462f,
+    -0.093995f,
+    -0.060324f,
+    -0.043571f,
+    -0.004562f,
+    0.016833f,
+    0.028629f,
+    0.028929f,
+    0.048100f,
+    0.074310f,
+    0.089276f,
+    0.092252f,
+    0.093457f,
+    0.097771f,
+    0.095529f,
+    0.092833f,
+    0.089452f,
+    0.086076f,
+    0.080648f,
+    0.074586f,
+    0.064967f,
+    0.055629f,
+    0.041362f,
+    0.027186f,
+    0.011248f,
+    -0.005348f,
+    -0.022533f,
+    -0.039757f,
+    -0.057181f,
+    -0.073738f,
+    -0.088533f,
+    -0.101305f,
+    -0.110681f,
+    -0.119095f,
+    -0.124067f,
+    -0.129243f,
+    -0.133676f,
+    -0.137000f,
+    -0.139419f,
+    -0.137543f,
+    -0.139748f,
+    -0.135795f,
+    -0.136829f,
+    -0.127386f,
+    -0.077514f,
+    -0.055914f,
+    -0.054995f,
+    -0.046371f,
+    -0.024052f,
+    0.016171f,
+    0.043138f,
+    0.046600f,
+    0.064605f,
+    0.096029f,
+    0.135214f,
+    0.139433f,
+    0.156105f,
+    0.183829f,
+    0.190548f,
+    0.197224f,
+    0.195686f,
+    0.197957f,
+    0.195867f,
+    0.193690f,
+    0.190324f,
+    0.185171f,
+    0.177748f,
+    0.169248f,
+    0.158724f,
+    0.143314f,
+    0.125000f,
+    0.102610f,
+    0.080119f,
+    0.056790f,
+    0.033062f,
+    0.010057f,
+    -0.015381f,
+    -0.038657f,
+    -0.063052f,
+    -0.084848f,
+    -0.106986f,
+    -0.125681f,
+    -0.142557f,
+    -0.154248f,
+    -0.162929f,
+    -0.170038f,
+    -0.176124f,
+    -0.180557f,
+    -0.183514f,
+    -0.184038f,
+    -0.186033f,
+    -0.182433f,
+    -0.178810f,
+    -0.177962f,
+};
\ No newline at end of file
diff --git a/motors/python/BUILD b/motors/python/BUILD
index 20dd786..458399f 100644
--- a/motors/python/BUILD
+++ b/motors/python/BUILD
@@ -10,3 +10,16 @@
     ],
     restricted_to = ["//tools:k8"],
 )
+
+py_binary(
+    name = "haptic_phase_current",
+    srcs = [
+        "haptic_phase_current.py",
+    ],
+    deps = [
+        "//external:python-gflags",
+        "//external:python-glog",
+        "//frc971/control_loops/python:controls",
+    ],
+    restricted_to = ["//tools:k8"],
+)
diff --git a/motors/python/haptic_phase_current.py b/motors/python/haptic_phase_current.py
new file mode 100755
index 0000000..b17c514
--- /dev/null
+++ b/motors/python/haptic_phase_current.py
@@ -0,0 +1,576 @@
+#!/usr/bin/python3
+
+import numpy
+from matplotlib import pylab
+import scipy.integrate
+from frc971.control_loops.python import controls
+import time
+import operator
+
+K1 = 1.81e04
+K2 = 0.0
+
+# Make the amplitude of the fundamental 1 for ease of playing with.
+K2 /= K1
+K1 = 1
+
+vcc = 14.0  # volts
+R_motor = 0.1073926073926074  # ohms for the motor
+R = R_motor + 0.080 + 0.02  # motor + fets + wires ohms for system
+
+L = 80.0 * 1e-6  # Henries
+M = L / 10.0
+
+Kv = 37.6  # rad/s/volt, where the voltage is measured from the neutral to the phase.
+J = 0.0000007
+
+R_shunt = 0.0003
+
+# RC circuit for current sense filtering.
+R_sense1 = 768.0
+R_sense2 = 1470.0
+C_sense = 10.0 * 1e-9
+
+# So, we measured the inductance by switching between ~5 and ~20 amps through
+# the motor.
+# We then looked at the change in voltage that should give us (assuming duty
+# cycle * vin), and divided it by the corresponding change in current.
+
+# We then looked at the amount of time it took to decay the current to 1/e
+# That gave us the inductance.
+
+# Overrides for experiments
+J = J * 10.0
+
+# Firing phase A -> 0.0
+# Firing phase B -> - numpy.pi * 2.0 / 3.0
+# Firing phase C -> + numpy.pi * 2.0 / 3.0
+
+hz = 20000.0
+
+#switching_pattern = 'front'
+switching_pattern = 'centered'
+#switching_pattern = 'rear'
+#switching_pattern = 'centered front shifted'
+#switching_pattern = 'anticentered'
+
+Vconv = numpy.matrix([[2.0, -1.0, -1.0],
+                      [-1.0, 2.0, -1.0],
+                      [-1.0, -1.0, 2.0]]) / 3.0
+
+def f_single(theta):
+  return K1 * numpy.sin(theta) + K2 * numpy.sin(theta * 5)
+
+def g_single(theta):
+  return K1 * numpy.sin(theta) - K2 * numpy.sin(theta * 5)
+
+def gdot_single(theta):
+  """Derivitive of the current.
+
+  Must be multiplied by omega externally.
+  """
+  return K1 * numpy.cos(theta) - 5.0 * K2 * numpy.cos(theta * 5.0)
+
+f = numpy.vectorize(f_single, otypes=(numpy.float,))
+g = numpy.vectorize(g_single, otypes=(numpy.float,))
+gdot = numpy.vectorize(gdot_single, otypes=(numpy.float,))
+
+def torque(theta):
+  return f(theta) * g(theta)
+
+def phase_a(function, theta):
+  return function(theta)
+
+def phase_b(function, theta):
+  return function(theta + 2 * numpy.pi / 3)
+
+def phase_c(function, theta):
+  return function(theta + 4 * numpy.pi / 3)
+
+def phases(function, theta):
+  return numpy.matrix([[phase_a(function, theta)],
+                       [phase_b(function, theta)],
+                       [phase_c(function, theta)]])
+
+def all_phases(function, theta_range):
+  return (phase_a(function, theta_range) +
+          phase_b(function, theta_range) +
+          phase_c(function, theta_range))
+
+theta_range = numpy.linspace(start=0, stop=4 * numpy.pi, num=10000)
+one_amp_driving_voltage = R * g(theta_range) + (L * gdot(theta_range) + M * gdot(theta_range + 2.0 / 3.0 * numpy.pi) + M * gdot(theta_range - 2.0 / 3.0 * numpy.pi)) * Kv * vcc / 2.0
+
+max_one_amp_driving_voltage = max(one_amp_driving_voltage)
+
+# The number to divide the product of the unit BEMF and the per phase current
+# by to get motor current.
+one_amp_scalar = (phases(f_single, 0.0).T * phases(g_single, 0.0))[0, 0]
+
+print 'Max BEMF', max(f(theta_range))
+print 'Max current', max(g(theta_range))
+print 'Max drive voltage (one_amp_driving_voltage)', max(one_amp_driving_voltage)
+print 'one_amp_scalar', one_amp_scalar
+
+pylab.figure()
+pylab.subplot(1, 1, 1)
+pylab.plot(theta_range, f(theta_range), label='bemf')
+pylab.plot(theta_range, g(theta_range), label='phase_current')
+pylab.plot(theta_range, torque(theta_range), label='phase_torque')
+pylab.plot(theta_range, all_phases(torque, theta_range), label='sum_torque/current')
+pylab.legend()
+
+
+def full_sample_times(Ton, Toff, dt, n, start_time):
+  """Returns n + 4 samples for the provided switching times.
+
+  We need the timesteps and Us to integrate.
+
+  Args:
+    Ton: On times for each phase.
+    Toff: Off times for each phase.
+    dt: The cycle time.
+    n: Number of intermediate points to include in the result.
+    start_time: Starting value for the t values in the result.
+
+  Returns:
+    array of [t, U matrix]
+  """
+
+  assert((Toff <= 1.0).all())
+  assert((Ton <= 1.0).all())
+  assert((Toff >= 0.0).all())
+  assert((Ton >= 0.0).all())
+
+  if (Ton <= Toff).all():
+    on_before_off = True
+  else:
+    # Verify that they are all ordered correctly.
+    assert(not (Ton <= Toff).any())
+    on_before_off = False
+
+  Toff = Toff.copy() * dt
+  Toff[Toff < 100e-9] = -1.0
+  Toff[Toff > dt] = dt
+
+  Ton = Ton.copy() * dt
+  Ton[Ton < 100e-9] = -1.0
+  Ton[Ton > dt - 100e-9] = dt + 1.0
+
+  result = []
+  t = 0
+
+  result_times = numpy.concatenate(
+      (numpy.linspace(0, dt, num=n),
+       numpy.reshape(numpy.asarray(Ton[numpy.logical_and(Ton < dt, Ton > 0.0)]), (-1,)),
+       numpy.reshape(numpy.asarray(Toff[numpy.logical_and(Toff < dt, Toff > 0.0)]), (-1,))
+       ))
+  result_times.sort()
+  assert((result_times >= 0).all())
+  assert((result_times <= dt).all())
+
+  for t in result_times:
+    if on_before_off:
+      U = numpy.matrix([[vcc], [vcc], [vcc]])
+      U[t <= Ton] = 0.0
+      U[Toff < t] = 0.0
+    else:
+      U = numpy.matrix([[0.0], [0.0], [0.0]])
+      U[t > Ton] = vcc
+      U[t <= Toff] = vcc
+    result.append((float(t + start_time), U.copy()))
+
+  return result
+
+def sample_times(T, dt, n, start_time):
+  if switching_pattern == 'rear':
+    T = 1.0 - T
+    ans = full_sample_times(T, numpy.matrix(numpy.ones((3, 1))) * 1.0, dt, n, start_time)
+  elif switching_pattern == 'centered front shifted':
+    # Centered, but shifted to the beginning of the cycle.
+    Ton = 0.5 - T / 2.0
+    Toff = 0.5 + T / 2.0
+
+    tn = min(Ton)[0, 0]
+    Ton -= tn
+    Toff -= tn
+
+    ans = full_sample_times(Ton, Toff, dt, n, start_time)
+  elif switching_pattern == 'centered':
+    # Centered, looks waaay better.
+    Ton = 0.5 - T / 2.0
+    Toff = 0.5 + T / 2.0
+
+    ans = full_sample_times(Ton, Toff, dt, n, start_time)
+  elif switching_pattern == 'anticentered':
+    # Centered, looks waaay better.
+    Toff = T / 2.0
+    Ton = 1.0 - T / 2.0
+
+    ans = full_sample_times(Ton, Toff, dt, n, start_time)
+  elif switching_pattern == 'front':
+    ans = full_sample_times(numpy.matrix(numpy.zeros((3, 1))), T, dt, n, start_time)
+  else:
+    assert(False)
+
+  return ans
+
+class DataLogger(object):
+  def __init__(self, title=None):
+    self.title = title
+    self.ia = []
+    self.ib = []
+    self.ic = []
+    self.ia_goal = []
+    self.ib_goal = []
+    self.ic_goal = []
+    self.ia_controls = []
+    self.ib_controls = []
+    self.ic_controls = []
+    self.isensea = []
+    self.isenseb = []
+    self.isensec = []
+
+    self.va = []
+    self.vb = []
+    self.vc = []
+    self.van = []
+    self.vbn = []
+    self.vcn = []
+
+    self.ea = []
+    self.eb = []
+    self.ec = []
+
+    self.theta = []
+    self.omega = []
+
+    self.i_goal = []
+
+    self.time = []
+    self.controls_time = []
+    self.predicted_time = []
+
+    self.ia_pred = []
+    self.ib_pred = []
+    self.ic_pred = []
+
+    self.voltage_time = []
+    self.estimated_velocity = []
+    self.U_last = numpy.matrix(numpy.zeros((3, 1)))
+
+  def log_predicted(self, current_time, p):
+    self.predicted_time.append(current_time)
+    self.ia_pred.append(p[0, 0])
+    self.ib_pred.append(p[1, 0])
+    self.ic_pred.append(p[2, 0])
+
+  def log_controls(self, current_time, measured_current, In, E, estimated_velocity):
+    self.controls_time.append(current_time)
+    self.ia_controls.append(measured_current[0, 0])
+    self.ib_controls.append(measured_current[1, 0])
+    self.ic_controls.append(measured_current[2, 0])
+
+    self.ea.append(E[0, 0])
+    self.eb.append(E[1, 0])
+    self.ec.append(E[2, 0])
+
+    self.ia_goal.append(In[0, 0])
+    self.ib_goal.append(In[1, 0])
+    self.ic_goal.append(In[2, 0])
+    self.estimated_velocity.append(estimated_velocity)
+
+  def log_data(self, X, U, current_time, Vn, i_goal):
+    self.ia.append(X[0, 0])
+    self.ib.append(X[1, 0])
+    self.ic.append(X[2, 0])
+
+    self.i_goal.append(i_goal)
+
+    self.isensea.append(X[5, 0])
+    self.isenseb.append(X[6, 0])
+    self.isensec.append(X[7, 0])
+
+    self.theta.append(X[3, 0])
+    self.omega.append(X[4, 0])
+
+    self.time.append(current_time)
+
+    self.van.append(Vn[0, 0])
+    self.vbn.append(Vn[1, 0])
+    self.vcn.append(Vn[2, 0])
+
+    if (self.U_last != U).any():
+      self.va.append(self.U_last[0, 0])
+      self.vb.append(self.U_last[1, 0])
+      self.vc.append(self.U_last[2, 0])
+      self.voltage_time.append(current_time)
+
+      self.va.append(U[0, 0])
+      self.vb.append(U[1, 0])
+      self.vc.append(U[2, 0])
+      self.voltage_time.append(current_time)
+      self.U_last = U.copy()
+
+  def plot(self):
+    fig = pylab.figure()
+    pylab.subplot(3, 1, 1)
+    pylab.plot(self.controls_time, self.ia_controls, 'ro', label='ia_controls')
+    pylab.plot(self.controls_time, self.ib_controls, 'go', label='ib_controls')
+    pylab.plot(self.controls_time, self.ic_controls, 'bo', label='ic_controls')
+    pylab.plot(self.controls_time, self.ia_goal, 'r--', label='ia_goal')
+    pylab.plot(self.controls_time, self.ib_goal, 'g--', label='ib_goal')
+    pylab.plot(self.controls_time, self.ic_goal, 'b--', label='ic_goal')
+
+    #pylab.plot(self.controls_time, self.ia_pred, 'r*', label='ia_pred')
+    #pylab.plot(self.controls_time, self.ib_pred, 'g*', label='ib_pred')
+    #pylab.plot(self.controls_time, self.ic_pred, 'b*', label='ic_pred')
+    pylab.plot(self.time, self.isensea, 'r:', label='ia_sense')
+    pylab.plot(self.time, self.isenseb, 'g:', label='ib_sense')
+    pylab.plot(self.time, self.isensec, 'b:', label='ic_sense')
+    pylab.plot(self.time, self.ia, 'r', label='ia')
+    pylab.plot(self.time, self.ib, 'g', label='ib')
+    pylab.plot(self.time, self.ic, 'b', label='ic')
+    pylab.plot(self.time, self.i_goal, label='i_goal')
+    if self.title is not None:
+      fig.canvas.set_window_title(self.title)
+    pylab.legend()
+
+    pylab.subplot(3, 1, 2)
+    pylab.plot(self.voltage_time, self.va, label='va')
+    pylab.plot(self.voltage_time, self.vb, label='vb')
+    pylab.plot(self.voltage_time, self.vc, label='vc')
+    pylab.plot(self.time, self.van, label='van')
+    pylab.plot(self.time, self.vbn, label='vbn')
+    pylab.plot(self.time, self.vcn, label='vcn')
+    pylab.plot(self.controls_time, self.ea, label='ea')
+    pylab.plot(self.controls_time, self.eb, label='eb')
+    pylab.plot(self.controls_time, self.ec, label='ec')
+    pylab.legend()
+
+    pylab.subplot(3, 1, 3)
+    pylab.plot(self.time, self.theta, label='theta')
+    pylab.plot(self.time, self.omega, label='omega')
+    #pylab.plot(self.controls_time, self.estimated_velocity, label='estimated omega')
+
+    pylab.legend()
+
+    fig = pylab.figure()
+    pylab.plot(self.controls_time,
+               map(operator.sub, self.ia_goal, self.ia_controls), 'r', label='ia_error')
+    pylab.plot(self.controls_time,
+               map(operator.sub, self.ib_goal, self.ib_controls), 'g', label='ib_error')
+    pylab.plot(self.controls_time,
+               map(operator.sub, self.ic_goal, self.ic_controls), 'b', label='ic_error')
+    if self.title is not None:
+      fig.canvas.set_window_title(self.title)
+    pylab.legend()
+    pylab.show()
+
+
+# So, from running a bunch of math, we know the following:
+# Van + Vbn + Vcn = 0
+# ia + ib + ic = 0
+# ea + eb + ec = 0
+# d ia/dt + d ib/dt + d ic/dt = 0
+#
+# We also have:
+#  [ Van ]   [  2/3 -1/3 -1/3] [Va]
+#  [ Vbn ] = [ -1/3  2/3 -1/3] [Vb]
+#  [ Vcn ]   [ -1/3 -1/3  2/3] [Vc]
+#
+# or,
+#
+#  Vabcn = Vconv * V
+#
+# The base equation is:
+#
+# [ Van ]   [ R 0 0 ] [ ia ]   [ L M M ] [ dia/dt ]   [ ea ]
+# [ Vbn ] = [ 0 R 0 ] [ ib ] + [ M L M ] [ dib/dt ] + [ eb ]
+# [ Vbn ]   [ 0 0 R ] [ ic ]   [ M M L ] [ dic/dt ]   [ ec ]
+#
+# or
+#
+# Vabcn = R_matrix * I + L_matrix * I_dot + E
+#
+# We can re-arrange this as:
+#
+# inv(L_matrix) * (Vconv * V - E - R_matrix * I) = I_dot
+# B * V - inv(L_matrix) * E - A * I = I_dot
+class Simulation(object):
+  def __init__(self):
+    self.R_matrix = numpy.matrix(numpy.eye(3)) * R
+    self.L_matrix = numpy.matrix([[L, M, M], [M, L, M], [M, M, L]])
+    self.L_matrix_inv = numpy.linalg.inv(self.L_matrix)
+    self.A = self.L_matrix_inv * self.R_matrix
+    self.B = self.L_matrix_inv * Vconv
+    self.A_discrete, self.B_discrete = controls.c2d(-self.A, self.B, 1.0 / hz)
+    self.B_discrete_inverse = numpy.matrix(numpy.eye(3)) / (self.B_discrete[0, 0] - self.B_discrete[1, 0])
+
+    self.R_model = R * 1.0
+    self.L_model = L * 1.0
+    self.M_model = M * 1.0
+    self.R_matrix_model = numpy.matrix(numpy.eye(3)) * self.R_model
+    self.L_matrix_model = numpy.matrix([[self.L_model, self.M_model, self.M_model],
+                                        [self.M_model, self.L_model, self.M_model],
+                                        [self.M_model, self.M_model, self.L_model]])
+    self.L_matrix_inv_model = numpy.linalg.inv(self.L_matrix_model)
+    self.A_model = self.L_matrix_inv_model * self.R_matrix_model
+    self.B_model = self.L_matrix_inv_model * Vconv
+    self.A_discrete_model, self.B_discrete_model = \
+        controls.c2d(-self.A_model, self.B_model, 1.0 / hz)
+    self.B_discrete_inverse_model = numpy.matrix(numpy.eye(3)) / (self.B_discrete_model[0, 0] - self.B_discrete_model[1, 0])
+
+    print 'constexpr double kL = %g;' % self.L_model
+    print 'constexpr double kM = %g;' % self.M_model
+    print 'constexpr double kR = %g;' % self.R_model
+    print 'constexpr float kAdiscrete_diagonal = %gf;' % self.A_discrete_model[0, 0]
+    print 'constexpr float kAdiscrete_offdiagonal = %gf;' % self.A_discrete_model[1, 0]
+    print 'constexpr float kBdiscrete_inv_diagonal = %gf;' % self.B_discrete_inverse_model[0, 0]
+    print 'constexpr float kBdiscrete_inv_offdiagonal = %gf;' % self.B_discrete_inverse_model[1, 0]
+    print 'constexpr double kOneAmpScalar = %g;' % one_amp_scalar
+    print 'constexpr double kMaxOneAmpDrivingVoltage = %g;' % max_one_amp_driving_voltage
+    print('A_discrete', self.A_discrete)
+    print('B_discrete', self.B_discrete)
+    print('B_discrete_sub', numpy.linalg.inv(self.B_discrete[0:2, 0:2]))
+    print('B_discrete_inv', self.B_discrete_inverse)
+
+    # Xdot[5:, :] = (R_sense2 + R_sense1) / R_sense2 * (
+    #      (1.0 / (R_sense1 * C_sense)) * (-Isense * R_sense2 / (R_sense1 + R_sense2) * (R_sense1 / R_sense2 + 1.0) + I))
+    self.mk1 = (R_sense2 + R_sense1) / R_sense2 * (1.0 / (R_sense1 * C_sense))
+    self.mk2 = -self.mk1 * R_sense2 / (R_sense1 + R_sense2) * (R_sense1 / R_sense2 + 1.0)
+
+    # ia, ib, ic, theta, omega, isensea, isenseb, isensec
+    self.X = numpy.matrix([[0.0], [0.0], [0.0], [-2.0 * numpy.pi / 3.0], [0.0], [0.0], [0.0], [0.0]])
+
+    self.K = 0.05 * Vconv
+    print('A %s' % repr(self.A))
+    print('B %s' % repr(self.B))
+    print('K %s' % repr(self.K))
+
+    print('System poles are %s' % repr(numpy.linalg.eig(self.A)[0]))
+    print('Poles are %s' % repr(numpy.linalg.eig(self.A - self.B * self.K)[0]))
+
+    controllability = controls.ctrb(self.A, self.B)
+    print('Rank of augmented controlability matrix. %d' % numpy.linalg.matrix_rank(
+          controllability))
+
+    self.data_logger = DataLogger(switching_pattern)
+    self.current_time = 0.0
+
+    self.estimated_velocity = self.X[4, 0]
+
+  def motor_diffeq(self, x, t, U):
+    I = numpy.matrix(x[0:3]).T
+    theta = x[3]
+    omega = x[4]
+    Isense = numpy.matrix(x[5:]).T
+
+    dflux = phases(f_single, theta) / Kv
+
+    Xdot = numpy.matrix(numpy.zeros((8, 1)))
+    di_dt = -self.A_model * I + self.B_model * U - self.L_matrix_inv_model * dflux * omega
+    torque = I.T * dflux
+    Xdot[0:3, :] = di_dt
+    Xdot[3, :] = omega
+    Xdot[4, :] = torque / J
+
+    Xdot[5:, :] = self.mk1 * I + self.mk2 * Isense
+    return numpy.squeeze(numpy.asarray(Xdot))
+
+  def DoControls(self, goal_current):
+    theta = self.X[3, 0]
+    # Use the actual angular velocity.
+    omega = self.X[4, 0]
+
+    measured_current = self.X[5:, :].copy()
+
+    # Ok, lets now fake it.
+    E_imag1 = numpy.exp(1j * theta) * K1 * numpy.matrix(
+            [[-1j],
+             [-1j * numpy.exp(1j * numpy.pi * 2.0 / 3.0)],
+             [-1j * numpy.exp(-1j * numpy.pi * 2.0 / 3.0)]])
+    E_imag2 =  numpy.exp(1j * 5.0 * theta) * K2 * numpy.matrix(
+            [[-1j],
+             [-1j * numpy.exp(-1j * numpy.pi * 2.0 / 3.0)],
+             [-1j * numpy.exp(1j * numpy.pi * 2.0 / 3.0)]])
+
+    overall_measured_current = ((E_imag1 + E_imag2).real.T * measured_current / one_amp_scalar)[0, 0]
+
+    current_error = goal_current - overall_measured_current
+    #print(current_error)
+    self.estimated_velocity += current_error * 1.0
+    omega = self.estimated_velocity
+
+    # Now, apply the transfer function of the inductor.
+    # Use that to difference the current across the cycle.
+    Icurrent = self.Ilast
+    # No history:
+    #Icurrent = phases(g_single, theta) * goal_current
+    Inext = phases(g_single, theta + omega * 1.0 / hz) * goal_current
+
+    deltaI = Inext - Icurrent
+
+    H1 = -numpy.linalg.inv(1j * omega * self.L_matrix + self.R_matrix) * omega / Kv
+    H2 = -numpy.linalg.inv(1j * omega * 5.0 * self.L_matrix + self.R_matrix) * omega / Kv
+    p_imag = H1 * E_imag1 + H2 * E_imag2
+    p_next_imag = numpy.exp(1j * omega * 1.0 / hz) * H1 * E_imag1 + \
+        numpy.exp(1j * omega * 5.0 * 1.0 / hz) * H2 * E_imag2
+    p = p_imag.real
+
+    # So, we now know how much the change in current is due to changes in BEMF.
+    # Subtract that, and then run the stock statespace equation.
+    Vn_ff = self.B_discrete_inverse * (Inext - self.A_discrete * (Icurrent - p) - p_next_imag.real)
+    print 'Vn_ff', Vn_ff
+    print 'Inext', Inext
+    Vn = Vn_ff + self.K * (Icurrent - measured_current)
+
+    E = phases(f_single, self.X[3, 0]) / Kv * self.X[4, 0]
+    self.data_logger.log_controls(self.current_time, measured_current, Icurrent, E, self.estimated_velocity)
+
+    self.Ilast = Inext
+
+    return Vn
+
+  def Simulate(self):
+    start_wall_time = time.time()
+    self.Ilast = numpy.matrix(numpy.zeros((3, 1)))
+    for n in range(200):
+      goal_current = 1.0
+      max_current = (vcc - (self.X[4, 0] / Kv * 2.0)) / max_one_amp_driving_voltage
+      min_current = (-vcc - (self.X[4, 0] / Kv * 2.0)) / max_one_amp_driving_voltage
+      goal_current = max(min_current, min(max_current, goal_current))
+
+      Vn = self.DoControls(goal_current)
+
+      #Vn = numpy.matrix([[1.00], [0.0], [0.0]])
+      Vn = numpy.matrix([[0.00], [1.00], [0.0]])
+      #Vn = numpy.matrix([[0.00], [0.0], [1.00]])
+
+      # T is the fractional rate.
+      T = Vn / vcc
+      tn = -numpy.min(T)
+      T += tn
+      if (T > 1.0).any():
+        T = T / numpy.max(T)
+
+      for t, U in sample_times(T = T,
+                               dt = 1.0 / hz, n = 10,
+                               start_time = self.current_time):
+        # Analog amplifier mode!
+        #U = Vn
+
+        self.data_logger.log_data(self.X, (U - min(U)), self.current_time, Vn, goal_current)
+        t_array = numpy.array([self.current_time, t])
+        self.X = numpy.matrix(scipy.integrate.odeint(
+            self.motor_diffeq,
+            numpy.squeeze(numpy.asarray(self.X)),
+            t_array, args=(U,)))[1, :].T
+
+        self.current_time = t
+
+    print 'Took %f to simulate' % (time.time() - start_wall_time)
+
+    self.data_logger.plot()
+
+simulation = Simulation()
+simulation.Simulate()
diff --git a/motors/usb/hid.cc b/motors/usb/hid.cc
index 0c5075e..d885e75 100644
--- a/motors/usb/hid.cc
+++ b/motors/usb/hid.cc
@@ -15,46 +15,6 @@
 constexpr uint8_t set_protcol() { return 0x0b; }
 }  // namespace hid_class_requests
 
-// The hard-coded HID report descriptor.
-uint8_t kReportDescriptor[] = {
-    0x05, 0x01,        // Usage Page (Generic Desktop),
-    0x09, 0x04,        // Usage (Joystick),
-    0xA1, 0x01,        // Collection (Application),
-    0x75, 0x10,        //     Report Size (16),
-    0x95, 0x04,        //     Report Count (4),
-    0x15, 0x00,        //     Logical Minimum (0),
-    0x26, 0xFF, 0xFF,  //     Logical Maximum (65535),
-    0x35, 0x00,        //     Physical Minimum (0),
-    0x46, 0xFF, 0xFF,  //     Physical Maximum (65535),
-    0x09, 0x30,        //     Usage (X),
-    0x09, 0x31,        //     Usage (Y),
-    0x09, 0x32,        //     Usage (Z),
-    0x09, 0x35,        //     Usage (Rz),
-    0x81, 0x02,        //     Input (Variable),
-    0x75, 0x01,        //     Report Size (1),
-    0x95, 0x10,        //     Report Count (16),
-    0x25, 0x01,        //     Logical Maximum (1),
-    0x45, 0x01,        //     Physical Maximum (1),
-    0x05, 0x09,        //     Usage Page (Button),
-    0x19, 0x01,        //     Usage Minimum (1),
-    0x29, 0x10,        //     Usage Maximum (16),
-    0x81, 0x02,        //     Input (Variable),
-    0xC0               // End Collection
-};
-
-// The hard-coded HID descriptor.
-uint8_t kHidDescriptor[] = {
-    9,                                                      // bLength
-    static_cast<uint8_t>(UsbClassDescriptorType::kHidHid),  // bDescriptorType
-    0x10, 0x01,                                             // bcdHID
-    0,                                                      // bCountryCode
-    1,                                                      // bNumDescriptors
-    static_cast<uint8_t>(
-        UsbClassDescriptorType::kHidReport),  // bDescriptorType
-    sizeof(kReportDescriptor),  // wDescriptorLength
-    0,
-};
-
 }  // namespace
 
 void HidFunction::Initialize() {
@@ -80,7 +40,17 @@
     interface_descriptor->AddByte(device()->AddString("Hid"));  // iInterface
   }
 
-  AddPremadeDescriptor(kHidDescriptor, sizeof(kHidDescriptor));
+  {
+    const auto hid_descriptor = hid_descriptor_list_.CreateDescriptor(
+        9, UsbClassDescriptorType::kHidHid);
+    hid_descriptor->AddUint16(0x0110);  // bcdHID
+    hid_descriptor->AddByte(0);         // bCountryCode
+    hid_descriptor->AddByte(1);         // bNumDescriptors
+    hid_descriptor->AddByte(static_cast<uint8_t>(
+        UsbClassDescriptorType::kHidReport));              // bDescriptorType
+    hid_descriptor->AddUint16(report_descriptor_.size());  // wDescriptorLength
+  }
+  AddPremadeDescriptor(hid_descriptor_list_);
 
   {
     const auto endpoint_descriptor = CreateDescriptor(
@@ -90,7 +60,7 @@
     endpoint_descriptor->AddByte(
         m_endpoint_attributes_interrupt());                  // bmAttributes
     endpoint_descriptor->AddUint16(in_endpoint_max_size());  // wMaxPacketSize
-    endpoint_descriptor->AddByte(1);                         // bInterval
+    endpoint_descriptor->AddByte(0x8);                        // bInterval
   }
 }
 
@@ -167,8 +137,9 @@
         return SetupResponse::kStall;
       }
       device()->QueueEndpoint0Data(
-          reinterpret_cast<const char *>(kHidDescriptor),
-          ::std::min<int>(setup_packet.length, sizeof(kHidDescriptor)));
+          hid_descriptor_list_.GetData(),
+          ::std::min<int>(setup_packet.length,
+                          hid_descriptor_list_.CurrentSize()));
       return SetupResponse::kHandled;
 
     case static_cast<uint8_t>(UsbClassDescriptorType::kHidReport):
@@ -176,8 +147,8 @@
         return SetupResponse::kStall;
       }
       device()->QueueEndpoint0Data(
-          reinterpret_cast<const char *>(kReportDescriptor),
-          ::std::min<int>(setup_packet.length, sizeof(kReportDescriptor)));
+          report_descriptor_.data(),
+          ::std::min<int>(setup_packet.length, report_descriptor_.size()));
       return SetupResponse::kHandled;
 
     case static_cast<uint8_t>(UsbClassDescriptorType::kHidPhysical):
diff --git a/motors/usb/hid.h b/motors/usb/hid.h
index 37aa86b..019231c 100644
--- a/motors/usb/hid.h
+++ b/motors/usb/hid.h
@@ -23,6 +23,13 @@
   }
   ~HidFunction() override = default;
 
+  // Sets the report descriptor. Must be called at least once.
+  //
+  // May only be called during setup.
+  void set_report_descriptor(const ::std::string &report_descriptor) {
+    report_descriptor_ = report_descriptor;
+  }
+
   void UpdateReport(const void *data, int length,
                     const DisableInterrupts &disable_interrupts) {
     memcpy(report_tx_buffer_to_fill(disable_interrupts), data, length);
@@ -82,6 +89,9 @@
   int in_endpoint_;
 
   const int report_max_size_;
+
+  ::std::string report_descriptor_;
+  UsbDescriptorList hid_descriptor_list_;
 };
 
 }  // namespace teensy
diff --git a/motors/usb/usb.cc b/motors/usb/usb.cc
index 4a1b115..7a6286e 100644
--- a/motors/usb/usb.cc
+++ b/motors/usb/usb.cc
@@ -130,7 +130,7 @@
   device_descriptor_->AddUint16(product_id);  // idProduct
   // Increment this whenever you need Windows boxes to actually pay attention to
   // changes.
-  device_descriptor_->AddUint16(7);  // bcdDevice
+  device_descriptor_->AddUint16(24);  // bcdDevice
   // We might overwrite these string descriptor indices later if we get strings
   // to put there.
   device_descriptor_->AddByte(0);  // iManufacturer
diff --git a/motors/usb/usb.h b/motors/usb/usb.h
index 8fd2fb3..299df59 100644
--- a/motors/usb/usb.h
+++ b/motors/usb/usb.h
@@ -214,10 +214,22 @@
     memcpy(&data_[start_index], data, length);
   }
 
+  void AddPremadeDescriptor(const UsbDescriptorList &other_list) {
+    other_list.CheckFinished();
+    AddPremadeDescriptor(
+        reinterpret_cast<const uint8_t *>(other_list.data_.data()),
+        other_list.data_.size());
+  }
+
   void CheckFinished() const { assert(open_descriptors_ == 0); }
 
   int CurrentSize() const { return data_.size(); }
 
+  const char *GetData() const {
+    CheckFinished();
+    return data_.data();
+  }
+
  private:
   ::std::unique_ptr<Descriptor> CreateDescriptor(uint8_t length,
                                                  uint8_t descriptor_type) {
@@ -504,6 +516,9 @@
   void AddPremadeDescriptor(const uint8_t *data, int length) {
     device_->config_descriptor_list_.AddPremadeDescriptor(data, length);
   }
+  void AddPremadeDescriptor(const UsbDescriptorList &other_list) {
+    device_->config_descriptor_list_.AddPremadeDescriptor(other_list);
+  }
 
   UsbDevice *device() const { return device_; }
 
diff --git a/third_party/blasfeo/.gitignore b/third_party/blasfeo/.gitignore
index bd23910..1c36c52 100644
--- a/third_party/blasfeo/.gitignore
+++ b/third_party/blasfeo/.gitignore
@@ -2,7 +2,6 @@
 *.s
 *.o
 *.out
-include/blasfeo_target.h
 libblasfeo.a
 libblasfeo.so
 octave-workspace
diff --git a/third_party/blasfeo/BUILD b/third_party/blasfeo/BUILD
index 92be2d4..ba61061 100644
--- a/third_party/blasfeo/BUILD
+++ b/third_party/blasfeo/BUILD
@@ -13,6 +13,9 @@
         "include/blasfeo_d_blas.h",
         "include/blasfeo_m_aux.h",
         "include/blasfeo_s_blas.h",
+        "include/blasfeo_v_aux_ext_dep.h",
+        "include/blasfeo_d_aux_ext_dep.h",
+        "include/blasfeo_i_aux_ext_dep.h",
     ],
     includes = [
         "include",
diff --git a/third_party/ct/BUILD b/third_party/ct/BUILD
new file mode 100644
index 0000000..6455466
--- /dev/null
+++ b/third_party/ct/BUILD
@@ -0,0 +1,277 @@
+licenses(["notice"])  # lgpl
+
+cc_library(
+    name = "ct",
+    includes = [
+        "ct_optcon/include",
+        "ct_core/include",
+        "ct_core/include/external",
+    ],
+    hdrs = [
+        "ct_optcon/include/ct/optcon/optcon.h",
+        "ct_core/include/ct/core/core.h",
+        "ct_core/include/ct/core/internal/autodiff/CppadParallel.h",
+        "ct_core/include/ct/core/Common",
+        "ct_core/include/ct/core/Common-impl",
+        "ct_core/include/ct/core/common/GaussianNoise.h",
+        "ct_core/include/ct/core/common/QuantizationNoise.h",
+        "ct_core/include/ct/core/common/InfoFileParser.h",
+        "ct_core/include/ct/core/common/Timer.h",
+        "ct_core/include/ct/core/common/ExternallyDrivenTimer.h",
+        "ct_core/include/ct/core/common/Interpolation.h",
+        "ct_core/include/ct/core/types/arrays/DiscreteArray.h",
+        "ct_core/include/ct/core/types/arrays/TimeArray.h",
+        "ct_core/include/ct/core/types/Time.h",
+        "ct_core/include/ct/core/common/linspace.h",
+        "ct_core/include/ct/core/types/arrays/ScalarArray.h",
+        "ct_core/include/ct/core/common/activations/Activations.h",
+        "ct_core/include/ct/core/common/activations/ActivationBase.hpp",
+        "ct_core/include/ct/core/common/activations/PeriodicActivation.hpp",
+        "ct_core/include/ct/core/internal/traits/TraitSelectorSpecs.h",
+        "ct_core/include/ct/core/internal/traits/CppADCodegenTrait.h",
+        "ct_core/include/ct/core/internal/traits/CppADDoubleTrait.h",
+        "ct_core/include/ct/core/internal/traits/TraitSelector.h",
+        "ct_core/include/ct/core/internal/traits/FloatTrait.h",
+        "ct_core/include/ct/core/internal/traits/DoubleTrait.h",
+        "ct_core/include/ct/core/common/activations/RBFGaussActivation.h",
+        "ct_core/include/ct/core/common/activations/SingleActivation.hpp",
+        "ct_core/include/ct/core/common/activations/BarrierActivation.hpp",
+        "ct_core/include/ct/core/common/activations/utilities/ActivationLoadMacros.h",
+        "ct_core/include/ct/core/Types",
+        "ct_core/include/ct/core/Types-impl",
+        "ct_core/include/ct/core/types/AutoDiff.h",
+        "ct_core/include/ct/core/types/ControlVector.h",
+        "ct_core/include/ct/core/types/StateVector.h",
+        "ct_core/include/ct/core/types/FeedbackMatrix.h",
+        "ct_core/include/ct/core/types/StateMatrix.h",
+        "ct_core/include/ct/core/types/ControlMatrix.h",
+        "ct_core/include/ct/core/types/StateControlMatrix.h",
+        "ct_core/include/ct/core/types/arrays/MatrixArrays.h",
+        "ct_core/include/ct/core/types/trajectories/DiscreteTrajectoryBase.h",
+        "ct_core/include/ct/core/types/trajectories/TrajectoryBase.h",
+        "ct_core/include/ct/core/types/trajectories/ScalarTrajectory.h",
+        "ct_core/include/ct/core/types/trajectories/MatrixTrajectories.h",
+        "ct_core/include/ct/core/Control",
+        "ct_core/include/ct/core/Control-impl",
+        "ct_core/include/ct/core/control/continuous_time/Controller.h",
+        "ct_core/include/ct/core/control/continuous_time/StateFeedbackController.h",
+        "ct_core/include/ct/core/control/continuous_time/ConstantController.h",
+        "ct_core/include/ct/core/control/continuous_time/ConstantStateFeedbackController.h",
+        "ct_core/include/ct/core/control/continuous_time/ConstantTrajectoryController.h",
+        "ct_core/include/ct/core/control/continuous_time/siso/PIDController.h",
+        "ct_core/include/ct/core/control/continuous_time/siso/PIDController-impl.h",
+        "ct_core/include/ct/core/control/continuous_time/siso/StepInputController.h",
+        "ct_core/include/ct/core/control/continuous_time/mimo/LinearFunctions.h",
+        "ct_core/include/ct/core/control/discrete_time/DiscreteController.h",
+        "ct_core/include/ct/core/Systems",
+        "ct_core/include/ct/core/Systems-impl",
+        "ct_core/include/ct/core/systems/continuous_time/System.h",
+        "ct_core/include/ct/core/systems/continuous_time/ControlledSystem.h",
+        "ct_core/include/ct/core/systems/continuous_time/SecondOrderSystem.h",
+        "ct_core/include/ct/core/systems/continuous_time/linear/LinearSystem.h",
+        "ct_core/include/ct/core/systems/continuous_time/linear/LTISystem.h",
+        "ct_core/include/ct/core/systems/linearizer/DynamicsLinearizerNumDiff.h",
+        "ct_core/include/ct/core/systems/linearizer/DynamicsLinearizerAD.h",
+        "ct_core/include/ct/core/systems/linearizer/DynamicsLinearizerADBase.h",
+        "ct_core/include/ct/core/internal/autodiff/SparsityPattern.h",
+        "ct_core/include/ct/core/systems/linearizer/DynamicsLinearizerADCG.h",
+        "ct_core/include/ct/core/internal/autodiff/CGHelpers.h",
+        "ct_core/include/ct/core/systems/continuous_time/linear/SystemLinearizer.h",
+        "ct_core/include/ct/core/systems/continuous_time/linear/AutoDiffLinearizer.h",
+        "ct_core/include/ct/core/systems/continuous_time/linear/ADCodegenLinearizer.h",
+        "ct_core/include/ct/core/templateDir.h",  # TODO(austin): Looks like this could be non-hermetic.
+        "ct_core/include/ct/core/systems/discrete_time/DiscreteControlledSystem.h",
+        "ct_core/include/ct/core/systems/discrete_time/DiscreteSystem.h",
+        "ct_core/include/ct/core/systems/discrete_time/SystemDiscretizer.h",
+        "ct_core/include/ct/core/integration/Integrator.h",
+        "ct_core/include/ct/core/integration/EventHandler.h",
+        "ct_core/include/ct/core/integration/Observer.h",
+        "ct_core/include/ct/core/integration/eigenIntegration.h",
+        "ct_core/include/ct/core/integration/internal/StepperBase.h",
+        "ct_core/include/ct/core/integration/internal/SteppersODEInt.h",
+        "ct_core/include/ct/core/integration/internal/SteppersODEIntDefinitions.h",
+        "ct_core/include/ct/core/integration/internal/SteppersCT.h",
+        "ct_core/include/ct/core/integration/IntegratorSymplectic.h",
+        "ct_core/include/ct/core/systems/continuous_time/SymplecticSystem.h",
+        "ct_core/include/ct/core/integration/EventHandlers/SubstepRecorder.h",
+        "ct_core/include/ct/core/systems/discrete_time/linear/DiscreteLinearSystem.h",
+        "ct_core/include/ct/core/systems/discrete_time/linear/DiscreteSystemLinearizer.h",
+        "ct_core/include/ct/core/systems/discrete_time/linear/DiscreteSystemLinearizerAD.h",
+        "ct_core/include/ct/core/systems/discrete_time/linear/DiscreteSystemLinearizerADCG.h",
+        "ct_core/include/ct/core/Integration",
+        "ct_core/include/ct/core/Integration-impl",
+        "ct_core/include/ct/core/integration/EventHandlers/KillIntegrationEventHandler.h",
+        "ct_core/include/ct/core/integration/EventHandlers/MaxStepsEventHandler.h",
+        "ct_core/include/ct/core/integration/sensitivity/Sensitivity.h",
+        "ct_core/include/ct/core/integration/sensitivity/SensitivityApproximation.h",
+        "ct_core/include/ct/core/integration/sensitivity/SensitivityIntegrator.h",
+        "ct_core/include/ct/core/Geometry",
+        "ct_core/include/ct/core/Geometry-impl",
+        "ct_core/include/ct/core/geometry/Ellipsoid.h",
+        "ct_core/include/ct/core/geometry/Plane.h",
+        "ct_core/include/ct/core/geometry/PlaneEstimator.h",
+        "ct_core/include/ct/core/Internal",
+        "ct_core/include/ct/core/Internal-impl",
+        "ct_core/include/ct/core/internal/autodiff/ADHelpers.h",
+        "ct_core/include/ct/core/Math",
+        "ct_core/include/ct/core/Math-impl",
+        "ct_core/include/ct/core/math/Derivatives.h",
+        "ct_core/include/ct/core/math/DerivativesCppadSettings.h",
+        "ct_core/include/ct/core/math/DerivativesNumDiff.h",
+        "ct_core/include/ct/core/math/DerivativesCppad.h",
+        "ct_core/include/ct/core/math/DerivativesCppadJIT.h",
+        "ct_core/include/ct/core/math/DerivativesCppadCG.h",
+        "ct_core/include/ct/core/Simulation",
+        "ct_core/include/ct/core/Simulation-impl",
+        "ct_core/include/ct/core/simulation/ControlSimulator.h",
+        "ct_core/include/ct/core/control/continuous_time/StateFeedbackController-impl.h",
+        "ct_core/include/ct/core/control/continuous_time/ConstantController-impl.h",
+        "ct_core/include/ct/core/systems/discrete_time/SystemDiscretizer-impl.h",
+        "ct_core/include/ct/core/integration/Observer-impl.h",
+        "ct_core/include/ct/core/integration/Integrator-impl.h",
+        "ct_core/include/ct/core/integration/IntegratorSymplectic-impl.h",
+        "ct_optcon/include/ct/optcon/costfunction/costfunction.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermBase.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermLinear.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermMixed.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermQuadratic.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermQuadMult.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermQuadTracking.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermStateBarrier.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/CostFunction.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/CostFunctionQuadratic.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/CostFunctionQuadratic-impl.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/CostFunctionAD.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/CostFunctionAD-impl.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/utility/utilities.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermLoadMacros.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/CostFunctionAnalytical.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/CostFunctionQuadraticSimple.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/CostFunctionQuadraticSimple-impl.hpp",
+        "ct_optcon/include/ct/optcon/constraint/constraint.h",
+        "ct_optcon/include/ct/optcon/constraint/term/ConstraintBase.h",
+        "ct_optcon/include/ct/optcon/constraint/term/BoxConstraintBase.h",
+        "ct_optcon/include/ct/optcon/constraint/term/BoxConstraintBase-impl.h",
+        "ct_optcon/include/ct/optcon/constraint/term/ControlInputConstraint.h",
+        "ct_optcon/include/ct/optcon/constraint/term/ControlInputConstraint-impl.h",
+        "ct_optcon/include/ct/optcon/constraint/term/ObstacleConstraint.h",
+        "ct_optcon/include/ct/optcon/constraint/term/ObstacleConstraint-impl.h",
+        "ct_optcon/include/ct/optcon/constraint/term/StateConstraint.h",
+        "ct_optcon/include/ct/optcon/constraint/term/StateConstraint-impl.h",
+        "ct_optcon/include/ct/optcon/constraint/term/TerminalConstraint.h",
+        "ct_optcon/include/ct/optcon/constraint/term/TerminalConstraint-impl.h",
+        "ct_optcon/include/ct/optcon/constraint/ConstraintContainerBase.h",
+        "ct_optcon/include/ct/optcon/constraint/ConstraintContainerBase-impl.h",
+        "ct_optcon/include/ct/optcon/constraint/LinearConstraintContainer.h",
+        "ct_optcon/include/ct/optcon/constraint/LinearConstraintContainer-impl.h",
+        "ct_optcon/include/ct/optcon/constraint/ConstraintContainerAD.h",
+        "ct_optcon/include/ct/optcon/constraint/ConstraintContainerAD-impl.h",
+        "ct_optcon/include/ct/optcon/constraint/ConstraintContainerAnalytical.h",
+        "ct_optcon/include/ct/optcon/constraint/ConstraintContainerAnalytical-impl.h",
+        "ct_optcon/include/ct/optcon/problem/OptConProblem.h",
+        "ct_optcon/include/ct/optcon/problem/OptConProblem-impl.h",
+        "ct_optcon/include/ct/optcon/problem/LQOCProblem.hpp",
+        "ct_optcon/include/ct/optcon/solver/OptConSolver.h",
+        "ct_optcon/include/ct/optcon/nloc/NLOCBackendBase.hpp",
+        "ct_optcon/include/ct/optcon/solver/lqp/GNRiccatiSolver.hpp",
+        "ct_optcon/include/ct/optcon/solver/lqp/LQOCSolver.hpp",
+        "ct_optcon/include/ct/optcon/solver/NLOptConSettings.hpp",
+        "ct_optcon/include/ct/optcon/solver/lqp/HPIPMInterface.hpp",
+        "ct_optcon/include/ct/optcon/nloc/NLOCResults.hpp",
+        "ct_optcon/include/ct/optcon/nloc/NLOCBackendST.hpp",
+        "ct_optcon/include/ct/optcon/nloc/NLOCBackendMP.hpp",
+        "ct_optcon/include/ct/optcon/nloc/algorithms/gnms/GNMS.hpp",
+        "ct_optcon/include/ct/optcon/nloc/NLOCAlgorithm.hpp",
+        "ct_optcon/include/ct/optcon/nloc/algorithms/ilqr/iLQR.hpp",
+        "ct_optcon/include/ct/optcon/solver/NLOptConSolver.hpp",
+        "ct_optcon/include/ct/optcon/lqr/riccati/CARE.hpp",
+        "ct_optcon/include/ct/optcon/lqr/riccati/DARE.hpp",
+        "ct_optcon/include/ct/optcon/lqr/riccati/DynamicRiccatiEquation.hpp",
+        "ct_optcon/include/ct/optcon/lqr/FHDTLQR.hpp",
+        "ct_optcon/include/ct/optcon/lqr/LQR.hpp",
+        "ct_optcon/include/ct/optcon/dms/dms.h",
+        "ct_optcon/include/ct/optcon/dms/Constraints",
+        "ct_optcon/include/ct/optcon/dms/constraints/ConstraintDiscretizer.h",
+        "ct_optcon/include/ct/optcon/nlp/DiscreteConstraintBase.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/OptVectorDms.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/TimeGrid.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/DmsDimensions.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/spline/SplinerBase.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/spline/ZeroOrderHold/ZeroOrderHoldSpliner.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/spline/Linear/LinearSpliner.h",
+        "ct_optcon/include/ct/optcon/nlp/OptVector.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/DmsSettings.h",
+        "ct_optcon/include/ct/optcon/nlp/solver/NlpSolverSettings.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/implementation/OptVectorDms-impl.h",
+        "ct_optcon/include/ct/optcon/dms/constraints/ConstraintsContainerDms.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/ShotContainer.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/SensitivityIntegratorCT.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/ControllerDms.h",
+        "ct_optcon/include/ct/optcon/nlp/DiscreteConstraintContainerBase.h",
+        "ct_optcon/include/ct/optcon/dms/constraints/InitStateConstraint.h",
+        "ct_optcon/include/ct/optcon/dms/constraints/ContinuityConstraint.h",
+        "ct_optcon/include/ct/optcon/dms/constraints/TimeHorizonEqualityConstraint.h",
+        "ct_optcon/include/ct/optcon/dms/constraints/implementation/ConstraintsContainerDms-impl.h",
+        "ct_optcon/include/ct/optcon/dms/Dms",
+        "ct_optcon/include/ct/optcon/dms/dms_core/DmsSolver.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/DmsProblem.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/cost_evaluator/CostEvaluatorSimple.h",
+        "ct_optcon/include/ct/optcon/nlp/DiscreteCostEvaluatorBase.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/cost_evaluator/CostEvaluatorFull.h",
+        "ct_optcon/include/ct/optcon/nlp/Nlp.h",
+        "ct_optcon/include/ct/optcon/nlp/Nlp",
+        "ct_optcon/include/ct/optcon/nlp/solver/NlpSolver.h",
+        "ct_optcon/include/ct/optcon/nlp/solver/IpoptSolver.h",
+        "ct_optcon/include/ct/optcon/nlp/solver/SnoptSolver.h",
+        "ct_optcon/include/ct/optcon/dms/dms_core/RKnDerivatives.h",
+        "ct_optcon/include/ct/optcon/mpc/MpcSettings.h",
+        "ct_optcon/include/ct/optcon/mpc/MPC.h",
+        "ct_optcon/include/ct/optcon/mpc/MpcTimeKeeper.h",
+        "ct_optcon/include/ct/optcon/mpc/timehorizon/MpcTimeHorizon.h",
+        "ct_optcon/include/ct/optcon/mpc/policyhandler/PolicyHandler.h",
+        "ct_optcon/include/ct/optcon/mpc/policyhandler/default/StateFeedbackPolicyHandler.h",
+        "ct_optcon/include/ct/optcon/costfunction/costfunction-impl.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermBase-impl.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermLinear-impl.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermMixed-impl.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermQuadratic-impl.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermQuadMult-impl.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermQuadTracking-impl.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/term/TermStateBarrier-impl.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/CostFunction-impl.hpp",
+        "ct_optcon/include/ct/optcon/costfunction/CostFunctionAnalytical-impl.hpp",
+        "ct_optcon/include/ct/optcon/constraint/constraint-impl.h",
+        "ct_optcon/include/ct/optcon/constraint/term/ConstraintBase-impl.h",
+        "ct_optcon/include/ct/optcon/problem/LQOCProblem-impl.hpp",
+        "ct_optcon/include/ct/optcon/solver/lqp/GNRiccatiSolver-impl.hpp",
+        "ct_optcon/include/ct/optcon/solver/lqp/HPIPMInterface-impl.hpp",
+        "ct_optcon/include/ct/optcon/solver/NLOptConSolver-impl.hpp",
+        "ct_optcon/include/ct/optcon/lqr/riccati/CARE-impl.hpp",
+        "ct_optcon/include/ct/optcon/lqr/riccati/DARE-impl.hpp",
+        "ct_optcon/include/ct/optcon/lqr/FHDTLQR-impl.hpp",
+        "ct_optcon/include/ct/optcon/lqr/LQR-impl.hpp",
+        "ct_optcon/include/ct/optcon/nloc/NLOCBackendBase-impl.hpp",
+        "ct_optcon/include/ct/optcon/nloc/NLOCBackendST-impl.hpp",
+        "ct_optcon/include/ct/optcon/nloc/NLOCBackendMP-impl.hpp",
+        "ct_optcon/include/ct/optcon/nloc/algorithms/gnms/GNMS-impl.hpp",
+        "ct_optcon/include/ct/optcon/nloc/algorithms/ilqr/iLQR-impl.hpp",
+        "ct_optcon/include/ct/optcon/mpc/MPC-impl.h",
+        "ct_optcon/include/ct/optcon/mpc/timehorizon/MpcTimeHorizon-impl.h",
+        "ct_optcon/include/ct/optcon/mpc/policyhandler/PolicyHandler-impl.h",
+        "ct_optcon/include/ct/optcon/mpc/policyhandler/default/StateFeedbackPolicyHandler-impl.h",
+    ] + glob(["ct_core/include/external/cppad/**/*.hpp"]),
+    deps = [
+        "//third_party/hpipm",
+        "//third_party/eigen",
+    ],
+    copts = [
+        "-Wno-pointer-arith",
+        "-Wno-unused-variable",
+        "-Wno-unused-parameter",
+    ],
+    defines = [
+        "HPIPM=1",
+    ],
+    visibility = ["//visibility:public"],
+    restricted_to = ["//tools:k8"],
+)
diff --git a/third_party/ct/ct_core/include/ct/core/math/DerivativesCppadJIT.h b/third_party/ct/ct_core/include/ct/core/math/DerivativesCppadJIT.h
index 639f218..70d8f16 100644
--- a/third_party/ct/ct_core/include/ct/core/math/DerivativesCppadJIT.h
+++ b/third_party/ct/ct_core/include/ct/core/math/DerivativesCppadJIT.h
@@ -266,8 +266,8 @@
         Eigen::Matrix<bool, Eigen::Dynamic, Eigen::Dynamic> sparsityMat(outputDim_, inputDim_);
 
         assert((int)(sparsityVec.size()) == outputDim_ * inputDim_);
-        for (size_t row = 0; row < outputDim_; ++row)
-            for (size_t col = 0; col < inputDim_; ++col)
+        for (int row = 0; row < outputDim_; ++row)
+            for (int col = 0; col < inputDim_; ++col)
                 sparsityMat(row, col) = sparsityVec[col + row * inputDim_];
 
         return sparsityMat;
@@ -286,8 +286,8 @@
         Eigen::Matrix<bool, Eigen::Dynamic, Eigen::Dynamic> sparsityMat(inputDim_, inputDim_);
 
         assert(sparsityVec.size() == inputDim_ * inputDim_);
-        for (size_t row = 0; row < inputDim_; ++row)
-            for (size_t col = 0; col < inputDim_; ++col)
+        for (int row = 0; row < inputDim_; ++row)
+            for (int col = 0; col < inputDim_; ++col)
             {
                 // std::cout << "sparsityVec: " << sparsityRowsHessian_[col + row * this->inputDim_] << std::endl;
                 sparsityMat(row, col) = sparsityVec[col + row * inputDim_];
diff --git a/third_party/ct/ct_core/include/ct/core/simulation/ControlSimulator.h b/third_party/ct/ct_core/include/ct/core/simulation/ControlSimulator.h
index d0d655d..66e159f 100644
--- a/third_party/ct/ct_core/include/ct/core/simulation/ControlSimulator.h
+++ b/third_party/ct/ct_core/include/ct/core/simulation/ControlSimulator.h
@@ -46,13 +46,13 @@
         std::shared_ptr<CONTROLLED_SYSTEM> controlled_system)
         : sim_dt_(sim_dt),
           control_dt_(control_dt),
-          x0_(x0),
           system_(controlled_system),
+          x0_(x0),
           stop_(false)
     {
         system_->getController(controller_);
-        if (sim_dt_ <= 0 || control_dt_ <= 0) throw std::runtime_error("Step sizes must be positive.");
-        if (sim_dt_ > control_dt_) throw std::runtime_error("Simulation step must be smaller than the control step.");
+        if (sim_dt_ <= 0 || control_dt_ <= 0) throw "Step sizes must be positive.";
+        if (sim_dt_ > control_dt_) throw "Simulation step must be smaller than the control step.";
     }
 
     //! copy constructor
diff --git a/third_party/ct/ct_core/include/ct/core/templateDir.h b/third_party/ct/ct_core/include/ct/core/templateDir.h
new file mode 100644
index 0000000..34b631b
--- /dev/null
+++ b/third_party/ct/ct_core/include/ct/core/templateDir.h
@@ -0,0 +1,17 @@
+/**********************************************************************************************************************
+This file is part of the Control Toolbox (https://adrlab.bitbucket.io/ct), copyright by ETH Zurich, Google Inc.
+Authors:  Michael Neunert, Markus Giftthaler, Markus Stäuble, Diego Pardo, Farbod Farshidian
+Licensed under Apache2 license (see LICENSE file in main directory)
+**********************************************************************************************************************/
+
+#pragma once
+
+namespace ct {
+namespace core {
+
+static const std::string CODEGEN_TEMPLATE_DIR = "./third_party/ct/ct_core/templates";
+static const std::string CODEGEN_OUTPUT_DIR = "./third_party/ct/ct_core/generated";
+
+}
+}
+
diff --git a/third_party/ct/ct_optcon/include/ct/optcon/constraint/ConstraintContainerAD-impl.h b/third_party/ct/ct_optcon/include/ct/optcon/constraint/ConstraintContainerAD-impl.h
index 3668114..2b5e8f3 100644
--- a/third_party/ct/ct_optcon/include/ct/optcon/constraint/ConstraintContainerAD-impl.h
+++ b/third_party/ct/ct_optcon/include/ct/optcon/constraint/ConstraintContainerAD-impl.h
@@ -434,9 +434,9 @@
         size_t stateIndex = 0;
         size_t inputIndex = 0;
 
-        for (size_t i = 0; i < sparsityRows.rows(); ++i)
+        for (size_t i = 0; i < static_cast<size_t>(sparsityRows.rows()); ++i)
         {
-            if (sparsityCols(i) < STATE_DIM)
+            if (sparsityCols(i) < static_cast<ssize_t>(STATE_DIM))
             {
                 sparsityStateIntermediateRows_(stateIndex) = sparsityRows(i);
                 sparsityStateIntermediateCols_(stateIndex) = sparsityCols(i);
@@ -499,9 +499,9 @@
         size_t stateIndex = 0;
         size_t inputIndex = 0;
 
-        for (size_t i = 0; i < sparsityRows.rows(); ++i)
+        for (int i = 0; i < sparsityRows.rows(); ++i)
         {
-            if (sparsityCols(i) < STATE_DIM)
+            if (sparsityCols(i) < static_cast<int>(STATE_DIM))
             {
                 sparsityStateTerminalRows_(stateIndex) = sparsityRows(i);
                 sparsityStateTerminalCols_(stateIndex) = sparsityCols(i);
diff --git a/third_party/ct/ct_optcon/include/ct/optcon/constraint/term/BoxConstraintBase-impl.h b/third_party/ct/ct_optcon/include/ct/optcon/constraint/term/BoxConstraintBase-impl.h
index c143490..5b45748 100644
--- a/third_party/ct/ct_optcon/include/ct/optcon/constraint/term/BoxConstraintBase-impl.h
+++ b/third_party/ct/ct_optcon/include/ct/optcon/constraint/term/BoxConstraintBase-impl.h
@@ -97,7 +97,7 @@
     const VectorXs& ub) const
 {
     // assert that the size of constraint vectors is equal to the computed/given number of constraints
-    if (lb.rows() != nCon | ub.rows() != nCon)
+    if (lb.rows() != static_cast<ssize_t>(nCon) || ub.rows() != static_cast<ssize_t>(nCon))
     {
         std::cout << "no. Constraints: " << nCon << std::endl;
         std::cout << "BoxConstraintBase: lb " << lb.transpose() << std::endl;
diff --git a/third_party/ct/ct_optcon/include/ct/optcon/dms/dms_core/cost_evaluator/CostEvaluatorFull.h b/third_party/ct/ct_optcon/include/ct/optcon/dms/dms_core/cost_evaluator/CostEvaluatorFull.h
index 43d2a76..6a124a8 100644
--- a/third_party/ct/ct_optcon/include/ct/optcon/dms/dms_core/cost_evaluator/CostEvaluatorFull.h
+++ b/third_party/ct/ct_optcon/include/ct/optcon/dms/dms_core/cost_evaluator/CostEvaluatorFull.h
@@ -6,7 +6,7 @@
 
 #pragma once
 
-#include <omp.h>
+//#include <omp.h>
 #include <math.h>
 #include <cmath>
 #include <functional>
diff --git a/third_party/ct/ct_optcon/include/ct/optcon/dms/dms_core/cost_evaluator/CostEvaluatorSimple.h b/third_party/ct/ct_optcon/include/ct/optcon/dms/dms_core/cost_evaluator/CostEvaluatorSimple.h
index d2b32f7..d7e70cf 100644
--- a/third_party/ct/ct_optcon/include/ct/optcon/dms/dms_core/cost_evaluator/CostEvaluatorSimple.h
+++ b/third_party/ct/ct_optcon/include/ct/optcon/dms/dms_core/cost_evaluator/CostEvaluatorSimple.h
@@ -6,7 +6,7 @@
 
 #pragma once
 
-#include <omp.h>
+//#include <omp.h>
 #include <math.h>
 #include <cmath>
 
diff --git a/third_party/ct/ct_optcon/include/ct/optcon/lqr/FHDTLQR-impl.hpp b/third_party/ct/ct_optcon/include/ct/optcon/lqr/FHDTLQR-impl.hpp
index b098be2..c547c69 100644
--- a/third_party/ct/ct_optcon/include/ct/optcon/lqr/FHDTLQR-impl.hpp
+++ b/third_party/ct/ct_optcon/include/ct/optcon/lqr/FHDTLQR-impl.hpp
@@ -64,7 +64,7 @@
     A.resize(N);
     B.resize(N);
 
-    for (int i = 0; i < N; i++)
+    for (size_t i = 0; i < N; i++)
     {
         A[i] = state_matrix_t::Identity() + dt * derivatives->getDerivativeState(x_trajectory[i], u_trajectory[i]);
         B[i] = dt * derivatives->getDerivativeControl(x_trajectory[i], u_trajectory[i]);
diff --git a/third_party/ct/ct_optcon/include/ct/optcon/mpc/MPC-impl.h b/third_party/ct/ct_optcon/include/ct/optcon/mpc/MPC-impl.h
index 81adecd..54742eb 100644
--- a/third_party/ct/ct_optcon/include/ct/optcon/mpc/MPC-impl.h
+++ b/third_party/ct/ct_optcon/include/ct/optcon/mpc/MPC-impl.h
@@ -18,12 +18,12 @@
     :
 
       solver_(problem, solverSettings),
+      policyHandler_(new PolicyHandler<Policy_t, STATE_DIM, CONTROL_DIM, Scalar_t>()),
       mpc_settings_(mpcsettings),
+      firstRun_(true),
       dynamics_(problem.getNonlinearSystem()->clone()),
       forwardIntegrator_(dynamics_, mpcsettings.stateForwardIntegratorType_),
-      firstRun_(true),
-      runCallCounter_(0),
-      policyHandler_(new PolicyHandler<Policy_t, STATE_DIM, CONTROL_DIM, Scalar_t>())
+      runCallCounter_(0)
 {
     checkSettings(mpcsettings);
 
diff --git a/third_party/ct/ct_optcon/include/ct/optcon/mpc/policyhandler/default/StateFeedbackPolicyHandler-impl.h b/third_party/ct/ct_optcon/include/ct/optcon/mpc/policyhandler/default/StateFeedbackPolicyHandler-impl.h
index 4eaa32b..8a3bc61 100644
--- a/third_party/ct/ct_optcon/include/ct/optcon/mpc/policyhandler/default/StateFeedbackPolicyHandler-impl.h
+++ b/third_party/ct/ct_optcon/include/ct/optcon/mpc/policyhandler/default/StateFeedbackPolicyHandler-impl.h
@@ -64,7 +64,7 @@
     {
         //extend at back with constant value taken from last element
         bool timeIsRelative = true;
-        for (size_t i = 0; i < Kn_new - currentSize; i++)
+        for (int i = 0; i < Kn_new - currentSize; i++)
         {
             FeedbackTraj.push_back(FeedbackTraj.back(), dt_, timeIsRelative);
             FeedForwardTraj.push_back(FeedForwardTraj.back(), dt_, timeIsRelative);
@@ -74,7 +74,7 @@
     else if (Kn_new < currentSize)
     {
         // remove elements from back
-        for (size_t i = 0; i < currentSize - Kn_new; i++)
+        for (int i = 0; i < currentSize - Kn_new; i++)
         {
             FeedbackTraj.pop_back();
             FeedForwardTraj.pop_back();
diff --git a/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendBase-impl.hpp b/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendBase-impl.hpp
index d68bcc9..9c79dd5 100644
--- a/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendBase-impl.hpp
+++ b/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendBase-impl.hpp
@@ -433,6 +433,7 @@
             std::shared_ptr<HPIPMInterface<STATE_DIM, CONTROL_DIM>>(new HPIPMInterface<STATE_DIM, CONTROL_DIM>());
 #else
         throw std::runtime_error("HPIPM selected but not built.");
+        #error
 #endif
     }
     else
@@ -1169,8 +1170,9 @@
             }
             else
             {
-#ifdef MATLAB  // in case of no debug printing but still logging, need to compute them \
-    //! compute l2 norms of state and control update
+#ifdef MATLAB
+              // in case of no debug printing but still logging, need to compute them 
+              //! compute l2 norms of state and control update
                 lu_norm_ = computeDiscreteArrayNorm<ControlVectorArray, 2>(u_ff_prev_, uff_local);
                 lx_norm_ = computeDiscreteArrayNorm<StateVectorArray, 2>(x_prev_, x_);
 #endif
@@ -1481,7 +1483,7 @@
         lqocSolver_->setProblem(lqocProblem_);
 
         //iterate backward up to first stage
-        for (int i = this->lqocProblem_->getNumberOfStages() - 1; i >= startIndex; i--)
+        for (int i = this->lqocProblem_->getNumberOfStages() - 1; i >= static_cast<int>(startIndex); i--)
             lqocSolver_->solveSingleStage(i);
     }
     else
diff --git a/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendMP-impl.hpp b/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendMP-impl.hpp
index d9f6c71..9a95591 100644
--- a/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendMP-impl.hpp
+++ b/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendMP-impl.hpp
@@ -214,7 +214,7 @@
     size_t lastIndex)
 {
     // fill terminal cost
-    if (lastIndex == (this->K_ - 1))
+    if (static_cast<int>(lastIndex) == (this->K_ - 1))
         this->initializeCostToGo();
 
     /*
diff --git a/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendST-impl.hpp b/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendST-impl.hpp
index bc0eaab..96a4fc8 100644
--- a/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendST-impl.hpp
+++ b/third_party/ct/ct_optcon/include/ct/optcon/nloc/NLOCBackendST-impl.hpp
@@ -38,7 +38,7 @@
 void NLOCBackendST<STATE_DIM, CONTROL_DIM, P_DIM, V_DIM, SCALAR>::computeLQApproximation(size_t firstIndex,
     size_t lastIndex)
 {
-    if (lastIndex == this->K_ - 1)
+    if (static_cast<int>(lastIndex) == this->K_ - 1)
         this->initializeCostToGo();
 
     for (size_t k = firstIndex; k <= lastIndex; k++)
diff --git a/third_party/ct/ct_optcon/include/ct/optcon/solver/lqp/HPIPMInterface-impl.hpp b/third_party/ct/ct_optcon/include/ct/optcon/solver/lqp/HPIPMInterface-impl.hpp
index 01255c0..ddc2d10 100644
--- a/third_party/ct/ct_optcon/include/ct/optcon/solver/lqp/HPIPMInterface-impl.hpp
+++ b/third_party/ct/ct_optcon/include/ct/optcon/solver/lqp/HPIPMInterface-impl.hpp
@@ -375,7 +375,7 @@
     std::shared_ptr<LQOCProblem<STATE_DIM, CONTROL_DIM>> lqocProblem)
 {
     // stages 1 to N
-    for (size_t i = 0; i < N_ + 1; i++)
+    for (int i = 0; i < N_ + 1; i++)
     {
         nb_[i] = lqocProblem->nb_[i];
 
@@ -411,7 +411,7 @@
 void HPIPMInterface<STATE_DIM, CONTROL_DIM>::configureGeneralConstraints(
     std::shared_ptr<LQOCProblem<STATE_DIM, CONTROL_DIM>> lqocProblem)
 {
-    for (size_t i = 0; i < N_ + 1; i++)
+    for (int i = 0; i < N_ + 1; i++)
     {
         // check dimensions
         assert(lqocProblem->d_lb_[i].rows() == lqocProblem->d_ub_[i].rows());
diff --git a/third_party/elfutils/.gitignore b/third_party/elfutils/.gitignore
new file mode 100644
index 0000000..e8201dc
--- /dev/null
+++ b/third_party/elfutils/.gitignore
@@ -0,0 +1,166 @@
+#*
+*#
+*.a
+*.o
+*.orig
+*.os
+*.patch
+*.rej
+*.so
+*.so.1
+*/Makefile.in
+*~
+.#*
+.deps
+.glimpse_*
+=*
+/INSTALL
+Makefile
+Makefile.in
+/aclocal.m4
+/autom4te.*
+/backends/*.map
+/config.cache
+/config.h
+/config.h.in
+/config.log
+/config.status
+/config/ar-lib
+/config/compile
+/config/config.guess
+/config/config.sub
+/config/depcomp
+/config/install-sh
+/config/libdw.pc
+/config/libelf.pc
+/config/missing
+/config/test-driver
+/config/ylwrap
+/configure
+/elfutils.spec
+/libcpu/*_dis.h
+/libcpu/*.mnemonics
+/libcpu/*_gendis
+/libcpu/*_lex.c
+/libcpu/*_parse.[ch]
+/libdw/known-dwarf.h
+/po/*.gmo
+/po/*.pot
+/po/en@boldquot.insert-header
+/po/en@boldquot.po
+/po/en@quot.insert-header
+/po/en@quot.po
+/po/Makevars.template
+/po/POTFILES
+/po/remove-potcdate.sed
+/po/stamp-po
+/src/addr2line
+/src/ar
+/src/elfcmp
+/src/elfcompress
+/src/elflint
+/src/findtextrel
+/src/make-debug-archive
+/src/nm
+/src/objdump
+/src/ranlib
+/src/readelf
+/src/size
+/src/stack
+/src/strings
+/src/strip
+/src/unstrip
+/stamp-h1
+/tests/*.log
+/tests/*.trs
+/tests/addrcfi
+/tests/addrscopes
+/tests/aggregate_size
+/tests/alldts
+/tests/allfcts
+/tests/allregs
+/tests/arextract
+/tests/arls
+/tests/arsymtest
+/tests/asm-tst1
+/tests/asm-tst2
+/tests/asm-tst3
+/tests/asm-tst4
+/tests/asm-tst5
+/tests/asm-tst6
+/tests/asm-tst7
+/tests/asm-tst8
+/tests/asm-tst9
+/tests/backtrace
+/tests/backtrace-child
+/tests/backtrace-child-biarch
+/tests/backtrace-data
+/tests/backtrace-dwarf
+/tests/buildid
+/tests/debugaltlink
+/tests/debuglink
+/tests/deleted
+/tests/dwarf-getmacros
+/tests/dwarf-getstring
+/tests/dwarf-ranges
+/tests/dwelfgnucompressed
+/tests/dwfl-addr-sect
+/tests/dwfl-bug-addr-overflow
+/tests/dwfl-bug-fd-leak
+/tests/dwfl-bug-getmodules
+/tests/dwfl-bug-report
+/tests/dwfl-proc-attach
+/tests/dwfl-report-elf-align
+/tests/dwfllines
+/tests/dwflmodtest
+/tests/dwflsyms
+/tests/early-offscn
+/tests/ecp
+/tests/elfgetchdr
+/tests/elfgetzdata
+/tests/elfputzdata
+/tests/elfshphehdr
+/tests/elfstrmerge
+/tests/elfstrtab
+/tests/emptyfile
+/tests/fillfile
+/tests/find-prologues
+/tests/funcretval
+/tests/funcscopes
+/tests/get-aranges
+/tests/get-files
+/tests/get-lines
+/tests/get-pubnames
+/tests/getsrc_die
+/tests/hash
+/tests/line2addr
+/tests/low_high_pc
+/tests/msg_tst
+/tests/newdata
+/tests/newfile
+/tests/newscn
+/tests/peel_type
+/tests/rdwrmmap
+/tests/rerequest_tag
+/tests/saridx
+/tests/scnnames
+/tests/sectiondump
+/tests/show-abbrev
+/tests/show-die-info
+/tests/showptable
+/tests/strptr
+/tests/system-elf-libelf-test
+/tests/test-elf_cntl_gelf_getshdr
+/tests/test-flag-nobits
+/tests/test-nlist
+/tests/typeiter
+/tests/typeiter2
+/tests/update1
+/tests/update2
+/tests/update3
+/tests/update4
+/tests/varlocs
+/tests/vendorelf
+/tests/vdsosyms
+/tests/zstrptr
+/version.h
diff --git a/third_party/elfutils/ABOUT-NLS b/third_party/elfutils/ABOUT-NLS
new file mode 100644
index 0000000..83bc72e
--- /dev/null
+++ b/third_party/elfutils/ABOUT-NLS
@@ -0,0 +1,1068 @@
+1 Notes on the Free Translation Project
+***************************************
+
+Free software is going international!  The Free Translation Project is
+a way to get maintainers of free software, translators, and users all
+together, so that free software will gradually become able to speak many
+languages.  A few packages already provide translations for their
+messages.
+
+   If you found this `ABOUT-NLS' file inside a distribution, you may
+assume that the distributed package does use GNU `gettext' internally,
+itself available at your nearest GNU archive site.  But you do _not_
+need to install GNU `gettext' prior to configuring, installing or using
+this package with messages translated.
+
+   Installers will find here some useful hints.  These notes also
+explain how users should proceed for getting the programs to use the
+available translations.  They tell how people wanting to contribute and
+work on translations can contact the appropriate team.
+
+   When reporting bugs in the `intl/' directory or bugs which may be
+related to internationalization, you should tell about the version of
+`gettext' which is used.  The information can be found in the
+`intl/VERSION' file, in internationalized packages.
+
+1.1 Quick configuration advice
+==============================
+
+If you want to exploit the full power of internationalization, you
+should configure it using
+
+     ./configure --with-included-gettext
+
+to force usage of internationalizing routines provided within this
+package, despite the existence of internationalizing capabilities in the
+operating system where this package is being installed.  So far, only
+the `gettext' implementation in the GNU C library version 2 provides as
+many features (such as locale alias, message inheritance, automatic
+charset conversion or plural form handling) as the implementation here.
+It is also not possible to offer this additional functionality on top
+of a `catgets' implementation.  Future versions of GNU `gettext' will
+very likely convey even more functionality.  So it might be a good idea
+to change to GNU `gettext' as soon as possible.
+
+   So you need _not_ provide this option if you are using GNU libc 2 or
+you have installed a recent copy of the GNU gettext package with the
+included `libintl'.
+
+1.2 INSTALL Matters
+===================
+
+Some packages are "localizable" when properly installed; the programs
+they contain can be made to speak your own native language.  Most such
+packages use GNU `gettext'.  Other packages have their own ways to
+internationalization, predating GNU `gettext'.
+
+   By default, this package will be installed to allow translation of
+messages.  It will automatically detect whether the system already
+provides the GNU `gettext' functions.  If not, the included GNU
+`gettext' library will be used.  This library is wholly contained
+within this package, usually in the `intl/' subdirectory, so prior
+installation of the GNU `gettext' package is _not_ required.
+Installers may use special options at configuration time for changing
+the default behaviour.  The commands:
+
+     ./configure --with-included-gettext
+     ./configure --disable-nls
+
+will, respectively, bypass any pre-existing `gettext' to use the
+internationalizing routines provided within this package, or else,
+_totally_ disable translation of messages.
+
+   When you already have GNU `gettext' installed on your system and run
+configure without an option for your new package, `configure' will
+probably detect the previously built and installed `libintl.a' file and
+will decide to use this.  This might not be desirable.  You should use
+the more recent version of the GNU `gettext' library.  I.e. if the file
+`intl/VERSION' shows that the library which comes with this package is
+more recent, you should use
+
+     ./configure --with-included-gettext
+
+to prevent auto-detection.
+
+   The configuration process will not test for the `catgets' function
+and therefore it will not be used.  The reason is that even an
+emulation of `gettext' on top of `catgets' could not provide all the
+extensions of the GNU `gettext' library.
+
+   Internationalized packages usually have many `po/LL.po' files, where
+LL gives an ISO 639 two-letter code identifying the language.  Unless
+translations have been forbidden at `configure' time by using the
+`--disable-nls' switch, all available translations are installed
+together with the package.  However, the environment variable `LINGUAS'
+may be set, prior to configuration, to limit the installed set.
+`LINGUAS' should then contain a space separated list of two-letter
+codes, stating which languages are allowed.
+
+1.3 Using This Package
+======================
+
+As a user, if your language has been installed for this package, you
+only have to set the `LANG' environment variable to the appropriate
+`LL_CC' combination.  If you happen to have the `LC_ALL' or some other
+`LC_xxx' environment variables set, you should unset them before
+setting `LANG', otherwise the setting of `LANG' will not have the
+desired effect.  Here `LL' is an ISO 639 two-letter language code, and
+`CC' is an ISO 3166 two-letter country code.  For example, let's
+suppose that you speak German and live in Germany.  At the shell
+prompt, merely execute `setenv LANG de_DE' (in `csh'),
+`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
+This can be done from your `.login' or `.profile' file, once and for
+all.
+
+   You might think that the country code specification is redundant.
+But in fact, some languages have dialects in different countries.  For
+example, `de_AT' is used for Austria, and `pt_BR' for Brazil.  The
+country code serves to distinguish the dialects.
+
+   The locale naming convention of `LL_CC', with `LL' denoting the
+language and `CC' denoting the country, is the one use on systems based
+on GNU libc.  On other systems, some variations of this scheme are
+used, such as `LL' or `LL_CC.ENCODING'.  You can get the list of
+locales supported by your system for your language by running the
+command `locale -a | grep '^LL''.
+
+   Not all programs have translations for all languages.  By default, an
+English message is shown in place of a nonexistent translation.  If you
+understand other languages, you can set up a priority list of languages.
+This is done through a different environment variable, called
+`LANGUAGE'.  GNU `gettext' gives preference to `LANGUAGE' over `LANG'
+for the purpose of message handling, but you still need to have `LANG'
+set to the primary language; this is required by other parts of the
+system libraries.  For example, some Swedish users who would rather
+read translations in German than English for when Swedish is not
+available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
+
+   Special advice for Norwegian users: The language code for Norwegian
+bokma*l changed from `no' to `nb' recently (in 2003).  During the
+transition period, while some message catalogs for this language are
+installed under `nb' and some older ones under `no', it's recommended
+for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and
+older translations are used.
+
+   In the `LANGUAGE' environment variable, but not in the `LANG'
+environment variable, `LL_CC' combinations can be abbreviated as `LL'
+to denote the language's main dialect.  For example, `de' is equivalent
+to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
+(Portuguese as spoken in Portugal) in this context.
+
+1.4 Translating Teams
+=====================
+
+For the Free Translation Project to be a success, we need interested
+people who like their own language and write it well, and who are also
+able to synergize with other translators speaking the same language.
+Each translation team has its own mailing list.  The up-to-date list of
+teams can be found at the Free Translation Project's homepage,
+`http://translationproject.org/', in the "Teams" area.
+
+   If you'd like to volunteer to _work_ at translating messages, you
+should become a member of the translating team for your own language.
+The subscribing address is _not_ the same as the list itself, it has
+`-request' appended.  For example, speakers of Swedish can send a
+message to `sv-request@li.org', having this message body:
+
+     subscribe
+
+   Keep in mind that team members are expected to participate
+_actively_ in translations, or at solving translational difficulties,
+rather than merely lurking around.  If your team does not exist yet and
+you want to start one, or if you are unsure about what to do or how to
+get started, please write to `coordinator@translationproject.org' to
+reach the coordinator for all translator teams.
+
+   The English team is special.  It works at improving and uniformizing
+the terminology in use.  Proven linguistic skills are praised more than
+programming skills, here.
+
+1.5 Available Packages
+======================
+
+Languages are not equally supported in all packages.  The following
+matrix shows the current state of internationalization, as of November
+2007.  The matrix shows, in regard of each package, for which languages
+PO files have been submitted to translation coordination, with a
+translation percentage of at least 50%.
+
+     Ready PO files       af am ar az be bg bs ca cs cy da de el en en_GB eo
+                        +----------------------------------------------------+
+     Compendium         |                      []       [] []        []      |
+     a2ps               |             []                [] [] []     []      |
+     aegis              |                                  ()                |
+     ant-phone          |                                  ()                |
+     anubis             |                                  []                |
+     ap-utils           |                                                    |
+     aspell             |                      [] []    [] []        []      |
+     bash               |                                                 [] |
+     bfd                |                                                    |
+     bibshelf           |                                  []                |
+     binutils           |                                                    |
+     bison              |                               [] []                |
+     bison-runtime      |                                  []                |
+     bluez-pin          | []                      []       [] []          [] |
+     cflow              |                               []                   |
+     clisp              |                               [] []    []          |
+     console-tools      |                         []       []                |
+     coreutils          |                []    [] []       []                |
+     cpio               |                                                    |
+     cpplib             |                      []       [] []                |
+     cryptonit          |                                  []                |
+     dialog             |                                                    |
+     diffutils          |                      [] []    [] [] []          [] |
+     doodle             |                                  []                |
+     e2fsprogs          |                         []       []                |
+     enscript           |                      []       [] []        []      |
+     fetchmail          |                      []       [] () []     []      |
+     findutils          |                []                                  |
+     findutils_stable   |                []    []       []                   |
+     flex               |                      []       [] []                |
+     fslint             |                                                    |
+     gas                |                                                    |
+     gawk               |                      []       [] []                |
+     gcal               |                      []                            |
+     gcc                |                                  []                |
+     gettext-examples   | []                   []          [] []          [] |
+     gettext-runtime    |             []       []       [] []             [] |
+     gettext-tools      |                      []          []                |
+     gip                |                []                                  |
+     gliv               |                []                []                |
+     glunarclock        |                []                                  |
+     gmult              | []                               []                |
+     gnubiff            |                                  ()                |
+     gnucash            |                      [] []       () ()     []      |
+     gnuedu             |                                                    |
+     gnulib             |                []                                  |
+     gnunet             |                                                    |
+     gnunet-gtk         |                                                    |
+     gnutls             |                                  []                |
+     gpe-aerial         |                         []       []                |
+     gpe-beam           |                         []       []                |
+     gpe-calendar       |                                                    |
+     gpe-clock          |                         []       []                |
+     gpe-conf           |                         []       []                |
+     gpe-contacts       |                                                    |
+     gpe-edit           |                         []                         |
+     gpe-filemanager    |                                                    |
+     gpe-go             |                         []                         |
+     gpe-login          |                         []       []                |
+     gpe-ownerinfo      |                         []       []                |
+     gpe-package        |                                                    |
+     gpe-sketchbook     |                         []       []                |
+     gpe-su             |                         []       []                |
+     gpe-taskmanager    |                         []       []                |
+     gpe-timesheet      |                         []                         |
+     gpe-today          |                         []       []                |
+     gpe-todo           |                                                    |
+     gphoto2            |                         []    [] []        []      |
+     gprof              |                               [] []                |
+     gpsdrive           |                                                    |
+     gramadoir          | []                               []                |
+     grep               |                         []                      [] |
+     gretl              |                                  ()                |
+     gsasl              |                                                    |
+     gss                |                                                    |
+     gst-plugins-bad    |                []             []                   |
+     gst-plugins-base   |                []             []                   |
+     gst-plugins-good   |                []    []       []                   |
+     gst-plugins-ugly   |                []             []                   |
+     gstreamer          | []             []    [] []    [] []        []      |
+     gtick              |                                  ()                |
+     gtkam              |             []          []    [] []                |
+     gtkorphan          |                []                []                |
+     gtkspell           |             []                   [] []          [] |
+     gutenprint         |                               []                   |
+     hello              |                []    []       [] []             [] |
+     herrie             |                                  []                |
+     hylafax            |                                                    |
+     idutils            |                               [] []                |
+     indent             |                      [] []       []             [] |
+     iso_15924          |                                                    |
+     iso_3166           |       []    [] [] [] [] [] [] [] [] []          [] |
+     iso_3166_2         |                                                    |
+     iso_4217           |                         []    [] []                |
+     iso_639            |                         []    [] []             [] |
+     jpilot             |                         []                         |
+     jtag               |                                                    |
+     jwhois             |                                                    |
+     kbd                |                         []    [] [] []             |
+     keytouch           |                      []          []                |
+     keytouch-editor    |                                  []                |
+     keytouch-keyboa... |                      []                            |
+     latrine            |                                  ()                |
+     ld                 |                               []                   |
+     leafpad            |                []    [] []       [] []             |
+     libc               |                      [] []    [] []                |
+     libexif            |                                  []                |
+     libextractor       |                                  []                |
+     libgpewidget       |                         []    [] []                |
+     libgpg-error       |                                  []                |
+     libgphoto2         |                               [] []                |
+     libgphoto2_port    |                               [] []                |
+     libgsasl           |                                                    |
+     libiconv           |                                  []             [] |
+     libidn             |                         []    []                [] |
+     lifelines          |                               [] ()                |
+     lilypond           |                                  []                |
+     lingoteach         |                                                    |
+     lprng              |                                                    |
+     lynx               |                      [] []    [] []                |
+     m4                 |                         []    [] [] []             |
+     mailfromd          |                                                    |
+     mailutils          |                      []                            |
+     make               |                               [] []                |
+     man-db             |                      []       [] []                |
+     minicom            |                         []    [] []                |
+     nano               |                []    []          []                |
+     opcodes            |                                  []                |
+     parted             |                         []       []                |
+     pilot-qof          |                                                    |
+     popt               |                         []    [] []                |
+     psmisc             |                []                                  |
+     pwdutils           |                                                    |
+     qof                |                                                    |
+     radius             |                      []                            |
+     recode             |             []       []       [] [] []          [] |
+     rpm                |                               []                   |
+     screem             |                                                    |
+     scrollkeeper       |          [] []       [] [] [] [] []        []      |
+     sed                |                      []          []             [] |
+     shared-mime-info   |                []    [] []    [] () []     []   [] |
+     sharutils          |                []    [] []    [] [] []             |
+     shishi             |                                                    |
+     skencil            |                               [] ()                |
+     solfege            |                                                    |
+     soundtracker       |                               [] []                |
+     sp                 |                                  []                |
+     system-tools-ba... |       []       [] [] [] []    [] [] []     []      |
+     tar                |                []                []                |
+     texinfo            |                               [] []             [] |
+     tin                |                                  ()        ()      |
+     tuxpaint           | []             []             [] []        []   [] |
+     unicode-han-tra... |                                                    |
+     unicode-transla... |                                                    |
+     util-linux         |                      [] []    [] []                |
+     util-linux-ng      |                      [] []    [] []                |
+     vorbis-tools       |                         []                         |
+     wastesedge         |                                  ()                |
+     wdiff              |                      []       [] []        []      |
+     wget               |                      [] []       []                |
+     xchat              |             [] []    [] []       [] []     []      |
+     xkeyboard-config   |                []                                  |
+     xpad               |                []             []           []      |
+                        +----------------------------------------------------+
+                          af am ar az be bg bs ca cs cy da de el en en_GB eo
+                           6  0  2  1  8 26  2 40 48  2 56 88 15  1  15   18
+
+                          es et eu fa fi fr  ga gl gu he hi hr hu id is it
+                        +--------------------------------------------------+
+     Compendium         | []          [] []  []                []          |
+     a2ps               |    []       [] []                             () |
+     aegis              |                                                  |
+     ant-phone          |                []                                |
+     anubis             |                []                                |
+     ap-utils           |             [] []                                |
+     aspell             |                []  []                         [] |
+     bash               | []                                               |
+     bfd                | []          []                                   |
+     bibshelf           | []                 []                         [] |
+     binutils           | []          [] []                                |
+     bison              | [] []          []  []                   []    [] |
+     bison-runtime      |    []          []  []                   []    [] |
+     bluez-pin          |             [] []  []                [] []       |
+     cflow              |                    []                            |
+     clisp              | []             []                                |
+     console-tools      |                                                  |
+     coreutils          | [] []       [] []  []                []          |
+     cpio               | []             []  []                            |
+     cpplib             | []             []                                |
+     cryptonit          |                []                                |
+     dialog             |       []           []                         [] |
+     diffutils          | []          [] []  [] []    []       [] []    [] |
+     doodle             |                    []                         [] |
+     e2fsprogs          | []             []                             [] |
+     enscript           |                []  []             []             |
+     fetchmail          | []                                               |
+     findutils          |    []              []                []          |
+     findutils_stable   |    []          []  []                []          |
+     flex               | []             []  []                            |
+     fslint             |                                                  |
+     gas                | []             []                                |
+     gawk               | []             []  []       []                () |
+     gcal               | []             []                                |
+     gcc                | []                                               |
+     gettext-examples   | []          [] []  []                [] []    [] |
+     gettext-runtime    | []          [] []  []                   []    [] |
+     gettext-tools      | []    []       []                             [] |
+     gip                | []    []       []  []                            |
+     gliv               |                ()                                |
+     glunarclock        |             []     []                []          |
+     gmult              |       []       []                             [] |
+     gnubiff            |                ()                             () |
+     gnucash            | ()             ()                    ()          |
+     gnuedu             | []                                               |
+     gnulib             | [] []              []                            |
+     gnunet             |                                                  |
+     gnunet-gtk         |                                                  |
+     gnutls             |                                                  |
+     gpe-aerial         | []             []                                |
+     gpe-beam           | []             []                                |
+     gpe-calendar       |                                                  |
+     gpe-clock          | []          [] []                    []          |
+     gpe-conf           |                []                                |
+     gpe-contacts       | []             []                                |
+     gpe-edit           | []             []                    [] []       |
+     gpe-filemanager    | []                                               |
+     gpe-go             | []             []                    []          |
+     gpe-login          | []             []                    []          |
+     gpe-ownerinfo      | []          [] []                    [] []       |
+     gpe-package        | []                                               |
+     gpe-sketchbook     | []             []                                |
+     gpe-su             | []          [] []                    []          |
+     gpe-taskmanager    | []          [] []                                |
+     gpe-timesheet      | []             []  []                   []       |
+     gpe-today          | []          [] []  []                            |
+     gpe-todo           | []                                               |
+     gphoto2            | []          [] []                    []       [] |
+     gprof              | []          [] []  []                   []       |
+     gpsdrive           |    []                                            |
+     gramadoir          |                []  []                            |
+     grep               | []          []     []                            |
+     gretl              | []    []       []                             () |
+     gsasl              |                    []                   []       |
+     gss                |                []  []                            |
+     gst-plugins-bad    | []          []                       []       [] |
+     gst-plugins-base   | []          []                       []       [] |
+     gst-plugins-good   | []    []    []                       []       [] |
+     gst-plugins-ugly   | []          []                       []       [] |
+     gstreamer          |             []                       []       [] |
+     gtick              |             []     []                         [] |
+     gtkam              | []             []                    []       [] |
+     gtkorphan          |                []                             [] |
+     gtkspell           | []    []    [] []  []                []       [] |
+     gutenprint         |                                      []          |
+     hello              | [] [] [] [] [] []  [] []    []    [] [] []    [] |
+     herrie             |                    []                            |
+     hylafax            |                                                  |
+     idutils            |                []  []                [] []    [] |
+     indent             | [] [] []    [] []  [] []             [] []    [] |
+     iso_15924          |                []                                |
+     iso_3166           | [] [] []    [] []     [] [] [] [] [] [] []    [] |
+     iso_3166_2         |                []                                |
+     iso_4217           | [] []       [] []                    []       [] |
+     iso_639            | []       [] [] []  []                []          |
+     jpilot             | []             []                                |
+     jtag               |                []                                |
+     jwhois             | []             []                    [] []    [] |
+     kbd                | []             []                                |
+     keytouch           |                []  []                         [] |
+     keytouch-editor    |                    []                            |
+     keytouch-keyboa... |                    []                         [] |
+     latrine            |                    []                         [] |
+     ld                 | []          [] []  []                            |
+     leafpad            | []             []  []       []       []       [] |
+     libc               | []          [] []     []             []          |
+     libexif            | []                                               |
+     libextractor       |                    []                            |
+     libgpewidget       | []             []  []                [] []       |
+     libgpg-error       |                []                                |
+     libgphoto2         | []             []                             [] |
+     libgphoto2_port    |                []                             [] |
+     libgsasl           |                []  []                            |
+     libiconv           |    []       []     []                            |
+     libidn             |                []                             [] |
+     lifelines          |                ()                                |
+     lilypond           | []          [] []                                |
+     lingoteach         |                []                       []    [] |
+     lprng              |                                                  |
+     lynx               |    []                                []       [] |
+     m4                 |                []  [] []                []       |
+     mailfromd          |                                                  |
+     mailutils          | []             []                                |
+     make               | []          [] []  [] []    []    []    []       |
+     man-db             |                                               [] |
+     minicom            | []          [] []                    []          |
+     nano               | []    []       []  [] []             []       [] |
+     opcodes            | []          [] []  []                            |
+     parted             |                []                       []    [] |
+     pilot-qof          |                                                  |
+     popt               |                []  [] []                   []    |
+     psmisc             |                                      []       [] |
+     pwdutils           |                                                  |
+     qof                |                                         []       |
+     radius             | []             []                                |
+     recode             | []             []  [] []    []       [] []    [] |
+     rpm                |                []                       []       |
+     screem             |                                                  |
+     scrollkeeper       | []          []                       []          |
+     sed                | [] []          []  []                []          |
+     shared-mime-info   | []    []    [] []                    []       [] |
+     sharutils          | [] []       [] []  [] []             []       [] |
+     shishi             |                []                                |
+     skencil            | []             []                                |
+     solfege            |                                               [] |
+     soundtracker       | []             []                             [] |
+     sp                 |                []                                |
+     system-tools-ba... | []    []    [] []  []             [] [] []    [] |
+     tar                |    [] []    []     []                []          |
+     texinfo            |                []           []       []          |
+     tin                |    []          ()                                |
+     tuxpaint           |                    []                []          |
+     unicode-han-tra... |                                                  |
+     unicode-transla... |                []  []                            |
+     util-linux         | [] []       [] []                    [] []    [] |
+     util-linux-ng      | [] []       [] []                    [] []    [] |
+     vorbis-tools       |                                                  |
+     wastesedge         |                ()                                |
+     wdiff              | [] []          []  [] []             [] []    [] |
+     wget               |    []       [] []  []             [] [] []    [] |
+     xchat              | []          [] []        []    []    []       [] |
+     xkeyboard-config   | []          [] []                    []          |
+     xpad               | []                 []                []          |
+                        +--------------------------------------------------+
+                          es et eu fa fi fr  ga gl gu he hi hr hu id is it
+                          85 22 14  2 48 101 61 12  2  8  2  6 53 29  1 52
+
+                          ja ka ko ku ky lg lt lv mk mn ms mt nb ne nl  nn
+                        +--------------------------------------------------+
+     Compendium         |                                           []     |
+     a2ps               |       ()                      []          []     |
+     aegis              |                                           ()     |
+     ant-phone          |                                           []     |
+     anubis             |                               []    []    []     |
+     ap-utils           |                               []                 |
+     aspell             |                            []             []     |
+     bash               |                                           []     |
+     bfd                |                                                  |
+     bibshelf           |                               []                 |
+     binutils           |                                                  |
+     bison              |                               []    []    []     |
+     bison-runtime      |                               []    []    []     |
+     bluez-pin          |          []                   []          []     |
+     cflow              |                                                  |
+     clisp              |                                           []     |
+     console-tools      |                                                  |
+     coreutils          |                                           []     |
+     cpio               |                                           []     |
+     cpplib             |                                           []     |
+     cryptonit          |                                           []     |
+     dialog             |                               []          []     |
+     diffutils          | []                            []          []     |
+     doodle             |                                                  |
+     e2fsprogs          |                                           []     |
+     enscript           |                                           []     |
+     fetchmail          | []                                        []     |
+     findutils          |                                           []     |
+     findutils_stable   |                                           []     |
+     flex               |       []                                  []     |
+     fslint             |                                                  |
+     gas                |                                                  |
+     gawk               | []                                        []     |
+     gcal               |                                                  |
+     gcc                |                                                  |
+     gettext-examples   | []                            []          []     |
+     gettext-runtime    | []    []                                  []     |
+     gettext-tools      | []    []                                         |
+     gip                |                               []          []     |
+     gliv               |                                           []     |
+     glunarclock        |                               []          []     |
+     gmult              | []                            []          []     |
+     gnubiff            |                                                  |
+     gnucash            | ()                                  () ()        |
+     gnuedu             |                                                  |
+     gnulib             | []                                        []     |
+     gnunet             |                                                  |
+     gnunet-gtk         |                                                  |
+     gnutls             |                               []                 |
+     gpe-aerial         |                                           []     |
+     gpe-beam           |                                           []     |
+     gpe-calendar       | []                                               |
+     gpe-clock          | []    []                                  []     |
+     gpe-conf           | []    []                                  []     |
+     gpe-contacts       |       []                                         |
+     gpe-edit           | []    []                                  []     |
+     gpe-filemanager    | []    []                                         |
+     gpe-go             | []    []                                  []     |
+     gpe-login          | []    []                                  []     |
+     gpe-ownerinfo      | []                                        []     |
+     gpe-package        | []    []                                         |
+     gpe-sketchbook     |       []                                  []     |
+     gpe-su             | []    []                                  []     |
+     gpe-taskmanager    | []    [] []                               []     |
+     gpe-timesheet      |                                           []     |
+     gpe-today          | []                                        []     |
+     gpe-todo           | []                                               |
+     gphoto2            | []                                        []     |
+     gprof              |                               []                 |
+     gpsdrive           |                                           []     |
+     gramadoir          |                                           ()     |
+     grep               |             []                            []     |
+     gretl              |                                                  |
+     gsasl              |                                           []     |
+     gss                |                                                  |
+     gst-plugins-bad    |                                           []     |
+     gst-plugins-base   |                                           []     |
+     gst-plugins-good   |                                           []     |
+     gst-plugins-ugly   |                                           []     |
+     gstreamer          |                                           []     |
+     gtick              |                                           []     |
+     gtkam              | []                                        []     |
+     gtkorphan          |                                           []     |
+     gtkspell           |                            []             []     |
+     gutenprint         |                                           []     |
+     hello              | [] [] []                      []    []    []  [] |
+     herrie             |                                           []     |
+     hylafax            |                                                  |
+     idutils            |                                           []     |
+     indent             | []                                        []     |
+     iso_15924          |                                           []     |
+     iso_3166           | []    [] []       []    []          []    []  [] |
+     iso_3166_2         |                                           []     |
+     iso_4217           | []                []                      []     |
+     iso_639            | []                []                      []  [] |
+     jpilot             | ()                                        ()     |
+     jtag               |                                                  |
+     jwhois             |                                           []     |
+     kbd                |                                           []     |
+     keytouch           |                                           []     |
+     keytouch-editor    |                                           []     |
+     keytouch-keyboa... |                                                  |
+     latrine            |                                           []     |
+     ld                 |                                                  |
+     leafpad            | []                []                             |
+     libc               | []    []                                  []     |
+     libexif            |                                                  |
+     libextractor       |                                                  |
+     libgpewidget       |                                           []     |
+     libgpg-error       |                                                  |
+     libgphoto2         | []                                               |
+     libgphoto2_port    | []                                               |
+     libgsasl           |                                           []     |
+     libiconv           |                                           []     |
+     libidn             | []                                        []     |
+     lifelines          |                                           []     |
+     lilypond           |                                           []     |
+     lingoteach         |                                           []     |
+     lprng              |                                                  |
+     lynx               | []                                        []     |
+     m4                 | []                                        []     |
+     mailfromd          |                                                  |
+     mailutils          |                                                  |
+     make               | []    []                                  []     |
+     man-db             |                                                  |
+     minicom            | []                                               |
+     nano               |                               []    []    []     |
+     opcodes            |                                           []     |
+     parted             | []                                        []     |
+     pilot-qof          |                                                  |
+     popt               | []    []                                  []     |
+     psmisc             | []                                  []    []     |
+     pwdutils           |                                                  |
+     qof                |                                                  |
+     radius             |                                                  |
+     recode             |                                           []     |
+     rpm                | []    []                                         |
+     screem             | []                                               |
+     scrollkeeper       |                                     [] [] []  [] |
+     sed                | []                                        []     |
+     shared-mime-info   | []    []          []          []    []    []  [] |
+     sharutils          | []                                        []     |
+     shishi             |                                                  |
+     skencil            |                                                  |
+     solfege            |                                     ()        () |
+     soundtracker       |                                                  |
+     sp                 | ()                                               |
+     system-tools-ba... | []    []          []                      []     |
+     tar                | []          []                            []     |
+     texinfo            |                                     []    []     |
+     tin                |                                                  |
+     tuxpaint           |                                     ()    []  [] |
+     unicode-han-tra... |                                                  |
+     unicode-transla... |                                                  |
+     util-linux         | []                                        []     |
+     util-linux-ng      | []                                        []     |
+     vorbis-tools       |                                                  |
+     wastesedge         |                                           []     |
+     wdiff              |                               []    []           |
+     wget               | []                                        []     |
+     xchat              | []    []                []                []     |
+     xkeyboard-config   |    [] []                                  []     |
+     xpad               |       []                      []          []     |
+                        +--------------------------------------------------+
+                          ja ka ko ku ky lg lt lv mk mn ms mt nb ne nl  nn
+                          51  2 25  3  2  0  6  0  2  2 20  0 11  1 103  6
+
+                          or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv  ta
+                        +--------------------------------------------------+
+     Compendium         |          []  []      []       []          []     |
+     a2ps               |       ()     []      [] []       []    [] []     |
+     aegis              |                      () ()                       |
+     ant-phone          |                      []                   []     |
+     anubis             |       []             [] []                       |
+     ap-utils           |       ()                                         |
+     aspell             |                      [] []    []                 |
+     bash               |       []                      []                 |
+     bfd                |                                                  |
+     bibshelf           |                                           []     |
+     binutils           |                         []    []                 |
+     bison              |       []     []      [] []                []     |
+     bison-runtime      |       []     []      []          []       []     |
+     bluez-pin          |       []     []   [] [] []    [] []    [] []     |
+     cflow              |       []                                         |
+     clisp              |                         []                       |
+     console-tools      |                         []                       |
+     coreutils          |       []                []       []       []     |
+     cpio               |       []                []                []     |
+     cpplib             |                                           []     |
+     cryptonit          |              []                           []     |
+     dialog             |                                           []     |
+     diffutils          |       []     []      [] []             [] []     |
+     doodle             |                                     []    []     |
+     e2fsprogs          |       []                                  []     |
+     enscript           |              []      [] []       []       []     |
+     fetchmail          |       []                []          []           |
+     findutils          |       [] []                               []     |
+     findutils_stable   |       [] []          []       [] []       []     |
+     flex               |       []     []      [] []                []     |
+     fslint             |                                           []     |
+     gas                |                                                  |
+     gawk               |       []     []      []                   []     |
+     gcal               |                                           []     |
+     gcc                |                                        [] []     |
+     gettext-examples   |       [] []          [] []    [] []    [] []     |
+     gettext-runtime    |       [] []          [] []    [] []    [] []     |
+     gettext-tools      |       []             [] []    [] []    [] []     |
+     gip                |                   []          []       [] []     |
+     gliv               |       []     []      [] []    []          []     |
+     glunarclock        |              []      [] []    []       [] []     |
+     gmult              |                   [] []                [] []     |
+     gnubiff            |                      ()                   []     |
+     gnucash            |       ()                                  []     |
+     gnuedu             |                                                  |
+     gnulib             |       []                         []       []     |
+     gnunet             |                                                  |
+     gnunet-gtk         |                                           []     |
+     gnutls             |       []                                  []     |
+     gpe-aerial         |          []  []      [] []       []    [] []     |
+     gpe-beam           |          []  []      [] []       []    [] []     |
+     gpe-calendar       |                         []       []    [] []     |
+     gpe-clock          |          []  []      [] []    [] []    [] []     |
+     gpe-conf           |          []  []      [] []    [] []       []     |
+     gpe-contacts       |                      [] []       []    [] []     |
+     gpe-edit           |       [] []  []      [] []    [] []    [] []     |
+     gpe-filemanager    |                                  []       []     |
+     gpe-go             |       []     []      [] []    [] []    [] []     |
+     gpe-login          |          []  []      [] []    [] []    [] []     |
+     gpe-ownerinfo      |          []  []      [] []    [] []    [] []     |
+     gpe-package        |                                  []       []     |
+     gpe-sketchbook     |          []  []      [] []    [] []    [] []     |
+     gpe-su             |          []  []      [] []    [] []    [] []     |
+     gpe-taskmanager    |          []  []      [] []    [] []    [] []     |
+     gpe-timesheet      |          []  []      [] []    [] []    [] []     |
+     gpe-today          |          []  []      [] []    [] []    [] []     |
+     gpe-todo           |                         []       []    [] []     |
+     gphoto2            |    [] []             []       []       [] []     |
+     gprof              |              []      []                   []     |
+     gpsdrive           |                         []                []     |
+     gramadoir          |                               []          []     |
+     grep               |       []                      [] []       []     |
+     gretl              |       [] []  []                                  |
+     gsasl              |       []                               [] []     |
+     gss                |       []             []       []          []     |
+     gst-plugins-bad    |       []     []                           []     |
+     gst-plugins-base   |       []                                  []     |
+     gst-plugins-good   |       []                                  []     |
+     gst-plugins-ugly   |       []     []                           []     |
+     gstreamer          |       []                            [] [] []     |
+     gtick              |                         []                       |
+     gtkam              |    [] []     []         []                []     |
+     gtkorphan          |                                           []     |
+     gtkspell           |              []   [] [] []    [] []    [] []     |
+     gutenprint         |                                           []     |
+     hello              |       []     []      [] []    [] []    [] []     |
+     herrie             |       []                []                []     |
+     hylafax            |                                                  |
+     idutils            |       []     []      [] []                []     |
+     indent             |       []     []      [] []    []       [] []     |
+     iso_15924          |                                                  |
+     iso_3166           |    [] [] []  []      [] [] [] [] [] [] [] []  [] |
+     iso_3166_2         |                                                  |
+     iso_4217           |       [] []             [] []    []    [] []     |
+     iso_639            |       []                [] [] [] []    [] []     |
+     jpilot             |                                                  |
+     jtag               |                               []                 |
+     jwhois             |       []     []      []                   []     |
+     kbd                |       []             []                   []     |
+     keytouch           |                                           []     |
+     keytouch-editor    |                                           []     |
+     keytouch-keyboa... |                                           []     |
+     latrine            |                                                  |
+     ld                 |                                           []     |
+     leafpad            |       [] []             []    []          []  [] |
+     libc               |       []                []    []          []     |
+     libexif            |       []                      []                 |
+     libextractor       |                      []                   []     |
+     libgpewidget       |       [] []  []      []       [] []    [] []     |
+     libgpg-error       |       []             []                   []     |
+     libgphoto2         |       []                                         |
+     libgphoto2_port    |       []                []                []     |
+     libgsasl           |       []             []                [] []     |
+     libiconv           |                                  []    [] []     |
+     libidn             |       []                               [] ()     |
+     lifelines          |       []                                  []     |
+     lilypond           |                                                  |
+     lingoteach         |              []                                  |
+     lprng              |       []                                         |
+     lynx               |              []         []                []     |
+     m4                 |       []     []      [] []                []     |
+     mailfromd          |       []                                         |
+     mailutils          |       []                []                []     |
+     make               |       []     []         []                []     |
+     man-db             |       []             [] []                []     |
+     minicom            |       []     []      [] []                []     |
+     nano               |              []      [] []                []     |
+     opcodes            |                      []                   []     |
+     parted             |       []                                         |
+     pilot-qof          |                                                  |
+     popt               |       [] []             []                []     |
+     psmisc             |       []                                  []     |
+     pwdutils           |       []                                  []     |
+     qof                |              []                           []     |
+     radius             |       []                []                       |
+     recode             |       [] []  []      [] []       []       []     |
+     rpm                |       [] []             []                []     |
+     screem             |                                                  |
+     scrollkeeper       |       []             [] []    []    [] [] []     |
+     sed                |       [] []  []      [] []    [] []    [] []     |
+     shared-mime-info   |       [] []  []                     [] [] []     |
+     sharutils          |       []                []             [] []     |
+     shishi             |       []                                         |
+     skencil            |          []  []                           []     |
+     solfege            |              []                                  |
+     soundtracker       |                               []          []     |
+     sp                 |                                                  |
+     system-tools-ba... |    [] [] []  []      []             [] [] []  [] |
+     tar                |       []                []       []       []     |
+     texinfo            |       []             [] []                []     |
+     tin                |                         ()                       |
+     tuxpaint           |       [] []                      [] [] [] []     |
+     unicode-han-tra... |                                                  |
+     unicode-transla... |                                                  |
+     util-linux         |              []         []       []       []     |
+     util-linux-ng      |              []         []       []       []     |
+     vorbis-tools       |                         []                       |
+     wastesedge         |                                                  |
+     wdiff              |       []     []      [] []    [] []       []     |
+     wget               |          []             []    []          []     |
+     xchat              |    []                   []    [] [] [] [] []     |
+     xkeyboard-config   |                               [] []       []     |
+     xpad               |                               [] []       []     |
+                        +--------------------------------------------------+
+                          or pa pl pt pt_BR rm ro ru rw sk sl sq sr sv  ta
+                           0  5 77 31  53    4 58 72  3 45 46  9 45 122  3
+
+                          tg th tk tr uk ven vi  wa xh zh_CN zh_HK zh_TW zu
+                        +---------------------------------------------------+
+     Compendium         |          []        []         []          []      | 19
+     a2ps               |          [] []     []                             | 19
+     aegis              |                    []                             |  1
+     ant-phone          |          []        []                             |  6
+     anubis             |          [] []     []                             | 11
+     ap-utils           |             ()     []                             |  4
+     aspell             |             []     []  []                         | 16
+     bash               |          []                                       |  6
+     bfd                |                                                   |  2
+     bibshelf           |                    []                             |  7
+     binutils           |          [] []     []                     []      |  9
+     bison              |          [] []     []                     []      | 20
+     bison-runtime      |             []     []         []          []      | 18
+     bluez-pin          |          [] []     []  []     []          []      | 28
+     cflow              |             []     []                             |  5
+     clisp              |                                                   |  9
+     console-tools      |          []        []                             |  5
+     coreutils          |          [] []     []                             | 18
+     cpio               |          [] []     []         []                  | 11
+     cpplib             |          [] []     []         []          []      | 12
+     cryptonit          |                    []                             |  6
+     dialog             |                    []  []     []                  |  9
+     diffutils          |          [] []     []         []          []      | 29
+     doodle             |                    []                             |  6
+     e2fsprogs          |          []        []                             | 10
+     enscript           |          [] []     []                             | 16
+     fetchmail          |          []        []                             | 12
+     findutils          |          [] []     []                             | 11
+     findutils_stable   |          [] []     []                     []      | 18
+     flex               |          []        []                             | 15
+     fslint             |                    []                             |  2
+     gas                |          []                                       |  3
+     gawk               |          []        []         []                  | 16
+     gcal               |          []                                       |  5
+     gcc                |          []                   []          []      |  7
+     gettext-examples   |          [] []     []         []    []    []      | 29
+     gettext-runtime    |          [] []     []         []    []    []      | 28
+     gettext-tools      |          [] []     []         []          []      | 20
+     gip                |                    []                     []      | 13
+     gliv               |          []        []                             | 11
+     glunarclock        |                    []  []                 []      | 15
+     gmult              |          []        []         []          []      | 16
+     gnubiff            |                    []                             |  2
+     gnucash            |          () []                                    |  5
+     gnuedu             |                    []                             |  2
+     gnulib             |                    []                             | 10
+     gnunet             |                                                   |  0
+     gnunet-gtk         |          []        []                             |  3
+     gnutls             |                                                   |  4
+     gpe-aerial         |                    []         []                  | 14
+     gpe-beam           |                    []         []                  | 14
+     gpe-calendar       |                    []  []                         |  7
+     gpe-clock          |          []        []  []     []                  | 21
+     gpe-conf           |                    []  []     []                  | 16
+     gpe-contacts       |                    []         []                  | 10
+     gpe-edit           |          []        []  []     []          []      | 22
+     gpe-filemanager    |                    []  []                         |  7
+     gpe-go             |          []        []  []     []                  | 19
+     gpe-login          |          []        []  []     []          []      | 21
+     gpe-ownerinfo      |          []        []         []          []      | 21
+     gpe-package        |                    []                             |  6
+     gpe-sketchbook     |          []        []                             | 16
+     gpe-su             |          []        []  []     []                  | 21
+     gpe-taskmanager    |          []        []  []     []                  | 21
+     gpe-timesheet      |          []        []         []          []      | 18
+     gpe-today          |          []        []  []     []          []      | 21
+     gpe-todo           |                    []  []                         |  8
+     gphoto2            |             []     []         []          []      | 21
+     gprof              |          []        []                             | 13
+     gpsdrive           |                    []                             |  5
+     gramadoir          |                    []                             |  7
+     grep               |                    []                             | 12
+     gretl              |                                                   |  6
+     gsasl              |                    []         []          []      |  9
+     gss                |                    []                             |  7
+     gst-plugins-bad    |             []     []         []                  | 13
+     gst-plugins-base   |             []     []                             | 11
+     gst-plugins-good   |             []     []         []    []    []      | 16
+     gst-plugins-ugly   |             []     []         []                  | 13
+     gstreamer          |          [] []     []                             | 18
+     gtick              |             []     []                             |  7
+     gtkam              |                    []                             | 16
+     gtkorphan          |                    []                             |  7
+     gtkspell           |             []     []  []     []    []    []      | 27
+     gutenprint         |                                                   |  4
+     hello              |          [] []     []         []          []      | 38
+     herrie             |          []        []                             |  8
+     hylafax            |                                                   |  0
+     idutils            |          []        []                             | 15
+     indent             |          [] []     []         []          []      | 28
+     iso_15924          |                    []         []                  |  4
+     iso_3166           |    [] [] [] []     []  []     []    []    []      | 54
+     iso_3166_2         |                    []         []                  |  4
+     iso_4217           |    []    []        []         []    []            | 24
+     iso_639            |             []     []  []     []    []            | 26
+     jpilot             |          [] []     []         []                  |  7
+     jtag               |                    []                             |  3
+     jwhois             |          []        []                     []      | 13
+     kbd                |          [] []     []                             | 13
+     keytouch           |                    []                             |  8
+     keytouch-editor    |                    []                             |  5
+     keytouch-keyboa... |                    []                             |  5
+     latrine            |          []        []                             |  5
+     ld                 |          []        []         []          []      | 10
+     leafpad            |          [] []     []         []          []      | 24
+     libc               |          []                   []          []      | 19
+     libexif            |                    []                             |  5
+     libextractor       |                    []                             |  5
+     libgpewidget       |                    []  []     []                  | 20
+     libgpg-error       |                    []                             |  6
+     libgphoto2         |             []     []                             |  9
+     libgphoto2_port    |             []     []                     []      | 11
+     libgsasl           |                    []                             |  8
+     libiconv           |                    []  []                         | 11
+     libidn             |                    []         []                  | 11
+     lifelines          |                                                   |  4
+     lilypond           |                    []                             |  6
+     lingoteach         |                    []                             |  6
+     lprng              |                    []                             |  2
+     lynx               |          [] []     []                             | 15
+     m4                 |                    []         []          []      | 18
+     mailfromd          |             []     []                             |  3
+     mailutils          |             []     []                             |  8
+     make               |          []        []         []                  | 20
+     man-db             |                    []                             |  9
+     minicom            |                    []                             | 14
+     nano               |                    []         []          []      | 20
+     opcodes            |          []        []                             | 10
+     parted             |          [] []                            []      | 11
+     pilot-qof          |                    []                             |  1
+     popt               |          []        []         []          []      | 18
+     psmisc             |                    []         []                  | 10
+     pwdutils           |                    []                             |  3
+     qof                |                    []                             |  4
+     radius             |             []     []                             |  7
+     recode             |          []        []         []                  | 25
+     rpm                |          [] []     []                     []      | 13
+     screem             |                    []                             |  2
+     scrollkeeper       |          [] []     []                     []      | 26
+     sed                |          []        []         []          []      | 23
+     shared-mime-info   |             []     []         []                  | 29
+     sharutils          |          []        []                     []      | 23
+     shishi             |                    []                             |  3
+     skencil            |                    []                             |  7
+     solfege            |                    []                             |  3
+     soundtracker       |          []        []                             |  9
+     sp                 |          []                                       |  3
+     system-tools-ba... |    []    [] []     []     []  []          []      | 38
+     tar                |          [] []     []                             | 17
+     texinfo            |          []        []         []                  | 15
+     tin                |                                                   |  1
+     tuxpaint           |                    []  []                 []      | 19
+     unicode-han-tra... |                                                   |  0
+     unicode-transla... |                                                   |  2
+     util-linux         |          [] []     []                             | 20
+     util-linux-ng      |          [] []     []                             | 20
+     vorbis-tools       |             []     []                             |  4
+     wastesedge         |                                                   |  1
+     wdiff              |          []        []                             | 23
+     wget               |          []        []                     []      | 20
+     xchat              |             []     []         []          []      | 29
+     xkeyboard-config   |          [] []     []                             | 14
+     xpad               |                    []         []          []      | 15
+                        +---------------------------------------------------+
+       76 teams           tg th tk tr uk ven vi  wa xh zh_CN zh_HK zh_TW zu
+      163 domains          0  3  1 74 51  0  143 21  1  57     7    45    0  2036
+
+   Some counters in the preceding matrix are higher than the number of
+visible blocks let us expect.  This is because a few extra PO files are
+used for implementing regional variants of languages, or language
+dialects.
+
+   For a PO file in the matrix above to be effective, the package to
+which it applies should also have been internationalized and
+distributed as such by its maintainer.  There might be an observable
+lag between the mere existence a PO file and its wide availability in a
+distribution.
+
+   If November 2007 seems to be old, you may fetch a more recent copy
+of this `ABOUT-NLS' file on most GNU archive sites.  The most
+up-to-date matrix with full percentage details can be found at
+`http://translationproject.org/extra/matrix.html'.
+
+1.6 Using `gettext' in new packages
+===================================
+
+If you are writing a freely available program and want to
+internationalize it you are welcome to use GNU `gettext' in your
+package.  Of course you have to respect the GNU Library General Public
+License which covers the use of the GNU `gettext' library.  This means
+in particular that even non-free programs can use `libintl' as a shared
+library, whereas only free software can use `libintl' as a static
+library or use modified versions of `libintl'.
+
+   Once the sources are changed appropriately and the setup can handle
+the use of `gettext' the only thing missing are the translations.  The
+Free Translation Project is also available for packages which are not
+developed inside the GNU project.  Therefore the information given above
+applies also for every other Free Software Project.  Contact
+`coordinator@translationproject.org' to make the `.pot' files available
+to the translation teams.
+
diff --git a/third_party/elfutils/AUTHORS b/third_party/elfutils/AUTHORS
new file mode 100644
index 0000000..ef3c543
--- /dev/null
+++ b/third_party/elfutils/AUTHORS
@@ -0,0 +1,4 @@
+For Now:
+Ulrich Drepper.
+Roland McGrath
+Petr Machata
diff --git a/third_party/elfutils/CONTRIBUTING b/third_party/elfutils/CONTRIBUTING
new file mode 100644
index 0000000..e3d5a0f
--- /dev/null
+++ b/third_party/elfutils/CONTRIBUTING
@@ -0,0 +1,106 @@
+The project home is http://elfutils.org/
+
+The current elfutils source code can be checked out with
+git clone git://sourceware.org/git/elfutils.git
+
+The developer mailinglist to send patches to is
+elfutils-devel@sourceware.org.
+https://sourceware.org/ml/elfutils-devel/
+
+To subscribe send an email to elfutils-devel-subscribe@sourceware.org
+Or use the form at https://sourceware.org/lists.html#ml-requestor
+
+Please supply patches using git format-patch or using git send-email.
+
+Sign your work
+
+To facilitate tracking of who did what, we've adopted a "sign-off"
+procedure for patches based on the procedure used by the Linux kernel
+project.
+
+The sign-off is a simple line at the end of the explanation for the
+patch, which certifies that you wrote it or otherwise have the right
+to pass it on as a patch under an appropriate license. The rules are
+pretty simple: if you can certify the below:
+
+        Developer's Certificate of Origin
+
+        By making a contribution to this project, I certify that:
+
+	(a) The contribution was created in whole or in part by me,
+	    and I have the right to submit the contribution under each
+	    license indicated in, or otherwise designated as being
+	    applicable to, the file.
+
+        (b) The contribution was provided directly to me by some other
+            person who certified (a), and I have not modified it.
+
+        (c) I understand and agree that the project and the
+            contribution are public and that a record of the
+            contribution (including all personal information I submit
+            with it, including my sign-off) is maintained indefinitely
+            and may be redistributed.
+
+then you just add a line saying
+
+Signed-off-by: Random J Developer <random@developer.example.org>
+
+using your real name (sorry, no pseudonyms or anonymous contributions.)
+
+git commit --signoff will add such a Signed-off-by line at the end of
+the commit log message for you.
+
+The ideal patch contains a ChangeLog entry and a test case for the
+bug fixed or feature added.
+
+The testsuite (make check) is expected to have zero failing tests.
+Do not knowingly add tests that FAIL. If there are architectures or
+configurations where a tests is not supported make sure they are
+skipped instead of failing. Adding "exit 77" in the test shell wrapper
+indicates that a test was SKIPPED.
+
+We do allow binaries in the testsuite for tests that only need to
+read ELF or DWARF data and if generating the data in the testcase
+itself is difficult or would be architecture specific.
+The binaries should be bzip2 compressed. Add a note in the test
+wrapper run-<testcase>.sh script how to regenerate the binary.
+
+After sending your patch to the mailinglist one of the committers
+to the project will review it, give feedback, and if perfect they
+will commit it for you.
+
+You can become a maintainer/committer yourself after you have provided
+at least a handful of accepted patches and agree to the guidelines in
+this document for creating, reviewing, accepting and committing patches.
+
+To become a committer you need a sourceware account:
+https://sourceware.org/cgi-bin/pdw/ps_form.cgi
+Upload a SSH public key and have an existing maintainer sponsor you
+for the elfutils group.
+
+committers can push patches through:
+ssh://<user>@sourceware.org/git/elfutils.git
+
+The current webpages published at https://sourceware.org/elfutils/
+can be checked out with:
+git clone ssh://<user>@sourceware.org/git/elfutils-htdocs.git
+Patches should also be posted to the mailinglist.
+
+As a maintainer/committer you should still post patches as described
+above. And ideally they are reviewed and approved as above. If no
+other committer has reviewed or objected to your patch for a week
+you may use your own judgement whether you ping your patch or push
+it after "self-review". If you do, you should post a message to the
+mailinglist that the patch has been pushed.
+
+committers may also create git branches starting with <nickname>/...
+patches on these branches are works in progress, so might not be perfect
+yet, but should follow the above guidelines as much as possible and should
+be aimed at integration into master. For merging a branch into master
+the same process as above should be followed by posting the patches
+to the list first.
+
+committers/maintainers who repeatedly ignore the above guidelines,
+are hostile or offensive towards other committers or contributors,
+and don't correct their behavior after being asked by other committers
+will be removed as maintainer/committer.
diff --git a/third_party/elfutils/COPYING b/third_party/elfutils/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/third_party/elfutils/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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 3 of the License, or
+    (at your option) any later version.
+
+    This program 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.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/third_party/elfutils/COPYING-GPLV2 b/third_party/elfutils/COPYING-GPLV2
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/third_party/elfutils/COPYING-GPLV2
@@ -0,0 +1,339 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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 program 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.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/third_party/elfutils/COPYING-LGPLV3 b/third_party/elfutils/COPYING-LGPLV3
new file mode 100644
index 0000000..65c5ca8
--- /dev/null
+++ b/third_party/elfutils/COPYING-LGPLV3
@@ -0,0 +1,165 @@
+                   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/third_party/elfutils/ChangeLog b/third_party/elfutils/ChangeLog
new file mode 100644
index 0000000..279c3b2
--- /dev/null
+++ b/third_party/elfutils/ChangeLog
@@ -0,0 +1,746 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* configure.ac (HAVE_FALLTHROUGH): New define.
+
+2017-10-16  Mark Wielaard  <mark@klomp.org>
+
+	* .gitignore: Remove tests/md5-sha1-test.
+
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* configure.ac: Check if the compiler supports
+	__attribute__((gcc_struct)).
+
+2017-09-19  Mark Wielaard  <mark@klomp.org>
+
+	* README: Add basic build instructions.
+
+2017-05-03  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* configure.ac: Test if symbol versioning is supported.
+
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* configure.ac: Check if the compiler supports
+	__attribute__((visibility(...))).
+
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* configure.ac: Check if -fPIC, -fPIE, -Wl,-z,defs,
+	and -Wl,-z,relro are supported by the compiler.
+
+2017-08-02  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Set version to 0.170.
+	* NEWS: Mention new libdw dwarf_line_file function.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* NEWS: Mention dwarf_getmacros handling version 5 .debug_macro.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* NEWS: Mention dwarf_peel_type DWARF5 tags improvement.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* NEWS: Mention new DWARF5 calling conventions and defaulted member
+	function.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* NEWS: Mention new dwarf_default_lower_bound function.
+
+2017-07-25  Mark Wielaard  <mark@klomp.org>
+
+	* NEWS: Mention new DWARF5 attributes, tags, character encodings
+	and language codes in dwarf.h.
+
+2017-07-18  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Don't check for linux/bpf.h.
+	* NEWS: Mention always build bpf backend.
+
+2017-07-14  Mark Wielaard  <mark@klomp.org>
+
+	* NEWS: Add 0.170 section and new strip options.
+
+2017-05-05  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Set version to 0.169. Update copyright year.
+	* NEWS: Add 0.169 section.
+
+2017-04-21  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* .gitignore: Add fillfile and peel_type tests.
+
+2017-02-15  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* configure.ac: Add check for mempcpy.
+
+2017-02-09  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Add check for adding -D_FORTIFY_SOURCE=2 to CFLAGS.
+
+2017-01-12  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Define PACKAGE_URL for older autoconf.
+
+2016-12-27  Mark Wielaard  <mark@klomp.org>
+
+	* configure.ac: Set version to 0.168.
+	* NEWS: Add 0.168 updates.
+
+2016-12-24  Mark Wielaard  <mark@klomp.org>
+
+	* README: Move design notes to NOTES. Add URLs for home, releases,
+	bugs, git and mailinglist now on sourceware.
+	* NOTES: Add notes from README.
+	* CONTRIBUTING: Change fedorahosted.org references to new
+	sourceware.org locations.
+	* configure.ac (AC_INIT): Add package URL http://elfutils.org/
+	change bug-report to https://sourceware.org/bugzilla/
+	(AC_COPYRIGHT): Set to the elfutils developers.
+
+2016-11-23  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Add test for bad fts.h. Add -DBAD_FTS=1 to CFLAGS
+	if necessary.
+
+2016-11-02  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Add check for whether gcc accepts
+	-Wimplict-fallthrough.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* configure.ac: Add memrchr, rawmemchr and powerof2 checks.
+
+2016-08-04  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.167.
+	* NEWS: Add 0.167 section.
+
+2016-07-06  Mark Wielaard  <mjw@redhat.com>
+
+	* .gitignore: Remove src/ld. ldlex.c, ldscript.c and ldscript.h.
+	* configure.ac (enable generic): Removed.
+
+2016-06-28  Richard Henderson <rth@redhat.com>
+
+	* configure.ac (HAVE_LINUX_BPF_H): New test and conditional.
+
+2016-06-10  Mark Wielaard  <mjw@redhat.com>
+
+	* CONTRIBUTING: Extend patch, committer and maintainer guidelines.
+
+2016-05-02  Filipe Brandenburger  <filbranden@google.com>
+
+	* configure.ac (argp check): Pass pass &argv.
+	* configure.ac (-W<...> checks): Pass -Werror to the warning checks,
+	to ensure unsupported warning options are noticed during ./configure
+	time and not only later during build.
+
+2016-03-31  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.166.
+
+2016-03-02  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set program_prefix to eu- by default.
+	* NEWS (0.166): New sections, document --program-prefix default.
+
+2016-02-13  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Add check for whether gcc accepts -Wnull-dereference.
+
+2016-02-08  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Add checks for sane -Wlogical-op and whether gcc
+	accepts -Wduplicated-cond.
+
+2016-01-08  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.165.
+	* NEWS: Add 0.164 section.
+
+2016-01-04  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Add BZ2_LIBS and LIBLZMA substitutions.
+	Add config/libelf.pc and config/libdw.pc config files.
+
+2015-12-31  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (AM_MAKEFLAGS): Set --no-print-directory.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Make zlib mandatory.
+
+2015-10-15  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.164.
+	* NEWS: Add 0.164 additions.
+
+2015-10-07  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Add AM_SILENT_RULES([yes]).
+
+2015-09-24  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* configure.ac: Use -fPIC instead of -fpic to avoid relocation
+	overflows in some platforms.
+
+2015-07-11  Pino Toscano  <toscano.pino@tiscali.it>
+
+	* .gitignore: Add more generated files, and anchor some of the
+	existing ones.
+
+2015-06-19  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.163.
+	* NEWS: Mention 0.163 is bug fixes only.
+
+2015-06-10  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.162.
+	* NEWS: Add 0.162 additions.
+
+2015-06-08  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac (ADD_STACK_USAGE_WARNING): New conditional based on
+	gcc -Wstack-usage check.
+
+2015-05-31  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac (MODVERSION): Define using LIBEBL_SUBDIR, eu_version
+	and ac_cv_build.
+
+2015-05-31  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac (use_undefined): Use AC_LINK_IFELSE. AC_DEFINE
+	CHECK_UNDEFINED.
+
+2015-05-30  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Check for bunzip2. Check flex and bison are
+	installed in maintainer-mode. Otherwise check libdw/known-dwarf.h
+	is already generated.
+
+2015-05-21  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Add --enable-sanitize-undefined.
+	* Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Rename to...
+	(AM_DISTCHECK_CONFIGURE_FLAGS): this. Add --enable-sanitize-undefined.
+
+2015-05-04  Anthony G. Basile  <blueness@gentoo.org>
+
+	* configure.ac (argp_LDADD): Check if libc has argp and set
+	argp_LDADD accordingly.
+
+2015-05-03  Max Filippov  <jcmvbkbc@gmail.com>
+
+	* configure.ac (DEMANGLE): Fix enable_demangler setting.
+
+2015-05-01  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac (DEMANGLE): Explicitly set enable_demangler.
+
+2015-05-01  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac (debugpred): Use and set use_debugpred_val.
+	(textrelcheck): Explicitly set enable_textrelcheck to yes or no.
+	(symbol-versioning): Likewise for enable_symbol_versioning.
+	AC_MSG_NOTICE overview of enabled/disabled features.
+
+2015-04-23  Max Filippov  <jcmvbkbc@gmail.com>
+
+	* configure.ac: Add --disable-symbol-versioning.
+
+2015-04-14  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac (ac_cv_c99): Add explicit checks for all GNU99
+	extensions used.
+
+2015-03-13  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac (ac_cv_c99): Add explicit return.
+	(ac_cv_tls): Add stdlib.h include.
+
+2014-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.161.
+	* NEWS: Add dwarf.h additions.
+
+2014-12-15  Josh Stone  <jistone@redhat.com>
+
+	* .gitignore: Add config/compile as installed by automake 1.14.
+
+2014-11-27  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Add --disable-textrelcheck.
+
+2014-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS: New section 0.161. Add dwarf_peel_type.
+
+2014-08-25  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.160.
+	* NEWS: Add removal of DW_TAG_mutable_type, LZMA .ko.xz kernel
+	module support, ARM THUMB functions and ppc64le ELFv2 abi backends.
+
+2014-08-15  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS: Add dwarf_cu_die.
+
+2014-08-15  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS: Add dwarf_cu_getdwarf.
+
+2014-07-18  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac (AC_CHECK_TYPE): Test for struct user_regs_struct.
+
+2014-05-26  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS: New section 0.160. Add unstrip --force.
+
+2014-05-17  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.159.
+	* NEWS: Add entries for version 0.159.
+
+2014-05-02  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS: Add note about dwz support no longer being experimental and
+	new helper functions.
+	* configure.ac: Remove --enable-dwz.
+	* Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Remove --enable-dwz.
+
+2014-04-11  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (SUBDIRS): Add libdwelf.
+	* configure.ac (AC_CONFIG_FILES): Add libdwelf/Makefile.
+	* NEWS: Add note about libdwelf.
+
+2014-04-13  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Remove mudflap enable arg and MUDFLAP conditional.
+
+2014-01-21  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS (Version 0.159): Add stack -i.
+
+2014-01-20  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS (Version 0.159): New. Add stack -d.
+
+2014-01-03  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.158.
+	* NEWS: Add entries for version 0.158.
+
+2013-12-20  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS (libdwfl): Add dwfl_getthread_frames.
+	(stack): New entry.
+
+2013-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS (libdwfl): Add dwfl_module_getsym_info and
+	dwfl_module_addrinfo.
+	(addr2line): Add -x option.
+
+2013-12-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* NEWS (Version 0.158) (libdwfl): Added Dwfl_Thread_Callbacks,
+	Dwfl_Thread, Dwfl_Frame, dwfl_attach_state, dwfl_pid, dwfl_thread_dwfl,
+	dwfl_thread_tid, dwfl_frame_thread, dwfl_thread_state_registers,
+	dwfl_thread_state_register_pc, dwfl_getthreads, dwfl_thread_getframes
+	and dwfl_frame_pc.
+
+2013-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS (libdwfl): Add dwfl_module_getsymtab_first_global.
+
+2013-12-09  Josh Stone  <jistone@redhat.com>
+
+	* .gitignore: Add config/ar-lib, installed due to AM_PROG_AR.
+
+2013-12-02  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* configure.ac (CC_BIARCH): Remove AS_IF for it.
+
+2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* configure.ac: New AC_CHECK_SIZEOF for long.  Call utrace_BIARCH, new
+	AC_SUBST for CC_BIARCH.
+
+2013-11-06  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac (--enable-dwz): Add AC_MSG_WARN when disabled but
+	local system does have /usr/lib/debug/.dwz.
+
+2013-11-06  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac (--enable-thread-safety): Add AC_MSG_WARN experimental
+	option.
+
+2013-11-01  Michael Forney  <mforney@mforney.org>
+
+	* configure.ac: Call AM_PROG_AR and AC_CHECK_TOOL for readelf and nm.
+
+2013-10-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* NEWS (Version 0.158): New.
+
+2013-09-30  Mark Wielaard  <mjw@redhat.com>
+
+	* NEWS: Update for readelf NT_SIGINFO and NT_FILE core notes.
+
+2013-09-27  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.157.
+	* NEWS: Add entries for version 0.157.
+
+2013-09-20  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Add --enable-dwz.
+
+2013-07-25  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* configure.ac: Set version to 0.156.
+
+2013-07-19  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* NEWS: Remove bugfix only entries from Version 0.156.
+
+2013-07-18  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* NEWS: Add entries for Version 0.156.
+
+2013-04-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* NEWS (Version 0.156): New.
+
+2013-04-26  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac (AM_INIT_AUTOMAKE): Request parallel-tests.
+
+2013-04-25  Mark Wielaard  <mjw@redhat.com>
+
+	* .gitignore: Add config/test-driver as installed by automake 1.13.
+	* configure.ac (AM_INIT_AUTOMAKE): Require at least automake 1.11.
+
+2012-10-01  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Add --enable-valgrind check.
+	* Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Add --enable-valgrind.
+
+2012-08-27  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.155.
+
+2012-08-24  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Add --enable-dwz check, defaults to no.
+
+2012-07-24  Mark Wielaard  <mjw@redhat.com>
+
+	* TODO: Add note on shdrs after elf_cntl (ELF_C_FDREAD).
+
+2012-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.154.
+
+2012-01-24  Mark Wielaard  <mjw@redhat.com>
+
+	* COPYING: Fix address. Updated version from gnulib.
+
+2012-01-23  Mark Wielaard  <mjw@redhat.com>
+
+	* configure.ac: Set version to 0.153, update copyright years.
+
+2012-01-20  Roland McGrath  <roland@hack.frob.com>
+
+	* configure.ac: Handle --enable-deterministic-archives.
+
+2011-10-08  Roland McGrath  <roland@hack.frob.com>
+
+	* configure.ac (eu_version): Use sed instead of ${x/y/z} syntax.
+	Use POSIX.2 $((...)) syntax instead of $[...].
+	Reported by Mike Frysinger <vapier@gentoo.org>.
+
+2011-10-08  Mike Frysinger  <vapier@gentoo.org>
+
+	* configure.ac: Fix use of AC_ARG_ENABLE to handle $enableval correctly.
+
+2011-10-02  Ulrich Drepper  <drepper@gmail.com>
+
+	* configure.ac: Check for __cxa_demangle in libstdc++.
+
+2011-02-08  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (C99 check): Use AC_LANG_SOURCE.
+
+	* configure.ac (ALL_LINGUAS): Remove variable, now obsolete.
+
+2010-09-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac (ALL_LINGUAS): Add languages which have some
+	translations.
+
+2010-04-15  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (LOCALEDIR, DATADIRNAME): Removed.
+
+2009-09-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Update for more modern autoconf.
+
+2009-08-26  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (zip_LIBS): Check for liblzma too.
+
+2009-04-19  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (eu_version): Round down here, not in version.h macros.
+
+2009-04-17  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (eu_version): Compute number 1000 times larger,
+	let $PACKAGE_VERSION be x.y.z as well as x.y (implied x.y.0).
+
+2009-01-23  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (zlib check): Check for gzdirect, need zlib >= 1.2.2.3.
+
+	* configure.ac (__thread check): Use AC_LINK_IFELSE, in case of
+	building with compiler support but no working runtime support.
+
+2009-01-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (rpm): The tarball is now bzip2-compressed.
+
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Require gcc with TLS support.
+	Rename USE_TLS to USE_LOCKS.  The option is renamed to
+	--enable-thread-safety.
+
+2009-01-08  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (eu_ZIPLIB): Moved to m4/zip.am.
+
+2009-01-05  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (eu_ZIPLIB): New macro.
+	Use it to test for -lz, -lbz2, set .am ZLIB, BZLIB, zip_LIBS.
+
+2008-12-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: We need automake 1.8 now.
+
+2008-12-24  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac: Use automake flags dist-bzip2 no-dist-gzip,
+	distribute only in .tar.bz2 form now.
+
+2008-12-16  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (pkginclude_HEADERS): New variable, install version.h.
+	* configure.ac: Create it, substituting @eu_version@ with
+	PACKAGE_VERSION canonicalized to four digits of decimal.
+
+2008-08-25  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (--enable-tls): Set AM_CONDITIONAL USE_TLS too.
+
+2008-08-21  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (AH_BOTTOM): Emit #include <eu-config.h> and
+	move the contents to lib/eu-config.h instead of keeping them here.
+
+2007-12-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Add support for --enable-debugpred.
+	Update likely/unlikely macros for it.
+
+2007-06-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Remove traces of mini builds.
+	* configure.ac: Don't use libelf-po/POTFILES.in as config file
+	anymore.
+
+2007-05-16  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (AM_INIT_AUTOMAKE): Use -Wno-portability.
+
+2006-11-02  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add EXCEPTION file.
+
+2006-08-29  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac: Use AM_MAINTAINER_MODE.
+
+2006-07-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac (internal_function): Don't use internal visibility.
+
+2006-07-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Add dummy automake conditional to get dependencies
+	for non-generic linker right.  See src/Makefile.am.
+
+2005-11-18  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (DISTCHECK_CONFIGURE_FLAGS): New variable.
+
+2005-11-16  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac: Define HAVE_LIBASM and STANDALONE conditionals.
+	In config.h, define ELFUTILS_HEADER macro.
+
+2005-11-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (all_SUBDIRS): Add backends.
+	* configure.ac: Write backends/Makefile.
+
+	* configure.ac: Add --enable-tests-rpath option.
+
+2005-09-16  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac (ALLOW_UNALIGNED) [__ia64__ || __alpha__]:
+	Don't set it, since on IA64 you get error messages for unaligned
+	accesses, and on Alpha it's at least very slow.
+
+2005-08-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Fix GCOV make condition generation.
+
+2005-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Add --enable-gcov option.
+
+2005-08-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Add --enable-gprof option.
+
+2005-07-27  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (all_SUBDIRS): Put libdwfl before libdw.
+
+2005-07-21  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac: Take --enable-libebl-subdir=DIR to set LIBEBL_SUBDIR.
+
+2005-06-01  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (all_SUBDIRS): Add libdwfl.
+	* configure.ac: Write libdwfl/Makefile.
+
+2005-05-19  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac [AH_BOTTOM] (INTDECL, _INTDECL): New macros.
+
+2005-05-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Define MODVERSION in config.h.
+
+2005-02-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (all_SUBDIRS): Don't add doc subdir for now.
+	* configure.ac: Don't use doc subdir for now.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Remove AM_GNU_GETTEXT use.  Use only AM_PO_SUBDIRS.
+
+2005-02-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac (AM_INIT_AUTOMAKE): Removed dist-bzip2.
+
+	* Makefile.am (EXTRA_DIST): Remove splint.rc.
+	* splint.rc: Removed.
+
+2004-09-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Make compile with gcc 4.0.
+
+2004-03-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Use AS_HELP_STRING where applicable.
+
+2004-01-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Check for C99 compiler.
+
+	* configure.ac: Change locking macros in config.h to at least
+	evaluate the parameter.  Define base_cpu to none for generic linker.
+
+2004-01-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Print error message in case --disable-generic is
+	used if no linker support for the architecture is available.
+
+2004-01-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Dont generate libebl-po/Makefile.in,
+	libdw-po/Makefile.in, libasm-po/Makefile.in.
+
+	* Makefile.am (all_SUBDIRS): Remove libebl-po, libdw-po, libasm-po.
+
+2004-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Pretty printing of help message.
+
+	* configure.ac: Move AC_SYS_LARGEFILE test to the front.
+
+	* configure.ac: Add --enable-mudflap option.
+
+2004-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Major cleanups.  Use aux dir.
+	* config.guess: Moved to new config subdir.
+	* config.rpath: Likewise.
+	* config.sub: Likewise.
+	* depcomp: Likewise.
+	* install-sh: Likewise.
+	* missing: Likewise.
+	* mkinstalldirs: Likewise.
+	* Makefile.am (mini_SUBDIRS): Add config.
+	(EXTRA_DIST): Remove config.rpath.
+
+	* configure.ac: Add AC_REVISION.
+
+	* configure.ac: Add --enable-mudflap option.
+
+2004-01-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* configure.ac: Drop libdwarf directory.  Add libdw-po.
+	* Makefile.am (all_SUBDIRS): Likewise.
+	* elfutils.spec: Don't distribute anything from libdwarf.
+
+2004-01-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support separate libelf built.
+
+	* elfutils.spec.in: Create separata elfutils-libelf-devel package.
+	Install libdw DSOs.
+
+	* configure.ac (AC_CONFIG_SRCDIR): Use libelf/libelf.h as the file
+	name.
+
+2003-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in: Remove references to libebl.so.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* Moved to CVS archive.
+
+2000-08-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* The beginning.  See the NEWS file for the time being.
diff --git a/third_party/elfutils/GPG-KEY b/third_party/elfutils/GPG-KEY
new file mode 100644
index 0000000..cd60f82
--- /dev/null
+++ b/third_party/elfutils/GPG-KEY
@@ -0,0 +1,33 @@
+Public key for drepper@redhat.com
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.2.1 (GNU/Linux)
+
+mQGiBDuFth0RBACPcHEkyqJE26wTXuuuCxpqJjxlBnNFkJGkWUoeu89QjzWgzXy/
+EA8+ptNBgCTPKnLEqhkRUyxAT/Uz+t+xbKqUtL54IzYfxO4NQsN/VVM0uppNfIJb
+MWvAjvpp2HCkd/32i693rlH+G9dvG8K57by3PBRHBgH2L8Q7t/QvA2AWpwCgzokX
+DDUiitysGn4rWO0rBBoR6OED/3ehpcHtbGixNoubRZAxpw99VTKs/I76OkrQzqcm
++w+zwZeihJXC88yAHA77/LBB3YKaX3G4CmDQUbeRJ9zPlETTLmRMcF61dQdq/3qV
+Biq1sm6ctZ4uEpm8HnysKMT+VY4Xmj9LLzF2BdING9frcX9rk8Vk25iCLBronS0M
+IU3WA/sEvlUFlfbyCBRBoq+Rlr9u05fnHc7CLMKI7EIS1T1dLPxH1ivuUhyYNGAM
+RhCivBbT2Z0t/R4ksu3VdnPGkCyAAdWNSafSGqCYUzQH0u5Z8HK6c2iXrIX3Ipk5
+DhQOQ6k1tyYzuQw3cCf7RYRJ9/iup8RlscVt2kmGnSucqpxJCbQjVWxyaWNoIERy
+ZXBwZXIgPGRyZXBwZXJAcmVkaGF0LmNvbT6IVwQTEQIAFwUCO4W2HQULBwoDBAMV
+AwIDFgIBAheAAAoJENoowjp5/0R0SqUAoL5HBbaRWR19vjldUeJvYCG2AR94AKDL
+nmVEaykaZWyyNg0OTuxLe1boa4hGBBARAgAGBQI8iQDvAAoJEFWW3Qzpv2U97wgA
+n1RVl6FbIHVVmT224nOp5b98OZVnAJ9ehXzM60RbmGi3kJNS30II+SGft4hGBBMR
+AgAGBQI9Tvt0AAoJEP3S3qzTM8uhUy0AoNqATBj2usEtJduGHukKZ9mQaycFAJ9y
+lq0MmZJwMZ3699e6rgMiHAMAVbkCDQQ7hbZPEAgAzuFAPq1sYUtpJClwX7+pdz1K
+dIgbxDKoSHh2rSRx24HLYY/xg9ps6fZF21/SBialKaB8BFnIeh8S9LXUtWt9aUeC
+klnnQwPbR0BGRcZAS7+nHZ9agiMd4CRe4RWFmS6KhIeUsDa70+8XhIm/C+Ogd7ag
+kBw7ykTb/jWHMyvcP9iY0QtmIatfVTDJUm7Rm5TtM1mDCml/gWIQJ5ezr9gv2NUG
+3kpNYwP+G9o4BLyTOHamix/0YHI/HiZSYiwq40ao0zROd/yXY6/a3mitN96AidJL
+5I5tbqnrFy6LmRvWmyOxWkJD/bF31rrO5PfVUgcVpUxbtW44PtVilhLuh+qjTwAD
+BQf+NTHwjUw1j+PZs/y5XnPw0x0ZdYGEl0I7NqtMgCxI4ZHT9jaLcLXARb3UVEuc
+1LuJ1tAA1ss1c1NLK3Lg+uZzeKMRffRYEUg0Emer8QGWr1uSOxDHcAzuRZX3PYNX
+cEGEyEm443DDnXr/4b8zYK6O+sy1Ld+SVxxp6jwtk0LyT7okgD0E1dDUzX+qxpsV
+ujbzdH4bdqocKouMNMT+BHeobNZpR4Tyz5+pwW+rw1+XZebyBUkIPXOoWPZpUTDG
+fZ+om9xfg0JOcKZIZ0X91dLQp5x99aCmzwWeWy9LFPTAf9pYky8wXzteEotE/Tkm
+DeA1caPC9IEK9BBrrS9TeubrEIhGBBgRAgAGBQI7hbZPAAoJENoowjp5/0R0Z38A
+mgM4FAquwltH0ooTdAmBMoCfKb4/AJ9ufAh4Rl9sFaCie/j8jdo02bcV1A==
+=Yeua
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/third_party/elfutils/Makefile.am b/third_party/elfutils/Makefile.am
new file mode 100644
index 0000000..2ff444e
--- /dev/null
+++ b/third_party/elfutils/Makefile.am
@@ -0,0 +1,53 @@
+## Process this file with automake to create Makefile.in
+## Configure input file for elfutils.
+##
+## Copyright (C) 1996-2006, 2008, 2009, 2015 Red Hat, Inc.
+##
+## This file is part of elfutils.
+##
+## This file 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 3 of the License, or
+## (at your option) any later version.
+##
+## elfutils 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.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program.  If not, see <http://www.gnu.org/licenses/>.
+##
+ACLOCAL_AMFLAGS = -I m4
+
+# automake already tells which subdir is being entered.
+# Don't make make repeat.
+AM_MAKEFLAGS = --no-print-directory
+
+pkginclude_HEADERS = version.h
+
+# Add doc back when we have some real content.
+SUBDIRS = config m4 lib libelf libebl libdwelf libdwfl libdw libcpu libasm \
+	  backends src po tests
+
+EXTRA_DIST = elfutils.spec GPG-KEY NOTES CONTRIBUTING \
+	     COPYING COPYING-GPLV2 COPYING-LGPLV3
+
+# Make sure the test install uses lib64 when $LIB will yield lib64.
+# Make sure the test build uses the same compiler, which on e.g. ppc64
+# determines which platform we are actually testing.
+# Run all tests under valgrind.
+AM_DISTCHECK_CONFIGURE_FLAGS = \
+	--libdir=`echo $(libdir) | sed "s,^$(exec_prefix),$$dc_install_base,"`\
+	--enable-valgrind --enable-sanitize-undefined \
+	CC="$(CC)"
+
+distcheck-hook:
+	chmod -R u+w $(distdir)
+
+rpm: dist
+	rpmbuild -ts --sign elfutils-@PACKAGE_VERSION@.tar.bz2
+
+# Tell version 3.79 and up of GNU make to not build goals in this
+# directory in parallel.
+.NOTPARALLEL:
diff --git a/third_party/elfutils/NEWS b/third_party/elfutils/NEWS
new file mode 100644
index 0000000..72e5118
--- /dev/null
+++ b/third_party/elfutils/NEWS
@@ -0,0 +1,1465 @@
+Version 0.170
+
+libdw: Added new DWARF5 attribute, tag, character encoding, language code,
+       calling convention, defaulted member function and macro constants
+       to dwarf.h.
+       New functions dwarf_default_lower_bound and dwarf_line_file.
+       dwarf_peel_type now handles DWARF5 immutable, packed and shared tags.
+       dwarf_getmacros now handles DWARF5 .debug_macro sections.
+
+strip: Add -R, --remove-section=SECTION and --keep-section=SECTION.
+
+backends: The bpf disassembler is now always build on all platforms.
+
+Version 0.169
+
+backends: Add support for EM_PPC64 GNU_ATTRIBUTES.
+          Frame pointer unwinding fallback support for i386, x86_64, aarch64.
+
+translations: Update Polish translation.
+
+Version 0.168
+
+http://elfutils.org/ is now hosted at http://sourceware.org/elfutils/
+
+libelf: gelf_newehdr and gelf_newehdr now return void *.
+
+libdw: dwarf.h corrected the DW_LANG_PLI constant name (was DW_LANG_PL1).
+
+readelf: Add optional --symbols[=SECTION] argument to select section name.
+
+Version 0.167
+
+libasm: Add eBPF disassembler for EM_BPF files.
+
+backends: Add m68k and BPF backends.
+
+ld: Removed.
+
+dwelf: Add ELF/DWARF string table creation functions. dwelf_strtab_init,
+       dwelf_strtab_add, dwelf_strtab_add_len, dwelf_strtab_finalize,
+       dwelf_strent_off, dwelf_strent_str and dwelf_strtab_free.
+
+Version 0.166
+
+config: The default program prefix for the installed tools is now eu-.
+        Use configure --program-prefix="" to not use a program prefix.
+
+Version 0.165
+
+elfcompress: New utility to compress or decompress ELF sections.
+
+readelf: Add -z,--decompress option.
+
+libelf: Add elf_compress, elf_compress_gnu, elf32_getchdr, elf64_getchdr
+        and gelf_getchdr.
+
+libdwelf: New function dwelf_scn_gnu_compressed_size.
+
+config: Add libelf and libdw pkg-config files.
+
+backends: sparc support for core and live backtraces.
+
+translations: Updated Polish translation.
+
+Version 0.164
+
+strip, unstrip: Handle ELF files with merged strtab/shstrtab tables.
+                Handle missing SHF_INFO_LINK section flags.
+
+libelf: Use int64_t for offsets in libelf.h instead of loff_t.
+
+libdw: dwarf.h Add preliminary DWARF5 DW_LANG_Haskell.
+
+libdwfl: dwfl_standard_find_debuginfo now searches any subdir of the binary
+         path under the debuginfo root when the separate debug file couldn't
+         be found by build-id.
+         dwfl_linux_proc_attach can now be called before any Dwfl_Modules
+         have been reported.
+
+backends: Better sparc and sparc64 support.
+
+translations: Updated Ukrainian translation.
+
+Provide default-yama-scope subpackage.
+
+Version 0.163
+
+Bug fixes only, no new features.
+
+Version 0.162
+
+libdw: Install new header elfutils/known-dwarf.h.
+       dwarf.h Add preliminary DWARF5 constants DW_TAG_atomic_type,
+       DW_LANG_Fortran03, DW_LANG_Fortran08. dwarf_peel_type now also
+       handles DW_TAG_atomic_type.
+
+addr2line: Input addresses are now always interpreted as hexadecimal
+           numbers, never as octal or decimal numbers.
+           New option -a, --addresses to print address before each entry.
+           New option -C, --demangle to show demangled symbols.
+           New option --pretty-print to print all information on one line.
+
+ar: CVE-2014-9447 Directory traversal vulnerability in ar extraction.
+
+backends: x32 support.
+
+Version 0.161
+
+libdw: New function dwarf_peel_type. dwarf_aggregate_size now uses
+       dwarf_peel_type to also provide the sizes of qualified types.
+       dwarf_getmacros will now serve either of .debug_macro and
+       .debug_macinfo transparently.  New interfaces
+       dwarf_getmacros_off, dwarf_macro_getsrcfiles,
+       dwarf_macro_getparamcnt, and dwarf_macro_param are available
+       for more generalized inspection of macros and their parameters.
+       dwarf.h: Add DW_AT_GNU_deleted, DW_AT_noreturn, DW_LANG_C11,
+       DW_LANG_C_plus_plus_11 and DW_LANG_C_plus_plus_14.
+
+Version 0.160
+
+libdw: New functions dwarf_cu_getdwarf, dwarf_cu_die.
+       dwarf.h remove non-existing DW_TAG_mutable_type.
+
+libdwfl: Handle LZMA .ko.xz compressed kernel modules.
+
+unstrip: New option -F, --force to combining files even if some ELF headers
+         don't seem to match.
+
+backends: Handle ARM THUMB functions. Add support for ppc64le ELFv2 abi.
+
+Version 0.159
+
+stack: New option -d, --debugname to lookup DWARF debuginfo name for frame.
+       New option -i, --inlines to show inlined frames using DWARF debuginfo.
+
+libdwelf: New libdwelf.h header for libdw.so DWARF ELF Low-level Functions.
+          New function dwelf_elf_gnu_debuglink, dwelf_dwarf_gnu_debugaltlink,
+	  and dwelf_elf_gnu_build_id.
+
+libdw: Support for DWZ multifile forms DW_FORM_GNU_ref_alt and
+       DW_FORM_GNU_strp_alt is now enabled by default and no longer
+       experimental. Added new functions dwarf_getalt and dwarf_setalt
+       to get or set the alternative debug file used for the alt FORMs.
+       The dwfl_linux_proc_find_elf callback will now find ELF from
+       process memory for (deleted) files if the Dwfl has process state
+       attached.
+
+libdwfl: The dwfl_build_id_find_debuginfo and dwfl_standard_find_debuginfo
+         functions will now try to resolve and set the alternative debug file.
+
+backends: Add CFI unwinding for arm. Relies on .debug_frame.
+          Add arm process initial register state compatible mode to AARCH64.
+          Add aarch64 native and core unwind support.
+
+other: All separate elfutils-robustify patches have been merged.
+       CVE-2014-0172 Check overflow before calling malloc to uncompress data.
+
+Version 0.158
+
+libdwfl: dwfl_core_file_report has new parameter executable.
+         New functions dwfl_module_getsymtab_first_global,
+         dwfl_module_getsym_info and dwfl_module_addrinfo.
+         Added unwinder with type Dwfl_Thread_Callbacks, opaque types
+         Dwfl_Thread and Dwfl_Frame and functions dwfl_attach_state,
+         dwfl_pid, dwfl_thread_dwfl, dwfl_thread_tid, dwfl_frame_thread,
+         dwfl_thread_state_registers, dwfl_thread_state_register_pc,
+         dwfl_getthread_frames, dwfl_getthreads, dwfl_thread_getframes
+         and dwfl_frame_pc.
+
+addr2line: New option -x to show the section an address was found in.
+
+stack: New utility that uses the new unwinder for processes and cores.
+
+backends: Unwinder support for i386, x86_64, s390, s390x, ppc and ppc64.
+          aarch64 support.
+
+Version 0.157
+
+libdw: Add new functions dwarf_getlocations, dwarf_getlocation_attr
+       and dwarf_getlocation_die.
+
+readelf: Show contents of NT_SIGINFO and NT_FILE core notes.
+
+addr2line: Support -i, --inlines output option.
+
+backends: abi_cfi hook for arm, ppc and s390.
+
+Version 0.156
+
+lib: New macro COMPAT_VERSION_NEWPROTO.
+
+libdw: Handle GNU extension opcodes in dwarf_getlocation.
+
+libdwfl: Fix STB_GLOBAL over STB_WEAK preference in dwfl_module_addrsym.
+         Add minisymtab support.
+         Add parameter add_p_vaddr to dwfl_report_elf.
+         Use DT_DEBUG library search first.
+
+libebl: Handle new core note types in EBL.
+
+backends: Interpret NT_ARM_VFP.
+          Implement core file registers parsing for s390/s390x.
+
+readelf: Add --elf-section input option to inspect an embedded ELF file.
+         Add -U, --unresolved-address-offsets output control.
+         Add --debug-dump=decodedline support.
+         Accept version 8 .gdb_index section format.
+         Adjust output formatting width.
+         When highpc is in constant form print it also as address.
+         Display raw .debug_aranges. Use libdw only for decodedaranges.
+
+elflint: Add __bss_start__ to the list of allowed symbols.
+
+tests: Add configure --enable-valgrind option to run all tests under valgrind.
+       Enable automake parallel-tests for make check.
+
+translations: Updated Polish translation.
+
+Updates for Automake 1.13.
+
+Version 0.155
+
+libelf: elf*_xlatetomd now works for cross-endian ELF note data.
+        elf_getshdr now works consistently on non-mmaped ELF files after
+        calling elf_cntl(ELF_C_FDREAD).
+        Implement support for ar archives with 64-bit symbol table.
+
+libdw: dwarf.h corrected the DW_LANG_ObjC constant name (was DW_LANG_Objc).
+       Any existing sources using the old name will have to be updated.
+       Add DW_MACRO_GNU .debug_macro type encodings constants, DW_ATE_UTF
+       and DW_OP_GNU_parameter_ref to dwarf.h.
+       Experimental support for DWZ multifile forms DW_FORM_GNU_ref_alt
+       and DW_FORM_GNU_strp_alt.  Disabled by default.  Use configure
+       --enable-dwz to test it.
+
+readelf: Add .debug_macro parsing support.
+         Add .gdb_index version 7 parsing support.
+         Recognize DW_OP_GNU_parameter_ref.
+
+backends: Add support for Tilera TILE-Gx processor.
+
+translations: Updated Ukrainian translation.
+
+Version 0.154
+
+libelf: [g]elf[32|64]_offscn() do not match SHT_NOBITS sections at OFFSET.
+
+libdw: dwarf_highpc function now handles DWARF 4 DW_AT_high_pc constant form.
+       Fix bug using dwarf_next_unit to iterate over .debug_types.
+
+elflint: Now accepts gold linker produced executables.
+
+The license is now GPLv2/LGPLv3+ for the libraries and GPLv3+ for stand-alone
+programs. There is now also a formal CONTRIBUTING document describing how to
+submit patches.
+
+Version 0.153
+
+libdw: Support reading .zdebug_* DWARF sections compressed via zlib.
+
+libdwfl: Speed up dwfl_module_addrsym.
+
+nm: Support C++ demangling.
+
+ar: Support D modifier for "deterministic output" with no uid/gid/mtime info.
+    The U modifier is the inverse.
+    elfutils can be configured with the --enable-deterministic-archives
+    option to make the D behavior the default when U is not specified.
+
+ranlib: Support -D and -U flags with same meaning.
+
+readelf: Improve output of -wline. Add support for printing SDT elf notes.
+         Add printing of .gdb_index section.
+	 Support for typed DWARF stack, call_site and entry_value.
+
+strip: Add --reloc-debug-sections option.
+       Improved SHT_GROUP sections handling.
+
+Version 0.152
+
+Various build and warning nits fixed for newest GCC and Autoconf.
+
+libdwfl: Yet another prelink-related fix for another regression.
+	 Look for Linux kernel images in files named with compression suffixes.
+
+elfcmp: New flag --ignore-build-id to ignore differing build ID bits.
+	New flag -l/--verbose to print all differences.
+
+Version 0.151
+
+libdwfl: Fix for more prelink cases with separate debug file.
+
+strip: New flag --strip-sections to remove section headers entirely.
+
+Version 0.150
+
+libdw: Fix for handling huge .debug_aranges section.
+
+libdwfl: Fix for handling prelinked DSO with separate debug file.
+
+findtextrel: Fix diagnostics to work with usual section ordering.
+
+libebl: i386 backend fix for multi-register integer return value location.
+
+Version 0.149:
+
+libdw: Decode new DW_OP_GNU_implicit_pointer operation;
+       new function dwarf_getlocation_implicit_pointer.
+
+libdwfl: New function dwfl_dwarf_line.
+
+addr2line: New flag -F/--flags to print more DWARF line information details.
+
+strip: -g recognizes .gdb_index as a debugging section.
+
+Version 0.148:
+
+libdw: Accept DWARF 4 format: new functions dwarf_next_unit, dwarf_offdie_types.
+       New functions dwarf_lineisa, dwarf_linediscriminator, dwarf_lineop_index.
+
+libdwfl: Fixes in core-file handling, support cores from PIEs.
+	 When working from build IDs, don't open a named file that mismatches.
+
+readelf: Handle DWARF 4 formats.
+
+Version 0.147:
+
+libdw: Fixes in CFI handling, best possible handling of bogus CFA ops.
+
+libdwfl: Ignore R_*_NONE relocs, works around old (binutils) ld -r bugs.
+
+Version 0.146:
+
+libdwfl: New function dwfl_core_file_report.
+
+Version 0.145:
+
+Fix build with --disable-dependency-tracking.
+
+Fix build with most recent glibc headers.
+
+libelf: More robust to bogus section headers.
+
+libdw: Fix CFI decoding.
+
+libdwfl: Fix address bias returned by CFI accessors.
+	 Fix core file module layout identification.
+
+readelf: Fix CFI decoding.
+
+Version 0.144:
+
+libelf: New function elf_getphdrnum.
+	Now support using more than 65536 program headers in a file.
+
+libdw: New function dwarf_aggregate_size for computing (constant) type
+       sizes, including array_type cases with nontrivial calculation.
+
+readelf: Don't give errors for missing info under -a.
+	 Handle Linux "VMCOREINFO" notes under -n.
+
+Version 0.143:
+
+libdw: Various convenience functions for individual attributes now use
+       dwarf_attr_integrate to look up indirect inherited attributes.
+       Location expression handling now supports DW_OP_implicit_value.
+
+libdwfl: Support automatic decompression of files in XZ format,
+	 and of Linux kernel images made with bzip2 or LZMA (as well as gzip).
+
+Version 0.142:
+
+libelf: Add elf_getshdrnum alias for elf_getshnum and elf_getshdrstrndx alias
+	for elf_getshstrndx and deprecate original names.  Sun screwed up
+	their implementation and asked for a solution.
+
+libebl: Add support for STB_GNU_UNIQUE.
+
+elflint: Add support for STB_GNU_UNIQUE.
+
+readelf: Add -N option, speeds up DWARF printing without address->name lookups.
+
+libdw: Add support for decoding DWARF CFI into location description form.
+       Handle some new DWARF 3 expression operations previously omitted.
+       Basic handling of some new encodings slated for DWARF 4.
+
+Version 0.141:
+
+libebl: sparc backend fixes;
+	some more arm backend support
+
+libdwfl: fix dwfl_module_build_id for prelinked DSO case;
+	 fixes in core file support;
+	 dwfl_module_getsym interface improved for non-address symbols
+
+strip: fix infinite loop on strange inputs with -f
+
+addr2line: take -j/--section=NAME option for binutils compatibility
+	   (same effect as '(NAME)0x123' syntax already supported)
+
+Version 0.140:
+
+libelf: Fix regression in creation of section header
+
+libdwfl: Less strict behavior if DWARF reader ist just used to display data
+
+Version 0.139:
+
+libcpu: Add Intel SSE4 disassembler support
+
+readelf: Implement call frame information and exception handling dumping.
+	 Add -e option.  Enable it implicitly for -a.
+
+elflint: Check PT_GNU_EH_FRAME program header entry.
+
+libdwfl: Support automatic gzip/bzip2 decompression of ELF files.
+
+Version 0.138:
+
+Install <elfutils/version.h> header file for applications to use in source
+version compatibility checks.
+
+libebl: backend fixes for i386 TLS relocs; backend support for NT_386_IOPERM
+
+libcpu: disassembler fixes
+
+libdwfl: bug fixes
+
+libelf: bug fixes
+
+nm: bug fixes for handling corrupt input files
+
+Version 0.137:
+
+Minor fixes for unreleased 0.136 release.
+
+Version 0.136:
+
+libdwfl: bug fixes; new "segment" interfaces;
+	 all the libdwfl-based tools now support --core=COREFILE option
+
+Version 0.135:
+
+libdwfl: bug fixes
+
+strip: changed handling of ET_REL files wrt symbol tables and relocs
+
+Version 0.134:
+
+elflint: backend improvements for sparc, alpha
+
+libdwfl, libelf: bug fixes
+
+Version 0.133:
+
+readelf, elflint, libebl: SHT_GNU_ATTRIBUTE section handling (readelf -A)
+
+readelf: core note handling for NT_386_TLS, NT_PPC_SPE, Alpha NT_AUXV
+
+libdwfl: bug fixes and optimization in relocation handling
+
+elfcmp: bug fix for non-allocated section handling
+
+ld: implement newer features of binutils linker.
+
+Version 0.132:
+
+libcpu: Implement x86 and x86-64 disassembler.
+libasm: Add interface for disassembler.
+
+all programs: add debugging of branch prediction.
+
+libelf: new function elf_scnshndx.
+
+Version 0.131:
+
+libdw: DW_FORM_ref_addr support; dwarf_formref entry point now deprecated;
+       bug fixes for oddly-formatted DWARF
+
+libdwfl: bug fixes in offline archive support, symbol table handling;
+	 apply partial relocations for dwfl_module_address_section on ET_REL
+
+libebl: powerpc backend support for Altivec registers
+
+Version 0.130:
+
+readelf: -p option can take an argument like -x for one section,
+	 or no argument (as before) for all SHF_STRINGS sections;
+	 new option --archive-index (or -c);
+	 improved -n output for core files, on many machines
+
+libelf: new function elf_getdata_rawchunk, replaces gelf_rawchunk;
+	new functions gelf_getnote, gelf_getauxv, gelf_update_auxv
+
+readelf, elflint: handle SHT_NOTE sections without requiring phdrs
+
+elflint: stricter checks on debug sections
+
+libdwfl: new functions dwfl_build_id_find_elf, dwfl_build_id_find_debuginfo,
+	 dwfl_module_build_id, dwfl_module_report_build_id;
+	 support dynamic symbol tables found via phdrs;
+	 dwfl_standard_find_debuginfo now uses build IDs when available
+
+unstrip: new option --list (or -n)
+
+libebl: backend improvements for sparc, alpha, powerpc
+
+Version 0.129:
+
+readelf: new options --hex-dump (or -x), --strings (or -p)
+
+addr2line: new option --symbols (or -S)
+
+Version 0.128:
+
+new program: unstrip
+
+elfcmp: new option --hash-inexact
+
+Version 0.127:
+
+libdw: new function dwarf_getsrcdirs
+
+libdwfl: new functions dwfl_module_addrsym, dwfl_report_begin_add,
+	 dwfl_module_address_section
+
+Version 0.126:
+
+new program: ar
+
+Version 0.125:
+
+elflint: Compare DT_GNU_HASH tests.
+
+move archives into -static RPMs
+
+libelf, elflint: better support for core file handling
+
+Version 0.124:
+
+libebl: sparc backend support for return value location
+
+libebl, libdwfl: backend register name support extended with more info
+
+libelf, libdw: bug fixes for unaligned accesses on machines that care
+
+readelf, elflint: trivial bugs fixed
+
+Version 0.123:
+
+libebl: Backend build fixes, thanks to Stepan Kasal.
+
+libebl: ia64 backend support for register names, return value location
+
+libdwfl: Handle truncated linux kernel module section names.
+
+libdwfl: Look for linux kernel "vmlinux" files with ".debug" suffix.
+
+elflint: Fix checks to permit --hash-style=gnu format.
+
+Version 0.122:
+
+libebl: add function to test for relative relocation
+
+elflint: fix and extend DT_RELCOUNT/DT_RELACOUNT checks
+
+elflint, readelf: add support for DT_GNU_HASH
+libelf: add elf_gnu_hash
+
+elflint, readelf: add support for 64-bit SysV-style hash tables
+
+libdwfl: new functions dwfl_module_getsymtab, dwfl_module_getsym.
+
+Version 0.121:
+
+libelf: bug fixes for rewriting existing files when using mmap.
+
+make all installed headers usable in C++ code.
+
+readelf: better output format.
+
+elflint: fix tests of dynamic section content.
+
+ld: Implement --as-needed, --execstack, PT_GNU_STACK.  Many small patches.
+
+libdw, libdwfl: handle files without aranges info.
+
+Version 0.120:
+
+Bug fixes.
+
+dwarf.h updated for DWARF 3.0 final specification.
+
+libdwfl: New function dwfl_version.
+
+The license is now GPL for most files.  The libelf, libebl, libdw,
+and libdwfl libraries have additional exceptions.  Add reference to
+OIN.
+
+Version 0.119:
+
+bug fixes
+
+Version 0.118:
+
+elflint: more tests.
+
+libdwfl: New function dwfl_module_register_names.
+
+libebl: New backend hook for register names.
+
+Version 0.117:
+
+libdwfl: New function dwfl_module_return_value_location.
+
+libebl: Backend improvements for several CPUs.
+
+Version 0.116:
+
+libdw: New functions dwarf_ranges, dwarf_entrypc, dwarf_diecu,
+       dwarf_entry_breakpoints.  Removed Dwarf_Func type and functions
+       dwarf_func_name, dwarf_func_lowpc, dwarf_func_highpc,
+       dwarf_func_entrypc, dwarf_func_die; dwarf_getfuncs callback now uses
+       Dwarf_Die, and dwarf_func_file, dwarf_func_line, dwarf_func_col
+       replaced by dwarf_decl_file, dwarf_decl_line, dwarf_decl_column;
+       dwarf_func_inline, dwarf_func_inline_instances now take Dwarf_Die.
+       Type Dwarf_Loc renamed to Dwarf_Op; dwarf_getloclist,
+       dwarf_addrloclists renamed dwarf_getlocation, dwarf_getlocation_addr.
+
+Version 0.115:
+
+libelf: speed-ups of non-mmap reading.
+
+strings: New program.
+
+Implement --enable-gcov option for configure.
+
+libdw: New function dwarf_getscopes_die.
+
+Version 0.114:
+
+libelf: new function elf_getaroff
+
+libdw: Added dwarf_func_die, dwarf_func_inline, dwarf_func_inline_instances.
+
+libdwfl: New functions dwfl_report_offline, dwfl_offline_section_address,
+	 dwfl_linux_kernel_report_offline.
+
+ranlib: new program
+
+Version 0.113:
+
+elflint: relax a bit. Allow version definitions for defined symbols against
+DSO versions also for symbols in nobits sections.  Allow .rodata section
+to have STRINGS and MERGE flag set.
+
+strip: add some more compatibility with binutils.
+
+Version 0.112:
+
+elfcmp: some more relaxation.
+
+elflint: many more tests, especially regarding to symbol versioning.
+
+libelf: Add elfXX_offscn and gelf_offscn.
+
+libasm: asm_begin interface changes.
+
+libebl: Add three new interfaces to directly access machine, class, and
+data encoding information.
+
+objdump: New program.  Just the beginning.
+
+Version 0.111:
+
+libdw: now contains all of libdwfl.  The latter is not installed anymore.
+
+elfcmp: little usability tweak, name and index of differing section is printed.
+
+Version 0.110:
+
+libelf: fix a number of problems with elf_update
+
+elfcmp: fix a few bugs.  Compare gaps.
+
+Fix a few PLT problems and mudflap build issues.
+
+libebl: Don't expose Ebl structure definition in libebl.h.  It's now private.
+
+Version 0.109:
+
+libebl: Check for matching modules.
+
+elflint: Check that copy relocations only happen for OBJECT or NOTYPE symbols.
+
+elfcmp: New program.
+
+libdwfl: New library.
+
+Version 0.108:
+
+strip: fix bug introduced in last change
+
+libdw: records returned by dwarf_getsrclines are now sorted by address
+
+Version 0.107:
+
+readelf: improve DWARF output format
+
+strip: support Linux kernel modules
+
+Version 0.106:
+
+libdw: Updated dwarf.h from DWARF3 spec
+libdw: add new funtions dwarf_func_entrypc, dwarf_func_file, dwarf_func_line,
+dwarf_func_col, dwarf_getsrc_file
+
+Version 0.105:
+
+addr2line: New program
+
+libdw: add new functions: dwarf_addrdie, dwarf_macro_*, dwarf_getfuncs,
+dwarf_func_*.
+
+findtextrel: use dwarf_addrdie
+
+Version 0.104:
+
+findtextrel: New program.
+
+Version 0.103:
+
+libdw: Fix using libdw.h with gcc < 4 and C++ code.  Compiler bug.
+
+Version 0.102:
+
+More Makefile and spec file cleanups.
+
+Version 0.101:
+
+Remove most gettext autoconf handling.
+
+Add more warnings
+
+Fix resulting problems.  One actual bug found and fixed this way
+
+Version 0.100:
+
+libebl: Fix x86-64 relocations.
+
+Add -Wunused -Wextra warnings.
+
+Some cleanups resulting from those additional warnings.
+
+Lots of Makefile cleanup.
+
+Version 0.99:
+
+libelf: add gelf_checksum prototype to <libelf.h>
+
+libelf: fix elf*_checksum handling of NOBITS sections
+
+Finish mudflap support.
+
+Fix three bugs found by mudflap.
+
+ld: add as_needed support
+
+Version 0.98:
+
+readelf: in section to segment mapping, indicate read-only sections.
+
+elflint: more relaxation for GNU ld
+
+Version 0.97:
+
+Fix compiling with gcc 4.0.
+Some tests called elflint without appropriate LD_LIBRARY_PATH.
+
+Version 0.96:
+
+Fix support for platforms with lib64.
+
+Version 0.95:
+
+libebl: add ppc and ppc64 support
+
+readelf: fix minimal memory leak.
+
+Add support to compile with mudflap.
+
+Modernize configure.ac.  Move scripts in config subdir.
+
+Modernize *-po directory infrastructure.
+
+libelf: Add gelf_getlib and gelf_update_lib
+
+readelf: print liblist sections
+
+Version 0.94:
+
+Fix some minimal build problems.
+
+Version 0.93:
+
+ibdw: tons of new functionality and bug fixes.  Several interface changes.
+
+readelf: use libdw now.
+
+libdwarf: removed completely.
+
+Version 0.92:
+
+configuration changes.
+
+Version 0.91:
+
+libdw: fix memory handling.  Implement source line handling.
+nm: use libdw instead of libdwarf.
+libelf: change to GPL from OSL1 for now.
+
+Version 0.90:
+
+libebl: Recognize a few more section types and dynamic tags and return
+approriate strings.
+
+Version 0.89:
+
+strip: fix overwriting of symbol table in input file.
+
+Version 0.88:
+
+libebl: Add some ia64 bits.
+
+Version 0.87:
+
+Bug fixes for big endian and some 64-bit machines.
+
+Version 0.86:
+
+strip: fix handling of Alpha and s390x which use incorrect hash bucket sizes.
+
+ld: tons of changes, moving towards usability.
+
+Version 0.85:
+
+strip: update section group symbol index if the associated symbol table changed
+
+libelf: fix two problems with generating output not via mmap
+
+elflint: add probably 10-15 more tests
+libebl: add support for some of the new tests
+
+ld: gazillion changes
+
+Version 0.84:
+
+elflint: deal with .rel.dyn section.  Fix a problem with rela platforms.
+Handle PT_GNU_STACK.  Change to write messages to stdout.
+
+readelf: fix a problem with version information in the symbol table output.
+
+strip: update all version symbol table entries
+
+Version 0.83:
+
+size: fix a warning
+
+strip: last changed caused problems when the symbol table is before the
+relocation section.  Fixed.  This fix also improved the asymptotic
+behavior if many symbol table sections are present.
+
+Version 0.82:
+
+Run strip tests with the correct libelf and libebl.
+
+libelf: fix bug in verneed byte order changing code.
+
+Version 0.81:
+
+strip: Remove unused symbol table entries.  This might require updating
+various other sections.
+
+Version 0.80:
+
+Fix some libelf problems with ET_REL files.
+
+Version 0.79:
+
+More warning changes, mainly by jbj.
+
+libdw: yet more new code.  dwarf_child and dwarf_sibling should now actually
+work.
+
+Version 0.78:
+
+libdw: 10+ new functions.  get-pubnames2 works now fully.  Almost all the
+code needed for nm is in place.
+
+Version 0.77:
+
+cleanups to compile cleanly with gcc 3.3 and -Werror.
+
+libdw: some new code.
+
+Version 0.76:
+
+libebl: Fix last patch to recognize relocation sections.   We must not
+use the name.
+
+Version 0.75:
+
+libebl: .debug_ranges is a DWARF 3 debug section
+libebl: recognize relocation sections for debug section
+Patches by Jakub Jelinek.
+
+Version 0.74:
+
+Cleanups and more SPARC support by Tom Callaway <tcallaway@redhat.com>.
+
+Version 0.73:
+
+64-bit cleanups for the programs.
+
+Version 0.72:
+
+libelf: and yet more fun with endian tranformation at output time.
+
+Version 0.71:
+
+libelf: more fun with endian tranformation at output time.  Add test for it.
+
+Version 0.70:
+
+libelf: Two little bugs left from previous patch to handle section output
+order.
+
+libelf: add unlikely in some more places.
+
+Version 0.69:
+
+libelf: fix output routines to handle case where section indeces and
+ordre in the output file don't match correctly.  Patch by Jakub.
+
+elflint: fix test of note section content for 64-bit platforms and files
+with different byte order.
+
+Version 0.68:
+
+libebl: Fix SH_ENTSIZE_HASH definition (patch by Jakub)
+
+Version 0.67:
+
+libelf: correct mistake in error string handling.
+
+libelf: Implement ELF_F_PERMISSIVE.
+strip: Implement --permissive option.
+
+Version 0.66:
+
+strip: Implement -g option.
+
+libelf: Handle broken hash table entry sizes.
+
+libebl: New function ebl_debugscn_p.  Use it where appropriate.
+
+Version 0.65:
+
+libelf: Use correct file size for NOBITS section with ELF_F_LAYOUT set
+
+Version 0.64:
+
+libelf: Make error handling more robust.
+libelf: Use TLS in error handler if configured with --enable-tls
+
+tests: input files are now distributed, not uuencoded in the shell scripts
+
+libdw: implement error handling, dwarf_get_pubnames
+
+Version 0.63:
+
+Build (incomplete) libdw.
+
+Version 0.62:
+
+Get rid of libtool.
+
+Version 0.61:
+
+Fix URL of OSL.
+
+Version 0.60:
+
+libebl: Handle .gnu.warning.* sections correctly.
+
+size: Implement -t option.
+
+libebl: Add IA-64 support.
+libebl: Update SH relocations.
+libebl: Add Alpha support.
+libebl: Add Arm support.
+libebl: Add support for all currently known architecture to the loader.
+
+Version 0.59:
+
+nm: Implement -S option.  Correct portable output format.  Implement -s option.
+
+libelf: Take offset of archive into account in elf_rand.
+
+Version 0.58:
+
+strip: fix handling of ET_REL files.
+Add tests for strip.
+
+Version 0.57:
+
+strip: respect layout of input file
+
+Version 0.56:
+
+strip: handle files with large number of sections.
+
+Version 0.55:
+
+libelf: quite a few bug fixes by Alex Larsson.
+
+strip: implement -f option to place stripped sections into a separate
+file.  By Alex Larsson.
+
+Version 0.54:
+
+strip: don't let STT_SECTION symbols keeps sections from being removed
+
+elflint: local symbols are allowed in .dynsym
+elflint: special case .rel.dyn a bit
+
+Version 0.53:
+
+elflint: check types and flags of special sections defined in gABI
+
+libebl: add x86-64 support
+
+Version 0.52:
+
+Start improvement of debug info handling in nm.
+
+libasm: implement asm_adduleb128 and asm_addsleb128 and a test for them
+
+Version 0.51:
+
+Fix build on 64-bit platforms.
+
+Version 0.50:
+
+nm: print file/line number also for local symbols
+
+use versions scripts not libtool's useless -export-symbols option
+
+Version 0.49:
+
+Update to autoconf 2.54 and automake 1.7.
+
+elflint: check note sections
+
+libdwarf: a number of bug fixes
+
+readelf: print .debug_info section content
+
+dwarf.h: Update from draft 7
+
+Version 0.48:
+
+libcpu: beginning
+
+libelf: new function to read parts of the ELF file
+
+libebl: support for note section handling
+
+readelf: dump note sections
+
+Version 0.47:
+
+libelf: fix little new section-handling related bugs in elf_getshstrndx
+and elf_nextscn
+
+elflint: tests for mandatory content of dynamic section
+
+libasm: better handling of absolute symbols
+
+Version 0.46:
+
+libasm: rewrite to store Elf_Scn* instead of indices
+
+nm: finish many-section support
+
+nm: use debug in to print file/line info in sysv format
+
+libdwarf: fix a few bugs in DIE handling
+
+Version 0.45:
+
+libelf: major rewrite to keep Elf_Scn references valid until elf_end
+
+Version 0.44:
+
+libasm: Add support for bss, ABS, and COM sections.
+
+libebl: ebl_section_name takes now two index arguments to distinguish
+between special sections and extended sections
+
+Version 0.43:
+
+General: fix a few problem gcc 3.1 had with the code.
+
+libelf: implement {gelf,elf32,elf64}_checksum
+
+libelf: optimze DSO: fewer relocations, fewer PLTs
+
+add msg_tst test
+
+ld: use correct section header string table index; write correct index
+
+add dependencies for *.sym files
+
+Version 0.42:
+
+libelf: add elf_getshnum and elf_getshstrndx
+
+libebl: update section type name function
+
+elflint: tons of fixes wrt large number of sections.  New tests in this area.
+Same amount of other bug fixes.
+
+size, strip, nm: better support for large number of sections.  Including
+using correct section header string table
+
+libasm: correctly create data structures for large number of sections
+
+new tests asm-tst4 and asm-tst5 to check large number of sections
+
+libasm: implement section group generation
+
+elflint: more tests on section groups.  Improve performance on existing
+section group tests
+
+Version 0.41:
+
+ld: add undefined symbols to dynamic symbol table if --export-dynamic is
+not given
+
+ld: fix value of e_entry
+
+Version 0.40:
+
+elflint: print section names in error messages
+
+elflint: mustn't warn about multiple DT_NULL
+
+ld: don't emit all symbols if --export-dynamic is not given
+
+ld: correct compute symbol address in output file (section index was off by 1)
+
+ld: generate correct version info in dynsym without --export-dynamic and
+in symtab
+
+Version 0.39:
+
+Fix check of various e_*size entries in elflint.
+
+Handle text output in asm_newsym.
+
+Finish checks in asm-tst3.
+
+Version 0.38:
+
+Update to autoconf 2.53, automake 1.6, gettext 0.11+.
+
+Introduce *.sym files to restrict export from DSOs.
+
+Use attribute_hidden and internal_function to optimize DSO code.
+
+Add TLS definitions in elf.h and handle them in readelf.
+
+Fix bug in verdef section generation in ld.
+
+Add initial libasm code.
+
+Version 0.37:
+
+Implement better hash size optimization heuristic in ld.  It uses a formula
+taking number of tests into account.
+
+Lots of small bug fixes.
+
+Improve readelf output format.  Respect various sh_link/sh_info values.
+Correctly print versioning information for symbol tables.
+
+Version 0.36:
+
+Implement preprocessing of linker script.  Recognize -z combreloc.
+
+Version 0.35:
+
+Implement -z ignore|record for ld.
+
+Implement creating of .gnu.version_r and .gnu.version sections.  The
+.gnu.version does not yet contain correct info for defined and versioned
+symbols (means .gnu.version_d is not yet implemented).
+
+Implement gelf_update_* functions to create versioning data.
+
+Version 0.34:
+
+Add DT_RUNPATH/DT_RPATH entries to dynamic section.  Create .plt and
+.rel.plt sections (completely).  Add support for all four PLT related
+dynamic section entries.  Add callback function for PLT creation.
+
+More tests in elflint.  Add support for very strict checking which for
+now flags level 2 (deprecated features) usage.
+
+Version 0.33:
+
+Create dynamic symbol table, dynamic string table, and hash table to ld.
+
+Add hash table histogram support to readelf.
+
+Version 0.32:
+
+more work on elflint
+
+ld now creates the dynamic section and references it.  Start adding entries
+to dynamic section.
+
+Version 0.31:
+
+Start implementing elflint.
+
+Version 0.30:
+
+Fix handling of NOBITS sections in elf_getdata.
+
+Start implementing generation of executables and DSOs in ld.
+Generation of program header mostly done.  Address computation done.
+Extension of linker script syntax.
+
+Various cleanups.
+
+Implement section group handling in readelf.
+
+Version 0.29:
+
+Implement section groups.  This involved a lot of code moving.  The
+new code is entirely untested since gas/gcc are currently not able to
+create section groups.  ld works fine on files without section groups.
+
+Version 0.28:
+
+Fix problem with adding more section in elf_newscn.  The section pointers
+for the data buffers wasn't adjusted.
+
+Fix elf_getdata with nonzero second parameter.  Correctly handle creation
+of internal data buffer for machines without unaligned access.
+
+Version 0.27:
+
+Start adding support to selectively add sections.  Includes support for
+section groups.
+Add --gc-sections/--no-gc-sections options.
+Add general section merging support.
+
+Fix a bug in section group support in strip.
+
+Fix some potential problems with hash value in dynamic hash implementation.
+
+Version 0.26:
+
+section merging works in ld.
+
+Version 0.25:
+
+Actually create data structures from version map file and use it to hide
+symbols in ld.
+
+Implement -s -s for ld.
+
+Version 0.24:
+
+Improve relocation table output in readelf.  Avoid some crashes.
+Finish many section handling in readelf.
+
+Finish: finish implementation of ld -r.  At least some simple tests pass.
+
+Version 0.23:
+
+Fix a number of errors in ELF_C_WRITE handling.
+
+Almost finished implementation of ld -r.  The data sections are all copied.
+Handling of symbol tables is missing.
+
+Version 0.22:
+
+Handle DSO and archive input files correctly if -r option is given.
+
+Gracefully deal with no phdr in new file in libelf.
+Fix various small error handling problems.
+Don't mmap file for output unless the command says so.
+
+Add code to create ELF section header table to ld finalize routines.
+
+Version 0.21:
+
+Fix some problems with recursive handling of archives in libelf.
+
+Improve messages printed by nm.
+
+Add symbol binding name handling to libebl.  Fix section name handling in
+libebl.
+
+readelf and nm use more libebl functions.
+
+Handle XINDEX correctly in nm and string.
+
+Add first machine ld backend library (i386).
+Use it.  Recognize -r and --shared.  Avoid using -lxxx parameters for -r.
+Create ELF header in output file.  Change mode of output file according to
+output file type.  Reorganize callback initialization in ld.
+
+Version 0.20:
+
+Fix some memory leaks in libelf.
+
+Version 0.19:
+
+Implement reading version script.  Both inside linker scripts and via the
+--version-script command line parameter.  Uses the same code.
+What remains to be done is to implement a data structure which allows
+efficient matching against the version names to decide which pattern
+matches.
+
+Beginning of output generation and output writing functions.
+
+Version 0.18:
+
+Finish implementation for DSO input file handling.  Implement rpath, runpath,
+and LD_LIBRARY_PATH handling.
+
+Version 0.17:
+
+make handling of e_shnum overflow in libelf standard conforming
+
+ld now actually can handle DSOs in linker scripts.  Handling of DT_RUNPATH,
+DT_RPATH, -rpath, -rpath-link still remains to be implemented.
+
+fix handling of -L parameters.  Make actual use of the default_paths element.
+
+make re-definition of symbols in and from DSO compatible with existing linker
+
+Version 0.16:
+
+more work on assigning input sections to output sections.
+
+Add gelf_xlatetof and gelf_xlatetom which were accidently left out.
+
+Fix memory handling of section headers.
+
+Version 0.15:
+
+Add many-section support to ld.  Add various new command line parameters.
+Allow pagesize to be specified in linker script or on the command line.
+Collect input sections in list for the output section according to the rules
+specified in the linker script.
+
+Version 0.14:
+
+Fix some problems in the internal list handling which had the result
+that we didn't look for some of the unresolved symbols.
+
+Free some memory if we know we don't need it anymore.
+
+Optimize the list of unresolved symbols.  Throw out symbols which are
+meanwhile resolved.
+
+Version 0.13:
+
+Got file reading correct now.  The files are all read while parsing
+the parameters.  No creating of data structures to describe the linker
+command line.  The symbol table is built up while reading the files.
+DSOs are handled now.  -( -) handling is optimized.
+
+Version 0.12:
+
+Linker read linker scripts everywhere.  Handles --whole-archive.  Recognizes
+--dynamic and --static.  Collects defined and undefined symbols.  Recognizes
+conflicts.
+
+libebl now defines functions to call the callbacks.  Add generic name handling
+in these new functions.  Remove the code from readelf and call the new
+functions.
+
+Version 0.11:
+
+Start of linker.  Basic argument parsing, finding of input files,
+linker script reading.
+
+Version 0.10:
+
+Implement dwarf_get_fde_n(), dwarf_get_abbrev(), dwarf_get_abbrev_tag(),
+dwarf_get_abbrev_code(), dwarf_get_abbrev_children_flag(),
+dwarf_get_abbrev_entry(), dwarf_get_fde_at_pc(), and tests for it.
+
+Version 0.9:
+
+Implement dwarf_get_fde_list_eh(), dwarf_get_cie_of_fde(),
+dwarf_get_fde_range(), dwarf_get_cie_info(), dwarf_get_fde_instr_bytes(),
+and tests for them.
+
+Version 0.8:
+
+Make handling of binaries in other byte order work and add tests for it.
+
+Version 0.7:
+
+Implement dwarf_get_aranges(), dwarf_get_arange(), dwarf_get_cu_die_offset(),
+dwarf_get_arange_info(), and tests for them.
+
+Version 0.6:
+
+Implement dwarf_get_global(), dwarf_globname(), dwarf_global_die_offset(),
+dwarf_global_cu_offset(), dwarf_global_name_offsets(), and tests for them
+
+Version 0.5:
+
+Implemented dwarf_srclines(), dwarf_srcfiles(), dwarf_linebeginstatement(),
+dwarf_lineendsequence(), dwarf_lineno(), dwarf_lineaddr(), dwarf_lineoff(),
+dwarf_linesrc(), dwarf_lineblock(), dwarf_lineprologueend(),
+dwarf_lineepiloguebegin(), and tests for them.
+
+Version 0.4:
+
+Implemented dwarf_loclist().
+
+Version 0.3:
+
+Implemented dwarf_dieoffset(), dwarf_die_CU_offset(), dwarf_diename() and
+tests.
+
+Implemented dwarf_attrlist(), dwarf_hasattr(), dwarf_attr(), dwarf_lowpc(),
+dwarf_highpc(), dwarf_bytesize(), dwarf_bitsize(), dwarf_bitoffset(),
+dwarf_srclang(), dwarf_arrayorder(), dwarf_hasform(), dwarf_whatform(),
+dwarf_whatattr(), dwarf_formref(), dwarf_global_formref(), dwarf_formaddr(),
+dwarf_formflag(), dwarf_formudata(), dwarf_formsdata(), dwarf_formblock,
+dwarf_formstring() and tests for them.
+
+Version 0.2:
+
+Implemented dwarf_offdie()), dwarf_tag(), dwarf_dieoffset(),
+dwarf_die_CU_offset(), dwarf_diename() and tests for them.
+
+Version 0.1:
+
+First libdwarf functions work.
+
+Version 0.0:
+
+libelf and parts of libebl are done.
diff --git a/third_party/elfutils/NOTES b/third_party/elfutils/NOTES
new file mode 100644
index 0000000..2a5c23b
--- /dev/null
+++ b/third_party/elfutils/NOTES
@@ -0,0 +1,95 @@
+Fundamental design decision:
+
+- the sizes of external and internal types are assumed to be the same.
+  This leaves byte ordering aside.  While assuming this the code can be
+  greatly simplified and speed increases.  Since no change violating this
+  assumption is in sight this is believed to be a worthwhile optimization.
+
+- the ABI of the backend modules is not guaranteed.  Really, no guarantee
+  whatsoever.  We are enforcing this in the code.  The modules and their
+  users must match.  No third-party EBL module are supported or allowed.
+  The only reason there are separate modules is to not have the code for
+  all architectures in all the binaries.
+
+- although the public libraries (libasm, libdw) have a stable API and are
+  backwards ABI compatible they, and the elfutils tools, do depend on each
+  others internals, and on internals of libelf to provide their interfaces.
+  So they should always be upgraded in lockstep when packaging the tools
+  and libraries separately. For one example of how to do that, see the
+  config/elfutils.spec.
+
+Some notes:
+
+- old GNU ld's behavior wrt DSOs seems to be severely broken.
+
+     y.o reference foo()
+     y1.o defines foo(), references bar()
+     y2.o defines bar()
+     libbar.so defines bar()
+
+  Running
+
+     gcc -o y y.o -lbar y1.o y2.o
+
+  uses the bar() definition from libbar.so and does not mention the definition
+  in y2.o at all (no duplicate symbol message).  Correct is to use the
+  definition in y2.o.
+
+
+     y.o reference foo()
+     y1.o defines foo(), references bar()
+     y2.o in liby2.a defines bar()
+     libbar.so defines bar()
+
+  Running
+
+     gcc -o y y.o -lbar y1.o -ly3
+
+  has to use the definition in -lbar and not pull the definition from liby3.a.
+
+
+- the old linker follows DT_NEEDED entries and adds the objects referenced
+  this way which define a symbol which is needed as a DT_NEEDED to the
+  generated binary.  This is wrong since the DT_NEEDED changes the search
+  path in the object (which is breadth first).
+
+
+- the old linker supported extern "C++", extern "java" in version scripts.
+  I believe this implementation is severly broken and needs a redesign
+  (how do wildcards work with these languages*?).  Therefore it is left
+  out for now.
+
+
+- what should happen if two sections in different files with the same
+  name have different types and/or the flags are different
+
+
+- section names in input files are mostly irrelevant.  Exceptions:
+
+  .comment/SHT_PROGBITS		in strip, ld
+
+  .debug		\
+  .line			|
+  .debug_srcinfo	|
+  .debug_sfnames	|
+  .debug_aranges	|
+  .debug_pubnames	|
+  .debug_info		|
+  .debug_abbrev		|
+  .debug_line		|
+  .debug_abbrev		 >	DWARF sections in ld
+  .debug_line		|
+  .debug_frame		|
+  .debug_str		|
+  .debug_loc		|
+  .debug_macinfo	|
+  .debug_weaknames	|
+  .debug_funcnames	|
+  .debug_typenames	|
+  .debug_varnames	/
+
+  Sections created in output files follow the naming of special section
+  from the gABI.
+
+  In no place is a section solely indentified by its name.  Internal
+  references always use the section index.
diff --git a/third_party/elfutils/README b/third_party/elfutils/README
new file mode 100644
index 0000000..0e15bae
--- /dev/null
+++ b/third_party/elfutils/README
@@ -0,0 +1,31 @@
+The elfutils project provides libraries and tools for ELF files and DWARF data.
+
+The project home is http://elfutils.org/
+
+Releases are published at ftp://sourceware.org/pub/elfutils/
+Which can also be found at https://sourceware.org/elfutils/ftp/
+
+To build a release do: ./configure && make && make check
+Please check the configure summary to make sure all recommended
+features are enabled. There should be no failures after make check.
+
+Please reports bugs at https://sourceware.org/bugzilla/
+
+The current elfutils source code can be checked out with
+git clone git://sourceware.org/git/elfutils.git
+
+To build a git checkout do:
+  autoreconf -i -f && \
+  ./configure --enable-maintainer-mode && \
+  make && make check
+
+The developer mailinglist to send patches to is
+elfutils-devel@sourceware.org.
+https://sourceware.org/ml/elfutils-devel/
+
+To subscribe send an email to elfutils-devel-subscribe@sourceware.org
+Or use the form at https://sourceware.org/lists.html#ml-requestor
+
+See the CONTRIBUTING file for how to propose patches to the code.
+
+See the NOTES files for some design decisions and notes.
diff --git a/third_party/elfutils/THANKS b/third_party/elfutils/THANKS
new file mode 100644
index 0000000..887c067
--- /dev/null
+++ b/third_party/elfutils/THANKS
@@ -0,0 +1,6 @@
+At least the following have submitted valuable patches:
+
+Jeff Johnson		building. rpm wrestling
+Alexander Larsson	separate debug info
+Jakub Jelinek		bug fixes, testing
+Denys Vlasenko		bug fuxes
diff --git a/third_party/elfutils/TODO b/third_party/elfutils/TODO
new file mode 100644
index 0000000..ad10a5e
--- /dev/null
+++ b/third_party/elfutils/TODO
@@ -0,0 +1,195 @@
+		      ToDo list for elfutils                      -*-outline-*-
+                      ----------------------
+
+Time-stamp: <2009-02-05 22:08:01 drepper>
+
+* mkinstalldirs
+
+  Remove everywhere.  Use mkdir -p.
+
+* libelf:
+
+** verify section
+
+   Currently the elf_update function trusts the user blindly if the
+   ELF_F_LAYOUT flag is set.  This is OK if the data is prepared by a
+   ELF_C_NULL call but not if the user prepared the data herself
+
+** break out archive handling from elf_begin
+
+   The handling of archives (especially of the symbol tables) must be
+   broken out of elf_begin.  There are several different forms of
+   archives and only when having the archive handling separately this
+   remains maintainable.
+
+** shdrs in read-only files
+
+   When reading (ELF_C_READ*) then there is no need to malloc Shdr
+   structure in elfXX_getshdr if file is mmaped and unaligned access
+   is allowed or the structure is aligned.  Use ELF_F_MALLOCED flag
+   to differentiate.
+
+** shdrs after elf_cntl (ELF_C_FDREAD)
+
+   Similar to the above. After ELF_C_FDREAD the file is completely
+   in memory.  See also this mailing list thread:
+   https://fedorahosted.org/pipermail/elfutils-devel/2012-July/002368.html
+
+* libdw
+
+** More memory access checks needed
+
+   All accesses to the debug sections should make sure the offsets are
+   valid.  This is currently especially a problem with leb128 accesses.
+
+** Low level macro information operations
+
+   in 5.11.3 are not implemented.  gcc currently does not emit this
+   information so I cannot test it.
+
+** Rename dwarf_getabbrev
+
+
+* libcpu
+
+** x86
+
+*** Opcodes
+
+     crc32
+     extractps
+     pextrb
+     pextrd/pextrq
+     pextrw
+     pinsrq
+     popcnt 64-bit reg
+
+* nm:
+
+** add demangler support
+
+   Use demangler from libiberty.
+
+** add support to read debugging symbols
+
+   Implement -l option for BSD and POSIX format
+
+
+* strip:
+
+** support SHT_SYMTAB_SHNDX
+
+   should be removed if not needed anymore
+
+* ld:
+
+** sanity check .rel sh_info content
+
+   the sh_info of all .rel sections with the same name must point to
+   sections which also have the same name
+
+** use ld.so.conf
+
+   to locate shared libraries also use /etc/ld.so.conf
+
+** handle object files for different architectures
+
+   ld.so is expected to ignore object files for different architectures and
+   continue looking for a matching file (e.g., ignore 32-bit binaries on
+   64-bit platforms and vice versa).  We probably need the same in ld.
+
+** reuse after elf_end
+
+   Some files are closed using elf_end.  They are removed from memory only
+   if no reference is left (especially for archives this is a problem).
+   The old mapping should be reused in that case.  The problem is worse
+   for files which are not mapped read-only (archives again).
+
+** size for STT_SECTION entries
+
+   The STT_SECTION entries have zero for the size but can easily get
+   the size of the section.
+
+** .eh_frame_hdr
+
+   Not implemented at all in the moment except for recognition of the option
+   itself.
+
+** variables with aliases in executables
+
+   When linking an executable with a references against a variable in a
+   DSO, create symbol table entries for all the aliases of the variable
+   in the DSO and create a relocation for one of them (a non-weak
+   definition)
+
+* elflint
+
+** additional checks
+
+   1st GOT entry == _DYNAMIC
+
+   check versioning info:
+
+     always BASE in verdef
+     sh_size/sh_entsize matches last offset != 0
+
+   check whether any relocation is for a merge-able section
+
+   check TLS relocation depencies
+
+   Check content of .eh_frame_hdr, .eh_frame, .gcc_except_table
+
+*** for x86
+
+    check that R_386_TLS_GD is followed by R_386_PLT32 for __tls_get_addr
+
+** relax
+
+   prelink generated files
+
+* elfcmp
+
+** treat relocation sections special
+
+   Differences in the relocation sections can be ignored if all
+   the same symbols with the same targets are present and the order
+   of overlapping relocations doesn't change.  There really never
+   should be overlapping relocations but who knows.
+
+* mcs
+
+  Sun has it.  Can modify sections which are not in segments.
+
+     -a string
+           Append string to the comment section of the ELF object
+           files. If  string contains embedded blanks, it must be
+           enclosed in quotation marks.
+
+     -c    Compress the contents of the comment  section  of  the
+           ELF  object  files. All duplicate entries are removed.
+           The ordering of the  remaining  entries  is  not  dis-
+           turbed.
+
+     -d    Delete the contents of the comment  section  from  the
+           ELF  object  files. The section header for the comment
+           section is also removed.
+
+     -n name
+           Specify the name of the comment section to  access  if
+           other  than  .comment.  By default, mcs deals with the
+           section named .comment. This option  can  be  used  to
+           specify  another  section.  mcs  can  take multiple -n
+           options to allow for specification of   multiple  sec-
+           tion comments.
+
+     -p    Print the contents of the comment section on the stan-
+           dard  output.  Each  section  printed is tagged by the
+           name of the file from which it  was  extracted,  using
+           the  format  file[member_name]:  for archive files and
+           file:  for other files.
+
+     -V    Print on standard error the version number of mcs.
+
+Local Variables:
+eval:(hide-sublevels 3)
+End:
diff --git a/third_party/elfutils/backends/ChangeLog b/third_party/elfutils/backends/ChangeLog
new file mode 100644
index 0000000..098bed7
--- /dev/null
+++ b/third_party/elfutils/backends/ChangeLog
@@ -0,0 +1,1116 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* aarch64_retval.c (aarch64_return_value_location): Use FALLTHROUGH
+	macro instead of comment.
+	* alpha_retval.c (alpha_return_value_location): Likewise.
+	* arm_regs.c (arm_register_info): Likewise.
+	* arm_retval.c (arm_return_value_location): Likewise.
+	* i386_regs.c (i386_register_info): Likewise.
+	* i386_retval.c (i386_return_value_location): Likewise.
+	* ia64_retval.c (ia64_return_value_location): Likewise.
+	* linux-core-note.c (core_note): Likewise.
+	* m68k_retval.c (m68k_return_value_location): Likewise.
+	* ppc64_retval.c (ppc64_return_value_location): Likewise.
+	* ppc_regs.c (ppc_register_info): Likewise.
+	* ppc_retval.c (ppc_return_value_location): Likewise.
+	* s390_retval.c (s390_return_value_location): Likewise.
+	* sh_retval.c (sh_return_value_location): Likewise.
+	* sparc_retval.c (sparc_return_value_location): Likewise.
+	* tilegx_retval.c (tilegx_return_value_location): Likewise.
+	* x86_64_regs.c (x86_64_register_info): Likewise.
+	* x86_64_retval.c (x86_64_return_value_location): Likewise.
+
+2017-10-24  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am (m68k_corenote_no_Wpacked_not_aligned): New variable.
+
+2017-08-18  Ulf Hermann <ulf.hermann@qt.io>
+
+	* linux-core-note.c: Use attribute_packed.
+
+2017-04-27  Ulf Hermann <ulf.hermann@qt.io>
+
+	* Makefile.am: Use dso_LDFLAGS.
+
+2017-07-27  Mark Wielaard  <mark@klomp.org>
+
+	* sparc_reloc.def: GOTDATA_OP_HIX22, GOTDATA_OP_LOX10 and
+	GOTDATA_OP can be used in ET_REL files.
+
+2017-07-19  Gustavo Romero <gromero@linux.vnet.ibm.com>
+
+	* ppc_corenote.c: Add offsets for ppc64 HTM SPRs: thfar, tfiar,
+	and texasr.
+	* ppc_regs.c: Add names for ppc64 HTM SPRs mappings.
+
+2017-07-20  Mark Wielaard  <mark@klomp.org>
+
+	* aarch64_init.c (aarch64_init): Hook data_marker_symbol.
+	* aarch64_symbol.c (aarch64_data_marker_symbol): New function.
+	* arm_init.c (arm_init): Hook data_marker_symbol.
+	* arm_symbol.c (aarch64_data_marker_symbol): New function.
+
+2017-07-18  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am (cpu_bpf): Always define.
+	* bpf_init.c (disasm): Always hook.
+	* bpf_regs.c: Include bpf.h instead of linux/bpf.h. Don't define
+	MAX_BPF_REG.
+
+2017-02-17  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Add libeu.
+	(libebl_%so): Link with --no-undefined,-z,defs,-z,relro
+	and libeu.a.
+
+2017-06-17  Mark Wielaard  <mark@klomp.org>
+
+	* s390_initreg.c: Swap sys/ptrace.h and asm/ptrace.h include order.
+
+2017-06-15  Andreas Schwab  <schwab@linux-m68k.org>
+
+	* ppc_symbol.c (ppc_machine_flag_check): New function.
+	* ppc_init.c (ppc_init): Hook it.
+
+2017-05-30  Mark Wielaard  <mark@klomp.org>
+
+	* ppc64_unwind.c: New file.
+	* ppc64_init.c (pcc64_init): Hook unwind.
+	* Makefile.am (ppc64_SRCS): Add ppc64_unwind.c
+
+2017-04-06  Mark Wielaard  <mark@klomp.org>
+
+	* i386_unwind.c: New file.
+	* i386_init.c: Hook i386_unwind.
+	* Makefile.am (i386_SRCS): Add i386_unwind.c
+
+2017-02-09  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* aarch64_unwind.c: New file
+	* Makefile.am (aarch64_SRCS): Add aarch64_unwind.c
+	* aarch64_init.c (aarch64_init): Hook aarch64_unwind
+
+2017-02-09  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* x86_64_unwind.c: New file
+	* Makefile.am (x86_64_SRCS): Add x86_64_unwind.c
+	* x86_64_init.c (x86_64_init): Hook x86_64_unwind
+
+2017-04-20  Ulf Hermann <ulf.hermann@qt.io>
+
+	* aarch64_initreg.c: Compile register initialization only on linux.
+	* arm_initreg.c: Likewise.
+	* ppc_initreg.c: Likewise.
+	* s390_initreg.c: Likewise.
+	* x86_64_initreg.c: Likewise.
+
+2017-02-15  Mark Wielaard  <mark@klomp.org>
+
+	* ppc64_init.c (ppc64_init): Add check_object_attribute HOOK.
+	* ppc_attrs.c (ppc_check_object_attribute): Add Single-precision hard
+	float.
+
+2016-11-02  Mark Wielaard  <mjw@redhat.com>
+
+	* i386_regs.c (i386_register_info): Add fallthrough comment.
+	* i386_retval.c (i386_return_value_location): Move fallthrough
+	comment.
+	* linux-core-note.c (core_note): Adjust fallthrough comment.
+	* m68k_retval.c (m68k_return_value_location): Move fallthrough
+	comment.
+	* ppc_regs.c (ppc_register_info): Add fallthrough comment.
+	* x86_64_regs.c (x86_64_register_info): Likewise.
+
+2016-08-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* sparc_attrs.c (sparc_check_object_attribute): Fix the
+	calculation of GNU_SParc_HWCAPS and GNU_SParc_HWCAPS2 values as
+	comma-separated list of hw capability names.
+
+2016-07-10  Andreas Schwab  <schwab@linux-m68k.org>
+
+	* m68k_corenote.c (ALIGN_PRSTATUS): Define.
+	* linux-core-note.c (struct EBLHOOK(prstatus)): Set alignment to
+	ALIGN_PRSTATUS if defined.
+
+2016-06-28  Richard Henderson <rth@redhat.com>
+
+	* Makefile.am (modules): Add bpf.
+	(libebl_pic): Add libebl_bpf_pic.a.
+	(am_libebl_bpf_pic_a_OBJECTS): New.
+	* bpf_init.c, bpf_regs.c, bpf_reloc.def: New files.
+	* common-reloc.c (copy_reloc_p): Honor NO_COPY_RELOC.
+	(init_reloc): Likewise.
+
+2016-05-20  Andreas Schwab  <schwab@linux-m68k.org>
+
+	* Makefile.am (modules): Add m68k.
+	(libebl_pic): Add libebl_m68k_pic.a.
+	(m68k_SRCS, libebl_m68k_pic_a_SOURCES)
+	(am_libebl_m68k_pic_a_OBJECTS): Define.
+	* m68k_init.c: New file.
+	* m68k_symbol.c: New file.
+	* m68k_regs.c: New file.
+	* m68k_retval.c: New file.
+	* m68k_corenote.c: New file.
+	* m68k_reloc.def: New file.
+	* linux-core-note.c (ALIGN_INT): Only define if not defined.
+
+2016-02-26  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* sparc_initreg.c (EBLHOOK): Provide a dummy
+	sparc_set_initial_registers_tid for sparc32.  This fixes the build
+	in sparcv9-*-* targets.
+
+2016-02-26  Andreas Schwab  <schwab@suse.de>
+
+	* ppc_symbol.c (ppc_dynamic_tag_name): Add DT_PPC_OPT.
+	(ppc_dynamic_tag_check): Likewise.
+
+2015-12-28  Mark Wielaard  <mjw@redhat.com>
+
+	* i386_reloc.def: Add GOT32X.
+	* x86_64_reloc.def: Add GOTPCRELX and REX_GOTPCRELX.
+
+2016-02-12  Mark Wielaard  <mjw@redhat.com>
+
+	* aarch64_corenote.c (aarch64_syscall_items): New Ebl_Core_Item[].
+	(EXTRA_NOTES): Add NT_ARM_SYSTEM_CALL.
+	* eblcorenotetypename.c (ebl_core_note_type_name):
+	Add ARM_SYSTEM_CALL.
+
+2015-12-08  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* sparc_init.c (sparc_init): Hook sparc_set_initial_registers_tid.
+	* sparc_initreg.c: New file.
+	* Makefile.am (sparc_SRCS): Added sparc_initreg.c.
+
+2015-12-08  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* sparc_corenote.c: Header comment typo fixed.
+	(PRSTATUS_REGSET_ITEMS): Defined, so the PC can be fetched from
+	core files.
+	* Makefile.am (sparc_SRCS): Added sparc_cfi.c
+	* sparc_cfi.c: New file.
+	* sparc_init.c (sparc_init): Set eh->frame_nregs, eh->ra_offset
+	and hook sparc_abi_cfi.
+
+2015-10-21  Chih-Hung Hsieh  <chh@google.com>
+
+	* ia64_retval.c (hfa_type): Move nested function 'hfa' to file scope.
+	* aarch64_regs.c (aarch64_register_info): Move nested function 'regtype'
+	to file scope.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* ppc_symbol.c (ppc_check_special_symbol): Also allow _SDA_BASE_
+	in .data section.
+
+2015-10-05  Josh Stone  <jistone@redhat.com>
+
+	* Makefile.am (libebl_%.so): Add AM_V_at and AM_V_CCLD silencers.
+
+2015-10-06  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* sparc_attrs.c: New file.
+	* Makefile.am (sparc_SRCS): Added sparc_attrs.c
+	* sparc_init.c (sparc_init): Hook sparc_check_object_attribute.
+
+2015-10-02  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* sparc_init.c (RELOC_TYPE_ID): Defined.
+	* common-reloc.c (reloc_type_name): Apply target-specific
+	relocation ID extractors if defined.
+	(reloc_type_check): Likewise.
+	(reloc_valid_use): Likewise.
+
+2015-10-02  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* sparc_reloc.def: Added relocation types WDISP10, JMP_IREL and
+	IRELATIVE.
+
+2015-09-22  Mark Wielaard  <mjw@redhat.com>
+
+	* arm_attrs.c: Remove old-style function definitions.
+	* linux-core-note.c: Likewise.
+	* ppc_attrs.c: Likewise.
+
+2015-09-04  Chih-Hung Hsieh  <chh@google.com>
+
+	* aarch64_init.c (aarch64_init): Replace K&R function definition
+	with ansi-C definitions.
+	* alpha_init.c (alpha_init): Likewise.
+	* arm_init.c (arm_init): Likewise.
+	* i386_init.c (i386_init): Likewise.
+	* ia64_init.c (ia64_init): Likewise.
+	* ppc64_init.c (ppc64_init): Likewise.
+	* ppc_init.c (ppc_init): Likewise.
+	* s390_init.c (s390_init): Likewise.
+	* sh_init.c (sh_init): Likewise.
+	* sparc_init.c (sparc_init): Likewise.
+	* tilegx_init.c (tilegx_init): Likewise.
+	* x86_64_init.c (x86_64_init): Likewise.
+
+2015-09-03  Mark Wielaard  <mjw@redhat.com>
+
+	* sparc_regs.c (sparc_register_info): Use ebl->class not ebl->machine.
+
+2015-06-26  Pino Toscano  <toscano.pino@tiscali.it>
+
+	* i386_initreg.c: Reduce scope of some includes to match their usage.
+
+2015-04-28  Mark Wielaard  <mjw@redhat.com>
+
+	* aarch64_reloc.def: Drop "64" from TLS_DTPMOD64, TLS_DTPREL64 and
+	TLS_TPREL64.
+
+2015-04-01  H.J. Lu  <hjl.tools@gmail.com>
+
+	* Makefile.am (x86_64_SRCS): Add x32_corenote.c.
+	* linux-core-note.c (PR_REG): New.
+	(PRPSINFO_UID_T): Likewise.
+	(ALIGN_PRPSINFO_UID_T): Likewise.
+	(TYPE_PRPSINFO_UID_T): Likewise.
+	(PRPSINFO_GID_T): Likewise.
+	(ALIGN_PRPSINFO_GID_T): Likewise.
+	(TYPE_PRPSINFO_GID_T): Likewise.
+	(pr_reg): Replace ULONG with PR_REG.
+	(pr_uid): Replace UID_T with PRPSINFO_UID_T.
+	(uid): Likewise.
+	(pr_gid): Replace GID_T with PRPSINFO_GID_T.
+	(gid): Likewise.
+	* x32_corenote.c: New file.
+	* x86_64_corenote.c (BITS): New.  Support x32.
+	(BACKEND): Support x32.
+	(ULONG): Likewise.
+	(ALIGN_ULONG): Likewise.
+	(TYPE_ULONG): Likewise.
+	(PRPSINFO_UID_T): New.
+	(ALIGN_PRPSINFO_UID_T): Likewise.
+	(TYPE_PRPSINFO_UID_T): Likewise.
+	(PRPSINFO_GID_T): Likewise.
+	(ALIGN_PRPSINFO_GID_T): Likewise.
+	(TYPE_PRPSINFO_GID_T): Likewise.
+	(PR_REG): Likewise.
+	(ALIGN_PR_REG): Likewise.
+	* x86_64_init.c (x32_core_note): New.
+	(x86_64_init): Set eh->core_note to x32_core_note for x32.
+
+2015-03-23  Mark Wielaard  <mjw@redhat.com>
+
+	* aarch64_symbol.c (aarch64_check_special_symbol): Accept
+	_GLOBAL_OFFSET_TABLE_ pointing anywhere in .got.
+
+2015-03-09  Mark Wielaard  <mjw@redhat.com>
+
+	* aarch64_reloc.def (COPY): Add DYN.
+	* arm_reloc.def (COPY): Likewise.
+	* i386_reloc.def (COPY): Likewise.
+	* ia64_reloc.def (COPY): Likewise.
+	* ppc64_reloc.def (COPY): Likewise.
+	* ppc_reloc.def (COPY): Likewise.
+	* s390_reloc.def (COPY): Likewise.
+	* sh_reloc.def (COPY): Likewise.
+	* sparc_reloc.def (COPY): Likewise.
+	* tilegx_reloc.def (COPY): Likewise.
+	* x86_64_reloc.def (COPY): Likewise.
+
+2015-02-23  Petr Machata  <pmachata@redhat.com>
+
+	* arm_symbol.c (arm_symbol_type_name): New function.
+	* arm_init.c (arm_init): Initialize the hook.
+
+2014-12-30  Mark Wielaard  <mjw@redhat.com>
+
+	* ppc_symbol.c (find_dyn_got): Check sh_entsize is not zero.
+
+2014-12-18  Ulrich Drepper  <drepper@gmail.com>
+
+	* Makefile.am: Suppress output of textrel_check command.
+
+2014-11-22  Mark Wielaard  <mjw@redhat.com>
+
+	* ppc64_symbol.c (ppc64_bss_plt_p): Remove ehdr argument.
+	* ppc_symbol.c (find_dyn_got): Likewise. Use elf_getphdrnum.
+	(ppc_check_special_symbol): Call find_dyn_got without ehdr.
+	(ppc_bss_plt_p): Remove ehdr argument.
+
+2014-11-17  Mark Wielaard  <mjw@redhat.com>
+
+	* ppc64_init.c (ppc64_init): Check section name is not NULL.
+
+2014-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* libebl_CPU.h (dwarf_peel_type): Removed.
+	(dwarf_peeled_die_type): Use libdw dwarf_peel_type.
+
+2014-07-18  Kyle McMartin  <kyle@redhat.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* aarch64_initreg.c: Check HAVE_SYS_USER_REGS.
+	(aarch64_set_initial_registers_tid): Use user_regs_struct and
+	user_fpsimd_struct.
+	* arm_initreg.c: Check HAVE_SYS_USER_REGS.
+	(arm_set_initial_registers_tid): Use user_regs_struct in compat mode.
+
+2014-07-04  Menanteau Guy  <menantea@linux.vnet.ibm.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* ppc64_init.c (ppc64_init): Hook check_st_other_bits.
+	* ppc64_reloc.def: TLSGD, TLSLD, TOCSAVE, ADDR16_HIGH, ADDR16_HIGHA,
+	TPREL16_HIGH, TPREL16_HIGHA, DTPREL16_HIGH, DTPREL16_HIGHA, JMP_IREL,
+	IRELATIVE, REL16, REL16_LO, REL16_HI and REL16_HA.
+	* ppc64_symbol.c (ppc64_dynamic_tag_name): Recognize DT_PPC64_OPT.
+	(ppc64_dynamic_tag_check): Likewise.
+	(ppc64_check_st_other_bits): New function.
+
+2014-07-04  Mark Wielaard  <mjw@redhat.com>
+
+	* aarch64_retval.c (aarch64_return_value_location): Handle
+	DW_ATE_boolean.
+
+2014-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* libebl_CPU.h (dwarf_peel_type): Remove DW_TAG_mutable_type
+	handling.
+
+2014-06-17  Mark Wielaard  <mjw@redhat.com>
+
+	* arm_init.c (arm_init): Set func_addr_mask.
+
+2014-06-20  Petr Machata  <pmachata@redhat.com>
+
+	* alpha_retval.c (alpha_return_value_location): Call
+	dwarf_peeled_die_type instead of inlining equivalent code.
+	* arm_retval.c (arm_return_value_location): Likewise.
+	* i386_retval.c (i386_return_value_location): Likewise.
+	* ia64_retval.c (ia64_return_value_location): Likewise.
+	* ppc64_retval.c (ppc64_return_value_location): Likewise.
+	* ppc_retval.c (ppc_return_value_location): Likewise.
+	* s390_retval.c (s390_return_value_location): Likewise.
+	* sh_retval.c (sh_return_value_location): Likewise.
+	* sparc_retval.c (sparc_return_value_location): Likewise.
+	* tilegx_retval.c (tilegx_return_value_location): Likewise.
+	* x86_64_retval.c (x86_64_return_value_location): Likewise.
+
+2014-05-19  Mark Wielaard  <mjw@redhat.com>
+
+	* arm_init.c (arm_init): Hook check_reloc_target_type.
+	* arm_symbol.c (arm_check_reloc_target_type): New function.
+	* ia64_init.c (ia64_init): Hook check_reloc_target_type.
+	* ia64_symbol.c (ia64_check_reloc_target_type): New function.
+
+2014-04-22  Kurt Roeckx  <kurt@roeckx.be>
+
+	* i386_initreg.c: Make Linux only.
+	* x86_64_initreg.c: Make Linux only.
+
+2014-04-13  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Remove libelf and libdw definitions when MUDFLAP
+	is defined. Remove libmudflap from LINK line.
+
+2014-04-09  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (aarch64_SRCS): Add aarch64_initreg.c.
+	* aarch64_corenote.c (prstatus_regs): Mark pc_register.
+	* aarch64_init.c: Assign frame_nregs. Hook set_initial_registers_tid.
+	* aarch64_initreg: New file.
+
+2014-03-28  Jean Pihet  <jean.pihet@linaro.org>
+
+	* arm_initreg.c (arm_set_initial_registers_tid): Handle compat mode.
+	ARM compatible code running on AARCH64.
+
+2014-03-19  Mark Wielaard  <mjw@redhat.com>
+
+	* aarch64_reloc.def: AARCH64_ABS32 and AARCH64_ABS64 are also valid
+	in ET_REL.
+
+2014-01-30  Petr Machata  <pmachata@redhat.com>
+
+	* aarch64_regs.c (aarch64_register_info.regtype): Make this
+	variadic printf-like function.  Call one vsnprintf instead of two
+	snprintf's.
+	(regtyper, regtypen): Drop.
+	(aarch64_register_info): Adjust callers.
+
+2014-01-26  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (arm_SRCS): Add arm_initreg.c.
+	* arm_init.c (arm_init): Define frame_nregs and hook
+	set_initial_registers_tid.
+	* arm_initreg.c: New file.
+
+2014-01-25  Mark Wielaard  <mjw@redhat.com>
+
+	* arm_cfi.c (arm_abi_cfi): Restore SP (r13) from CFA.
+
+2014-01-24  Mark Wielaard  <mjw@redhat.com>
+
+	* arm_reloc.def: Update list.
+
+2014-01-22  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (aarch64_regs_no_Wformat): Removed.
+	* aarch64_regs.c (regtype): Add bool nr argument. snprintf arg
+	when nr is true.
+	(regtyper): New function.
+	(regtypen): Likewise.
+	(aarch64_register_info): Call either regtyper or regtypen not
+	regtype directly.
+
+2014-01-14  Mark Wielaard  <mjw@redhat.com>
+
+	* aarch64_symbol.c (aarch64_check_special_symbol): Check shdr is
+	not NULL before usage.
+
+2014-01-04  Mark Wielaard  <mjw@redhat.com>
+
+	* ppc64_symbol.c (ppc64_machine_flag_check): New function.
+	* ppc64_init.c (ppc64_init): Hook machine_flag_check.
+
+2014-01-03  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (aarch64_SRCS): Add aarch64_cfi.c.
+	* aarch64_cfi.c: New file.
+	* aarch64_init.c (aarch64_init): Hook abi_cfi.
+	* aarch64_regs.c (aarch64_register_info): Set *prefix to "".
+
+2013-12-19  Mark Wielaard  <mjw@redhat.com>
+
+	* aarch64_init.c (aarch64_init): Hook check_special_symbol.
+	* aarch64_symbol.c (aarch64_check_special_symbol): New function.
+
+2013-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (ppc64_SRCS): Add ppc64_resolve_sym.c.
+	* ppc64_resolve_sym.c: New file.
+	* ppc64_init.c: Hook resolve_sym_value and find function descriptor
+	table.
+
+2013-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* s390_initreg.c (s390_set_initial_registers_tid): Use union
+	to avoid type-punning when assigning a double to a Dwarf_Word.
+
+2013-12-18  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	unwinder: s390 and s390x
+	* Makefile.am (s390_SRCS): Add s390_initreg.c and s390_unwind.c.
+	* s390_corenote.c (prstatus_regs): Set PC_REGISTER.  Reindent all the
+	entries.
+	* s390_init.c (s390_init): Initialize frame_nregs,
+	set_initial_registers_tid, normalize_pc and unwind.
+	* s390_initreg.c: New file.
+	* s390_unwind.c: New file.
+
+2013-12-15  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	unwinder: ppc and ppc64
+	* Makefile.am (ppc_SRCS, ppc64_SRCS): Add ppc_initreg.c.
+	* ppc64_init.c (ppc64_init): Initialize also frame_nregs,
+	set_initial_registers_tid and dwarf_to_regno.
+	* ppc_corenote.c (PRSTATUS_REGSET_ITEMS) <nip>: Set PC_REGISTER.
+	* ppc_init.c (ppc64_init): Initialize also frame_nregs,
+	set_initial_registers_tid and dwarf_to_regno.
+	* ppc_initreg.c: New file.
+
+2013-11-25  Petr Machata  <pmachata@redhat.com>
+
+	* Makefile.am (modules): Add aarch64.
+	(libebl_pic): Add libebl_aarch64_pic.a.
+	(aarch64_SRCS): New variable.
+	(libebl_aarch64_pic_a_SOURCES): Likewise.
+	(am_libebl_aarch64_pic_a_OBJECTS): Likewise.
+	(aarch64_regs_no_Wformat): Likewise.
+	* aarch64_corenote.c, aarch64_init.c: New files.
+	* aarch64_regs.c, aarch64_reloc.def: Likewise.
+	* aarch64_retval.c, aarch64_symbol.c: Likewise.
+	* libebl_CPU.h (dwarf_peel_type): New function.
+	(dwarf_peeled_die_type): Likewise.
+
+2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (i386_SRCS): Add i386_initreg.c.
+	(x86_64_SRCS): Add x86_64_initreg.c.
+	* i386_initreg.c: New file.
+	* i386_init.c (i386_init): Initialize frame_nregs and
+	set_initial_registers_tid.
+	* x86_64_initreg.c: New file.
+	* x86_64_init.c (x86_64_init): Initialize frame_nregs and
+	set_initial_registers_tid.
+
+2013-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* ppc_cfi.c (ppc_abi_cfi): Use DW_CFA_val_offset for reg1, not
+	DW_CFA_val_expression.
+
+2013-08-29  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (arm_SRCS): Add arm_cfi.c.
+	* arm_cfi.c: New file.
+	* arm_init.c (arm_init): Initialize abi_cfi.
+
+2013-08-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* Makefile.am (ppc_SRCS, ppc64_SRCS): Add ppc_cfi.c.
+	(s390_SRCS): Add s390_cfi.c.
+	* ppc64_init.c (ppc64_init): Initialize abi_cfi.
+	* ppc_cfi.c: New file.
+	* ppc_init.c (ppc_init): Initialize abi_cfi.
+	* s390_cfi.c: New file.
+	* s390_init.c (s390_init): Initialize abi_cfi.
+
+2013-08-28  Mark Wielaard  <mjw@redhat.com>
+
+	* arm_regs.c (arm_register_info): Set *prefix to "".
+	* ppc_regs.c (ppc_register_info): Likewise.
+	* sh_regs.c (sh_register_info): Likewise.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+
+2013-02-06  Mark Wielaard  <mjw@redhat.com>
+
+	* libebl_CPU.h (DWARF_TAG_OR_RETURN): New macro.
+	* backends/alpha_retval.c (alpha_return_value_location): Use new
+	DWARF_TAG_OR_RETURN macro instead of dwarf_tag ().
+	* backends/arm_retval.c (arm_return_value_location): Likewise.
+	* backends/i386_retval.c (i386_return_value_location): Likewise.
+	* backends/ia64_retval.c (hfa_type): Likewise.
+	(ia64_return_value_location): Likewise.
+	* backends/ppc64_retval.c (ppc64_return_value_location): Likewise.
+	* backends/ppc_retval.c (ppc_return_value_location): Likewise.
+	* backends/s390_retval.c (s390_return_value_location): Likewise.
+	* backends/sh_retval.c (sh_return_value_location): Likewise.
+	* backends/sparc_retval.c (sparc_return_value_location): Likewise.
+	* backends/tilegx_retval.c (tilegx_return_value_location): Likewise.
+	* backends/x86_64_retval.c (x86_64_return_value_location): Likewise.
+
+2013-01-29  Jan Kratochvil  <jan.kratochvil@redhat.com>
+	    Roland McGrath <roland@hack.frob.com>
+
+	* Makefile.am (s390_SRCS): Add s390_corenote.c and s390x_corenote.c.
+	* linux-core-note.c (ALIGN_PR_REG): New definitions.
+	(struct EBLHOOK(prstatus)): Change field pr_reg to anonymous struct with
+	ALIGN_PR_REG.
+	(EXTRA_ITEMS): New macro.
+	* s390_corenote.c: New file.
+	* s390_init.c (s390x_core_note): New declaration.
+	(s390_init): Install s390x_core_note and s390_core_note.
+	* s390x_corenote.c: New file.
+
+2013-01-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* arm_corenote.c (vfp_items): Remove zero COUNT initializer.
+
+2012-10-12  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* linux-core-note.c (prstatus_items): Rename groups of sigpend and
+	sighold to signal2 and signal3.
+
+2012-09-24  Petr Machata  <pmachata@redhat.com>
+
+	* arm_corenote.c (vfp_items, vfp_regs): New const variables.
+	(EXTRA_NOTES): Use it for NT_ARM_VFP.
+	* linux-core-note.c (EXTRA_REGSET_ITEMS): New macro.
+
+2012-09-17  Petr Machata  <pmachata@redhat.com>
+
+	* arm_corenote.c (FPREGSET_SIZE): Change to 116.
+
+2012-08-22  Jeff Kenton  <jkenton@tilera.com>
+
+	* Makefile.am (modules): Add tilegx.
+	(libebl_pic): Add libebl_tilegx_pic.a.
+	(tilegx_SRCS): New variable.
+	(libebl_tilegx_pic_a_SOURCES): Likewise.
+	(am_libebl_tilegx_pic_a_OBJECTS): Likewise.
+	* tilegx_corenote.c: New file.
+	* tilegx_regs.c: New file.
+	* tilegx_reloc.def: New file.
+	* tilegx_init.c: New file.
+	* tilegx_retval.c: New file.
+	* tilegx_symbol.c: New file.
+
+2011-03-09  Mark Wielaard  <mjw@redhat.com>
+
+	* alpha_init.c (alpha_init): Initialize check_st_other_bits hook.
+	* alpha_symbol.c (alpha_check_st_other_bits): New function.
+
+2011-03-09  Roland McGrath  <roland@redhat.com>
+
+	* alpha_symbol.c (alpha_check_special_symbol): New function.
+	* alpha_init.c (alpha_init): Initialize hook.
+
+2010-11-08  Roland McGrath  <roland@redhat.com>
+
+	* i386_retval.c (loc_intreg): Typo fix.
+	Reported by Thorsten Glaser <tg@mirbsd.de>.
+
+2010-04-10  Matt Fleming  <matt@console-pimps.org>
+
+	* sh_corenote.c: New file.
+	* sh_regs.c: New file.
+	* sh_retval.c: New file.
+	* sh_symbol.c (sh_machine_flag_check): New function.
+	* Makefile.am (sh_SRCS): Add new files.
+	* sh_init.c (sh_init): Add initializers.
+
+2010-04-07  Roland McGrath  <roland@redhat.com>
+
+	* arm_reloc.def: Accept PC24 and ABS32 in EXEC|DYN too.
+
+2010-03-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* x86_64_reloc.def: Add entries for R_X86_64_SIZE32 and
+	R_X86_64_SIZE64.
+
+2010-02-18  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (libebl_%.so): Use multi-target pattern rule instead of
+	intermediate dependency file for libebl_%.map, working around apparent
+	make -j timing-sensitive bugs.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Use config/eu.am for common stuff.
+
+2010-01-05  Roland McGrath  <roland@redhat.com>
+
+	* arm_retval.c (arm_return_value_location): Use dwarf_aggregate_size.
+	* ia64_retval.c (ia64_return_value_location): Likewise.
+	* ppc_retval.c (ppc_return_value_location): Likewise.
+	* ppc64_retval.c (ppc64_return_value_location): Likewise.
+	* sparc_retval.c (sparc_return_value_location): Likewise.
+
+	* ppc64_retval.c (ppc64_return_value_location):
+	Use vr2 for DW_TAG_array_type with DW_AT_GNU_vector.
+	* ppc_retval.c (ppc_return_value_location): Likewise.
+
+2010-01-04  Roland McGrath  <roland@redhat.com>
+
+	* linux-core-note.c (vmcoreinfo_items): New static const variable.
+	(EBLHOOK(core_note)): Update arguments for new protocol.
+	Validate the name as "CORE" or "LINUX" for known n_type cases.
+	Handle name "VMCOREINFO" n_type=0 with vmcoreinfo_items.
+	* i386_corenote.c (EXTRA_NOTES): Update parameter usage.
+	* x86_corenote.c (EXTRA_NOTES_IOPERM): Likewise.
+
+2009-09-10  Mark Wielaard  <mjw@redhat.com>
+
+	* sparc_retval.c: Fix license header.
+
+2009-08-07  Roland McGrath  <roland@redhat.com>
+
+	* x86_64_reloc.def: Add PC64, GOTOFF64, GOTPC32, GOTPC32_TLSDESC,
+	TLSDESC_CALL, TLSDESC.
+
+2009-07-08  Roland McGrath  <roland@redhat.com>
+
+	* x86_64_cfi.c (x86_64_abi_cfi): New file.
+	* Makefile.am (x86_64_SRCS): Add it.
+	* x86_64_init.c (x86_64_init): Add initializer.
+
+	* i386_cfi.c (i386_abi_cfi): New file.
+	* Makefile.am (i386_SRCS): Add it.
+	* i386_init.c (i386_init): Initialize abi_cfi hook.
+
+2009-06-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_reloc.def: Add IRELATIVE entry.
+	* x86_64_reloc.def: Likewise.
+
+2009-04-16  Roland McGrath  <roland@redhat.com>
+
+	* arm_regs.c (arm_register_info): Handle VFP registers.
+
+	* i386_corenote.c (EXTRA_NOTES): NT_PRXFPREG -> NT_PRXFPREG
+
+2009-04-14  Roland McGrath  <roland@redhat.com>
+
+	* arm_retval.c: New file.
+	* arm_attrs.c: New file.
+	* Makefile.am (arm_SRCS): Add them.
+	* arm_symbol.c (arm_segment_type_name): New function.
+	(arm_section_type_name): New function.
+	(arm_machine_flag_check): New function.
+	* arm_init.c (arm_init): Initialize those hooks.
+
+	* arm_regs.c: New file.
+	* arm_corenote.c: New file.
+	* arm_auxv.c: New file.
+	* Makefile.am (arm_SRCS): Add them.
+	* arm_init.c (arm_init): Initialize core_note, register_info,
+	and auxv_info hooks.
+
+	* ia64_symbol.c (ia64_section_type_name): Remove "SHT_" prefixes.
+
+2009-04-01  Roland McGrath  <roland@redhat.com>
+
+	* sparc_reloc.def: Update table.
+	Data from Dave Miller <davem@davemloft.net>.
+
+2009-02-15  Roland McGrath  <roland@redhat.com>
+
+	* ppc_attrs.c (ppc_check_object_attribute): Handle tag
+	GNU_Power_ABI_Struct_Return.
+
+2008-10-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_reloc.def: Fix entries for TLS_GOTDESC, TLS_DESC_CALL, and
+	TLS_DESC.
+
+2008-08-01  Roland McGrath  <roland@redhat.com>
+
+	* x86_corenote.c: New file.
+	* Makefile.am (noinst_HEADERS): Add it.
+	* i386_corenote.c: Include it, use EXTRA_NOTES_IOPERM in EXTRA_NOTES.
+	* x86_64_corenote.c: Likewise.
+
+	* linux-core-note.c (prstatus_items): Use 'B' instead of 'b'
+	for sigpend and sighold.
+
+2008-07-04  Roland McGrath  <roland@redhat.com>
+
+	* i386_syscall.c: New file.
+	* x86_64_syscall.c: New file.
+	* ppc_syscall.c: New file.
+	* Makefile.am (i386_SRCS, x86_64_SRCS, ppc_SRCS, ppc64_SRCS): Add them.
+	* i386_init.c (i386_init): Initialize syscall_abi hook.
+	* x86_64_init.c (x86_64_init): Likewise.
+	* ppc_init.c (ppc_init): Likewise.
+	* ppc64_init.c (ppc64_init): Likewise.
+
+	* ppc_corenote.c (PRSTATUS_REGSET_ITEMS): Add nip.
+	Fix offset calculation for 64-bit case.
+
+2008-04-04  Roland McGrath  <roland@redhat.com>
+
+	* alpha_symbol.c (alpha_check_special_section): New function.
+	* alpha_init.c (alpha_init): Initialize check_special_section hook.
+
+2008-03-31  Roland McGrath  <roland@redhat.com>
+
+	* sparc_symbol.c (sparc_symbol_type_name): New function.
+	(sparc_dynamic_tag_name): New function.
+	(sparc_dynamic_tag_check): New function.
+	* sparc_init.c (sparc_init): Initialize those hooks.
+
+	* sparc_symbol.c (sparc_check_special_section): New function.
+	* sparc_init.c (sparc_init): Initialize check_special_section hook.
+
+2008-02-20  Roland McGrath  <roland@redhat.com>
+
+	* ppc_attrs.c: New file.
+	* Makefile.am (ppc_SRCS, ppc64_SRCS): Add it.
+	* ppc_init.c (ppc_init): Initialize check_object_attribute hook.
+
+2008-02-14  Roland McGrath  <roland@redhat.com>
+
+	* alpha_auxv.c: New file.
+	* Makefile.am (alpha_SRCS): Add it.
+	* alpha_init.c (alpha_init): Initialize auxv_info hook.
+
+2008-02-08  Roland McGrath  <roland@redhat.com>
+
+	* ppc_corenote.c (spe_regs): New const variable.
+	(EXTRA_NOTES): Use it for NT_PPC_SPE.
+
+2008-01-02  Roland McGrath  <roland@redhat.com>
+
+	* i386_corenote.c (tls_items): New const table.
+	(tls_info): New function, uses it.
+	(EXTRA_NOTES): Use it to handle NT_386_TLS.
+
+2008-01-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Add x86-64 disassembler.
+	* x86_64_init.c (x86_64_init): Hook up disassembler.
+
+2007-12-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Add x86 disassembler.
+	* i386_init.c (i386_init): Hook up disassembler.
+
+2007-12-15  Roland McGrath  <roland@redhat.com>
+
+	* ppc_regs.c (ppc_register_info): Return "spefscr", not "spr512".
+
+2007-10-18  Roland McGrath  <roland@redhat.com>
+
+	* ppc_regs.c (ppc_register_info): Assign 67 to "vscr".
+	Return "vector" and 32 bits for vscr and vrsave.
+	* ppc_corenote.c (altivec_regs): New variable.
+	(EXTRA_NOTES): New macro, handle NT_PPC_VMX.
+
+	* linux-core-note.c (EXTRA_REGSET): New macro.
+	Remove NT_PRXFPREG case.  Instead, use EXTRA_NOTES if defined.
+	* i386_corenote.c (EXTRA_NOTES): Define it.
+
+2007-10-09  Roland McGrath  <roland@redhat.com>
+
+	* sparc_auxv.c: New file.
+	* Makefile.am (sparc_SRCS): Add it.
+	* sparc_init.c (sparc_init): Initialize auxv_info hook.
+
+2007-10-08  Roland McGrath  <roland@redhat.com>
+
+	* linux-core-note.c (TIMEVAL_FIELD): New macro.
+	(prstatus_items): Use it.
+	* sparc_corenote.c: New file.
+	* sparc64_corenote.c: New file.
+	* Makefile.am (sparc_SRCS): Add them.
+	* sparc_init.c (sparc_init): Initialize core_note hook.
+
+	* sparc_symbol.c (sparc_machine_flag_check): New function.
+	* sparc_init.c (sparc_init): Use it.
+
+2007-09-27  Roland McGrath  <roland@redhat.com>
+
+	* alpha_retval.c: Use dwarf_attr_integrate and dwarf_hasattr_integrate.
+	* i386_retval.c: Likewise.
+	* ia64_retval.c: Likewise.
+	* ppc64_retval.c: Likewise.
+	* ppc_retval.c: Likewise.
+	* s390_retval.c: Likewise.
+	* sparc_retval.c: Likewise.
+	* x86_64_retval.c: Likewise.
+
+2007-10-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: More dependencies for the libebl_* libraries.
+
+2007-08-23  Roland McGrath  <roland@redhat.com>
+
+	* x86_64_regs.c (x86_64_register_info): Put %rflags in "integer" set.
+
+2007-08-22  Roland McGrath  <roland@redhat.com>
+
+	* linux-core-note.c (prstatus_items): Add .group initializers.
+	(prpsinfo_items): Likewise.
+	* x86_64_corenote.c (PRSTATUS_REGSET_ITEMS): Likewise.
+	* i386_corenote.c (PRSTATUS_REGSET_ITEMS): Likewise.
+	* ppc_corenote.c (PRSTATUS_REGSET_ITEMS): Likewise.
+
+2007-08-20  Roland McGrath  <roland@redhat.com>
+
+	* ppc_symbol.c (ppc_check_special_symbol): For _GLOBAL_OFFSET_TABLE_
+	when DT_PPC_GOT is not found, anywhere in the section is valid.
+
+2007-08-19  Roland McGrath  <roland@redhat.com>
+
+	* i386_auxv.c: New file.
+	* Makefile.am (i386_SRCS, x86_64_SRCS): Add it.
+	* ppc_auxv.c: New file.
+	* Makefile.am (ppc_SRCS, ppc64_SRCS): Add it.
+	* i386_init.c (i386_init): Initialize auxv_info hook.
+	* x86_64_init.c (x86_64_init): Likewise.
+	* ppc_init.c (ppc_init): Likewise.
+	* ppc64_init.c (ppc64_init): Likewise.
+
+	* alpha_corenote.c: New file.
+	* Makefile.am (alpha_SRCS): Add it.
+	* alpha_init.c (alpha_init): Initialize core_note hook.
+
+	* ppc_corenote.c: New file.
+	* ppc64_corenote.c: New file.
+	* Makefile.am (ppc_SRCS, ppc64_SRCS): Add them.
+	* ppc_init.c (ppc_init): Initialize core_note hook.
+	* ppc64_init.c (ppc64_init): Likewise.
+
+	* linux-core-note.c: New file.
+	* Makefile.am (noinst_HEADERS): Add it.
+	* i386_corenote.c: Rewritten.
+	* x86_64_corenote.c: Likewise.
+
+2007-05-23  Roland McGrath  <roland@redhat.com>
+
+	* alpha_regs.c (alpha_register_info): fp -> s6
+
+2007-04-26  Roland McGrath  <roland@redhat.com>
+
+	* alpha_symbol.c (alpha_machine_section_flag_check): New function.
+	* alpha_init.c (alpha_init): Initialize hook.
+
+	* alpha_regs.c: New file.
+	* Makefile.am (alpha_SRCS): Add it.
+	* alpha_init.c (alpha_init): Initialize register_info hook.
+
+2007-04-22  Roland McGrath  <roland@redhat.com>
+
+	* ppc_regs.c (ppc_register_info): Use some names instead of sprNNN:
+	mq, xer, lr, ctr, dsisr, dar, dec, vrsave.
+	Set *BITS to 64 for FPU registers.
+
+	* i386_regs.c (i386_register_info): Set *BITS to 16 for fctrl, fstat.
+	* x86_64_regs.c (x86_64_register_info): Likewise for fcw, fsw.
+
+2007-04-01  Roland McGrath  <roland@redhat.com>
+
+	* x86_64_regs.c (x86_64_register_info): Add more registers from newer
+	ABI spec.
+
+2007-01-11  Roland McGrath  <roland@redhat.com>
+
+	* ia64_symbol.c (ia64_machine_section_flag_check): New function.
+	* ia64_init.c (ia64_init): Use it.
+
+	* ia64_symbol.c (ia64_section_type_name): Typo fix in string.
+
+2006-10-09  Roland McGrath  <roland@redhat.com>
+
+	* ia64_symbol.c (ia64_reloc_simple_type): Treat SECREL types as simple.
+
+2006-08-29  Roland McGrath  <roland@redhat.com>
+
+	* sparc_retval.c: New file.
+	* Makefile.am (sparc_SRCS): Add it.
+	* sparc_init.c (sparc_init): Initialize return_value_location hook.
+
+2006-08-22  Roland McGrath  <roland@redhat.com>
+
+	* i386_regs.c (i386_register_name): Renamed i386_register_info.
+	Take new args, yield more info.
+	* i386_init.c (i386_init): Update initializer.
+	* ia64_regs.c (ia64_register_name): Likewise.
+	* ia64_init.c (ia64_init): Likewise.
+	* ppc_regs.c (ppc_register_name): Likewise.
+	* ppc64_init.c (ppc64_init): Likewise.
+	* ppc_init.c (ppc_init): Likewise.
+	* s390_regs.c (s390_register_name): Likewise.
+	* s390_init.c (s390_init): Likewise.
+	* sparc_regs.c (sparc_register_name): Likewise.
+	* sparc_init.c (sparc_init): Likewise.
+	* x86_64_regs.c (x86_64_register_name): Likewise.
+	* x86_64_init.c (x86_64_init): Likewise.
+
+2006-08-08  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (%.os): Don't depend on %.o, since we don't actually
+	need static object for anything here.  This rule is the only source of
+	.deps/ files.
+
+2006-06-23  Stepan Kasal  <skasal@redhat.com>
+
+	* Makefile.am (PACKAGE_VERSION): Remove superfluous definition.
+
+2006-08-03  Roland McGrath  <roland@redhat.com>
+
+	* sparc_regs.c (sparc_register_name): List 32 FPU regs only for
+	EM_SPARC.  EM_SPARC32PLUS also has 64.
+
+2006-07-21  Roland McGrath  <roland@redhat.com>
+
+	* i386_regs.c (i386_register_name): Fix return value when using stpcpy.
+	* ppc_regs.c (ppc_register_name): Likewise.
+	* s390_regs.c (s390_register_name): Likewise.
+
+	* ia64_retval.c: New file.
+	* Makefile.am (ia64_SRCS): Add it.
+	* ia64_init.c (ia64_init): Install return_value_location hook.
+
+	* ia64_regs.c: New file.
+	* Makefile.am (ia64_SRCS): Add it.
+	* ia64_init.c (ia64_init): Install register_name hook.
+
+2006-07-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* alpha_init.c: Initialize sysvhash_entrysize.
+	* s390_init.c: Likewise.
+
+2006-07-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* common-reloc.c (relative_reloc_p): New function.
+	(init_reloc): Hook it up.
+	* ia64_reloc.def: Define NO_RELATIVE_RELOC.
+
+2006-06-13  Roland McGrath  <roland@redhat.com>
+
+	* ppc64_retval.c: Remove SVR4_STRUCT_RETURN braino.
+
+2006-06-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* common-reloc.c (none_reloc_p): New function.
+	(init_reloc): Hook it up.
+
+2006-02-22  Roland McGrath  <roland@redhat.com>
+
+	* ppc64_retval.c (SVR4_STRUCT_RETURN): New macro.
+	(ppc64_return_value_location): Use registers for aggregate conditional
+	on that.
+	* ppc_retval.c (SVR4_STRUCT_RETURN): New macro.
+	(ppc_return_value_location): Use registers for aggregate conditional
+	on that.
+
+2006-01-12  Roland McGrath  <roland@redhat.com>
+
+	* s390_retval.c: New file.
+	* Makefile.am (s390_SRCS): Add it.
+	* s390_init.c (s390_init): Install return_value_location hook.
+
+2006-01-11  Roland McGrath  <roland@redhat.com>
+
+	* s390_regs.c: New file.
+	* Makefile.am (s390_SRCS): Add it.
+	* s390_init.c (s390_init): Install register_name hook.
+
+	* s390_reloc.def: Update bits per
+	Martin Schwidefsky <schwidefsky@de.ibm.com>.
+
+2005-12-10  Ulrich Drepper
+
+	* common-reloc.c (R_NAME): Generate string correctly.
+
+2005-12-05  Roland McGrath  <roland@redhat.com>
+
+	* i386_regs.c (i386_register_name): Use a table for the first 8 regs.
+	* x86_64_regs.c (x86_64_register_name): Likewise.
+
+2005-11-25  Roland McGrath  <roland@redhat.com>
+
+	* i386_regs.c (i386_register_name): Return 0, not 1, for gaps.
+
+	* i386_regs.c: New file.
+	* ppc_regs.c: New file.
+	* sparc_regs.c: New file.
+	* x86_64_regs.c: New file.
+	* Makefile.am
+	(i386_SRCS, x86_64_SRCS, ppc_SRCS, ppc64_SRCS, sparc_SRCS): Add them.
+	* i386_init.c: Initialize register_name hook.
+	* ppc_init.c: Likewise.
+	* ppc64_init.c: Likewise.
+	* sparc_init.c: Likewise.
+	* x86_64_init.c: Likewise.
+
+2005-11-19  Roland McGrath  <roland@redhat.com>
+
+	* ppc64_reloc.def: REL30 -> ADDR30.
+
+2005-11-18  Roland McGrath  <roland@redhat.com>
+
+	* alpha_init.c: Use HOOK macro.
+	* arm_init.c: Likewise.
+	* i386_init.c: Likewise.
+	* ia64_init.c: Likewise.
+	* ppc64_init.c: Likewise.
+	* ppc_init.c: Likewise.
+	* s390_init.c: Likewise.
+	* sh_init.c: Likewise.
+	* sparc_init.c: Likewise.
+	* x86_64_init.c: Likewise.
+
+2005-11-17  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (uninstall): Don't try to remove $(pkgincludedir).
+	(CLEANFILES): Add libebl_$(m).so.
+
+	* ppc_reloc.def: Update bits per Alan Modra <amodra@bigpond.net.au>.
+	* ppc64_reloc.def: Likewise.
+
+2005-11-15  Roland McGrath  <roland@redhat.com>
+
+	* Contents moved here from ../libebl.
diff --git a/third_party/elfutils/backends/Makefile.am b/third_party/elfutils/backends/Makefile.am
new file mode 100644
index 0000000..2c62add
--- /dev/null
+++ b/third_party/elfutils/backends/Makefile.am
@@ -0,0 +1,169 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 2000-2010, 2013, 2014 Red Hat, Inc.
+## Copyright (C) 2012 Tilera Corporation
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * 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
+##
+## or both in parallel, as here.
+##
+## elfutils 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.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+include $(top_srcdir)/config/eu.am
+AM_CPPFLAGS += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \
+	   -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw
+
+
+modules = i386 sh x86_64 ia64 alpha arm aarch64 sparc ppc ppc64 s390 \
+	  tilegx m68k bpf
+libebl_pic = libebl_i386_pic.a libebl_sh_pic.a libebl_x86_64_pic.a    \
+	     libebl_ia64_pic.a libebl_alpha_pic.a libebl_arm_pic.a    \
+	     libebl_aarch64_pic.a libebl_sparc_pic.a libebl_ppc_pic.a \
+	     libebl_ppc64_pic.a libebl_s390_pic.a libebl_tilegx_pic.a \
+	     libebl_m68k_pic.a libebl_bpf_pic.a
+noinst_LIBRARIES = $(libebl_pic)
+noinst_DATA = $(libebl_pic:_pic.a=.so)
+
+
+libelf = ../libelf/libelf.so
+libdw = ../libdw/libdw.so
+libeu = ../lib/libeu.a
+
+i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \
+	    i386_retval.c i386_regs.c i386_auxv.c i386_syscall.c \
+	    i386_initreg.c i386_unwind.c
+cpu_i386 = ../libcpu/libcpu_i386.a
+libebl_i386_pic_a_SOURCES = $(i386_SRCS)
+am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
+
+sh_SRCS = sh_init.c sh_symbol.c sh_corenote.c sh_regs.c sh_retval.c
+libebl_sh_pic_a_SOURCES = $(sh_SRCS)
+am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os)
+
+x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c x86_64_cfi.c \
+	      x86_64_retval.c x86_64_regs.c i386_auxv.c x86_64_syscall.c \
+	      x86_64_initreg.c x86_64_unwind.c x32_corenote.c
+cpu_x86_64 = ../libcpu/libcpu_x86_64.a
+libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
+am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
+
+ia64_SRCS = ia64_init.c ia64_symbol.c ia64_regs.c ia64_retval.c
+libebl_ia64_pic_a_SOURCES = $(ia64_SRCS)
+am_libebl_ia64_pic_a_OBJECTS = $(ia64_SRCS:.c=.os)
+
+alpha_SRCS = alpha_init.c alpha_symbol.c alpha_retval.c alpha_regs.c \
+	     alpha_corenote.c alpha_auxv.c
+libebl_alpha_pic_a_SOURCES = $(alpha_SRCS)
+am_libebl_alpha_pic_a_OBJECTS = $(alpha_SRCS:.c=.os)
+
+arm_SRCS = arm_init.c arm_symbol.c arm_regs.c arm_corenote.c \
+	   arm_auxv.c arm_attrs.c arm_retval.c arm_cfi.c arm_initreg.c
+libebl_arm_pic_a_SOURCES = $(arm_SRCS)
+am_libebl_arm_pic_a_OBJECTS = $(arm_SRCS:.c=.os)
+
+aarch64_SRCS = aarch64_init.c aarch64_regs.c aarch64_symbol.c	\
+	       aarch64_corenote.c aarch64_retval.c aarch64_cfi.c \
+	       aarch64_initreg.c aarch64_unwind.c
+libebl_aarch64_pic_a_SOURCES = $(aarch64_SRCS)
+am_libebl_aarch64_pic_a_OBJECTS = $(aarch64_SRCS:.c=.os)
+
+sparc_SRCS = sparc_init.c sparc_symbol.c sparc_regs.c sparc_retval.c \
+	     sparc_corenote.c sparc64_corenote.c sparc_auxv.c sparc_attrs.c \
+             sparc_cfi.c sparc_initreg.c
+libebl_sparc_pic_a_SOURCES = $(sparc_SRCS)
+am_libebl_sparc_pic_a_OBJECTS = $(sparc_SRCS:.c=.os)
+
+ppc_SRCS = ppc_init.c ppc_symbol.c ppc_retval.c ppc_regs.c \
+	   ppc_corenote.c ppc_auxv.c ppc_attrs.c ppc_syscall.c \
+	   ppc_cfi.c ppc_initreg.c
+libebl_ppc_pic_a_SOURCES = $(ppc_SRCS)
+am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os)
+
+ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c \
+	     ppc64_corenote.c ppc_regs.c ppc_auxv.c ppc_attrs.c ppc_syscall.c \
+	     ppc_cfi.c ppc_initreg.c ppc64_unwind.c ppc64_resolve_sym.c
+libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
+am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
+
+s390_SRCS = s390_init.c s390_symbol.c s390_regs.c s390_retval.c \
+	    s390_corenote.c s390x_corenote.c s390_cfi.c s390_initreg.c \
+	    s390_unwind.c
+libebl_s390_pic_a_SOURCES = $(s390_SRCS)
+am_libebl_s390_pic_a_OBJECTS = $(s390_SRCS:.c=.os)
+
+tilegx_SRCS = tilegx_init.c tilegx_symbol.c tilegx_regs.c \
+              tilegx_retval.c tilegx_corenote.c
+libebl_tilegx_pic_a_SOURCES = $(tilegx_SRCS)
+am_libebl_tilegx_pic_a_OBJECTS = $(tilegx_SRCS:.c=.os)
+
+m68k_SRCS = m68k_init.c m68k_symbol.c m68k_regs.c \
+	    m68k_retval.c m68k_corenote.c
+libebl_m68k_pic_a_SOURCES = $(m68k_SRCS)
+am_libebl_m68k_pic_a_OBJECTS = $(m68k_SRCS:.c=.os)
+
+# m68k prstatus core notes are described by a packed structure
+# which has not naturally aligned fields. Since we don't access
+# these fields directly, but take their offset to be used later
+# to extract the data through elfxx_xlatetom/memmove, this isn't
+# an issue.
+m68k_corenote_no_Wpacked_not_aligned = yes
+
+bpf_SRCS = bpf_init.c bpf_regs.c
+cpu_bpf = ../libcpu/libcpu_bpf.a
+libebl_bpf_pic_a_SOURCES = $(bpf_SRCS)
+am_libebl_bpf_pic_a_OBJECTS = $(bpf_SRCS:.c=.os)
+
+
+libebl_%.so libebl_%.map: libebl_%_pic.a $(libelf) $(libdw) $(libeu)
+	@rm -f $(@:.so=.map)
+	$(AM_V_at)echo 'ELFUTILS_$(PACKAGE_VERSION) { global: $*_init; local: *; };' \
+	  > $(@:.so=.map)
+	$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $(@:.map=.so) \
+		-Wl,--whole-archive $< $(cpu_$*) -Wl,--no-whole-archive \
+		-Wl,--version-script,$(@:.so=.map),--no-undefined \
+		-Wl,--as-needed $(libelf) $(libdw) $(libeu)
+	@$(textrel_check)
+
+libebl_i386.so: $(cpu_i386)
+libebl_x86_64.so: $(cpu_x86_64)
+libebl_bpf.so: $(cpu_bpf)
+
+install: install-am install-ebl-modules
+install-ebl-modules:
+	$(mkinstalldirs) $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)
+	for m in $(modules); do \
+	  $(INSTALL_PROGRAM) libebl_$${m}.so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \
+	  ln -fs libebl_$${m}-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \
+	done
+
+uninstall: uninstall-am
+	for m in $(modules); do \
+	  rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}-$(PACKAGE_VERSION).so; \
+	  rm -f $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)/libebl_$${m}.so; \
+	done
+	rmdir --ignore-fail-on-non-empty $(DESTDIR)$(libdir)/$(LIBEBL_SUBDIR)
+
+noinst_HEADERS = libebl_CPU.h common-reloc.c linux-core-note.c x86_corenote.c
+EXTRA_DIST = $(foreach m,$(modules),$($(m)_SRCS)) $(modules:=_reloc.def)
+
+CLEANFILES += $(foreach m,$(modules),\
+			libebl_$(m).map libebl_$(m).so \
+			$(am_libebl_$(m)_pic_a_OBJECTS))
diff --git a/third_party/elfutils/backends/aarch64_cfi.c b/third_party/elfutils/backends/aarch64_cfi.c
new file mode 100644
index 0000000..acbb9b6
--- /dev/null
+++ b/third_party/elfutils/backends/aarch64_cfi.c
@@ -0,0 +1,82 @@
+/* arm ABI-specified defaults for DWARF CFI.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#define BACKEND aarch64_
+#include "libebl_CPU.h"
+
+
+/* ABI-specified state of DWARF CFI based on:
+
+   "DWARF for the ARM 64 bit architecture (AArch64) 1.0"
+http://infocenter.arm.com/help/topic/com.arm.doc.ihi0057b/IHI0057B_aadwarf64.pdf
+
+   "Procedure Call Standard for the ARM 64 bit Architecture 1.0"
+http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
+*/
+
+int
+aarch64_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
+{
+  static const uint8_t abi_cfi[] =
+    {
+      /* The initial Canonical Frame Address is the value of the
+         Stack Pointer (r31) as setup in the previous frame. */
+      DW_CFA_def_cfa, ULEB128_7 (30), ULEB128_7 (0),
+
+#define SV(n) DW_CFA_same_value, ULEB128_7 (n)
+      /* Callee-saved regs r19-r28.  */
+      SV (19), SV (20), SV (21), SV (22), SV (23),
+      SV (24), SV (25), SV (26), SV (27), SV (28),
+
+      /* The Frame Pointer (FP, r29) and Link Register (LR, r30).  */
+      SV (29), SV (30),
+
+      /* Callee-saved fpregs v8-v15.  v0 == 64.  */
+      SV (72), SV (73), SV (74), SV (75),
+      SV (76), SV (77), SV (78), SV (79),
+#undef SV
+
+      /* XXX Note: registers intentionally unused by the program,
+	 for example as a consequence of the procedure call standard
+	 should be initialized as if by DW_CFA_same_value.  */
+    };
+
+  abi_info->initial_instructions = abi_cfi;
+  abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
+  abi_info->data_alignment_factor = -4;
+
+  abi_info->return_address_register = 30; /* lr.  */
+
+  return 0;
+}
diff --git a/third_party/elfutils/backends/aarch64_corenote.c b/third_party/elfutils/backends/aarch64_corenote.c
new file mode 100644
index 0000000..905a4b8
--- /dev/null
+++ b/third_party/elfutils/backends/aarch64_corenote.c
@@ -0,0 +1,172 @@
+/* AArch64 specific core note handling.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND aarch64_
+#include "libebl_CPU.h"
+
+#define	ULONG			uint64_t
+#define PID_T			int32_t
+#define	UID_T			uint32_t
+#define	GID_T			uint32_t
+#define ALIGN_ULONG		8
+#define ALIGN_PID_T		4
+#define ALIGN_UID_T		4
+#define ALIGN_GID_T		4
+#define TYPE_ULONG		ELF_T_XWORD
+#define TYPE_PID_T		ELF_T_SWORD
+#define TYPE_UID_T		ELF_T_WORD
+#define TYPE_GID_T		ELF_T_WORD
+
+#define PRSTATUS_REGS_SIZE	(34 * 8)
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+    { .offset = 0, .regno = 0, .count = 32, .bits = 64 }, /* x0..x30, sp */
+  };
+
+#define PRSTATUS_REGSET_ITEMS						\
+  {									\
+    .name = "pc", .type = ELF_T_XWORD, .format = 'x',			\
+    .offset = (offsetof (struct EBLHOOK(prstatus), pr_reg)		\
+	       + PRSTATUS_REGS_SIZE - 16),				\
+    .group = "register",						\
+    .pc_register = true							\
+  },									\
+  {									\
+    .name = "pstate", .type = ELF_T_XWORD, .format = 'x',		\
+    .offset = (offsetof (struct EBLHOOK(prstatus), pr_reg)		\
+	       + PRSTATUS_REGS_SIZE - 8),				\
+    .group = "register"							\
+  }
+
+static const Ebl_Register_Location aarch64_fpregset_regs[] =
+  {
+    { .offset = 0, .regno = 64, .count = 32, .bits = 128 }, /* v0..v31 */
+  };
+
+static const Ebl_Core_Item aarch64_fpregset_items[] =
+  {
+    {
+      .name = "fpsr", .type = ELF_T_WORD, .format = 'x',
+      .offset = 512, .group = "register"
+    },
+    {
+      .name = "fpcr", .type = ELF_T_WORD, .format = 'x',
+      .offset = 516, .group = "register"
+    }
+  };
+
+static const Ebl_Core_Item aarch64_tls_items[] =
+  {
+    {
+      .name = "tls", .type = ELF_T_XWORD, .format = 'x',
+      .offset = 0, .group = "register"
+    }
+  };
+
+static const Ebl_Core_Item aarch64_syscall_items [] =
+  {
+    {
+      .name = "syscall", .type = ELF_T_WORD, .format = 'x',
+      .offset = 0, .group = "register"
+    }
+  };
+
+#define AARCH64_HWBP_REG(KIND, N)					\
+    {									\
+      .name = "DBG" KIND "VR" #N "_EL1", .type = ELF_T_XWORD, .format = 'x', \
+      .offset = 8 + N * 16, .group = "register"				\
+    },									\
+    {									\
+      .name = "DBG" KIND "CR" #N "_EL1", .type = ELF_T_WORD, .format = 'x', \
+      .offset = 16 + N * 16, .group = "register"			\
+    }
+
+#define AARCH64_BP_WP_GROUP(KIND, NAME)					\
+  static const Ebl_Core_Item NAME[] =					\
+    {									\
+      {									\
+	.name = "dbg_info", .type = ELF_T_WORD, .format = 'x',		\
+	.offset = 0, .group = "control"					\
+      },								\
+      /* N.B.: 4 bytes of padding here.  */				\
+									\
+      AARCH64_HWBP_REG(KIND, 0),					\
+      AARCH64_HWBP_REG(KIND, 1),					\
+      AARCH64_HWBP_REG(KIND, 2),					\
+      AARCH64_HWBP_REG(KIND, 3),					\
+      AARCH64_HWBP_REG(KIND, 4),					\
+      AARCH64_HWBP_REG(KIND, 5),					\
+      AARCH64_HWBP_REG(KIND, 6),					\
+      AARCH64_HWBP_REG(KIND, 7),					\
+      AARCH64_HWBP_REG(KIND, 8),					\
+      AARCH64_HWBP_REG(KIND, 9),					\
+      AARCH64_HWBP_REG(KIND, 10),					\
+      AARCH64_HWBP_REG(KIND, 11),					\
+      AARCH64_HWBP_REG(KIND, 12),					\
+      AARCH64_HWBP_REG(KIND, 13),					\
+      AARCH64_HWBP_REG(KIND, 14),					\
+      AARCH64_HWBP_REG(KIND, 15),					\
+									\
+      /* The DBGBVR+DBGBCR pair only takes 12 bytes.  There are 4 bytes	\
+	 of padding at the end of each pair.  The item formatter in	\
+	 readelf can skip those, but the missing 4 bytes at the end of	\
+	 the whole block cause it to assume the whole item bunch	\
+	 repeats, so it loops around to read more.  Insert an explicit	\
+	 (but invisible) padding word.  */				\
+      {									\
+	.name = "", .type = ELF_T_WORD, .format = 'h',			\
+	.offset = 260, .group = "register"				\
+      }									\
+    }
+
+AARCH64_BP_WP_GROUP ("B", aarch64_hw_bp_items);
+AARCH64_BP_WP_GROUP ("W", aarch64_hw_wp_items);
+
+#undef AARCH64_BP_WP_GROUP
+#undef AARCH64_HWBP_REG
+
+#define EXTRA_NOTES							\
+  EXTRA_REGSET_ITEMS (NT_FPREGSET, 528,					\
+		      aarch64_fpregset_regs, aarch64_fpregset_items)	\
+  EXTRA_ITEMS (NT_ARM_TLS, 8, aarch64_tls_items)			\
+  EXTRA_ITEMS (NT_ARM_HW_BREAK, 264, aarch64_hw_bp_items)		\
+  EXTRA_ITEMS (NT_ARM_HW_WATCH, 264, aarch64_hw_wp_items)		\
+  EXTRA_ITEMS (NT_ARM_SYSTEM_CALL, 4, aarch64_syscall_items)
+
+#include "linux-core-note.c"
diff --git a/third_party/elfutils/backends/aarch64_init.c b/third_party/elfutils/backends/aarch64_init.c
new file mode 100644
index 0000000..fad923f
--- /dev/null
+++ b/third_party/elfutils/backends/aarch64_init.c
@@ -0,0 +1,70 @@
+/* Initialization of AArch64 specific backend library.
+   Copyright (C) 2013, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		aarch64_
+#define RELOC_PREFIX	R_AARCH64_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on aarch64_reloc.def.  */
+#include "common-reloc.c"
+
+
+const char *
+aarch64_init (Elf *elf __attribute__ ((unused)),
+	      GElf_Half machine __attribute__ ((unused)),
+	      Ebl *eh,
+	      size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "AARCH64";
+  aarch64_init_reloc (eh);
+  HOOK (eh, register_info);
+  HOOK (eh, core_note);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, return_value_location);
+  HOOK (eh, check_special_symbol);
+  HOOK (eh, data_marker_symbol);
+  HOOK (eh, abi_cfi);
+
+  /* X0-X30 (31 regs) + SP + 1 Reserved + ELR, 30 Reserved regs (34-43)
+     + V0-V31 (32 regs, least significant 64 bits only)
+     + ALT_FRAME_RETURN_COLUMN (used when LR isn't used) = 97 DWARF regs. */
+  eh->frame_nregs = 97;
+  HOOK (eh, set_initial_registers_tid);
+  HOOK (eh, unwind);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/aarch64_initreg.c b/third_party/elfutils/backends/aarch64_initreg.c
new file mode 100644
index 0000000..daf6f37
--- /dev/null
+++ b/third_party/elfutils/backends/aarch64_initreg.c
@@ -0,0 +1,92 @@
+/* Fetch live process registers from TID.
+   Copyright (C) 2013, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "system.h"
+#include <assert.h>
+#if defined(__aarch64__) && defined(__linux__)
+# include <linux/uio.h>
+# include <sys/user.h>
+# include <sys/ptrace.h>
+/* Deal with old glibc defining user_pt_regs instead of user_regs_struct.  */
+# ifndef HAVE_SYS_USER_REGS
+#  define user_regs_struct user_pt_regs
+#  define user_fpsimd_struct user_fpsimd_state
+# endif
+#endif
+
+#define BACKEND aarch64_
+#include "libebl_CPU.h"
+
+bool
+aarch64_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
+			  ebl_tid_registers_t *setfunc __attribute__ ((unused)),
+				void *arg __attribute__ ((unused)))
+{
+#if !defined(__aarch64__) || !defined(__linux__)
+  return false;
+#else /* __aarch64__ */
+
+  /* General registers.  */
+  struct user_regs_struct gregs;
+  struct iovec iovec;
+  iovec.iov_base = &gregs;
+  iovec.iov_len = sizeof (gregs);
+  if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec) != 0)
+    return false;
+
+  /* X0..X30 plus SP.  */
+  if (! setfunc (0, 32, (Dwarf_Word *) &gregs.regs[0], arg))
+    return false;
+
+  /* PC.  */
+  if (! setfunc (-1, 1, (Dwarf_Word *) &gregs.pc, arg))
+    return false;
+
+  /* ELR cannot be found.  */
+
+  /* FP registers (only 64bits are used).  */
+  struct user_fpsimd_struct fregs;
+  iovec.iov_base = &fregs;
+  iovec.iov_len = sizeof (fregs);
+  if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec) != 0)
+    return false;
+
+  Dwarf_Word dwarf_fregs[32];
+  for (int r = 0; r < 32; r++)
+    dwarf_fregs[r] = fregs.vregs[r] & 0xFFFFFFFF;
+
+  if (! setfunc (64, 32, dwarf_fregs, arg))
+    return false;
+
+  return true;
+#endif /* __aarch64__ */
+}
diff --git a/third_party/elfutils/backends/aarch64_regs.c b/third_party/elfutils/backends/aarch64_regs.c
new file mode 100644
index 0000000..23014bf
--- /dev/null
+++ b/third_party/elfutils/backends/aarch64_regs.c
@@ -0,0 +1,108 @@
+/* Register names and numbers for AArch64 DWARF.
+   Copyright (C) 2013, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <dwarf.h>
+#include <stdarg.h>
+
+#define BACKEND aarch64_
+#include "libebl_CPU.h"
+
+__attribute__ ((format (printf, 7, 8)))
+static ssize_t
+do_regtype (const char *setname, int type,
+           const char **setnamep, int *typep,
+           char *name, size_t namelen, const char *fmt, ...)
+{
+  *setnamep = setname;
+  *typep = type;
+
+  va_list ap;
+  va_start (ap, fmt);
+  int s = vsnprintf (name, namelen, fmt, ap);
+  va_end(ap);
+
+  if (s < 0 || (unsigned) s >= namelen)
+    return -1;
+  return s + 1;
+}
+
+ssize_t
+aarch64_register_info (Ebl *ebl __attribute__ ((unused)),
+		       int regno, char *name, size_t namelen,
+		       const char **prefix, const char **setnamep,
+		       int *bits, int *typep)
+{
+  if (name == NULL)
+    return 128;
+
+
+  *prefix = "";
+  *bits = 64;
+
+#define regtype(setname, type, ...) \
+    do_regtype(setname, type, setnamep, typep, name, namelen, __VA_ARGS__)
+
+  switch (regno)
+    {
+    case 0 ... 30:
+      return regtype ("integer", DW_ATE_signed, "x%d", regno);
+
+    case 31:
+      return regtype ("integer", DW_ATE_address, "sp");
+
+    case 32:
+      return 0;
+
+    case 33:
+      return regtype ("integer", DW_ATE_address, "elr");
+
+    case 34 ... 63:
+      return 0;
+
+    case 64 ... 95:
+      /* FP/SIMD register file supports a variety of data types--it
+	 can be thought of as a register holding a single integer or
+	 floating-point value, or a vector of 8-, 16-, 32- or 64-bit
+	 integers.  128-bit quad-word is the only singular value that
+	 covers the whole register, so mark the register thus.  */
+      *bits = 128;
+      return regtype ("FP/SIMD", DW_ATE_unsigned, "v%d", regno - 64);
+
+    case 96 ... 127:
+      return 0;
+
+    default:
+      return -1;
+    }
+}
diff --git a/third_party/elfutils/backends/aarch64_reloc.def b/third_party/elfutils/backends/aarch64_reloc.def
new file mode 100644
index 0000000..f894687
--- /dev/null
+++ b/third_party/elfutils/backends/aarch64_reloc.def
@@ -0,0 +1,157 @@
+/* List the relocation types for AArch64.  -*- C -*-
+   Copyright (C) 2013, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (ABS64,		REL|EXEC|DYN)
+RELOC_TYPE (ABS32,		REL|EXEC|DYN)
+RELOC_TYPE (COPY,		EXEC|DYN)
+RELOC_TYPE (GLOB_DAT,		EXEC|DYN)
+RELOC_TYPE (JUMP_SLOT,		EXEC|DYN)
+RELOC_TYPE (RELATIVE,		EXEC|DYN)
+RELOC_TYPE (TLS_DTPMOD,		EXEC|DYN)
+RELOC_TYPE (TLS_DTPREL,		EXEC|DYN)
+RELOC_TYPE (TLS_TPREL,		EXEC|DYN)
+RELOC_TYPE (TLSDESC,		EXEC|DYN)
+
+/* R_AARCH64_NONE records that the section containing the place to be
+   relocated depends on the section defining the symbol mentioned in
+   the relocation directive[.]  (ARM IHI 0056B).  */
+RELOC_TYPE (NONE,		REL)
+
+RELOC_TYPE (ABS16,		REL)
+RELOC_TYPE (PREL64,		REL)
+RELOC_TYPE (PREL32,		REL)
+RELOC_TYPE (PREL16,		REL)
+RELOC_TYPE (MOVW_UABS_G0,	REL)
+RELOC_TYPE (MOVW_UABS_G0_NC,	REL)
+RELOC_TYPE (MOVW_UABS_G1,	REL)
+RELOC_TYPE (MOVW_UABS_G1_NC,	REL)
+RELOC_TYPE (MOVW_UABS_G2,	REL)
+RELOC_TYPE (MOVW_UABS_G2_NC,	REL)
+RELOC_TYPE (MOVW_UABS_G3,	REL)
+RELOC_TYPE (MOVW_SABS_G0,	REL)
+RELOC_TYPE (MOVW_SABS_G1,	REL)
+RELOC_TYPE (MOVW_SABS_G2,	REL)
+RELOC_TYPE (LD_PREL_LO19,	REL)
+RELOC_TYPE (ADR_PREL_LO21,	REL)
+RELOC_TYPE (ADR_PREL_PG_HI21,	REL)
+RELOC_TYPE (ADR_PREL_PG_HI21_NC, REL)
+RELOC_TYPE (ADD_ABS_LO12_NC,	REL)
+RELOC_TYPE (LDST8_ABS_LO12_NC,	REL)
+RELOC_TYPE (LDST16_ABS_LO12_NC,	REL)
+RELOC_TYPE (LDST32_ABS_LO12_NC,	REL)
+RELOC_TYPE (LDST64_ABS_LO12_NC,	REL)
+RELOC_TYPE (LDST128_ABS_LO12_NC, REL)
+RELOC_TYPE (TSTBR14,		REL)
+RELOC_TYPE (CONDBR19,		REL)
+RELOC_TYPE (JUMP26,		REL)
+RELOC_TYPE (CALL26,		REL)
+RELOC_TYPE (MOVW_PREL_G0,	REL)
+RELOC_TYPE (MOVW_PREL_G0_NC,	REL)
+RELOC_TYPE (MOVW_PREL_G1,	REL)
+RELOC_TYPE (MOVW_PREL_G1_NC,	REL)
+RELOC_TYPE (MOVW_PREL_G2,	REL)
+RELOC_TYPE (MOVW_PREL_G2_NC,	REL)
+RELOC_TYPE (MOVW_PREL_G3,	REL)
+RELOC_TYPE (MOVW_GOTOFF_G0,	REL)
+RELOC_TYPE (MOVW_GOTOFF_G0_NC,	REL)
+RELOC_TYPE (MOVW_GOTOFF_G1,	REL)
+RELOC_TYPE (MOVW_GOTOFF_G1_NC,	REL)
+RELOC_TYPE (MOVW_GOTOFF_G2,	REL)
+RELOC_TYPE (MOVW_GOTOFF_G2_NC,	REL)
+RELOC_TYPE (MOVW_GOTOFF_G3,	REL)
+RELOC_TYPE (GOTREL64,		REL)
+RELOC_TYPE (GOTREL32,		REL)
+RELOC_TYPE (GOT_LD_PREL19,	REL)
+RELOC_TYPE (LD64_GOTOFF_LO15,	REL)
+RELOC_TYPE (ADR_GOT_PAGE,	REL)
+RELOC_TYPE (LD64_GOT_LO12_NC,	REL)
+RELOC_TYPE (LD64_GOTPAGE_LO15,	REL)
+RELOC_TYPE (TLSGD_ADR_PREL21,	REL)
+RELOC_TYPE (TLSGD_ADR_PAGE21,	REL)
+RELOC_TYPE (TLSGD_ADD_LO12_NC,	REL)
+RELOC_TYPE (TLSGD_MOVW_G1,	REL)
+RELOC_TYPE (TLSGD_MOVW_G0_NC,	REL)
+RELOC_TYPE (TLSLD_ADR_PREL21,	REL)
+RELOC_TYPE (TLSLD_ADR_PAGE21,	REL)
+RELOC_TYPE (TLSLD_ADD_LO12_NC,	REL)
+RELOC_TYPE (TLSLD_MOVW_G1,	REL)
+RELOC_TYPE (TLSLD_MOVW_G0_NC,	REL)
+RELOC_TYPE (TLSLD_LD_PREL19,	REL)
+RELOC_TYPE (TLSLD_MOVW_DTPREL_G2,	REL)
+RELOC_TYPE (TLSLD_MOVW_DTPREL_G1,	REL)
+RELOC_TYPE (TLSLD_MOVW_DTPREL_G1_NC,	REL)
+RELOC_TYPE (TLSLD_MOVW_DTPREL_G0,	REL)
+RELOC_TYPE (TLSLD_MOVW_DTPREL_G0_NC,	REL)
+RELOC_TYPE (TLSLD_ADD_DTPREL_HI12,	REL)
+RELOC_TYPE (TLSLD_ADD_DTPREL_LO12,	REL)
+RELOC_TYPE (TLSLD_ADD_DTPREL_LO12_NC,	REL)
+RELOC_TYPE (TLSLD_LDST8_DTPREL_LO12,	REL)
+RELOC_TYPE (TLSLD_LDST8_DTPREL_LO12_NC,	REL)
+RELOC_TYPE (TLSLD_LDST16_DTPREL_LO12,	REL)
+RELOC_TYPE (TLSLD_LDST16_DTPREL_LO12_NC, REL)
+RELOC_TYPE (TLSLD_LDST32_DTPREL_LO12,	REL)
+RELOC_TYPE (TLSLD_LDST32_DTPREL_LO12_NC, REL)
+RELOC_TYPE (TLSLD_LDST64_DTPREL_LO12,	REL)
+RELOC_TYPE (TLSLD_LDST64_DTPREL_LO12_NC, REL)
+RELOC_TYPE (TLSLD_LDST128_DTPREL_LO12,	REL)
+RELOC_TYPE (TLSLD_LDST128_DTPREL_LO12_NC, REL)
+RELOC_TYPE (TLSIE_MOVW_GOTTPREL_G1,	REL)
+RELOC_TYPE (TLSIE_MOVW_GOTTPREL_G0_NC,	REL)
+RELOC_TYPE (TLSIE_ADR_GOTTPREL_PAGE21,	REL)
+RELOC_TYPE (TLSIE_LD64_GOTTPREL_LO12_NC, REL)
+RELOC_TYPE (TLSIE_LD_GOTTPREL_PREL19,	REL)
+RELOC_TYPE (TLSLE_MOVW_TPREL_G2,	REL)
+RELOC_TYPE (TLSLE_MOVW_TPREL_G1,	REL)
+RELOC_TYPE (TLSLE_MOVW_TPREL_G1_NC,	REL)
+RELOC_TYPE (TLSLE_MOVW_TPREL_G0,	REL)
+RELOC_TYPE (TLSLE_MOVW_TPREL_G0_NC,	REL)
+RELOC_TYPE (TLSLE_ADD_TPREL_HI12,	REL)
+RELOC_TYPE (TLSLE_ADD_TPREL_LO12,	REL)
+RELOC_TYPE (TLSLE_ADD_TPREL_LO12_NC,	REL)
+RELOC_TYPE (TLSLE_LDST8_TPREL_LO12,	REL)
+RELOC_TYPE (TLSLE_LDST8_TPREL_LO12_NC,	REL)
+RELOC_TYPE (TLSLE_LDST16_TPREL_LO12,	REL)
+RELOC_TYPE (TLSLE_LDST16_TPREL_LO12_NC,	REL)
+RELOC_TYPE (TLSLE_LDST32_TPREL_LO12,	REL)
+RELOC_TYPE (TLSLE_LDST32_TPREL_LO12_NC,	REL)
+RELOC_TYPE (TLSLE_LDST64_TPREL_LO12,	REL)
+RELOC_TYPE (TLSLE_LDST64_TPREL_LO12_NC,	REL)
+RELOC_TYPE (TLSLE_LDST128_TPREL_LO12,	REL)
+RELOC_TYPE (TLSLE_LDST128_TPREL_LO12_NC, REL)
+RELOC_TYPE (TLSDESC_LD_PREL19,		REL)
+RELOC_TYPE (TLSDESC_ADR_PREL21,		REL)
+RELOC_TYPE (TLSDESC_ADR_PAGE21,		REL)
+RELOC_TYPE (TLSDESC_LD64_LO12,		REL)
+RELOC_TYPE (TLSDESC_ADD_LO12,		REL)
+RELOC_TYPE (TLSDESC_OFF_G1,		REL)
+RELOC_TYPE (TLSDESC_OFF_G0_NC,		REL)
+RELOC_TYPE (TLSDESC_LDR,		REL)
+RELOC_TYPE (TLSDESC_ADD,		REL)
+RELOC_TYPE (TLSDESC_CALL,		REL)
diff --git a/third_party/elfutils/backends/aarch64_retval.c b/third_party/elfutils/backends/aarch64_retval.c
new file mode 100644
index 0000000..1308340
--- /dev/null
+++ b/third_party/elfutils/backends/aarch64_retval.c
@@ -0,0 +1,376 @@
+/* Function return value location for Linux/AArch64 ABI.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND aarch64_
+#include "libebl_CPU.h"
+
+static int
+skip_until (Dwarf_Die *child, int tag)
+{
+  int i;
+  while (DWARF_TAG_OR_RETURN (child) != tag)
+    if ((i = dwarf_siblingof (child, child)) != 0)
+      /* If there are no members, then this is not a HFA.  Errors
+	 are propagated.  */
+      return i;
+  return 0;
+}
+
+static int
+dwarf_bytesize_aux (Dwarf_Die *die, Dwarf_Word *sizep)
+{
+  int bits;
+  if (((bits = 8 * dwarf_bytesize (die)) < 0
+       && (bits = dwarf_bitsize (die)) < 0)
+      || bits % 8 != 0)
+    return -1;
+
+  *sizep = bits / 8;
+  return 0;
+}
+
+/* HFA (Homogeneous Floating-point Aggregate) is an aggregate type
+   whose members are all of the same floating-point type, which is
+   then base type of this HFA.  Instead of being floating-point types
+   directly, members can instead themselves be HFA.  Such HFA fields
+   are handled as if their type were HFA base type.
+
+   This function returns 0 if TYPEDIE is HFA, 1 if it is not, or -1 if
+   there were errors.  In the former case, *SIZEP contains byte size
+   of the base type (e.g. 8 for IEEE double).  *COUNT is set to the
+   number of leaf members of the HFA.  */
+static int hfa_type (Dwarf_Die *ftypedie, int tag,
+		     Dwarf_Word *sizep, Dwarf_Word *countp);
+
+/* Return 0 if MEMBDIE refers to a member with a floating-point or HFA
+   type, or 1 if it's not.  Return -1 for errors.  The meaning of the
+   remaining arguments is as documented at hfa_type.  */
+static int
+member_is_fp (Dwarf_Die *membdie, Dwarf_Word *sizep, Dwarf_Word *countp)
+{
+  Dwarf_Die typedie;
+  int tag = dwarf_peeled_die_type (membdie, &typedie);
+  switch (tag)
+    {
+    case DW_TAG_base_type:;
+      Dwarf_Word encoding;
+      Dwarf_Attribute attr_mem;
+      if (dwarf_attr_integrate (&typedie, DW_AT_encoding, &attr_mem) == NULL
+	  || dwarf_formudata (&attr_mem, &encoding) != 0)
+	return -1;
+
+      switch (encoding)
+	{
+	case DW_ATE_complex_float:
+	  *countp = 2;
+	  break;
+
+	case DW_ATE_float:
+	  *countp = 1;
+	  break;
+
+	default:
+	  return 1;
+	}
+
+      if (dwarf_bytesize_aux (&typedie, sizep) < 0)
+	return -1;
+
+      *sizep /= *countp;
+      return 0;
+
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_array_type:
+      return hfa_type (&typedie, tag, sizep, countp);
+    }
+
+  return 1;
+}
+
+static int
+hfa_type (Dwarf_Die *ftypedie, int tag, Dwarf_Word *sizep, Dwarf_Word *countp)
+{
+  assert (tag == DW_TAG_structure_type || tag == DW_TAG_class_type
+	  || tag == DW_TAG_union_type || tag == DW_TAG_array_type);
+
+  int i;
+  if (tag == DW_TAG_array_type)
+    {
+      Dwarf_Word tot_size;
+      if (dwarf_aggregate_size (ftypedie, &tot_size) < 0)
+	return -1;
+
+      /* For vector types, we don't care about the underlying
+	 type, but only about the vector type itself.  */
+      bool vec;
+      Dwarf_Attribute attr_mem;
+      if (dwarf_formflag (dwarf_attr_integrate (ftypedie, DW_AT_GNU_vector,
+						&attr_mem), &vec) == 0
+	  && vec)
+	{
+	  *sizep = tot_size;
+	  *countp = 1;
+
+	  return 0;
+	}
+
+      if ((i = member_is_fp (ftypedie, sizep, countp)) == 0)
+	{
+	  *countp = tot_size / *sizep;
+	  return 0;
+	}
+
+      return i;
+    }
+
+  /* Find first DW_TAG_member and determine its type.  */
+  Dwarf_Die member;
+  if ((i = dwarf_child (ftypedie, &member) != 0))
+    return i;
+
+  if ((i = skip_until (&member, DW_TAG_member)) != 0)
+    return i;
+
+  *countp = 0;
+  if ((i = member_is_fp (&member, sizep, countp)) != 0)
+    return i;
+
+  while ((i = dwarf_siblingof (&member, &member)) == 0
+	 && (i = skip_until (&member, DW_TAG_member)) == 0)
+    {
+      Dwarf_Word size, count;
+      if ((i = member_is_fp (&member, &size, &count)) != 0)
+	return i;
+
+      if (*sizep != size)
+	return 1;
+
+      *countp += count;
+    }
+
+  /* At this point we already have at least one FP member, which means
+     FTYPEDIE is an HFA.  So either return 0, or propagate error.  */
+  return i < 0 ? i : 0;
+}
+
+static int
+pass_in_gpr (const Dwarf_Op **locp, Dwarf_Word size)
+{
+  static const Dwarf_Op loc[] =
+    {
+      { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 8 },
+      { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 8 }
+    };
+
+  *locp = loc;
+  return size <= 8 ? 1 : 4;
+}
+
+static int
+pass_by_ref (const Dwarf_Op **locp)
+{
+  static const Dwarf_Op loc[] = { { .atom = DW_OP_breg0 } };
+
+  *locp = loc;
+  return 1;
+}
+
+static int
+pass_hfa (const Dwarf_Op **locp, Dwarf_Word size, Dwarf_Word count)
+{
+  assert (count >= 1 && count <= 4);
+  assert (size == 2 || size == 4 || size == 8 || size == 16);
+
+#define DEFINE_FPREG(NAME, SIZE)		\
+  static const Dwarf_Op NAME[] = {		\
+    { .atom = DW_OP_regx, .number = 64 },	\
+    { .atom = DW_OP_piece, .number = SIZE },	\
+    { .atom = DW_OP_regx, .number = 65 },	\
+    { .atom = DW_OP_piece, .number = SIZE },	\
+    { .atom = DW_OP_regx, .number = 66 },	\
+    { .atom = DW_OP_piece, .number = SIZE },	\
+    { .atom = DW_OP_regx, .number = 67 },	\
+    { .atom = DW_OP_piece, .number = SIZE }	\
+  }
+
+  switch (size)
+    {
+    case 2:;
+      DEFINE_FPREG (loc_hfa_2, 2);
+      *locp = loc_hfa_2;
+      break;
+
+    case 4:;
+      DEFINE_FPREG (loc_hfa_4, 4);
+      *locp = loc_hfa_4;
+      break;
+
+    case 8:;
+      DEFINE_FPREG (loc_hfa_8, 8);
+      *locp = loc_hfa_8;
+      break;
+
+    case 16:;
+      DEFINE_FPREG (loc_hfa_16, 16);
+      *locp = loc_hfa_16;
+      break;
+    }
+#undef DEFINE_FPREG
+
+  return count == 1 ? 1 : 2 * count;
+}
+
+static int
+pass_in_simd (const Dwarf_Op **locp)
+{
+  /* This is like passing single-element HFA.  Size doesn't matter, so
+     pretend it's for example double.  */
+  return pass_hfa (locp, 8, 1);
+}
+
+int
+aarch64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die typedie;
+  int tag = dwarf_peeled_die_type (functypedie, &typedie);
+  if (tag <= 0)
+    return tag;
+
+  Dwarf_Word size = (Dwarf_Word)-1;
+
+  /* If the argument type is a Composite Type that is larger than 16
+     bytes, then the argument is copied to memory allocated by the
+     caller and the argument is replaced by a pointer to the copy.  */
+  if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type
+      || tag == DW_TAG_class_type || tag == DW_TAG_array_type)
+    {
+      Dwarf_Word base_size, count;
+      switch (hfa_type (&typedie, tag, &base_size, &count))
+	{
+	default:
+	  return -1;
+
+	case 0:
+	  assert (count > 0);
+	  if (count <= 4)
+	    return pass_hfa (locp, base_size, count);
+	  FALLTHROUGH;
+
+	case 1:
+	  /* Not a HFA.  */
+	  if (dwarf_aggregate_size (&typedie, &size) < 0)
+	    return -1;
+	  if (size > 16)
+	    return pass_by_ref (locp);
+	}
+    }
+
+  if (tag == DW_TAG_base_type
+      || tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+    {
+      if (dwarf_bytesize_aux (&typedie, &size) < 0)
+	{
+	  if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	    size = 8;
+	  else
+	    return -1;
+	}
+
+      Dwarf_Attribute attr_mem;
+      if (tag == DW_TAG_base_type)
+	{
+	  Dwarf_Word encoding;
+	  if (dwarf_formudata (dwarf_attr_integrate (&typedie, DW_AT_encoding,
+						     &attr_mem),
+			       &encoding) != 0)
+	    return -1;
+
+	  switch (encoding)
+	    {
+	      /* If the argument is a Half-, Single-, Double- or Quad-
+		 precision Floating-point [...] the argument is allocated
+		 to the least significant bits of register v[NSRN].  */
+	    case DW_ATE_float:
+	      switch (size)
+		{
+		case 2: /* half */
+		case 4: /* sigle */
+		case 8: /* double */
+		case 16: /* quad */
+		  return pass_in_simd (locp);
+
+		default:
+		  return -2;
+		}
+
+	    case DW_ATE_complex_float:
+	      switch (size)
+		{
+		case 8: /* float _Complex */
+		case 16: /* double _Complex */
+		case 32: /* long double _Complex */
+		  return pass_hfa (locp, size / 2, 2);
+
+		default:
+		  return -2;
+		}
+
+	      /* If the argument is an Integral or Pointer Type, the
+		 size of the argument is less than or equal to 8 bytes
+		 [...] the argument is copied to the least significant
+		 bits in x[NGRN].  */
+	    case DW_ATE_boolean:
+	    case DW_ATE_signed:
+	    case DW_ATE_unsigned:
+	    case DW_ATE_unsigned_char:
+	    case DW_ATE_signed_char:
+	      return pass_in_gpr (locp, size);
+	    }
+
+	  return -2;
+	}
+      else
+	return pass_in_gpr (locp, size);
+    }
+
+  *locp = NULL;
+  return 0;
+}
diff --git a/third_party/elfutils/backends/aarch64_symbol.c b/third_party/elfutils/backends/aarch64_symbol.c
new file mode 100644
index 0000000..da3382e
--- /dev/null
+++ b/third_party/elfutils/backends/aarch64_symbol.c
@@ -0,0 +1,104 @@
+/* AArch64 specific symbolic name handling.
+   Copyright (C) 2013, 2015, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND		aarch64_
+#include "libebl_CPU.h"
+
+
+/* Check for the simple reloc types.  */
+Elf_Type
+aarch64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_AARCH64_ABS64:
+      return ELF_T_XWORD;
+    case R_AARCH64_ABS32:
+      return ELF_T_WORD;
+    case R_AARCH64_ABS16:
+      return ELF_T_HALF;
+
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+/* If this is the _GLOBAL_OFFSET_TABLE_ symbol, then it should point in
+   the .got even if there is a .got.plt section.
+   https://sourceware.org/ml/libc-ports/2013-06/msg00057.html
+   https://bugzilla.redhat.com/show_bug.cgi?id=1201778
+ */
+bool
+aarch64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym,
+                              const char *name, const GElf_Shdr *destshdr)
+{
+  if (name != NULL
+      && strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
+    {
+      const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name);
+      if (sname != NULL
+	  && (strcmp (sname, ".got") == 0 || strcmp (sname, ".got.plt") == 0))
+	{
+	  Elf_Scn *scn = NULL;
+	  while ((scn = elf_nextscn (elf, scn)) != NULL)
+	    {
+	      GElf_Shdr shdr_mem;
+	      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	      if (shdr != NULL)
+		{
+		  sname = elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name);
+		  if (sname != NULL && strcmp (sname, ".got") == 0)
+		    return (sym->st_value >= shdr->sh_addr
+			    && sym->st_value < shdr->sh_addr + shdr->sh_size);
+		}
+	    }
+	}
+    }
+
+  return false;
+}
+
+/* A data mapping symbol is a symbol with "$d" name or "$d.<any...>" name,
+   STT_NOTYPE, STB_LOCAL and st_size of zero. The indicate the stat of a
+   sequence of data items.  */
+bool
+aarch64_data_marker_symbol (const GElf_Sym *sym, const char *sname)
+{
+  return (sym != NULL && sname != NULL
+	  && sym->st_size == 0 && GELF_ST_BIND (sym->st_info) == STB_LOCAL
+	  && GELF_ST_TYPE (sym->st_info) == STT_NOTYPE
+	  && (strcmp (sname, "$d") == 0 || strncmp (sname, "$d.", 3) == 0));
+}
diff --git a/third_party/elfutils/backends/aarch64_unwind.c b/third_party/elfutils/backends/aarch64_unwind.c
new file mode 100644
index 0000000..e0a7e96
--- /dev/null
+++ b/third_party/elfutils/backends/aarch64_unwind.c
@@ -0,0 +1,83 @@
+/* Get previous frame state for an existing frame state.
+   Copyright (C) 2016 The Qt Company Ltd.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND aarch64_
+#define FP_REG 29
+#define LR_REG 30
+#define SP_REG 31
+#define FP_OFFSET 0
+#define LR_OFFSET 8
+#define SP_OFFSET 16
+
+#include "libebl_CPU.h"
+
+/* There was no CFI. Maybe we happen to have a frame pointer and can unwind from that?  */
+
+bool
+EBLHOOK(unwind) (Ebl *ebl __attribute__ ((unused)), Dwarf_Addr pc __attribute__ ((unused)),
+                 ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc,
+                 ebl_pid_memory_read_t *readfunc, void *arg,
+                 bool *signal_framep __attribute__ ((unused)))
+{
+  Dwarf_Word fp, lr, sp;
+
+  if (!getfunc(LR_REG, 1, &lr, arg))
+    return false;
+
+  if (lr == 0 || !setfunc(-1, 1, &lr, arg))
+    return false;
+
+  if (!getfunc(FP_REG, 1, &fp, arg))
+    fp = 0;
+
+  if (!getfunc(SP_REG, 1, &sp, arg))
+    sp = 0;
+
+  Dwarf_Word newLr, newFp, newSp;
+
+  if (!readfunc(fp + LR_OFFSET, &newLr, arg))
+    newLr = 0;
+
+  if (!readfunc(fp + FP_OFFSET, &newFp, arg))
+    newFp = 0;
+
+  newSp = fp + SP_OFFSET;
+
+  // These are not fatal if they don't work. They will just prevent unwinding at the next frame.
+  setfunc(LR_REG, 1, &newLr, arg);
+  setfunc(FP_REG, 1, &newFp, arg);
+  setfunc(SP_REG, 1, &newSp, arg);
+
+  // If the fp is invalid, we might still have a valid lr.
+  // But if the fp is valid, then the stack should be moving in the right direction.
+  return fp == 0 || newSp > sp;
+}
diff --git a/third_party/elfutils/backends/alpha_auxv.c b/third_party/elfutils/backends/alpha_auxv.c
new file mode 100644
index 0000000..83e7199
--- /dev/null
+++ b/third_party/elfutils/backends/alpha_auxv.c
@@ -0,0 +1,49 @@
+/* Alpha-specific auxv handling.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND alpha_
+#include "libebl_CPU.h"
+
+int
+EBLHOOK(auxv_info) (GElf_Xword a_type, const char **name, const char **format)
+{
+  if (a_type != AT_HWCAP)
+    return 0;
+
+  *name = "HWCAP";
+  *format = "b"
+    "bwx\0" "fix\0" "cix\0" "0x08\0"
+    "0x10\0" "0x20\0" "0x40\0" "0x80\0"
+    "max\0" "precise_trap\0"
+    "\0";
+  return 1;
+}
diff --git a/third_party/elfutils/backends/alpha_corenote.c b/third_party/elfutils/backends/alpha_corenote.c
new file mode 100644
index 0000000..6190df3
--- /dev/null
+++ b/third_party/elfutils/backends/alpha_corenote.c
@@ -0,0 +1,70 @@
+/* PowerPC specific core note handling.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND	alpha_
+#include "libebl_CPU.h"
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+    { .offset = 0, .regno = 0, .count = 31, .bits = 64 }, /* r0-r30 */
+    { .offset = 32 * 8, .regno = 64, .count = 1, .bits = 64 }, /* pc */
+    { .offset = 33 * 8, .regno = 66, .count = 1, .bits = 64 }, /* unique */
+  };
+#define PRSTATUS_REGS_SIZE	(33 * 8)
+
+static const Ebl_Register_Location fpregset_regs[] =
+  {
+    { .offset = 0, .regno = 32, .count = 32, .bits = 64 }, /* f0-f30, fpcr */
+  };
+#define FPREGSET_SIZE		(32 * 8)
+
+#define ULONG			uint64_t
+#define ALIGN_ULONG		8
+#define TYPE_ULONG		ELF_T_XWORD
+#define TYPE_LONG		ELF_T_SXWORD
+#define PID_T			int32_t
+#define	UID_T			uint32_t
+#define	GID_T			uint32_t
+#define ALIGN_PID_T		4
+#define ALIGN_UID_T		4
+#define ALIGN_GID_T		4
+#define TYPE_PID_T		ELF_T_SWORD
+#define TYPE_UID_T		ELF_T_WORD
+#define TYPE_GID_T		ELF_T_WORD
+
+#include "linux-core-note.c"
diff --git a/third_party/elfutils/backends/alpha_init.c b/third_party/elfutils/backends/alpha_init.c
new file mode 100644
index 0000000..25c5b32
--- /dev/null
+++ b/third_party/elfutils/backends/alpha_init.c
@@ -0,0 +1,69 @@
+/* Initialization of Alpha specific backend library.
+   Copyright (C) 2002-2011 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		alpha_
+#define RELOC_PREFIX	R_ALPHA_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on alpha_reloc.def.  */
+#include "common-reloc.c"
+
+
+const char *
+alpha_init (Elf *elf __attribute__ ((unused)),
+	    GElf_Half machine __attribute__ ((unused)),
+	    Ebl *eh,
+	    size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "Alpha";
+  alpha_init_reloc (eh);
+  HOOK (eh, dynamic_tag_name);
+  HOOK (eh, dynamic_tag_check);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, return_value_location);
+  HOOK (eh, machine_section_flag_check);
+  HOOK (eh, check_special_section);
+  HOOK (eh, check_special_symbol);
+  HOOK (eh, check_st_other_bits);
+  HOOK (eh, register_info);
+  HOOK (eh, core_note);
+  HOOK (eh, auxv_info);
+  eh->sysvhash_entrysize = sizeof (Elf64_Xword);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/alpha_regs.c b/third_party/elfutils/backends/alpha_regs.c
new file mode 100644
index 0000000..436af3b
--- /dev/null
+++ b/third_party/elfutils/backends/alpha_regs.c
@@ -0,0 +1,164 @@
+/* Register names and numbers for Alpha DWARF.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND alpha_
+#include "libebl_CPU.h"
+
+ssize_t
+alpha_register_info (Ebl *ebl __attribute__ ((unused)),
+		     int regno, char *name, size_t namelen,
+		     const char **prefix, const char **setname,
+		     int *bits, int *type)
+{
+  if (name == NULL)
+    return 67;
+
+  if (regno < 0 || regno > 66 || namelen < 7)
+    return -1;
+
+  *prefix = "$";
+
+  *bits = 64;
+  *type = DW_ATE_signed;
+  *setname = "integer";
+  if (regno >= 32 && regno < 64)
+    {
+      *setname = "FPU";
+      *type = DW_ATE_float;
+    }
+
+  switch (regno)
+    {
+    case 0:
+      name[0] = 'v';
+      name[1] = '0';
+      namelen = 2;
+      break;
+
+    case 1 ... 8:
+      name[0] = 't';
+      name[1] = regno - 1 + '0';
+      namelen = 2;
+      break;
+
+    case 9 ... 15:
+      name[0] = 's';
+      name[1] = regno - 9 + '0';
+      namelen = 2;
+      break;
+
+    case 16 ... 21:
+      name[0] = 'a';
+      name[1] = regno - 16 + '0';
+      namelen = 2;
+      break;
+
+    case 22 ... 23:
+      name[0] = 't';
+      name[1] = regno - 22 + '8';
+      namelen = 2;
+      break;
+
+    case 24 ... 25:
+      name[0] = 't';
+      name[1] = '1';
+      name[2] = regno - 24 + '0';
+      namelen = 3;
+      break;
+
+    case 26:
+      *type = DW_ATE_address;
+      return stpcpy (name, "ra") + 1 - name;
+
+    case 27:
+      return stpcpy (name, "t12") + 1 - name;
+
+    case 28:
+      return stpcpy (name, "at") + 1 - name;
+
+    case 29:
+      *type = DW_ATE_address;
+      return stpcpy (name, "gp") + 1 - name;
+
+    case 30:
+      *type = DW_ATE_address;
+      return stpcpy (name, "sp") + 1 - name;
+
+    case 31:
+      return stpcpy (name, "zero") + 1 - name;
+
+    case 32 ... 32 + 9:
+      name[0] = 'f';
+      name[1] = regno - 32 + '0';
+      namelen = 2;
+      break;
+
+    case 32 + 10 ... 32 + 19:
+      name[0] = 'f';
+      name[1] = '1';
+      name[2] = regno - 32 - 10 + '0';
+      namelen = 3;
+      break;
+
+    case 32 + 20 ... 32 + 29:
+      name[0] = 'f';
+      name[1] = '2';
+      name[2] = regno - 32 - 20 + '0';
+      namelen = 3;
+      break;
+
+    case 32 + 30:
+      return stpcpy (name, "f30") + 1 - name;
+
+    case 32 + 31:
+      *type = DW_ATE_unsigned;
+      return stpcpy (name, "fpcr") + 1 - name;
+
+    case 64:
+      *type = DW_ATE_address;
+      return stpcpy (name, "pc") + 1 - name;
+
+    case 66:
+      *type = DW_ATE_address;
+      return stpcpy (name, "unique") + 1 - name;
+
+    default:
+      *setname = NULL;
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
diff --git a/third_party/elfutils/backends/alpha_reloc.def b/third_party/elfutils/backends/alpha_reloc.def
new file mode 100644
index 0000000..ed7e5c3
--- /dev/null
+++ b/third_party/elfutils/backends/alpha_reloc.def
@@ -0,0 +1,63 @@
+/* List the relocation types for alpha.  -*- C -*-
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,		0)
+RELOC_TYPE (REFLONG,		REL|EXEC|DYN)
+RELOC_TYPE (REFQUAD,		REL|EXEC|DYN)
+RELOC_TYPE (GPREL32,		REL)
+RELOC_TYPE (LITERAL,		REL)
+RELOC_TYPE (LITUSE,		REL)
+RELOC_TYPE (GPDISP,		REL)
+RELOC_TYPE (BRADDR,		REL)
+RELOC_TYPE (HINT,		REL)
+RELOC_TYPE (SREL16,		REL)
+RELOC_TYPE (SREL32,		REL)
+RELOC_TYPE (SREL64,		REL)
+RELOC_TYPE (GPRELHIGH,		REL)
+RELOC_TYPE (GPRELLOW,		REL)
+RELOC_TYPE (GPREL16,		REL)
+RELOC_TYPE (COPY,		0)
+RELOC_TYPE (GLOB_DAT,		EXEC|DYN)
+RELOC_TYPE (JMP_SLOT,		EXEC|DYN)
+RELOC_TYPE (RELATIVE,		EXEC|DYN)
+RELOC_TYPE (TLS_GD_HI,		REL)
+RELOC_TYPE (TLSGD,		REL)
+RELOC_TYPE (TLS_LDM,		REL)
+RELOC_TYPE (DTPMOD64,		REL|EXEC|DYN)
+RELOC_TYPE (GOTDTPREL,		REL)
+RELOC_TYPE (DTPREL64,		REL|EXEC|DYN)
+RELOC_TYPE (DTPRELHI,		REL)
+RELOC_TYPE (DTPRELLO,		REL)
+RELOC_TYPE (DTPREL16,		REL)
+RELOC_TYPE (GOTTPREL,		REL)
+RELOC_TYPE (TPREL64,		REL|EXEC|DYN)
+RELOC_TYPE (TPRELHI,		REL)
+RELOC_TYPE (TPRELLO,		REL)
+RELOC_TYPE (TPREL16,		REL)
diff --git a/third_party/elfutils/backends/alpha_retval.c b/third_party/elfutils/backends/alpha_retval.c
new file mode 100644
index 0000000..d9bae3b
--- /dev/null
+++ b/third_party/elfutils/backends/alpha_retval.c
@@ -0,0 +1,150 @@
+/* Function return value location for Alpha ELF ABI.
+   Copyright (C) 2005, 2007, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND alpha_
+#include "libebl_CPU.h"
+
+
+/* $0.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg0 }
+  };
+#define nloc_intreg	1
+
+/* $f0, or pair $f0, $f1.  */
+static const Dwarf_Op loc_fpreg[] =
+  {
+    { .atom = DW_OP_regx, .number = 32 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_regx, .number = 33 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+#define nloc_fpreg	1
+#define nloc_fpregpair	4
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in $0.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_breg0, .number = 0 }
+  };
+#define nloc_aggregate 1
+
+int
+alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Attribute attr_mem;
+	Dwarf_Word size;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+						   &attr_mem), &size) != 0)
+	  {
+	    if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	      size = 8;
+	    else
+	      return -1;
+	  }
+	if (tag == DW_TAG_base_type)
+	  {
+	    Dwarf_Word encoding;
+	    if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+						       &attr_mem),
+				 &encoding) != 0)
+	      return -1;
+
+	    *locp = loc_fpreg;
+	    if (encoding == DW_ATE_float)
+	      {
+		if (size <= 8)
+		  return nloc_fpreg;
+		goto aggregate;
+	      }
+	    if (encoding == DW_ATE_complex_float)
+	      {
+		if (size <= 8 * 2)
+		  return nloc_fpregpair;
+		goto aggregate;
+	      }
+	  }
+	if (size <= 8)
+	  {
+	    *locp = loc_intreg;
+	    return nloc_intreg;
+	  }
+      }
+
+      FALLTHROUGH;
+
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+    case DW_TAG_string_type:
+    case DW_TAG_array_type:
+    aggregate:
+      *locp = loc_aggregate;
+      return nloc_aggregate;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/alpha_symbol.c b/third_party/elfutils/backends/alpha_symbol.c
new file mode 100644
index 0000000..657d9ee
--- /dev/null
+++ b/third_party/elfutils/backends/alpha_symbol.c
@@ -0,0 +1,156 @@
+/* Alpha specific symbolic name handling.
+   Copyright (C) 2002-2011 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND		alpha_
+#include "libebl_CPU.h"
+
+
+const char *
+alpha_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+			size_t len __attribute__ ((unused)))
+{
+  switch (tag)
+    {
+    case DT_ALPHA_PLTRO:
+      return "ALPHA_PLTRO";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+bool
+alpha_dynamic_tag_check (int64_t tag)
+{
+  return tag == DT_ALPHA_PLTRO;
+}
+
+/* Check for the simple reloc types.  */
+Elf_Type
+alpha_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_ALPHA_REFLONG:
+      return ELF_T_WORD;
+    case R_ALPHA_REFQUAD:
+      return ELF_T_XWORD;
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+
+/* Check whether SHF_MASKPROC flags are valid.  */
+bool
+alpha_machine_section_flag_check (GElf_Xword sh_flags)
+{
+  return (sh_flags &~ (SHF_ALPHA_GPREL)) == 0;
+}
+
+bool
+alpha_check_special_section (Ebl *ebl,
+			     int ndx __attribute__ ((unused)),
+			     const GElf_Shdr *shdr,
+			     const char *sname __attribute__ ((unused)))
+{
+  if ((shdr->sh_flags
+       & (SHF_WRITE | SHF_EXECINSTR)) == (SHF_WRITE | SHF_EXECINSTR)
+      && shdr->sh_addr != 0)
+    {
+      /* This is ordinarily flagged, but is valid for an old-style PLT.
+
+	 Look for the SHT_DYNAMIC section and the DT_PLTGOT tag in it.
+	 Its d_ptr should match the .plt section's sh_addr.  */
+
+      Elf_Scn *scn = NULL;
+      while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+	{
+	  GElf_Shdr scn_shdr;
+	  if (likely (gelf_getshdr (scn, &scn_shdr) != NULL)
+	      && scn_shdr.sh_type == SHT_DYNAMIC
+	      && scn_shdr.sh_entsize != 0)
+	    {
+	      GElf_Addr pltgot = 0;
+	      Elf_Data *data = elf_getdata (scn, NULL);
+	      if (data != NULL)
+		for (size_t i = 0; i < data->d_size / scn_shdr.sh_entsize; ++i)
+		  {
+		    GElf_Dyn dyn;
+		    if (unlikely (gelf_getdyn (data, i, &dyn) == NULL))
+		      break;
+		    if (dyn.d_tag == DT_PLTGOT)
+		      pltgot = dyn.d_un.d_ptr;
+		    else if (dyn.d_tag == DT_ALPHA_PLTRO && dyn.d_un.d_val != 0)
+		      return false; /* This PLT should not be writable.  */
+		  }
+	      return pltgot == shdr->sh_addr;
+	    }
+	}
+    }
+
+  return false;
+}
+
+/* Check whether given symbol's st_value and st_size are OK despite failing
+   normal checks.  */
+bool
+alpha_check_special_symbol (Elf *elf __attribute__ ((unused)),
+			    GElf_Ehdr *ehdr __attribute__ ((unused)),
+			    const GElf_Sym *sym __attribute__ ((unused)),
+			    const char *name,
+			    const GElf_Shdr *destshdr __attribute__ ((unused)))
+{
+  if (name == NULL)
+    return false;
+
+  if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
+    /* On Alpha any place in the section is valid.  */
+    return true;
+
+  return false;
+}
+
+/* Check whether only valid bits are set on the st_other symbol flag.
+   Standard ST_VISIBILITY have already been masked off.  */
+bool
+alpha_check_st_other_bits (unsigned char st_other)
+{
+  return ((((st_other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_NOPV)
+	   || ((st_other & STO_ALPHA_STD_GPLOAD) == STO_ALPHA_STD_GPLOAD))
+	  && (st_other &~ STO_ALPHA_STD_GPLOAD) == 0);
+}
diff --git a/third_party/elfutils/backends/arm_attrs.c b/third_party/elfutils/backends/arm_attrs.c
new file mode 100644
index 0000000..6842b77
--- /dev/null
+++ b/third_party/elfutils/backends/arm_attrs.c
@@ -0,0 +1,241 @@
+/* Object attribute tags for ARM.
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND arm_
+#include "libebl_CPU.h"
+
+#define KNOWN_VALUES(...) do				\
+  {							\
+    static const char *table[] = { __VA_ARGS__ };	\
+    if (value < sizeof table / sizeof table[0])		\
+      *value_name = table[value];			\
+  } while (0)
+
+bool
+arm_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
+			    const char *vendor, int tag, uint64_t value,
+			    const char **tag_name, const char **value_name)
+{
+  if (!strcmp (vendor, "aeabi"))
+    switch (tag)
+      {
+      case 4:
+	*tag_name = "CPU_raw_name";
+	return true;
+      case 5:
+	*tag_name = "CPU_name";
+	return true;
+      case 6:
+	*tag_name = "CPU_arch";
+	KNOWN_VALUES ("Pre-v4",
+		      "v4",
+		      "v4T",
+		      "v5T",
+		      "v5TE",
+		      "v5TEJ",
+		      "v6",
+		      "v6KZ",
+		      "v6T2",
+		      "v6K",
+		      "v7",
+		      "v6-M",
+		      "v6S-M");
+	return true;
+      case 7:
+	*tag_name = "CPU_arch_profile";
+	switch (value)
+	  {
+	  case 'A':
+	    *value_name = "Application";
+	    break;
+	  case 'R':
+	    *value_name = "Realtime";
+	    break;
+	  case 'M':
+	    *value_name = "Microcontroller";
+	    break;
+	  }
+	return true;
+      case 8:
+	*tag_name = "ARM_ISA_use";
+	KNOWN_VALUES ("No", "Yes");
+	return true;
+      case 9:
+	*tag_name = "THUMB_ISA_use";
+	KNOWN_VALUES ("No", "Thumb-1", "Thumb-2");
+	return true;
+      case 10:
+	*tag_name = "VFP_arch";
+	KNOWN_VALUES ("No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16");
+	return true;
+      case 11:
+	*tag_name = "WMMX_arch";
+	KNOWN_VALUES ("No", "WMMXv1", "WMMXv2");
+	return true;
+      case 12:
+	*tag_name = "Advanced_SIMD_arch";
+	KNOWN_VALUES ("No", "NEONv1");
+	return true;
+      case 13:
+	*tag_name = "PCS_config";
+	KNOWN_VALUES ("None",
+		      "Bare platform",
+		      "Linux application",
+		      "Linux DSO",
+		      "PalmOS 2004",
+		      "PalmOS (reserved)",
+		      "SymbianOS 2004",
+		      "SymbianOS (reserved)");
+	return true;
+      case 14:
+	*tag_name = "ABI_PCS_R9_use";
+	KNOWN_VALUES ("V6", "SB", "TLS", "Unused");
+	return true;
+      case 15:
+	*tag_name = "ABI_PCS_RW_data";
+	KNOWN_VALUES ("Absolute", "PC-relative", "SB-relative", "None");
+	return true;
+      case 16:
+	*tag_name = "ABI_PCS_RO_data";
+	KNOWN_VALUES ("Absolute", "PC-relative", "None");
+	return true;
+      case 17:
+	*tag_name = "ABI_PCS_GOT_use";
+	KNOWN_VALUES ("None", "direct", "GOT-indirect");
+	return true;
+      case 18:
+	*tag_name = "ABI_PCS_wchar_t";
+	return true;
+      case 19:
+	*tag_name = "ABI_FP_rounding";
+	KNOWN_VALUES ("Unused", "Needed");
+	return true;
+      case 20:
+	*tag_name = "ABI_FP_denormal";
+	KNOWN_VALUES ("Unused", "Needed", "Sign only");
+	return true;
+      case 21:
+	*tag_name = "ABI_FP_exceptions";
+	KNOWN_VALUES ("Unused", "Needed");
+	return true;
+      case 22:
+	*tag_name = "ABI_FP_user_exceptions";
+	KNOWN_VALUES ("Unused", "Needed");
+	return true;
+      case 23:
+	*tag_name = "ABI_FP_number_model";
+	KNOWN_VALUES ("Unused", "Finite", "RTABI", "IEEE 754");
+	return true;
+      case 24:
+	*tag_name = "ABI_align8_needed";
+	KNOWN_VALUES ("No", "Yes", "4-byte");
+	return true;
+      case 25:
+	*tag_name = "ABI_align8_preserved";
+	KNOWN_VALUES ("No", "Yes, except leaf SP", "Yes");
+	return true;
+      case 26:
+	*tag_name = "ABI_enum_size";
+	KNOWN_VALUES ("Unused", "small", "int", "forced to int");
+	return true;
+      case 27:
+	*tag_name = "ABI_HardFP_use";
+	KNOWN_VALUES ("as VFP_arch", "SP only", "DP only", "SP and DP");
+	return true;
+      case 28:
+	*tag_name = "ABI_VFP_args";
+	KNOWN_VALUES ("AAPCS", "VFP registers", "custom");
+	return true;
+      case 29:
+	*tag_name = "ABI_WMMX_args";
+	KNOWN_VALUES ("AAPCS", "WMMX registers", "custom");
+	return true;
+      case 30:
+	*tag_name = "ABI_optimization_goals";
+	KNOWN_VALUES ("None",
+		      "Prefer Speed",
+		      "Aggressive Speed",
+		      "Prefer Size",
+		      "Aggressive Size",
+		      "Prefer Debug",
+		      "Aggressive Debug");
+	return true;
+      case 31:
+	*tag_name = "ABI_FP_optimization_goals";
+	KNOWN_VALUES ("None",
+		      "Prefer Speed",
+		      "Aggressive Speed",
+		      "Prefer Size",
+		      "Aggressive Size",
+		      "Prefer Accuracy",
+		      "Aggressive Accuracy");
+	return true;
+      case 34:
+	*tag_name = "CPU_unaligned_access";
+	KNOWN_VALUES ("None", "v6");
+	return true;
+      case 36:
+	*tag_name = "VFP_HP_extension";
+	KNOWN_VALUES ("Not Allowed", "Allowed");
+	return true;
+      case 38:
+	*tag_name = "ABI_FP_16bit_format";
+	KNOWN_VALUES ("None", "IEEE 754", "Alternative Format");
+	return true;
+      case 64:
+	*tag_name = "nodefaults";
+	return true;
+      case 65:
+	*tag_name = "also_compatible_with";
+	return true;
+      case 66:
+	*tag_name = "T2EE_use";
+	KNOWN_VALUES ("Not Allowed", "Allowed");
+	return true;
+      case 67:
+	*tag_name = "conformance";
+	return true;
+      case 68:
+	*tag_name = "Virtualization_use";
+	KNOWN_VALUES ("Not Allowed", "Allowed");
+	return true;
+      case 70:
+	*tag_name = "MPextension_use";
+	KNOWN_VALUES ("Not Allowed", "Allowed");
+	return true;
+      }
+
+  return false;
+}
diff --git a/third_party/elfutils/backends/arm_auxv.c b/third_party/elfutils/backends/arm_auxv.c
new file mode 100644
index 0000000..3282baf
--- /dev/null
+++ b/third_party/elfutils/backends/arm_auxv.c
@@ -0,0 +1,49 @@
+/* ARM-specific auxv handling.
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND arm_
+#include "libebl_CPU.h"
+
+int
+EBLHOOK(auxv_info) (GElf_Xword a_type, const char **name, const char **format)
+{
+  if (a_type != AT_HWCAP)
+    return 0;
+
+  *name = "HWCAP";
+  *format = "b"
+    "swp\0" "half\0" "thumb\0" "26bit\0"
+    "fast-mult\0" "fpa\0" "vfp\0" "edsp\0"
+    "java\0" "iwmmxt\0"
+    "\0";
+  return 1;
+}
diff --git a/third_party/elfutils/backends/arm_cfi.c b/third_party/elfutils/backends/arm_cfi.c
new file mode 100644
index 0000000..971a1fc
--- /dev/null
+++ b/third_party/elfutils/backends/arm_cfi.c
@@ -0,0 +1,90 @@
+/* arm ABI-specified defaults for DWARF CFI.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#define BACKEND arm_
+#include "libebl_CPU.h"
+
+
+/* ABI-specified state of DWARF CFI based on:
+
+   "DWARF for the ARM Architecture ABI r2.09"
+http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040b/IHI0040B_aadwarf.pdf
+
+   "Procedure Call Standard for the ARM Architecture ABI r2.09"
+http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042e/IHI0042E_aapcs.pdf
+*/
+
+int
+arm_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
+{
+  static const uint8_t abi_cfi[] =
+    {
+      /* The initial Canonical Frame Address is the value of the
+         Stack Pointer (r13) as setup in the previous frame. */
+      DW_CFA_def_cfa, ULEB128_7 (13), ULEB128_7 (0),
+
+      /* The Stack Pointer (r13) is restored from CFA address by default.  */
+      DW_CFA_val_offset, ULEB128_7 (13), ULEB128_7 (0),
+
+#define SV(n) DW_CFA_same_value, ULEB128_7 (n)
+      /* Callee-saved regs r4-r8, r10, r11.  */
+      SV (4), SV (5), SV (6), SV (7), SV (8), SV (10), SV (11),
+
+      /* The link register contains the return address setup by caller.  */
+      SV (14),
+      DW_CFA_register, ULEB128_7 (15), ULEB128_7 (14), /* pc = lr */
+#undef SV
+
+      /* VFP S16-S31/D8-D15/Q4-Q7 are callee saved.
+         And uleb128 encoded with two bytes.  */
+#define ULEB128_8_2(x) ((x & 0x7f) | 0x80), 0x02
+#define SV(n) DW_CFA_same_value, ULEB128_8_2 (n)
+      SV (264), SV (265), SV (266), SV (267),
+      SV (268), SV (269), SV (270), SV (271),
+
+      /* XXX Note: registers intentionally unused by the program,
+	 for example as a consequence of the procedure call standard
+	 should be initialized as if by DW_CFA_same_value.  */
+    };
+#undef ULEB128_8_2
+#undef SV
+
+  abi_info->initial_instructions = abi_cfi;
+  abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
+  abi_info->data_alignment_factor = 4;
+
+  abi_info->return_address_register = 15; /* pc.  */
+
+  return 0;
+}
diff --git a/third_party/elfutils/backends/arm_corenote.c b/third_party/elfutils/backends/arm_corenote.c
new file mode 100644
index 0000000..c5d8d88
--- /dev/null
+++ b/third_party/elfutils/backends/arm_corenote.c
@@ -0,0 +1,94 @@
+/* ARM specific core note handling.
+   Copyright (C) 2009, 2012 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND arm_
+#include "libebl_CPU.h"
+
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+    { .offset = 0, .regno = 0, .count = 16, .bits = 32 },	/* r0..r15 */
+    { .offset = 16 * 4, .regno = 128, .count = 1, .bits = 32 }, /* cpsr */
+  };
+#define PRSTATUS_REGS_SIZE	(18 * 4)
+
+#define PRSTATUS_REGSET_ITEMS						      \
+  {									      \
+    .name = "orig_r0", .type = ELF_T_SWORD, .format = 'd',		      \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + (4 * 17),	      \
+    .group = "register"	       			  	       	 	      \
+  }
+
+static const Ebl_Register_Location fpregset_regs[] =
+  {
+    { .offset = 0, .regno = 96, .count = 8, .bits = 96 }, /* f0..f7 */
+  };
+#define FPREGSET_SIZE	116
+
+#define	ULONG			uint32_t
+#define PID_T			int32_t
+#define	UID_T			uint16_t
+#define	GID_T			uint16_t
+#define ALIGN_ULONG		4
+#define ALIGN_PID_T		4
+#define ALIGN_UID_T		2
+#define ALIGN_GID_T		2
+#define TYPE_ULONG		ELF_T_WORD
+#define TYPE_PID_T		ELF_T_SWORD
+#define TYPE_UID_T		ELF_T_HALF
+#define TYPE_GID_T		ELF_T_HALF
+
+#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
+static const Ebl_Register_Location vfp_regs[] =
+  {
+    { .offset = 0, .regno = 256, .count = 32, .bits = 64 }, /* fpregs */
+  };
+
+static const Ebl_Core_Item vfp_items[] =
+  {
+    {
+      .name = "fpscr", .group = "register",
+      .offset = 0,
+      .type = ELF_T_WORD, .format = 'x',
+    },
+  };
+
+#define	EXTRA_NOTES \
+  EXTRA_REGSET_ITEMS (NT_ARM_VFP, ARM_VFPREGS_SIZE, vfp_regs, vfp_items)
+
+#include "linux-core-note.c"
diff --git a/third_party/elfutils/backends/arm_init.c b/third_party/elfutils/backends/arm_init.c
new file mode 100644
index 0000000..f2b1b11
--- /dev/null
+++ b/third_party/elfutils/backends/arm_init.c
@@ -0,0 +1,77 @@
+/* Initialization of Arm specific backend library.
+   Copyright (C) 2002, 2005, 2009, 2013, 2014, 2015, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		arm_
+#define RELOC_PREFIX	R_ARM_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on arm_reloc.def.  */
+#include "common-reloc.c"
+
+
+const char *
+arm_init (Elf *elf __attribute__ ((unused)),
+	  GElf_Half machine __attribute__ ((unused)),
+	  Ebl *eh,
+	  size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "ARM";
+  arm_init_reloc (eh);
+  HOOK (eh, segment_type_name);
+  HOOK (eh, section_type_name);
+  HOOK (eh, machine_flag_check);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, register_info);
+  HOOK (eh, core_note);
+  HOOK (eh, auxv_info);
+  HOOK (eh, check_object_attribute);
+  HOOK (eh, return_value_location);
+  HOOK (eh, abi_cfi);
+  HOOK (eh, check_reloc_target_type);
+  HOOK (eh, symbol_type_name);
+  HOOK (eh, data_marker_symbol);
+
+  /* We only unwind the core integer registers.  */
+  eh->frame_nregs = 16;
+  HOOK (eh, set_initial_registers_tid);
+
+  /* Bit zero encodes whether an function address is THUMB or ARM. */
+  eh->func_addr_mask = ~(GElf_Addr)1;
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/arm_initreg.c b/third_party/elfutils/backends/arm_initreg.c
new file mode 100644
index 0000000..efcabaf
--- /dev/null
+++ b/third_party/elfutils/backends/arm_initreg.c
@@ -0,0 +1,94 @@
+/* Fetch live process registers from TID.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef __linux__
+#if defined __arm__
+# include <sys/types.h>
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#endif
+
+#ifdef __aarch64__
+# include <linux/uio.h>
+# include <sys/user.h>
+# include <sys/ptrace.h>
+/* Deal with old glibc defining user_pt_regs instead of user_regs_struct.  */
+# ifndef HAVE_SYS_USER_REGS
+#  define user_regs_struct user_pt_regs
+# endif
+#endif
+#endif
+
+#define BACKEND arm_
+#include "libebl_CPU.h"
+
+bool
+arm_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
+			  ebl_tid_registers_t *setfunc __attribute__ ((unused)),
+			       void *arg __attribute__ ((unused)))
+{
+#if !defined(__linux__) || (!defined __arm__ && !defined __aarch64__)
+  return false;
+#else	/* __arm__ || __aarch64__ */
+#if defined __arm__
+  struct user_regs user_regs;
+  if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0)
+    return false;
+
+  Dwarf_Word dwarf_regs[16];
+  /* R0..R12 SP LR PC */
+  for (int i = 0; i < 16; i++)
+    dwarf_regs[i] = user_regs.uregs[i];
+
+  return setfunc (0, 16, dwarf_regs, arg);
+#elif defined __aarch64__
+  /* Compat mode: arm compatible code running on aarch64 */
+  int i;
+  struct user_regs_struct gregs;
+  struct iovec iovec;
+  iovec.iov_base = &gregs;
+  iovec.iov_len = sizeof (gregs);
+  if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, &iovec) != 0)
+    return false;
+
+  Dwarf_Word dwarf_regs[16];
+  /* R0..R12 SP LR PC, encoded as 32 bit quantities */
+  uint32_t *u32_ptr = (uint32_t *) &gregs.regs[0];
+  for (i = 0; i < 16; i++)
+    dwarf_regs[i] = u32_ptr[i];
+
+  return setfunc (0, 16, dwarf_regs, arg);
+#else
+# error "source file error, it cannot happen"
+#endif
+#endif
+}
diff --git a/third_party/elfutils/backends/arm_regs.c b/third_party/elfutils/backends/arm_regs.c
new file mode 100644
index 0000000..a46a4c9
--- /dev/null
+++ b/third_party/elfutils/backends/arm_regs.c
@@ -0,0 +1,120 @@
+/* Register names and numbers for ARM DWARF.
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND arm_
+#include "libebl_CPU.h"
+
+ssize_t
+arm_register_info (Ebl *ebl __attribute__ ((unused)),
+		   int regno, char *name, size_t namelen,
+		   const char **prefix, const char **setname,
+		   int *bits, int *type)
+{
+  if (name == NULL)
+    return 320;
+
+  if (regno < 0 || regno > 320 || namelen < 5)
+    return -1;
+
+  *prefix = "";
+  *bits = 32;
+  *type = DW_ATE_signed;
+  *setname = "integer";
+
+  switch (regno)
+    {
+    case 0 ... 9:
+      name[0] = 'r';
+      name[1] = regno + '0';
+      namelen = 2;
+      break;
+
+    case 10 ... 12:
+      name[0] = 'r';
+      name[1] = '1';
+      name[2] = regno % 10 + '0';
+      namelen = 3;
+      break;
+
+    case 13 ... 15:
+      *type = DW_ATE_address;
+      name[0] = "slp"[regno - 13];
+      name[1] = "prc"[regno - 13];
+      namelen = 2;
+      break;
+
+    case 16 + 0 ... 16 + 7:
+      regno += 96 - 16;
+      FALLTHROUGH;
+    case 96 + 0 ... 96 + 7:
+      *setname = "FPA";
+      *type = DW_ATE_float;
+      *bits = 96;
+      name[0] = 'f';
+      name[1] = regno - 96 + '0';
+      namelen = 2;
+      break;
+
+    case 128:
+      *type = DW_ATE_unsigned;
+      return stpcpy (name, "spsr") + 1 - name;
+
+    case 256 + 0 ... 256 + 9:
+      *setname = "VFP";
+      *type = DW_ATE_float;
+      *bits = 64;
+      name[0] = 'd';
+      name[1] = regno - 256 + '0';
+      namelen = 2;
+      break;
+
+    case 256 + 10 ... 256 + 31:
+      *setname = "VFP";
+      *type = DW_ATE_float;
+      *bits = 64;
+      name[0] = 'd';
+      name[1] = (regno - 256) / 10 + '0';
+      name[2] = (regno - 256) % 10 + '0';
+      namelen = 3;
+      break;
+
+    default:
+      *setname = NULL;
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
diff --git a/third_party/elfutils/backends/arm_reloc.def b/third_party/elfutils/backends/arm_reloc.def
new file mode 100644
index 0000000..113648e
--- /dev/null
+++ b/third_party/elfutils/backends/arm_reloc.def
@@ -0,0 +1,157 @@
+/* List the relocation types for arm.  -*- C -*-
+   Copyright (C) 2005-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,		REL) /* It really is used in ET_REL on ARM.  */
+RELOC_TYPE (PC24,		REL|EXEC|DYN)
+RELOC_TYPE (ABS32,		REL|EXEC|DYN)
+RELOC_TYPE (REL32,		REL)
+RELOC_TYPE (PC13,		REL)
+RELOC_TYPE (ABS16,		REL)
+RELOC_TYPE (ABS12,		REL)
+RELOC_TYPE (THM_ABS5,		REL)
+RELOC_TYPE (ABS8,		REL)
+RELOC_TYPE (SBREL32,		REL)
+RELOC_TYPE (THM_PC22,		REL)
+RELOC_TYPE (THM_PC8,		REL)
+RELOC_TYPE (AMP_VCALL9,		REL)
+RELOC_TYPE (TLS_DESC,		EXEC|DYN)
+RELOC_TYPE (THM_SWI8,		REL)
+RELOC_TYPE (XPC25,		REL)
+RELOC_TYPE (THM_XPC22,		REL)
+RELOC_TYPE (TLS_DTPMOD32,	EXEC|DYN)
+RELOC_TYPE (TLS_DTPOFF32,	EXEC|DYN)
+RELOC_TYPE (TLS_TPOFF32,	EXEC|DYN)
+RELOC_TYPE (COPY,		EXEC|DYN)
+RELOC_TYPE (GLOB_DAT,		EXEC|DYN)
+RELOC_TYPE (JUMP_SLOT,		EXEC|DYN)
+RELOC_TYPE (RELATIVE,		EXEC|DYN)
+RELOC_TYPE (GOTOFF,		REL)
+RELOC_TYPE (GOTPC,		REL)
+RELOC_TYPE (GOT32,		REL)
+RELOC_TYPE (PLT32,		REL)
+RELOC_TYPE (CALL,		REL)
+RELOC_TYPE (JUMP24,		REL)
+RELOC_TYPE (THM_JUMP24,		REL)
+RELOC_TYPE (BASE_ABS,		REL)
+RELOC_TYPE (ALU_PCREL_7_0,	REL)
+RELOC_TYPE (ALU_PCREL_15_8,	REL)
+RELOC_TYPE (ALU_PCREL_23_15,	REL)
+RELOC_TYPE (LDR_SBREL_11_0,	REL)
+RELOC_TYPE (ALU_SBREL_19_12,	REL)
+RELOC_TYPE (ALU_SBREL_27_20,	REL)
+RELOC_TYPE (TARGET1,		REL)
+RELOC_TYPE (SBREL31,		REL)
+RELOC_TYPE (V4BX,		REL)
+RELOC_TYPE (TARGET2,		REL)
+RELOC_TYPE (PREL31,		REL)
+RELOC_TYPE (MOVW_ABS_NC,	REL)
+RELOC_TYPE (MOVT_ABS,		REL)
+RELOC_TYPE (MOVW_PREL_NC,	REL)
+RELOC_TYPE (MOVT_PREL,		REL)
+RELOC_TYPE (THM_MOVW_ABS_NC,	REL)
+RELOC_TYPE (THM_MOVT_ABS,	REL)
+RELOC_TYPE (THM_MOVW_PREL_NC,	REL)
+RELOC_TYPE (THM_MOVT_PREL,	REL)
+RELOC_TYPE (THM_JUMP19,		REL)
+RELOC_TYPE (THM_JUMP6,		REL)
+RELOC_TYPE (THM_ALU_PREL_11_0,	REL)
+RELOC_TYPE (THM_PC12,		REL)
+RELOC_TYPE (ABS32_NOI,		REL)
+RELOC_TYPE (REL32_NOI,		REL)
+RELOC_TYPE (ALU_PC_G0_NC,	REL)
+RELOC_TYPE (ALU_PC_G0,		REL)
+RELOC_TYPE (ALU_PC_G1_NC,	REL)
+RELOC_TYPE (ALU_PC_G1,		REL)
+RELOC_TYPE (ALU_PC_G2,		REL)
+RELOC_TYPE (LDR_PC_G1,		REL)
+RELOC_TYPE (LDR_PC_G2,		REL)
+RELOC_TYPE (LDRS_PC_G0,		REL)
+RELOC_TYPE (LDRS_PC_G1,		REL)
+RELOC_TYPE (LDRS_PC_G2,		REL)
+RELOC_TYPE (LDC_PC_G0,		REL)
+RELOC_TYPE (LDC_PC_G1,		REL)
+RELOC_TYPE (LDC_PC_G2,		REL)
+RELOC_TYPE (ALU_SB_G0_NC,	REL)
+RELOC_TYPE (ALU_SB_G0,		REL)
+RELOC_TYPE (ALU_SB_G1_NC,	REL)
+RELOC_TYPE (ALU_SB_G1,		REL)
+RELOC_TYPE (ALU_SB_G2,		REL)
+RELOC_TYPE (LDR_SB_G0,		REL)
+RELOC_TYPE (LDR_SB_G1,		REL)
+RELOC_TYPE (LDR_SB_G2,		REL)
+RELOC_TYPE (LDRS_SB_G0,		REL)
+RELOC_TYPE (LDRS_SB_G1,		REL)
+RELOC_TYPE (LDRS_SB_G2,		REL)
+RELOC_TYPE (LDC_SB_G0,		REL)
+RELOC_TYPE (LDC_SB_G1,		REL)
+RELOC_TYPE (LDC_SB_G2,		REL)
+RELOC_TYPE (MOVW_BREL_NC,	REL)
+RELOC_TYPE (MOVT_BREL,		REL)
+RELOC_TYPE (MOVW_BREL,		REL)
+RELOC_TYPE (THM_MOVW_BREL_NC,	REL)
+RELOC_TYPE (THM_MOVT_BREL,	REL)
+RELOC_TYPE (THM_MOVW_BREL,	REL)
+RELOC_TYPE (TLS_GOTDESC,	REL)
+RELOC_TYPE (TLS_CALL,		REL)
+RELOC_TYPE (TLS_DESCSEQ,	REL)
+RELOC_TYPE (THM_TLS_CALL,	REL)
+RELOC_TYPE (PLT32_ABS,		REL)
+RELOC_TYPE (GOT_ABS,		REL)
+RELOC_TYPE (GOT_PREL,		REL)
+RELOC_TYPE (GOT_BREL12,		REL)
+RELOC_TYPE (GOTOFF12,		REL)
+RELOC_TYPE (GOTRELAX,		REL)
+RELOC_TYPE (GNU_VTENTRY,	REL)
+RELOC_TYPE (GNU_VTINHERIT,	REL)
+RELOC_TYPE (THM_PC11,		REL)
+RELOC_TYPE (THM_PC9,		REL)
+RELOC_TYPE (TLS_GD32,		REL)
+RELOC_TYPE (TLS_LDM32,		REL)
+RELOC_TYPE (TLS_LDO32,		REL)
+RELOC_TYPE (TLS_IE32,		REL)
+RELOC_TYPE (TLS_LE32,		REL)
+RELOC_TYPE (TLS_LDO12,		REL)
+RELOC_TYPE (TLS_LE12,		REL)
+RELOC_TYPE (TLS_IE12GP,		REL)
+
+RELOC_TYPE (ME_TOO,		REL)
+RELOC_TYPE (THM_TLS_DESCSEQ16,	REL)
+RELOC_TYPE (THM_TLS_DESCSEQ32,	REL)
+RELOC_TYPE (THM_GOT_BREL12,	REL)
+
+RELOC_TYPE (IRELATIVE,		EXEC|DYN)
+
+RELOC_TYPE (RXPC25,		REL)
+RELOC_TYPE (RSBREL32,		REL)
+RELOC_TYPE (THM_RPC22,		REL)
+RELOC_TYPE (RREL32,		REL)
+RELOC_TYPE (RABS22,		REL)
+RELOC_TYPE (RPC24,		REL)
+RELOC_TYPE (RBASE,		REL)
diff --git a/third_party/elfutils/backends/arm_retval.c b/third_party/elfutils/backends/arm_retval.c
new file mode 100644
index 0000000..1c28f01
--- /dev/null
+++ b/third_party/elfutils/backends/arm_retval.c
@@ -0,0 +1,127 @@
+/* Function return value location for ARM EABI.
+   Copyright (C) 2009-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND arm_
+#include "libebl_CPU.h"
+
+
+/* r0, or pair r0, r1, or aggregate up to r0-r3.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+#define nloc_intreg	1
+#define nloc_intregs(n)	(2 * (n))
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in r0.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_breg0, .number = 0 }
+  };
+#define nloc_aggregate 1
+
+
+int
+arm_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  Dwarf_Word size;
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Attribute attr_mem;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+						   &attr_mem), &size) != 0)
+	  {
+	    if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	      size = 4;
+	    else
+	      return -1;
+	  }
+	if (size <= 16)
+	  {
+	  intreg:
+	    *locp = loc_intreg;
+	    return size <= 4 ? nloc_intreg : nloc_intregs ((size + 3) / 4);
+	  }
+
+      aggregate:
+	*locp = loc_aggregate;
+	return nloc_aggregate;
+      }
+
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+    case DW_TAG_array_type:
+      if (dwarf_aggregate_size (typedie, &size) == 0
+	  && size > 0 && size <= 4)
+	goto intreg;
+      goto aggregate;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/arm_symbol.c b/third_party/elfutils/backends/arm_symbol.c
new file mode 100644
index 0000000..3edda72
--- /dev/null
+++ b/third_party/elfutils/backends/arm_symbol.c
@@ -0,0 +1,157 @@
+/* Arm specific symbolic name handling.
+   Copyright (C) 2002-2009, 2014, 2015, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND		arm_
+#include "libebl_CPU.h"
+
+
+const char *
+arm_segment_type_name (int segment, char *buf __attribute__ ((unused)),
+		       size_t len __attribute__ ((unused)))
+{
+  switch (segment)
+    {
+    case PT_ARM_EXIDX:
+      return "ARM_EXIDX";
+    }
+  return NULL;
+}
+
+/* Return symbolic representation of section type.  */
+const char *
+arm_section_type_name (int type,
+		       char *buf __attribute__ ((unused)),
+		       size_t len __attribute__ ((unused)))
+{
+  switch (type)
+    {
+    case SHT_ARM_EXIDX:
+      return "ARM_EXIDX";
+    case SHT_ARM_PREEMPTMAP:
+      return "ARM_PREEMPTMAP";
+    case SHT_ARM_ATTRIBUTES:
+      return "ARM_ATTRIBUTES";
+    }
+
+  return NULL;
+}
+
+/* Check whether machine flags are valid.  */
+bool
+arm_machine_flag_check (GElf_Word flags)
+{
+  switch (flags & EF_ARM_EABIMASK)
+    {
+    case EF_ARM_EABI_UNKNOWN:
+    case EF_ARM_EABI_VER1:
+    case EF_ARM_EABI_VER2:
+    case EF_ARM_EABI_VER3:
+    case EF_ARM_EABI_VER4:
+    case EF_ARM_EABI_VER5:
+      break;
+    default:
+      return false;
+    }
+
+  return ((flags &~ (EF_ARM_EABIMASK
+		     | EF_ARM_RELEXEC
+		     | EF_ARM_HASENTRY
+		     | EF_ARM_INTERWORK
+		     | EF_ARM_APCS_26
+		     | EF_ARM_APCS_FLOAT
+		     | EF_ARM_PIC
+		     | EF_ARM_ALIGN8
+		     | EF_ARM_NEW_ABI
+		     | EF_ARM_OLD_ABI
+		     | EF_ARM_SOFT_FLOAT
+		     | EF_ARM_VFP_FLOAT
+		     | EF_ARM_MAVERICK_FLOAT
+		     | EF_ARM_SYMSARESORTED
+		     | EF_ARM_DYNSYMSUSESEGIDX
+		     | EF_ARM_MAPSYMSFIRST
+		     | EF_ARM_EABIMASK
+		     | EF_ARM_BE8
+		     | EF_ARM_LE8)) == 0);
+}
+
+/* Check for the simple reloc types.  */
+Elf_Type
+arm_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_ARM_ABS32:
+      return ELF_T_WORD;
+    case R_ARM_ABS16:
+      return ELF_T_HALF;
+    case R_ARM_ABS8:
+      return ELF_T_BYTE;
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+/* The SHT_ARM_EXIDX section type is a valid target for relocation.  */
+bool
+arm_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), Elf64_Word sh_type)
+{
+  return sh_type == SHT_ARM_EXIDX;
+}
+
+const char *
+arm_symbol_type_name (int type,
+		      char *buf __attribute__ ((unused)),
+		      size_t len __attribute__ ((unused)))
+{
+  switch (type)
+    {
+    case STT_ARM_TFUNC:
+      return "ARM_TFUNC";
+    }
+  return NULL;
+}
+
+/* A data mapping symbol is a symbol with "$d" name or "$d.<any...>" name,
+ *    STT_NOTYPE, STB_LOCAL and st_size of zero. The indicate the stat of a
+ *       sequence of data items.  */
+bool
+arm_data_marker_symbol (const GElf_Sym *sym, const char *sname)
+{
+  return (sym != NULL && sname != NULL
+          && sym->st_size == 0 && GELF_ST_BIND (sym->st_info) == STB_LOCAL
+          && GELF_ST_TYPE (sym->st_info) == STT_NOTYPE
+          && (strcmp (sname, "$d") == 0 || strncmp (sname, "$d.", 3) == 0));
+}
diff --git a/third_party/elfutils/backends/bpf_init.c b/third_party/elfutils/backends/bpf_init.c
new file mode 100644
index 0000000..8ea1bc1
--- /dev/null
+++ b/third_party/elfutils/backends/bpf_init.c
@@ -0,0 +1,58 @@
+/* Initialization of BPF specific backend library.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		bpf_
+#define RELOC_PREFIX	R_BPF_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on bpf_reloc.def.  */
+#define NO_RELATIVE_RELOC
+#define NO_COPY_RELOC
+#include "common-reloc.c"
+
+
+const char *
+bpf_init (Elf *elf __attribute__ ((unused)),
+	  GElf_Half machine __attribute__ ((unused)),
+	  Ebl *eh, size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "BPF";
+  bpf_init_reloc (eh);
+  HOOK (eh, register_info);
+  HOOK (eh, disasm);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/bpf_regs.c b/third_party/elfutils/backends/bpf_regs.c
new file mode 100644
index 0000000..1863a16
--- /dev/null
+++ b/third_party/elfutils/backends/bpf_regs.c
@@ -0,0 +1,60 @@
+/* Register names and numbers for BPF DWARF.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "bpf.h"
+
+#define BACKEND bpf_
+#include "libebl_CPU.h"
+
+ssize_t
+bpf_register_info (Ebl *ebl __attribute__ ((unused)),
+		   int regno, char *name, size_t namelen,
+		   const char **prefix, const char **setname,
+		   int *bits, int *type)
+{
+  ssize_t len;
+
+  if (name == NULL)
+    return MAX_BPF_REG;
+  if (regno < 0 || regno >= MAX_BPF_REG)
+    return -1;
+
+  *prefix = "";
+  *setname = "integer";
+  *bits = 64;
+  *type = DW_ATE_signed;
+
+  len = snprintf(name, namelen, "r%d", regno);
+  return ((size_t)len < namelen ? len : -1);
+}
diff --git a/third_party/elfutils/backends/bpf_reloc.def b/third_party/elfutils/backends/bpf_reloc.def
new file mode 100644
index 0000000..a410da9
--- /dev/null
+++ b/third_party/elfutils/backends/bpf_reloc.def
@@ -0,0 +1,31 @@
+/* List the relocation types for BPF.  -*- C -*-
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,		EXEC|DYN)
+RELOC_TYPE (MAP_FD,		REL|EXEC|DYN)
diff --git a/third_party/elfutils/backends/common-reloc.c b/third_party/elfutils/backends/common-reloc.c
new file mode 100644
index 0000000..096ed1c
--- /dev/null
+++ b/third_party/elfutils/backends/common-reloc.c
@@ -0,0 +1,162 @@
+/* Common code for ebl reloc functions.
+   Copyright (C) 2005, 2006 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include "libebl_CPU.h"
+#include <assert.h>
+
+#define R_TYPE(name)		PASTE (RELOC_PREFIX, name)
+#define PASTE(a, b)		PASTE_1 (a, b)
+#define PASTE_1(a, b)		a##b
+#define R_NAME(name)		R_NAME_1 (RELOC_PREFIX, name)
+#define R_NAME_1(prefix, type)	R_NAME_2 (prefix, type)
+#define R_NAME_2(prefix, type)	#prefix #type
+
+#define RELOC_TYPES		STRINGIFIED_PASTE (BACKEND, reloc.def)
+#define STRINGIFIED_PASTE(a, b)	STRINGIFY (PASTE (a, b))
+#define STRINGIFY(x)		STRINGIFY_1 (x)
+#define STRINGIFY_1(x)		#x
+
+/* Provide a table of reloc type names, in a PIC-friendly fashion.  */
+
+static const struct EBLHOOK(reloc_nametable)
+{
+  char zero;
+#define	RELOC_TYPE(type, uses) \
+  char name_##type[sizeof R_NAME (type)];
+#include RELOC_TYPES
+#undef RELOC_TYPE
+} EBLHOOK(reloc_nametable) =
+  {
+    '\0',
+#define	RELOC_TYPE(type, uses) R_NAME (type),
+#include RELOC_TYPES
+#undef RELOC_TYPE
+  };
+#define reloc_namestr (&EBLHOOK(reloc_nametable).zero)
+
+static const uint_fast16_t EBLHOOK(reloc_nameidx)[] =
+{
+#define	RELOC_TYPE(type, uses) \
+  [R_TYPE (type)] = offsetof (struct EBLHOOK(reloc_nametable), name_##type),
+#include RELOC_TYPES
+#undef RELOC_TYPE
+};
+#define nreloc \
+  ((int) (sizeof EBLHOOK(reloc_nameidx) / sizeof EBLHOOK(reloc_nameidx)[0]))
+
+#define REL	(1 << (ET_REL - 1))
+#define EXEC	(1 << (ET_EXEC - 1))
+#define DYN	(1 << (ET_DYN - 1))
+static const uint8_t EBLHOOK(reloc_valid)[] =
+{
+#define	RELOC_TYPE(type, uses) [R_TYPE (type)] = uses,
+#include RELOC_TYPES
+#undef RELOC_TYPE
+};
+#undef REL
+#undef EXEC
+#undef DYN
+
+const char *
+EBLHOOK(reloc_type_name) (int reloc,
+			  char *buf __attribute__ ((unused)),
+			  size_t len __attribute__ ((unused)))
+{
+#ifdef RELOC_TYPE_ID
+  reloc = RELOC_TYPE_ID (reloc);
+#endif
+
+  if (reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0)
+    return &reloc_namestr[EBLHOOK(reloc_nameidx)[reloc]];
+  return NULL;
+}
+
+bool
+EBLHOOK(reloc_type_check) (int reloc)
+{
+#ifdef RELOC_TYPE_ID
+  reloc = RELOC_TYPE_ID (reloc);
+#endif
+
+  return reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0;
+}
+
+bool
+EBLHOOK(reloc_valid_use) (Elf *elf, int reloc)
+{
+  uint8_t uses;
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  assert (ehdr != NULL);
+  uint8_t type = ehdr->e_type;
+
+#ifdef RELOC_TYPE_ID
+  reloc = RELOC_TYPE_ID (reloc);
+#endif
+
+  uses = EBLHOOK(reloc_valid)[reloc];
+  return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1)));
+}
+
+#ifndef NO_COPY_RELOC
+bool
+EBLHOOK(copy_reloc_p) (int reloc)
+{
+  return reloc == R_TYPE (COPY);
+}
+#endif
+
+bool
+EBLHOOK(none_reloc_p) (int reloc)
+{
+  return reloc == R_TYPE (NONE);
+}
+
+#ifndef NO_RELATIVE_RELOC
+bool
+EBLHOOK(relative_reloc_p) (int reloc)
+{
+  return reloc == R_TYPE (RELATIVE);
+}
+#endif
+
+static void
+EBLHOOK(init_reloc) (Ebl *ebl)
+{
+  ebl->reloc_type_name = EBLHOOK(reloc_type_name);
+  ebl->reloc_type_check = EBLHOOK(reloc_type_check);
+  ebl->reloc_valid_use = EBLHOOK(reloc_valid_use);
+  ebl->none_reloc_p = EBLHOOK(none_reloc_p);
+#ifndef NO_COPY_RELOC
+  ebl->copy_reloc_p = EBLHOOK(copy_reloc_p);
+#endif
+#ifndef NO_RELATIVE_RELOC
+  ebl->relative_reloc_p = EBLHOOK(relative_reloc_p);
+#endif
+}
diff --git a/third_party/elfutils/backends/i386_auxv.c b/third_party/elfutils/backends/i386_auxv.c
new file mode 100644
index 0000000..dba63fe
--- /dev/null
+++ b/third_party/elfutils/backends/i386_auxv.c
@@ -0,0 +1,52 @@
+/* i386 specific auxv handling.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+int
+EBLHOOK(auxv_info) (GElf_Xword a_type, const char **name, const char **format)
+{
+  if (a_type != AT_HWCAP)
+    return 0;
+
+  *name = "HWCAP";
+  *format = "b"
+    "fpu\0" "vme\0" "de\0" "pse\0" "tsc\0" "msr\0" "pae\0" "mce\0"
+    "cx8\0" "apic\0" "10\0" "sep\0" "mtrr\0" "pge\0" "mca\0" "cmov\0"
+    "pat\0" "pse36\0" "pn\0" "clflush\0" "20\0" "dts\0" "acpi\0" "mmx\0"
+    "fxsr\0" "sse\0" "sse2\0" "ss\0" "ht\0" "tm\0" "ia64\0" "pbe\0" "\0";
+  return 1;
+}
+
+__typeof (i386_auxv_info) x86_64_auxv_info
+			  __attribute__ ((alias ("i386_auxv_info")));
diff --git a/third_party/elfutils/backends/i386_cfi.c b/third_party/elfutils/backends/i386_cfi.c
new file mode 100644
index 0000000..31f85f7
--- /dev/null
+++ b/third_party/elfutils/backends/i386_cfi.c
@@ -0,0 +1,68 @@
+/* i386 ABI-specified defaults for DWARF CFI.
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+int
+i386_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
+{
+  static const uint8_t abi_cfi[] =
+    {
+      /* Call-saved regs.  */
+      DW_CFA_same_value, ULEB128_7 (3), /* %ebx */
+      DW_CFA_same_value, ULEB128_7 (5), /* %ebp */
+      DW_CFA_same_value, ULEB128_7 (6), /* %esi */
+      DW_CFA_same_value, ULEB128_7 (7), /* %edi */
+
+      /* The CFA is the SP.  */
+      DW_CFA_val_offset, ULEB128_7 (4), ULEB128_7 (0),
+
+      /* Segment registers are call-saved if ever used at all.  */
+      DW_CFA_same_value, ULEB128_7 (40), /* %es */
+      DW_CFA_same_value, ULEB128_7 (41), /* %cs */
+      DW_CFA_same_value, ULEB128_7 (42), /* %ss */
+      DW_CFA_same_value, ULEB128_7 (43), /* %ds */
+      DW_CFA_same_value, ULEB128_7 (44), /* %fs */
+      DW_CFA_same_value, ULEB128_7 (45), /* %gs */
+    };
+
+  abi_info->initial_instructions = abi_cfi;
+  abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
+  abi_info->data_alignment_factor = 4;
+
+  abi_info->return_address_register = 8; /* %eip */
+
+  return 0;
+}
diff --git a/third_party/elfutils/backends/i386_corenote.c b/third_party/elfutils/backends/i386_corenote.c
new file mode 100644
index 0000000..15cd66b
--- /dev/null
+++ b/third_party/elfutils/backends/i386_corenote.c
@@ -0,0 +1,138 @@
+/* i386 specific core note handling.
+   Copyright (C) 2007-2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+#define GR(at, n, dwreg)						\
+    { .offset = at * 4, .regno = dwreg, .count = n, .bits = 32 }
+#define SR(at, n, dwreg)						\
+    { .offset = at * 4, .regno = dwreg, .count = n, .bits = 16, .pad = 2 }
+
+    GR (0, 1, 3),		/* %ebx */
+    GR (1, 2, 1),		/* %ecx-%edx */
+    GR (3, 2, 6),		/* %esi-%edi */
+    GR (5, 1, 5),		/* %ebp */
+    GR (6, 1, 0),		/* %eax */
+    SR (7, 1, 43),		/* %ds */
+    SR (8, 1, 40),		/* %es */
+    SR (9, 1, 44),		/* %fs */
+    SR (10, 1, 45),		/* %gs */
+    /*  11, 1,			   orig_eax */
+    GR (12, 1, 8),		/* %eip */
+    SR (13, 1, 41),		/* %cs */
+    GR (14, 1, 9),		/* eflags */
+    GR (15, 1, 4),		/* %esp */
+    SR (16, 1, 42),		/* %ss */
+
+#undef	GR
+#undef	SR
+  };
+#define PRSTATUS_REGS_SIZE	(17 * 4)
+
+#define	ULONG			uint32_t
+#define PID_T			int32_t
+#define	UID_T			uint16_t
+#define	GID_T			uint16_t
+#define ALIGN_ULONG		4
+#define ALIGN_PID_T		4
+#define ALIGN_UID_T		2
+#define ALIGN_GID_T		2
+#define TYPE_ULONG		ELF_T_WORD
+#define TYPE_PID_T		ELF_T_SWORD
+#define TYPE_UID_T		ELF_T_HALF
+#define TYPE_GID_T		ELF_T_HALF
+
+#define PRSTATUS_REGSET_ITEMS						      \
+  {									      \
+    .name = "orig_eax", .type = ELF_T_SWORD, .format = 'd',		      \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + (4 * 11),	      \
+    .group = "register"	       			  	       	 	      \
+  }
+
+static const Ebl_Register_Location fpregset_regs[] =
+  {
+    { .offset = 0, .regno = 37, .count = 2, .bits = 32 }, /* fctrl-fstat */
+    { .offset = 7 * 4, .regno = 11, .count = 8, .bits = 80 }, /* stN */
+  };
+#define FPREGSET_SIZE	108
+
+static const Ebl_Register_Location prxfpreg_regs[] =
+  {
+    { .offset = 0, .regno = 37, .count = 2, .bits = 16 }, /* fctrl-fstat */
+    { .offset = 24, .regno = 39, .count = 1, .bits = 32 }, /* mxcsr */
+    { .offset = 32, .regno = 11, .count = 8, .bits = 80, .pad = 6 }, /* stN */
+    { .offset = 32 + 128, .regno = 21, .count = 8, .bits = 128 }, /* xmm */
+  };
+
+#define	EXTRA_NOTES \
+  EXTRA_REGSET (NT_PRXFPREG, 512, prxfpreg_regs) \
+  case NT_386_TLS: \
+    return tls_info (nhdr->n_descsz, regs_offset, nregloc, reglocs, \
+		     nitems, items);				    \
+  EXTRA_NOTES_IOPERM
+
+static const Ebl_Core_Item tls_items[] =
+  {
+    { .type = ELF_T_WORD, .offset = 0x0, .format = 'd', .name = "index" },
+    { .type = ELF_T_WORD, .offset = 0x4, .format = 'x', .name = "base" },
+    { .type = ELF_T_WORD, .offset = 0x8, .format = 'x', .name = "limit" },
+    { .type = ELF_T_WORD, .offset = 0xc, .format = 'x', .name = "flags" },
+  };
+
+static int
+tls_info (GElf_Word descsz, GElf_Word *regs_offset,
+	  size_t *nregloc, const Ebl_Register_Location **reglocs,
+	  size_t *nitems, const Ebl_Core_Item **items)
+{
+  if (descsz % 16 != 0)
+    return 0;
+
+  *regs_offset = 0;
+  *nregloc = 0;
+  *reglocs = NULL;
+  *nitems = sizeof tls_items / sizeof tls_items[0];
+  *items = tls_items;
+  return 1;
+}
+
+#include "x86_corenote.c"
+#include "linux-core-note.c"
diff --git a/third_party/elfutils/backends/i386_init.c b/third_party/elfutils/backends/i386_init.c
new file mode 100644
index 0000000..fc1587a
--- /dev/null
+++ b/third_party/elfutils/backends/i386_init.c
@@ -0,0 +1,71 @@
+/* Initialization of i386 specific backend library.
+   Copyright (C) 2000-2009, 2013, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		i386_
+#define RELOC_PREFIX	R_386_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on i386_reloc.def.  */
+#include "common-reloc.c"
+
+const char *
+i386_init (Elf *elf __attribute__ ((unused)),
+	   GElf_Half machine __attribute__ ((unused)),
+	   Ebl *eh,
+	   size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "Intel 80386";
+  i386_init_reloc (eh);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, gotpc_reloc_check);
+  HOOK (eh, core_note);
+  generic_debugscn_p = eh->debugscn_p;
+  HOOK (eh, debugscn_p);
+  HOOK (eh, return_value_location);
+  HOOK (eh, register_info);
+  HOOK (eh, syscall_abi);
+  HOOK (eh, auxv_info);
+  HOOK (eh, disasm);
+  HOOK (eh, abi_cfi);
+  /* gcc/config/ #define DWARF_FRAME_REGISTERS.  For i386 it is 17, why?  */
+  eh->frame_nregs = 9;
+  HOOK (eh, set_initial_registers_tid);
+  HOOK (eh, unwind);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/i386_initreg.c b/third_party/elfutils/backends/i386_initreg.c
new file mode 100644
index 0000000..c344282
--- /dev/null
+++ b/third_party/elfutils/backends/i386_initreg.c
@@ -0,0 +1,79 @@
+/* Fetch live process registers from TID.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if (defined __i386__ || defined __x86_64__) && defined(__linux__)
+# include <sys/types.h>
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#endif
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+bool
+i386_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
+			  ebl_tid_registers_t *setfunc __attribute__ ((unused)),
+				void *arg __attribute__ ((unused)))
+{
+#if (!defined __i386__ && !defined __x86_64__) || !defined(__linux__)
+  return false;
+#else /* __i386__ || __x86_64__ */
+  struct user_regs_struct user_regs;
+  if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0)
+    return false;
+  Dwarf_Word dwarf_regs[9];
+# if defined __i386__
+  dwarf_regs[0] = user_regs.eax;
+  dwarf_regs[1] = user_regs.ecx;
+  dwarf_regs[2] = user_regs.edx;
+  dwarf_regs[3] = user_regs.ebx;
+  dwarf_regs[4] = user_regs.esp;
+  dwarf_regs[5] = user_regs.ebp;
+  dwarf_regs[6] = user_regs.esi;
+  dwarf_regs[7] = user_regs.edi;
+  dwarf_regs[8] = user_regs.eip;
+# elif defined __x86_64__
+  dwarf_regs[0] = user_regs.rax;
+  dwarf_regs[1] = user_regs.rcx;
+  dwarf_regs[2] = user_regs.rdx;
+  dwarf_regs[3] = user_regs.rbx;
+  dwarf_regs[4] = user_regs.rsp;
+  dwarf_regs[5] = user_regs.rbp;
+  dwarf_regs[6] = user_regs.rsi;
+  dwarf_regs[7] = user_regs.rdi;
+  dwarf_regs[8] = user_regs.rip;
+# else /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */
+#  error "source file error, it cannot happen"
+# endif /* (__i386__ || __x86_64__) && (!__i386__ && !__x86_64__) */
+  return setfunc (0, 9, dwarf_regs, arg);
+#endif /* __i386__ || __x86_64__ */
+}
diff --git a/third_party/elfutils/backends/i386_regs.c b/third_party/elfutils/backends/i386_regs.c
new file mode 100644
index 0000000..7ec93bb
--- /dev/null
+++ b/third_party/elfutils/backends/i386_regs.c
@@ -0,0 +1,153 @@
+/* Register names and numbers for i386 DWARF.
+   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+ssize_t
+i386_register_info (Ebl *ebl __attribute__ ((unused)),
+		    int regno, char *name, size_t namelen,
+		    const char **prefix, const char **setname,
+		    int *bits, int *type)
+{
+  if (name == NULL)
+    return 46;
+
+  if (regno < 0 || regno > 45 || namelen < 6)
+    return -1;
+
+  *prefix = "%";
+  *bits = 32;
+  *type = DW_ATE_unsigned;
+  if (regno < 11)
+    {
+      *setname = "integer";
+      if (regno < 9)
+	*type = DW_ATE_signed;
+    }
+  else if (regno < 19)
+    {
+      *setname = "x87";
+      *type = DW_ATE_float;
+      *bits = 80;
+    }
+  else if (regno < 29)
+    {
+      *setname = "SSE";
+      *bits = 128;
+    }
+  else if (regno < 37)
+    {
+      *setname = "MMX";
+      *bits = 64;
+    }
+  else if (regno < 40)
+    *setname = "FPU-control";
+  else
+    {
+      *setname = "segment";
+      *bits = 16;
+    }
+
+  switch (regno)
+    {
+      static const char baseregs[][2] =
+	{
+	  "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "ip"
+	};
+
+    case 4:
+    case 5:
+    case 8:
+      *type = DW_ATE_address;
+      FALLTHROUGH;
+    case 0 ... 3:
+    case 6 ... 7:
+      name[0] = 'e';
+      name[1] = baseregs[regno][0];
+      name[2] = baseregs[regno][1];
+      namelen = 3;
+      break;
+
+    case 9:
+      return stpcpy (name, "eflags") + 1 - name;
+    case 10:
+      return stpcpy (name, "trapno") + 1 - name;
+
+    case 11 ... 18:
+      name[0] = 's';
+      name[1] = 't';
+      name[2] = regno - 11 + '0';
+      namelen = 3;
+      break;
+
+    case 21 ... 28:
+      name[0] = 'x';
+      name[1] = 'm';
+      name[2] = 'm';
+      name[3] = regno - 21 + '0';
+      namelen = 4;
+      break;
+
+    case 29 ... 36:
+      name[0] = 'm';
+      name[1] = 'm';
+      name[2] = regno - 29 + '0';
+      namelen = 3;
+      break;
+
+    case 37:
+      *bits = 16;
+      return stpcpy (name, "fctrl") + 1 - name;
+    case 38:
+      *bits = 16;
+      return stpcpy (name, "fstat") + 1 - name;
+    case 39:
+      return stpcpy (name, "mxcsr") + 1 - name;
+
+    case 40 ... 45:
+      name[0] = "ecsdfg"[regno - 40];
+      name[1] = 's';
+      namelen = 2;
+      break;
+
+    default:
+      *setname = NULL;
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
diff --git a/third_party/elfutils/backends/i386_reloc.def b/third_party/elfutils/backends/i386_reloc.def
new file mode 100644
index 0000000..a6a03f3
--- /dev/null
+++ b/third_party/elfutils/backends/i386_reloc.def
@@ -0,0 +1,71 @@
+/* List the relocation types for i386.	-*- C -*-
+   Copyright (C) 2000, 2001, 2002, 2003, 2005, 2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,		0)
+RELOC_TYPE (COPY,		EXEC|DYN)
+RELOC_TYPE (32,			REL|EXEC|DYN)
+RELOC_TYPE (PC32,		REL|EXEC|DYN)
+RELOC_TYPE (GOT32,		REL)
+RELOC_TYPE (PLT32,		REL)
+RELOC_TYPE (GLOB_DAT,		EXEC|DYN)
+RELOC_TYPE (JMP_SLOT,		EXEC|DYN)
+RELOC_TYPE (RELATIVE,		EXEC|DYN)
+RELOC_TYPE (GOTOFF,		REL)
+RELOC_TYPE (GOTPC,		REL)
+RELOC_TYPE (32PLT,		REL)
+RELOC_TYPE (TLS_TPOFF,		EXEC|DYN)
+RELOC_TYPE (TLS_IE,		REL)
+RELOC_TYPE (TLS_GOTIE,		REL)
+RELOC_TYPE (TLS_LE,		REL)
+RELOC_TYPE (TLS_GD,		REL)
+RELOC_TYPE (TLS_LDM,		REL)
+RELOC_TYPE (16,			REL)
+RELOC_TYPE (PC16,		REL)
+RELOC_TYPE (8,			REL)
+RELOC_TYPE (PC8,		REL)
+RELOC_TYPE (TLS_GD_32,		REL)
+RELOC_TYPE (TLS_GD_PUSH,	REL)
+RELOC_TYPE (TLS_GD_CALL,	REL)
+RELOC_TYPE (TLS_GD_POP,		REL)
+RELOC_TYPE (TLS_LDM_32,		REL)
+RELOC_TYPE (TLS_LDM_PUSH,	REL)
+RELOC_TYPE (TLS_LDM_CALL,	REL)
+RELOC_TYPE (TLS_LDM_POP,	REL)
+RELOC_TYPE (TLS_LDO_32,		REL)
+RELOC_TYPE (TLS_IE_32,		REL)
+RELOC_TYPE (TLS_LE_32,		REL)
+RELOC_TYPE (TLS_DTPMOD32,	EXEC|DYN)
+RELOC_TYPE (TLS_DTPOFF32,	EXEC|DYN)
+RELOC_TYPE (TLS_TPOFF32,	EXEC|DYN)
+RELOC_TYPE (TLS_GOTDESC,	REL)
+RELOC_TYPE (TLS_DESC_CALL,	REL)
+RELOC_TYPE (TLS_DESC,		EXEC)
+RELOC_TYPE (IRELATIVE,		EXEC|DYN)
+RELOC_TYPE (GOT32X,		REL)
diff --git a/third_party/elfutils/backends/i386_retval.c b/third_party/elfutils/backends/i386_retval.c
new file mode 100644
index 0000000..32fec72
--- /dev/null
+++ b/third_party/elfutils/backends/i386_retval.c
@@ -0,0 +1,140 @@
+/* Function return value location for Linux/i386 ABI.
+   Copyright (C) 2005-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+
+/* %eax, or pair %eax, %edx.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+#define nloc_intreg	1
+#define nloc_intregpair	4
+
+/* %st(0).  */
+static const Dwarf_Op loc_fpreg[] =
+  {
+    { .atom = DW_OP_reg11 }
+  };
+#define nloc_fpreg	1
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in %eax.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_breg0, .number = 0 }
+  };
+#define nloc_aggregate 1
+
+int
+i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Word size;
+	Dwarf_Attribute attr_mem;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+						   &attr_mem), &size) != 0)
+	  {
+	    if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	      size = 4;
+	    else
+	      return -1;
+	  }
+	if (tag == DW_TAG_base_type)
+	  {
+	    Dwarf_Word encoding;
+	    if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+						       &attr_mem),
+				 &encoding) != 0)
+	      return -1;
+	    if (encoding == DW_ATE_float)
+	      {
+		if (size > 16)
+		  return -2;
+		*locp = loc_fpreg;
+		return nloc_fpreg;
+	      }
+	  }
+	*locp = loc_intreg;
+	if (size <= 4)
+	  return nloc_intreg;
+	if (size <= 8)
+	  return nloc_intregpair;
+      }
+    FALLTHROUGH;
+
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+    case DW_TAG_array_type:
+      *locp = loc_aggregate;
+      return nloc_aggregate;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/i386_symbol.c b/third_party/elfutils/backends/i386_symbol.c
new file mode 100644
index 0000000..7dbf899
--- /dev/null
+++ b/third_party/elfutils/backends/i386_symbol.c
@@ -0,0 +1,75 @@
+/* i386 specific symbolic name handling.
+   Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+
+/* Return true if the symbol type is that referencing the GOT.  */
+bool
+i386_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type)
+{
+  return type == R_386_GOTPC;
+}
+
+/* Check for the simple reloc types.  */
+Elf_Type
+i386_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_386_32:
+      return ELF_T_SWORD;
+    case R_386_16:
+      return ELF_T_HALF;
+    case R_386_8:
+      return ELF_T_BYTE;
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+/* Check section name for being that of a debug information section.  */
+bool (*generic_debugscn_p) (const char *);
+bool
+i386_debugscn_p (const char *name)
+{
+  return (generic_debugscn_p (name)
+	  || strcmp (name, ".stab") == 0
+	  || strcmp (name, ".stabstr") == 0);
+}
diff --git a/third_party/elfutils/backends/i386_syscall.c b/third_party/elfutils/backends/i386_syscall.c
new file mode 100644
index 0000000..535dcd8
--- /dev/null
+++ b/third_party/elfutils/backends/i386_syscall.c
@@ -0,0 +1,50 @@
+/* Linux/i386 system call ABI in DWARF register numbers.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+int
+i386_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+		  int *sp, int *pc, int *callno, int args[6])
+{
+  *sp = 4;			/* %esp */
+  *pc = 8;			/* %eip */
+  *callno = 0;			/* %eax */
+  args[0] = 3;			/* %ebx */
+  args[1] = 1;			/* %ecx */
+  args[2] = 2;			/* %edx */
+  args[3] = 6;			/* %esi */
+  args[4] = 7;			/* %edi */
+  args[5] = 5;			/* %ebp */
+  return 0;
+}
diff --git a/third_party/elfutils/backends/i386_unwind.c b/third_party/elfutils/backends/i386_unwind.c
new file mode 100644
index 0000000..5c9a5de
--- /dev/null
+++ b/third_party/elfutils/backends/i386_unwind.c
@@ -0,0 +1,84 @@
+/* Get previous frame state for an existing frame state using frame pointers.
+   Copyright (C) 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+/* Register numbers for frame and stack pointers.  We take advantage of
+   them being next to each other when calling getfunc and setfunc.  */
+#define ESP 4
+#define EBP (ESP + 1)
+
+/* Most basic frame pointer chasing with EBP as frame pointer.
+   PC = *(FP + 4), SP = FP + 8, FP = *FP.  */
+bool
+i386_unwind (Ebl *ebl __attribute__ ((unused)),
+	     Dwarf_Addr pc __attribute__ ((unused)),
+	     ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc,
+	     ebl_pid_memory_read_t *readfunc, void *arg,
+	     bool *signal_framep __attribute__ ((unused)))
+{
+  /* sp = 0, fp = 1 */
+  Dwarf_Word regs[2];
+
+  /* Get current stack and frame pointers.  */
+  if (! getfunc (ESP, 2, regs, arg))
+    return false;
+
+  Dwarf_Word sp = regs[0];
+  Dwarf_Word fp = regs[1];
+
+  /* Sanity check.  We only support traditional stack frames.  */
+  if (fp == 0 || sp == 0 || fp < sp)
+    return false;
+
+  /* Get the return address from the stack, it is our new pc.  */
+  Dwarf_Word ret_addr;
+  if (! readfunc (fp + 4, &ret_addr, arg) || ret_addr == 0)
+    return false;
+
+  /* Get new sp and fp.  Sanity check again.  */
+  sp = fp + 8;
+  if (! readfunc (fp, &fp, arg) || fp == 0 || sp >= fp)
+    return false;
+
+  /* Set new sp, fp and pc.  */
+  regs[0] = sp;
+  regs[1] = fp;
+  if (! setfunc (ESP, 2, regs, arg) || ! setfunc (-1, 1, &ret_addr, arg))
+    return false;
+
+  return true;
+}
diff --git a/third_party/elfutils/backends/ia64_init.c b/third_party/elfutils/backends/ia64_init.c
new file mode 100644
index 0000000..7241d7b
--- /dev/null
+++ b/third_party/elfutils/backends/ia64_init.c
@@ -0,0 +1,66 @@
+/* Initialization of IA-64 specific backend library.
+   Copyright (C) 2002, 2003, 2005, 2006, 2007, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		ia64_
+#define RELOC_PREFIX	R_IA64_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on ia64_reloc.def.  */
+#include "common-reloc.c"
+
+const char *
+ia64_init (Elf *elf __attribute__ ((unused)),
+	   GElf_Half machine __attribute__ ((unused)),
+	   Ebl *eh,
+	   size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "Intel IA-64";
+  ia64_init_reloc (eh);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, segment_type_name);
+  HOOK (eh, section_type_name);
+  HOOK (eh, dynamic_tag_name);
+  HOOK (eh, dynamic_tag_check);
+  HOOK (eh, machine_flag_check);
+  HOOK (eh, machine_section_flag_check);
+  HOOK (eh, register_info);
+  HOOK (eh, return_value_location);
+  HOOK (eh, check_reloc_target_type);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/ia64_regs.c b/third_party/elfutils/backends/ia64_regs.c
new file mode 100644
index 0000000..a27fe63
--- /dev/null
+++ b/third_party/elfutils/backends/ia64_regs.c
@@ -0,0 +1,273 @@
+/* Register names and numbers for IA64 DWARF.
+   Copyright (C) 2006 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND i386_
+#include "libebl_CPU.h"
+
+ssize_t
+ia64_register_info (Ebl *ebl __attribute__ ((unused)),
+		    int regno, char *name, size_t namelen,
+		    const char **prefix, const char **setname,
+		    int *bits, int *type)
+{
+  if (name == NULL)
+    return 687 + 64;
+
+  if (regno < 0 || regno > 687 + 63 || namelen < 12)
+    return -1;
+
+  *prefix = "ar.";
+  *setname = "application";
+  *bits = 64;
+  *type = DW_ATE_signed;
+  switch (regno)
+    {
+    case 0 ... 9:
+      name[0] = 'r';
+      name[1] = (regno - 0) + '0';
+      namelen = 2;
+      *setname = "integer";
+      *prefix = "";
+      break;
+
+    case 10 ... 99:
+      name[0] = 'r';
+      name[1] = (regno - 0) / 10 + '0';
+      name[2] = (regno - 0) % 10 + '0';
+      namelen = 3;
+      *setname = "integer";
+      *prefix = "";
+      break;
+
+    case 100 ... 127:
+      name[0] = 'r';
+      name[1] = '1';
+      name[2] = (regno - 100) / 10 + '0';
+      name[3] = (regno - 0) % 10 + '0';
+      namelen = 4;
+      *setname = "integer";
+      *prefix = "";
+      break;
+
+    case 128 + 0 ... 128 + 9:
+      name[0] = 'f';
+      name[1] = (regno - 128) + '0';
+      namelen = 2;
+      *type = DW_ATE_float;
+      *bits = 128;
+      *setname = "FPU";
+      *prefix = "";
+      break;
+
+    case 128 + 10 ... 128 + 99:
+      name[0] = 'f';
+      name[1] = (regno - 128) / 10 + '0';
+      name[2] = (regno - 128) % 10 + '0';
+      namelen = 3;
+      *setname = "FPU";
+      *prefix = "";
+      break;
+
+    case 128 + 100 ... 128 + 127:
+      name[0] = 'f';
+      name[1] = '1';
+      name[2] = (regno - 128 - 100) / 10 + '0';
+      name[3] = (regno - 128) % 10 + '0';
+      namelen = 4;
+      *type = DW_ATE_float;
+      *bits = 128;
+      *setname = "FPU";
+      *prefix = "";
+      break;
+
+    case 320 + 0 ... 320 + 7:
+      name[0] = 'b';
+      name[1] = (regno - 320) + '0';
+      namelen = 2;
+      *type = DW_ATE_address;
+      *setname = "branch";
+      *prefix = "";
+      break;
+
+    case 328 ... 333:
+      {
+	static const char named_special[][5] =
+	  {
+	    "vfp", "vrap", "pr", "ip", "psr", "cfm"
+	  };
+	*setname = "special";
+	*prefix = "";
+	*type = regno == 331 ? DW_ATE_address : DW_ATE_unsigned;
+	return stpcpy (name, named_special[regno - 328]) + 1 - name;
+      }
+
+    case 590:
+      *setname = "special";
+      *prefix = "";
+      *type = DW_ATE_unsigned;
+      return stpcpy (name, "bof") + 1 - name;
+
+    case 334 + 0 ... 334 + 7:
+      name[0] = 'k';
+      name[1] = 'r';
+      name[2] = (regno - 334) + '0';
+      namelen = 3;
+      *prefix = "";
+      break;
+
+    case 334 + 8 ... 334 + 127:
+      {
+	static const char named_ar[][9] =
+	  {
+	    [16 - 8] = "rsc",
+	    [17 - 8] = "bsp",
+	    [18 - 8] = "bspstore",
+	    [19 - 8] = "rnat",
+	    [21 - 8] = "fcr",
+	    [24 - 8] = "eflag",
+	    [25 - 8] = "csd",
+	    [26 - 8] = "ssd",
+	    [27 - 8] = "cflg",
+	    [28 - 8] = "fsr",
+	    [29 - 8] = "fir",
+	    [30 - 8] = "fdr",
+	    [32 - 8] = "ccv",
+	    [36 - 8] = "unat",
+	    [40 - 8] = "fpsr",
+	    [44 - 8] = "itc",
+	    [64 - 8] = "pfs",
+	    [65 - 8] = "lc",
+	    [66 - 8] = "ec",
+	  };
+	const size_t idx = regno - (334 + 8);
+	*type = DW_ATE_unsigned;
+	if (idx == 1 || idx == 2)
+	  *type = DW_ATE_address;
+	if (idx < sizeof named_ar / sizeof named_ar[0]
+	    && named_ar[idx][0] != '\0')
+	  return stpcpy (name, named_ar[idx]) + 1 - name;
+
+	name[0] = 'a';
+	name[1] = 'r';
+	switch (regno - 334)
+	  {
+	  case 0 ... 9:
+	    name[2] = (regno - 334) + '0';
+	    namelen = 3;
+	    break;
+	  case 10 ... 99:
+	    name[2] = (regno - 334) / 10 + '0';
+	    name[3] = (regno - 334) % 10 + '0';
+	    namelen = 4;
+	    break;
+	  case 100 ... 127:
+	    name[2] = '1';
+	    name[3] = (regno - 334 - 100) / 10 + '0';
+	    name[4] = (regno - 334) % 10 + '0';
+	    namelen = 5;
+	    break;
+	  }
+	*prefix = "";
+	break;
+      }
+
+    case 462 + 0 ... 462 + 9:
+      name[0] = 'n';
+      name[1] = 'a';
+      name[2] = 't';
+      name[3] = (regno - 462) + '0';
+      namelen = 4;
+      *setname = "NAT";
+      *type = DW_ATE_boolean;
+      *bits = 1;
+      *prefix = "";
+      break;
+
+    case 462 + 10 ... 462 + 99:
+      name[0] = 'n';
+      name[1] = 'a';
+      name[2] = 't';
+      name[3] = (regno - 462) / 10 + '0';
+      name[4] = (regno - 462) % 10 + '0';
+      namelen = 5;
+      *setname = "NAT";
+      *type = DW_ATE_boolean;
+      *bits = 1;
+      *prefix = "";
+      break;
+
+    case 462 + 100 ... 462 + 127:
+      name[0] = 'n';
+      name[1] = 'a';
+      name[2] = 't';
+      name[3] = '1';
+      name[4] = (regno - 462 - 100) / 10 + '0';
+      name[5] = (regno - 462) % 10 + '0';
+      namelen = 6;
+      *setname = "NAT";
+      *type = DW_ATE_boolean;
+      *bits = 1;
+      *prefix = "";
+      break;
+
+    case 687 + 0 ... 687 + 9:
+      name[0] = 'p';
+      name[1] = (regno - 687) + '0';
+      namelen = 2;
+      *setname = "predicate";
+      *type = DW_ATE_boolean;
+      *bits = 1;
+      *prefix = "";
+      break;
+
+    case 687 + 10 ... 687 + 63:
+      name[0] = 'p';
+      name[1] = (regno - 687) / 10 + '0';
+      name[2] = (regno - 687) % 10 + '0';
+      namelen = 3;
+      *setname = "predicate";
+      *type = DW_ATE_boolean;
+      *bits = 1;
+      *prefix = "";
+      break;
+
+    default:
+      *setname = NULL;
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
diff --git a/third_party/elfutils/backends/ia64_reloc.def b/third_party/elfutils/backends/ia64_reloc.def
new file mode 100644
index 0000000..2428925
--- /dev/null
+++ b/third_party/elfutils/backends/ia64_reloc.def
@@ -0,0 +1,113 @@
+/* List the relocation types for ia64.  -*- C -*-
+   Copyright (C) 2005, 2006, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,		0)
+RELOC_TYPE (IMM14,		REL)
+RELOC_TYPE (IMM22,		REL)
+RELOC_TYPE (IMM64,		REL)
+RELOC_TYPE (DIR32MSB,		REL|EXEC|DYN)
+RELOC_TYPE (DIR32LSB,		REL|EXEC|DYN)
+RELOC_TYPE (DIR64MSB,		REL|EXEC|DYN)
+RELOC_TYPE (DIR64LSB,		REL|EXEC|DYN)
+RELOC_TYPE (GPREL22,		REL)
+RELOC_TYPE (GPREL64I,		REL)
+RELOC_TYPE (GPREL32MSB,		REL)
+RELOC_TYPE (GPREL32LSB,		REL)
+RELOC_TYPE (GPREL64MSB,		REL)
+RELOC_TYPE (GPREL64LSB,		REL)
+RELOC_TYPE (LTOFF22,		REL)
+RELOC_TYPE (LTOFF64I,		REL)
+RELOC_TYPE (PLTOFF22,		REL)
+RELOC_TYPE (PLTOFF64I,		REL)
+RELOC_TYPE (PLTOFF64MSB,	REL)
+RELOC_TYPE (PLTOFF64LSB,	REL)
+RELOC_TYPE (FPTR64I,		REL)
+RELOC_TYPE (FPTR32MSB,		REL|EXEC|DYN)
+RELOC_TYPE (FPTR32LSB,		REL|EXEC|DYN)
+RELOC_TYPE (FPTR64MSB,		REL|EXEC|DYN)
+RELOC_TYPE (FPTR64LSB,		REL|EXEC|DYN)
+RELOC_TYPE (PCREL60B,		REL)
+RELOC_TYPE (PCREL21B,		REL)
+RELOC_TYPE (PCREL21M,		REL)
+RELOC_TYPE (PCREL21F,		REL)
+RELOC_TYPE (PCREL32MSB,		REL|EXEC|DYN)
+RELOC_TYPE (PCREL32LSB,		REL|EXEC|DYN)
+RELOC_TYPE (PCREL64MSB,		REL|EXEC|DYN)
+RELOC_TYPE (PCREL64LSB,		REL|EXEC|DYN)
+RELOC_TYPE (LTOFF_FPTR22,	REL)
+RELOC_TYPE (LTOFF_FPTR64I,	REL)
+RELOC_TYPE (LTOFF_FPTR32MSB,	REL)
+RELOC_TYPE (LTOFF_FPTR32LSB,	REL)
+RELOC_TYPE (LTOFF_FPTR64MSB,	REL)
+RELOC_TYPE (LTOFF_FPTR64LSB,	REL)
+RELOC_TYPE (SEGREL32MSB,	REL)
+RELOC_TYPE (SEGREL32LSB,	REL)
+RELOC_TYPE (SEGREL64MSB,	REL)
+RELOC_TYPE (SEGREL64LSB,	REL)
+RELOC_TYPE (SECREL32MSB,	REL)
+RELOC_TYPE (SECREL32LSB,	REL)
+RELOC_TYPE (SECREL64MSB,	REL)
+RELOC_TYPE (SECREL64LSB,	REL)
+RELOC_TYPE (REL32MSB,		EXEC|DYN)
+RELOC_TYPE (REL32LSB,		EXEC|DYN)
+RELOC_TYPE (REL64MSB,		EXEC|DYN)
+RELOC_TYPE (REL64LSB,		EXEC|DYN)
+RELOC_TYPE (LTV32MSB,		REL)
+RELOC_TYPE (LTV32LSB,		REL)
+RELOC_TYPE (LTV64MSB,		REL)
+RELOC_TYPE (LTV64LSB,		REL)
+RELOC_TYPE (PCREL21BI,		REL)
+RELOC_TYPE (PCREL22,		REL)
+RELOC_TYPE (PCREL64I,		REL)
+RELOC_TYPE (IPLTMSB,		REL|EXEC|DYN)
+RELOC_TYPE (IPLTLSB,		REL|EXEC|DYN)
+RELOC_TYPE (COPY,		EXEC|DYN)
+RELOC_TYPE (SUB,		0)
+RELOC_TYPE (LTOFF22X,		REL)
+RELOC_TYPE (LDXMOV,		REL)
+RELOC_TYPE (TPREL14,		REL)
+RELOC_TYPE (TPREL22,		REL)
+RELOC_TYPE (TPREL64I,		REL)
+RELOC_TYPE (TPREL64MSB,		REL|EXEC|DYN)
+RELOC_TYPE (TPREL64LSB,		REL|EXEC|DYN)
+RELOC_TYPE (LTOFF_TPREL22,	REL)
+RELOC_TYPE (DTPMOD64MSB,	REL|EXEC|DYN)
+RELOC_TYPE (DTPMOD64LSB,	REL|EXEC|DYN)
+RELOC_TYPE (LTOFF_DTPMOD22,	REL)
+RELOC_TYPE (DTPREL14,		REL)
+RELOC_TYPE (DTPREL22,		REL)
+RELOC_TYPE (DTPREL64I,		REL)
+RELOC_TYPE (DTPREL32MSB,	REL|EXEC|DYN)
+RELOC_TYPE (DTPREL32LSB,	REL|EXEC|DYN)
+RELOC_TYPE (DTPREL64MSB,	REL|EXEC|DYN)
+RELOC_TYPE (DTPREL64LSB,	REL|EXEC|DYN)
+RELOC_TYPE (LTOFF_DTPREL22,	REL)
+
+#define NO_RELATIVE_RELOC	1
diff --git a/third_party/elfutils/backends/ia64_retval.c b/third_party/elfutils/backends/ia64_retval.c
new file mode 100644
index 0000000..03ea4d8
--- /dev/null
+++ b/third_party/elfutils/backends/ia64_retval.c
@@ -0,0 +1,366 @@
+/* Function return value location for IA64 ABI.
+   Copyright (C) 2006-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND ia64_
+#include "libebl_CPU.h"
+
+
+/* r8, or pair r8, r9, or aggregate up to r8-r11.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg8 }, { .atom = DW_OP_piece, .number = 8 },
+    { .atom = DW_OP_reg9 }, { .atom = DW_OP_piece, .number = 8 },
+    { .atom = DW_OP_reg10 }, { .atom = DW_OP_piece, .number = 8 },
+    { .atom = DW_OP_reg11 }, { .atom = DW_OP_piece, .number = 8 },
+  };
+#define nloc_intreg	1
+#define nloc_intregs(n)	(2 * (n))
+
+/* f8, or aggregate up to f8-f15.  */
+#define DEFINE_FPREG(size) 						      \
+  static const Dwarf_Op loc_fpreg_##size[] =				      \
+    {									      \
+      { .atom = DW_OP_regx, .number = 128 + 8 },			      \
+      { .atom = DW_OP_piece, .number = size },				      \
+      { .atom = DW_OP_regx, .number = 128 + 9 },			      \
+      { .atom = DW_OP_piece, .number = size },				      \
+      { .atom = DW_OP_regx, .number = 128 + 10 },			      \
+      { .atom = DW_OP_piece, .number = size },				      \
+      { .atom = DW_OP_regx, .number = 128 + 11 },			      \
+      { .atom = DW_OP_piece, .number = size },				      \
+      { .atom = DW_OP_regx, .number = 128 + 12 },			      \
+      { .atom = DW_OP_piece, .number = size },				      \
+      { .atom = DW_OP_regx, .number = 128 + 13 },			      \
+      { .atom = DW_OP_piece, .number = size },				      \
+      { .atom = DW_OP_regx, .number = 128 + 14 },			      \
+      { .atom = DW_OP_piece, .number = size },				      \
+      { .atom = DW_OP_regx, .number = 128 + 15 },			      \
+      { .atom = DW_OP_piece, .number = size },				      \
+    }
+#define nloc_fpreg	1
+#define nloc_fpregs(n)	(2 * (n))
+
+DEFINE_FPREG (4);
+DEFINE_FPREG (8);
+DEFINE_FPREG (10);
+
+#undef DEFINE_FPREG
+
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in r8.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_breg8, .number = 0 }
+  };
+#define nloc_aggregate 1
+
+
+static inline int
+compute_hfa (const Dwarf_Op *loc, int nregs,
+	     const Dwarf_Op **locp, int fpregs_used)
+{
+  if (fpregs_used == 0)
+    *locp = loc;
+  else if (*locp != loc)
+    return 9;
+  return fpregs_used + nregs;
+}
+
+/* If this type is an HFA small enough to be returned in FP registers,
+   return the number of registers to use.  Otherwise 9, or -1 for errors.  */
+static int
+hfa_type (Dwarf_Die *typedie, Dwarf_Word size,
+	  const Dwarf_Op **locp, int fpregs_used)
+{
+  /* Descend the type structure, counting elements and finding their types.
+     If we find a datum that's not an FP type (and not quad FP), punt.
+     If we find a datum that's not the same FP type as the first datum, punt.
+     If we count more than eight total homogeneous FP data, punt.  */
+
+  int tag = DWARF_TAG_OR_RETURN (typedie);
+  switch (tag)
+    {
+      Dwarf_Attribute attr_mem;
+
+    case -1:
+      return -1;
+
+    case DW_TAG_base_type:;
+      Dwarf_Word encoding;
+      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+						 &attr_mem), &encoding) != 0)
+	return -1;
+
+#define hfa(loc, nregs) compute_hfa(loc, nregs, locp, fpregs_used)
+      switch (encoding)
+	{
+	case DW_ATE_float:
+	  switch (size)
+	    {
+	    case 4:		/* float */
+	      return hfa (loc_fpreg_4, 1);
+	    case 8:		/* double */
+	      return hfa (loc_fpreg_8, 1);
+	    case 10:       /* x86-style long double, not really used */
+	      return hfa (loc_fpreg_10, 1);
+	    }
+	  break;
+
+	case DW_ATE_complex_float:
+	  switch (size)
+	    {
+	    case 4 * 2:	/* complex float */
+	      return hfa (loc_fpreg_4, 2);
+	    case 8 * 2:	/* complex double */
+	      return hfa (loc_fpreg_8, 2);
+	    case 10 * 2:	/* complex long double (x86-style) */
+	      return hfa (loc_fpreg_10, 2);
+	    }
+	  break;
+	}
+      break;
+
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:;
+      Dwarf_Die child_mem;
+      switch (dwarf_child (typedie, &child_mem))
+	{
+	default:
+	  return -1;
+
+	case 1:			/* No children: empty struct.  */
+	  break;
+
+	case 0:;		/* Look at each element.  */
+	  int max_used = fpregs_used;
+	  do
+	    switch (dwarf_tag (&child_mem))
+	      {
+	      case -1:
+		return -1;
+
+	      case DW_TAG_member:;
+		Dwarf_Die child_type_mem;
+		Dwarf_Die *child_typedie
+		  = dwarf_formref_die (dwarf_attr_integrate (&child_mem,
+							     DW_AT_type,
+							     &attr_mem),
+				       &child_type_mem);
+		Dwarf_Word child_size;
+		if (dwarf_aggregate_size (child_typedie, &child_size) != 0)
+		  return -1;
+		if (tag == DW_TAG_union_type)
+		  {
+		    int used = hfa_type (child_typedie, child_size,
+					 locp, fpregs_used);
+		    if (used < 0 || used > 8)
+		      return used;
+		    if (used > max_used)
+		      max_used = used;
+		  }
+		else
+		  {
+		    fpregs_used = hfa_type (child_typedie, child_size,
+					    locp, fpregs_used);
+		    if (fpregs_used < 0 || fpregs_used > 8)
+		      return fpregs_used;
+		  }
+	      }
+	  while (dwarf_siblingof (&child_mem, &child_mem) == 0);
+	  if (tag == DW_TAG_union_type)
+	    fpregs_used = max_used;
+	  break;
+	}
+      break;
+
+    case DW_TAG_array_type:
+      if (size == 0)
+	break;
+
+      Dwarf_Die base_type_mem;
+      Dwarf_Die *base_typedie
+	= dwarf_formref_die (dwarf_attr_integrate (typedie, DW_AT_type,
+						   &attr_mem),
+			     &base_type_mem);
+      Dwarf_Word base_size;
+      if (dwarf_aggregate_size (base_typedie, &base_size) != 0)
+	return -1;
+
+      int used = hfa_type (base_typedie, base_size, locp, 0);
+      if (used < 0 || used > 8)
+	return used;
+      if (size % (*locp)[1].number != 0)
+	return 0;
+      fpregs_used += used * (size / (*locp)[1].number);
+      break;
+
+    default:
+      return 9;
+    }
+
+  return fpregs_used;
+}
+
+int
+ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  Dwarf_Word size;
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Attribute attr_mem;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+						   &attr_mem), &size) != 0)
+	  {
+	    if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	      size = 8;
+	    else
+	      return -1;
+	  }
+      }
+
+      if (tag == DW_TAG_base_type)
+	{
+	  Dwarf_Attribute attr_mem;
+	  Dwarf_Word encoding;
+	  if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+						     &attr_mem),
+			       &encoding) != 0)
+	    return -1;
+
+	  switch (encoding)
+	    {
+	    case DW_ATE_float:
+	      switch (size)
+		{
+		case 4:		/* float */
+		  *locp = loc_fpreg_4;
+		  return nloc_fpreg;
+		case 8:		/* double */
+		  *locp = loc_fpreg_8;
+		  return nloc_fpreg;
+		case 10:       /* x86-style long double, not really used */
+		  *locp = loc_fpreg_10;
+		  return nloc_fpreg;
+		case 16:	/* long double, IEEE quad format */
+		  *locp = loc_intreg;
+		  return nloc_intregs (2);
+		}
+	      return -2;
+
+	    case DW_ATE_complex_float:
+	      switch (size)
+		{
+		case 4 * 2:	/* complex float */
+		  *locp = loc_fpreg_4;
+		  return nloc_fpregs (2);
+		case 8 * 2:	/* complex double */
+		  *locp = loc_fpreg_8;
+		  return nloc_fpregs (2);
+		case 10 * 2:	/* complex long double (x86-style) */
+		  *locp = loc_fpreg_10;
+		  return nloc_fpregs (2);
+		case 16 * 2:	/* complex long double (IEEE quad) */
+		  *locp = loc_intreg;
+		  return nloc_intregs (4);
+		}
+	      return -2;
+	    }
+	}
+
+    intreg:
+      *locp = loc_intreg;
+      if (size <= 8)
+	return nloc_intreg;
+      if (size <= 32)
+	return nloc_intregs ((size + 7) / 8);
+
+    large:
+      *locp = loc_aggregate;
+      return nloc_aggregate;
+
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+    case DW_TAG_array_type:
+      if (dwarf_aggregate_size (typedie, &size) != 0)
+	return -1;
+
+      /* If this qualifies as an homogeneous floating-point aggregate
+	 (HFA), then it should be returned in FP regs. */
+      int nfpreg = hfa_type (typedie, size, locp, 0);
+      if (nfpreg < 0)
+	return nfpreg;
+      else if (nfpreg > 0 && nfpreg <= 8)
+	return nfpreg == 1 ? nloc_fpreg : nloc_fpregs (nfpreg);
+
+      if (size > 32)
+	goto large;
+
+      goto intreg;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/ia64_symbol.c b/third_party/elfutils/backends/ia64_symbol.c
new file mode 100644
index 0000000..f928b0b
--- /dev/null
+++ b/third_party/elfutils/backends/ia64_symbol.c
@@ -0,0 +1,157 @@
+/* IA-64 specific symbolic name handling.
+   Copyright (C) 2002-2009, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+#include <assert.h>
+
+#define BACKEND		ia64_
+#include "libebl_CPU.h"
+
+
+const char *
+ia64_segment_type_name (int segment, char *buf __attribute__ ((unused)),
+			size_t len __attribute__ ((unused)))
+{
+  switch (segment)
+    {
+    case PT_IA_64_ARCHEXT:
+      return "IA_64_ARCHEXT";
+    case PT_IA_64_UNWIND:
+      return "IA_64_UNWIND";
+    case PT_IA_64_HP_OPT_ANOT:
+      return "IA_64_HP_OPT_ANOT";
+    case PT_IA_64_HP_HSL_ANOT:
+      return "IA_64_HP_HSL_ANOT";
+    case PT_IA_64_HP_STACK:
+      return "IA_64_HP_STACK";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+const char *
+ia64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+		       size_t len __attribute__ ((unused)))
+{
+  switch (tag)
+    {
+    case DT_IA_64_PLT_RESERVE:
+      return "IA_64_PLT_RESERVE";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+/* Check dynamic tag.  */
+bool
+ia64_dynamic_tag_check (int64_t tag)
+{
+  return tag == DT_IA_64_PLT_RESERVE;
+}
+
+/* Check whether machine flags are valid.  */
+bool
+ia64_machine_flag_check (GElf_Word flags)
+{
+  return ((flags &~ EF_IA_64_ABI64) == 0);
+}
+
+/* Check whether SHF_MASKPROC flags are valid.  */
+bool
+ia64_machine_section_flag_check (GElf_Xword sh_flags)
+{
+  return (sh_flags &~ (SHF_IA_64_SHORT | SHF_IA_64_NORECOV)) == 0;
+}
+
+/* Return symbolic representation of section type.  */
+const char *
+ia64_section_type_name (int type,
+			char *buf __attribute__ ((unused)),
+			size_t len __attribute__ ((unused)))
+{
+  switch (type)
+    {
+    case SHT_IA_64_EXT:
+      return "IA_64_EXT";
+    case SHT_IA_64_UNWIND:
+      return "IA_64_UNWIND";
+    }
+
+  return NULL;
+}
+
+/* Check for the simple reloc types.  */
+Elf_Type
+ia64_reloc_simple_type (Ebl *ebl, int type)
+{
+  switch (type)
+    {
+      /* The SECREL types when used with non-allocated sections
+	 like .debug_* are the same as direct absolute relocs
+	 applied to those sections, since a 0 section address is assumed.
+	 So we treat them the same here.  */
+
+    case R_IA64_SECREL32MSB:
+    case R_IA64_DIR32MSB:
+      if (ebl->data == ELFDATA2MSB)
+	return ELF_T_WORD;
+      break;
+    case R_IA64_SECREL32LSB:
+    case R_IA64_DIR32LSB:
+      if (ebl->data == ELFDATA2LSB)
+	return ELF_T_WORD;
+      break;
+    case R_IA64_DIR64MSB:
+    case R_IA64_SECREL64MSB:
+      if (ebl->data == ELFDATA2MSB)
+	return ELF_T_XWORD;
+      break;
+    case R_IA64_SECREL64LSB:
+    case R_IA64_DIR64LSB:
+      if (ebl->data == ELFDATA2LSB)
+	return ELF_T_XWORD;
+      break;
+    }
+
+  return ELF_T_NUM;
+}
+
+/* The SHT_IA_64_UNWIND section type is a valid target for relocation.  */
+bool
+ia64_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), Elf64_Word sh_type)
+{
+  return sh_type == SHT_IA_64_UNWIND;
+}
diff --git a/third_party/elfutils/backends/libebl_CPU.h b/third_party/elfutils/backends/libebl_CPU.h
new file mode 100644
index 0000000..ef2b922
--- /dev/null
+++ b/third_party/elfutils/backends/libebl_CPU.h
@@ -0,0 +1,76 @@
+/* Common interface for libebl modules.
+   Copyright (C) 2000, 2001, 2002, 2003, 2005, 2013, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBEBL_CPU_H
+#define _LIBEBL_CPU_H 1
+
+#include <dwarf.h>
+#include <libeblP.h>
+
+#define EBLHOOK(name)	EBLHOOK_1(BACKEND, name)
+#define EBLHOOK_1(a, b)	EBLHOOK_2(a, b)
+#define EBLHOOK_2(a, b)	a##b
+
+/* Constructor.  */
+extern const char *EBLHOOK(init) (Elf *elf, GElf_Half machine,
+				  Ebl *eh, size_t ehlen);
+
+#include "ebl-hooks.h"
+
+#define HOOK(eh, name)	eh->name = EBLHOOK(name)
+
+extern bool (*generic_debugscn_p) (const char *) attribute_hidden;
+
+/* Helper for retval.  Return dwarf_tag (die), but calls return -1
+   if there where previous errors that leave die NULL.  */
+#define DWARF_TAG_OR_RETURN(die)  \
+  ({ Dwarf_Die *_die = (die);	  \
+     if (_die == NULL) return -1; \
+     dwarf_tag (_die); })
+
+/* Get a type die corresponding to DIE.  Peel CV qualifiers off
+   it.  */
+static inline int
+dwarf_peeled_die_type (Dwarf_Die *die, Dwarf_Die *result)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Attribute *attr = dwarf_attr_integrate (die, DW_AT_type, &attr_mem);
+  if (attr == NULL)
+    /* The function has no return value, like a `void' function in C.  */
+    return 0;
+
+  if (dwarf_formref_die (attr, result) == NULL)
+    return -1;
+
+  if (dwarf_peel_type (result, result) != 0)
+    return -1;
+
+  return DWARF_TAG_OR_RETURN (result);
+}
+
+#endif	/* libebl_CPU.h */
diff --git a/third_party/elfutils/backends/linux-core-note.c b/third_party/elfutils/backends/linux-core-note.c
new file mode 100644
index 0000000..9faae4c
--- /dev/null
+++ b/third_party/elfutils/backends/linux-core-note.c
@@ -0,0 +1,315 @@
+/* Common core note type descriptions for Linux.
+   Copyright (C) 2007-2010 Red Hat, Inc.
+   Copyright (C) H.J. Lu <hjl.tools@gmail.com>, 2015.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <string.h>
+
+/* The including CPU_corenote.c file provides prstatus_regs and
+   defines macros ULONG, [PUG]ID_T, and ALIGN_*, TYPE_*.
+
+   Here we describe the common layout used in <linux/elfcore.h>.  */
+
+#define	CHAR			int8_t
+#define	ALIGN_CHAR		1
+#define	TYPE_CHAR		ELF_T_BYTE
+#define	SHORT			uint16_t
+#define ALIGN_SHORT		2
+#define TYPE_SHORT		ELF_T_HALF
+#define	INT			int32_t
+#ifndef ALIGN_INT
+# define ALIGN_INT		4
+#endif
+#define TYPE_INT		ELF_T_SWORD
+#ifndef PR_REG
+# define PR_REG			ULONG
+#endif
+#ifndef ALIGN_PR_REG
+# define ALIGN_PR_REG		ALIGN_ULONG
+#endif
+#ifndef PRPSINFO_UID_T
+# define PRPSINFO_UID_T		UID_T
+# define ALIGN_PRPSINFO_UID_T	ALIGN_UID_T
+# define TYPE_PRPSINFO_UID_T	TYPE_UID_T
+#endif
+#ifndef PRPSINFO_GID_T
+# define PRPSINFO_GID_T		GID_T
+# define ALIGN_PRPSINFO_GID_T	ALIGN_GID_T
+# define TYPE_PRPSINFO_GID_T	TYPE_GID_T
+#endif
+
+#define FIELD(type, name) type name __attribute__ ((aligned (ALIGN_##type)))
+
+struct EBLHOOK(siginfo)
+{
+  FIELD (INT, si_signo);
+  FIELD (INT, si_code);
+  FIELD (INT, si_errno);
+};
+
+struct EBLHOOK(timeval)
+{
+  FIELD (ULONG, tv_sec);
+  FIELD (ULONG, tv_usec);
+};
+
+/* On sparc64, tv_usec (suseconds_t) is actually 32 bits with 32 bits padding.
+   The 'T'|0x80 value for .format indicates this as a special kludge.  */
+#if SUSECONDS_HALF
+# define TIMEVAL_FIELD(name)	FIELD (time, ULONG, name, 'T'|0x80, .count = 2)
+#else
+# define TIMEVAL_FIELD(name)	FIELD (time, ULONG, name, 'T', .count = 2)
+#endif
+
+
+struct EBLHOOK(prstatus)
+{
+  struct EBLHOOK(siginfo) pr_info;
+  FIELD (SHORT, pr_cursig);
+  FIELD (ULONG, pr_sigpend);
+  FIELD (ULONG, pr_sighold);
+  FIELD (PID_T, pr_pid);
+  FIELD (PID_T, pr_ppid);
+  FIELD (PID_T, pr_pgrp);
+  FIELD (PID_T, pr_sid);
+  struct EBLHOOK(timeval) pr_utime;
+  struct EBLHOOK(timeval) pr_stime;
+  struct EBLHOOK(timeval) pr_cutime;
+  struct EBLHOOK(timeval) pr_cstime;
+  struct
+  {
+    FIELD (PR_REG, pr_reg[PRSTATUS_REGS_SIZE / sizeof (PR_REG)]);
+  }
+#ifdef ALIGN_PR_REG
+    __attribute__ ((aligned (ALIGN_PR_REG)))
+#endif
+    ;
+  FIELD (INT, pr_fpvalid);
+}
+#ifdef ALIGN_PRSTATUS
+  attribute_packed __attribute__ ((aligned (ALIGN_PRSTATUS)))
+#endif
+;
+
+#define	FNAMESZ	16
+#define	PRARGSZ	80
+
+struct EBLHOOK(prpsinfo)
+{
+  FIELD (CHAR, pr_state);
+  FIELD (CHAR, pr_sname);
+  FIELD (CHAR, pr_zomb);
+  FIELD (CHAR, pr_nice);
+  FIELD (ULONG, pr_flag);
+  FIELD (PRPSINFO_UID_T, pr_uid);
+  FIELD (PRPSINFO_GID_T, pr_gid);
+  FIELD (PID_T, pr_pid);
+  FIELD (PID_T, pr_ppid);
+  FIELD (PID_T, pr_pgrp);
+  FIELD (PID_T, pr_sid);
+  FIELD (CHAR, pr_fname[FNAMESZ]);
+  FIELD (CHAR, pr_psargs[PRARGSZ]);
+};
+
+#undef	FIELD
+
+#define FIELD(igroup, itype, item, fmt, ...)			\
+    {								\
+      .name = #item,						\
+      .group = #igroup,					\
+      .offset = offsetof (struct EBLHOOK(prstatus), pr_##item),	\
+      .type = TYPE_##itype,					\
+      .format = fmt,						\
+      __VA_ARGS__						\
+    }
+
+static const Ebl_Core_Item prstatus_items[] =
+  {
+    FIELD (signal, INT, info.si_signo, 'd'),
+    FIELD (signal, INT, info.si_code, 'd'),
+    FIELD (signal, INT, info.si_errno, 'd'),
+    FIELD (signal, SHORT, cursig, 'd'),
+
+    /* Use different group name for a newline delimiter.  */
+    FIELD (signal2, ULONG, sigpend, 'B'),
+    FIELD (signal3, ULONG, sighold, 'B'),
+    FIELD (identity, PID_T, pid, 'd', .thread_identifier = true),
+    FIELD (identity, PID_T, ppid, 'd'),
+    FIELD (identity, PID_T, pgrp, 'd'),
+    FIELD (identity, PID_T, sid, 'd'),
+    TIMEVAL_FIELD (utime),
+    TIMEVAL_FIELD (stime),
+    TIMEVAL_FIELD (cutime),
+    TIMEVAL_FIELD (cstime),
+#ifdef PRSTATUS_REGSET_ITEMS
+    PRSTATUS_REGSET_ITEMS,
+#endif
+    FIELD (register, INT, fpvalid, 'd'),
+  };
+
+#undef	FIELD
+
+#define FIELD(igroup, itype, item, fmt, ...)			\
+    {								\
+      .name = #item,						\
+      .group = #igroup,					\
+      .offset = offsetof (struct EBLHOOK(prpsinfo), pr_##item),	\
+      .type = TYPE_##itype,					\
+      .format = fmt,						\
+      __VA_ARGS__						\
+    }
+
+static const Ebl_Core_Item prpsinfo_items[] =
+  {
+    FIELD (state, CHAR, state, 'd'),
+    FIELD (state, CHAR, sname, 'c'),
+    FIELD (state, CHAR, zomb, 'd'),
+    FIELD (state, CHAR, nice, 'd'),
+    FIELD (state, ULONG, flag, 'x'),
+    FIELD (identity, PRPSINFO_UID_T, uid, 'd'),
+    FIELD (identity, PRPSINFO_GID_T, gid, 'd'),
+    FIELD (identity, PID_T, pid, 'd'),
+    FIELD (identity, PID_T, ppid, 'd'),
+    FIELD (identity, PID_T, pgrp, 'd'),
+    FIELD (identity, PID_T, sid, 'd'),
+    FIELD (command, CHAR, fname, 's', .count = FNAMESZ),
+    FIELD (command, CHAR, psargs, 's', .count = PRARGSZ),
+  };
+
+static const Ebl_Core_Item vmcoreinfo_items[] =
+  {
+    {
+      .type = ELF_T_BYTE, .format = '\n'
+    }
+  };
+
+#undef	FIELD
+
+int
+EBLHOOK(core_note) (const GElf_Nhdr *nhdr, const char *name,
+		    GElf_Word *regs_offset, size_t *nregloc,
+		    const Ebl_Register_Location **reglocs,
+		    size_t *nitems, const Ebl_Core_Item **items)
+{
+  switch (nhdr->n_namesz)
+    {
+    case sizeof "CORE" - 1:	/* Buggy old Linux kernels.  */
+      if (memcmp (name, "CORE", nhdr->n_namesz) == 0)
+	break;
+      return 0;
+
+    case sizeof "CORE":
+      if (memcmp (name, "CORE", nhdr->n_namesz) == 0)
+	break;
+      /* Buggy old Linux kernels didn't terminate "LINUX".  */
+      FALLTHROUGH;
+
+    case sizeof "LINUX":
+      if (memcmp (name, "LINUX", nhdr->n_namesz) == 0)
+	break;
+      return 0;
+
+    case sizeof "VMCOREINFO":
+      if (nhdr->n_type != 0
+	  || memcmp (name, "VMCOREINFO", sizeof "VMCOREINFO") != 0)
+	return 0;
+      *regs_offset = 0;
+      *nregloc = 0;
+      *nitems = 1;
+      *items = vmcoreinfo_items;
+      return 1;
+
+    default:
+      return 0;
+    }
+
+  switch (nhdr->n_type)
+    {
+    case NT_PRSTATUS:
+      if (nhdr->n_descsz != sizeof (struct EBLHOOK(prstatus)))
+	return 0;
+      *regs_offset = offsetof (struct EBLHOOK(prstatus), pr_reg);
+      *nregloc = sizeof prstatus_regs / sizeof prstatus_regs[0];
+      *reglocs = prstatus_regs;
+      *nitems = sizeof prstatus_items / sizeof prstatus_items[0];
+      *items = prstatus_items;
+      return 1;
+
+    case NT_PRPSINFO:
+      if (nhdr->n_descsz != sizeof (struct EBLHOOK(prpsinfo)))
+	return 0;
+      *regs_offset = 0;
+      *nregloc = 0;
+      *reglocs = NULL;
+      *nitems = sizeof prpsinfo_items / sizeof prpsinfo_items[0];
+      *items = prpsinfo_items;
+      return 1;
+
+#define EXTRA_REGSET(type, size, table)					      \
+    case type:								      \
+      if (nhdr->n_descsz != size)					      \
+	return 0;							      \
+      *regs_offset = 0;							      \
+      *nregloc = sizeof table / sizeof table[0];			      \
+      *reglocs = table;							      \
+      *nitems = 0;							      \
+      *items = NULL;							      \
+      return 1;
+
+#define EXTRA_REGSET_ITEMS(type, size, table, extra_items)		      \
+    case type:								      \
+      if (nhdr->n_descsz != size)					      \
+	return 0;							      \
+      *regs_offset = 0;							      \
+      *nregloc = sizeof table / sizeof table[0];			      \
+      *reglocs = table;							      \
+      *nitems = sizeof extra_items / sizeof extra_items[0];		      \
+      *items = extra_items;						      \
+      return 1;
+
+#define EXTRA_ITEMS(type, size, extra_items)				      \
+    case type:								      \
+      if (nhdr->n_descsz != size)					      \
+	return 0;							      \
+      *regs_offset = 0;							      \
+      *nregloc = 0;							      \
+      *reglocs = NULL;							      \
+      *nitems = sizeof extra_items / sizeof extra_items[0];		      \
+      *items = extra_items;						      \
+      return 1;
+
+#ifdef FPREGSET_SIZE
+    EXTRA_REGSET (NT_FPREGSET, FPREGSET_SIZE, fpregset_regs)
+#endif
+
+#ifdef EXTRA_NOTES
+    EXTRA_NOTES
+#endif
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/backends/m68k_corenote.c b/third_party/elfutils/backends/m68k_corenote.c
new file mode 100644
index 0000000..3c1d019
--- /dev/null
+++ b/third_party/elfutils/backends/m68k_corenote.c
@@ -0,0 +1,72 @@
+/* M68K specific core note handling.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND	m68k_
+#include "libebl_CPU.h"
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+    { .offset = 0, .regno = 1, .count = 14, .bits = 32 }, /* d1-d7, a0-a6 */
+    { .offset = 14 * 4, .regno = 0, .count = 1, .bits = 32 }, /* d0 */
+    { .offset = 15 * 4, .regno = 15, .count = 1, .bits = 32 }, /* a7 */
+    { .offset = 18 * 4, .regno = 24, .count = 1, .bits = 32 } /* pc */
+  };
+#define PRSTATUS_REGS_SIZE	(20 * 4)
+
+#define ULONG			uint32_t
+#define PID_T			int32_t
+#define	UID_T			uint16_t
+#define	GID_T			uint16_t
+#define ALIGN_INT		2
+#define ALIGN_ULONG		2
+#define ALIGN_PID_T		2
+#define ALIGN_UID_T		2
+#define ALIGN_GID_T		2
+#define ALIGN_PRSTATUS		2
+#define TYPE_ULONG		ELF_T_WORD
+#define TYPE_PID_T		ELF_T_SWORD
+#define TYPE_UID_T		ELF_T_HALF
+#define TYPE_GID_T		ELF_T_HALF
+
+static const Ebl_Register_Location fpregset_regs[] =
+  {
+    { .offset = 0, .regno = 16, .count = 8, .bits = 96 }, /* fp0-fp7 */
+  };
+#define FPREGSET_SIZE	(27 * 4)
+
+#include "linux-core-note.c"
diff --git a/third_party/elfutils/backends/m68k_init.c b/third_party/elfutils/backends/m68k_init.c
new file mode 100644
index 0000000..943478f
--- /dev/null
+++ b/third_party/elfutils/backends/m68k_init.c
@@ -0,0 +1,60 @@
+/* Initialization of M68K specific backend library.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		m68k_
+#define RELOC_PREFIX	R_68K_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on m68k_reloc.def.  */
+#include "common-reloc.c"
+
+
+const char *
+m68k_init (Elf *elf __attribute__ ((unused)),
+	   GElf_Half machine __attribute__ ((unused)),
+	   Ebl *eh,
+	   size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "M68K";
+  m68k_init_reloc (eh);
+  HOOK (eh, gotpc_reloc_check);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, return_value_location);
+  HOOK (eh, register_info);
+  HOOK (eh, core_note);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/m68k_regs.c b/third_party/elfutils/backends/m68k_regs.c
new file mode 100644
index 0000000..cb99f55
--- /dev/null
+++ b/third_party/elfutils/backends/m68k_regs.c
@@ -0,0 +1,96 @@
+/* Register names and numbers for M68K DWARF.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND m68k_
+#include "libebl_CPU.h"
+
+ssize_t
+m68k_register_info (Ebl *ebl __attribute__ ((unused)),
+		    int regno, char *name, size_t namelen,
+		    const char **prefix, const char **setname,
+		    int *bits, int *type)
+{
+  if (name == NULL)
+    return 25;
+
+  if (regno < 0 || regno > 24 || namelen < 5)
+    return -1;
+
+  *prefix = "%";
+  *setname = "integer";
+  *bits = 32;
+
+  switch (regno)
+    {
+    case 0 ... 7:
+      *type = DW_ATE_signed;
+      name[0] = 'd';
+      name[1] = regno + '0';
+      namelen = 2;
+      break;
+
+    case 8 ... 15:
+      *type = DW_ATE_address;
+      name[0] = 'a';
+      name[1] = regno - 8 + '0';
+      namelen = 2;
+      break;
+
+    case 16 ... 23:
+      *type = DW_ATE_float;
+      *setname = "FPU";
+      *bits = 96;
+      name[0] = 'f';
+      name[1] = 'p';
+      name[2] = regno - 16 + '0';
+      namelen = 3;
+      break;
+
+    case 24:
+      *type = DW_ATE_address;
+      name[0] = 'p';
+      name[1] = 'c';
+      namelen = 2;
+      break;
+
+    /* Can't happen.  */
+    default:
+      *setname = NULL;
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
diff --git a/third_party/elfutils/backends/m68k_reloc.def b/third_party/elfutils/backends/m68k_reloc.def
new file mode 100644
index 0000000..b7cc4df
--- /dev/null
+++ b/third_party/elfutils/backends/m68k_reloc.def
@@ -0,0 +1,70 @@
+/* List the relocation types for m68k.  -*- C -*-
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,		EXEC|DYN)
+RELOC_TYPE (32,			REL|EXEC|DYN)
+RELOC_TYPE (16,			REL|EXEC|DYN)
+RELOC_TYPE (8,			REL|EXEC|DYN)
+RELOC_TYPE (PC32,		REL|EXEC|DYN)
+RELOC_TYPE (PC16,		REL|EXEC|DYN)
+RELOC_TYPE (PC8,		REL|EXEC|DYN)
+RELOC_TYPE (GOT32,		REL)
+RELOC_TYPE (GOT16,		REL)
+RELOC_TYPE (GOT8,		REL)
+RELOC_TYPE (GOT32O,		REL)
+RELOC_TYPE (GOT16O,		REL)
+RELOC_TYPE (GOT8O,		REL)
+RELOC_TYPE (PLT32,		REL)
+RELOC_TYPE (PLT16,		REL)
+RELOC_TYPE (PLT8,		REL)
+RELOC_TYPE (PLT32O,		REL)
+RELOC_TYPE (PLT16O,		REL)
+RELOC_TYPE (PLT8O,		REL)
+RELOC_TYPE (COPY,		EXEC|DYN)
+RELOC_TYPE (GLOB_DAT,		EXEC|DYN)
+RELOC_TYPE (JMP_SLOT,		EXEC|DYN)
+RELOC_TYPE (RELATIVE,		EXEC|DYN)
+RELOC_TYPE (TLS_GD32,		REL)
+RELOC_TYPE (TLS_GD16,		REL)
+RELOC_TYPE (TLS_GD8,		REL)
+RELOC_TYPE (TLS_LDM32,		REL)
+RELOC_TYPE (TLS_LDM16,		REL)
+RELOC_TYPE (TLS_LDM8,		REL)
+RELOC_TYPE (TLS_LDO32,		REL)
+RELOC_TYPE (TLS_LDO16,		REL)
+RELOC_TYPE (TLS_LDO8,		REL)
+RELOC_TYPE (TLS_IE32,		REL)
+RELOC_TYPE (TLS_IE16,		REL)
+RELOC_TYPE (TLS_IE8,		REL)
+RELOC_TYPE (TLS_LE32,		REL)
+RELOC_TYPE (TLS_LE16,		REL)
+RELOC_TYPE (TLS_LE8,		REL)
+RELOC_TYPE (TLS_DTPMOD32,	EXEC|DYN)
+RELOC_TYPE (TLS_DTPREL32,	EXEC|DYN)
+RELOC_TYPE (TLS_TPREL32,	EXEC|DYN)
diff --git a/third_party/elfutils/backends/m68k_retval.c b/third_party/elfutils/backends/m68k_retval.c
new file mode 100644
index 0000000..a653ba3
--- /dev/null
+++ b/third_party/elfutils/backends/m68k_retval.c
@@ -0,0 +1,151 @@
+/* Function return value location for Linux/m68k ABI.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND m68k_
+#include "libebl_CPU.h"
+
+
+/* %d0, or pair %d0, %d1.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+#define nloc_intreg	1
+#define nloc_intregpair	4
+
+/* %a0.  */
+static const Dwarf_Op loc_ptrreg[] =
+  {
+    { .atom = DW_OP_reg8 }
+  };
+#define nloc_ptrreg	1
+
+/* %fp0.  */
+static const Dwarf_Op loc_fpreg[] =
+  {
+    { .atom = DW_OP_reg16 }
+  };
+#define nloc_fpreg	1
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in %a0.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_reg8 }
+  };
+#define nloc_aggregate 1
+
+int
+m68k_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Word size;
+	Dwarf_Attribute attr_mem;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+						   &attr_mem), &size) != 0)
+	  {
+	    if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	      size = 4;
+	    else
+	      return -1;
+	  }
+	if (tag == DW_TAG_base_type)
+	  {
+	    Dwarf_Word encoding;
+	    if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+						       &attr_mem),
+				 &encoding) != 0)
+	      return -1;
+	    if (encoding == DW_ATE_float)
+	      {
+		if (size > 12)
+		  return -2;
+		*locp = loc_fpreg;
+		return nloc_fpreg;
+	      }
+	  }
+	if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	  {
+	    *locp = loc_ptrreg;
+	    return nloc_ptrreg;
+	  }
+	*locp = loc_intreg;
+	if (size <= 4)
+	  return nloc_intreg;
+	if (size <= 8)
+	  return nloc_intregpair;
+      }
+      FALLTHROUGH;
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+    case DW_TAG_array_type:
+      *locp = loc_aggregate;
+      return nloc_aggregate;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/m68k_symbol.c b/third_party/elfutils/backends/m68k_symbol.c
new file mode 100644
index 0000000..269d12e
--- /dev/null
+++ b/third_party/elfutils/backends/m68k_symbol.c
@@ -0,0 +1,70 @@
+/* m68k specific symbolic name handling.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND m68k_
+#include "libebl_CPU.h"
+
+
+/* Return true if the symbol type is that referencing the GOT.  */
+bool
+m68k_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_68K_GOT32:
+    case R_68K_GOT16:
+    case R_68K_GOT8:
+      return true;
+    }
+  return false;
+}
+
+/* Check for the simple reloc types.  */
+Elf_Type
+m68k_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_68K_32:
+      return ELF_T_SWORD;
+    case R_68K_16:
+      return ELF_T_HALF;
+    case R_68K_8:
+      return ELF_T_BYTE;
+    default:
+      return ELF_T_NUM;
+    }
+}
diff --git a/third_party/elfutils/backends/ppc64_corenote.c b/third_party/elfutils/backends/ppc64_corenote.c
new file mode 100644
index 0000000..9d6a6a4
--- /dev/null
+++ b/third_party/elfutils/backends/ppc64_corenote.c
@@ -0,0 +1,2 @@
+#define BITS 64
+#include "ppc_corenote.c"
diff --git a/third_party/elfutils/backends/ppc64_init.c b/third_party/elfutils/backends/ppc64_init.c
new file mode 100644
index 0000000..e567033
--- /dev/null
+++ b/third_party/elfutils/backends/ppc64_init.c
@@ -0,0 +1,110 @@
+/* Initialization of PPC64 specific backend library.
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#define BACKEND		ppc64_
+#define RELOC_PREFIX	R_PPC64_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on ppc64_reloc.def.  */
+#include "common-reloc.c"
+
+
+const char *
+ppc64_init (Elf *elf __attribute__ ((unused)),
+	    GElf_Half machine __attribute__ ((unused)),
+	    Ebl *eh,
+	    size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "PowerPC 64-bit";
+  ppc64_init_reloc (eh);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, dynamic_tag_name);
+  HOOK (eh, dynamic_tag_check);
+  HOOK (eh, machine_flag_check);
+  HOOK (eh, copy_reloc_p);
+  HOOK (eh, check_special_symbol);
+  HOOK (eh, check_st_other_bits);
+  HOOK (eh, bss_plt_p);
+  HOOK (eh, return_value_location);
+  HOOK (eh, register_info);
+  HOOK (eh, syscall_abi);
+  HOOK (eh, core_note);
+  HOOK (eh, auxv_info);
+  HOOK (eh, check_object_attribute);
+  HOOK (eh, abi_cfi);
+  /* gcc/config/ #define DWARF_FRAME_REGISTERS.  */
+  eh->frame_nregs = (114 - 1) + 32;
+  HOOK (eh, set_initial_registers_tid);
+  HOOK (eh, dwarf_to_regno);
+  HOOK (eh, unwind);
+  HOOK (eh, resolve_sym_value);
+
+  /* Find the function descriptor .opd table for resolve_sym_value.  */
+  if (elf != NULL)
+    {
+      GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
+      if (ehdr != NULL && ehdr->e_type != ET_REL)
+	{
+	  /* We could also try through DT_PPC64_OPD and DT_PPC64_OPDSZ. */
+	  GElf_Shdr opd_shdr_mem, *opd_shdr;
+	  Elf_Scn *scn = NULL;
+	  while ((scn = elf_nextscn (elf, scn)) != NULL)
+	    {
+	      opd_shdr = gelf_getshdr (scn, &opd_shdr_mem);
+	      if (opd_shdr != NULL
+		  && (opd_shdr->sh_flags & SHF_ALLOC) != 0
+		  && opd_shdr->sh_type == SHT_PROGBITS
+		  && opd_shdr->sh_size > 0)
+		{
+		  const char *name = elf_strptr (elf, ehdr->e_shstrndx,
+						 opd_shdr->sh_name);
+		  if (name != NULL && strcmp (name, ".opd") == 0)
+		    {
+		      eh->fd_addr = opd_shdr->sh_addr;
+		      eh->fd_data = elf_getdata (scn, NULL);
+		      break;
+		    }
+		}
+	    }
+	}
+    }
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/ppc64_reloc.def b/third_party/elfutils/backends/ppc64_reloc.def
new file mode 100644
index 0000000..15a73ba
--- /dev/null
+++ b/third_party/elfutils/backends/ppc64_reloc.def
@@ -0,0 +1,161 @@
+/* List the relocation types for ppc64.  -*- C -*-
+   Copyright (C) 2005, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,		0)
+RELOC_TYPE (ADDR32,		REL|EXEC|DYN)
+RELOC_TYPE (ADDR24,		REL)
+RELOC_TYPE (ADDR16,		REL)		/* note 1 */
+RELOC_TYPE (ADDR16_LO,		REL)		/* note 1 */
+RELOC_TYPE (ADDR16_HI,		REL)		/* note 1 */
+RELOC_TYPE (ADDR16_HA,		REL)		/* note 1 */
+RELOC_TYPE (ADDR14,		REL)		/* note 1 */
+RELOC_TYPE (ADDR14_BRTAKEN,	REL)		/* note 1 */
+RELOC_TYPE (ADDR14_BRNTAKEN,	REL)		/* note 1 */
+RELOC_TYPE (REL24,		REL)
+RELOC_TYPE (REL14,		REL)
+RELOC_TYPE (REL14_BRTAKEN,	REL)
+RELOC_TYPE (REL14_BRNTAKEN,	REL)
+RELOC_TYPE (GOT16,		REL)
+RELOC_TYPE (GOT16_LO,		REL)
+RELOC_TYPE (GOT16_HI,		REL)
+RELOC_TYPE (GOT16_HA,		REL)
+RELOC_TYPE (COPY,		EXEC|DYN)
+RELOC_TYPE (GLOB_DAT,		EXEC|DYN)
+RELOC_TYPE (JMP_SLOT,		EXEC|DYN)
+RELOC_TYPE (RELATIVE,		EXEC|DYN)
+RELOC_TYPE (UADDR32,		REL|EXEC|DYN)
+RELOC_TYPE (UADDR16,		REL)
+RELOC_TYPE (REL32,		REL|EXEC|DYN)
+RELOC_TYPE (PLT32,		REL)
+RELOC_TYPE (PLTREL32,		REL)
+RELOC_TYPE (PLT16_LO,		REL)
+RELOC_TYPE (PLT16_HI,		REL)
+RELOC_TYPE (PLT16_HA,		REL)
+RELOC_TYPE (SECTOFF,		REL)
+RELOC_TYPE (SECTOFF_LO,		REL)
+RELOC_TYPE (SECTOFF_HI,		REL)
+RELOC_TYPE (SECTOFF_HA,		REL)
+RELOC_TYPE (ADDR30,		REL)		/* note 1 */
+RELOC_TYPE (ADDR64,		REL|EXEC|DYN)
+RELOC_TYPE (ADDR16_HIGHER,	REL)		/* note 1 */
+RELOC_TYPE (ADDR16_HIGHERA,	REL)		/* note 1 */
+RELOC_TYPE (ADDR16_HIGHEST,	REL)		/* note 1 */
+RELOC_TYPE (ADDR16_HIGHESTA,	REL)		/* note 1 */
+RELOC_TYPE (UADDR64,		REL|EXEC|DYN)
+RELOC_TYPE (REL64,		REL|EXEC|DYN)
+RELOC_TYPE (PLT64,		REL)
+RELOC_TYPE (PLTREL64,		REL)
+RELOC_TYPE (TOC16,		REL)
+RELOC_TYPE (TOC16_LO,		REL)
+RELOC_TYPE (TOC16_HI,		REL)
+RELOC_TYPE (TOC16_HA,		REL)
+RELOC_TYPE (TOC,		REL)
+RELOC_TYPE (PLTGOT16,		REL)
+RELOC_TYPE (PLTGOT16_LO,	REL)
+RELOC_TYPE (PLTGOT16_HI,	REL)
+RELOC_TYPE (PLTGOT16_HA,	REL)
+RELOC_TYPE (ADDR16_DS,		REL)		/* note 1 */
+RELOC_TYPE (ADDR16_LO_DS,	REL)		/* note 1 */
+RELOC_TYPE (GOT16_DS,		REL)
+RELOC_TYPE (GOT16_LO_DS,	REL)
+RELOC_TYPE (PLT16_LO_DS,	REL)
+RELOC_TYPE (SECTOFF_DS,		REL)
+RELOC_TYPE (SECTOFF_LO_DS,	REL)
+RELOC_TYPE (TOC16_DS,		REL)
+RELOC_TYPE (TOC16_LO_DS,	REL)
+RELOC_TYPE (PLTGOT16_DS,	REL)
+RELOC_TYPE (PLTGOT16_LO_DS,	REL)
+RELOC_TYPE (TLS,		REL)
+RELOC_TYPE (DTPMOD64,		REL|EXEC|DYN)	/* note 3 */
+RELOC_TYPE (TPREL16,		REL)		/* note 2 */
+RELOC_TYPE (TPREL16_LO,		REL)		/* note 2 */
+RELOC_TYPE (TPREL16_HI,		REL)		/* note 2 */
+RELOC_TYPE (TPREL16_HA,		REL)		/* note 2 */
+RELOC_TYPE (TPREL64,		REL|EXEC|DYN)	/* note 3 */
+RELOC_TYPE (DTPREL16,		REL)
+RELOC_TYPE (DTPREL16_LO,	REL)
+RELOC_TYPE (DTPREL16_HI,	REL)
+RELOC_TYPE (DTPREL16_HA,	REL)
+RELOC_TYPE (DTPREL64,		REL|EXEC|DYN)	/* note 3 */
+RELOC_TYPE (GOT_TLSGD16,	REL)
+RELOC_TYPE (GOT_TLSGD16_LO,	REL)
+RELOC_TYPE (GOT_TLSGD16_HI,	REL)
+RELOC_TYPE (GOT_TLSGD16_HA,	REL)
+RELOC_TYPE (GOT_TLSLD16,	REL)
+RELOC_TYPE (GOT_TLSLD16_LO,	REL)
+RELOC_TYPE (GOT_TLSLD16_HI,	REL)
+RELOC_TYPE (GOT_TLSLD16_HA,	REL)
+RELOC_TYPE (GOT_TPREL16_DS,	REL)
+RELOC_TYPE (GOT_TPREL16_LO_DS,	REL)
+RELOC_TYPE (GOT_TPREL16_HI,	REL)
+RELOC_TYPE (GOT_TPREL16_HA,	REL)
+RELOC_TYPE (GOT_DTPREL16_DS,	REL)
+RELOC_TYPE (GOT_DTPREL16_LO_DS, REL)
+RELOC_TYPE (GOT_DTPREL16_HI,	REL)
+RELOC_TYPE (GOT_DTPREL16_HA,	REL)
+RELOC_TYPE (TPREL16_DS,		REL)		/* note 2 */
+RELOC_TYPE (TPREL16_LO_DS,	REL)		/* note 2 */
+RELOC_TYPE (TPREL16_HIGHER,	REL)		/* note 2 */
+RELOC_TYPE (TPREL16_HIGHERA,	REL)		/* note 2 */
+RELOC_TYPE (TPREL16_HIGHEST,	REL)		/* note 2 */
+RELOC_TYPE (TPREL16_HIGHESTA,	REL)		/* note 2 */
+RELOC_TYPE (DTPREL16_DS,	REL)
+RELOC_TYPE (DTPREL16_LO_DS,	REL)
+RELOC_TYPE (DTPREL16_HIGHER,	REL)
+RELOC_TYPE (DTPREL16_HIGHERA,	REL)
+RELOC_TYPE (DTPREL16_HIGHEST,	REL)
+RELOC_TYPE (DTPREL16_HIGHESTA,	REL)
+RELOC_TYPE (TLSGD,		REL)
+RELOC_TYPE (TLSLD,		REL)
+RELOC_TYPE (TOCSAVE,		REL)
+RELOC_TYPE (ADDR16_HIGH,	REL)
+RELOC_TYPE (ADDR16_HIGHA,	REL)
+RELOC_TYPE (TPREL16_HIGH,	REL)
+RELOC_TYPE (TPREL16_HIGHA,	REL)
+RELOC_TYPE (DTPREL16_HIGH,	REL)
+RELOC_TYPE (DTPREL16_HIGHA,	REL)
+RELOC_TYPE (JMP_IREL,		REL)
+RELOC_TYPE (IRELATIVE,		REL)
+RELOC_TYPE (REL16,		REL)
+RELOC_TYPE (REL16_LO,		REL)
+RELOC_TYPE (REL16_HI,		REL)
+RELOC_TYPE (REL16_HA,		REL)
+
+/* Notes from Alan Modra:
+
+   1) These can appear in DYN and EXEC with improper assembly, but they
+   aren't really kosher.
+
+   2) These can appear in DYN with improper assembly (or silly gcc
+      attributes, I think).  Again, not kosher.
+
+   3) These are legal in REL for PowerOpen compatible assembler syntax,
+      ie. TOC managed by compiler.
+*/
diff --git a/third_party/elfutils/backends/ppc64_resolve_sym.c b/third_party/elfutils/backends/ppc64_resolve_sym.c
new file mode 100644
index 0000000..03f6558
--- /dev/null
+++ b/third_party/elfutils/backends/ppc64_resolve_sym.c
@@ -0,0 +1,63 @@
+/* Resolve symbol values through .opd function descriptors.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND ppc64_
+#include "libebl_CPU.h"
+
+/* Resolve a function descriptor if addr points into the .opd section.
+   The .opd section contains function descriptors consisting of 3 addresses.
+   function, toc and chain. We are just interested in the first.
+   http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#FUNC-DES
+
+   Returns true if the given address could be resolved, false otherwise.
+*/
+bool
+ppc64_resolve_sym_value (Ebl *ebl, GElf_Addr *addr)
+{
+  if (ebl->fd_data != NULL && *addr >= ebl->fd_addr
+      && *addr + sizeof (Elf64_Addr) <= ebl->fd_addr + ebl->fd_data->d_size)
+    {
+      GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (ebl->elf, &ehdr_mem);
+      if (ehdr != NULL)
+	{
+	  Elf_Data opd_in, opd_out;
+	  opd_in.d_buf = ebl->fd_data->d_buf + (*addr - ebl->fd_addr);
+	  opd_out.d_buf = addr;
+	  opd_out.d_size = opd_in.d_size = sizeof (Elf64_Addr);
+	  opd_out.d_type = opd_in.d_type = ELF_T_ADDR;
+	  if (elf64_xlatetom (&opd_out, &opd_in,
+			      ehdr->e_ident[EI_DATA]) != NULL)
+	    return true;
+	}
+    }
+  return false;
+}
diff --git a/third_party/elfutils/backends/ppc64_retval.c b/third_party/elfutils/backends/ppc64_retval.c
new file mode 100644
index 0000000..eb1c11e
--- /dev/null
+++ b/third_party/elfutils/backends/ppc64_retval.c
@@ -0,0 +1,195 @@
+/* Function return value location for Linux/PPC64 ABI.
+   Copyright (C) 2005-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND ppc64_
+#include "libebl_CPU.h"
+
+
+/* r3.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg3 }
+  };
+#define nloc_intreg	1
+
+/* f1, or f1:f2, or f1:f4.  */
+static const Dwarf_Op loc_fpreg[] =
+  {
+    { .atom = DW_OP_regx, .number = 33 }, { .atom = DW_OP_piece, .number = 8 },
+    { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 8 },
+    { .atom = DW_OP_regx, .number = 35 }, { .atom = DW_OP_piece, .number = 8 },
+    { .atom = DW_OP_regx, .number = 36 }, { .atom = DW_OP_piece, .number = 8 },
+  };
+#define nloc_fpreg	1
+#define nloc_fp2regs	4
+#define nloc_fp4regs	8
+
+/* vr2.  */
+static const Dwarf_Op loc_vmxreg[] =
+  {
+    { .atom = DW_OP_regx, .number = 1124 + 2 }
+  };
+#define nloc_vmxreg	1
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in r3.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_breg3, .number = 0 }
+  };
+#define nloc_aggregate 1
+
+int
+ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  Dwarf_Word size;
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Attribute attr_mem;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+						   &attr_mem), &size) != 0)
+	  {
+	    if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	      size = 8;
+	    else
+	      return -1;
+	}
+      }
+
+      if (tag == DW_TAG_base_type)
+	{
+	  Dwarf_Attribute attr_mem;
+	  Dwarf_Word encoding;
+	  if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+						     &attr_mem),
+			       &encoding) != 0)
+	    return -1;
+
+	  if (encoding == DW_ATE_float || encoding == DW_ATE_complex_float)
+	    {
+	      *locp = loc_fpreg;
+	      if (size <= 8)
+		return nloc_fpreg;
+	      if (size <= 16)
+		return nloc_fp2regs;
+	      if (size <= 32)
+		return nloc_fp4regs;
+	    }
+	}
+      if (size <= 8)
+	{
+	intreg:
+	  *locp = loc_intreg;
+	  return nloc_intreg;
+	}
+
+      FALLTHROUGH;
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+    aggregate:
+      *locp = loc_aggregate;
+      return nloc_aggregate;
+
+    case DW_TAG_array_type:
+      {
+	Dwarf_Attribute attr_mem;
+	bool is_vector;
+	if (dwarf_formflag (dwarf_attr_integrate (typedie, DW_AT_GNU_vector,
+						  &attr_mem), &is_vector) == 0
+	    && is_vector)
+	  {
+	    *locp = loc_vmxreg;
+	    return nloc_vmxreg;
+	  }
+      }
+      FALLTHROUGH;
+
+    case DW_TAG_string_type:
+      if (dwarf_aggregate_size (typedie, &size) == 0 && size <= 8)
+	{
+	  if (tag == DW_TAG_array_type)
+	    {
+	      /* Check if it's a character array.  */
+	      Dwarf_Attribute attr_mem, *attr;
+	      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	      typedie = dwarf_formref_die (attr, &die_mem);
+	      tag = DWARF_TAG_OR_RETURN (typedie);
+	      if (tag != DW_TAG_base_type)
+		goto aggregate;
+	      if (dwarf_formudata (dwarf_attr_integrate (typedie,
+							 DW_AT_byte_size,
+							 &attr_mem),
+				   &size) != 0)
+		return -1;
+	      if (size != 1)
+		goto aggregate;
+	    }
+	  goto intreg;
+	}
+      goto aggregate;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/ppc64_symbol.c b/third_party/elfutils/backends/ppc64_symbol.c
new file mode 100644
index 0000000..0feddce
--- /dev/null
+++ b/third_party/elfutils/backends/ppc64_symbol.c
@@ -0,0 +1,130 @@
+/* PPC64 specific symbolic name handling.
+   Copyright (C) 2004, 2005, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND		ppc64_
+#include "libebl_CPU.h"
+
+
+/* Check for the simple reloc types.  */
+Elf_Type
+ppc64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_PPC64_ADDR64:
+    case R_PPC64_UADDR64:
+      return ELF_T_XWORD;
+    case R_PPC64_ADDR32:
+    case R_PPC64_UADDR32:
+      return ELF_T_WORD;
+    case R_PPC64_UADDR16:
+      return ELF_T_HALF;
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+
+const char *
+ppc64_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+			size_t len __attribute__ ((unused)))
+{
+  switch (tag)
+    {
+    case DT_PPC64_GLINK:
+      return "PPC64_GLINK";
+    case DT_PPC64_OPD:
+      return "PPC64_OPD";
+    case DT_PPC64_OPDSZ:
+      return "PPC64_OPDSZ";
+    case DT_PPC64_OPT:
+      return "PPC64_OPT";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+
+bool
+ppc64_dynamic_tag_check (int64_t tag)
+{
+  return (tag == DT_PPC64_GLINK
+	  || tag == DT_PPC64_OPD
+	  || tag == DT_PPC64_OPDSZ
+	  || tag == DT_PPC64_OPT);
+}
+
+
+/* Check whether given symbol's st_value and st_size are OK despite failing
+   normal checks.  */
+bool
+ppc64_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr,
+			    const GElf_Sym *sym __attribute__ ((unused)),
+			    const char *name __attribute__ ((unused)),
+			    const GElf_Shdr *destshdr)
+{
+  const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name);
+  if (sname == NULL)
+    return false;
+  return strcmp (sname, ".opd") == 0;
+}
+
+
+/* Check if backend uses a bss PLT in this file.  */
+bool
+ppc64_bss_plt_p (Elf *elf __attribute__ ((unused)))
+{
+  return true;
+}
+
+/* Check whether machine flags are valid.  PPC64 has three possible values:
+   0 - for unspecified ABI, or not using any specific ABI features.
+   1 - for the original ELF PPC64 ABI using function descriptors.
+   2 - for the revised ELFv2 PPC64 ABI without function descriptors.  */
+bool
+ppc64_machine_flag_check (GElf_Word flags)
+{
+  return flags == 0 || flags == 1 || flags == 2;
+}
+
+bool
+ppc64_check_st_other_bits (unsigned char st_other)
+{
+  return (PPC64_LOCAL_ENTRY_OFFSET (st_other) != 0);
+}
diff --git a/third_party/elfutils/backends/ppc64_unwind.c b/third_party/elfutils/backends/ppc64_unwind.c
new file mode 100644
index 0000000..4fa0b5a
--- /dev/null
+++ b/third_party/elfutils/backends/ppc64_unwind.c
@@ -0,0 +1,76 @@
+/* Get previous frame state for an existing frame state.
+   Copyright (C) 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND ppc64_
+
+#define LR_REG 65 /* Not 108, see ppc_dwarf_to_regno.  */
+#define SP_REG  1
+
+#define LR_OFFSET 16
+
+#include "libebl_CPU.h"
+
+/* Simplistic fallback frame unwinder. SP points to the backchain (contains
+   address of previous stack pointer). At SP offset 16 is the LR save area
+   (contains the value of the previous LR).  */
+
+bool
+EBLHOOK(unwind) (Ebl *ebl __attribute__ ((unused)),
+		 Dwarf_Addr pc __attribute__ ((unused)),
+                 ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc,
+                 ebl_pid_memory_read_t *readfunc, void *arg,
+                 bool *signal_framep __attribute__ ((unused)))
+{
+  Dwarf_Word sp, newSp, lr, newLr;
+
+  /* Stack pointer points to the backchain which contains the previous sp.  */
+  if (! getfunc (SP_REG, 1, &sp, arg))
+    sp = 0;
+
+  /* Link register contains previous program counter.  */
+  if (! getfunc (LR_REG, 1, &lr, arg)
+      || lr == 0
+      || ! setfunc (-1, 1, &lr, arg))
+    return false;
+
+  if (! readfunc(sp, &newSp, arg))
+    newSp = 0;
+
+  if (! readfunc(newSp + LR_OFFSET, &newLr, arg))
+    newLr = 0;
+
+  setfunc(SP_REG, 1, &newSp, arg);
+  setfunc(LR_REG, 1, &newLr, arg);
+
+  /* Sanity check the stack grows down.  */
+  return newSp > sp;
+}
diff --git a/third_party/elfutils/backends/ppc_attrs.c b/third_party/elfutils/backends/ppc_attrs.c
new file mode 100644
index 0000000..48d7129
--- /dev/null
+++ b/third_party/elfutils/backends/ppc_attrs.c
@@ -0,0 +1,86 @@
+/* Object attribute tags for PowerPC.
+   Copyright (C) 2008, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+bool
+ppc_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
+			    const char *vendor, int tag, uint64_t value,
+			    const char **tag_name, const char **value_name)
+{
+  if (!strcmp (vendor, "gnu"))
+    switch (tag)
+      {
+      case 4:
+	*tag_name = "GNU_Power_ABI_FP";
+	static const char *fp_kinds[] =
+	  {
+	    "Hard or soft float",
+	    "Hard float",
+	    "Soft float",
+	    "Single-precision hard float",
+	  };
+	if (value < sizeof fp_kinds / sizeof fp_kinds[0])
+	  *value_name = fp_kinds[value];
+	return true;
+
+      case 8:
+	*tag_name = "GNU_Power_ABI_Vector";
+	static const char *vector_kinds[] =
+	  {
+	    "Any", "Generic", "AltiVec", "SPE"
+	  };
+	if (value < sizeof vector_kinds / sizeof vector_kinds[0])
+	  *value_name = vector_kinds[value];
+	return true;
+
+      case 12:
+	*tag_name = "GNU_Power_ABI_Struct_Return";
+	static const char *struct_return_kinds[] =
+	  {
+	    "Any", "r3/r4", "Memory"
+	  };
+	if (value < sizeof struct_return_kinds / sizeof struct_return_kinds[0])
+	  *value_name = struct_return_kinds[value];
+	return true;
+      }
+
+  return false;
+}
+
+__typeof (ppc_check_object_attribute)
+     ppc64_check_object_attribute
+     __attribute__ ((alias ("ppc_check_object_attribute")));
diff --git a/third_party/elfutils/backends/ppc_auxv.c b/third_party/elfutils/backends/ppc_auxv.c
new file mode 100644
index 0000000..a27a1da
--- /dev/null
+++ b/third_party/elfutils/backends/ppc_auxv.c
@@ -0,0 +1,55 @@
+/* i386 specific auxv handling.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+int
+EBLHOOK(auxv_info) (GElf_Xword a_type, const char **name, const char **format)
+{
+  if (a_type != AT_HWCAP)
+    return 0;
+
+  *name = "HWCAP";
+  *format = "b"
+    "ppcle\0" "truele\0" "3\0" "4\0" "5\0" "6\0" "7\0" "8\0" "9\0"
+    "power6x\0" "dfp\0" "pa6t\0" "arch_2_05\0"
+    "ic_snoop\0" "smt\0" "booke\0" "cellbe\0"
+    "power5+\0" "power5\0" "power4\0" "notb\0"
+    "efpdouble\0" "efpsingle\0" "spe\0" "ucache\0"
+    "4xxmac\0" "mmu\0" "fpu\0" "altivec\0"
+    "ppc601\0" "ppc64\0" "ppc32\0" "\0";
+  return 1;
+}
+
+__typeof (ppc_auxv_info) ppc64_auxv_info
+			 __attribute__ ((alias ("ppc_auxv_info")));
diff --git a/third_party/elfutils/backends/ppc_cfi.c b/third_party/elfutils/backends/ppc_cfi.c
new file mode 100644
index 0000000..55169ae
--- /dev/null
+++ b/third_party/elfutils/backends/ppc_cfi.c
@@ -0,0 +1,77 @@
+/* ppc ABI-specified defaults for DWARF CFI.
+   Copyright (C) 2012, 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+int
+ppc_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
+{
+  static const uint8_t abi_cfi[] =
+    {
+      /* This instruction is provided in every CIE.  It is not repeated here:
+	 DW_CFA_def_cfa, ULEB128_7 (1), ULEB128_7 (0)  */
+      /* r1 is assumed to be restored from cfa adress,
+	 r1 acts as a stack frame pointer.  */
+      DW_CFA_val_offset, ULEB128_7 (1), ULEB128_7 (0),
+      /* lr is not callee-saved but it needs to be preserved as it is pre-set
+	 by the caller.  */
+      DW_CFA_same_value, ULEB128_7 (65), /* lr */
+
+      /* Callee-saved regs.  */
+#define SV(n) DW_CFA_same_value, ULEB128_7 (n)
+      SV (2),			/* r2 is TOC pointer.  */
+      SV (13),			/* Reserved as system thread id (is it for CFI?).  */
+      /* r14-r31 are non-volatile registers.  */
+      SV (14), SV (15), SV (16), SV (17), SV (18), SV (19), SV (20), SV (21),
+      SV (22), SV (23), SV (24), SV (25), SV (26), SV (27), SV (28), SV (29),
+      SV (30), SV (31)
+      /* VMX registers v20-v31 and vrsave are non-volatile but they are
+	 assigned DWARF registers 1144-1156 (v20-v31) which is outside of the
+	 CFI supported range.  */
+#undef SV
+    };
+
+  abi_info->initial_instructions = abi_cfi;
+  abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
+  abi_info->data_alignment_factor = ebl->class == ELFCLASS64 ? 8 : 4;
+
+  abi_info->return_address_register = 65;
+
+  return 0;
+}
+
+__typeof (ppc_abi_cfi)
+     ppc64_abi_cfi
+     __attribute__ ((alias ("ppc_abi_cfi")));
diff --git a/third_party/elfutils/backends/ppc_corenote.c b/third_party/elfutils/backends/ppc_corenote.c
new file mode 100644
index 0000000..2b4ada7
--- /dev/null
+++ b/third_party/elfutils/backends/ppc_corenote.c
@@ -0,0 +1,145 @@
+/* PowerPC specific core note handling.
+   Copyright (C) 2007, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#ifndef BITS
+# define BITS 		32
+# define BACKEND	ppc_
+#else
+# define BITS 		64
+# define BACKEND	ppc64_
+#endif
+#include "libebl_CPU.h"
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+#define GR(at, n, dwreg)						\
+    { .offset = at * BITS/8, .regno = dwreg, .count = n, .bits = BITS }
+
+    GR (0, 32, 0),		/* r0-r31 */
+    /*	32, 1,			   nip */
+    GR (33, 1, 66),		/* msr */
+    /*	34, 1,			   orig_gpr3 */
+    GR (35, 1, 109),		/* ctr */
+    GR (36, 1, 108),		/* lr */
+    GR (37, 1, 101),		/* xer */
+    GR (38, 1, 64),		/* cr */
+    GR (39, 1, 100),		/* mq */
+    /*  40, 1,			   trap */
+    GR (41, 1, 119),		/* dar */
+    GR (42, 1, 118),		/* dsisr */
+
+#undef	GR
+  };
+#define PRSTATUS_REGS_SIZE	(BITS / 8 * 48)
+
+static const Ebl_Register_Location fpregset_regs[] =
+  {
+    { .offset = 0, .regno = 32, .count = 32, .bits = 64 }, /* f0-f31 */
+    { .offset = 32 * 8 + 4, .regno = 65, .count = 1, .bits = 32 } /* fpscr */
+  };
+#define FPREGSET_SIZE		(33 * 8)
+
+static const Ebl_Register_Location altivec_regs[] =
+  {
+    /* vr0-vr31 */
+    { .offset = 0, .regno = 1124, .count = 32, .bits = 128 },
+    /* vscr XXX 67 is an unofficial assignment */
+    { .offset = 32 * 16, .regno = 67, .count = 1, .bits = 32, .pad = 12 },
+    /* vrsave */
+    { .offset = 33 * 16, .regno = 356, .count = 1, .bits = 32, .pad = 12 }
+  };
+
+static const Ebl_Register_Location spe_regs[] =
+  {
+    /* evr0-evr31
+    { .offset = 0, .regno = ???, .count = 32, .bits = 32 },
+     * acc *
+    { .offset = 32 * 4, .regno = ???, .count = 1, .bits = 64 }, */
+    /* spefscr */
+    { .offset = 34 * 4, .regno = 612, .count = 1, .bits = 32 }
+  };
+
+static const Ebl_Register_Location tm_spr_regs[] =
+  {
+    /* tfhar */
+    { .offset = 0, .regno = 114, .count = 1, .bits = 64 },
+    /* texasr */
+    { .offset = 8, .regno = 116, .count = 1, .bits = 64 },
+    /* tfiar */
+    { .offset = 16, .regno = 115, .count = 1, .bits = 64 }
+  };
+
+#define EXTRA_NOTES \
+  EXTRA_REGSET (NT_PPC_VMX, 34 * 16, altivec_regs) \
+  EXTRA_REGSET (NT_PPC_SPE, 35 * 4, spe_regs) \
+  EXTRA_REGSET (NT_PPC_TM_SPR, 3 * 8, tm_spr_regs)
+
+#if BITS == 32
+# define ULONG			uint32_t
+# define ALIGN_ULONG		4
+# define TYPE_ULONG		ELF_T_WORD
+# define TYPE_LONG		ELF_T_SWORD
+#else
+# define ULONG			uint64_t
+# define ALIGN_ULONG		8
+# define TYPE_ULONG		ELF_T_XWORD
+# define TYPE_LONG		ELF_T_SXWORD
+#endif
+#define PID_T			int32_t
+#define	UID_T			uint32_t
+#define	GID_T			uint32_t
+#define ALIGN_PID_T		4
+#define ALIGN_UID_T		4
+#define ALIGN_GID_T		4
+#define TYPE_PID_T		ELF_T_SWORD
+#define TYPE_UID_T		ELF_T_WORD
+#define TYPE_GID_T		ELF_T_WORD
+
+#define PRSTATUS_REGSET_ITEMS						      \
+  {									      \
+    .name = "nip", .type = ELF_T_ADDR, .format = 'x',			      \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[32]),		      \
+    .group = "register", .pc_register = true				      \
+  },								      	      \
+  {									      \
+    .name = "orig_gpr3", .type = TYPE_LONG, .format = 'd',		      \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[34]),		      \
+    .group = "register"	       			  	       	 	      \
+  }
+
+#include "linux-core-note.c"
diff --git a/third_party/elfutils/backends/ppc_init.c b/third_party/elfutils/backends/ppc_init.c
new file mode 100644
index 0000000..aea9f2d
--- /dev/null
+++ b/third_party/elfutils/backends/ppc_init.c
@@ -0,0 +1,74 @@
+/* Initialization of PPC specific backend library.
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		ppc_
+#define RELOC_PREFIX	R_PPC_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on ppc_reloc.def.  */
+#include "common-reloc.c"
+
+
+const char *
+ppc_init (Elf *elf __attribute__ ((unused)),
+	  GElf_Half machine __attribute__ ((unused)),
+	  Ebl *eh,
+	  size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "PowerPC";
+  ppc_init_reloc (eh);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, machine_flag_check);
+  HOOK (eh, dynamic_tag_name);
+  HOOK (eh, dynamic_tag_check);
+  HOOK (eh, check_special_symbol);
+  HOOK (eh, bss_plt_p);
+  HOOK (eh, return_value_location);
+  HOOK (eh, register_info);
+  HOOK (eh, syscall_abi);
+  HOOK (eh, core_note);
+  HOOK (eh, auxv_info);
+  HOOK (eh, check_object_attribute);
+  HOOK (eh, abi_cfi);
+  /* gcc/config/ #define DWARF_FRAME_REGISTERS.  */
+  eh->frame_nregs = (114 - 1) + 32;
+  HOOK (eh, set_initial_registers_tid);
+  HOOK (eh, dwarf_to_regno);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/ppc_initreg.c b/third_party/elfutils/backends/ppc_initreg.c
new file mode 100644
index 0000000..69d623b
--- /dev/null
+++ b/third_party/elfutils/backends/ppc_initreg.c
@@ -0,0 +1,114 @@
+/* Fetch live process registers from TID.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "system.h"
+#include <stdlib.h>
+#if defined(__powerpc__) && defined(__linux__)
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#endif
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+bool
+ppc_dwarf_to_regno (Ebl *ebl __attribute__ ((unused)), unsigned *regno)
+{
+  switch (*regno)
+  {
+    case 108:
+      // LR uses both 65 and 108 numbers, there is no consistency for it.
+      *regno = 65;
+      return true;
+    case 0 ... 107:
+    case 109 ... (114 - 1) -1:
+      return true;
+    case 1200 ... 1231:
+      *regno = *regno - 1200 + (114 - 1);
+      return true;
+    default:
+      return false;
+  }
+  abort ();
+}
+
+__typeof (ppc_dwarf_to_regno)
+     ppc64_dwarf_to_regno
+     __attribute__ ((alias ("ppc_dwarf_to_regno")));
+
+bool
+ppc_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
+			  ebl_tid_registers_t *setfunc __attribute__ ((unused)),
+			       void *arg __attribute__ ((unused)))
+{
+#if !defined(__powerpc__) || !defined(__linux__)
+  return false;
+#else /* __powerpc__ */
+  union
+    {
+      struct pt_regs r;
+      long l[sizeof (struct pt_regs) / sizeof (long)];
+    }
+  user_regs;
+  eu_static_assert (sizeof (struct pt_regs) % sizeof (long) == 0);
+  /* PTRACE_GETREGS is EIO on kernel-2.6.18-308.el5.ppc64.  */
+  errno = 0;
+  for (unsigned regno = 0; regno < sizeof (user_regs) / sizeof (long);
+       regno++)
+    {
+      user_regs.l[regno] = ptrace (PTRACE_PEEKUSER, tid,
+				   (void *) (uintptr_t) (regno
+							 * sizeof (long)),
+				   NULL);
+      if (errno != 0)
+	return false;
+    }
+  const size_t gprs = sizeof (user_regs.r.gpr) / sizeof (*user_regs.r.gpr);
+  Dwarf_Word dwarf_regs[gprs];
+  for (unsigned gpr = 0; gpr < gprs; gpr++)
+    dwarf_regs[gpr] = user_regs.r.gpr[gpr];
+  if (! setfunc (0, gprs, dwarf_regs, arg))
+    return false;
+  dwarf_regs[0] = user_regs.r.link;
+  // LR uses both 65 and 108 numbers, there is no consistency for it.
+  if (! setfunc (65, 1, dwarf_regs, arg))
+    return false;
+  /* Registers like msr, ctr, xer, dar, dsisr etc. are probably irrelevant
+     for CFI.  */
+  dwarf_regs[0] = user_regs.r.nip;
+  return setfunc (-1, 1, dwarf_regs, arg);
+#endif /* __powerpc__ */
+}
+
+__typeof (ppc_set_initial_registers_tid)
+     ppc64_set_initial_registers_tid
+     __attribute__ ((alias ("ppc_set_initial_registers_tid")));
diff --git a/third_party/elfutils/backends/ppc_regs.c b/third_party/elfutils/backends/ppc_regs.c
new file mode 100644
index 0000000..43d2534
--- /dev/null
+++ b/third_party/elfutils/backends/ppc_regs.c
@@ -0,0 +1,208 @@
+/* Register names and numbers for PowerPC DWARF.
+   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+ssize_t
+ppc_register_info (Ebl *ebl __attribute__ ((unused)),
+		   int regno, char *name, size_t namelen,
+		   const char **prefix, const char **setname,
+		   int *bits, int *type)
+{
+  if (name == NULL)
+    return 1156;
+
+  if (regno < 0 || regno > 1155 || namelen < 8)
+    return -1;
+
+  *prefix = "";
+  *bits = ebl->machine == EM_PPC64 ? 64 : 32;
+  *type = (regno < 32 ? DW_ATE_signed
+	   : regno < 64 ? DW_ATE_float : DW_ATE_unsigned);
+
+  if (regno < 32 || regno == 64 || regno == 66)
+    *setname = "integer";
+  else if (regno < 64 || regno == 65)
+    {
+      *setname = "FPU";
+      if (ebl->machine != EM_PPC64 && regno < 64)
+	*bits = 64;
+    }
+  else if (regno == 67 || regno == 356 || regno == 612 || regno >= 1124)
+    {
+      *setname = "vector";
+      *bits = regno >= 1124 ? 128 : 32;
+    }
+  else
+    *setname = "privileged";
+
+  switch (regno)
+    {
+    case 0 ... 9:
+      name[0] = 'r';
+      name[1] = regno + '0';
+      namelen = 2;
+      break;
+
+    case 10 ... 31:
+      name[0] = 'r';
+      name[1] = regno / 10 + '0';
+      name[2] = regno % 10 + '0';
+      namelen = 3;
+      break;
+
+    case 32 + 0 ... 32 + 9:
+      name[0] = 'f';
+      name[1] = (regno - 32) + '0';
+      namelen = 2;
+      break;
+
+    case 32 + 10 ... 32 + 31:
+      name[0] = 'f';
+      name[1] = (regno - 32) / 10 + '0';
+      name[2] = (regno - 32) % 10 + '0';
+      namelen = 3;
+      break;
+
+    case 64:
+      return stpcpy (name, "cr") + 1 - name;
+    case 65:
+      return stpcpy (name, "fpscr") + 1 - name;
+    case 66:
+      return stpcpy (name, "msr") + 1 - name;
+    case 67:			/* XXX unofficial assignment */
+      return stpcpy (name, "vscr") + 1 - name;
+
+    case 70 + 0 ... 70 + 9:
+      name[0] = 's';
+      name[1] = 'r';
+      name[2] = (regno - 70) + '0';
+      namelen = 3;
+      break;
+
+    case 70 + 10 ... 70 + 15:
+      name[0] = 's';
+      name[1] = 'r';
+      name[2] = (regno - 70) / 10 + '0';
+      name[3] = (regno - 70) % 10 + '0';
+      namelen = 4;
+      break;
+
+    case 101:
+      return stpcpy (name, "xer") + 1 - name;
+    case 108:
+      return stpcpy (name, "lr") + 1 - name;
+    case 109:
+      return stpcpy (name, "ctr") + 1 - name;
+    case 118:
+      return stpcpy (name, "dsisr") + 1 - name;
+    case 119:
+      return stpcpy (name, "dar") + 1 - name;
+    case 122:
+      return stpcpy (name, "dec") + 1 - name;
+    case 356:
+      return stpcpy (name, "vrsave") + 1 - name;
+    case 612:
+      return stpcpy (name, "spefscr") + 1 - name;
+    case 100:
+      if (*bits == 32)
+	return stpcpy (name, "mq") + 1 - name;
+      FALLTHROUGH;
+    case 102 ... 107:
+      name[0] = 's';
+      name[1] = 'p';
+      name[2] = 'r';
+      name[3] = (regno - 100) + '0';
+      namelen = 4;
+      break;
+
+    case 114:
+      return stpcpy (name, "tfhar") + 1 - name;
+    case 115:
+      return stpcpy (name, "tfiar") + 1 - name;
+    case 116:
+      return stpcpy (name, "texasr") + 1 - name;
+
+    case 110 ... 113:
+    case 117:
+    case 120 ... 121:
+    case 123 ... 199:
+      name[0] = 's';
+      name[1] = 'p';
+      name[2] = 'r';
+      name[3] = (regno - 100) / 10 + '0';
+      name[4] = (regno - 100) % 10 + '0';
+      namelen = 5;
+      break;
+
+    case 200 ... 355:
+    case 357 ... 611:
+    case 613 ... 999:
+      name[0] = 's';
+      name[1] = 'p';
+      name[2] = 'r';
+      name[3] = (regno - 100) / 100 + '0';
+      name[4] = ((regno - 100) % 100 / 10) + '0';
+      name[5] = (regno - 100) % 10 + '0';
+      namelen = 6;
+      break;
+
+    case 1124 + 0 ... 1124 + 9:
+      name[0] = 'v';
+      name[1] = 'r';
+      name[2] = (regno - 1124) + '0';
+      namelen = 3;
+      break;
+
+    case 1124 + 10 ... 1124 + 31:
+      name[0] = 'v';
+      name[1] = 'r';
+      name[2] = (regno - 1124) / 10 + '0';
+      name[3] = (regno - 1124) % 10 + '0';
+      namelen = 4;
+      break;
+
+    default:
+      *setname = NULL;
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
+
+__typeof (ppc_register_info)
+     ppc64_register_info __attribute__ ((alias ("ppc_register_info")));
diff --git a/third_party/elfutils/backends/ppc_reloc.def b/third_party/elfutils/backends/ppc_reloc.def
new file mode 100644
index 0000000..3723a9c
--- /dev/null
+++ b/third_party/elfutils/backends/ppc_reloc.def
@@ -0,0 +1,137 @@
+/* List the relocation types for ppc.  -*- C -*-
+   Copyright (C) 2005, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,		0)
+RELOC_TYPE (ADDR32,		REL|EXEC|DYN)
+RELOC_TYPE (ADDR24,		REL)
+RELOC_TYPE (ADDR16,		REL|EXEC|DYN)	/* note 1 */
+RELOC_TYPE (ADDR16_LO,		REL|EXEC|DYN)	/* note 1 */
+RELOC_TYPE (ADDR16_HI,		REL|EXEC|DYN)	/* note 1 */
+RELOC_TYPE (ADDR16_HA,		REL|EXEC|DYN)	/* note 1 */
+RELOC_TYPE (ADDR14,		REL|EXEC|DYN)	/* note 1 */
+RELOC_TYPE (ADDR14_BRTAKEN,	REL|EXEC|DYN)	/* note 1 */
+RELOC_TYPE (ADDR14_BRNTAKEN,	REL|EXEC|DYN)	/* note 1 */
+RELOC_TYPE (REL24,		REL|EXEC|DYN)	/* note 1 */
+RELOC_TYPE (REL14,		REL|EXEC|DYN)	/* note 1 */
+RELOC_TYPE (REL14_BRTAKEN,	REL|EXEC|DYN)	/* note 1 */
+RELOC_TYPE (REL14_BRNTAKEN,	REL|EXEC|DYN)	/* note 1 */
+RELOC_TYPE (GOT16,		REL)
+RELOC_TYPE (GOT16_LO,		REL)
+RELOC_TYPE (GOT16_HI,		REL)
+RELOC_TYPE (GOT16_HA,		REL)
+RELOC_TYPE (PLTREL24,		REL)
+RELOC_TYPE (COPY,		EXEC|DYN)
+RELOC_TYPE (GLOB_DAT,		EXEC|DYN)
+RELOC_TYPE (JMP_SLOT,		EXEC|DYN)
+RELOC_TYPE (RELATIVE,		EXEC|DYN)
+RELOC_TYPE (LOCAL24PC,		REL)
+RELOC_TYPE (UADDR32,		REL|EXEC|DYN)
+RELOC_TYPE (UADDR16,		REL)		/* note 2 */
+RELOC_TYPE (REL32,		REL|EXEC|DYN)
+RELOC_TYPE (PLT32,		REL)
+RELOC_TYPE (PLTREL32,		REL)
+RELOC_TYPE (PLT16_LO,		REL)
+RELOC_TYPE (PLT16_HI,		REL)
+RELOC_TYPE (PLT16_HA,		REL)
+RELOC_TYPE (SDAREL16,		REL)
+RELOC_TYPE (SECTOFF,		REL)
+RELOC_TYPE (SECTOFF_LO,		REL)
+RELOC_TYPE (SECTOFF_HI,		REL)
+RELOC_TYPE (SECTOFF_HA,		REL)
+RELOC_TYPE (TLS,		REL)
+RELOC_TYPE (DTPMOD32,		EXEC|DYN)	/* note 2 */
+RELOC_TYPE (TPREL16,		REL)		/* note 2 */
+RELOC_TYPE (TPREL16_LO,		REL)		/* note 2 */
+RELOC_TYPE (TPREL16_HI,		REL)		/* note 2 */
+RELOC_TYPE (TPREL16_HA,		REL)		/* note 2 */
+RELOC_TYPE (TPREL32,		EXEC|DYN)	/* note 2 */
+RELOC_TYPE (DTPREL16,		REL)
+RELOC_TYPE (DTPREL16_LO,	REL)
+RELOC_TYPE (DTPREL16_HI,	REL)
+RELOC_TYPE (DTPREL16_HA,	REL)
+RELOC_TYPE (DTPREL32,		EXEC|DYN)	/* note 2 */
+RELOC_TYPE (GOT_TLSGD16,	REL)
+RELOC_TYPE (GOT_TLSGD16_LO,	REL)
+RELOC_TYPE (GOT_TLSGD16_HI,	REL)
+RELOC_TYPE (GOT_TLSGD16_HA,	REL)
+RELOC_TYPE (GOT_TLSLD16,	REL)
+RELOC_TYPE (GOT_TLSLD16_LO,	REL)
+RELOC_TYPE (GOT_TLSLD16_HI,	REL)
+RELOC_TYPE (GOT_TLSLD16_HA,	REL)
+RELOC_TYPE (GOT_TPREL16,	REL)
+RELOC_TYPE (GOT_TPREL16_LO,	REL)
+RELOC_TYPE (GOT_TPREL16_HI,	REL)
+RELOC_TYPE (GOT_TPREL16_HA,	REL)
+RELOC_TYPE (GOT_DTPREL16,	REL)
+RELOC_TYPE (GOT_DTPREL16_LO,	REL)
+RELOC_TYPE (GOT_DTPREL16_HI,	REL)
+RELOC_TYPE (GOT_DTPREL16_HA,	REL)
+RELOC_TYPE (EMB_NADDR32,	REL)		/* note 3 */
+RELOC_TYPE (EMB_NADDR16,	REL)		/* note 3 */
+RELOC_TYPE (EMB_NADDR16_LO,	REL)		/* note 3 */
+RELOC_TYPE (EMB_NADDR16_HI,	REL)		/* note 3 */
+RELOC_TYPE (EMB_NADDR16_HA,	REL)		/* note 3 */
+RELOC_TYPE (EMB_SDAI16,		REL)		/* note 3 */
+RELOC_TYPE (EMB_SDA2I16,	REL)		/* note 3 */
+RELOC_TYPE (EMB_SDA2REL,	REL)		/* note 3 */
+RELOC_TYPE (EMB_SDA21,		REL)		/* note 3 */
+RELOC_TYPE (EMB_MRKREF,		REL)		/* note 3 */
+RELOC_TYPE (EMB_RELSEC16,	REL)		/* note 3 */
+RELOC_TYPE (EMB_RELST_LO,	REL)		/* note 3 */
+RELOC_TYPE (EMB_RELST_HI,	REL)		/* note 3 */
+RELOC_TYPE (EMB_RELST_HA,	REL)		/* note 3 */
+RELOC_TYPE (EMB_BIT_FLD,	REL)		/* note 3 */
+RELOC_TYPE (EMB_RELSDA,		REL)		/* note 3 */
+RELOC_TYPE (DIAB_SDA21_LO,	REL)		/* note 3 */
+RELOC_TYPE (DIAB_SDA21_HI,	REL)		/* note 3 */
+RELOC_TYPE (DIAB_SDA21_HA,	REL)		/* note 3 */
+RELOC_TYPE (DIAB_RELSDA_LO,	REL)		/* note 3 */
+RELOC_TYPE (DIAB_RELSDA_HI,	REL)		/* note 3 */
+RELOC_TYPE (DIAB_RELSDA_HA,	REL)		/* note 3 */
+RELOC_TYPE (REL16,		REL)		/* note 2 */
+RELOC_TYPE (REL16_LO,		REL)		/* note 2 */
+RELOC_TYPE (REL16_HI,		REL)		/* note 2 */
+RELOC_TYPE (REL16_HA,		REL)		/* note 2 */
+RELOC_TYPE (TOC16,		REL)		/* note 2 */
+
+/* Notes from Alan Modra:
+
+   1) These relocs should not really appear in EXEC or DYN, but they do,
+   primarily due to improper assembly or non-pic shared objects.  They
+   will cause TEXTREL to be set.  I marked them in the table, because
+   numerous people seem to think non-pic shared libs are a good idea.
+
+   2) As for (1), these relocs can appear anywhere with improper
+   assembler.  I should probably make ld reject anything other than the
+   cases allowed in this table.	 Not seen in the wild, so I haven't
+   added the other cases.
+
+   3) Not used in SYSV4
+*/
diff --git a/third_party/elfutils/backends/ppc_retval.c b/third_party/elfutils/backends/ppc_retval.c
new file mode 100644
index 0000000..39b42da
--- /dev/null
+++ b/third_party/elfutils/backends/ppc_retval.c
@@ -0,0 +1,191 @@
+/* Function return value location for Linux/PPC ABI.
+   Copyright (C) 2005, 2006, 2007, 2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+
+/* This is the SVR4 ELF ABI convention, but AIX and Linux do not use it.  */
+#define SVR4_STRUCT_RETURN 0
+
+
+/* r3, or pair r3, r4, or quad r3-r6.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg4 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg5 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg6 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+#define nloc_intreg	1
+#define nloc_intregpair	4
+#define nloc_intregquad	8
+
+/* f1.  */
+static const Dwarf_Op loc_fpreg[] =
+  {
+    { .atom = DW_OP_regx, .number = 33 }
+  };
+#define nloc_fpreg	1
+
+/* vr2.  */
+static const Dwarf_Op loc_vmxreg[] =
+  {
+    { .atom = DW_OP_regx, .number = 1124 + 2 }
+  };
+#define nloc_vmxreg	1
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in r3.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_breg3, .number = 0 }
+  };
+#define nloc_aggregate 1
+
+
+/* XXX We should check the SHT_GNU_ATTRIBUTES bits here (or in ppc_init).  */
+static bool
+ppc_altivec_abi (void)
+{
+  return true;
+}
+
+int
+ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  Dwarf_Word size;
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Attribute attr_mem;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+						   &attr_mem), &size) != 0)
+	  {
+	    if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	      size = 4;
+	    else
+	      return -1;
+	  }
+      }
+
+      if (size <= 8)
+	{
+	  if (tag == DW_TAG_base_type)
+	    {
+	      Dwarf_Attribute attr_mem;
+	      Dwarf_Word encoding;
+	      if (dwarf_formudata (dwarf_attr_integrate (typedie,
+							 DW_AT_encoding,
+							 &attr_mem),
+				   &encoding) != 0)
+		return -1;
+	      if (encoding == DW_ATE_float)
+		{
+		  *locp = loc_fpreg;
+		  return nloc_fpreg;
+		}
+	    }
+	intreg:
+	  *locp = loc_intreg;
+	  return size <= 4 ? nloc_intreg : nloc_intregpair;
+	}
+
+    aggregate:
+      *locp = loc_aggregate;
+      return nloc_aggregate;
+
+    case DW_TAG_array_type:
+      {
+	Dwarf_Attribute attr_mem;
+	bool is_vector;
+	if (dwarf_formflag (dwarf_attr_integrate (typedie, DW_AT_GNU_vector,
+						  &attr_mem), &is_vector) == 0
+	    && is_vector
+	    && dwarf_aggregate_size (typedie, &size) == 0)
+	  switch (size)
+	    {
+	    case 16:
+	      if (ppc_altivec_abi ())
+		{
+		  *locp = loc_vmxreg;
+		  return nloc_vmxreg;
+		}
+	      *locp = loc_intreg;
+	      return nloc_intregquad;
+	    }
+      }
+      FALLTHROUGH;
+
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+      if (SVR4_STRUCT_RETURN
+	  && dwarf_aggregate_size (typedie, &size) == 0
+	  && size > 0 && size <= 8)
+	goto intreg;
+      goto aggregate;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/ppc_symbol.c b/third_party/elfutils/backends/ppc_symbol.c
new file mode 100644
index 0000000..4b32003
--- /dev/null
+++ b/third_party/elfutils/backends/ppc_symbol.c
@@ -0,0 +1,184 @@
+/* PPC specific symbolic name handling.
+   Copyright (C) 2004, 2005, 2007, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <elf.h>
+#include <stddef.h>
+#include <string.h>
+
+#define BACKEND		ppc_
+#include "libebl_CPU.h"
+
+
+/* Check for the simple reloc types.  */
+Elf_Type
+ppc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_PPC_ADDR32:
+    case R_PPC_UADDR32:
+      return ELF_T_WORD;
+    case R_PPC_UADDR16:
+      return ELF_T_HALF;
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+
+/* Check whether machine flags are valid.  */
+bool
+ppc_machine_flag_check (GElf_Word flags)
+{
+  return ((flags &~ (EF_PPC_EMB
+		     | EF_PPC_RELOCATABLE
+		     | EF_PPC_RELOCATABLE_LIB)) == 0);
+}
+
+
+const char *
+ppc_dynamic_tag_name (int64_t tag, char *buf __attribute__ ((unused)),
+		      size_t len __attribute__ ((unused)))
+{
+  switch (tag)
+    {
+    case DT_PPC_GOT:
+      return "PPC_GOT";
+    case DT_PPC_OPT:
+      return "PPC_OPT";
+    default:
+      break;
+    }
+  return NULL;
+}
+
+
+bool
+ppc_dynamic_tag_check (int64_t tag)
+{
+  return (tag == DT_PPC_GOT
+	  || tag == DT_PPC_OPT);
+}
+
+
+/* Look for DT_PPC_GOT.  */
+static bool
+find_dyn_got (Elf *elf, GElf_Addr *addr)
+{
+  size_t phnum;
+  if (elf_getphdrnum (elf, &phnum) != 0)
+    return false;
+
+  for (size_t i = 0; i < phnum; ++i)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
+      if (phdr == NULL || phdr->p_type != PT_DYNAMIC)
+	continue;
+
+      Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset);
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      Elf_Data *data = elf_getdata (scn, NULL);
+      if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC && data != NULL
+	  && shdr->sh_entsize != 0)
+	for (unsigned int j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j)
+	  {
+	    GElf_Dyn dyn_mem;
+	    GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
+	    if (dyn != NULL && dyn->d_tag == DT_PPC_GOT)
+	      {
+		*addr = dyn->d_un.d_ptr;
+		return true;
+	      }
+	  }
+
+      /* There is only one PT_DYNAMIC entry.  */
+      break;
+    }
+
+  return false;
+}
+
+
+/* Check whether given symbol's st_value and st_size are OK despite failing
+   normal checks.  */
+bool
+ppc_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr, const GElf_Sym *sym,
+			  const char *name, const GElf_Shdr *destshdr)
+{
+  if (name == NULL)
+    return false;
+
+  if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
+    {
+      /* In -msecure-plt mode, DT_PPC_GOT is present and must match.  */
+      GElf_Addr gotaddr;
+      if (find_dyn_got (elf, &gotaddr))
+	return sym->st_value == gotaddr;
+
+      /* In -mbss-plt mode, any place in the section is valid.  */
+      return true;
+    }
+
+  const char *sname = elf_strptr (elf, ehdr->e_shstrndx, destshdr->sh_name);
+  if (sname == NULL)
+    return false;
+
+  /* Small data area.  Normally points to .sdata, in which case we
+     check it is at an offset of 0x8000.  It might however fall in the
+     .data section, in which case we cannot check the offset.  The
+     size always should be zero.  */
+  if (strcmp (name, "_SDA_BASE_") == 0)
+    return (((strcmp (sname, ".sdata") == 0
+	      && sym->st_value == destshdr->sh_addr + 0x8000)
+	     || strcmp (sname, ".data") == 0)
+	    && sym->st_size == 0);
+
+  if (strcmp (name, "_SDA2_BASE_") == 0)
+    return (strcmp (sname, ".sdata2") == 0
+	    && sym->st_value == destshdr->sh_addr + 0x8000
+	    && sym->st_size == 0);
+
+  return false;
+}
+
+
+/* Check if backend uses a bss PLT in this file.  */
+bool
+ppc_bss_plt_p (Elf *elf)
+{
+  GElf_Addr addr;
+  return ! find_dyn_got (elf, &addr);
+}
diff --git a/third_party/elfutils/backends/ppc_syscall.c b/third_party/elfutils/backends/ppc_syscall.c
new file mode 100644
index 0000000..b1b9c52
--- /dev/null
+++ b/third_party/elfutils/backends/ppc_syscall.c
@@ -0,0 +1,53 @@
+/* Linux/PPC system call ABI in DWARF register numbers.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND ppc_
+#include "libebl_CPU.h"
+
+int
+ppc_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+		 int *sp, int *pc, int *callno, int args[6])
+{
+  *sp = 1;
+  *pc = -1;
+  *callno = 0;
+  args[0] = 3;
+  args[1] = 4;
+  args[2] = 5;
+  args[3] = 6;
+  args[4] = 7;
+  args[5] = 8;
+  return 0;
+}
+
+__typeof (ppc_syscall_abi)
+ppc64_syscall_abi __attribute__ ((alias ("ppc_syscall_abi")));
diff --git a/third_party/elfutils/backends/s390_cfi.c b/third_party/elfutils/backends/s390_cfi.c
new file mode 100644
index 0000000..cb49486
--- /dev/null
+++ b/third_party/elfutils/backends/s390_cfi.c
@@ -0,0 +1,65 @@
+/* s390 ABI-specified defaults for DWARF CFI.
+   Copyright (C) 2012, 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#define BACKEND s390_
+#include "libebl_CPU.h"
+
+int
+s390_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info)
+{
+  static const uint8_t abi_cfi[] =
+    {
+      /* This instruction is provided in every CIE.  It is not repeated here:
+	 DW_CFA_def_cfa, ULEB128_7 (15), ULEB128_7 (96)  */
+      /* r14 is not callee-saved but it needs to be preserved as it is pre-set
+	 by the caller.  */
+      DW_CFA_same_value, ULEB128_7 (14), /* r14 */
+
+      /* Callee-saved regs.  */
+#define SV(n) DW_CFA_same_value, ULEB128_7 (n)
+      SV (6), SV (7), SV (8), SV (9), SV (10),		       /* r6-r13, r15 */
+      SV (11), SV (12), SV (13), SV (15),
+      SV (16 + 8), SV (16 + 9), SV (16 + 10), SV (16 + 11),    /* f8-f15 */
+      SV (16 + 12), SV (16 + 13), SV (16 + 14), SV (16 + 15)
+#undef SV
+    };
+
+  abi_info->initial_instructions = abi_cfi;
+  abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
+  abi_info->data_alignment_factor = ebl->class == ELFCLASS64 ? 8 : 4;
+
+  abi_info->return_address_register = 14;
+
+  return 0;
+}
diff --git a/third_party/elfutils/backends/s390_corenote.c b/third_party/elfutils/backends/s390_corenote.c
new file mode 100644
index 0000000..7ca3516
--- /dev/null
+++ b/third_party/elfutils/backends/s390_corenote.c
@@ -0,0 +1,189 @@
+/* S390-specific core note handling.
+   Copyright (C) 2012 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#ifndef BITS
+# define BITS 		32
+# define BACKEND	s390_
+#else
+# define BITS 		64
+# define BACKEND	s390x_
+#endif
+#include "libebl_CPU.h"
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+#define GR(at, n, dwreg, b...)						\
+    { .offset = at * BITS/8, .regno = dwreg, .count = n, .bits = b }
+
+    GR ( 0,  1, 64, BITS),				/* pswm */
+    GR ( 1,  1, 65, BITS, .pc_register = true ),	/* pswa */
+    GR ( 2, 16,  0, BITS),				/* r0-r15 */
+    GR (18, 16, 48,   32),				/* ar0-ar15 */
+
+#undef	GR
+  };
+
+  /* orig_r2 is at offset (BITS == 32 ? 34 * 4 : 26 * 8).  */
+#define PRSTATUS_REGS_SIZE	(BITS / 8 * (BITS == 32 ? 35 : 27))
+
+static const Ebl_Register_Location fpregset_regs[] =
+  {
+#define FPR(at, n, dwreg)						\
+    { .offset = at * 64/8, .regno = dwreg, .count = n, .bits = 64 }
+
+    /* fpc is at offset 0, see fpregset_items, it has no assigned DWARF regno.
+       Bytes at offsets 4 to 7 are unused.  */
+    FPR (1 +  0, 1, 16),	/* f0 */
+    FPR (1 +  1, 1, 20),	/* f1 */
+    FPR (1 +  2, 1, 17),	/* f2 */
+    FPR (1 +  3, 1, 21),	/* f3 */
+    FPR (1 +  4, 1, 18),	/* f4 */
+    FPR (1 +  5, 1, 22),	/* f5 */
+    FPR (1 +  6, 1, 19),	/* f6 */
+    FPR (1 +  7, 1, 23),	/* f7 */
+    FPR (1 +  8, 1, 24),	/* f8 */
+    FPR (1 +  9, 1, 28),	/* f9 */
+    FPR (1 + 10, 1, 25),	/* f10 */
+    FPR (1 + 11, 1, 29),	/* f11 */
+    FPR (1 + 12, 1, 26),	/* f12 */
+    FPR (1 + 13, 1, 30),	/* f13 */
+    FPR (1 + 14, 1, 27),	/* f14 */
+    FPR (1 + 15, 1, 31),	/* f15 */
+
+#undef	FPR
+  };
+
+static const Ebl_Core_Item fpregset_items[] =
+  {
+    {
+      .name = "fpc", .group = "register", .offset = 0, .type = ELF_T_WORD,
+      .format = 'x',
+    },
+  };
+
+/* Do not set FPREGSET_SIZE so that we can supply fpregset_items.  */
+#define EXTRA_NOTES_FPREGSET \
+    EXTRA_REGSET_ITEMS (NT_FPREGSET, 17 * 8, fpregset_regs, fpregset_items)
+
+#if BITS == 32
+# define ULONG			uint32_t
+# define ALIGN_ULONG		4
+# define TYPE_ULONG		ELF_T_WORD
+# define TYPE_LONG		ELF_T_SWORD
+# define UID_T			uint16_t
+# define GID_T			uint16_t
+# define ALIGN_UID_T		2
+# define ALIGN_GID_T		2
+# define TYPE_UID_T		ELF_T_HALF
+# define TYPE_GID_T		ELF_T_HALF
+#else
+# define ULONG			uint64_t
+# define ALIGN_ULONG		8
+# define TYPE_ULONG		ELF_T_XWORD
+# define TYPE_LONG		ELF_T_SXWORD
+# define UID_T			uint32_t
+# define GID_T			uint32_t
+# define ALIGN_UID_T		4
+# define ALIGN_GID_T		4
+# define TYPE_UID_T		ELF_T_WORD
+# define TYPE_GID_T		ELF_T_WORD
+#endif
+#define PID_T			int32_t
+#define ALIGN_PID_T		4
+#define TYPE_PID_T		ELF_T_SWORD
+/* s390 psw_compat_t has alignment 8 bytes where it is inherited from.  */
+#define ALIGN_PR_REG		8
+
+#define PRSTATUS_REGSET_ITEMS					\
+  {								\
+    .name = "orig_r2", .type = TYPE_LONG, .format = 'd',	\
+    .offset = offsetof (struct EBLHOOK(prstatus),		\
+			pr_reg[BITS == 32 ? 34 : 26]),		\
+    .group = "register"						\
+  }
+
+#if BITS == 32
+
+static const Ebl_Core_Item high_regs_items[] =
+  {
+#define HR(n)								\
+    {									\
+      .name = "high_r" #n , .group = "register", .offset = (n) * 4,	\
+      .type = ELF_T_WORD, .format = 'x',				\
+    }
+
+    /* Upper halves of r0-r15 are stored here.
+       FIXME: They are currently not combined with the r0-r15 lower halves.  */
+    HR (0), HR (1), HR (2), HR (3), HR (4), HR (5), HR (6), HR (7),
+    HR (8), HR (9), HR (10), HR (11), HR (12), HR (13), HR (14), HR (15)
+
+#undef HR
+  };
+
+#define EXTRA_NOTES_HIGH_GPRS \
+  EXTRA_ITEMS (NT_S390_HIGH_GPRS, 16 * 4, high_regs_items)
+
+#else /* BITS == 64 */
+
+#define EXTRA_NOTES_HIGH_GPRS
+
+#endif /* BITS == 64 */
+
+static const Ebl_Core_Item last_break_items[] =
+  {
+    {
+      .name = "last_break", .group = "system", .offset = BITS == 32 ? 4 : 0,
+      .type = BITS == 32 ? ELF_T_WORD : ELF_T_XWORD, .format = 'x',
+    },
+  };
+
+static const Ebl_Core_Item system_call_items[] =
+  {
+    {
+      .name = "system_call", .group = "system", .offset = 0, .type = ELF_T_WORD,
+      .format = 'd',
+    },
+  };
+
+#define	EXTRA_NOTES							  \
+  EXTRA_NOTES_FPREGSET							  \
+  EXTRA_NOTES_HIGH_GPRS							  \
+  EXTRA_ITEMS (NT_S390_LAST_BREAK, 8, last_break_items)	  \
+  EXTRA_ITEMS (NT_S390_SYSTEM_CALL, 4, system_call_items)
+
+#include "linux-core-note.c"
diff --git a/third_party/elfutils/backends/s390_init.c b/third_party/elfutils/backends/s390_init.c
new file mode 100644
index 0000000..ba8df45
--- /dev/null
+++ b/third_party/elfutils/backends/s390_init.c
@@ -0,0 +1,79 @@
+/* Initialization of S/390 specific backend library.
+   Copyright (C) 2005, 2006, 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		s390_
+#define RELOC_PREFIX	R_390_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on arm_reloc.def.  */
+#include "common-reloc.c"
+
+extern __typeof (s390_core_note) s390x_core_note;
+
+
+const char *
+s390_init (Elf *elf __attribute__ ((unused)),
+	   GElf_Half machine __attribute__ ((unused)),
+	   Ebl *eh,
+	   size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "IBM S/390";
+  s390_init_reloc (eh);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, register_info);
+  HOOK (eh, return_value_location);
+  if (eh->class == ELFCLASS64)
+    eh->core_note = s390x_core_note;
+  else
+    HOOK (eh, core_note);
+  HOOK (eh, abi_cfi);
+  /* gcc/config/ #define DWARF_FRAME_REGISTERS 34.
+     But from the gcc/config/s390/s390.h "Register usage." comment it looks as
+     if #32 (Argument pointer) and #33 (Condition code) are not used for
+     unwinding.  */
+  eh->frame_nregs = 32;
+  HOOK (eh, set_initial_registers_tid);
+  if (eh->class == ELFCLASS32)
+    HOOK (eh, normalize_pc);
+  HOOK (eh, unwind);
+
+  /* Only the 64-bit format uses the incorrect hash table entry size.  */
+  if (eh->class == ELFCLASS64)
+    eh->sysvhash_entrysize = sizeof (Elf64_Xword);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/s390_initreg.c b/third_party/elfutils/backends/s390_initreg.c
new file mode 100644
index 0000000..23bf8ed
--- /dev/null
+++ b/third_party/elfutils/backends/s390_initreg.c
@@ -0,0 +1,95 @@
+/* Fetch live process registers from TID.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "system.h"
+#include <assert.h>
+#if defined(__s390__) && defined(__linux__)
+# include <sys/user.h>
+# include <sys/ptrace.h>
+# include <asm/ptrace.h>
+#endif
+
+#define BACKEND s390_
+#include "libebl_CPU.h"
+
+bool
+s390_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
+			  ebl_tid_registers_t *setfunc __attribute__ ((unused)),
+				void *arg __attribute__ ((unused)))
+{
+#if !defined(__s390__) || !defined(__linux__)
+  return false;
+#else /* __s390__ */
+  struct user user_regs;
+  ptrace_area parea;
+  parea.process_addr = (uintptr_t) &user_regs;
+  parea.kernel_addr = 0;
+  parea.len = sizeof (user_regs);
+  if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea, NULL) != 0)
+    return false;
+  /* If we run as s390x we get the 64-bit registers of tid.
+     But -m31 executable seems to use only the 32-bit parts of its
+     registers so we ignore the upper half.  */
+  Dwarf_Word dwarf_regs[16];
+  for (unsigned u = 0; u < 16; u++)
+    dwarf_regs[u] = user_regs.regs.gprs[u];
+  if (! setfunc (0, 16, dwarf_regs, arg))
+    return false;
+  /* Avoid conversion double -> integer.  */
+  eu_static_assert (sizeof user_regs.regs.fp_regs.fprs[0]
+		    == sizeof dwarf_regs[0]);
+  for (unsigned u = 0; u < 16; u++)
+    {
+      // Store the double bits as is in the Dwarf_Word without conversion.
+      union
+	{
+	  double d;
+	  Dwarf_Word w;
+	} fpr = { .d = user_regs.regs.fp_regs.fprs[u] };
+      dwarf_regs[u] = fpr.w;
+    }
+
+  if (! setfunc (16, 16, dwarf_regs, arg))
+    return false;
+  dwarf_regs[0] = user_regs.regs.psw.addr;
+  return setfunc (-1, 1, dwarf_regs, arg);
+#endif /* __s390__ */
+}
+
+void
+s390_normalize_pc (Ebl *ebl __attribute__ ((unused)), Dwarf_Addr *pc)
+{
+  assert (ebl->class == ELFCLASS32);
+
+  /* Clear S390 bit 31.  */
+  *pc &= (1U << 31) - 1;
+}
diff --git a/third_party/elfutils/backends/s390_regs.c b/third_party/elfutils/backends/s390_regs.c
new file mode 100644
index 0000000..ba6178a
--- /dev/null
+++ b/third_party/elfutils/backends/s390_regs.c
@@ -0,0 +1,146 @@
+/* Register names and numbers for S/390 DWARF.
+   Copyright (C) 2006 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND s390_
+#include "libebl_CPU.h"
+
+
+/*
+zseries (64)
+
+0-15	gpr0-gpr15	x
+16-19	fpr[0246]
+20-24	fpr[13578]
+25-27	fpr1[024]
+28	fpr9
+29-31	fpr1[135]
+32-47	cr0-cr15	x
+48-63	ar0-ar15	x
+64	psw_mask
+65	psw_address
+*/
+
+
+ssize_t
+s390_register_info (Ebl *ebl __attribute__ ((unused)),
+		    int regno, char *name, size_t namelen,
+		    const char **prefix, const char **setname,
+		    int *bits, int *type)
+{
+  if (name == NULL)
+    return 66;
+
+  if (regno < 0 || regno > 65 || namelen < 7)
+    return -1;
+
+  *prefix = "%";
+
+  *bits = ebl->class == ELFCLASS64 ? 64 : 32;
+  *type = DW_ATE_unsigned;
+  if (regno < 16)
+    {
+      *setname = "integer";
+      *type = DW_ATE_signed;
+    }
+  else if (regno < 32)
+    {
+      *setname = "FPU";
+      *type = DW_ATE_float;
+      *bits = 64;
+    }
+  else if (regno < 48 || regno > 63)
+    *setname = "control";
+  else
+    {
+      *setname = "access";
+      *bits = 32;
+    }
+
+  switch (regno)
+    {
+    case 0 ... 9:
+      name[0] = 'r';
+      name[1] = regno + '0';
+      namelen = 2;
+      break;
+
+    case 10 ... 15:
+      name[0] = 'r';
+      name[1] = '1';
+      name[2] = regno - 10 + '0';
+      namelen = 3;
+      break;
+
+    case 16 ... 31:
+      name[0] = 'f';
+      regno = (regno & 8) | ((regno & 4) >> 2) | ((regno & 3) << 1);
+      namelen = 1;
+      if (regno >= 10)
+	{
+	  regno -= 10;
+	  name[namelen++] = '1';
+	}
+      name[namelen++] = regno + '0';
+      break;
+
+    case 32 + 0 ... 32 + 9:
+    case 48 + 0 ... 48 + 9:
+      name[0] = regno < 48 ? 'c' : 'a';
+      name[1] = (regno & 15) + '0';
+      namelen = 2;
+      break;
+
+    case 32 + 10 ... 32 + 15:
+    case 48 + 10 ... 48 + 15:
+      name[0] = regno < 48 ? 'c' : 'a';
+      name[1] = '1';
+      name[2] = (regno & 15) - 10 + '0';
+      namelen = 3;
+      break;
+
+    case 64:
+      return stpcpy (name, "pswm") + 1 - name;
+    case 65:
+      *type = DW_ATE_address;
+      return stpcpy (name, "pswa") + 1 - name;
+
+    default:
+      *setname = NULL;
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
diff --git a/third_party/elfutils/backends/s390_reloc.def b/third_party/elfutils/backends/s390_reloc.def
new file mode 100644
index 0000000..cdef9eb
--- /dev/null
+++ b/third_party/elfutils/backends/s390_reloc.def
@@ -0,0 +1,91 @@
+/* List the relocation types for s390.  -*- C -*-
+   Copyright (C) 2005, 2006, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* 	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,               0)
+RELOC_TYPE (8,                  REL|EXEC|DYN)
+RELOC_TYPE (12,                 REL|EXEC|DYN)
+RELOC_TYPE (16,                 REL|EXEC|DYN)
+RELOC_TYPE (32,                 REL|EXEC|DYN)
+RELOC_TYPE (PC32,               REL|EXEC|DYN)
+RELOC_TYPE (GOT12,              REL)
+RELOC_TYPE (GOT32,              REL)
+RELOC_TYPE (PLT32,              REL)
+RELOC_TYPE (COPY,               EXEC|DYN)
+RELOC_TYPE (GLOB_DAT,           EXEC|DYN)
+RELOC_TYPE (JMP_SLOT,           EXEC|DYN)
+RELOC_TYPE (RELATIVE,           EXEC|DYN)
+RELOC_TYPE (GOTOFF32,           REL)
+RELOC_TYPE (GOTPC,              REL)
+RELOC_TYPE (GOT16,              REL)
+RELOC_TYPE (PC16,               REL|EXEC|DYN)
+RELOC_TYPE (PC16DBL,            REL|EXEC|DYN)
+RELOC_TYPE (PLT16DBL,           REL)
+RELOC_TYPE (PC32DBL,            REL|EXEC|DYN)
+RELOC_TYPE (PLT32DBL,           REL)
+RELOC_TYPE (GOTPCDBL,           REL)
+RELOC_TYPE (64,                 REL|EXEC|DYN)
+RELOC_TYPE (PC64,               REL|EXEC|DYN)
+RELOC_TYPE (GOT64,              REL)
+RELOC_TYPE (PLT64,              REL)
+RELOC_TYPE (GOTENT,             REL)
+RELOC_TYPE (GOTOFF16,           REL)
+RELOC_TYPE (GOTOFF64,           REL)
+RELOC_TYPE (GOTPLT12,           REL)
+RELOC_TYPE (GOTPLT16,           REL)
+RELOC_TYPE (GOTPLT32,           REL)
+RELOC_TYPE (GOTPLT64,           REL)
+RELOC_TYPE (GOTPLTENT,          REL)
+RELOC_TYPE (PLTOFF16,           REL)
+RELOC_TYPE (PLTOFF32,           REL)
+RELOC_TYPE (PLTOFF64,           REL)
+RELOC_TYPE (TLS_LOAD,           REL)
+RELOC_TYPE (TLS_GDCALL,         REL)
+RELOC_TYPE (TLS_LDCALL,         REL)
+RELOC_TYPE (TLS_GD32,           REL)
+RELOC_TYPE (TLS_GD64,           REL)
+RELOC_TYPE (TLS_GOTIE12,        REL)
+RELOC_TYPE (TLS_GOTIE32,        REL)
+RELOC_TYPE (TLS_GOTIE64,        REL)
+RELOC_TYPE (TLS_LDM32,          REL)
+RELOC_TYPE (TLS_LDM64,          REL)
+RELOC_TYPE (TLS_IE32,           REL)
+RELOC_TYPE (TLS_IE64,           REL)
+RELOC_TYPE (TLS_IEENT,          REL)
+RELOC_TYPE (TLS_LE32,           REL)
+RELOC_TYPE (TLS_LE64,           REL)
+RELOC_TYPE (TLS_LDO32,          REL)
+RELOC_TYPE (TLS_LDO64,          REL)
+RELOC_TYPE (TLS_DTPMOD,         DYN)
+RELOC_TYPE (TLS_DTPOFF,         DYN)
+RELOC_TYPE (TLS_TPOFF,          DYN)
+RELOC_TYPE (20,                 REL|EXEC|DYN)
+RELOC_TYPE (GOT20,              REL)
+RELOC_TYPE (GOTPLT20,           REL)
+RELOC_TYPE (TLS_GOTIE20,        REL)
diff --git a/third_party/elfutils/backends/s390_retval.c b/third_party/elfutils/backends/s390_retval.c
new file mode 100644
index 0000000..2043f98
--- /dev/null
+++ b/third_party/elfutils/backends/s390_retval.c
@@ -0,0 +1,144 @@
+/* Function return value location for S/390 ABI.
+   Copyright (C) 2006, 2007, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND s390_
+#include "libebl_CPU.h"
+
+
+/* %r2, or pair %r2, %r3.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg2 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg3 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+#define nloc_intreg	1
+#define nloc_intregpair	4
+
+/* %f0.  */
+static const Dwarf_Op loc_fpreg[] =
+  {
+    { .atom = DW_OP_reg16 },
+  };
+#define nloc_fpreg	1
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in %r2.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_breg2, .number = 0 }
+  };
+#define nloc_aggregate 1
+
+
+int
+s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  Dwarf_Word size;
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Die cudie;
+	uint8_t asize;
+	if (dwarf_diecu (typedie, &cudie, &asize, NULL) == NULL)
+	  return -1;
+
+	Dwarf_Attribute attr_mem;
+	if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
+					 &attr_mem), &size) != 0)
+	  {
+	    if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	      size = asize;
+	    else
+	      return -1;
+	  }
+	if (tag == DW_TAG_base_type)
+	  {
+	    Dwarf_Word encoding;
+	    if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+						       &attr_mem),
+				 &encoding) != 0)
+	      return -1;
+	    if (encoding == DW_ATE_float && size <= 8)
+	      {
+		*locp = loc_fpreg;
+		return nloc_fpreg;
+	      }
+	  }
+	if (size <= 8)
+	  {
+	    *locp = loc_intreg;
+	    return size <= asize ? nloc_intreg : nloc_intregpair;
+	  }
+      }
+      FALLTHROUGH;
+
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+    case DW_TAG_array_type:
+      *locp = loc_aggregate;
+      return nloc_aggregate;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/s390_symbol.c b/third_party/elfutils/backends/s390_symbol.c
new file mode 100644
index 0000000..a0a4faf
--- /dev/null
+++ b/third_party/elfutils/backends/s390_symbol.c
@@ -0,0 +1,56 @@
+/* S/390-specific symbolic name handling.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+
+#define BACKEND		s390_
+#include "libebl_CPU.h"
+
+/* Check for the simple reloc types.  */
+Elf_Type
+s390_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_390_64:
+      return ELF_T_SXWORD;
+    case R_390_32:
+      return ELF_T_SWORD;
+    case R_390_16:
+      return ELF_T_HALF;
+    case R_390_8:
+      return ELF_T_BYTE;
+    default:
+      return ELF_T_NUM;
+    }
+}
diff --git a/third_party/elfutils/backends/s390_unwind.c b/third_party/elfutils/backends/s390_unwind.c
new file mode 100644
index 0000000..752bc28
--- /dev/null
+++ b/third_party/elfutils/backends/s390_unwind.c
@@ -0,0 +1,139 @@
+/* Get previous frame state for an existing frame state.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+
+#define BACKEND s390_
+#include "libebl_CPU.h"
+
+/* s390/s390x do not annotate signal handler frame by CFI.  It would be also
+   difficult as PC points into a stub built on stack.  Function below is called
+   only if unwinder could not find CFI.  Function then verifies the register
+   state for this frame really belongs to a signal frame.  In such case it
+   fetches original registers saved by the signal frame.  */
+
+bool
+s390_unwind (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc,
+	     ebl_tid_registers_get_t *getfunc, ebl_pid_memory_read_t *readfunc,
+	     void *arg, bool *signal_framep)
+{
+  /* Caller already assumed caller adjustment but S390 instructions are 4 bytes
+     long.  Undo it.  */
+  if ((pc & 0x3) != 0x3)
+    return false;
+  pc++;
+  /* We can assume big-endian read here.  */
+  Dwarf_Word instr;
+  if (! readfunc (pc, &instr, arg))
+    return false;
+  /* Fetch only the very first two bytes.  */
+  instr = (instr >> (ebl->class == ELFCLASS64 ? 48 : 16)) & 0xffff;
+  /* See GDB s390_sigtramp_frame_sniffer.  */
+  /* Check for 'svc' as the first instruction.  */
+  if (((instr >> 8) & 0xff) != 0x0a)
+    return false;
+  /* Check for 'sigreturn' or 'rt_sigreturn' as the second instruction.  */
+  if ((instr & 0xff) != 119 && (instr & 0xff) != 173)
+    return false;
+  /* See GDB s390_sigtramp_frame_unwind_cache.  */
+  Dwarf_Word this_sp;
+  if (! getfunc (0 + 15, 1, &this_sp, arg))
+    return false;
+  unsigned word_size = ebl->class == ELFCLASS64 ? 8 : 4;
+  Dwarf_Addr next_cfa = this_sp + 16 * word_size + 32;
+  /* "New-style RT frame" is not supported,
+     assuming "Old-style RT frame and all non-RT frames".
+     Pointer to the array of saved registers is at NEXT_CFA + 8.  */
+  Dwarf_Word sigreg_ptr;
+  if (! readfunc (next_cfa + 8, &sigreg_ptr, arg))
+    return false;
+  /* Skip PSW mask.  */
+  sigreg_ptr += word_size;
+  /* Read PSW address.  */
+  Dwarf_Word val;
+  if (! readfunc (sigreg_ptr, &val, arg))
+    return false;
+  if (! setfunc (-1, 1, &val, arg))
+    return false;
+  sigreg_ptr += word_size;
+  /* Then the GPRs.  */
+  Dwarf_Word gprs[16];
+  for (int i = 0; i < 16; i++)
+    {
+      if (! readfunc (sigreg_ptr, &gprs[i], arg))
+	return false;
+      sigreg_ptr += word_size;
+    }
+  /* Then the ACRs.  Skip them, they are not used in CFI.  */
+  for (int i = 0; i < 16; i++)
+    sigreg_ptr += 4;
+  /* The floating-point control word.  */
+  sigreg_ptr += 8;
+  /* And finally the FPRs.  */
+  Dwarf_Word fprs[16];
+  for (int i = 0; i < 16; i++)
+    {
+      if (! readfunc (sigreg_ptr, &val, arg))
+	return false;
+      if (ebl->class == ELFCLASS32)
+	{
+	  Dwarf_Addr val_low;
+	  if (! readfunc (sigreg_ptr + 4, &val_low, arg))
+	    return false;
+	  val = (val << 32) | val_low;
+	}
+      fprs[i] = val;
+      sigreg_ptr += 8;
+    }
+  /* If we have them, the GPR upper halves are appended at the end.  */
+  if (ebl->class == ELFCLASS32)
+    {
+      /* Skip signal number.  */
+      sigreg_ptr += 4;
+      for (int i = 0; i < 16; i++)
+	{
+	  if (! readfunc (sigreg_ptr, &val, arg))
+	    return false;
+	  Dwarf_Word val_low = gprs[i];
+	  val = (val << 32) | val_low;
+	  gprs[i] = val;
+	  sigreg_ptr += 4;
+	}
+    }
+  if (! setfunc (0, 16, gprs, arg))
+    return false;
+  if (! setfunc (16, 16, fprs, arg))
+    return false;
+  *signal_framep = true;
+  return true;
+}
diff --git a/third_party/elfutils/backends/s390x_corenote.c b/third_party/elfutils/backends/s390x_corenote.c
new file mode 100644
index 0000000..427bf7d
--- /dev/null
+++ b/third_party/elfutils/backends/s390x_corenote.c
@@ -0,0 +1,2 @@
+#define BITS 64
+#include "s390_corenote.c"
diff --git a/third_party/elfutils/backends/sh_corenote.c b/third_party/elfutils/backends/sh_corenote.c
new file mode 100644
index 0000000..9268f56
--- /dev/null
+++ b/third_party/elfutils/backends/sh_corenote.c
@@ -0,0 +1,88 @@
+/* SH specific core note handling.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed Matt Fleming <matt@console-pimps.org>.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND		sh_
+#include "libebl_CPU.h"
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+#define GR(at, n, dwreg)						\
+    { .offset = at * 4, .regno = dwreg, .count = n, .bits = 32 }
+    GR (0, 16, 0),		/* r0-r15 */
+    GR (16, 1, 16),		/* pc */
+    GR (17, 1, 17),		/* pr */
+    GR (18, 1, 22),		/* sr */
+    GR (19, 1, 18),		/* gbr */
+    GR (20, 1, 20),		/* mach */
+    GR (21, 1, 21),		/* macl */
+    /*  22, 1,			   tra */
+#undef GR
+  };
+#define PRSTATUS_REGS_SIZE	(23 * 4)
+
+#define	ULONG			uint32_t
+#define PID_T			int32_t
+#define	UID_T			uint16_t
+#define	GID_T			uint16_t
+#define ALIGN_ULONG		4
+#define ALIGN_PID_T		4
+#define ALIGN_UID_T		2
+#define ALIGN_GID_T		2
+#define TYPE_ULONG		ELF_T_WORD
+#define TYPE_PID_T		ELF_T_SWORD
+#define TYPE_UID_T		ELF_T_HALF
+#define TYPE_GID_T		ELF_T_HALF
+
+#define PRSTATUS_REGSET_ITEMS						      \
+  {									      \
+    .name = "tra", .type = ELF_T_ADDR, .format = 'x',			      \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[22]),		      \
+    .group = "register"	       			  	       	 	      \
+  }
+
+static const Ebl_Register_Location fpregset_regs[] =
+  {
+    { .offset = 0, .regno = 25, .count = 16, .bits = 32 }, /* fr0-fr15 */
+    { .offset = 16, .regno = 87, .count = 16, .bits = 32 }, /* xf0-xf15 */
+    { .offset = 32, .regno = 24, .count = 1, .bits = 32 }, /* fpscr */
+    { .offset = 33, .regno = 23, .count = 1, .bits = 32 }  /* fpul */
+  };
+#define FPREGSET_SIZE		(50 * 4)
+
+#include "linux-core-note.c"
diff --git a/third_party/elfutils/backends/sh_init.c b/third_party/elfutils/backends/sh_init.c
new file mode 100644
index 0000000..5526aca
--- /dev/null
+++ b/third_party/elfutils/backends/sh_init.c
@@ -0,0 +1,63 @@
+/* Initialization of SH specific backend library.
+   Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		sh_
+#define RELOC_PREFIX	R_SH_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on sh_reloc.def.  */
+#include "common-reloc.c"
+
+
+const char *
+sh_init (Elf *elf __attribute__ ((unused)),
+	 GElf_Half machine __attribute__ ((unused)),
+	 Ebl *eh,
+	 size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "Hitachi SH";
+  sh_init_reloc (eh);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, gotpc_reloc_check);
+  HOOK (eh, machine_flag_check);
+  HOOK (eh, core_note);
+  HOOK (eh, register_info);
+  HOOK (eh, return_value_location);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/sh_regs.c b/third_party/elfutils/backends/sh_regs.c
new file mode 100644
index 0000000..d433236
--- /dev/null
+++ b/third_party/elfutils/backends/sh_regs.c
@@ -0,0 +1,191 @@
+/* Register names and numbers for SH DWARF.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Matt Fleming <matt@console-pimps.org>.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include <string.h>
+
+#define BACKEND sh_
+#include "libebl_CPU.h"
+
+ssize_t
+sh_register_info (Ebl *ebl __attribute__ ((unused)),
+		  int regno, char *name, size_t namelen,
+		  const char **prefix, const char **setname,
+		  int *bits, int *type)
+{
+  if (name == NULL)
+    return 104;
+
+  if (regno < 0 || regno > 103 || namelen < 6)
+    return -1;
+
+  *prefix = "";
+  *bits = 32;
+  *type = DW_ATE_signed;
+
+  switch (regno)
+    {
+    case 0 ... 9:
+      *setname = "integer";
+      name[0] = 'r';
+      name[1] = regno + '0';
+      namelen = 2;
+      break;
+
+    case 10 ... 15:
+      *setname = "integer";
+      name[0] = 'r';
+      name[1] = '1';
+      name[2] = regno - 10 + '0';
+      namelen = 3;
+      break;
+
+    case 16:
+      *setname = "system";
+      *type = DW_ATE_address;
+      name[0] = 'p';
+      name[1] = 'c';
+      namelen = 2;
+      break;
+
+    case 17:
+      *setname = "system";
+      *type = DW_ATE_address;
+      name[0] = 'p';
+      name[1] = 'r';
+      namelen = 2;
+      break;
+
+    case 18:
+      *setname = "control";
+      *type = DW_ATE_unsigned;
+      name[0] = 's';
+      name[1] = 'r';
+      namelen = 2;
+      break;
+
+    case 19:
+      *setname = "control";
+      *type = DW_ATE_unsigned;
+      name[0] = 'g';
+      name[1] = 'b';
+      name[2] = 'r';
+      namelen = 3;
+      break;
+
+    case 20:
+      *setname = "system";
+      name[0] = 'm';
+      name[1] = 'a';
+      name[2] = 'c';
+      name[3] = 'h';
+      namelen = 4;
+      break;
+
+    case 21:
+      *setname = "system";
+      name[0] = 'm';
+      name[1] = 'a';
+      name[2] = 'c';
+      name[3] = 'l';
+      namelen = 4;
+
+      break;
+
+    case 23:
+      *setname = "system";
+      *type = DW_ATE_unsigned;
+      name[0] = 'f';
+      name[1] = 'p';
+      name[2] = 'u';
+      name[3] = 'l';
+      namelen = 4;
+      break;
+
+    case 24:
+      *setname = "system";
+      *type = DW_ATE_unsigned;
+      name[0] = 'f';
+      name[1] = 'p';
+      name[2] = 's';
+      name[3] = 'c';
+      name[4] = 'r';
+      namelen = 5;
+      break;
+
+    case 25 ... 34:
+      *setname = "fpu";
+      *type = DW_ATE_float;
+      name[0] = 'f';
+      name[1] = 'r';
+      name[2] = regno - 25 + '0';
+      namelen = 3;
+      break;
+
+    case 35 ... 40:
+      *setname = "fpu";
+      *type = DW_ATE_float;
+      name[0] = 'f';
+      name[1] = 'r';
+      name[2] = '1';
+      name[3] = regno - 35 + '0';
+      namelen = 4;
+      break;
+
+    case 87 ... 96:
+      *type = DW_ATE_float;
+      *setname = "fpu";
+      name[0] = 'x';
+      name[1] = 'f';
+      name[2] = regno - 87 + '0';
+      namelen = 3;
+      break;
+
+    case 97 ... 103:
+      *type = DW_ATE_float;
+      *setname = "fpu";
+      name[0] = 'x';
+      name[1] = 'f';
+      name[2] = '1';
+      name[3] = regno - 97 + '0';
+      namelen = 4;
+      break;
+
+    default:
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
diff --git a/third_party/elfutils/backends/sh_reloc.def b/third_party/elfutils/backends/sh_reloc.def
new file mode 100644
index 0000000..aded361
--- /dev/null
+++ b/third_party/elfutils/backends/sh_reloc.def
@@ -0,0 +1,67 @@
+/* List the relocation types for SH.  -*- C -*-
+   Copyright (C) 2005, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,		0)
+RELOC_TYPE (DIR32,		REL|DYN)
+RELOC_TYPE (REL32,		REL|DYN)
+RELOC_TYPE (DIR8WPN,		REL)
+RELOC_TYPE (IND12W,		REL)
+RELOC_TYPE (DIR8WPL,		REL)
+RELOC_TYPE (DIR8WPZ,		REL)
+RELOC_TYPE (DIR8BP,		REL)
+RELOC_TYPE (DIR8W,		REL)
+RELOC_TYPE (DIR8L,		REL)
+RELOC_TYPE (SWITCH16,		REL)
+RELOC_TYPE (SWITCH32,		REL)
+RELOC_TYPE (USES,		REL)
+RELOC_TYPE (COUNT,		REL)
+RELOC_TYPE (ALIGN,		REL)
+RELOC_TYPE (CODE,		REL)
+RELOC_TYPE (DATA,		REL)
+RELOC_TYPE (LABEL,		REL)
+RELOC_TYPE (SWITCH8,		REL)
+RELOC_TYPE (GNU_VTINHERIT,	REL)
+RELOC_TYPE (GNU_VTENTRY,	REL)
+RELOC_TYPE (TLS_GD_32,		REL)
+RELOC_TYPE (TLS_LD_32,		REL)
+RELOC_TYPE (TLS_LDO_32,		REL)
+RELOC_TYPE (TLS_IE_32,		REL)
+RELOC_TYPE (TLS_LE_32,		REL)
+RELOC_TYPE (TLS_DTPMOD32,	DYN)
+RELOC_TYPE (TLS_DTPOFF32,	DYN)
+RELOC_TYPE (TLS_TPOFF32,	DYN)
+RELOC_TYPE (GOT32,		REL)
+RELOC_TYPE (PLT32,		REL)
+RELOC_TYPE (COPY,		EXEC|DYN)
+RELOC_TYPE (GLOB_DAT,		EXEC|DYN)
+RELOC_TYPE (JMP_SLOT,		EXEC|DYN)
+RELOC_TYPE (RELATIVE,		EXEC|DYN)
+RELOC_TYPE (GOTOFF,		REL)
+RELOC_TYPE (GOTPC,		REL)
diff --git a/third_party/elfutils/backends/sh_retval.c b/third_party/elfutils/backends/sh_retval.c
new file mode 100644
index 0000000..33d7d96
--- /dev/null
+++ b/third_party/elfutils/backends/sh_retval.c
@@ -0,0 +1,131 @@
+/* Function return value location for Linux/SH ABI.
+   Copyright (C) 2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Matt Fleming <matt@console-pimps.org>.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND sh_
+#include "libebl_CPU.h"
+
+
+/* This is the SVR4 ELF ABI convention, but AIX and Linux do not use it.  */
+#define SVR4_STRUCT_RETURN 0
+
+
+/* r0, or pair r0, r1.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+#define nloc_intreg	1
+#define nloc_intregpair	4
+
+/* fr0 or fr1.  */
+static const Dwarf_Op loc_fpreg[] =
+  {
+    { .atom = DW_OP_reg25 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg26 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+#define nloc_fpreg	1
+#define nloc_fpregpair	2
+
+int
+sh_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  Dwarf_Word size;
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Attribute attr_mem;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+						   &attr_mem), &size) != 0)
+	  {
+	    if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	      size = 4;
+	    else
+	      return -1;
+	  }
+      }
+
+      if (size <= 8)
+	{
+	  if (tag == DW_TAG_base_type)
+	    {
+	      Dwarf_Attribute attr_mem;
+	      Dwarf_Word encoding;
+	      if (dwarf_formudata (dwarf_attr_integrate (typedie,
+							 DW_AT_encoding,
+							 &attr_mem),
+				   &encoding) != 0)
+		return -1;
+	      if (encoding == DW_ATE_float)
+		{
+		  *locp = loc_fpreg;
+		  return size <= 4 ? nloc_fpreg : nloc_fpregpair;
+		}
+	    }
+	  *locp = loc_intreg;
+	  return size <= 4 ? nloc_intreg : nloc_intregpair;
+	}
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/sh_symbol.c b/third_party/elfutils/backends/sh_symbol.c
new file mode 100644
index 0000000..8101e96
--- /dev/null
+++ b/third_party/elfutils/backends/sh_symbol.c
@@ -0,0 +1,94 @@
+/* SH specific relocation handling.
+   Copyright (C) 2000, 2001, 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+
+#define BACKEND sh_
+#include "libebl_CPU.h"
+
+
+/* Return true if the symbol type is that referencing the GOT.  */
+bool
+sh_gotpc_reloc_check (Elf *elf __attribute__ ((unused)), int type)
+{
+  return type == R_SH_GOTPC;
+}
+
+/* Check for the simple reloc types.  */
+Elf_Type
+sh_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_SH_DIR32:
+      return ELF_T_WORD;
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+/* Check whether machine flags are valid.  */
+bool
+sh_machine_flag_check (GElf_Word flags)
+{
+  switch (flags & EF_SH_MACH_MASK)
+    {
+    case EF_SH_UNKNOWN:
+    case EF_SH1:
+    case EF_SH2:
+    case EF_SH3:
+    case EF_SH_DSP:
+    case EF_SH3_DSP:
+    case EF_SH4AL_DSP:
+    case EF_SH3E:
+    case EF_SH4:
+    case EF_SH2E:
+    case EF_SH4A:
+    case EF_SH2A:
+    case EF_SH4_NOFPU:
+    case EF_SH4A_NOFPU:
+    case EF_SH4_NOMMU_NOFPU:
+    case EF_SH2A_NOFPU:
+    case EF_SH3_NOMMU:
+    case EF_SH2A_SH4_NOFPU:
+    case EF_SH2A_SH3_NOFPU:
+    case EF_SH2A_SH4:
+    case EF_SH2A_SH3E:
+      break;
+    default:
+      return false;
+    }
+
+  return ((flags &~ (EF_SH_MACH_MASK)) == 0);
+}
diff --git a/third_party/elfutils/backends/sparc64_corenote.c b/third_party/elfutils/backends/sparc64_corenote.c
new file mode 100644
index 0000000..cef6431
--- /dev/null
+++ b/third_party/elfutils/backends/sparc64_corenote.c
@@ -0,0 +1,2 @@
+#define BITS 64
+#include "sparc_corenote.c"
diff --git a/third_party/elfutils/backends/sparc_attrs.c b/third_party/elfutils/backends/sparc_attrs.c
new file mode 100644
index 0000000..974e8fb
--- /dev/null
+++ b/third_party/elfutils/backends/sparc_attrs.c
@@ -0,0 +1,105 @@
+/* Object attribute tags for SPARC.
+   Copyright (C) 2015 Oracle, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND sparc_
+#include "libebl_CPU.h"
+
+bool
+sparc_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
+			      const char *vendor, int tag, uint64_t value,
+			      const char **tag_name, const char **value_name)
+{
+  static const char *hwcaps[32] =
+    {
+      "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2",
+      "asi_blk_init", "fmaf", "vis3", "hpc", "random", "trans",
+      "fjfmau", "ima", "asi_cache_sparing", "aes", "des", "kasumi",
+      "camellia", "md5", "sha1", "sha256", "sha512", "mpmul", "mont",
+      "pause", "cbcond", "crc32c", "resv30", "resv31"
+    };
+
+  
+  static const char *hwcaps2[32] =
+    {
+      "fjathplus", "vis3b", "adp", "sparc5", "mwait", "xmpmul", "xmont",
+      "nsec", "resv8", "resv9" , "resv10", "resv11", "fjathhpc", "fjdes",
+      "fjaes", "resv15", "resv16", "resv17", "resv18", "resv19", "resv20",
+      "resv21", "resv22", "resv23", "resv24", "resv25", "resv26", "resv27",
+      "resv28", "resv29", "resv30", "resv31",
+    };
+
+  /* NAME should be big enough to hold any possible comma-separated
+     list (no repetitions allowed) of attribute names from one of the
+     arrays above.  */
+  static char name[32*17+32+1];
+  name[0] = '\0';
+
+  if (!strcmp (vendor, "gnu"))
+    switch (tag)
+      {
+      case 4:
+      case 8:
+        {
+          const char **caps;
+          int cap;
+          
+          if (tag == 4)
+            {
+              *tag_name = "GNU_Sparc_HWCAPS";
+              caps = hwcaps;
+            }
+          else
+            {
+              *tag_name = "GNU_Sparc_HWCAPS2";
+              caps = hwcaps2;
+            }
+          
+          char *s = name;
+          for (cap = 0; cap < 32; cap++)
+            if (value & (1U << cap))
+              {
+                if (*s != '\0')
+                  s = strcat (s, ",");
+                s = strcat (s, caps[cap]);
+              }
+          
+          *value_name = s;
+          return true;
+        }
+      }
+
+  return false;
+}
+
diff --git a/third_party/elfutils/backends/sparc_auxv.c b/third_party/elfutils/backends/sparc_auxv.c
new file mode 100644
index 0000000..2da349c
--- /dev/null
+++ b/third_party/elfutils/backends/sparc_auxv.c
@@ -0,0 +1,46 @@
+/* SPARC-specific auxv handling.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND sparc_
+#include "libebl_CPU.h"
+
+int
+EBLHOOK(auxv_info) (GElf_Xword a_type, const char **name, const char **format)
+{
+  if (a_type != AT_HWCAP)
+    return 0;
+
+  *name = "HWCAP";
+  *format = "b"
+    "flush\0" "stbar\0" "swap\0" "muldiv\0" "v9\0" "ultra3\0" "v9v\0" "\0";
+  return 1;
+}
diff --git a/third_party/elfutils/backends/sparc_cfi.c b/third_party/elfutils/backends/sparc_cfi.c
new file mode 100644
index 0000000..dcc17bd
--- /dev/null
+++ b/third_party/elfutils/backends/sparc_cfi.c
@@ -0,0 +1,83 @@
+/* SPARC defaults for DWARF CFI.
+   Copyright (C) 2015 Oracle Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#define BACKEND sparc_
+#include "libebl_CPU.h"
+
+int
+sparc_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
+{
+  static const uint8_t abi_cfi[] =
+    {
+#define SV(n) DW_CFA_same_value, ULEB128_7 (n)
+      /* %g0 .. %g7 */
+      SV (0), SV (1), SV (2), SV (3), SV (4), SV (5), SV (6), SV (7),
+      /* %o0 .. %o7 */
+      SV (8), SV (9), SV (10), SV (11), SV (12), SV (13), SV (14), SV (15),
+      /* %l0 .. %l7 */
+      SV (16), SV (17), SV (18), SV (19), SV (20), SV (21), SV (22), SV (23),
+      /* %i0 .. %i7 */
+      SV (24), SV (25), SV (26), SV (27), SV (28), SV (29), SV (30), SV (31),
+      /* %f0 .. %f32 */
+      SV (32), SV (33), SV (34), SV (35), SV (36), SV (37), SV (38), SV (39),
+      SV (40), SV (41), SV (42), SV (43), SV (44), SV (45), SV (46), SV (47),
+      SV (48), SV (49), SV (50), SV (51), SV (52), SV (53), SV (54), SV (55),
+      SV (56), SV (57), SV (58), SV (59), SV (60), SV (61), SV (52), SV (63),
+      /* %f33 .. %63
+         Note that there are DWARF columns for the odd registers, even
+         if they don't exist in hardware) */
+      SV (64), SV (65), SV (66), SV (67), SV (68), SV (69), SV (70), SV (71),
+      SV (72), SV (73), SV (74), SV (75), SV (76), SV (77), SV (78), SV (79),
+      SV (80), SV (81), SV (82), SV (83), SV (84), SV (85), SV (86), SV (87),
+      SV (88), SV (89), SV (90), SV (91), SV (92), SV (93), SV (94), SV (95),
+      /* %fcc[0123] */
+      SV (96), SV (97), SV (98), SV (99),
+      /* %icc/%xcc */
+      SV (100),
+      /* Soft frame-pointer */
+      SV (101),
+      /* %gsr */
+      SV (102)
+#undef SV
+    };
+
+  abi_info->initial_instructions = abi_cfi;
+  abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
+  abi_info->data_alignment_factor = 4;
+
+  abi_info->return_address_register = 31; /* %i7 */
+
+  return 0;
+}
+
diff --git a/third_party/elfutils/backends/sparc_corenote.c b/third_party/elfutils/backends/sparc_corenote.c
new file mode 100644
index 0000000..c9b6ff3
--- /dev/null
+++ b/third_party/elfutils/backends/sparc_corenote.c
@@ -0,0 +1,120 @@
+/* SPARC specific core note handling.
+   Copyright (C) 2007 Red Hat, Inc.
+   Copyright (C) 2015 Oracle, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#ifndef BITS
+# define BITS 		32
+# define BACKEND	sparc_
+#else
+# define BITS 		64
+# define BACKEND	sparc64_
+#endif
+#include "libebl_CPU.h"
+
+#define GR(at, n, dwreg)						\
+    { .offset = at * BITS/8, .regno = dwreg, .count = n, .bits = BITS }
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+    GR (0, 32, 0),		/* %g0-%g7, %o0-%o7, %i0-%i7 */
+#if BITS == 32
+    GR (32, 1, 65),		/* %psr */
+    GR (33, 2, 68),		/* %pc, %npc */
+    GR (35, 1, 64),		/* %y */
+    GR (36, 1, 66),		/* %wim, %tbr */
+#else
+    GR (32, 1, 82),		/* %state */
+    GR (33, 2, 80),		/* %pc, %npc */
+    GR (35, 1, 85),		/* %y */
+#endif
+  };
+#define PRSTATUS_REGS_SIZE	(BITS / 8 * (32 + (BITS == 32 ? 6 : 4)))
+
+static const Ebl_Register_Location fpregset_regs[] =
+  {
+#if BITS == 32
+    GR (0, 32, 32),		/* %f0-%f31 */
+    /* 				   padding word */
+    GR (33, 1, 70),		/* %fsr */
+    /* 	       			   qcnt, q_entrysize, en, q, padding */
+# define FPREGSET_SIZE		(34 * 4 + 4 + 64 * 4 + 4)
+#else
+    GR (0, 32, 32),		/* %f0-%f31 */
+    GR (32, 1, 83),		/* %fsr */
+    /*  33, 1, 			   %gsr */
+    GR (34, 1, 84),		/* %fprs */
+# define FPREGSET_SIZE		(35 * 8)
+#endif
+  };
+
+#if BITS == 32
+# define ULONG			uint32_t
+# define ALIGN_ULONG		4
+# define TYPE_ULONG		ELF_T_WORD
+# define TYPE_LONG		ELF_T_SWORD
+# define UID_T			uint16_t
+# define GID_T			uint16_t
+# define ALIGN_UID_T		2
+# define ALIGN_GID_T		2
+# define TYPE_UID_T		ELF_T_HALF
+# define TYPE_GID_T		ELF_T_HALF
+#else
+# define ULONG			uint64_t
+# define ALIGN_ULONG		8
+# define TYPE_ULONG		ELF_T_XWORD
+# define TYPE_LONG		ELF_T_SXWORD
+# define UID_T			uint32_t
+# define GID_T			uint32_t
+# define ALIGN_UID_T		4
+# define ALIGN_GID_T		4
+# define TYPE_UID_T		ELF_T_WORD
+# define TYPE_GID_T		ELF_T_WORD
+# define SUSECONDS_HALF		1
+#endif
+#define PID_T			int32_t
+#define ALIGN_PID_T		4
+#define TYPE_PID_T		ELF_T_SWORD
+
+#define PRSTATUS_REGSET_ITEMS						      \
+  {									      \
+    .name = "pc", .type = ELF_T_ADDR, .format = 'x',			      \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg[33]),		      \
+    .group = "register", .pc_register = true				      \
+  }
+
+#include "linux-core-note.c"
diff --git a/third_party/elfutils/backends/sparc_init.c b/third_party/elfutils/backends/sparc_init.c
new file mode 100644
index 0000000..8e946fb
--- /dev/null
+++ b/third_party/elfutils/backends/sparc_init.c
@@ -0,0 +1,89 @@
+/* Initialization of SPARC specific backend library.
+   Copyright (C) 2002, 2005, 2006, 2007, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		sparc_
+#define RELOC_PREFIX	R_SPARC_
+#include "libebl_CPU.h"
+
+/* In SPARC some relocations use the most significative 24 bits of the
+   r_type field to encode a secondary addend.  Make sure the routines
+   in common-reloc.c acknowledge this.  */
+#define RELOC_TYPE_ID(type) ((type) & 0xff)
+
+/* This defines the common reloc hooks based on sparc_reloc.def.  */
+#include "common-reloc.c"
+
+extern __typeof (EBLHOOK (core_note)) sparc64_core_note attribute_hidden;
+
+const char *
+sparc_init (Elf *elf __attribute__ ((unused)),
+	    GElf_Half machine __attribute__ ((unused)),
+	    Ebl *eh,
+	    size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  if (machine == EM_SPARCV9)
+    eh->name = "SPARC v9";
+  else if (machine == EM_SPARC32PLUS)
+    eh->name = "SPARC v8+";
+  else
+    eh->name = "SPARC";
+  sparc_init_reloc (eh);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, machine_flag_check);
+  HOOK (eh, check_special_section);
+  HOOK (eh, symbol_type_name);
+  HOOK (eh, dynamic_tag_name);
+  HOOK (eh, dynamic_tag_check);
+  if (eh->class == ELFCLASS64)
+    eh->core_note = sparc64_core_note;
+  else
+    HOOK (eh, core_note);
+  HOOK (eh, auxv_info);
+  HOOK (eh, register_info);
+  HOOK (eh, return_value_location);
+  HOOK (eh, check_object_attribute);
+  HOOK (eh, abi_cfi);
+  /* gcc/config/sparc.h define FIRST_PSEUDO_REGISTER  */
+  eh->frame_nregs = 103;
+  /* The CFI Dwarf register with the "return address" in sparc
+     actually contains the call address.  The return address is
+     located 8 bytes after it.  */
+  eh->ra_offset = 8;
+  HOOK (eh, set_initial_registers_tid);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/sparc_initreg.c b/third_party/elfutils/backends/sparc_initreg.c
new file mode 100644
index 0000000..c4b321c
--- /dev/null
+++ b/third_party/elfutils/backends/sparc_initreg.c
@@ -0,0 +1,129 @@
+/* Fetch live process registers from TID.
+   Copyright (C) 2015 Oracle, In
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "system.h"
+#include <stdlib.h>
+#ifdef __sparc__
+# include <asm/ptrace.h>
+# include <sys/ptrace.h>
+#endif
+
+#define BACKEND sparc_
+#include "libebl_CPU.h"
+
+bool
+EBLHOOK (set_initial_registers_tid) (pid_t tid __attribute__ ((unused)),
+                                     ebl_tid_registers_t *setfunc __attribute__ ((unused)),
+                                     void *arg __attribute__ ((unused)))
+{
+#if !defined(__sparc__) || !defined( __arch64__)
+  return false;
+#else /* __sparc__ */
+
+
+  /* The pt_regs structure filled in by PTRACE_GETREGS provides the
+     PC, the global registers and the output registers.  Note how the
+     %g0 register is not explicitly provided in the structure (it's
+     value is always 0) and the resulting weird packing in the u_regs
+     array: the last element is not used.  */
+  
+  struct pt_regs regs;
+  if (ptrace (PTRACE_GETREGS, tid, &regs, 0) == -1)
+    return false;
+
+  /* PC: no DWARF number  */
+  if (!setfunc (-1, 1, (Dwarf_Word *) &regs.tpc, arg))
+    return false;
+  
+  /* Global registers: DWARF 0 .. 7  */
+  Dwarf_Word zero = 0;
+  if (!setfunc (0, 1, &zero, arg))
+    return false;
+  if (!setfunc (1, 7, (Dwarf_Word *) &regs.u_regs[0], arg))
+    return false;
+
+  /* Output registers: DWARF  8 .. 15  */
+  if (!setfunc (8, 8, (Dwarf_Word *) &regs.u_regs[7], arg))
+    return false;
+
+  /* Local and input registers must be read from the stack.  They are
+     saved in the previous stack frame.  The stack pointer is %o6,
+     read above.  */
+
+  Dwarf_Word locals_outs[16];
+  Dwarf_Word sp = regs.u_regs[13];
+
+  if (sp & 1)
+    {
+      /* Registers are 64 bits, and we need to apply the 2047 stack
+         bias in order to get the real stack pointer.  */
+
+      sp += 2047;
+
+      for (unsigned i = 0; i < 16; i++)
+        {
+          locals_outs[i] = ptrace (PTRACE_PEEKDATA, tid,
+                                   (void *) (uintptr_t) (sp + (i * 8)),
+                                   NULL);
+          if (errno != 0)
+            return false;
+        }
+    }
+  else
+    {
+      /* Registers are 32 bits.  */
+
+      for (unsigned i = 0; i < 8; i++)
+        {
+          Dwarf_Word tuple = ptrace (PTRACE_PEEKDATA, tid,
+                                     (void *) (uintptr_t) (sp + (i * 8)),
+                                     NULL);
+          if (errno != 0)
+            return false;
+
+          locals_outs[2*i] = (tuple >> 32) & 0xffffffff;
+          locals_outs[2*i+1] = tuple & 0xffffffff;
+        }
+    }
+
+  
+  /* Local registers:  DWARF 16 .. 23 */
+  if (!setfunc (16, 8, &locals_outs[0], arg))
+    return false;
+  
+  /* Input registers: DWARF 24 .. 31 */
+  if (!setfunc (24, 8, &locals_outs[8], arg))
+    return false;
+
+  return true;
+#endif
+}
diff --git a/third_party/elfutils/backends/sparc_regs.c b/third_party/elfutils/backends/sparc_regs.c
new file mode 100644
index 0000000..2bddcf4
--- /dev/null
+++ b/third_party/elfutils/backends/sparc_regs.c
@@ -0,0 +1,111 @@
+/* Register names and numbers for SPARC DWARF.
+   Copyright (C) 2005, 2006, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND sparc_
+#include "libebl_CPU.h"
+
+ssize_t
+sparc_register_info (Ebl *ebl,
+		     int regno, char *name, size_t namelen,
+		     const char **prefix, const char **setname,
+		     int *bits, int *type)
+{
+  const int nfp = 32 + (ebl->class == ELFCLASS32 ? 0 : 16);
+  const int nspec = ebl->class == ELFCLASS32 ? 8 : 6;
+
+  if (name == NULL)
+    return 32 + nfp + nspec;
+
+  if (regno < 0 || regno >= 32 + nfp + nspec || namelen < 6)
+    return -1;
+
+  *bits = ebl->class == ELFCLASS32 ? 32 : 64;
+  *type = DW_ATE_signed;
+
+  *prefix = "%";
+
+  if (regno >= 32 + nfp)
+    {
+      regno -= 32 + nfp;
+      static const char names[2][8][6] =
+	{
+	  { "y", "psr", "wim", "tbr", "pc", "npc", "fsr", "csr" }, /* v8 */
+	  { "pc", "npc", "state", "fsr", "fprs", "y" } /* v9 */
+	};
+      *setname = "control";
+      *type = DW_ATE_unsigned;
+      if ((ebl->class == ELFCLASS64 ? 0 : 4) + 1 - (unsigned int) regno <= 1)
+	*type = DW_ATE_address;
+      return stpncpy (name, names[ebl->class == ELFCLASS64][regno],
+		      namelen) + 1 - name;
+    }
+
+  if (regno < 32)
+    {
+      *setname = "integer";
+      name[0] = "goli"[regno >> 3];
+      name[1] = (regno & 7) + '0';
+      namelen = 2;
+      if ((regno & 8) && (regno & 7) == 6)
+	*type = DW_ATE_address;
+    }
+  else
+    {
+      *setname = "FPU";
+      *type = DW_ATE_float;
+
+      regno -= 32;
+      if (regno >= 32)
+	regno = 32 + 2 * (regno - 32);
+      else
+	*bits = 32;
+
+      name[0] = 'f';
+      if (regno < 10)
+	{
+	  name[1] = regno + '0';
+	  namelen = 2;
+	}
+      else
+	{
+	  name[1] = regno / 10 + '0';
+	  name[2] = regno % 10 + '0';
+	  namelen = 3;
+	}
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
diff --git a/third_party/elfutils/backends/sparc_reloc.def b/third_party/elfutils/backends/sparc_reloc.def
new file mode 100644
index 0000000..7cd5ce9
--- /dev/null
+++ b/third_party/elfutils/backends/sparc_reloc.def
@@ -0,0 +1,124 @@
+/* List the relocation types for sparc.  -*- C -*-
+   Copyright (C) 2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* 	    NAME,		REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,               REL)
+RELOC_TYPE (8,                  REL)
+RELOC_TYPE (16,                 REL)
+RELOC_TYPE (32,                 REL|DYN)
+RELOC_TYPE (DISP8,              REL)
+RELOC_TYPE (DISP16,             REL)
+RELOC_TYPE (DISP32,             REL)
+RELOC_TYPE (WDISP30,            REL)
+RELOC_TYPE (WDISP22,            REL)
+RELOC_TYPE (HI22,               REL)
+RELOC_TYPE (22,                 REL)
+RELOC_TYPE (13,                 REL)
+RELOC_TYPE (LO10,               REL)
+RELOC_TYPE (GOT10,              REL)
+RELOC_TYPE (GOT13,              REL)
+RELOC_TYPE (GOT22,              REL)
+RELOC_TYPE (PC10,               REL)
+RELOC_TYPE (PC22,               REL)
+RELOC_TYPE (WPLT30,             REL)
+RELOC_TYPE (COPY,               EXEC|DYN)
+RELOC_TYPE (GLOB_DAT,           EXEC|DYN)
+RELOC_TYPE (JMP_SLOT,           EXEC|DYN)
+RELOC_TYPE (RELATIVE,           EXEC|DYN)
+RELOC_TYPE (UA32,               REL)
+RELOC_TYPE (PLT32,              REL)
+RELOC_TYPE (HIPLT22,            REL)
+RELOC_TYPE (LOPLT10,            REL)
+RELOC_TYPE (PCPLT32,            REL)
+RELOC_TYPE (PCPLT22,            REL)
+RELOC_TYPE (PCPLT10,            REL)
+RELOC_TYPE (10,                 REL)
+RELOC_TYPE (11,                 REL)
+RELOC_TYPE (64,                 REL|DYN)
+RELOC_TYPE (OLO10,              REL)
+RELOC_TYPE (HH22,               REL)
+RELOC_TYPE (HM10,               REL)
+RELOC_TYPE (LM22,               REL)
+RELOC_TYPE (PC_HH22,            REL)
+RELOC_TYPE (PC_HM10,            REL)
+RELOC_TYPE (PC_LM22,            REL)
+RELOC_TYPE (WDISP16,            REL)
+RELOC_TYPE (WDISP19,            REL)
+RELOC_TYPE (GLOB_JMP,		EXEC|DYN)
+RELOC_TYPE (7,                  REL)
+RELOC_TYPE (5,                  REL)
+RELOC_TYPE (6,                  REL)
+RELOC_TYPE (DISP64,             REL)
+RELOC_TYPE (PLT64,              REL)
+RELOC_TYPE (HIX22,              REL)
+RELOC_TYPE (LOX10,              REL)
+RELOC_TYPE (H44,                REL)
+RELOC_TYPE (M44,                REL)
+RELOC_TYPE (L44,                REL)
+RELOC_TYPE (REGISTER,           REL)
+RELOC_TYPE (UA64,               REL)
+RELOC_TYPE (UA16,               REL)
+RELOC_TYPE (TLS_GD_HI22,        REL)
+RELOC_TYPE (TLS_GD_LO10,        REL)
+RELOC_TYPE (TLS_GD_ADD,         REL)
+RELOC_TYPE (TLS_GD_CALL,        REL)
+RELOC_TYPE (TLS_LDM_HI22,       REL)
+RELOC_TYPE (TLS_LDM_LO10,       REL)
+RELOC_TYPE (TLS_LDM_ADD,        REL)
+RELOC_TYPE (TLS_LDM_CALL,       REL)
+RELOC_TYPE (TLS_LDO_HIX22,      REL)
+RELOC_TYPE (TLS_LDO_LOX10,      REL)
+RELOC_TYPE (TLS_LDO_ADD,        REL)
+RELOC_TYPE (TLS_IE_HI22,        REL)
+RELOC_TYPE (TLS_IE_LO10,        REL)
+RELOC_TYPE (TLS_IE_LD,          REL)
+RELOC_TYPE (TLS_IE_LDX,         REL)
+RELOC_TYPE (TLS_IE_ADD,         REL)
+RELOC_TYPE (TLS_LE_HIX22,       REL)
+RELOC_TYPE (TLS_LE_LOX10,       REL)
+RELOC_TYPE (TLS_DTPMOD32,       DYN)
+RELOC_TYPE (TLS_DTPMOD64,       DYN)
+RELOC_TYPE (TLS_DTPOFF32,       DYN)
+RELOC_TYPE (TLS_DTPOFF64,       DYN)
+RELOC_TYPE (TLS_TPOFF32,        DYN)
+RELOC_TYPE (TLS_TPOFF64,        DYN)
+RELOC_TYPE (GOTDATA_HIX22,	REL)
+RELOC_TYPE (GOTDATA_LOX10,	REL)
+RELOC_TYPE (GOTDATA_OP_HIX22,	REL|DYN)
+RELOC_TYPE (GOTDATA_OP_LOX10,	REL|DYN)
+RELOC_TYPE (GOTDATA_OP,		REL|DYN)
+RELOC_TYPE (H34,		REL)
+RELOC_TYPE (SIZE32,		REL)
+RELOC_TYPE (SIZE64,		REL)
+RELOC_TYPE (WDISP10,		REL)
+RELOC_TYPE (JMP_IREL,		REL)
+RELOC_TYPE (IRELATIVE,		REL)
+RELOC_TYPE (GNU_VTINHERIT,	REL)
+RELOC_TYPE (GNU_VTENTRY,	REL)
+RELOC_TYPE (REV32,		REL)
diff --git a/third_party/elfutils/backends/sparc_retval.c b/third_party/elfutils/backends/sparc_retval.c
new file mode 100644
index 0000000..fb81cdc
--- /dev/null
+++ b/third_party/elfutils/backends/sparc_retval.c
@@ -0,0 +1,159 @@
+/* Function return value location for SPARC.
+   Copyright (C) 2006-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND sparc_
+#include "libebl_CPU.h"
+
+
+/* %o0, or pair %o0, %o1.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg8 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_reg9 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+#define nloc_intreg	1
+#define nloc_intregpair	4
+
+/* %f0 or pair %f0, %f1, or quad %f0..%f3.  */
+static const Dwarf_Op loc_fpreg[] =
+  {
+    { .atom = DW_OP_regx, .number = 32 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_regx, .number = 33 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_regx, .number = 34 }, { .atom = DW_OP_piece, .number = 4 },
+    { .atom = DW_OP_regx, .number = 35 }, { .atom = DW_OP_piece, .number = 4 },
+  };
+#define nloc_fpreg	1
+#define nloc_fpregpair	4
+#define nloc_fpregquad	8
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in %o0.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_breg8, .number = 0 }
+  };
+#define nloc_aggregate 1
+
+int
+sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  Dwarf_Word size;
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Attribute attr_mem;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+						   &attr_mem), &size) != 0)
+	  {
+	    uint8_t asize;
+	    Dwarf_Die cudie;
+	    if ((tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+		&& dwarf_diecu (typedie, &cudie, &asize, NULL) != NULL)
+	      size = asize;
+	    else
+	      return -1;
+	  }
+      }
+
+      if (tag == DW_TAG_base_type)
+	{
+	  Dwarf_Attribute attr_mem;
+	  Dwarf_Word encoding;
+	  if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+						     &attr_mem),
+			       &encoding) != 0)
+	    return -1;
+	  if (encoding == DW_ATE_float)
+	    {
+	      *locp = loc_fpreg;
+	      if (size <= 4)
+		return nloc_fpreg;
+	      if (size <= 8)
+		return nloc_fpregpair;
+	      if (size <= 16)
+		return nloc_fpregquad;
+	    }
+	}
+      if (size <= 8)
+	{
+	intreg:
+	  *locp = loc_intreg;
+	  return size <= 4 ? nloc_intreg : nloc_intregpair;
+	}
+
+    aggregate:
+      *locp = loc_aggregate;
+      return nloc_aggregate;
+
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+    case DW_TAG_array_type:
+      if (dwarf_aggregate_size (typedie, &size) == 0
+	  && size > 0 && size <= 8)
+	goto intreg;
+      goto aggregate;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/sparc_symbol.c b/third_party/elfutils/backends/sparc_symbol.c
new file mode 100644
index 0000000..ec11dc9
--- /dev/null
+++ b/third_party/elfutils/backends/sparc_symbol.c
@@ -0,0 +1,148 @@
+/* SPARC specific symbolic name handling.
+   Copyright (C) 2002, 2003, 2005, 2007, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+
+#define BACKEND		sparc_
+#include "libebl_CPU.h"
+
+/* Check for the simple reloc types.  */
+Elf_Type
+sparc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_SPARC_8:
+      return ELF_T_BYTE;
+    case R_SPARC_16:
+    case R_SPARC_UA16:
+      return ELF_T_HALF;
+    case R_SPARC_32:
+    case R_SPARC_UA32:
+      return ELF_T_WORD;
+    case R_SPARC_64:
+    case R_SPARC_UA64:
+      return ELF_T_XWORD;
+    default:
+      return ELF_T_NUM;
+    }
+}
+
+/* Check whether machine flags are valid.  */
+bool
+sparc_machine_flag_check (GElf_Word flags)
+{
+  return ((flags &~ (EF_SPARCV9_MM
+		     | EF_SPARC_LEDATA
+		     | EF_SPARC_32PLUS
+		     | EF_SPARC_SUN_US1
+		     | EF_SPARC_SUN_US3)) == 0);
+}
+
+bool
+sparc_check_special_section (Ebl *ebl,
+			     int ndx __attribute__ ((unused)),
+			     const GElf_Shdr *shdr,
+			     const char *sname __attribute__ ((unused)))
+{
+  if ((shdr->sh_flags & (SHF_WRITE | SHF_EXECINSTR))
+      == (SHF_WRITE | SHF_EXECINSTR))
+    {
+      /* This is ordinarily flagged, but is valid for a PLT on SPARC.
+
+	 Look for the SHT_DYNAMIC section and the DT_PLTGOT tag in it.
+	 Its d_ptr should match the .plt section's sh_addr.  */
+
+      Elf_Scn *scn = NULL;
+      while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+	{
+	  GElf_Shdr scn_shdr;
+	  if (likely (gelf_getshdr (scn, &scn_shdr) != NULL)
+	      && scn_shdr.sh_type == SHT_DYNAMIC
+	      && scn_shdr.sh_entsize != 0)
+	    {
+	      Elf_Data *data = elf_getdata (scn, NULL);
+	      if (data != NULL)
+		for (size_t i = 0; i < data->d_size / scn_shdr.sh_entsize; ++i)
+		  {
+		    GElf_Dyn dyn;
+		    if (unlikely (gelf_getdyn (data, i, &dyn) == NULL))
+		      break;
+		    if (dyn.d_tag == DT_PLTGOT)
+		      return dyn.d_un.d_ptr == shdr->sh_addr;
+		  }
+	      break;
+	    }
+	}
+    }
+
+  return false;
+}
+
+const char *
+sparc_symbol_type_name (int type,
+			char *buf __attribute__ ((unused)),
+			size_t len __attribute__ ((unused)))
+{
+  switch (type)
+    {
+    case STT_SPARC_REGISTER:
+      return "SPARC_REGISTER";
+    }
+  return NULL;
+}
+
+const char *
+sparc_dynamic_tag_name (int64_t tag,
+			char *buf __attribute__ ((unused)),
+			size_t len __attribute__ ((unused)))
+{
+  switch (tag)
+    {
+    case DT_SPARC_REGISTER:
+      return "SPARC_REGISTER";
+    }
+  return NULL;
+}
+
+bool
+sparc_dynamic_tag_check (int64_t tag)
+{
+  switch (tag)
+    {
+    case DT_SPARC_REGISTER:
+      return true;
+    }
+  return false;
+}
diff --git a/third_party/elfutils/backends/tilegx_corenote.c b/third_party/elfutils/backends/tilegx_corenote.c
new file mode 100644
index 0000000..be3e7db
--- /dev/null
+++ b/third_party/elfutils/backends/tilegx_corenote.c
@@ -0,0 +1,64 @@
+/* TILE-Gx specific core note handling.
+   Copyright (C) 2012 Tilera Corporation
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#define BACKEND	tilegx_
+#include "libebl_CPU.h"
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+    { .offset = 0, .regno = 0, .count = 56, .bits = 64 }, /* r0-r55 */
+    { .offset = 56 * 8, .regno = 64, .count = 1, .bits = 64 } /* pc */
+  };
+#define PRSTATUS_REGS_SIZE	(57 * 8)
+
+#define ULONG			uint64_t
+#define ALIGN_ULONG		8
+#define TYPE_ULONG		ELF_T_XWORD
+#define TYPE_LONG		ELF_T_SXWORD
+#define PID_T			int32_t
+#define	UID_T			uint32_t
+#define	GID_T			uint32_t
+#define ALIGN_PID_T		4
+#define ALIGN_UID_T		4
+#define ALIGN_GID_T		4
+#define TYPE_PID_T		ELF_T_SWORD
+#define TYPE_UID_T		ELF_T_WORD
+#define TYPE_GID_T		ELF_T_WORD
+
+#include "linux-core-note.c"
diff --git a/third_party/elfutils/backends/tilegx_init.c b/third_party/elfutils/backends/tilegx_init.c
new file mode 100644
index 0000000..162ed36
--- /dev/null
+++ b/third_party/elfutils/backends/tilegx_init.c
@@ -0,0 +1,59 @@
+/* Initialization of TILE-Gx specific backend library.
+   Copyright (C) 2012 Tilera Corporation
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		tilegx_
+#define RELOC_PREFIX	R_TILEGX_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on tilegx_reloc.def.  */
+#include "common-reloc.c"
+
+const char *
+tilegx_init (Elf *elf __attribute__ ((unused)),
+	     GElf_Half machine __attribute__ ((unused)),
+	     Ebl *eh,
+	     size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "TILE-Gx";
+  tilegx_init_reloc (eh);
+  HOOK (eh, reloc_simple_type);
+  HOOK (eh, return_value_location);
+  HOOK (eh, register_info);
+  HOOK (eh, core_note);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/tilegx_regs.c b/third_party/elfutils/backends/tilegx_regs.c
new file mode 100644
index 0000000..b1e1743
--- /dev/null
+++ b/third_party/elfutils/backends/tilegx_regs.c
@@ -0,0 +1,129 @@
+/* Register names and numbers for TILE-Gx DWARF.
+   Copyright (C) 2012 Tilera Corporation
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <dwarf.h>
+
+#define BACKEND tilegx_
+#include "libebl_CPU.h"
+
+ssize_t
+tilegx_register_info (Ebl *ebl __attribute__ ((unused)),
+		    int regno, char *name, size_t namelen,
+		    const char **prefix, const char **setname,
+		    int *bits, int *type)
+{
+  if (name == NULL)
+    return 65;
+
+  if (regno < 0 || regno > 64 || namelen < 5)
+    return -1;
+
+  *prefix = "";
+  *setname = "integer";
+  *bits = 64;
+
+  switch (regno)
+    {
+    case 0 ... 9:
+      *type = DW_ATE_signed;
+      name[0] = 'r';
+      name[1] = regno + '0';
+      namelen = 2;
+      break;
+
+    case 10 ... 52:
+      *type = DW_ATE_signed;
+      name[0] = 'r';
+      name[1] = regno / 10 + '0';
+      name[2] = regno % 10 + '0';
+      namelen = 3;
+      break;
+
+    case 53:
+      *type = DW_ATE_address;
+      return stpcpy (name, "tp") + 1 - name;
+
+    case 54:
+      *type = DW_ATE_address;
+      return stpcpy (name, "sp") + 1 - name;
+
+    case 55:
+      *type = DW_ATE_address;
+      return stpcpy (name, "lr") + 1 - name;
+
+    case 56:
+      *type = DW_ATE_unsigned;
+      return stpcpy (name, "sn") + 1 - name;
+
+    case 57:
+      *type = DW_ATE_unsigned;
+      return stpcpy (name, "idn0") + 1 - name;
+
+    case 58:
+      *type = DW_ATE_unsigned;
+      return stpcpy (name, "idn1") + 1 - name;
+
+    case 59:
+      *type = DW_ATE_unsigned;
+      return stpcpy (name, "udn0") + 1 - name;
+
+    case 60:
+      *type = DW_ATE_unsigned;
+      return stpcpy (name, "udn1") + 1 - name;
+
+    case 61:
+      *type = DW_ATE_unsigned;
+      return stpcpy (name, "udn2") + 1 - name;
+
+    case 62:
+      *type = DW_ATE_unsigned;
+      return stpcpy (name, "udn3") + 1 - name;
+
+    case 63:
+      *type = DW_ATE_unsigned;
+      return stpcpy (name, "zero") + 1 - name;
+
+    case 64:
+      *type = DW_ATE_address;
+      return stpcpy (name, "pc") + 1 - name;
+
+    /* Can't happen.  */
+    default:
+      *setname = NULL;
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
diff --git a/third_party/elfutils/backends/tilegx_reloc.def b/third_party/elfutils/backends/tilegx_reloc.def
new file mode 100644
index 0000000..1018110
--- /dev/null
+++ b/third_party/elfutils/backends/tilegx_reloc.def
@@ -0,0 +1,121 @@
+/* List the relocation types for tilegx.  -*- C -*-
+   Copyright (C) 2012 Tilera Corporation
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,			REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,			0)
+RELOC_TYPE (64,				REL|EXEC|DYN)
+RELOC_TYPE (32,				REL|EXEC|DYN)
+RELOC_TYPE (16,				REL|EXEC|DYN)
+RELOC_TYPE (8,				REL|EXEC|DYN)
+RELOC_TYPE (64_PCREL,			REL)
+RELOC_TYPE (32_PCREL,			REL)
+RELOC_TYPE (16_PCREL,			REL)
+RELOC_TYPE (8_PCREL,			REL)
+RELOC_TYPE (HW0,			REL)
+RELOC_TYPE (HW1,			REL)
+RELOC_TYPE (HW2,			REL)
+RELOC_TYPE (HW3,			REL)
+RELOC_TYPE (HW0_LAST,			REL)
+RELOC_TYPE (HW1_LAST,			REL)
+RELOC_TYPE (HW2_LAST,			REL)
+RELOC_TYPE (COPY,			EXEC|DYN)
+RELOC_TYPE (GLOB_DAT,			EXEC|DYN)
+RELOC_TYPE (JMP_SLOT,			EXEC|DYN)
+RELOC_TYPE (RELATIVE,			EXEC|DYN)
+RELOC_TYPE (BROFF_X1,			REL)
+RELOC_TYPE (JUMPOFF_X1,			REL)
+RELOC_TYPE (JUMPOFF_X1_PLT,		REL)
+RELOC_TYPE (IMM8_X0,			REL)
+RELOC_TYPE (IMM8_Y0,			REL)
+RELOC_TYPE (IMM8_X1,			REL)
+RELOC_TYPE (IMM8_Y1,			REL)
+RELOC_TYPE (DEST_IMM8_X1,		REL)
+RELOC_TYPE (MT_IMM14_X1,		REL)
+RELOC_TYPE (MF_IMM14_X1,		REL)
+RELOC_TYPE (MMSTART_X0,			REL)
+RELOC_TYPE (MMEND_X0,			REL)
+RELOC_TYPE (SHAMT_X0,			REL)
+RELOC_TYPE (SHAMT_X1,			REL)
+RELOC_TYPE (SHAMT_Y0,			REL)
+RELOC_TYPE (SHAMT_Y1,			REL)
+RELOC_TYPE (IMM16_X0_HW0,		REL)
+RELOC_TYPE (IMM16_X1_HW0,		REL)
+RELOC_TYPE (IMM16_X0_HW1,		REL)
+RELOC_TYPE (IMM16_X1_HW1,		REL)
+RELOC_TYPE (IMM16_X0_HW2,		REL)
+RELOC_TYPE (IMM16_X1_HW2,		REL)
+RELOC_TYPE (IMM16_X0_HW3,		REL)
+RELOC_TYPE (IMM16_X1_HW3,		REL)
+RELOC_TYPE (IMM16_X0_HW0_LAST,		REL)
+RELOC_TYPE (IMM16_X1_HW0_LAST,		REL)
+RELOC_TYPE (IMM16_X0_HW1_LAST,		REL)
+RELOC_TYPE (IMM16_X1_HW1_LAST,		REL)
+RELOC_TYPE (IMM16_X0_HW2_LAST,		REL)
+RELOC_TYPE (IMM16_X1_HW2_LAST,		REL)
+RELOC_TYPE (IMM16_X0_HW0_PCREL,		REL)
+RELOC_TYPE (IMM16_X1_HW0_PCREL,		REL)
+RELOC_TYPE (IMM16_X0_HW1_PCREL,		REL)
+RELOC_TYPE (IMM16_X1_HW1_PCREL,		REL)
+RELOC_TYPE (IMM16_X0_HW2_PCREL,		REL)
+RELOC_TYPE (IMM16_X1_HW2_PCREL,		REL)
+RELOC_TYPE (IMM16_X0_HW3_PCREL,		REL)
+RELOC_TYPE (IMM16_X1_HW3_PCREL,		REL)
+RELOC_TYPE (IMM16_X0_HW0_LAST_PCREL,	REL)
+RELOC_TYPE (IMM16_X1_HW0_LAST_PCREL,	REL)
+RELOC_TYPE (IMM16_X0_HW1_LAST_PCREL,	REL)
+RELOC_TYPE (IMM16_X1_HW1_LAST_PCREL,	REL)
+RELOC_TYPE (IMM16_X0_HW2_LAST_PCREL,	REL)
+RELOC_TYPE (IMM16_X1_HW2_LAST_PCREL,	REL)
+RELOC_TYPE (IMM16_X0_HW0_GOT,		REL)
+RELOC_TYPE (IMM16_X1_HW0_GOT,		REL)
+RELOC_TYPE (IMM16_X0_HW0_LAST_GOT,	REL)
+RELOC_TYPE (IMM16_X1_HW0_LAST_GOT,	REL)
+RELOC_TYPE (IMM16_X0_HW1_LAST_GOT,	REL)
+RELOC_TYPE (IMM16_X1_HW1_LAST_GOT,	REL)
+RELOC_TYPE (IMM16_X0_HW0_TLS_GD,	REL)
+RELOC_TYPE (IMM16_X1_HW0_TLS_GD,	REL)
+RELOC_TYPE (IMM16_X0_HW0_LAST_TLS_GD,	REL)
+RELOC_TYPE (IMM16_X1_HW0_LAST_TLS_GD,	REL)
+RELOC_TYPE (IMM16_X0_HW1_LAST_TLS_GD,	REL)
+RELOC_TYPE (IMM16_X1_HW1_LAST_TLS_GD,	REL)
+RELOC_TYPE (IMM16_X0_HW0_TLS_IE,	REL)
+RELOC_TYPE (IMM16_X1_HW0_TLS_IE,	REL)
+RELOC_TYPE (IMM16_X0_HW0_LAST_TLS_IE,	REL)
+RELOC_TYPE (IMM16_X1_HW0_LAST_TLS_IE,	REL)
+RELOC_TYPE (IMM16_X0_HW1_LAST_TLS_IE,	REL)
+RELOC_TYPE (IMM16_X1_HW1_LAST_TLS_IE,	REL)
+RELOC_TYPE (TLS_DTPMOD64,		EXEC|DYN)
+RELOC_TYPE (TLS_DTPOFF64,		EXEC|DYN)
+RELOC_TYPE (TLS_TPOFF64,		EXEC|DYN)
+RELOC_TYPE (TLS_DTPMOD32,		EXEC|DYN)
+RELOC_TYPE (TLS_DTPOFF32,		EXEC|DYN)
+RELOC_TYPE (TLS_TPOFF32,		EXEC|DYN)
+RELOC_TYPE (GNU_VTINHERIT,		REL)
+RELOC_TYPE (GNU_VTENTRY,		REL)
diff --git a/third_party/elfutils/backends/tilegx_retval.c b/third_party/elfutils/backends/tilegx_retval.c
new file mode 100644
index 0000000..7f7d24b
--- /dev/null
+++ b/third_party/elfutils/backends/tilegx_retval.c
@@ -0,0 +1,154 @@
+/* Function return value location for Linux/TILE-Gx ABI.
+   Copyright (C) 2012 Tilera Corporation
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND tilegx_
+#include "libebl_CPU.h"
+
+
+/* r0.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg0 }
+  };
+#define nloc_intreg	1
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in r0.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_breg0, .number = 0 }
+  };
+#define nloc_aggregate 1
+
+int
+tilegx_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  Dwarf_Word size;
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Attribute attr_mem;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+						   &attr_mem), &size) != 0)
+	  {
+	    if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	      size = 8;
+	    else
+	      return -1;
+	  }
+	if (tag == DW_TAG_base_type)
+	  {
+	    Dwarf_Word encoding;
+	    if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+						       &attr_mem),
+				 &encoding) != 0)
+	      return -1;
+	  }
+      }
+
+      /* Small enough structs are passed directly in registers R0 ... R7.  */
+      if (size <= 8)
+	{
+	intreg:
+	  *locp = loc_intreg;
+	  return nloc_intreg;
+	}
+
+      FALLTHROUGH;
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+    aggregate:
+      *locp = loc_aggregate;
+      return nloc_aggregate;
+
+    case DW_TAG_array_type:
+    case DW_TAG_string_type:
+      if (dwarf_aggregate_size (typedie, &size) == 0 && size <= 8)
+	{
+	  if (tag == DW_TAG_array_type)
+	    {
+	      Dwarf_Attribute attr_mem, *attr;
+	      /* Check if it's a character array.  */
+	      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	      typedie = dwarf_formref_die (attr, &die_mem);
+	      tag = DWARF_TAG_OR_RETURN (typedie);
+	      if (tag != DW_TAG_base_type)
+		goto aggregate;
+	      if (dwarf_formudata (dwarf_attr_integrate (typedie,
+							 DW_AT_byte_size,
+							 &attr_mem),
+				   &size) != 0)
+		return -1;
+	      if (size != 1)
+		goto aggregate;
+	    }
+	  goto intreg;
+	}
+      goto aggregate;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/tilegx_symbol.c b/third_party/elfutils/backends/tilegx_symbol.c
new file mode 100644
index 0000000..b653326
--- /dev/null
+++ b/third_party/elfutils/backends/tilegx_symbol.c
@@ -0,0 +1,57 @@
+/* TILEGX-specific symbolic name handling.
+   Copyright (C) 2012 Tilera Corporation
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <stddef.h>
+
+#define BACKEND		tilegx_
+#include "libebl_CPU.h"
+
+/* Check for the simple reloc types.  */
+Elf_Type
+tilegx_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_TILEGX_64:
+      return ELF_T_SXWORD;
+    case R_TILEGX_32:
+      return ELF_T_SWORD;
+    case R_TILEGX_16:
+      return ELF_T_HALF;
+    case R_TILEGX_8:
+      return ELF_T_BYTE;
+    default:
+      return ELF_T_NUM;
+    }
+}
diff --git a/third_party/elfutils/backends/x32_corenote.c b/third_party/elfutils/backends/x32_corenote.c
new file mode 100644
index 0000000..bd6560d
--- /dev/null
+++ b/third_party/elfutils/backends/x32_corenote.c
@@ -0,0 +1,2 @@
+#define BITS 32
+#include "x86_64_corenote.c"
diff --git a/third_party/elfutils/backends/x86_64_cfi.c b/third_party/elfutils/backends/x86_64_cfi.c
new file mode 100644
index 0000000..6db8ac4
--- /dev/null
+++ b/third_party/elfutils/backends/x86_64_cfi.c
@@ -0,0 +1,63 @@
+/* x86-64 ABI-specified defaults for DWARF CFI.
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+
+int
+x86_64_abi_cfi (Ebl *ebl __attribute__ ((unused)), Dwarf_CIE *abi_info)
+{
+  static const uint8_t abi_cfi[] =
+    {
+      /* Call-saved regs.  */
+      DW_CFA_same_value, ULEB128_7 (0), /* %rbx */
+      DW_CFA_same_value, ULEB128_7 (6), /* %rbp */
+      DW_CFA_same_value, ULEB128_7 (12), /* %r12 */
+      DW_CFA_same_value, ULEB128_7 (13), /* %r13 */
+      DW_CFA_same_value, ULEB128_7 (14), /* %r14 */
+      DW_CFA_same_value, ULEB128_7 (15), /* %r15 */
+      DW_CFA_same_value, ULEB128_7 (16), /* %r16 */
+
+      /* The CFA is the SP.  */
+      DW_CFA_val_offset, ULEB128_7 (7), ULEB128_7 (0),
+    };
+
+  abi_info->initial_instructions = abi_cfi;
+  abi_info->initial_instructions_end = &abi_cfi[sizeof abi_cfi];
+  abi_info->data_alignment_factor = 8;
+
+  abi_info->return_address_register = 16; /* %rip */
+
+  return 0;
+}
diff --git a/third_party/elfutils/backends/x86_64_corenote.c b/third_party/elfutils/backends/x86_64_corenote.c
new file mode 100644
index 0000000..1bacc60
--- /dev/null
+++ b/third_party/elfutils/backends/x86_64_corenote.c
@@ -0,0 +1,139 @@
+/* x86-64 specific core note handling.
+   Copyright (C) 2005, 2007, 2008 Red Hat, Inc.
+   Copyright (C) H.J. Lu <hjl.tools@gmail.com>, 2015.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <elf.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+#ifndef BITS
+# define BITS 		64
+# define BACKEND	x86_64_
+#else
+# define BITS 		32
+# define BACKEND	x32_
+#endif
+#include "libebl_CPU.h"
+
+
+static const Ebl_Register_Location prstatus_regs[] =
+  {
+#define GR(at, n, dwreg)						\
+    { .offset = at * 8, .regno = dwreg, .count = n, .bits = 64 }
+#define SR(at, n, dwreg)						\
+    { .offset = at * 8, .regno = dwreg, .count = n, .bits = 16, .pad = 6 }
+
+    GR (0, 1, 15),		/* %r15 */
+    GR (1, 1, 14),		/* %r14 */
+    GR (2, 1, 13),		/* %r13 */
+    GR (3, 1, 12),		/* %r12 */
+    GR (4, 1, 6),		/* %rbp */
+    GR (5, 1, 3),		/* %rbx */
+    GR (6, 1, 11),		/* %r11 */
+    GR (7, 1, 10),		/* %r10 */
+    GR (8, 1, 9),		/* %r9 */
+    GR (9, 1, 8),		/* %r8 */
+    GR (10,1, 0),		/* %rax */
+    GR (11,1, 2),		/* %rcx */
+    GR (12,1, 1),		/* %rdx */
+    GR (13,2, 4),		/* %rsi-%rdi */
+    /*  15,1,			    orig_rax */
+    GR (16,1, 16),		/* %rip */
+    SR (17,1, 51),		/* %cs */
+    GR (18,1, 49),		/* %rFLAGS */
+    GR (19,1, 7),		/* %rsp */
+    SR (20,1, 52),		/* %ss */
+    GR (21,2, 58),		/* %fs.base-%gs.base */
+    SR (23,1, 53),		/* %ds */
+    SR (24,1, 50),		/* %es */
+    SR (25,2, 54),		/* %fs-%gs */
+
+#undef	GR
+#undef	SR
+  };
+#define PRSTATUS_REGS_SIZE	(27 * 8)
+
+#if BITS == 32
+# define ULONG			uint32_t
+# define ALIGN_ULONG		4
+# define TYPE_ULONG		ELF_T_WORD
+# define PRPSINFO_UID_T		uint16_t
+# define ALIGN_PRPSINFO_UID_T	2
+# define TYPE_PRPSINFO_UID_T	ELF_T_HALF
+# define PRPSINFO_GID_T		uint16_t
+# define ALIGN_PRPSINFO_GID_T	2
+# define TYPE_PRPSINFO_GID_T	ELF_T_HALF
+#else
+# define ULONG			uint64_t
+# define ALIGN_ULONG		8
+# define TYPE_ULONG		ELF_T_XWORD
+# define PRPSINFO_UID_T		uint32_t
+# define ALIGN_PRPSINFO_UID_T	4
+# define TYPE_PRPSINFO_UID_T	TYPE_UID_T
+# define PRPSINFO_GID_T		uint32_t
+# define ALIGN_PRPSINFO_GID_T	4
+# define TYPE_PRPSINFO_GID_T	TYPE_GID_T
+#endif
+#define PR_REG			uint64_t
+#define ALIGN_PR_REG		8
+#define PID_T			int32_t
+#define	UID_T			uint32_t
+#define	GID_T			uint32_t
+#define ALIGN_PID_T		4
+#define ALIGN_UID_T		4
+#define ALIGN_GID_T		4
+#define TYPE_PID_T		ELF_T_SWORD
+#define TYPE_UID_T		ELF_T_SWORD
+#define TYPE_GID_T		ELF_T_SWORD
+
+#define PRSTATUS_REGSET_ITEMS						      \
+  {									      \
+    .name = "orig_rax", .type = ELF_T_SXWORD, .format = 'd',		      \
+    .offset = offsetof (struct EBLHOOK(prstatus), pr_reg) + (8 * 15),	      \
+    .group = "register"	       			  	       	 	      \
+  }
+
+static const Ebl_Register_Location fpregset_regs[] =
+  {
+    { .offset = 0, .regno = 65, .count = 2, .bits = 16 }, /* fcw-fsw */
+    { .offset = 24, .regno = 64, .count = 1, .bits = 32 }, /* mxcsr */
+    { .offset = 32, .regno = 33, .count = 8, .bits = 80, .pad = 6 }, /* stN */
+    { .offset = 32 + 128, .regno = 17, .count = 16, .bits = 128 }, /* xmm */
+  };
+#define FPREGSET_SIZE	512
+
+#define	EXTRA_NOTES	EXTRA_NOTES_IOPERM
+
+#include "x86_corenote.c"
+#include "linux-core-note.c"
diff --git a/third_party/elfutils/backends/x86_64_init.c b/third_party/elfutils/backends/x86_64_init.c
new file mode 100644
index 0000000..adfa479
--- /dev/null
+++ b/third_party/elfutils/backends/x86_64_init.c
@@ -0,0 +1,74 @@
+/* Initialization of x86-64 specific backend library.
+   Copyright (C) 2002-2009, 2013 Red Hat, Inc.
+   Copyright (C) H.J. Lu <hjl.tools@gmail.com>, 2015.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND		x86_64_
+#define RELOC_PREFIX	R_X86_64_
+#include "libebl_CPU.h"
+
+/* This defines the common reloc hooks based on x86_64_reloc.def.  */
+#include "common-reloc.c"
+
+extern __typeof (EBLHOOK (core_note)) x32_core_note attribute_hidden;
+
+const char *
+x86_64_init (Elf *elf __attribute__ ((unused)),
+	     GElf_Half machine __attribute__ ((unused)),
+	     Ebl *eh,
+	     size_t ehlen)
+{
+  /* Check whether the Elf_BH object has a sufficent size.  */
+  if (ehlen < sizeof (Ebl))
+    return NULL;
+
+  /* We handle it.  */
+  eh->name = "AMD x86-64";
+  x86_64_init_reloc (eh);
+  HOOK (eh, reloc_simple_type);
+  if (eh->class == ELFCLASS32)
+    eh->core_note = x32_core_note;
+  else
+    HOOK (eh, core_note);
+  HOOK (eh, return_value_location);
+  HOOK (eh, register_info);
+  HOOK (eh, syscall_abi);
+  HOOK (eh, auxv_info);
+  HOOK (eh, disasm);
+  HOOK (eh, abi_cfi);
+  /* gcc/config/ #define DWARF_FRAME_REGISTERS.  */
+  eh->frame_nregs = 17;
+  HOOK (eh, set_initial_registers_tid);
+  HOOK (eh, unwind);
+
+  return MODVERSION;
+}
diff --git a/third_party/elfutils/backends/x86_64_initreg.c b/third_party/elfutils/backends/x86_64_initreg.c
new file mode 100644
index 0000000..50e9002
--- /dev/null
+++ b/third_party/elfutils/backends/x86_64_initreg.c
@@ -0,0 +1,73 @@
+/* Fetch live process registers from TID.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#if defined(__x86_64__) && defined(__linux__)
+# include <sys/user.h>
+# include <sys/ptrace.h>
+#endif
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+
+bool
+x86_64_set_initial_registers_tid (pid_t tid __attribute__ ((unused)),
+			  ebl_tid_registers_t *setfunc __attribute__ ((unused)),
+				  void *arg __attribute__ ((unused)))
+{
+#if !defined(__x86_64__) || !defined(__linux__)
+  return false;
+#else /* __x86_64__ */
+  struct user_regs_struct user_regs;
+  if (ptrace (PTRACE_GETREGS, tid, NULL, &user_regs) != 0)
+    return false;
+  Dwarf_Word dwarf_regs[17];
+  dwarf_regs[0] = user_regs.rax;
+  dwarf_regs[1] = user_regs.rdx;
+  dwarf_regs[2] = user_regs.rcx;
+  dwarf_regs[3] = user_regs.rbx;
+  dwarf_regs[4] = user_regs.rsi;
+  dwarf_regs[5] = user_regs.rdi;
+  dwarf_regs[6] = user_regs.rbp;
+  dwarf_regs[7] = user_regs.rsp;
+  dwarf_regs[8] = user_regs.r8;
+  dwarf_regs[9] = user_regs.r9;
+  dwarf_regs[10] = user_regs.r10;
+  dwarf_regs[11] = user_regs.r11;
+  dwarf_regs[12] = user_regs.r12;
+  dwarf_regs[13] = user_regs.r13;
+  dwarf_regs[14] = user_regs.r14;
+  dwarf_regs[15] = user_regs.r15;
+  dwarf_regs[16] = user_regs.rip;
+  return setfunc (0, 17, dwarf_regs, arg);
+#endif /* __x86_64__ */
+}
diff --git a/third_party/elfutils/backends/x86_64_regs.c b/third_party/elfutils/backends/x86_64_regs.c
new file mode 100644
index 0000000..ef987da
--- /dev/null
+++ b/third_party/elfutils/backends/x86_64_regs.c
@@ -0,0 +1,186 @@
+/* Register names and numbers for x86-64 DWARF.
+   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include <string.h>
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+
+ssize_t
+x86_64_register_info (Ebl *ebl __attribute__ ((unused)),
+		      int regno, char *name, size_t namelen,
+		      const char **prefix, const char **setname,
+		      int *bits, int *type)
+{
+  if (name == NULL)
+    return 67;
+
+  if (regno < 0 || regno > 66 || namelen < 7)
+    return -1;
+
+  *prefix = "%";
+  *bits = 64;
+  *type = DW_ATE_unsigned;
+  if (regno < 17)
+    {
+      *setname = "integer";
+      *type = DW_ATE_signed;
+    }
+  else if (regno < 33)
+    {
+      *setname = "SSE";
+      *bits = 128;
+    }
+  else if (regno < 41)
+    {
+      *setname = "x87";
+      *type = DW_ATE_float;
+      *bits = 80;
+    }
+  else if (regno < 49)
+    *setname = "MMX";
+  else if (regno > 49 && regno < 60)
+    {
+      *setname = "segment";
+      *bits = 16;
+    }
+  else
+    *setname = "control";
+
+  switch (regno)
+    {
+      static const char baseregs[][2] =
+	{
+	  "ax", "dx", "cx", "bx", "si", "di", "bp", "sp"
+	};
+
+    case 6 ... 7:
+      *type = DW_ATE_address;
+      FALLTHROUGH;
+    case 0 ... 5:
+      name[0] = 'r';
+      name[1] = baseregs[regno][0];
+      name[2] = baseregs[regno][1];
+      namelen = 3;
+      break;
+
+    case 8 ... 9:
+      name[0] = 'r';
+      name[1] = regno - 8 + '8';
+      namelen = 2;
+      break;
+
+    case 10 ... 15:
+      name[0] = 'r';
+      name[1] = '1';
+      name[2] = regno - 10 + '0';
+      namelen = 3;
+      break;
+
+    case 16:
+      *type = DW_ATE_address;
+      name[0] = 'r';
+      name[1] = 'i';
+      name[2] = 'p';
+      namelen = 3;
+      break;
+
+    case 17 ... 26:
+      name[0] = 'x';
+      name[1] = 'm';
+      name[2] = 'm';
+      name[3] = regno - 17 + '0';
+      namelen = 4;
+      break;
+
+    case 27 ... 32:
+      name[0] = 'x';
+      name[1] = 'm';
+      name[2] = 'm';
+      name[3] = '1';
+      name[4] = regno - 27 + '0';
+      namelen = 5;
+      break;
+
+    case 33 ... 40:
+      name[0] = 's';
+      name[1] = 't';
+      name[2] = regno - 33 + '0';
+      namelen = 3;
+      break;
+
+    case 41 ... 48:
+      name[0] = 'm';
+      name[1] = 'm';
+      name[2] = regno - 41 + '0';
+      namelen = 3;
+      break;
+
+    case 50 ... 55:
+      name[0] = "ecsdfg"[regno - 50];
+      name[1] = 's';
+      namelen = 2;
+      break;
+
+    case 58 ... 59:
+      *type = DW_ATE_address;
+      *bits = 64;
+      name[0] = regno - 58 + 'f';
+      return stpcpy (&name[1], "s.base") + 1 - name;
+
+    case 49:
+      *setname = "integer";
+      return stpcpy (name, "rflags") + 1 - name;
+    case 62:
+      return stpcpy (name, "tr") + 1 - name;
+    case 63:
+      return stpcpy (name, "ldtr") + 1 - name;
+    case 64:
+      return stpcpy (name, "mxcsr") + 1 - name;
+
+    case 65 ... 66:
+      *bits = 16;
+      name[0] = 'f';
+      name[1] = "cs"[regno - 65];
+      name[2] = 'w';
+      namelen = 3;
+      break;
+
+    default:
+      return 0;
+    }
+
+  name[namelen++] = '\0';
+  return namelen;
+}
diff --git a/third_party/elfutils/backends/x86_64_reloc.def b/third_party/elfutils/backends/x86_64_reloc.def
new file mode 100644
index 0000000..07a7c3d
--- /dev/null
+++ b/third_party/elfutils/backends/x86_64_reloc.def
@@ -0,0 +1,65 @@
+/* List the relocation types for x86-64.  -*- C -*-
+   Copyright (C) 2000, 2001, 2002, 2003, 2005, 2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/*	    NAME,	REL|EXEC|DYN	*/
+
+RELOC_TYPE (NONE,	0)
+RELOC_TYPE (64,		REL|EXEC|DYN)
+RELOC_TYPE (PC32,	REL|EXEC|DYN)
+RELOC_TYPE (GOT32,	REL)
+RELOC_TYPE (PLT32,	REL)
+RELOC_TYPE (COPY,	EXEC|DYN)
+RELOC_TYPE (GLOB_DAT,	EXEC|DYN)
+RELOC_TYPE (JUMP_SLOT,	EXEC|DYN)
+RELOC_TYPE (RELATIVE,	EXEC|DYN)
+RELOC_TYPE (GOTPCREL,	REL)
+RELOC_TYPE (32,		REL|EXEC|DYN)
+RELOC_TYPE (32S,	REL)
+RELOC_TYPE (16,		REL)
+RELOC_TYPE (PC16,	REL)
+RELOC_TYPE (8,		REL)
+RELOC_TYPE (PC8,	REL)
+RELOC_TYPE (DTPMOD64,	EXEC|DYN)
+RELOC_TYPE (DTPOFF64,	EXEC|DYN)
+RELOC_TYPE (TPOFF64,	EXEC|DYN)
+RELOC_TYPE (TLSGD,	REL)
+RELOC_TYPE (TLSLD,	REL)
+RELOC_TYPE (DTPOFF32,	REL)
+RELOC_TYPE (GOTTPOFF,	REL)
+RELOC_TYPE (TPOFF32,	REL)
+RELOC_TYPE (PC64,	REL|EXEC|DYN)
+RELOC_TYPE (GOTOFF64,	REL)
+RELOC_TYPE (GOTPC32,	REL)
+RELOC_TYPE (SIZE32,	REL|EXEC|DYN)
+RELOC_TYPE (SIZE64,	REL|EXEC|DYN)
+RELOC_TYPE (GOTPC32_TLSDESC, REL)
+RELOC_TYPE (TLSDESC_CALL, REL)
+RELOC_TYPE (TLSDESC,	REL|EXEC|DYN)
+RELOC_TYPE (IRELATIVE,	EXEC|DYN)
+RELOC_TYPE (GOTPCRELX,	REL)
+RELOC_TYPE (REX_GOTPCRELX, REL)
diff --git a/third_party/elfutils/backends/x86_64_retval.c b/third_party/elfutils/backends/x86_64_retval.c
new file mode 100644
index 0000000..f9114cb
--- /dev/null
+++ b/third_party/elfutils/backends/x86_64_retval.c
@@ -0,0 +1,194 @@
+/* Function return value location for Linux/x86-64 ABI.
+   Copyright (C) 2005-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+
+
+/* %rax, or pair %rax, %rdx.  */
+static const Dwarf_Op loc_intreg[] =
+  {
+    { .atom = DW_OP_reg0 }, { .atom = DW_OP_piece, .number = 8 },
+    { .atom = DW_OP_reg1 }, { .atom = DW_OP_piece, .number = 8 },
+  };
+#define nloc_intreg	1
+#define nloc_intregpair	4
+
+/* %st(0), or pair %st(0), %st(1).  */
+static const Dwarf_Op loc_x87reg[] =
+  {
+    { .atom = DW_OP_regx, .number = 33 },
+    { .atom = DW_OP_piece, .number = 10 },
+    { .atom = DW_OP_regx, .number = 34 },
+    { .atom = DW_OP_piece, .number = 10 },
+  };
+#define nloc_x87reg	1
+#define nloc_x87regpair	4
+
+/* %xmm0, or pair %xmm0, %xmm1.  */
+static const Dwarf_Op loc_ssereg[] =
+  {
+    { .atom = DW_OP_reg17 }, { .atom = DW_OP_piece, .number = 16 },
+    { .atom = DW_OP_reg18 }, { .atom = DW_OP_piece, .number = 16 },
+  };
+#define nloc_ssereg	1
+#define nloc_sseregpair	4
+
+/* The return value is a structure and is actually stored in stack space
+   passed in a hidden argument by the caller.  But, the compiler
+   helpfully returns the address of that space in %rax.  */
+static const Dwarf_Op loc_aggregate[] =
+  {
+    { .atom = DW_OP_breg0, .number = 0 }
+  };
+#define nloc_aggregate 1
+
+
+int
+x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
+{
+  /* Start with the function's type, and get the DW_AT_type attribute,
+     which is the type of the return value.  */
+  Dwarf_Die die_mem, *typedie = &die_mem;
+  int tag = dwarf_peeled_die_type (functypedie, typedie);
+  if (tag <= 0)
+    return tag;
+
+  Dwarf_Word size;
+  switch (tag)
+    {
+    case -1:
+      return -1;
+
+    case DW_TAG_subrange_type:
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
+	{
+	  Dwarf_Attribute attr_mem, *attr;
+	  attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
+	  typedie = dwarf_formref_die (attr, &die_mem);
+	  tag = DWARF_TAG_OR_RETURN (typedie);
+	}
+      FALLTHROUGH;
+
+    case DW_TAG_base_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_pointer_type:
+    case DW_TAG_ptr_to_member_type:
+      {
+	Dwarf_Attribute attr_mem;
+	if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+						   &attr_mem), &size) != 0)
+	  {
+	    if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
+	      size = 8;
+	    else
+	      return -1;
+	  }
+      }
+
+      if (tag == DW_TAG_base_type)
+	{
+	  Dwarf_Attribute attr_mem;
+	  Dwarf_Word encoding;
+	  if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+						     &attr_mem),
+			       &encoding) != 0)
+	    return -1;
+
+	  switch (encoding)
+	    {
+	    case DW_ATE_complex_float:
+	      switch (size)
+		{
+		case 4 * 2:	/* complex float */
+		case 8 * 2:	/* complex double */
+		  *locp = loc_ssereg;
+		  return nloc_sseregpair;
+		case 16 * 2:	/* complex long double */
+		  *locp = loc_x87reg;
+		  return nloc_x87regpair;
+		}
+	      return -2;
+
+	    case DW_ATE_float:
+	      switch (size)
+		{
+		case 4:	/* float */
+		case 8:	/* double */
+		  *locp = loc_ssereg;
+		  return nloc_ssereg;
+		case 16:	/* long double */
+		  /* XXX distinguish __float128, which is sseregpair?? */
+		  *locp = loc_x87reg;
+		  return nloc_x87reg;
+		}
+	      return -2;
+	    }
+	}
+
+    intreg:
+      *locp = loc_intreg;
+      if (size <= 8)
+	return nloc_intreg;
+      if (size <= 16)
+	return nloc_intregpair;
+
+    large:
+      *locp = loc_aggregate;
+      return nloc_aggregate;
+
+    case DW_TAG_structure_type:
+    case DW_TAG_class_type:
+    case DW_TAG_union_type:
+    case DW_TAG_array_type:
+      if (dwarf_aggregate_size (typedie, &size) != 0)
+	goto large;
+      if (size > 16)
+	goto large;
+
+      /* XXX
+	 Must examine the fields in picayune ways to determine the
+	 actual answer.  This will be right for small C structs
+	 containing integer types and similarly simple cases.
+      */
+
+      goto intreg;
+    }
+
+  /* XXX We don't have a good way to return specific errors from ebl calls.
+     This value means we do not understand the type, but it is well-formed
+     DWARF and might be valid.  */
+  return -2;
+}
diff --git a/third_party/elfutils/backends/x86_64_symbol.c b/third_party/elfutils/backends/x86_64_symbol.c
new file mode 100644
index 0000000..1622461
--- /dev/null
+++ b/third_party/elfutils/backends/x86_64_symbol.c
@@ -0,0 +1,60 @@
+/* x86_64 specific symbolic name handling.
+   Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <elf.h>
+#include <stddef.h>
+
+#define BACKEND		x86_64_
+#include "libebl_CPU.h"
+
+/* Check for the simple reloc types.  */
+Elf_Type
+x86_64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+{
+  switch (type)
+    {
+    case R_X86_64_64:
+      return ELF_T_XWORD;
+    case R_X86_64_32:
+      return ELF_T_WORD;
+    case R_X86_64_32S:
+      return ELF_T_SWORD;
+    case R_X86_64_16:
+      return ELF_T_HALF;
+    case R_X86_64_8:
+      return ELF_T_BYTE;
+    default:
+      return ELF_T_NUM;
+    }
+}
diff --git a/third_party/elfutils/backends/x86_64_syscall.c b/third_party/elfutils/backends/x86_64_syscall.c
new file mode 100644
index 0000000..0deb8ba
--- /dev/null
+++ b/third_party/elfutils/backends/x86_64_syscall.c
@@ -0,0 +1,50 @@
+/* Linux/x86-64 system call ABI in DWARF register numbers.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+
+int
+x86_64_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+		    int *sp, int *pc, int *callno, int args[6])
+{
+  *sp = 7;			/* %rsp */
+  *pc = 16;			/* %rip */
+  *callno = 0;			/* %rax */
+  args[0] = 5;			/* %rdi */
+  args[1] = 4;			/* %rsi */
+  args[2] = 1;			/* %rdx */
+  args[3] = 10;			/* %r10 */
+  args[4] = 8;			/* %r8 */
+  args[5] = 9;			/* %r9 */
+  return 0;
+}
diff --git a/third_party/elfutils/backends/x86_64_unwind.c b/third_party/elfutils/backends/x86_64_unwind.c
new file mode 100644
index 0000000..ade64c0
--- /dev/null
+++ b/third_party/elfutils/backends/x86_64_unwind.c
@@ -0,0 +1,86 @@
+/* Get previous frame state for an existing frame state.
+   Copyright (C) 2016 The Qt Company Ltd.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+
+#define BACKEND x86_64_
+#include "libebl_CPU.h"
+
+/* There was no CFI. Maybe we happen to have a frame pointer and can unwind from that?  */
+
+bool
+x86_64_unwind (Ebl *ebl __attribute__ ((unused)),
+               Dwarf_Addr pc __attribute__ ((unused)),
+               ebl_tid_registers_t *setfunc, ebl_tid_registers_get_t *getfunc,
+               ebl_pid_memory_read_t *readfunc, void *arg,
+               bool *signal_framep __attribute__ ((unused)))
+{
+  // Register 6 is supposed to be rbp, thus the conventional frame pointer
+  const int fpReg = 6;
+  const int spReg = 7;
+
+  Dwarf_Word fp;
+  if (!getfunc(fpReg, 1, &fp, arg) || fp == 0)
+    return false;
+
+  // Try to read old sp, so that we can avoid infinite loops below
+  Dwarf_Word sp;
+  if (!getfunc(spReg, 1, &sp, arg))
+    sp = 0;
+
+  Dwarf_Word prev_fp;
+  if (!readfunc(fp, &prev_fp, arg))
+    prev_fp = 0;
+
+  Dwarf_Word ret;
+  if (!readfunc(fp + 8, &ret, arg))
+    return false;
+
+  if (!setfunc(fpReg, 1, &prev_fp, arg))
+    return false;
+
+  fp += 16; // Pop fp and return address and write result to sp
+  if (!setfunc(spReg, 1, &fp, arg))
+    return false;
+
+  if (!setfunc(-1, 1, &ret, arg))
+    return false;
+
+  // If the sp didn't move up we don't actually have a new stack
+  // frame but rather some random data that doesn't include frame
+  // pointers. Break the unwinding then.
+  if (sp >= fp)
+    return false;
+
+  return true;
+}
diff --git a/third_party/elfutils/backends/x86_corenote.c b/third_party/elfutils/backends/x86_corenote.c
new file mode 100644
index 0000000..629462c
--- /dev/null
+++ b/third_party/elfutils/backends/x86_corenote.c
@@ -0,0 +1,51 @@
+/* x86-specific core note handling, pieces common to x86-64 and i386.
+   Copyright (C) 2005-2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define	EXTRA_NOTES_IOPERM \
+  case NT_386_IOPERM: \
+    return ioperm_info (nhdr->n_descsz, \
+			regs_offset, nregloc, reglocs, nitems, items);
+
+static int
+ioperm_info (GElf_Word descsz, GElf_Word *regs_offset,
+	     size_t *nregloc, const Ebl_Register_Location **reglocs,
+	     size_t *nitems, const Ebl_Core_Item **items)
+{
+  static const Ebl_Core_Item ioperm_item =
+    { .type = ELF_T_WORD, .format = 'b', .name = "ioperm" };
+
+  if (descsz % 4 != 0)
+    return 0;
+
+  *regs_offset = 0;
+  *nregloc = 0;
+  *reglocs = NULL;
+  *nitems = 1;
+  *items = &ioperm_item;
+  return 1;
+}
diff --git a/third_party/elfutils/config/10-default-yama-scope.conf b/third_party/elfutils/config/10-default-yama-scope.conf
new file mode 100644
index 0000000..ba78ebd
--- /dev/null
+++ b/third_party/elfutils/config/10-default-yama-scope.conf
@@ -0,0 +1,35 @@
+# When yama is enabled in the kernel it might be used to filter any user
+# space access which requires PTRACE_MODE_ATTACH like ptrace attach, access
+# to /proc/PID/{mem,personality,stack,syscall}, and the syscalls
+# process_vm_readv and process_vm_writev which are used for interprocess
+# services, communication and introspection (like synchronisation, signaling,
+# debugging, tracing and profiling) of processes.
+#
+# Usage of ptrace attach is restricted by normal user permissions. Normal
+# unprivileged processes cannot interact through ptrace with processes
+# that they cannot send signals to or processes that are running set-uid
+# or set-gid.
+#
+# yama ptrace scope can be used to reduce these permissions even more.
+# This should normally not be done because it will break various programs
+# relying on the default ptrace security restrictions. But can be used
+# if you don't have any other way to separate processes in their own
+# domains. A different way to restrict ptrace is to set the selinux
+# deny_ptrace boolean. Both mechanisms will break some programs relying
+# on the ptrace system call and might force users to elevate their
+# priviliges to root to do their work.
+#
+# For more information see Documentation/security/Yama.txt in the kernel
+# sources. Which also describes the defaults when CONFIG_SECURITY_YAMA
+# is enabled in a kernel build (currently 1 for ptrace_scope).
+#
+# This runtime kernel parameter can be set to the following options:
+# (Note that setting this to anything except zero will break programs!)
+#
+# 0 - Default attach security permissions.
+# 1 - Restricted attach. Only child processes plus normal permissions.
+# 2 - Admin-only attach. Only executables with CAP_SYS_PTRACE.
+# 3 - No attach. No process may call ptrace at all. Irrevocable.
+#
+kernel.yama.ptrace_scope = 0
+
diff --git a/third_party/elfutils/config/ChangeLog b/third_party/elfutils/config/ChangeLog
new file mode 100644
index 0000000..681def2
--- /dev/null
+++ b/third_party/elfutils/config/ChangeLog
@@ -0,0 +1,342 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* eu.am (IMPLICIT_FALLTHROUGH_WARNING): Set to 5.
+
+2017-11-02  Mark Wielaard  <mark@klomp.org>
+
+	* elfutils.spec.in: Config files under /usr/lib/sysctl.d (_sysctldir)
+	aren't %config.
+
+2017-10-24  Mark Wielaard  <mark@klomp.org>
+
+	* eu.am (AM_CFLAGS): Handle -Wno-packed-not-aligned.
+
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* eu.am: Use fpic_CFLAGS.
+
+2016-08-02  Mark Wielaard  <mark@klomp.org>
+
+	* elfutils.spec.in: Update for 0.170.
+
+2017-05-05  Mark Wielaard  <mark@klomp.org>
+
+	* elfutils.spec.in: Update for 0.169.
+
+2016-12-27  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Update for 0.168 and new project location.
+
+2016-12-24  Mark Wielaard  <mark@klomp.org>
+
+	* libdw.pc.in: Set URL to http://elfutils.org/
+	* libelf.pc.in: Likewise.
+
+2016-11-02  Mark Wielaard  <mjw@redhat.com>
+
+	* eu.am: Check HAVE_IMPLICIT_FALLTHROUGH_WARNING.
+	(AM_CFLAGS): Add IMPLICIT_FALLTHROUGH_WARNING.
+
+2016-08-04  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Update for 0.167.
+
+2016-07-06  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Remove eu-ld.
+
+2016-03-31  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Update for 0.166.
+
+2016-02-13  Mark Wielaard  <mjw@redhat.com>
+
+	* eu.am: Check HAVE_NULL_DEREFERENCE_WARNING.
+	(AM_CFLAGS): Add NULL_DEREFERENCE_WARNING.
+
+2016-02-09  Mark Wielaard  <mjw@redhat.com>
+
+	* eu.am: Check SANE_LOGICAL_OP_WARNING and
+	HAVE_DUPLICATED_COND_WARNING.
+	(AM_CFLAGS): Add LOGICAL_OP_WARNING and DUPLICATED_COND_WARNING.
+
+2016-01-08  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Add elfcompress. Update for 0.165.
+
+2016-01-04  Mark Wielaard  <mjw@redhat.com>
+
+	* libelf.pc.in: New file.
+	* libdw.pc.in: Likewise.
+	* Makefile.am (EXTRA_DIST): Add libelf.pc.in and libdw.pc.in.
+	(pkgconfigdir): New variable.
+	(pkgconfigdir_DATA): Likewise.
+	* elfutils.spec.in (files devel): Add libdw.pc.
+	(files libelf-devel): Add libelf.pc.
+
+2015-10-15  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Update for 0.164.
+
+2015-10-07  Mark Wielaard  <mjw@redhat.com>
+
+	* eu.am (ARFLAGS): Set to "cr".
+
+2015-10-09  Josh Stone  <jistone@redhat.com>
+
+	* eu.am (print-%): New target to print any variable.
+
+2015-10-05  Josh Stone  <jistone@redhat.com>
+
+	* eu.am (%.os): Add AM_V_CC silencers.
+
+2015-09-24  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* eu.am (%.os): Use -fPIC instead of -fpic to avoid relocation
+	overflows in some platforms.
+
+2015-09-22  Mark Wielaard  <mjw@redhat.com>
+
+	* eu.am (AM_CFLAGS): Add -Wold-style-definition -Wstrict-prototypes.
+
+2015-08-04  Mark Wielaard  <mjw@redhat.com>
+
+	* 10-default-yama-scope.conf: New file.
+	* Makefile.am (EXTRA_DIST): Add 10-default-yama-scope.conf.
+	* elfutils.spec.in (Requires): default-yama-scope.
+	(default-yama-scope): New package.
+
+2015-06-19  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Update for 0.163.
+
+2015-06-11  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in (devel): Include elfutils/known-dwarf.h and
+	elfutils/version.h.
+
+2015-06-10  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Update for 0.162.
+
+2015-05-23  Mark Wielaard  <mjw@redhat.com>
+
+	* eu.am (STACK_USAGE_WARNING): New variable set based on
+	ADD_STACK_USAGE_WARNING conditional.
+	(AM_CFLAGS): Use STACK_USAGE_WARNING variable.
+
+2015-05-23  Mark Wielaard  <mjw@redhat.com>
+
+	* eu.am (AM_CFLAGS): Add -Wstack-usage=262144.
+
+2015-04-23  Max Filippov  <jcmvbkbc@gmail.com>
+
+	* eu.am (DEFS.os): New variable.
+
+2015-03-18  Petr Machata  <pmachata@redhat.com>
+
+	* known-dwarf.awk (comment): Drop all uses of this variable.
+	(END): Always emit the non-_DESC variant.  Emit
+	DWARF_ALL_KNOWN_DW_ instead of ALL_KNOWN_DW_*, and
+	DWARF_ONE_KNOWN_DW_ instead of ONE_KNOWN_DW_*.
+
+2015-02-20  Petr Machata  <pmachata@redhat.com>
+
+	* known-dwarf.awk (END): Drop useless variables lo, hi.  Merge two
+	continue-checks in one.
+
+2014-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Update for 0.161.
+
+2014-11-27  Mark Wielaard  <mjw@redhat.com>
+
+	* eu.am: Define textrel_msg, textrel_found and textrel_check based
+	on FATAL_TEXTREL.
+
+2014-08-25  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Update for 0.160.
+
+2014-05-17  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Update for 0.159.
+	(%files devel): Add libdwelf.h.
+
+2014-04-13  Mark Wielaard  <mjw@redhat.com>
+
+	* eu.am (AM_CFLAGS): Don't add -fmudflap.
+	(COMPILE.os): Don't remove no_mudflap.os.
+
+2014-01-22  Mark Wielaard  <mjw@redhat.com>
+
+	* eu.am (AM_CFLAGS): Unconditionally add -Wformat=2.
+
+2014-01-03  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Update for 0.158.
+
+2013-11-01  Michael Forney  <mforney@mforney.org>
+
+	* eu.am: Use READELF.
+
+2013-09-30  Mark Wielaard  <mjw@redhat.com>
+
+	* elfutils.spec.in: Update for readelf NT_SIGINFO and NT_FILE
+	core notes.
+
+2013-09-27  Mark Wielaard  <mjw@redhat.com>
+
+	* config/elfutils.spec.in: Update for 0.157.
+
+2013-07-25  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* config/elfutils.spec.in: Update for 0.156.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* eu.am: Use AM_CPPFLAGS instead of INCLUDES.
+
+2012-08-27  Mark Wielaard  <mjw@redhat.com>
+
+	* config/elfutils.spec.in: Update for 0.155.
+
+2012-07-19  Mark Wielaard  <mjw@redhat.com>
+
+	* known-dwarf.awk: "Generated by" header had wrong file names,
+	mention config/known-dwarf.awk and libdw/dwarf.h contents.
+
+2012-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* config/elfutils.spec.in: Update for 0.154.
+
+2012-02-23  Mark Wielaard  <mjw@redhat.com>
+
+	* config/elfutils.spec.in: Update for 0.153.
+
+2011-10-31  Mark Wielaard  <mjw@redhat.com>
+
+	* known-dwarf.awk: Use gawk.
+
+2010-07-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in: Add more BuildRequires.
+	Ship the .mo files with the libelf subpackage.
+
+2010-04-15  Roland McGrath  <roland@redhat.com>
+
+	* eu.am (DEFS): Add -DLOCALEDIR=... here.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* eu.am: New file.
+
+2009-04-19  Roland McGrath  <roland@redhat.com>
+
+	* version.h.in: Revert last change.
+
+2009-04-17  Roland McGrath  <roland@redhat.com>
+
+	* version.h.in (_ELFUTILS_PREREQ): Multiple major by 1000000 and minor
+	by 1000; now _ELFUTILS_VERSION is 789000 for version 0.789.
+
+2009-01-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in: Distribute <elfutils/version.h> in
+	elfutils-libelf-devel.
+
+2009-01-22  Roland McGrath  <roland@redhat.com>
+
+	* known-dwarf.awk: Handle DW_FOO_BAR_* sets better.
+
+2009-01-11  Roland McGrath  <roland@redhat.com>
+
+	* known-dwarf.awk: New file.
+	* Makefile.am (EXTRA_DIST): Add it.
+
+2008-12-24  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am ($(srcdir)/elfutils.spec.in): Rewrite awk magic.
+	Put the target inside [if MAINTAINER_MODE].
+
+2008-12-16  Roland McGrath  <roland@redhat.com>
+
+	* version.h.in: New file.
+
+2008-01-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in: Add m4 to build requirements.
+
+2008-01-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in: Changes for disasm branch merge.
+
+2007-08-08  Roland McGrath  <roland@redhat.com>
+
+	* elfutils.spec.in (License): Canonicalize.
+
+2007-04-23  Roland McGrath  <roland@redhat.com>
+
+	* elfutils.spec.in: Distribute eu-unstrip.
+
+2005-08-13  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am ($(srcdir)/elfutils.spec.in): Add missing $.
+
+2005-07-28  Roland McGrath  <roland@redhat.com>
+
+	* elfutils.spec.in: Remove libdwfl.so from package.
+
+2005-07-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in: Distribute eu-elfcmp.
+
+2005-04-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in: Distribute eu-addr2line.
+
+2005-03-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in: Distribute libdw.{a,so,h}.
+
+2005-02-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Ignore result of cvs run.
+
+	* elfutils.spec.in: Simplify build process by not using a subdir.
+	This means we can use %configure.
+
+2005-02-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Automatically added changelog from NEWS file on dist.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in: Make sure RPM_OPT_FLAGS is used.  During
+	%build, really do build the binaries.
+	Remove --enable-shared configure parameters.
+
+2005-02-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in (BuildRequires): Up gcc requirement to 3.4.
+
+2004-11-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in: Some more changes for the RPM with the fake
+	binaries.
+
+2004-01-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.spec.in: Update BuildRequires.
+
+2004-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: New file.
+	* config.guess: Moved to here from toplevel.
+	* config.rpath: Likewise.
+	* config.sub: Likewise.
+	* depcomp: Likewise.
+	* install-sh: Likewise.
+	* missing: Likewise.
+	* mkinstalldirs: Likewise.
+	* elfutils.spec.in: New file.
diff --git a/third_party/elfutils/config/Makefile.am b/third_party/elfutils/config/Makefile.am
new file mode 100644
index 0000000..66012d0
--- /dev/null
+++ b/third_party/elfutils/config/Makefile.am
@@ -0,0 +1,55 @@
+## Process this file with automake to produce Makefile.in -*-Makefile-*-
+## Configure input file for elfutils.
+##
+## Copyright (C) 2004, 2005, 2008, 2009, 2011, 2015, 2016 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * 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
+##
+## or both in parallel, as here.
+##
+## elfutils 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.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+##
+EXTRA_DIST = elfutils.spec.in known-dwarf.awk 10-default-yama-scope.conf
+	     libelf.pc.in libdw.pc.in
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libelf.pc libdw.pc
+
+if MAINTAINER_MODE
+$(srcdir)/elfutils.spec.in: $(top_srcdir)/NEWS
+	@tmpname=$$(mktemp $${TMPDIR:-/tmp}/elfutils.XXXXXX); \
+	date +'* %a %b %e %Y' | tr '[\n]' '[ ]' > $$tmpname; \
+	getent passwd "$$(whoami)" | \
+	  awk 'BEGIN {FS=":"} { printf $$5; exit 0}' >> $$tmpname; \
+	echo -n " <$$(whoami)@gmail.com> " >> $$tmpname; \
+	awk '\
+	  $$1 == "Version" && started { exit } \
+	  $$1 == "Version" { started=1; line=""; sub(/:/,"",$$2); \
+			     print $$2 "-1"; next } \
+	  NF > 0 { line = (line != "") ? (line " " $$0) : ("- " $$0) } \
+	  NF == 0 && line != "" { print line; line="" } \
+	  END { if (line != "") print line; print "" }' $< \
+	| fold -s -w 70 | sed '1!s/^[^-]/  &/' >> $$tmpname; \
+	sed "/^%changelog/r $$tmpname" $@ > $@.new; \
+	rm -f $$tmpname; \
+	mv -f $@.new $@
+endif
diff --git a/third_party/elfutils/config/elfutils.spec.in b/third_party/elfutils/config/elfutils.spec.in
new file mode 100644
index 0000000..1d0a4f8
--- /dev/null
+++ b/third_party/elfutils/config/elfutils.spec.in
@@ -0,0 +1,921 @@
+# -*- rpm-spec-*-
+Summary: A collection of utilities and DSOs to handle ELF files and DWARF data
+Name: elfutils
+Version: @PACKAGE_VERSION@
+Release: 1
+URL: http://elfutils.org/
+License: GPLv3+ and (GPLv2+ or LGPLv3+)
+Group: Development/Tools
+Source: ftp://sourceware.org/pub/elfutils/%{version}/elfutils-%{version}.tar.bz2
+Obsoletes: libelf libelf-devel
+Requires: elfutils-libelf = %{version}-%{release}
+Requires: glibc >= 2.7
+Requires: libstdc++
+Requires: default-yama-scope
+
+# ExcludeArch: xxx
+
+BuildRoot: %{_tmppath}/%{name}-root
+BuildRequires: gcc >= 4.1.2-33
+BuildRequires: glibc >= 2.7
+BuildRequires: bison >= 1.875
+BuildRequires: flex >= 2.5.4a
+BuildRequires: bzip2
+BuildRequires: m4
+BuildRequires: gettext
+BuildRequires: zlib-devel
+BuildRequires: bzip2-devel
+BuildRequires: xz-devel
+BuildRequires: gcc-c++
+
+%define _gnu %{nil}
+%define _programprefix eu-
+
+%description
+
+Elfutils is a collection of utilities, including stack (to show
+backtraces), nm (for listing symbols from object files), size
+(for listing the section sizes of an object or archive file),
+strip (for discarding symbols), readelf (to see the raw ELF file
+structures), elflint (to check for well-formed ELF files) and
+elfcompress (to compress or decompress ELF sections).
+Also included are helper libraries which implement DWARF, ELF,
+and machine-specific ELF handling and process introspection.
+
+%package devel
+Summary: Development libraries to handle compiled objects.
+Group: Development/Tools
+License: GPLv2+ or LGPLv3+
+Requires: elfutils = %{version}-%{release}
+Requires: elfutils-libelf-devel = %{version}-%{release}
+
+%description devel
+The elfutils-devel package contains the libraries to create
+applications for handling compiled objects.  libebl provides some
+higher-level ELF access functionality.  libdw provides access to
+the DWARF debugging information.  libasm provides a programmable
+assembler interface.
+
+%package devel-static
+Summary: Static archives to handle compiled objects.
+Group: Development/Tools
+License: GPLv2+ or LGPLv3+
+Requires: elfutils-devel = %{version}-%{release}
+
+%description devel-static
+The elfutils-devel-static archive contains the static archives
+with the code the handle compiled objects.
+
+%package libelf
+Summary: Library to read and write ELF files.
+Group: Development/Tools
+License: GPLv2+ or LGPLv3+
+
+%description libelf
+The elfutils-libelf package provides a DSO which allows reading and
+writing ELF files on a high level.  Third party programs depend on
+this package to read internals of ELF files.  The programs of the
+elfutils package use it also to generate new ELF files.
+
+%package libelf-devel
+Summary: Development support for libelf
+Group: Development/Tools
+License: GPLv2+ or LGPLv3+
+Requires: elfutils-libelf = %{version}-%{release}
+Conflicts: libelf-devel
+
+%description libelf-devel
+The elfutils-libelf-devel package contains the libraries to create
+applications for handling compiled objects.  libelf allows you to
+access the internals of the ELF object file format, so you can see the
+different sections of an ELF file.
+
+%package libelf-devel-static
+Summary: Static archive of libelf
+Group: Development/Tools
+License: GPLv2+ or LGPLv3+
+Requires: elfutils-libelf-devel = %{version}-%{release}
+Conflicts: libelf-devel
+
+%description libelf-devel-static
+The elfutils-libelf-static package contains the static archive
+for libelf.
+
+%package default-yama-scope
+Summary: Default yama attach scope sysctl setting
+Group: Development/Tools
+License: GPLv2+ or LGPLv3+
+Provides: default-yama-scope
+BuildArch: noarch
+
+%description default-yama-scope
+Yama sysctl setting to enable default attach scope settings
+enabling programs to use ptrace attach, access to
+/proc/PID/{mem,personality,stack,syscall}, and the syscalls
+process_vm_readv and process_vm_writev which are used for
+interprocess services, communication and introspection
+(like synchronisation, signaling, debugging, tracing and
+profiling) of processes.
+
+%prep
+%setup -q
+
+%build
+%configure --program-prefix=%{_programprefix}
+make
+
+%install
+rm -rf ${RPM_BUILD_ROOT}
+mkdir -p ${RPM_BUILD_ROOT}%{_prefix}
+
+%makeinstall
+
+chmod +x ${RPM_BUILD_ROOT}%{_prefix}/%{_lib}/lib*.so*
+chmod +x ${RPM_BUILD_ROOT}%{_prefix}/%{_lib}/elfutils/lib*.so*
+
+# XXX Nuke unpackaged files
+{ cd ${RPM_BUILD_ROOT}
+  rm -f .%{_includedir}/elfutils/libasm.h
+  rm -f .%{_libdir}/libasm.so
+  rm -f .%{_libdir}/libasm.a
+}
+
+install -Dm0644 config/10-default-yama-scope.conf ${RPM_BUILD_ROOT}%{_sysctldir}/10-default-yama-scope.conf
+
+%check
+make check
+
+%clean
+rm -rf ${RPM_BUILD_ROOT}
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%post libelf -p /sbin/ldconfig
+
+%postun libelf -p /sbin/ldconfig
+
+%post default-yama-scope
+%sysctl_apply 10-default-yama-scope.conf
+
+%files
+%defattr(-,root,root)
+%doc COPYING COPYING-GPLV2 COPYING-LGPLV3 README TODO CONTRIBUTING
+%{_bindir}/eu-elflint
+%{_bindir}/eu-nm
+%{_bindir}/eu-readelf
+%{_bindir}/eu-size
+%{_bindir}/eu-strip
+%{_bindir}/eu-findtextrel
+%{_bindir}/eu-addr2line
+%{_bindir}/eu-elfcmp
+%{_bindir}/eu-ranlib
+%{_bindir}/eu-strings
+%{_bindir}/eu-objdump
+%{_bindir}/eu-ar
+%{_bindir}/eu-unstrip
+%{_bindir}/eu-make-debug-archive
+%{_bindir}/eu-elfcompress
+%{_libdir}/libasm-%{version}.so
+%{_libdir}/libdw-%{version}.so
+%{_libdir}/libasm.so.*
+%{_libdir}/libdw.so.*
+%dir %{_libdir}/elfutils
+%{_libdir}/elfutils/lib*.so
+
+%files devel
+%defattr(-,root,root)
+%{_includedir}/dwarf.h
+%dir %{_includedir}/elfutils
+%{_includedir}/elfutils/elf-knowledge.h
+%{_includedir}/elfutils/known-dwarf.h
+#%{_includedir}/elfutils/libasm.h
+%{_includedir}/elfutils/libebl.h
+%{_includedir}/elfutils/libdw.h
+%{_includedir}/elfutils/libdwfl.h
+%{_includedir}/elfutils/libdwelf.h
+%{_includedir}/elfutils/version.h
+%{_libdir}/libebl.a
+#%{_libdir}/libasm.so
+%{_libdir}/libdw.so
+%{_libdir}/pkgconfig/libdw.pc
+
+%files devel-static
+%{_libdir}/libdw.a
+#%{_libdir}/libasm.a
+
+%files libelf
+%defattr(-,root,root)
+%{_libdir}/libelf-%{version}.so
+%{_libdir}/libelf.so.*
+%{_datadir}/locale/*/LC_MESSAGES/elfutils.mo
+
+%files libelf-devel
+%defattr(-,root,root)
+%{_includedir}/libelf.h
+%{_includedir}/gelf.h
+%{_includedir}/nlist.h
+%{_includedir}/elfutils/version.h
+%{_libdir}/libelf.so
+%{_libdir}/pkgconfig/libelf.pc
+
+%files libelf-devel-static
+%{_libdir}/libelf.a
+
+%files default-yama-scope
+%{_sysctldir}/10-default-yama-scope.conf
+
+%changelog
+* Wed Aug  2 2017 Mark Wielaard <mark@klomp.org> 0.170-1
+- libdw: Added new DWARF5 attribute, tag, character encoding,
+  language code, calling convention, defaulted member function
+  and macro constants to dwarf.h.
+  New functions dwarf_default_lower_bound and dwarf_line_file.
+  dwarf_peel_type now handles DWARF5 immutable, packed and shared tags.
+  dwarf_getmacros now handles DWARF5 .debug_macro sections.
+- strip: Add -R, --remove-section=SECTION and --keep-section=SECTION.
+- backends: The bpf disassembler is now always build on all platforms.
+
+* Fri May  5 2017 Mark Wielaard <mark@klomp.org> 0.169-1
+- backends: Add support for EM_PPC64 GNU_ATTRIBUTES.
+  Frame pointer unwinding fallback support for i386, x86_64, aarch64.
+- translations: Update Polish translation.
+
+* Tue Dec 27 2016 Mark Wielaard <mark@klomp.org> 0.168-1
+- http://elfutils.org/ is now hosted at http://sourceware.org/elfutils/
+- libelf: gelf_newehdr and gelf_newehdr now return void *.
+- libdw: dwarf.h corrected the DW_LANG_PLI constant name (was DW_LANG_PL1).
+- readelf: Add optional --symbols[=SECTION] argument to select section name.
+
+* Thu Aug  4 2016 Mark Wielaard <mjw@redhat.com> 0.167-1
+- libasm: Add eBPF disassembler for EM_BPF files.
+- backends: Add m68k and BPF backends.
+- ld: Removed.
+- dwelf: Add ELF/DWARF string table creation functions.
+  dwelf_strtab_init, dwelf_strtab_add, dwelf_strtab_add_len,
+  dwelf_strtab_finalize, dwelf_strent_off, dwelf_strent_str and
+  dwelf_strtab_free.
+
+* Thu Mar 31 2016 Mark Wielaard <mjw@redhat.com> 0.166-1
+- config: The default program prefix for the installed tools is now
+  eu-. Use configure --program-prefix="" to not use a program prefix.
+
+* Fri Jan  8 2016 Mark Wielaard <mjw@redhat.com> 0.165-1
+- elfcompress: New utility to compress or decompress ELF sections.
+- readelf: Add -z,--decompress option.
+- libelf: Add elf_compress, elf_compress_gnu, elf32_getchdr,
+  elf64_getchdr and gelf_getchdr.
+- libdwelf: New function dwelf_scn_gnu_compressed_size.
+- config: Add libelf and libdw pkg-config files.
+- backends: sparc support for core and live backtraces.
+- translations: Updated Polish translation.
+
+* Thu Oct 15 2015 Mark Wielaard <mjw@redhat.com> 0.164-1
+- strip, unstrip: Handle ELF files with merged strtab/shstrtab
+  tables. Handle missing SHF_INFO_LINK section flags.
+- libelf: Use int64_t for offsets in libelf.h instead of loff_t.
+- libdw: dwarf.h Add preliminary DWARF5 DW_LANG_Haskell.
+- libdwfl: dwfl_standard_find_debuginfo now searches any subdir of
+  the binary path under the debuginfo root when the separate
+  debug file couldn't be found by build-id.
+  dwfl_linux_proc_attach can now be called before any Dwfl_Modules
+  have been reported.
+- backends: Better sparc and sparc64 support.
+- translations: Updated Ukrainian translation.
+- Provide default-yama-scope subpackage.
+
+* Fri Jun 19 2015 Mark Wielaard <mjw@redhat.com> 0.163-1
+- Bug fixes only, no new features.
+
+* Wed Jun 10 2015 Mark Wielaard <mjw@redhat.com> 0.162-1
+- libdw: Install new header elfutils/known-dwarf.h.
+  dwarf.h Add preliminary DWARF5 constants DW_TAG_atomic_type,
+  DW_LANG_Fortran03, DW_LANG_Fortran08. dwarf_peel_type now also
+  handles DW_TAG_atomic_type.
+- addr2line: Input addresses are now always interpreted as
+  hexadecimal numbers, never as octal or decimal numbers.
+  New option -a, --addresses to print address before each entry.
+  New option -C, --demangle to show demangled symbols.
+  New option --pretty-print to print all information on one line.
+- ar: CVE-2014-9447 Directory traversal vulnerability in ar
+  extraction.
+- backends: x32 support.
+
+* Thu Dec 18 2014 Mark Wielaard <mjw@redhat.com> 0.161-1
+- libdw: New function dwarf_peel_type. dwarf_aggregate_size now uses
+  dwarf_peel_type to also provide the sizes of qualified types.
+  dwarf_getmacros will now serve either of .debug_macro and
+  .debug_macinfo transparently.  New interfaces dwarf_getmacros_off,
+  dwarf_macro_getsrcfiles, dwarf_macro_getparamcnt, and
+  dwarf_macro_param are available for more generalized inspection of
+  macros and their parameters.
+  dwarf.h: Add DW_AT_GNU_deleted, DW_AT_noreturn, DW_LANG_C11,
+  DW_LANG_C_plus_plus_11 and DW_LANG_C_plus_plus_14.
+
+* Mon Aug 25 2014 Mark Wielaard <mjw@redhat.com> 0.160-1
+- libdw: New functions dwarf_cu_getdwarf, dwarf_cu_die.
+  dwarf.h remove non-existing DW_TAG_mutable_type.
+- libdwfl: Handle LZMA .ko.xz compressed kernel modules.
+- unstrip: New option -F, --force to combining files even if some ELF
+  headers don't seem to match.
+- backends: Handle ARM THUMB functions. Add support for ppc64le ELFv2 abi.
+
+* Sat May 17 2014 Mark Wielaard <mjw@redhat.com> 0.159-1
+- stack: New option -d, --debugname to lookup DWARF debuginfo name 
+  for frame.  New option -i, --inlines to show inlined frames 
+  using DWARF debuginfo.
+- libdwelf: New libdwelf.h header for libdw.so DWARF ELF Low-level 
+  Functions.  New function dwelf_elf_gnu_debuglink, 
+  dwelf_dwarf_gnu_debugaltlink, and dwelf_elf_gnu_build_id.
+- libdw: Support for DWZ multifile forms DW_FORM_GNU_ref_alt and      
+  DW_FORM_GNU_strp_alt is now enabled by default and no longer        
+  experimental. Added new functions dwarf_getalt and dwarf_setalt       
+  to get or set the alternative debug file used for the alt FORMs.     
+  The dwfl_linux_proc_find_elf callback will now find ELF from       
+  process memory for (deleted) files if the Dwfl has process state     
+  attached.
+- libdwfl: The dwfl_build_id_find_debuginfo and 
+  dwfl_standard_find_debuginfo functions will now try to 
+  resolve and set the alternative debug file.
+- backends: Add CFI unwinding for arm. Relies on .debug_frame.        
+  Add arm process initial register state compatible mode to AARCH64. 
+  Add aarch64 native and core unwind support.
+- other: All separate elfutils-robustify patches have been merged.    
+  CVE-2014-0172 Check overflow before calling malloc to uncompress 
+  data.
+
+* Fri Jan  3 2014 Mark Wielaard <mjw@redhat.com> 0.158-1
+- libdwfl: dwfl_core_file_report has new parameter executable.
+  New functions dwfl_module_getsymtab_first_global,
+  dwfl_module_getsym_info and dwfl_module_addrinfo.
+  Added unwinder with type Dwfl_Thread_Callbacks, opaque types
+  Dwfl_Thread and Dwfl_Frame and functions dwfl_attach_state,
+  dwfl_pid, dwfl_thread_dwfl, dwfl_thread_tid, dwfl_frame_thread,
+  dwfl_thread_state_registers, dwfl_thread_state_register_pc,
+  dwfl_getthread_frames, dwfl_getthreads, dwfl_thread_getframes
+  and dwfl_frame_pc.
+- addr2line: New option -x to show the section an address was found in.
+- stack: New utility that uses the new unwinder for processes and cores.
+- backends: Unwinder support for i386, x86_64, s390, s390x, ppc and ppc64.
+  aarch64 support.
+
+* Mon Sep 30 2013 Mark Wielaard <mjw@redhat.com> 0.157-1
+- libdw: Add new functions dwarf_getlocations, dwarf_getlocation_attr 
+         and dwarf_getlocation_die.
+- readelf: Show contents of NT_SIGINFO and NT_FILE core notes.
+- addr2line: Support -i, --inlines output option.
+- backends: abi_cfi hook for arm, ppc and s390.
+
+* Thu Jul 25 2013 Jan Kratochvil <jan.kratochvil@redhat.com> 0.156-1
+- lib: New macro COMPAT_VERSION_NEWPROTO.
+- libdw: Handle GNU extension opcodes in dwarf_getlocation.
+- libdwfl: Fix STB_GLOBAL over STB_WEAK preference in 
+  dwfl_module_addrsym.          Add minisymtab support.          Add 
+  parameter add_p_vaddr to dwfl_report_elf.          Use DT_DEBUG 
+  library search first.
+- libebl: Handle new core note types in EBL.
+- backends: Interpret NT_ARM_VFP.           Implement core file 
+  registers parsing for s390/s390x.
+- readelf: Add --elf-section input option to inspect an embedded ELF 
+  file.          Add -U, --unresolved-address-offsets output control.   
+         Add --debug-dump=decodedline support.          Accept version 
+  8 .gdb_index section format.          Adjust output formatting width. 
+           When highpc is in constant form print it also as address.    
+        Display raw .debug_aranges. Use libdw only for decodedaranges.
+- elflint: Add __bss_start__ to the list of allowed symbols.
+- tests: Add configure --enable-valgrind option to run all tests 
+  under valgrind.        Enable automake parallel-tests for make check.
+- translations: Updated Polish translation.
+- Updates for Automake 1.13.
+
+* Fri Aug 24 2012 Mark Wielaard <mjw@redhat.com> 0.155-1
+- libelf: elf*_xlatetomd now works for cross-endian ELF note data.    
+       elf_getshdr now works consistently on non-mmaped ELF files after 
+          calling elf_cntl(ELF_C_FDREAD).         Implement support for 
+  ar archives with 64-bit symbol table.
+- libdw: dwarf.h corrected the DW_LANG_ObjC constant name (was 
+  DW_LANG_Objc).        Any existing sources using the old name will 
+  have to be updated.        Add DW_MACRO_GNU .debug_macro type 
+  encodings constants, DW_ATE_UTF        and DW_OP_GNU_parameter_ref to 
+  dwarf.h.        Experimental support for DWZ multifile forms 
+  DW_FORM_GNU_ref_alt        and DW_FORM_GNU_strp_alt.  Disabled by 
+  default.  Use configure        --enable-dwz to test it.
+- readelf: Add .debug_macro parsing support.          Add .gdb_index 
+  version 7 parsing support.          Recognize DW_OP_GNU_parameter_ref.
+- backends: Add support for Tilera TILE-Gx processor.
+- translations: Updated Ukrainian translation.
+
+* Fri Jun 22 2012 Mark Wielaard <mjw@redhat.com> 0.154-1
+- libelf: [g]elf[32|64]_offscn() do not match SHT_NOBITS sections at 
+  OFFSET.
+- libdw: dwarf_highpc function now handles DWARF 4 DW_AT_high_pc 
+  constant form.        Fix bug using dwarf_next_unit to iterate over 
+  .debug_types.
+- elflint: Now accepts gold linker produced executables.
+- The license is now GPLv2/LGPLv3+ for the libraries and GPLv3+ for 
+  stand-alone programs. There is now also a formal CONTRIBUTING 
+  document describing how to submit patches.
+
+* Thu Feb 23 2012 Mark Wielaard <mjw@redhat.com> 0.153-1
+- libdw: Support reading .zdebug_* DWARF sections compressed via zlib.
+- libdwfl: Speed up dwfl_module_addrsym.
+- nm: Support C++ demangling.
+- ar: Support D modifier for "deterministic output" with no 
+  uid/gid/mtime info.     The U modifier is the inverse.     elfutils 
+  can be configured with the --enable-deterministic-archives     option 
+  to make the D behavior the default when U is not specified.
+- ranlib: Support -D and -U flags with same meaning.
+- readelf: Improve output of -wline. Add support for printing SDT elf 
+  notes.          Add printing of .gdb_index section. 	 Support for 
+  typed DWARF stack, call_site and entry_value.
+- strip: Add --reloc-debug-sections option.        Improved SHT_GROUP 
+  sections handling.
+
+* Tue Feb 15 2011  <drepper@gmail.com> 0.152-1
+- Various build and warning nits fixed for newest GCC and Autoconf.
+- libdwfl: Yet another prelink-related fix for another regression.
+  	 Look for Linux kernel images in files named with compression
+  suffixes.
+- elfcmp: New flag --ignore-build-id to ignore differing build ID
+  bits. 	New flag -l/--verbose to print all differences.
+
+* Wed Jan 12 2011  <drepper@gmail.com> 0.151-1
+- libdwfl: Fix for more prelink cases with separate debug file.
+- strip: New flag --strip-sections to remove section headers entirely.
+
+* Mon Nov 22 2010  <drepper@gmail.com> 0.150-1
+- libdw: Fix for handling huge .debug_aranges section.
+- libdwfl: Fix for handling prelinked DSO with separate debug file.
+- findtextrel: Fix diagnostics to work with usual section ordering.
+- libebl: i386 backend fix for multi-register integer return value
+  location.
+
+* Mon Sep 13 2010  <drepper@redhat.com> 0.149-1
+- libdw: Decode new DW_OP_GNU_implicit_pointer operation;        new
+  function dwarf_getlocation_implicit_pointer.
+- libdwfl: New function dwfl_dwarf_line.
+- addr2line: New flag -F/--flags to print more DWARF line information
+  details.
+- strip: -g recognizes .gdb_index as a debugging section.
+
+* Mon Jun 28 2010  <drepper@redhat.com> 0.148-1
+- libdw: Accept DWARF 4 format: new functions dwarf_next_unit,
+  dwarf_offdie_types.        New functions dwarf_lineisa,
+  dwarf_linediscriminator, dwarf_lineop_index.
+- libdwfl: Fixes in core-file handling, support cores from PIEs.
+  	 When working from build IDs, don't open a named file that
+  mismatches.
+- readelf: Handle DWARF 4 formats.
+
+* Mon May  3 2010 Ulrich Drepper <drepper@redhat.com> 0.147-1
+- libdw: Fixes in CFI handling, best possible handling of bogus CFA
+  ops.
+- libdwfl: Ignore R_*_NONE relocs, works around old (binutils) ld -r
+  bugs.
+
+* Wed Apr 21 2010  <drepper@redhat.com> 0.146-1
+- libdwfl: New function dwfl_core_file_report.
+
+* Tue Feb 23 2010 Ulrich Drepper <drepper@redhat.com> 0.145-1
+- Fix build with --disable-dependency-tracking.
+- Fix build with most recent glibc headers.
+- libelf: More robust to bogus section headers.
+- libdw: Fix CFI decoding.
+- libdwfl: Fix address bias returned by CFI accessors. 	 Fix core
+  file module layout identification.
+- readelf: Fix CFI decoding.
+
+* Thu Jan 14 2010  <drepper@redhat.com> 0.144-1
+- libelf: New function elf_getphdrnum. 	Now support using more than
+  65536 program headers in a file.
+- libdw: New function dwarf_aggregate_size for computing (constant)
+  type        sizes, including array_type cases with nontrivial
+  calculation.
+- readelf: Don't give errors for missing info under -a.
+  Handle Linux "VMCOREINFO" notes under -n.
+
+* Mon Sep 21 2009  <drepper@redhat.com> 0.143-1
+- libdw: Various convenience functions for individual attributes now
+  use dwarf_attr_integrate to look up indirect inherited
+  attributes.  Location expression handling now supports
+  DW_OP_implicit_value.
+- libdwfl: Support automatic decompression of files in XZ format,
+  and of Linux kernel images made with bzip2 or LZMA (as well
+  as gzip).
+
+* Mon Jun 29 2009  <drepper@redhat.com> 0.142-1
+- libelf: Add elf_getshdrnum alias for elf_getshnum and elf_getshdrstrndx alias
+  for elf_getshstrndx and deprecate original names.  Sun screwed up
+  their implementation and asked for a solution.
+- libebl: Add support for STB_GNU_UNIQUE.
+- elflint: Add support for STB_GNU_UNIQUE.
+- readelf: Add -N option, speeds up DWARF printing without address->name lookups.
+- libdw: Add support for decoding DWARF CFI into location description form.
+  Handle some new DWARF 3 expression operations previously omitted.
+  Basic handling of some new encodings slated for DWARF
+
+* Thu Apr 23 2009 Ulrich Drepper <drepper@redhat.com> 0.141-1
+- libebl: sparc backend fixes; 	some more arm backend support
+- libdwfl: fix dwfl_module_build_id for prelinked DSO case;
+  fixes in core file support; 	 dwfl_module_getsym interface
+  improved for non-address symbols
+- strip: fix infinite loop on strange inputs with -f
+- addr2line: take -j/--section=NAME option for binutils compatibility
+  	   (same effect as '(NAME)0x123' syntax already supported)
+
+* Mon Feb 16 2009 Ulrich Drepper <drepper@redhat.com> 0.140-1
+- libelf: Fix regression in creation of section header
+- libdwfl: Less strict behavior if DWARF reader ist just used to
+  display data
+
+* Thu Jan 22 2009 Ulrich Drepper <drepper@redhat.com> 0.139-1
+- libcpu: Add Intel SSE4 disassembler support
+- readelf: Implement call frame information and exception handling
+  dumping.          Add -e option.  Enable it implicitly for -a.
+- elflint: Check PT_GNU_EH_FRAME program header entry.
+- libdwfl: Support automatic gzip/bzip2 decompression of ELF files.
+
+* Wed Dec 31 2008 Roland McGrath <roland@redhat.com> 0.138-1
+- Install <elfutils/version.h> header file for applications to use in
+  source version compatibility checks.
+- libebl: backend fixes for i386 TLS relocs; backend support for
+  NT_386_IOPERM
+- libcpu: disassembler fixes
+- libdwfl: bug fixes
+- libelf: bug fixes
+- nm: bug fixes for handling corrupt input files
+
+* Tue Aug 26 2008 Ulrich Drepper <drepper@redhat.com> 0.137-1
+- Minor fixes for unreleased 0.136 release.
+
+* Mon Aug 25 2008 Ulrich Drepper <drepper@redhat.com> 0.136-1
+- libdwfl: bug fixes; new segment interfaces;	 all the libdwfl-based
+ tools now support --core=COREFILE option
+
+* Mon May 12 2008 Ulrich Drepper <drepper@redhat.com> 0.135-1
+- libdwfl: bug fixes
+- strip: changed handling of ET_REL files wrt symbol tables and relocs
+
+* Tue Apr  8 2008 Ulrich Drepper <drepper@redhat.com> 0.134-1
+- elflint: backend improvements for sparc, alpha
+- libdwfl, libelf: bug fixes
+
+* Sat Mar  1 2008 Ulrich Drepper <drepper@redhat.com> 0.133-1
+- readelf, elflint, libebl: SHT_GNU_ATTRIBUTE section handling (readelf -A)
+- readelf: core note handling for NT_386_TLS, NT_PPC_SPE, Alpha NT_AUXV
+- libdwfl: bug fixes and optimization in relocation handling
+- elfcmp: bug fix for non-allocated section handling
+- ld: implement newer features of binutils linker.
+
+* Mon Jan 21 2008 Ulrich Drepper <drepper@redhat.com> 0.132-1
+- libcpu: Implement x86 and x86-64 disassembler.
+- libasm: Add interface for disassembler.
+- all programs: add debugging of branch prediction.
+- libelf: new function elf_scnshndx.
+
+* Sun Nov 11 2007 Ulrich Drepper <drepper@redhat.com> 0.131-1
+- libdw: DW_FORM_ref_addr support; dwarf_formref entry point now depreca
+ted;       bug fixes for oddly-formatted DWARF
+- libdwfl: bug fixes in offline archive support, symbol table handling;
+	 apply partial relocations for dwfl_module_address_section on
+ET_REL
+- libebl: powerpc backend support for Altivec registers
+
+* Mon Oct 15 2007 Ulrich Drepper <drepper@redhat.com> 0.130-1
+- readelf: -p option can take an argument like -x for one section,
+	 or no argument (as before) for all SHF_STRINGS sections;
+	 new option --archive-index (or -c);	 improved -n output fo
+r core files, on many machines
+- libelf: new function elf_getdata_rawchunk, replaces gelf_rawchunk;
+	new functions gelf_getnote, gelf_getauxv, gelf_update_auxv
+- readelf, elflint: handle SHT_NOTE sections without requiring phdrs
+- elflint: stricter checks on debug sections
+- libdwfl: new functions dwfl_build_id_find_elf, dwfl_build_id_find_debu
+ginfo,	 dwfl_module_build_id, dwfl_module_report_build_id;	 suppo
+rt dynamic symbol tables found via phdrs;	 dwfl_standard_find_de
+buginfo now uses build IDs when available
+- unstrip: new option --list (or -n)
+- libebl: backend improvements for sparc, alpha, powerpc
+
+* Tue Aug 14 2007 Ulrich Drepper <drepper@redhat.com> 0.129-1
+- readelf: new options --hex-dump (or -x), --strings (or -p)
+- addr2line: new option --symbols (or -S)
+
+* Wed Apr 18 2007 Ulrich Drepper <drepper@redhat.com> 0.127-1
+- libdw: new function dwarf_getsrcdirs
+- libdwfl: new functions dwfl_module_addrsym, dwfl_report_begin_add,
+	 dwfl_module_address_section
+
+* Mon Feb  5 2007 Ulrich Drepper <drepper@redhat.com> 0.126-1
+- new program: ar
+
+* Mon Dec 18 2006 Ulrich Drepper <drepper@redhat.com> 0.125-1
+- elflint: Compare DT_GNU_HASH tests.
+- move archives into -static RPMs
+- libelf, elflint: better support for core file handling
+
+* Tue Oct 10 2006 Ulrich Drepper <drepper@redhat.com> 0.124-1
+- libebl: sparc backend support for return value location
+- libebl, libdwfl: backend register name support extended with more info
+- libelf, libdw: bug fixes for unaligned accesses on machines that care
+- readelf, elflint: trivial bugs fixed
+
+* Mon Aug 14 2006 Roland McGrath <roland@redhat.com> 0.123-1
+- libebl: Backend build fixes, thanks to Stepan Kasal.
+- libebl: ia64 backend support for register names, return value location
+- libdwfl: Handle truncated linux kernel module section names.
+- libdwfl: Look for linux kernel vmlinux files with .debug suffix.
+- elflint: Fix checks to permit --hash-style=gnu format.
+
+* Wed Jul 12 2006 Ulrich Drepper <drepper@redhat.com> 0.122-1
+- libebl: add function to test for relative relocation
+- elflint: fix and extend DT_RELCOUNT/DT_RELACOUNT checks
+- elflint, readelf: add support for DT_GNU_HASHlibelf: add elf_gnu_hash
+- elflint, readelf: add support for 64-bit SysV-style hash tables
+- libdwfl: new functions dwfl_module_getsymtab, dwfl_module_getsym.
+
+* Wed Jun 14 2006  <drepper@redhat.com> 0.121-1
+- libelf: bug fixes for rewriting existing files when using mmap.
+- make all installed headers usable in C++ code.
+- readelf: better output format.
+- elflint: fix tests of dynamic section content.
+- ld: Implement --as-needed, --execstack, PT_GNU_STACK.  Many small patc
+hes.
+- libdw, libdwfl: handle files without aranges info.
+
+* Tue Apr  4 2006 Ulrich Drepper <drepper@redhat.com> 0.120-1
+- Bug fixes.
+- dwarf.h updated for DWARF 3.0 final specification.
+- libdwfl: New function dwfl_version.
+- The license is now GPL for most files.  The libelf, libebl, libdw,and
+libdwfl libraries have additional exceptions.  Add reference toOIN.
+
+* Thu Jan 12 2006 Roland McGrath <roland@redhat.com> 0.119-1
+- elflint: more tests.
+- libdwfl: New function dwfl_module_register_names.
+- libebl: New backend hook for register names.
+
+* Tue Dec  6 2005 Ulrich Drepper <drepper@redhat.com> 0.118-1
+- elflint: more tests.
+- libdwfl: New function dwfl_module_register_names.
+- libebl: New backend hook for register names.
+
+* Thu Nov 17 2005 Ulrich Drepper <drepper@redhat.com> 0.117-1
+- libdwfl: New function dwfl_module_return_value_location.
+- libebl: Backend improvements for several CPUs.
+
+* Mon Oct 31 2005 Ulrich Drepper <drepper@redhat.com> 0.116-1
+- libdw: New functions dwarf_ranges, dwarf_entrypc, dwarf_diecu,       d
+warf_entry_breakpoints.  Removed Dwarf_Func type and functions       d
+warf_func_name, dwarf_func_lowpc, dwarf_func_highpc,       dwarf_func_
+entrypc, dwarf_func_die; dwarf_getfuncs callback now uses       Dwarf_
+Die, and dwarf_func_file, dwarf_func_line, dwarf_func_col       replac
+ed by dwarf_decl_file, dwarf_decl_line, dwarf_decl_column;       dwarf
+_func_inline, dwarf_func_inline_instances now take Dwarf_Die.       Ty
+pe Dwarf_Loc renamed to Dwarf_Op; dwarf_getloclist,       dwarf_addrlo
+clists renamed dwarf_getlocation, dwarf_getlocation_addr.
+
+* Fri Sep  2 2005 Ulrich Drepper <drepper@redhat.com> 0.115-1
+- libelf: speed-ups of non-mmap reading.
+- strings: New program.
+- Implement --enable-gcov option for configure.
+- libdw: New function dwarf_getscopes_die.
+
+* Wed Aug 24 2005 Ulrich Drepper <drepper@redhat.com> 0.114-1
+- libelf: new function elf_getaroff
+- libdw: Added dwarf_func_die, dwarf_func_inline, dwarf_func_inline_inst
+ances.
+- libdwfl: New functions dwfl_report_offline, dwfl_offline_section_addre
+ss,	 dwfl_linux_kernel_report_offline.
+- ranlib: new program
+
+* Mon Aug 15 2005 Ulrich Drepper <drepper@redhat.com> 0.114-1
+- libelf: new function elf_getaroff
+- ranlib: new program
+
+* Wed Aug 10 2005 Ulrich Drepper <@redhat.com> 0.113-1
+- elflint: relax a bit. Allow version definitions for defined symbols ag
+ainstDSO versions also for symbols in nobits sections.  Allow .rodata
+sectionto have STRINGS and MERGE flag set.
+- strip: add some more compatibility with binutils.
+
+* Sat Aug  6 2005 Ulrich Drepper <@redhat.com> 0.113-1
+- elflint: relax a bit. Allow version definitions for defined symbols ag
+ainstDSO versions also for symbols in nobits sections.  Allow .rodata
+sectionto have STRINGS and MERGE flag set.
+
+* Sat Aug  6 2005 Ulrich Drepper <@redhat.com> 0.113-1
+- elflint: relax a bit. Allow version definitions for defined symbols ag
+ainstDSO versions also for symbols in nobits sections.
+
+* Fri Aug  5 2005 Ulrich Drepper <@redhat.com> 0.112-1
+- elfcmp: some more relaxation.
+- elflint: many more tests, especially regarding to symbol versioning.
+- libelf: Add elfXX_offscn and gelf_offscn.
+- libasm: asm_begin interface changes.
+- libebl: Add three new interfaces to directly access machine, class, an
+ddata encoding information.
+- objdump: New program.  Just the beginning.
+
+* Thu Jul 28 2005 Ulrich Drepper <@redhat.com> 0.111-1
+- libdw: now contains all of libdwfl.  The latter is not installed anymore.
+- elfcmp: little usability tweak, name and index of differing section is
+ printed.
+
+* Sun Jul 24 2005 Ulrich Drepper <@redhat.com> 0.110-1
+- libelf: fix a numbe rof problems with elf_update
+- elfcmp: fix a few bugs.  Compare gaps.
+- Fix a few PLT problems and mudflap build issues.
+- libebl: Don't expose Ebl structure definition in libebl.h.  It's now p
+rivate.
+
+* Thu Jul 21 2005 Ulrich Drepper <@redhat.com> 0.109-1
+- libebl: Check for matching modules.
+- elflint: Check that copy relocations only happen for OBJECT or NOTYPE
+symbols.
+- elfcmp: New program.
+- libdwfl: New library.
+
+* Mon May  9 2005 Ulrich Drepper <@redhat.com> 0.108-1
+- strip: fix bug introduced in last change
+- libdw: records returned by dwarf_getsrclines are now sorted by address
+
+* Sun May  8 2005 Ulrich Drepper <@redhat.com> 0.108-1
+- strip: fix bug introduced in last change
+
+* Sun May  8 2005 Ulrich Drepper <@redhat.com> 0.107-1
+- readelf: improve DWARF output format
+- strip: support Linux kernel modules
+
+* Fri Apr 29 2005 Ulrich Drepper <drepper@redhat.com> 0.107-1
+- readelf: improve DWARF output format
+
+* Mon Apr  4 2005 Ulrich Drepper <drepper@redhat.com> 0.106-1
+- libdw: Updated dwarf.h from DWARF3 speclibdw: add new funtions dwarf_f
+unc_entrypc, dwarf_func_file, dwarf_func_line,dwarf_func_col, dwarf_ge
+tsrc_file
+
+* Fri Apr  1 2005 Ulrich Drepper <drepper@redhat.com> 0.105-1
+- addr2line: New program
+- libdw: add new functions: dwarf_addrdie, dwarf_macro_*, dwarf_getfuncs
+,dwarf_func_*.
+- findtextrel: use dwarf_addrdie
+
+* Mon Mar 28 2005 Ulrich Drepper <drepper@redhat.com> 0.104-1
+- findtextrel: New program.
+
+* Mon Mar 21 2005 Ulrich Drepper <drepper@redhat.com> 0.103-1
+- libdw: Fix using libdw.h with gcc < 4 and C++ code.  Compiler bug.
+
+* Tue Feb 22 2005 Ulrich Drepper <drepper@redhat.com> 0.102-1
+- More Makefile and spec file cleanups.
+
+* Fri Jan 16 2004 Jakub Jelinek <jakub@redhat.com> 0.94-1
+- upgrade to 0.94
+
+* Fri Jan 16 2004 Jakub Jelinek <jakub@redhat.com> 0.93-1
+- upgrade to 0.93
+
+* Thu Jan  8 2004 Jakub Jelinek <jakub@redhat.com> 0.92-1
+- full version
+- macroized spec file for GPL or OSL builds
+- include only libelf under GPL plus wrapper scripts
+
+* Wed Jan  7 2004 Jakub Jelinek <jakub@redhat.com> 0.91-2
+- macroized spec file for GPL or OSL builds
+
+* Wed Jan  7 2004 Ulrich Drepper <drepper@redhat.com>
+- split elfutils-devel into two packages.
+
+* Wed Jan  7 2004 Jakub Jelinek <jakub@redhat.com> 0.91-1
+- include only libelf under GPL plus wrapper scripts
+
+* Tue Dec 23 2003 Jeff Johnson <jbj@redhat.com> 0.89-3
+- readelf, not readline, in %%description (#111214).
+
+* Fri Sep 26 2003 Bill Nottingham <notting@redhat.com> 0.89-1
+- update to 0.89 (fix eu-strip)
+
+* Tue Sep 23 2003 Jakub Jelinek <jakub@redhat.com> 0.86-3
+- update to 0.86 (fix eu-strip on s390x/alpha)
+- libebl is an archive now; remove references to DSO
+
+* Mon Jul 14 2003 Jeff Johnson <jbj@redhat.com> 0.84-3
+- upgrade to 0.84 (readelf/elflint improvements, rawhide bugs fixed).
+
+* Fri Jul 11 2003 Jeff Johnson <jbj@redhat.com> 0.83-3
+- upgrade to 0.83 (fix invalid ELf handle on *.so strip, more).
+
+* Wed Jul  9 2003 Jeff Johnson <jbj@redhat.com> 0.82-3
+- upgrade to 0.82 (strip tests fixed on big-endian).
+
+* Tue Jul  8 2003 Jeff Johnson <jbj@redhat.com> 0.81-3
+- upgrade to 0.81 (strip excludes unused symtable entries, test borked).
+
+* Thu Jun 26 2003 Jeff Johnson <jbj@redhat.com> 0.80-3
+- upgrade to 0.80 (debugedit changes for kernel in progress).
+
+* Wed Jun 04 2003 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Wed May 21 2003 Jeff Johnson <jbj@redhat.com> 0.79-2
+- upgrade to 0.79 (correct formats for size_t, more of libdw "works").
+
+* Mon May 19 2003 Jeff Johnson <jbj@redhat.com> 0.78-2
+- upgrade to 0.78 (libdwarf bugfix, libdw additions).
+
+* Mon Feb 24 2003 Elliot Lee <sopwith@redhat.com>
+- debuginfo rebuild
+
+* Thu Feb 20 2003 Jeff Johnson <jbj@redhat.com> 0.76-2
+- use the correct way of identifying the section via the sh_info link.
+
+* Sat Feb 15 2003 Jakub Jelinek <jakub@redhat.com> 0.75-2
+- update to 0.75 (eu-strip -g fix)
+
+* Tue Feb 11 2003 Jakub Jelinek <jakub@redhat.com> 0.74-2
+- update to 0.74 (fix for writing with some non-dirty sections)
+
+* Thu Feb  6 2003 Jeff Johnson <jbj@redhat.com> 0.73-3
+- another -0.73 update (with sparc fixes).
+- do "make check" in %%check, not %%install, section.
+
+* Mon Jan 27 2003 Jeff Johnson <jbj@redhat.com> 0.73-2
+- update to 0.73 (with s390 fixes).
+
+* Wed Jan 22 2003 Tim Powers <timp@redhat.com>
+- rebuilt
+
+* Wed Jan 22 2003 Jakub Jelinek <jakub@redhat.com> 0.72-4
+- fix arguments to gelf_getsymshndx and elf_getshstrndx
+- fix other warnings
+- reenable checks on s390x
+
+* Sat Jan 11 2003 Karsten Hopp <karsten@redhat.de> 0.72-3
+- temporarily disable checks on s390x, until someone has
+  time to look at it
+
+* Thu Dec 12 2002 Jakub Jelinek <jakub@redhat.com> 0.72-2
+- update to 0.72
+
+* Wed Dec 11 2002 Jakub Jelinek <jakub@redhat.com> 0.71-2
+- update to 0.71
+
+* Wed Dec 11 2002 Jeff Johnson <jbj@redhat.com> 0.69-4
+- update to 0.69.
+- add "make check" and segfault avoidance patch.
+- elfutils-libelf needs to run ldconfig.
+
+* Tue Dec 10 2002 Jeff Johnson <jbj@redhat.com> 0.68-2
+- update to 0.68.
+
+* Fri Dec  6 2002 Jeff Johnson <jbj@redhat.com> 0.67-2
+- update to 0.67.
+
+* Tue Dec  3 2002 Jeff Johnson <jbj@redhat.com> 0.65-2
+- update to 0.65.
+
+* Mon Dec  2 2002 Jeff Johnson <jbj@redhat.com> 0.64-2
+- update to 0.64.
+
+* Sun Dec 1 2002 Ulrich Drepper <drepper@redhat.com> 0.64
+- split packages further into elfutils-libelf
+
+* Sat Nov 30 2002 Jeff Johnson <jbj@redhat.com> 0.63-2
+- update to 0.63.
+
+* Fri Nov 29 2002 Ulrich Drepper <drepper@redhat.com> 0.62
+- Adjust for dropping libtool
+
+* Sun Nov 24 2002 Jeff Johnson <jbj@redhat.com> 0.59-2
+- update to 0.59
+
+* Thu Nov 14 2002 Jeff Johnson <jbj@redhat.com> 0.56-2
+- update to 0.56
+
+* Thu Nov  7 2002 Jeff Johnson <jbj@redhat.com> 0.54-2
+- update to 0.54
+
+* Sun Oct 27 2002 Jeff Johnson <jbj@redhat.com> 0.53-2
+- update to 0.53
+- drop x86_64 hack, ICE fixed in gcc-3.2-11.
+
+* Sat Oct 26 2002 Jeff Johnson <jbj@redhat.com> 0.52-3
+- get beehive to punch a rhpkg generated package.
+
+* Wed Oct 23 2002 Jeff Johnson <jbj@redhat.com> 0.52-2
+- build in 8.0.1.
+- x86_64: avoid gcc-3.2 ICE on x86_64 for now.
+
+* Tue Oct 22 2002 Ulrich Drepper <drepper@redhat.com> 0.52
+- Add libelf-devel to conflicts for elfutils-devel
+
+* Mon Oct 21 2002 Ulrich Drepper <drepper@redhat.com> 0.50
+- Split into runtime and devel package
+
+* Fri Oct 18 2002 Ulrich Drepper <drepper@redhat.com> 0.49
+- integrate into official sources
+
+* Wed Oct 16 2002 Jeff Johnson <jbj@redhat.com> 0.46-1
+- Swaddle.
diff --git a/third_party/elfutils/config/eu.am b/third_party/elfutils/config/eu.am
new file mode 100644
index 0000000..c2cc349
--- /dev/null
+++ b/third_party/elfutils/config/eu.am
@@ -0,0 +1,113 @@
+## Common automake fragments for elfutils subdirectory makefiles.
+##
+## Copyright (C) 2010, 2014, 2016 Red Hat, Inc.
+##
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * 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
+##
+## or both in parallel, as here.
+##
+## elfutils 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.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+##
+
+DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DLOCALEDIR='"${localedir}"'
+AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_srcdir)/lib -I..
+
+# Drop the 'u' flag that automake adds by default. It is incompatible
+# with deterministic archives.
+ARFLAGS = cr
+
+# Warn about stack usage of more than 256K = 262144 bytes.
+if ADD_STACK_USAGE_WARNING
+STACK_USAGE_WARNING=-Wstack-usage=262144
+else
+STACK_USAGE_WARNING=
+endif
+
+if SANE_LOGICAL_OP_WARNING
+LOGICAL_OP_WARNING=-Wlogical-op
+else
+LOGICAL_OP_WARNING=
+endif
+
+if HAVE_DUPLICATED_COND_WARNING
+DUPLICATED_COND_WARNING=-Wduplicated-cond
+else
+DUPLICATED_COND_WARNING=
+endif
+
+if HAVE_NULL_DEREFERENCE_WARNING
+NULL_DEREFERENCE_WARNING=-Wnull-dereference
+else
+NULL_DEREFERENCE_WARNING=
+endif
+
+if HAVE_IMPLICIT_FALLTHROUGH_WARNING
+# Use strict fallthrough. Only __attribute__((fallthrough)) will prevent the
+# warning
+IMPLICIT_FALLTHROUGH_WARNING=-Wimplicit-fallthrough=5
+else
+IMPLICIT_FALLTHROUGH_WARNING=
+endif
+
+AM_CFLAGS = -std=gnu99 -Wall -Wshadow -Wformat=2 \
+	    -Wold-style-definition -Wstrict-prototypes \
+	    $(LOGICAL_OP_WARNING) $(DUPLICATED_COND_WARNING) \
+	    $(NULL_DEREFERENCE_WARNING) $(IMPLICIT_FALLTHROUGH_WARNING) \
+	    $(if $($(*F)_no_Werror),,-Werror) \
+	    $(if $($(*F)_no_Wunused),,-Wunused -Wextra) \
+	    $(if $($(*F)_no_Wstack_usage),,$(STACK_USAGE_WARNING)) \
+	    $(if $($(*F)_no_Wpacked_not_aligned),-Wno-packed-not-aligned,) \
+	    $($(*F)_CFLAGS)
+
+COMPILE.os = $(filter-out -fprofile-arcs -ftest-coverage, $(COMPILE))
+
+DEFS.os = -DPIC -DSHARED
+if SYMBOL_VERSIONING
+DEFS.os += -DSYMBOL_VERSIONING
+else
+endif
+
+%.os: %.c %.o
+if AMDEP
+	$(AM_V_CC)if $(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) -MT $@ -MD -MP \
+	  -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
+	then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
+	     rm -f "$(DEPDIR)/$*.Tpo"; \
+	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+	fi
+else
+	$(AM_V_CC)$(COMPILE.os) -c -o $@ $(fpic_CFLAGS) $(DEFS.os) $<
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+textrel_msg = echo "WARNING: TEXTREL found in '$@'"
+if FATAL_TEXTREL
+textrel_found = $(textrel_msg); exit 1
+else
+textrel_found = $(textrel_msg)
+endif
+textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi
+
+print-%:
+	@echo $*=$($*)
diff --git a/third_party/elfutils/config/known-dwarf.awk b/third_party/elfutils/config/known-dwarf.awk
new file mode 100755
index 0000000..bc9b02d
--- /dev/null
+++ b/third_party/elfutils/config/known-dwarf.awk
@@ -0,0 +1,56 @@
+#!/bin/gawk -f
+
+## Copyright (C) 2012, 2015 Red Hat, Inc.
+##
+## This file is part of elfutils.
+##
+## This file 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 3 of the License, or
+## (at your option) any later version.
+##
+## elfutils 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.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+$1 == "enum" { set = ""; next }
+
+set == "" && $1 ~ /DW_([A-Z_]+)_([^ ]+)/ {
+  set = $1;
+  sub(/^DW_/, "", set);
+  sub(/_[^[:upper:]_].*$/, "", set);
+  if (set ~ /LANG_.+/) set = "LANG";
+}
+
+$1 ~ /DW([_A-Z]+)_([^ ]+)/ {
+  match($1, ("DW_" set "_([^ ]+)"), fields);
+  elt = fields[1];
+  if (set in DW)
+    DW[set] = DW[set] "," elt;
+  else
+    DW[set] = elt;
+}
+
+END {
+  print "/* Generated by config/known-dwarf.awk from libdw/dwarf.h contents.  */";
+  n = asorti(DW, sets);
+  for (i = 1; i <= n; ++i) {
+    set = sets[i];
+    if (what && what != set) continue;
+    split(DW[set], elts, ",");
+    m = asort(elts);
+    if (m == 0) continue;
+    print "\n#define DWARF_ALL_KNOWN_DW_" set " \\";
+    for (j = 1; j <= m; ++j) {
+      elt = elts[j];
+      if (elt ~ /(low?|hi|high)_user$/)
+	continue;
+      print "  DWARF_ONE_KNOWN_DW_" set " (" elt ", DW_" set "_" elt ") \\";
+    }
+    print "  /* End of DW_" set "_*.  */";
+  }
+}
diff --git a/third_party/elfutils/config/libdw.pc.in b/third_party/elfutils/config/libdw.pc.in
new file mode 100644
index 0000000..3fc283d
--- /dev/null
+++ b/third_party/elfutils/config/libdw.pc.in
@@ -0,0 +1,22 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libdw
+Description: elfutils library for DWARF data and ELF file or process inspection
+Version: @VERSION@
+URL: http://elfutils.org/
+
+Libs: -L${libdir} -ldw
+Cflags: -I${includedir}
+
+# We need the exact matching elfutils libelf version since internal data
+# structures are used.
+Requires: libelf = @VERSION@
+
+# We support various compressed ELF images, but don't export any of the
+# data structures or functions.  zlib (gz) is always required, bzip2 (bz2)
+# and lzma (xz) are optional.  But bzip2 doesn't have a pkg-config file.
+Requires.private: zlib @LIBLZMA@
+Libs.private: @BZ2_LIB@
diff --git a/third_party/elfutils/config/libelf.pc.in b/third_party/elfutils/config/libelf.pc.in
new file mode 100644
index 0000000..48f3f02
--- /dev/null
+++ b/third_party/elfutils/config/libelf.pc.in
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libelf
+Description: elfutils libelf library to read and write ELF files
+Version: @VERSION@
+URL: http://elfutils.org/
+
+Libs: -L${libdir} -lelf
+Cflags: -I${includedir}
+
+Requires.private: zlib
diff --git a/third_party/elfutils/config/version.h.in b/third_party/elfutils/config/version.h.in
new file mode 100644
index 0000000..34e62c3
--- /dev/null
+++ b/third_party/elfutils/config/version.h.in
@@ -0,0 +1,38 @@
+/* Version information about elfutils development libraries.
+   Copyright (C) 2008 Red Hat, Inc.
+
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ELFUTILS_VERSION_H
+#define _ELFUTILS_VERSION_H	1
+
+#define _ELFUTILS_VERSION	@eu_version@
+
+#define _ELFUTILS_PREREQ(major, minor) \
+  (_ELFUTILS_VERSION >= ((major) * 1000 + (minor)))
+
+#endif	/* elfutils/version.h */
diff --git a/third_party/elfutils/configure.ac b/third_party/elfutils/configure.ac
new file mode 100644
index 0000000..4cdb12a
--- /dev/null
+++ b/third_party/elfutils/configure.ac
@@ -0,0 +1,669 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl Configure input file for elfutils.                     -*-autoconf-*-
+dnl
+dnl Copyright (C) 1996-2017 Red Hat, Inc.
+dnl
+dnl This file is part of elfutils.
+dnl
+dnl  This file is free software; you can redistribute it and/or modify
+dnl  it under the terms of the GNU General Public License as published by
+dnl  the Free Software Foundation; either version 3 of the License, or
+dnl  (at your option) any later version.
+dnl
+dnl  elfutils is distributed in the hope that it will be useful, but
+dnl  WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl  GNU General Public License for more details.
+dnl
+dnl  You should have received a copy of the GNU General Public License
+dnl  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+AC_INIT([elfutils],[0.170],[https://sourceware.org/bugzilla],[elfutils],[http://elfutils.org/])
+
+dnl Workaround for older autoconf < 2.64
+m4_ifndef([AC_PACKAGE_URL],
+         [AC_DEFINE([PACKAGE_URL], ["http://elfutils.org/"],
+                    [Define to home page for this package])
+          AC_SUBST([PACKAGE_URL], ["http://elfutils.org/"])])
+
+# We want eu- as default program prefix if none was given by the user.
+# But if the user explicitly provided --program-prefix="" then pretend
+# it wasn't set at all (NONE). We want to test this really early before
+# configure has a chance to use the value.
+
+if test "x$program_prefix" = "xNONE"; then
+  AC_MSG_NOTICE([No --program-prefix given, using "eu-"])
+  program_prefix="eu-"
+elif test "x$program_prefix" = "x"; then
+  AC_MSG_NOTICE([Using no program-prefix])
+  program_prefix=NONE
+fi
+
+AC_CONFIG_AUX_DIR([config])
+AC_CONFIG_FILES([config/Makefile])
+
+AC_COPYRIGHT([Copyright (C) 1996-2017 The elfutils developers.])
+AC_PREREQ(2.63)			dnl Minimum Autoconf version required.
+
+dnl We use GNU make extensions; automake 1.10 defaults to -Wportability.
+AM_INIT_AUTOMAKE([gnits 1.11 -Wno-portability dist-bzip2 no-dist-gzip parallel-tests])
+AM_MAINTAINER_MODE
+
+AM_SILENT_RULES([yes])
+
+AC_CONFIG_SRCDIR([libelf/libelf.h])
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_HEADERS([config.h])
+
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_FILES([m4/Makefile])
+
+dnl The RPM spec file.  We substitute a few values in the file.
+AC_CONFIG_FILES([elfutils.spec:config/elfutils.spec.in])
+
+
+AC_CANONICAL_HOST
+
+AC_ARG_ENABLE(deterministic-archives,
+[AS_HELP_STRING([--enable-deterministic-archives],
+		[ar and ranlib default to -D behavior])], [
+if test "${enableval}" = no; then
+  default_ar_deterministic=false
+else
+  default_ar_deterministic=true
+fi], [default_ar_deterministic=false])
+AC_DEFINE_UNQUOTED(DEFAULT_AR_DETERMINISTIC, $default_ar_deterministic,
+		   [Should ar and ranlib use -D behavior by default?])
+
+AC_ARG_ENABLE([thread-safety],
+AS_HELP_STRING([--enable-thread-safety],
+               [enable thread safety of libraries EXPERIMENTAL]),
+               use_locks=$enableval, use_locks=no)
+AM_CONDITIONAL(USE_LOCKS, test "$use_locks" = yes)
+AS_IF([test "$use_locks" = yes], [AC_DEFINE(USE_LOCKS)])
+AS_IF([test "$use_locks" = yes],
+      [AC_MSG_WARN([thread-safety is EXPERIMENTAL tests might fail.])])
+
+AH_TEMPLATE([USE_LOCKS], [Defined if libraries should be thread-safe.])
+
+AC_PROG_CC
+AC_PROG_RANLIB
+AC_PROG_YACC
+AM_PROG_LEX
+# Only available since automake 1.12
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+AC_CHECK_TOOL([READELF], [readelf])
+AC_CHECK_TOOL([NM], [nm])
+
+# We use -std=gnu99 but have explicit checks for some language constructs
+# and GNU extensions since some compilers claim GNU99 support, but don't
+# really support all language extensions. In particular we need
+# Mixed Declarations and Code
+# https://gcc.gnu.org/onlinedocs/gcc/Mixed-Declarations.html
+# Nested Functions
+# https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html
+# Arrays of Variable Length
+# https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
+AC_CACHE_CHECK([for gcc with GNU99 support], ac_cv_c99, [dnl
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -std=gnu99"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+int foo (int a)
+{
+  for (int i = 0; i < a; ++i) if (i % 4) break; int s = a; return s;
+}
+
+double bar (double a, double b)
+{
+  double square (double z) { return z * z; }
+  return square (a) + square (b);
+}
+
+void baz (int n)
+{
+  struct S { int x[[n]]; };
+}])],
+		  ac_cv_c99=yes, ac_cv_c99=no)
+CFLAGS="$old_CFLAGS"])
+AS_IF([test "x$ac_cv_c99" != xyes],
+      AC_MSG_ERROR([gcc with GNU99 support required]))
+
+AC_CACHE_CHECK([whether gcc supports __attribute__((visibility()))],
+	ac_cv_visibility, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+int __attribute__((visibility("hidden")))
+foo (int a)
+{
+  return a;
+}])], ac_cv_visibility=yes, ac_cv_visibility=no)
+CFLAGS="$save_CFLAGS"])
+if test "$ac_cv_visibility" = "yes"; then
+	AC_DEFINE([HAVE_VISIBILITY], [1],
+		  [Defined if __attribute__((visibility())) is supported])
+fi
+
+AC_CACHE_CHECK([whether gcc supports __attribute__((gcc_struct))],
+	ac_cv_gcc_struct, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+struct test { int x; } __attribute__((gcc_struct));
+])], ac_cv_gcc_struct=yes, ac_cv_gcc_struct=no)
+CFLAGS="$save_CFLAGS"])
+if test "$ac_cv_gcc_struct" = "yes"; then
+	AC_DEFINE([HAVE_GCC_STRUCT], [1],
+		  [Defined if __attribute__((gcc_struct)) is supported])
+fi
+
+AC_CACHE_CHECK([whether gcc supports -fPIC], ac_cv_fpic, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -fPIC -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE()], ac_cv_fpic=yes, ac_cv_fpic=no)
+CFLAGS="$save_CFLAGS"
+])
+if test "$ac_cv_fpic" = "yes"; then
+	fpic_CFLAGS="-fPIC"
+else
+	fpic_CFLAGS=""
+fi
+AC_SUBST([fpic_CFLAGS])
+
+AC_CACHE_CHECK([whether gcc supports -fPIE], ac_cv_fpie, [dnl
+save_CFLAGS="$CFLAGS"
+CFLAGS="$save_CFLAGS -fPIE -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE()], ac_cv_fpie=yes, ac_cv_fpie=no)
+CFLAGS="$save_CFLAGS"
+])
+if test "$ac_cv_fpie" = "yes"; then
+	fpie_CFLAGS="-fPIE"
+else
+	fpie_CFLAGS=""
+fi
+AC_SUBST([fpie_CFLAGS])
+
+dso_LDFLAGS="-shared"
+
+ZDEFS_LDFLAGS="-Wl,-z,defs"
+AC_CACHE_CHECK([whether gcc supports $ZDEFS_LDFLAGS], ac_cv_zdefs, [dnl
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$ZDEFS_LDFLAGS $save_LDFLAGS"
+AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_zdefs=yes, ac_cv_zdefs=no)
+LDFLAGS="$save_LDFLAGS"
+])
+if test "$ac_cv_zdefs" = "yes"; then
+	dso_LDFLAGS="$dso_LDFLAGS $ZDEFS_LDFLAGS"
+fi
+
+ZRELRO_LDFLAGS="-Wl,-z,relro"
+AC_CACHE_CHECK([whether gcc supports $ZRELRO_LDFLAGS], ac_cv_zrelro, [dnl
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$ZRELRO_LDFLAGS $save_LDFLAGS"
+AC_LINK_IFELSE([AC_LANG_PROGRAM()], ac_cv_zrelro=yes, ac_cv_zrelro=no)
+LDFLAGS="$save_LDFLAGS"
+])
+if test "$ac_cv_zrelro" = "yes"; then
+	dso_LDFLAGS="$dso_LDFLAGS $ZRELRO_LDFLAGS"
+fi
+
+AC_SUBST([dso_LDFLAGS])
+
+AC_CACHE_CHECK([for __thread support], ac_cv_tls, [dnl
+# Use the same flags that we use for our DSOs, so the test is representative.
+# Some old compiler/linker/libc combinations fail some ways and not others.
+save_CFLAGS="$CFLAGS"
+save_LDFLAGS="$LDFLAGS"
+CFLAGS="$fpic_CFLAGS $CFLAGS"
+LDFLAGS="$dso_LDFLAGS $LDFLAGS"
+AC_LINK_IFELSE([dnl
+AC_LANG_PROGRAM([[#include <stdlib.h>
+#undef __thread
+static __thread int a; int foo (int b) { return a + b; }]],
+		[[exit (foo (0));]])],
+	       ac_cv_tls=yes, ac_cv_tls=no)
+CFLAGS="$save_CFLAGS"
+LDFLAGS="$save_LDFLAGS"])
+AS_IF([test "x$ac_cv_tls" != xyes],
+      AC_MSG_ERROR([__thread support required]))
+
+dnl This test must come as early as possible after the compiler configuration
+dnl tests, because the choice of the file model can (in principle) affect
+dnl whether functions and headers are available, whether they work, etc.
+AC_SYS_LARGEFILE
+
+dnl Older glibc had a broken fts that didn't work with Large File Systems.
+dnl We want the version that can handler LFS, but include workaround if we
+dnl get a bad one. Add define to CFLAGS (not AC_DEFINE it) since we need to
+dnl check it before including config.h (which might define _FILE_OFFSET_BITS).
+AC_CACHE_CHECK([whether fts.h is bad when included (with LFS)], ac_cv_bad_fts,
+  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <fts.h>]])],
+		     ac_cv_bad_fts=no, ac_cv_bad_fts=yes)])
+AS_IF([test "x$ac_cv_bad_fts" = "xyes"], [CFLAGS="$CFLAGS -DBAD_FTS=1"])
+
+# See if we can add -D_FORTIFY_SOURCE=2. Don't do it if it is already
+# (differently) defined or if it generates warnings/errors because we
+# don't use the right optimisation level (string.h will warn about that).
+AC_MSG_CHECKING([whether to add -D_FORTIFY_SOURCE=2 to CFLAGS])
+case "$CFLAGS" in
+  *-D_FORTIFY_SOURCE=2*)
+    AC_MSG_RESULT([no, already there])
+    ;;
+  *)
+    save_CFLAGS="$CFLAGS"
+    CFLAGS="-D_FORTIFY_SOURCE=2 -Werror $CFLAGS"
+    AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+      #include <string.h>
+      int main() { return 0; }
+    ]])], [ AC_MSG_RESULT([yes])
+            CFLAGS="-D_FORTIFY_SOURCE=2 $save_CFLAGS" ],
+          [ AC_MSG_RESULT([no])
+            CFLAGS="$save_CFLAGS"])
+  ;;
+esac
+
+dnl enable debugging of branch prediction.
+AC_ARG_ENABLE([debugpred],
+AS_HELP_STRING([--enable-debugpred],[build binaries with support to debug branch prediction]),
+[use_debugpred=$enableval], [use_debugpred=no])
+case $use_debugpred in
+ yes) use_debugpred_val=1 ;;
+ *)   use_debugpred_val=0 ;;
+esac
+AC_SUBST([DEBUGPRED], $use_debugpred_val)
+
+dnl Enable gprof suport.
+AC_ARG_ENABLE([gprof],
+AS_HELP_STRING([--enable-gprof],[build binaries with gprof support]), [use_gprof=$enableval], [use_gprof=no])
+if test "$use_gprof" = yes; then
+  CFLAGS="$CFLAGS -pg"
+  LDFLAGS="$LDFLAGS -pg"
+fi
+AM_CONDITIONAL(GPROF, test "$use_gprof" = yes)
+
+# Enable gcov suport.
+AC_ARG_ENABLE([gcov],
+AS_HELP_STRING([--enable-gcov],[build binaries with gcov support]), [use_gcov=$enableval], [use_gcov=no])
+if test "$use_gcov" = yes; then
+  CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage"
+  LDFLAGS="$LDFLAGS -fprofile-arcs"
+fi
+AM_CONDITIONAL(GCOV, test "$use_gcov" = yes)
+
+AC_ARG_ENABLE([sanitize-undefined],
+              AS_HELP_STRING([--enable-sanitize-undefined],
+                             [Use gcc undefined behaviour sanitizer]),
+                             [use_undefined=$enableval], [use_undefined=no])
+if test "$use_undefined" = yes; then
+  old_CFLAGS="$CFLAGS"
+  old_CXXFLAGS="$CXXFLAGS"
+  # We explicitly use unaligned access when possible (see ALLOW_UNALIGNED)
+  # We want to fail immediately on first error, don't try to recover.
+  CFLAGS="$CFLAGS -fsanitize=undefined -fno-sanitize-recover"
+  CXXFLAGS="$CXXFLAGS -fsanitize=undefined -fno-sanitize-recover"
+  AC_LINK_IFELSE([AC_LANG_SOURCE([int main (int argc, char **argv) { return 0; }])], use_undefined=yes, use_undefined=no)
+  AS_IF([test "x$use_undefined" != xyes],
+        AC_MSG_WARN([gcc undefined behaviour sanitizer not available])
+        CFLAGS="$old_CFLAGS" CXXFLAGS="$old_CXXFLAGS")
+fi
+case $use_undefined in
+ yes) check_undefined_val=1 ;;
+ *)   check_undefined_val=0 ;;
+esac
+AC_DEFINE_UNQUOTED(CHECK_UNDEFINED, $check_undefined_val,
+		   [Building with -fsanitize=undefined or not])
+
+AC_ARG_ENABLE([valgrind],
+AS_HELP_STRING([--enable-valgrind],[run all tests under valgrind]),
+[use_valgrind=$enableval], [use_valgrind=no])
+if test "$use_valgrind" = yes; then
+  AC_CHECK_PROG(HAVE_VALGRIND, valgrind, yes, no)
+  if test "$HAVE_VALGRIND" = "no"; then
+    AC_MSG_ERROR([valgrind not found])
+  fi
+fi
+AM_CONDITIONAL(USE_VALGRIND, test "$use_valgrind" = yes)
+
+AM_CONDITIONAL(BUILD_STATIC, [dnl
+test "$use_gprof" = yes -o "$use_gcov" = yes])
+
+AC_ARG_ENABLE([tests-rpath],
+AS_HELP_STRING([--enable-tests-rpath],[build $ORIGIN-using rpath into tests]),
+	       [tests_use_rpath=$enableval], [tests_use_rpath=no])
+AM_CONDITIONAL(TESTS_RPATH, test "$tests_use_rpath" = yes)
+
+LIBEBL_SUBDIR="$PACKAGE"
+AC_ARG_ENABLE([libebl-subdir],
+AS_HELP_STRING([--enable-libebl-subdir=DIR],
+[install libebl_CPU modules in $(libdir)/DIR]), [dnl
+LIBEBL_SUBDIR="$enable_libebl_subdir"])
+AC_SUBST([LIBEBL_SUBDIR])
+AC_DEFINE_UNQUOTED(LIBEBL_SUBDIR, "$LIBEBL_SUBDIR")
+AH_TEMPLATE([LIBEBL_SUBDIR], [$libdir subdirectory containing libebl modules.])
+
+dnl zlib is mandatory.
+save_LIBS="$LIBS"
+LIBS=
+eu_ZIPLIB(zlib,ZLIB,z,gzdirect,gzip)
+AS_IF([test "x$with_zlib" = xno], [AC_MSG_ERROR([zlib not found but is required])])
+LIBS="$save_LIBS"
+
+dnl Test for bzlib and xz/lzma, gives BZLIB/LZMALIB .am
+dnl conditional and config.h USE_BZLIB/USE_LZMALIB #define.
+save_LIBS="$LIBS"
+LIBS=
+eu_ZIPLIB(bzlib,BZLIB,bz2,BZ2_bzdopen,bzip2)
+# We need this since bzip2 doesn't have a pkgconfig file.
+BZ2_LIB="$LIBS"
+AC_SUBST([BZ2_LIB])
+eu_ZIPLIB(lzma,LZMA,lzma,lzma_auto_decoder,[LZMA (xz)])
+AS_IF([test "x$with_lzma" = xyes], [LIBLZMA="liblzma"], [LIBLZMA=""])
+AC_SUBST([LIBLZMA])
+zip_LIBS="$LIBS"
+LIBS="$save_LIBS"
+AC_SUBST([zip_LIBS])
+
+AC_CHECK_DECLS([memrchr, rawmemchr],[],[],
+               [#define _GNU_SOURCE
+                #include <string.h>])
+AC_CHECK_DECLS([powerof2],[],[],[#include <sys/param.h>])
+AC_CHECK_DECLS([mempcpy],[],[],
+               [#define _GNU_SOURCE
+                #include <string.h>])
+
+AC_CHECK_LIB([stdc++], [__cxa_demangle], [dnl
+AC_DEFINE([USE_DEMANGLE], [1], [Defined if demangling is enabled])])
+AM_CONDITIONAL(DEMANGLE, test "x$ac_cv_lib_stdcpp___cxa_demangle" = "xyes")
+AS_IF([test "x$ac_cv_lib_stdcpp___cxa_demangle" = "xyes"],
+      [enable_demangler=yes],[enable_demangler=no])
+
+AC_ARG_ENABLE([textrelcheck],
+AS_HELP_STRING([--disable-textrelcheck],
+               [Disable textrelcheck being a fatal error]))
+AM_CONDITIONAL(FATAL_TEXTREL, [test "x$enable_textrelcheck" != "xno"])
+AS_IF([test "x$enable_textrelcheck" != "xno"],
+      [enable_textrelcheck=yes],[enable_textrelcheck=no])
+
+AC_ARG_ENABLE([symbol-versioning],
+AS_HELP_STRING([--disable-symbol-versioning],
+               [Disable symbol versioning in shared objects]))
+
+AC_CACHE_CHECK([whether symbol versioning is supported], ac_cv_symbol_versioning, [dnl
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([dnl
+#define NEW_VERSION(name, version) \
+  asm (".symver " #name "," #name "@@@" #version);
+int foo(int x) { return x + 1; }
+NEW_VERSION (foo, ELFUTILS_12.12)
+])], ac_cv_symbol_versioning=yes, ac_cv_symbol_versioning=no)])
+if test "$ac_cv_symbol_versioning" = "no"; then
+    if test "x$enable_symbol_versioning" != "xno"; then
+        AC_MSG_ERROR([Symbol versioning is not supported.
+                      Use --disable-symbol-versioning to build without.])
+    fi
+fi
+
+AM_CONDITIONAL(SYMBOL_VERSIONING, [test "x$enable_symbol_versioning" != "xno"])
+AS_IF([test "x$enable_symbol_versioning" = "xno"],
+      [AC_MSG_WARN([Disabling symbol versioning breaks ABI compatibility.])
+       enable_symbol_versioning=no],[enable_symbol_versioning=yes])
+
+AC_CACHE_CHECK([whether gcc accepts -Wstack-usage], ac_cv_stack_usage, [dnl
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Wstack-usage=262144 -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],
+		  ac_cv_stack_usage=yes, ac_cv_stack_usage=no)
+CFLAGS="$old_CFLAGS"])
+AM_CONDITIONAL(ADD_STACK_USAGE_WARNING, [test "x$ac_cv_stack_usage" != "xno"])
+
+# -Wlogical-op was too fragile in the past, make sure we get a sane one.
+AC_CACHE_CHECK([whether gcc has a sane -Wlogical-op], ac_cv_logical_op, [dnl
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Wlogical-op -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+	[#define FLAG 1
+	int f (int r, int f) { return (r && (FLAG || (FLAG & f))); }])],
+		  ac_cv_logical_op=yes, ac_cv_logical_op=no)
+CFLAGS="$old_CFLAGS"])
+AM_CONDITIONAL(SANE_LOGICAL_OP_WARNING,
+	       [test "x$ac_cv_logical_op" != "xno"])
+
+# -Wduplicated-cond was added by GCC6
+AC_CACHE_CHECK([whether gcc accepts -Wduplicated-cond], ac_cv_duplicated_cond, [dnl
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Wduplicated-cond -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],
+		  ac_cv_duplicated_cond=yes, ac_cv_duplicated_cond=no)
+CFLAGS="$old_CFLAGS"])
+AM_CONDITIONAL(HAVE_DUPLICATED_COND_WARNING,
+	       [test "x$ac_cv_duplicated_cond" != "xno"])
+
+# -Wnull-dereference was added by GCC6
+AC_CACHE_CHECK([whether gcc accepts -Wnull-dereference], ac_cv_null_dereference, [dnl
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Wnull-dereference -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],
+		  ac_cv_null_dereference=yes, ac_cv_null_dereference=no)
+CFLAGS="$old_CFLAGS"])
+AM_CONDITIONAL(HAVE_NULL_DEREFERENCE_WARNING,
+	       [test "x$ac_cv_null_dereference" != "xno"])
+
+# -Wimplicit-fallthrough was added by GCC7
+AC_CACHE_CHECK([whether gcc accepts -Wimplicit-fallthrough], ac_cv_implicit_fallthrough, [dnl
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Wimplicit-fallthrough -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([])],
+		  ac_cv_implicit_fallthrough=yes, ac_cv_implicit_fallthrough=no)
+CFLAGS="$old_CFLAGS"])
+AM_CONDITIONAL(HAVE_IMPLICIT_FALLTHROUGH_WARNING,
+	       [test "x$ac_cv_implicit_fallthrough" != "xno"])
+
+# Assume the fallthrough attribute is supported if -Wimplict-fallthrough is supported
+if test "$ac_cv_implicit_fallthrough" = "yes"; then
+	AC_DEFINE([HAVE_FALLTHROUGH], [1],
+		  [Defined if __attribute__((fallthrough)) is supported])
+fi
+
+dnl Check if we have argp available from our libc
+AC_LINK_IFELSE(
+	[AC_LANG_PROGRAM(
+		[#include <argp.h>],
+		[int argc=1; char *argv[]={"test"}; argp_parse(0,argc,&argv,0,0,0); return 0;]
+		)],
+	[libc_has_argp="true"],
+	[libc_has_argp="false"]
+)
+
+dnl If our libc doesn't provide argp, then test for libargp
+if test "$libc_has_argp" = "false" ; then
+	AC_MSG_WARN("libc does not have argp")
+	AC_CHECK_LIB([argp], [argp_parse], [have_argp="true"], [have_argp="false"])
+
+	if test "$have_argp" = "false"; then
+		AC_MSG_ERROR("no libargp found")
+	else
+		argp_LDADD="-largp"
+	fi
+else
+	argp_LDADD=""
+fi
+AC_SUBST([argp_LDADD])
+
+dnl The directories with content.
+
+dnl Documentation.
+dnl Commented out for now.
+dnl AC_CONFIG_FILES([doc/Makefile])
+
+dnl Support library.
+AC_CONFIG_FILES([lib/Makefile])
+
+dnl ELF library.
+AC_CONFIG_FILES([libelf/Makefile])
+
+dnl Higher-level ELF support library.
+AC_CONFIG_FILES([libebl/Makefile])
+
+dnl DWARF-ELF Lower-level Functions support library.
+AC_CONFIG_FILES([libdwelf/Makefile])
+
+dnl DWARF library.
+AC_CONFIG_FILES([libdw/Makefile])
+
+dnl Higher-level DWARF support library.
+AC_CONFIG_FILES([libdwfl/Makefile])
+
+dnl CPU handling library.
+AC_CONFIG_FILES([libcpu/Makefile])
+
+dnl Assembler library.
+AM_CONDITIONAL(HAVE_LIBASM, true)dnl Used in tests/Makefile.am, which see.
+AC_CONFIG_FILES([libasm/Makefile])
+
+dnl CPU-specific backend libraries.
+AC_CONFIG_FILES([backends/Makefile])
+
+dnl Tools.
+AC_CONFIG_FILES([src/Makefile po/Makefile.in])
+
+dnl Test suite.
+AM_CONDITIONAL(STANDALONE, false)dnl Used in tests/Makefile.am, which see.
+AC_CONFIG_FILES([tests/Makefile])
+
+dnl pkgconfig files
+AC_CONFIG_FILES([config/libelf.pc config/libdw.pc])
+
+# Get the definitions necessary to create the Makefiles in the po
+# subdirectories.  This is a small subset of the gettext rules.
+AC_SUBST(USE_NLS, yes)
+AM_PO_SUBDIRS
+
+dnl Appended to the config.h file.
+dnl We hide all kinds of configuration magic in lib/eu-config.h.
+AH_BOTTOM([#include <eu-config.h>])
+
+dnl Version compatibility header.
+AC_CONFIG_FILES([version.h:config/version.h.in])
+AC_SUBST([eu_version])
+
+# 1.234<whatever> -> 1234<whatever>
+case "$PACKAGE_VERSION" in
+[[0-9]].*) eu_version=`echo "$PACKAGE_VERSION" | sed 's@\.@@'` ;;
+*)     	   AC_MSG_ERROR([confused by version number '$PACKAGE_VERSION']) ;;
+esac
+case "$eu_version" in
+*.*)
+  # 1234.567 -> "1234", "567"
+  eu_extra_version="${eu_version#*.}"
+  eu_version="${eu_version%%.*}"
+  case "$eu_extra_version" in
+  [[0-9]][[0-9]][[0-9]]) ;;
+  [[0-9]][[0-9]])	eu_extra_version="${eu_extra_version}0" ;;
+  [[0-9]])	   	eu_extra_version="${eu_extra_version}00" ;;
+  *) AC_MSG_ERROR([confused by version number '$PACKAGE_VERSION']) ;;
+  esac
+  ;;
+*)
+  eu_extra_version=000
+  ;;
+esac
+
+case "$eu_version" in
+      0[[0-9]][[0-9]][[0-9]]) eu_version="${eu_version#0}$eu_extra_version" ;;
+[[0-9]][[0-9]][[0-9]][[0-9]]) eu_version="${eu_version}$eu_extra_version" ;;
+[[0-9]][[0-9]][[0-9]])	      eu_version="${eu_version}0$eu_extra_version" ;;
+[[0-9]][[0-9]])	  	      eu_version="${eu_version}00$eu_extra_version";;
+*) AC_MSG_ERROR([confused by version number '$PACKAGE_VERSION']) ;;
+esac
+
+# Round up to the next release API (x.y) version.
+eu_version=$(( (eu_version + 999) / 1000 ))
+
+dnl Unique ID for this build.
+MODVERSION="Build for ${LIBEBL_SUBDIR} ${eu_version} ${ac_cv_build}"
+AC_SUBST([MODVERSION])
+AC_DEFINE_UNQUOTED(MODVERSION, "$MODVERSION")
+AH_TEMPLATE([MODVERSION], [Identifier for modules in the build.])
+
+AC_CHECK_SIZEOF(long)
+
+# On aarch64 before glibc 2.20 we would get the kernel user_pt_regs instead
+# of the user_regs_struct from sys/user.h. They are structurally the same
+# but we get either one or the other.
+AC_CHECK_TYPE([struct user_regs_struct],
+              [sys_user_has_user_regs=yes], [sys_user_has_user_regs=no],
+              [[#include <sys/ptrace.h>]
+               [#include <sys/time.h>]
+               [#include <sys/user.h>]])
+if test "$sys_user_has_user_regs" = "yes"; then
+  AC_DEFINE(HAVE_SYS_USER_REGS, 1,
+            [Define to 1 if <sys/user.h> defines struct user_regs_struct])
+fi
+
+# On a 64-bit host where can can use $CC -m32, we'll run two sets of tests.
+# Likewise in a 32-bit build on a host where $CC -m64 works.
+utrace_BIARCH
+# `$utrace_biarch' will be `-m64' even on an uniarch i386 machine.
+CC_BIARCH="$CC $utrace_biarch"
+AC_SUBST([CC_BIARCH])
+
+# In maintainer mode we really need flex and bison.
+# Otherwise we really need a release dir with maintainer files generated.
+if test "x$enable_maintainer_mode" = xyes; then
+  AC_CHECK_PROG(HAVE_FLEX, flex, yes, no)
+  if test "$HAVE_FLEX" = "no"; then
+    AC_MSG_ERROR([flex needed in maintainer mode])
+  fi
+  AC_CHECK_PROG(HAVE_BISON, bison, yes, no)
+  if test "$HAVE_BISON" = "no"; then
+    AC_MSG_ERROR([bison needed in maintainer mode])
+  fi
+else
+  if test ! -f ${srcdir}/libdw/known-dwarf.h; then
+    AC_MSG_ERROR([No libdw/known-dwarf.h. configure --enable-maintainer-mode])
+  fi
+fi
+
+# The testfiles are all compressed, we need bunzip2 when running make check
+AC_CHECK_PROG(HAVE_BUNZIP2, bunzip2, yes, no)
+if test "$HAVE_BUNZIP2" = "no"; then
+  AC_MSG_WARN([No bunzip2, needed to run make check])
+fi
+
+AC_OUTPUT
+
+AC_MSG_NOTICE([
+=====================================================================
+        elfutils: ${PACKAGE_VERSION} (eu_version: ${eu_version})
+=====================================================================
+
+    Prefix                             : ${prefix}
+    Program prefix ("eu-" recommended) : ${program_prefix}
+    Source code location               : ${srcdir}
+    Maintainer mode                    : ${enable_maintainer_mode}
+    libebl modules subdirectory        : ${LIBEBL_SUBDIR}
+    build arch                         : ${ac_cv_build}
+
+  RECOMMENDED FEATURES (should all be yes)
+    gzip support                       : ${with_zlib}
+    bzip2 support                      : ${with_bzlib}
+    lzma/xz support                    : ${with_lzma}
+    libstdc++ demangle support         : ${enable_demangler}
+    File textrel check                 : ${enable_textrelcheck}
+    Symbol versioning                  : ${enable_symbol_versioning}
+
+  NOT RECOMMENDED FEATURES (should all be no)
+    Experimental thread safety         : ${use_locks}
+
+  OTHER FEATURES
+    Deterministic archives by default  : ${default_ar_deterministic}
+    Native language support            : ${USE_NLS}
+
+  EXTRA TEST FEATURES (used with make check)
+    have bunzip2 installed (required)  : ${HAVE_BUNZIP2}
+    debug branch prediction            : ${use_debugpred}
+    gprof support                      : ${use_gprof}
+    gcov support                       : ${use_gcov}
+    run all tests under valgrind       : ${use_valgrind}
+    gcc undefined behaviour sanitizer  : ${use_undefined}
+    use rpath in tests                 : ${tests_use_rpath}
+    test biarch                        : ${utrace_cv_cc_biarch}
+])
diff --git a/third_party/elfutils/doc/ChangeLog b/third_party/elfutils/doc/ChangeLog
new file mode 100644
index 0000000..380a0cd
--- /dev/null
+++ b/third_party/elfutils/doc/ChangeLog
@@ -0,0 +1,12 @@
+2005-04-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfutils.sgml: Some typo fixes and a few extensions.
+	Patch by Eric Christopher <echristo@redhat.com>.
+
+2005-02-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Prefer pdf.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* Moved to CVS archive.
diff --git a/third_party/elfutils/doc/Makefile.am b/third_party/elfutils/doc/Makefile.am
new file mode 100644
index 0000000..44f0c11
--- /dev/null
+++ b/third_party/elfutils/doc/Makefile.am
@@ -0,0 +1,32 @@
+## Process this file with automake to create Makefile.in
+## Configure input file for elfutils.
+##
+## Copyright (C) 1996-2001, 2002, 2005 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file 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 3 of the License, or
+## (at your option) any later version.
+##
+## elfutils 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.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program.  If not, see <http://www.gnu.org/licenses/>.
+EXTRA_DIST = elfutils.sgml
+
+CLEANFILES = elfutils.dvi
+
+# We need only a few special rules to generate the various output formats
+# from the SGML sources.
+.PHONY: dvi pdf html
+pdf: $(srcdir)elfutils.pdf
+dvi: $(srcdir)elfutils.dvi
+
+$(srcdir)%.dvi: %.sgml
+	db2dvi $^
+$(srcdir)%.pdf: %.sgml
+	db2pdf $^
diff --git a/third_party/elfutils/doc/elfutils.sgml b/third_party/elfutils/doc/elfutils.sgml
new file mode 100644
index 0000000..d7fea40
--- /dev/null
+++ b/third_party/elfutils/doc/elfutils.sgml
@@ -0,0 +1,444 @@
+<!doctype book PUBLIC "-//OASIS//DTD DocBook V4.1//EN"[
+<!ENTITY package "<filename>new-bu</filename>">
+]>
+
+<book>
+  <title>New Binutils User's and Reference Manual</title>
+
+  <chapter>
+    <title><filename>libelf</filename> <acronym>ABI</acronym></title>
+
+    <simpara>The <acronym>ABI</acronym> of the
+    <filename>libelf</filename> implemented in the &package; package
+    is following that of Sun's implementation which in turn in derived
+    from the original SysVr4 implementation.  There are some
+    extensions over Sun's versions, though, which makes it impossible
+    to replace this implementation with Sun's.</simpara>
+
+    <beginpage>
+
+    <refentry xreflabel="Elf_Data" id="ElfUData">
+      <refnamediv>
+	<refname>Elf_Data</refname>
+	<refpurpose>Descriptor for Data Buffer</refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<synopsis>
+#include &lt;libelf.h&gt;
+</synopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>Description</title>
+
+	<simpara>The <structname>Elf_Data</structname> structure is as
+	a descriptor for a data buffer associated with a section.
+	Every data buffer is associated with a specific section (see
+	<!-- xref --><structname>Elf_Scn</structname>).</simpara>
+
+	<simpara>A data buffer is created when reading a file.  In
+	this case only a single buffer is present in the section.  The
+	user can add as many sections as wanted to a section and they
+	can be retrieved using the <function>elf_getdata</function>
+	and <function>elf_rawdata</function> functions.<!-- xref
+	--></simpara>
+
+	<simpara>The <structname>Elf_Data</structname> structure
+	contains the following members:</simpara>
+
+	<programlisting>
+   void         *d_buf
+   Elf_Type      d_type
+   size_t        d_size
+   off_t         d_off
+   size_t        d_align
+   unsigned int  d_version
+</programlisting>
+
+	<simpara>All of these members can be modified directly by the
+	user.  They can be used to resize a section, to change its
+	content or type, and many more tasks.  This is also true for
+	the data read from a file.  The meaning of each member is as
+	follows:</simpara>
+
+	<variablelist>
+	  <varlistentry>
+	    <term><structfield>d_buf</structfield></term>
+	    <listitem>
+	      <simpara>The <structfield>d_buf</structfield> member is
+	      the pointer to the buffer with the actual data.  When
+	      the ELF file was read from a file the first and only
+	      data buffer of a section is allocated by the
+	      <filename>libelf</filename> library.  The user should
+	      not try to resize or free this buffer.  When the user
+	      adds a new data buffer to a section the associated
+	      memory block is normally allocated by the user.  It is
+	      important that the buffer must have a lifetime at least
+	      until the ELF file is closed entirely (important when
+	      the buffer is allocated on the stack).  If the buffer is
+	      not allocated on the stack it is the user's
+	      responsibility to free the buffer after it is not used
+	      anymore.  The <structfield>d_buf</structfield> member
+	      can contain a null pointer if the data buffer is
+	      empty.</simpara>
+	    </listitem>
+	  </varlistentry>
+
+	  <varlistentry>
+	    <term><structfield>d_type</structfield></term>
+	    <listitem>
+	      <simpara>The <structfield>d_type</structfield>
+	      determines how the data of the buffer is interpreted.
+	      This type is determined from the section type and must
+	      be the same for all data buffers for a section.  See
+	      <!-- xref --><type>Elf_Type</type> for more information.
+	      The <function><link linkend="elfUgetdata"
+	      endterm="elfUgetdata.refname"></link></function>
+	      function uses this information to convert the data of
+	      the buffer between the external form and the form
+	      represented to the user and back if necessary.</simpara>
+	    </listitem>
+	  </varlistentry>
+
+	  <varlistentry>
+	    <term><structfield>d_version</structfield></term>
+	    <listitem>
+	      <simpara>The <structfield>d_version</structfield>
+              contains the ELF version of the file.</simpara>
+	    </listitem>
+	  </varlistentry>
+
+	  <varlistentry>
+	    <term><structfield>d_size</structfield></term>
+	    <listitem>
+	      <simpara>The <structfield>d_size</structfield> contains
+              the size of the buffer in bytes.</simpara>
+	    </listitem>
+	  </varlistentry>
+
+	  <varlistentry>
+	    <term><structfield>d_off</structfield></term>
+	    <listitem>
+	      <simpara>The <structfield>d_off</structfield> is the
+              offset into the section in bytes.</simpara>
+	    </listitem>
+	  </varlistentry>
+
+	  <varlistentry>
+	    <term><structfield>d_align</structfield></term>
+	    <listitem>
+	      <simpara>The <structfield>d_align</structfield> is the
+              address alignment of the section in bytes.</simpara>
+	    </listitem>
+	  </varlistentry>
+	</variablelist>
+      </refsect1>
+    </refentry>
+
+    <beginpage>
+
+    <refentry id="elfUgetdata">
+      <refnamediv>
+	<refname id="elfUgetdata.refname">elf_getdata</refname>
+	<refpurpose>Get washed data of section</refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcsynopsisinfo>
+#include &lt;libelf.h&gt;
+</funcsynopsisinfo>
+	  <funcprototype>
+	    <funcdef>Elf_Data *<function>elf_getdata</function></funcdef>
+	    <paramdef>Elf_Scn *<parameter>scn</parameter></paramdef>
+	    <paramdef>Elf_Data *<parameter>data</parameter></paramdef>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>Description</title>
+
+	<simpara>The <function>elf_getdata</function> function allows
+	the user to retrieve the data buffers of the section
+	<parameter>scn</parameter>.  There can be more than one buffer
+	if the user explicitly added them.  When a file is read the
+	<filename>libelf</filename> library creates exactly one data
+	buffer.</simpara>
+
+	<simpara>The first buffer in the list can be obtained by
+	passing a null pointer in the parameter
+	<parameter>data</parameter>.  To get the next data buffer the
+	previously returned value must be passed in the
+	<parameter>data</parameter> parameter.  If there are no more
+	buffer left in the list a null pointer is returned.</simpara>
+
+	<simpara>If the <parameter>data</parameter> parameter is not a
+	null pointer it must be a descriptor for a buffer
+	associated with the section <parameter>scn</parameter>.  If
+	this is not the case a null pointer is returned.  To
+	facilitate error handling <function>elf_getdata</function>
+	also returns a null pointer if the <parameter>scn</parameter>
+	parameter is a null pointer.</simpara>
+      </refsect1>
+    </refentry>
+
+    <refentry>
+      <refnamediv>
+	<refname id="elfUupdate.refname">elf_update</refname>
+	<refpurpose>update an ELF descriptor</refpurpose>
+      </refnamediv>
+
+      <refsynopsisdiv>
+	<funcsynopsis>
+	  <funcsynopsisinfo>
+#include &lt;libelf.h&gt;
+</funcsynopsisinfo>
+	  <funcprototype>
+	    <funcdef>off_t <function>elf_update</function></funcdef>
+	    <paramdef>Elf *<parameter>elf</parameter></paramdef>
+	    <paramdef>Elf_Cmd <parameter>cmd</parameter></paramdef>
+	  </funcprototype>
+	</funcsynopsis>
+      </refsynopsisdiv>
+
+      <refsect1>
+	<title>Description</title>
+
+	<simpara>The user is responsible for filling in the following
+	fields in the named data structures:</simpara>
+
+	<table>
+	  <title>Fields not set by <function>elf_update</function></title>
+	  <tgroup cols="3">
+            <colspec colwidth="90pt">
+            <colspec colwidth="110pt">
+	    <thead>
+	      <row>
+		<entry>Data Structure</entry>
+		<entry>Member</entry>
+		<entry>Exception</entry>
+	      </row>
+	    </thead>
+	    <tbody>
+	      <row>
+		<entry morerows="8"><type>Elfxx_Ehdr</type></entry>
+		<entry>e_ident[EI_DATA]</entry>
+		<entry>see below</entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>e_type</entry>
+		<!-- <entry morerows="1"></entry> -->
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>e_machine</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>e_version</entry>
+		<entry>see below</entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>e_entry</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>e_phoff</entry>
+		<entry>if <symbol>ELF_F_LAYOUT</symbol> is used</entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>e_shoff</entry>
+		<entry>if <symbol>ELF_F_LAYOUT</symbol> is used</entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>e_flags</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>e_shstrndx</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry morerows="7">Elfxx_Phdr</entry>
+		<entry>p_type</entry>
+		<entry morerows="7"></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>p_offset</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>p_vaddr</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>p_paddr</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>p_filesz</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>p_memsz</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>p_flags</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>p_align</entry>
+		<entry></entry>
+	      </row>
+
+	      <row>
+		<entry morerows="9">Elfxx_Shdr</entry>
+		<entry>sh_name</entry>
+		<entry morerows="3"></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>sh_type</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>sh_flags</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>sh_addr</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>sh_offset</entry>
+		<entry>if <symbol>ELF_F_LAYOUT</symbol> is used</entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>sh_size</entry>
+		<entry>if <symbol>ELF_F_LAYOUT</symbol> is used</entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>sh_link</entry>
+		<!-- <entry morerows="1"></entry> -->
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>sh_info</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>sh_addralign</entry>
+		<entry>if <symbol>ELF_F_LAYOUT</symbol> is used</entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>sh_entsize</entry>
+		<entry></entry>
+	      </row>
+
+	      <row>
+		<entry morerows="5">Elf_Data</entry>
+		<entry>d_buf</entry>
+		<entry morerows="2"></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>d_type</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>d_size</entry>
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>d_off</entry>
+		<entry>if <symbol>ELF_F_LAYOUT</symbol> is used</entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>d_align</entry>
+		<!-- <entry morerows="1"></entry> -->
+		<entry></entry>
+	      </row>
+	      <row>
+		<entry></entry>
+		<entry>d_version</entry>
+		<entry></entry>
+	      </row>
+	    </tbody>
+	  </tgroup>
+	</table>
+
+	<simpara>Two fields of the ELF header are handled in a special
+	way:</simpara>
+
+	<variablelist>
+	  <varlistentry>
+	    <term>e_version</term>
+	    <listitem>
+	      <simpara>The user can set this field to the vvalue for
+	      the version to be used.  It is an error if the library
+	      cannot handle this version.  If the field contains the
+	      value <symbol>EV_NONE</symbol> the library will fill in
+	      its own internal version.</simpara>
+	    </listitem>
+	  </varlistentry>
+
+	  <varlistentry>
+	    <term>e_ident[EI_DATA]</term>
+	    <listitem>
+	      <simpara>The user should fill in the byte ordering for
+	      the file.  If the value of the field is
+	      <symbol>ELFDATANONE</symbol> the library replaces it
+	      with the native byte ordering for the machine.</simpara>
+	    </listitem>
+	  </varlistentry>
+	</variablelist>
+      </refsect1>
+    </refentry>
+  </chapter>
+
+  <chapter>
+    <title><filename>libelf</filename> Internals</title>
+
+    <simpara>Since the binary format handling tools need constant
+    attention since there are always new machines and varients
+    therefore coming out it is important to have the implementation
+    well documented.  Only this way extensions can be made in the
+    right places and the mistakes of the past avoided.</simpara>
+  </chapter>
+</book>
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omitag:nil
+sgml-shorttag:t
+End:
+-->
diff --git a/third_party/elfutils/lib/ChangeLog b/third_party/elfutils/lib/ChangeLog
new file mode 100644
index 0000000..0f03dab
--- /dev/null
+++ b/third_party/elfutils/lib/ChangeLog
@@ -0,0 +1,278 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* eu-config.h (FALLTHROUGH): New macro.
+
+2017-10-16  Mark Wielaard  <mark@klomp.org>
+
+	* md5.{c,h}: Removed.
+	* sha1.{c,h}: Likewise.
+	* Makefile.am (libeu_a_SOURCES): Remove md5.c and sha1.c.
+	(noinst_HEADERS): Remove md5.h and sha1.h.
+
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* eu-config.h: Define attribute_packed to either
+	__attribute__((packed)) or __attribute__((packed, gcc_struct)).
+
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* eu-config.h: Define attribute_hidden to be empty if the compiler
+	doesn't support it.
+
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpic_CFLAGS.
+
+2017-07-18  Mark Wielaard  <mark@klomp.org>
+
+	* bpf.h: New file.
+	* Makefile.am (noinst_HEADERS): Add bpf.h
+
+2017-05-05  Mark Wielaard  <mark@klomp.org>
+
+	* printversion.c (print_version): Update copyright year.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* crc32.c: include config.h.
+	* system.h: Don't include config.h.
+
+2017-02-16  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am (libeu_a_SOURCES): Remove version.c, add printversion.c
+	(noinst_HEADERS): Add printversion.h
+	* version.c: Moved to printversion.c.
+	* printversion.c: New file, moved from version.c,
+	remove stdio.h, argp.h, system.h includes,
+	add printversion.h include.
+	* printversion.h: New file.
+	* system.h: Remove argp.h include,
+	(ARGP_PROGRAM_VERSION_HOOK_DEF, ARGP_PROGRAM_BUG_ADDRESS_DEF): Remove.
+	(print_version): Remove.
+
+2017-02-15  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* system.h: Provide mempcpy if it doesn't exist.
+	* xstrndup.c: Include system.h.
+
+2017-02-15  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* crc32_file.c: Use _SC_PAGESIZE rather than _SC_PAGE_SIZE.
+
+2017-02-14  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* color.h: New file.
+	* color.c: Include color.h.
+	* libeu.h: Remove color handling.
+	* Makefile.am (noinst_HEADERS): Add color.h.
+
+2016-12-29  Luiz Angelo Daros de Luca  <luizluca@gmail.com>
+
+	* crc32_file.c: Include system.h.
+	* system.h: Remove semi-colon after TEMP_FAILURE_RETRY definition.
+
+2016-12-24  Mark Wielaard  <mark@klomp.org>
+
+	* version.c: New source file.
+	* Makefile.am (libeu_a_SOURCES): Add version.c
+	* system.h (print_version): New function definition.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* fixedsizehash.h (CONCAT): Use __CONCAT when available.
+	* system.h: Include config.h and errno.h.
+	(powerof2): Define if not already defined.
+	(TEMP_FAILURE_RETRY): Define when not yet defined.
+
+2015-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* Makefile.am (noinst_HEADERS): Add libeu.h.
+	* color.c: Remove system.h include, add libeu.h include.
+	* crc32_file.c: Likewise.
+	* fixedsizehash.h: Remove sys/param.h include.
+	* libeu.h: New file.
+	* system.h: Include sys/param.h.
+	(xmalloc, xcalloc, xrealloc, xstrdup, xstrndup, crc32, crc32_file,
+	color_argp, color_enum, color_*): Move definitions to libeu.h.
+	* xstrdup.c: Remove system.h include, add libeu.h include.
+	* xstrndup.c: Remove system.h include, add libeu.h and stdint.h
+	includes.
+
+2015-09-24  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid relocation
+	overflows in some platforms.
+
+2015-09-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dynamicsizehash.c: Remove old-style function definitions.
+	* md5.c: Likewise.
+	* sha1.c: Likewise.
+	* xmalloc.c: Likewise.
+	* xstrdup.c: Likewise.
+	* xstrndup.c: Likewise.
+
+2015-05-31  Mark Wielaard  <mjw@redhat.com>
+
+	* eu-config.h (ALLOW_UNALIGNED): Define when ! CHECK_UNDEFINED.
+
+2015-04-23  Max Filippov  <jcmvbkbc@gmail.com>
+
+	* eu-config.h: Use SYMBOL_VERSIONING as guard.
+
+2014-01-17  Lei Zhang  <thestig@google.com>
+
+	* crc32_file.c: Include config.h.
+
+2013-12-12  Josh Stone  <jistone@redhat.com>
+
+	* dynamicsizehash.c (lookup): Add a shortcut around division.
+
+2013-04-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* eu-config.h (COMPAT_VERSION_NEWPROTO): New.  Twice.
+
+2013-04-26  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* system.h (LE64, BE64): Move here the definitions from
+	libdwfl/link_map.c.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+
+2012-10-09  Adam Markey  <adam@etinternational.com>
+
+	* system.h: Changed pwrite_retry, write_retry, and pread_retry to
+	handle case where not all data was read/written.
+
+2012-10-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* system.h (eu_static_assert): New macro.
+
+2012-01-21  Ulrich Drepper  <drepper@gmail.com>
+
+	* Makefile.am (libeu_a_SOURCES): Add color.c.
+	* system.h: Declare color_argp.  Define color_enum.  Declare
+	color_* variables.
+	* color.c: New file.
+
+2011-10-02  Ulrich Drepper  <drepper@gmail.com>
+
+	* system.h: Declare __cxa_demangle.
+
+2011-07-09  Roland McGrath  <roland@hack.frob.com>
+
+	* sha1.c (be64_copy): New function.
+	(sha1_finish_ctx): Use it.
+	* md5.c (le64_copy): New function.
+	(md5_finish_ctx): Use it.
+	* system.h (LE32, BE32): New macros, using <endian.h> and <byteswap.h>.
+	* md5.c (SWAP): Use LE32.
+	* sha1.c (SWAP): Use BE32.
+
+2010-06-16  Roland McGrath  <roland@redhat.com>
+
+	* dynamicsizehash.h (HASHTYPE): New macro.
+	(struct): Use size_t for table sizes.
+	* dynamicsizehash.c: Likewise.  Use HASHTYPE for hash values.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Use config/eu.am for common stuff.
+
+2009-08-09  Roland McGrath  <roland@redhat.com>
+
+	* eu-config.h (OLD_VERSION, NEW_VERSION, COMPAT_VERSION): New macros.
+
+2009-01-23  Roland McGrath  <roland@redhat.com>
+
+	* eu-config.h: Add multiple inclusion protection.
+
+2009-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* system.h (ARGP_PROGRAM_VERSION_HOOK_DEF): Define.
+	(ARGP_PROGRAM_BUG_ADDRESS_DEF): Define.
+
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* eu-config.h: Remove tls_key_t, key_create, getspecific, setspecific,
+	once_define, and once_execute macros.  Use USE_LOCKS instead of
+	USE_TLS.
+
+2008-08-25  Roland McGrath  <roland@redhat.com>
+
+	* eu-config.h [USE_TLS] (RWLOCK_CALL): New macro.
+	(rwlock_init, rwlock_fini, rwlock_rdlock, rwlock_wrlock, rwlock_unlock):
+	Use it.
+
+2008-08-24  Roland McGrath  <roland@redhat.com>
+
+	* eu-config.h: New file.
+	* Makefile.am (noinst_HEADERS): Add it.
+
+2008-02-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (libeu_a_SOURCES): Add sha1.c.
+	(noinst_HEADERS): Add sha1.h.
+	* sha1.c: New file.
+	* sha1.h: New file.
+
+2008-01-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (libeu_a_SOURCES): Add md5.c.
+	(noinst_HEADERS): Add md5.h.
+	* md5.c: New file.
+	* md5.h: New file.
+
+2006-04-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (libeu_a_SOURCES): We don't need xstrdup in the moment.
+
+2005-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* system.h: Define pwrite_retry, write_retry, and pread_retry.
+
+2005-08-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (xmalloc_CFLAGS): Define only if !GPROF.
+
+2005-05-03  Roland McGrath  <roland@redhat.com>
+
+	* crc32_file.c: New file.
+	* Makefile.am (libeu_a_SOURCES): Add it.
+	* system.h: Declare crc32_file.
+
+2005-04-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Use -ffunction-sections for xmalloc.c.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* dynamicsizehash.c (lookup): Mark val parameter as possibly unused.
+
+2005-02-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* fixedsizehash.h: Mark unused parameters.  Correct CLASS and
+	const order for fshash_find.
+
+	* Makefile.am: Cleanup AM_CFLAGS handling.  Add -Wunused -Wextra.
+
+2005-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am [MUDFLAP] (AM_CFLAGS): Add -fpic and -fmudflap.
+
+2004-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support building with mudflap.
+
+2003-09-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add -fpic.
+
+	* Makefile.am (noinst_HEADERS): Add list.h.
+	* list.h: New file.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* Moved to CVS archive.
diff --git a/third_party/elfutils/lib/Makefile.am b/third_party/elfutils/lib/Makefile.am
new file mode 100644
index 0000000..36d21a0
--- /dev/null
+++ b/third_party/elfutils/lib/Makefile.am
@@ -0,0 +1,46 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 1996-2011 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * 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
+##
+## or both in parallel, as here.
+##
+## elfutils 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.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+AM_CFLAGS += $(fpic_CFLAGS)
+AM_CPPFLAGS += -I$(srcdir)/../libelf
+
+noinst_LIBRARIES = libeu.a
+
+libeu_a_SOURCES = xstrdup.c xstrndup.c xmalloc.c next_prime.c \
+		  crc32.c crc32_file.c \
+		  color.c printversion.c
+
+noinst_HEADERS = fixedsizehash.h libeu.h system.h dynamicsizehash.h list.h \
+		 eu-config.h color.h printversion.h bpf.h
+EXTRA_DIST = dynamicsizehash.c
+
+if !GPROF
+xmalloc_CFLAGS = -ffunction-sections
+endif
diff --git a/third_party/elfutils/lib/bpf.h b/third_party/elfutils/lib/bpf.h
new file mode 100644
index 0000000..db80a51
--- /dev/null
+++ b/third_party/elfutils/lib/bpf.h
@@ -0,0 +1,82 @@
+/* Minimal extended BPF constants as alternative for linux/bpf.h.  */
+
+#ifndef _ELFUTILS_BPF_H
+#define _ELFUTILS_BPF_H 1
+
+#include <stdint.h>
+
+#define BPF_CLASS(code) ((code) & 0x07)
+
+#define BPF_LD    0x00
+#define BPF_LDX   0x01
+#define BPF_ST    0x02
+#define BPF_STX   0x03
+#define BPF_ALU   0x04
+#define BPF_JMP   0x05
+#define BPF_RET   0x06
+#define BPF_MISC  0x07
+
+#define BPF_ALU64 0x07
+
+#define BPF_JNE  0x50
+#define BPF_JSGT 0x60
+#define BPF_JSGE 0x70
+#define BPF_CALL 0x80
+#define BPF_EXIT 0x90
+
+#define BPF_W 0x00
+#define BPF_H 0x08
+#define BPF_B 0x10
+
+#define BPF_IMM 0x00
+#define BPF_ABS 0x20
+#define BPF_IND 0x40
+#define BPF_MEM 0x60
+#define BPF_LEN 0x80
+#define BPF_MSH 0xa0
+
+#define BPF_DW   0x18
+#define BPF_XADD 0xc0
+
+#define BPF_ADD 0x00
+#define BPF_SUB 0x10
+#define BPF_MUL 0x20
+#define BPF_DIV 0x30
+#define BPF_OR  0x40
+#define BPF_AND 0x50
+#define BPF_LSH 0x60
+#define BPF_RSH 0x70
+#define BPF_NEG 0x80
+#define BPF_MOD 0x90
+#define BPF_XOR 0xa0
+
+#define BPF_MOV  0xb0
+#define BPF_ARSH 0xc0
+
+#define BPF_JA   0x00
+#define BPF_JEQ  0x10
+#define BPF_JGT  0x20
+#define BPF_JGE  0x30
+#define BPF_JSET 0x40
+
+#define BPF_K 0x00
+#define BPF_X 0x08
+
+#define BPF_END   0xd0
+#define BPF_TO_LE 0x00
+#define BPF_TO_BE 0x08
+
+#define BPF_PSEUDO_MAP_FD 1
+
+#define MAX_BPF_REG 10
+
+struct bpf_insn
+{
+  uint8_t code;
+  uint8_t dst_reg:4;
+  uint8_t src_reg:4;
+  int16_t off;
+  int32_t imm;
+};
+
+#endif
diff --git a/third_party/elfutils/lib/color.c b/third_party/elfutils/lib/color.c
new file mode 100644
index 0000000..f62389d
--- /dev/null
+++ b/third_party/elfutils/lib/color.c
@@ -0,0 +1,230 @@
+/* Handling of color output.
+   Copyright (C) 2011 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2011.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <error.h>
+#include <libintl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "libeu.h"
+#include "color.h"
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Option values.  */
+#define OPT_COLOR 0x100100
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { "color", OPT_COLOR, "WHEN", OPTION_ARG_OPTIONAL,
+    N_("colorize the output.  WHEN defaults to 'always' or can be 'auto' or 'never'"), 0 },
+
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Parser data structure.  */
+const struct argp color_argp =
+  {
+    options, parse_opt, NULL, NULL, NULL, NULL, NULL
+  };
+
+/* Coloring mode.  */
+enum color_enum color_mode;
+
+/* Colors to use for the various components.  */
+char *color_address = "";
+char *color_bytes = "";
+char *color_mnemonic = "";
+char *color_operand = NULL;
+char *color_operand1 = "";
+char *color_operand2 = "";
+char *color_operand3 = "";
+char *color_label = "";
+char *color_undef = "";
+char *color_undef_tls = "";
+char *color_undef_weak = "";
+char *color_symbol = "";
+char *color_tls = "";
+char *color_weak = "";
+
+const char color_off[] = "\e[0m";
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg,
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case OPT_COLOR:
+      if (arg == NULL)
+	color_mode = color_always;
+      else
+	{
+	  static const struct
+	  {
+	    const char str[7];
+	    enum color_enum mode;
+	  } values[] =
+	      {
+		{ "always", color_always },
+		{ "yes", color_always },
+		{ "force", color_always },
+		{ "never", color_never },
+		{ "no", color_never },
+		{ "none", color_never },
+		{ "auto", color_auto },
+		{ "tty", color_auto },
+		{ "if-tty", color_auto }
+	      };
+	  const int nvalues = sizeof (values) / sizeof (values[0]);
+	  int i;
+	  for (i = 0; i < nvalues; ++i)
+	    if (strcmp (arg, values[i].str) == 0)
+	      {
+		color_mode = values[i].mode;
+		if (color_mode == color_auto)
+		  color_mode
+		    = isatty (STDOUT_FILENO) ? color_always : color_never;
+		break;
+	      }
+	  if (i == nvalues)
+	    {
+	      error (0, 0, dgettext ("elfutils", "\
+%s: invalid argument '%s' for '--color'\n\
+valid arguments are:\n\
+  - 'always', 'yes', 'force'\n\
+  - 'never', 'no', 'none'\n\
+  - 'auto', 'tty', 'if-tty'\n"),
+		     program_invocation_short_name, arg);
+	      argp_help (&color_argp, stderr, ARGP_HELP_SEE,
+			 program_invocation_short_name);
+	      exit (EXIT_FAILURE);
+	    }
+	}
+
+      if (color_mode == color_always)
+	{
+	  const char *env = getenv ("ELFUTILS_COLORS");
+	  if (env != NULL)
+	    {
+	      do
+		{
+		  const char *start = env;
+		  while (*env != '=' && *env != '\0')
+		    ++env;
+		  if (*env == '=' && env != start)
+		    {
+		      size_t name_len = env - start;
+		      const char *val = ++env;
+		      env = strchrnul (env, ':');
+		      if (val != env)
+			{
+			  static const struct
+			  {
+			    unsigned char len;
+			    const char name[sizeof (char *) - 1];
+			    char **varp;
+			  } known[] =
+			      {
+#define E(name, var) { sizeof (#name) - 1, #name,  &color_##var }
+				E (a, address),
+				E (b, bytes),
+				E (m, mnemonic),
+				E (o, operand),
+				E (o1, operand1),
+				E (o1, operand2),
+				E (o1, operand3),
+				E (l, label),
+				E (u, undef),
+				E (ut, undef_tls),
+				E (uw, undef_weak),
+				E (sy, symbol),
+				E (st, tls),
+				E (sw, weak),
+			      };
+			  const size_t nknown = (sizeof (known)
+						 / sizeof (known[0]));
+
+			  for (size_t i = 0; i < nknown; ++i)
+			    if (name_len == known[i].len
+				&& memcmp (start, known[i].name, name_len) == 0)
+			      {
+				if (asprintf (known[i].varp, "\e[%.*sm",
+					      (int) (env - val), val) < 0)
+				  error (EXIT_FAILURE, errno,
+					 gettext ("cannot allocate memory"));
+				break;
+			      }
+			}
+		      if (*env == ':')
+			++env;
+		    }
+		}
+	      while (*env != '\0');
+
+	      if (color_operand != NULL)
+		{
+		  if (color_operand1[0] == '\0')
+		    color_operand1 = color_operand;
+		  if (color_operand2[0] == '\0')
+		    color_operand2 = color_operand;
+		  if (color_operand3[0] == '\0')
+		    color_operand3 = color_operand;
+		}
+	    }
+#if 0
+	  else
+	    {
+	      // XXX Just for testing.
+	      color_address = xstrdup ("\e[38;5;166;1m");
+	      color_bytes = xstrdup ("\e[38;5;141m");
+	      color_mnemonic = xstrdup ("\e[38;5;202;1m");
+	      color_operand1 = xstrdup ("\e[38;5;220m");
+	      color_operand2 = xstrdup ("\e[38;5;48m");
+	      color_operand3 = xstrdup ("\e[38;5;112m");
+	      color_label = xstrdup ("\e[38;5;21m");
+	    }
+#endif
+	}
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
diff --git a/third_party/elfutils/lib/color.h b/third_party/elfutils/lib/color.h
new file mode 100644
index 0000000..3872eb0
--- /dev/null
+++ b/third_party/elfutils/lib/color.h
@@ -0,0 +1,63 @@
+/* Handling of color output.
+   Copyright (C) 2017 The Qt Company
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2011.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+
+#ifndef COLOR_H
+#define COLOR_H 1
+
+/* Command line parser.  */
+extern const struct argp color_argp;
+
+/* Coloring mode.  */
+enum color_enum
+  {
+    color_never = 0,
+    color_always,
+    color_auto
+  } __attribute__ ((packed));
+extern enum color_enum color_mode;
+
+/* Colors to use for the various components.  */
+extern char *color_address;
+extern char *color_bytes;
+extern char *color_mnemonic;
+extern char *color_operand1;
+extern char *color_operand2;
+extern char *color_operand3;
+extern char *color_label;
+extern char *color_undef;
+extern char *color_undef_tls;
+extern char *color_undef_weak;
+extern char *color_symbol;
+extern char *color_tls;
+extern char *color_weak;
+
+extern const char color_off[];
+
+#endif /* color.h */
diff --git a/third_party/elfutils/lib/crc32.c b/third_party/elfutils/lib/crc32.c
new file mode 100644
index 0000000..758602e
--- /dev/null
+++ b/third_party/elfutils/lib/crc32.c
@@ -0,0 +1,102 @@
+/* Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdint.h>
+#include "system.h"
+
+
+/* Table computed with Mark Adler's makecrc.c utility.  */
+static const uint32_t crc32_table[256] =
+{
+  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+  0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+  0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+  0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+  0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+  0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+  0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+  0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+  0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+  0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+  0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+  0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+  0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+  0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+  0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+  0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+  0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+  0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+  0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+  0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+  0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+  0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+  0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+  0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+  0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+  0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+  0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+  0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+  0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+  0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+  0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+  0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+  0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+  0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+  0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+  0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+  0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+  0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+  0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+  0x2d02ef8d
+};
+
+uint32_t
+crc32 (uint32_t crc, unsigned char *buf, size_t len)
+{
+  unsigned char *end;
+
+  crc = ~crc;
+  for (end = buf + len; buf < end; ++buf)
+    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+  return ~crc;
+}
diff --git a/third_party/elfutils/lib/crc32_file.c b/third_party/elfutils/lib/crc32_file.c
new file mode 100644
index 0000000..f7607d0
--- /dev/null
+++ b/third_party/elfutils/lib/crc32_file.c
@@ -0,0 +1,92 @@
+/* Compute CRC32 checksum of file contents.
+   Copyright (C) 2006 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libeu.h"
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include "system.h"
+
+int
+crc32_file (int fd, uint32_t *resp)
+{
+  unsigned char buffer[1024 * 8];
+  uint32_t crc = 0;
+  off_t off = 0;
+  ssize_t count;
+
+  struct stat st;
+  if (fstat (fd, &st) == 0)
+    {
+      /* Try mapping in the file data.  */
+      size_t mapsize = st.st_size;
+      void *mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0);
+      if (mapped == MAP_FAILED && errno == ENOMEM)
+	{
+	  const size_t pagesize = sysconf (_SC_PAGESIZE);
+	  mapsize = ((mapsize / 2) + pagesize - 1) & -pagesize;
+	  while (mapsize >= pagesize
+		 && (mapped = mmap (NULL, mapsize, PROT_READ, MAP_PRIVATE,
+				    fd, 0)) == MAP_FAILED && errno == ENOMEM)
+	    mapsize /= 2;
+	}
+      if (mapped != MAP_FAILED)
+	{
+	  do
+	    {
+	      if (st.st_size <= (off_t) mapsize)
+		{
+		  *resp = crc32 (crc, mapped, st.st_size);
+		  munmap (mapped, mapsize);
+		  return 0;
+		}
+	      crc = crc32 (crc, mapped, mapsize);
+	      off += mapsize;
+	      st.st_size -= mapsize;
+	    } while (mmap (mapped, mapsize, PROT_READ, MAP_FIXED|MAP_PRIVATE,
+			   fd, off) == mapped);
+	  munmap (mapped, mapsize);
+	}
+    }
+
+  while ((count = TEMP_FAILURE_RETRY (pread (fd, buffer, sizeof buffer,
+					     off))) > 0)
+    {
+      off += count;
+      crc = crc32 (crc, buffer, count);
+    }
+
+  *resp = crc;
+
+  return count == 0 ? 0 : -1;
+}
diff --git a/third_party/elfutils/lib/dynamicsizehash.c b/third_party/elfutils/lib/dynamicsizehash.c
new file mode 100644
index 0000000..f9406eb
--- /dev/null
+++ b/third_party/elfutils/lib/dynamicsizehash.c
@@ -0,0 +1,315 @@
+/* Copyright (C) 2000-2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <system.h>
+
+/* Before including this file the following macros must be defined:
+
+   NAME      name of the hash table structure.
+   TYPE      data type of the hash table entries
+   COMPARE   comparison function taking two pointers to TYPE objects
+
+   The following macros if present select features:
+
+   ITERATE   iterating over the table entries is possible
+   REVERSE   iterate in reverse order of insert
+ */
+
+
+static size_t
+lookup (NAME *htab, HASHTYPE hval, TYPE val __attribute__ ((unused)))
+{
+  /* First hash function: simply take the modul but prevent zero.  Small values
+     can skip the division, which helps performance when this is common.  */
+  size_t idx = 1 + (hval < htab->size ? hval : hval % htab->size);
+
+  if (htab->table[idx].hashval != 0)
+    {
+      HASHTYPE hash;
+
+      if (htab->table[idx].hashval == hval
+	  && COMPARE (htab->table[idx].data, val) == 0)
+	return idx;
+
+      /* Second hash function as suggested in [Knuth].  */
+      hash = 1 + hval % (htab->size - 2);
+
+      do
+	{
+	  if (idx <= hash)
+	    idx = htab->size + idx - hash;
+	  else
+	    idx -= hash;
+
+	  /* If entry is found use it.  */
+	  if (htab->table[idx].hashval == hval
+	      && COMPARE (htab->table[idx].data, val) == 0)
+	    return idx;
+	}
+      while (htab->table[idx].hashval);
+    }
+  return idx;
+}
+
+
+static void
+insert_entry_2 (NAME *htab, HASHTYPE hval, size_t idx, TYPE data)
+{
+#ifdef ITERATE
+  if (htab->table[idx].hashval == 0)
+    {
+# ifdef REVERSE
+      htab->table[idx].next = htab->first;
+      htab->first = &htab->table[idx];
+# else
+      /* Add the new value to the list.  */
+      if (htab->first == NULL)
+	htab->first = htab->table[idx].next = &htab->table[idx];
+      else
+	{
+	  htab->table[idx].next = htab->first->next;
+	  htab->first = htab->first->next = &htab->table[idx];
+	}
+# endif
+    }
+#endif
+
+  htab->table[idx].hashval = hval;
+  htab->table[idx].data = data;
+
+  ++htab->filled;
+  if (100 * htab->filled > 90 * htab->size)
+    {
+      /* Table is filled more than 90%.  Resize the table.  */
+#ifdef ITERATE
+      __typeof__ (htab->first) first;
+# ifndef REVERSE
+      __typeof__ (htab->first) runp;
+# endif
+#else
+      size_t old_size = htab->size;
+#endif
+#define _TABLE(name) \
+      name##_ent *table = htab->table
+#define TABLE(name) _TABLE (name)
+      TABLE(NAME);
+
+      htab->size = next_prime (htab->size * 2);
+      htab->filled = 0;
+#ifdef ITERATE
+      first = htab->first;
+      htab->first = NULL;
+#endif
+      htab->table = calloc ((1 + htab->size), sizeof (htab->table[0]));
+      if (htab->table == NULL)
+	{
+	  /* We cannot enlarge the table.  Live with what we got.  This
+	     might lead to an infinite loop at some point, though.  */
+	  htab->table = table;
+	  return;
+	}
+
+      /* Add the old entries to the new table.  When iteration is
+	 supported we maintain the order.  */
+#ifdef ITERATE
+# ifdef REVERSE
+      while (first != NULL)
+	{
+	  insert_entry_2 (htab, first->hashval,
+			  lookup (htab, first->hashval, first->data),
+			  first->data);
+
+	  first = first->next;
+	}
+# else
+      assert (first != NULL);
+      runp = first = first->next;
+      do
+	insert_entry_2 (htab, runp->hashval,
+			lookup (htab, runp->hashval, runp->data), runp->data);
+      while ((runp = runp->next) != first);
+# endif
+#else
+      for (idx = 1; idx <= old_size; ++idx)
+	if (table[idx].hashval != 0)
+	  insert_entry_2 (htab, table[idx].hashval,
+			  lookup (htab, table[idx].hashval, table[idx].data),
+			  table[idx].data);
+#endif
+
+      free (table);
+    }
+}
+
+
+int
+#define INIT(name) _INIT (name)
+#define _INIT(name) \
+  name##_init
+INIT(NAME) (NAME *htab, size_t init_size)
+{
+  /* We need the size to be a prime.  */
+  init_size = next_prime (init_size);
+
+  /* Initialize the data structure.  */
+  htab->size = init_size;
+  htab->filled = 0;
+#ifdef ITERATE
+  htab->first = NULL;
+#endif
+  htab->table = (void *) calloc ((init_size + 1), sizeof (htab->table[0]));
+  if (htab->table == NULL)
+    return -1;
+
+  return 0;
+}
+
+
+int
+#define FREE(name) _FREE (name)
+#define _FREE(name) \
+  name##_free
+FREE(NAME) (NAME *htab)
+{
+  free (htab->table);
+  return 0;
+}
+
+
+int
+#define INSERT(name) _INSERT (name)
+#define _INSERT(name) \
+  name##_insert
+INSERT(NAME) (NAME *htab, HASHTYPE hval, TYPE data)
+{
+  size_t idx;
+
+  /* Make the hash value nonzero.  */
+  hval = hval ?: 1;
+
+  idx = lookup (htab, hval, data);
+
+  if (htab->table[idx].hashval != 0)
+    /* We don't want to overwrite the old value.  */
+    return -1;
+
+  /* An empty bucket has been found.  */
+  insert_entry_2 (htab, hval, idx, data);
+  return 0;
+}
+
+
+#ifdef OVERWRITE
+int
+#define INSERT(name) _INSERT (name)
+#define _INSERT(name) \
+  name##_overwrite
+INSERT(NAME) (NAME *htab, HASHTYPE hval, TYPE data)
+{
+  size_t idx;
+
+  /* Make the hash value nonzero.  */
+  hval = hval ?: 1;
+
+  idx = lookup (htab, hval, data);
+
+  /* The correct bucket has been found.  */
+  insert_entry_2 (htab, hval, idx, data);
+  return 0;
+}
+#endif
+
+
+TYPE
+#define FIND(name) _FIND (name)
+#define _FIND(name) \
+  name##_find
+FIND(NAME) (NAME *htab, HASHTYPE hval, TYPE val)
+{
+  size_t idx;
+
+  /* Make the hash value nonzero.  */
+  hval = hval ?: 1;
+
+  idx = lookup (htab, hval, val);
+
+  if (htab->table[idx].hashval == 0)
+    return NULL;
+
+  return htab->table[idx].data;
+}
+
+
+#ifdef ITERATE
+# define ITERATEFCT(name) _ITERATEFCT (name)
+# define _ITERATEFCT(name) \
+  name##_iterate
+TYPE
+ITERATEFCT(NAME) (NAME *htab, void **ptr)
+{
+  void *p = *ptr;
+
+# define TYPENAME(name) _TYPENAME (name)
+# define _TYPENAME(name) name##_ent
+
+# ifdef REVERSE
+  if (p == NULL)
+    p = htab->first;
+  else
+    p = ((TYPENAME(NAME) *) p)->next;
+
+  if (p == NULL)
+    {
+      *ptr = NULL;
+      return NULL;
+    }
+# else
+  if (p == NULL)
+    {
+      if (htab->first == NULL)
+	return NULL;
+      p = htab->first->next;
+    }
+  else
+    {
+      if (p == htab->first)
+	return NULL;
+
+      p = ((TYPENAME(NAME) *) p)->next;
+    }
+# endif
+
+  /* Prepare the next element.  If possible this will pull the data
+     into the cache, for reading.  */
+  __builtin_prefetch (((TYPENAME(NAME) *) p)->next, 0, 2);
+
+  return ((TYPENAME(NAME) *) (*ptr = p))->data;
+}
+#endif
diff --git a/third_party/elfutils/lib/dynamicsizehash.h b/third_party/elfutils/lib/dynamicsizehash.h
new file mode 100644
index 0000000..ccd41d0
--- /dev/null
+++ b/third_party/elfutils/lib/dynamicsizehash.h
@@ -0,0 +1,127 @@
+/* Copyright (C) 2000-2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+
+/* Before including this file the following macros must be defined:
+
+   NAME      name of the hash table structure.
+   TYPE      data type of the hash table entries
+
+   The following macros if present select features:
+
+   ITERATE   iterating over the table entries is possible
+   HASHTYPE  integer type for hash values, default unsigned long int
+ */
+
+
+/* Optionally include an entry pointing to the first used entry.  */
+#ifdef ITERATE
+# define FIRST(name)	name##_ent *first;
+# define NEXT(name)	struct name##_ent *next;
+#else
+# define FIRST(name)
+# define NEXT(name)
+#endif
+
+#ifndef HASHTYPE
+# define HASHTYPE unsigned long int
+#endif
+
+
+/* Defined separately.  */
+extern size_t next_prime (size_t seed);
+
+
+/* Table entry type.  */
+#define _DYNHASHENTTYPE(name) \
+  typedef struct name##_ent						      \
+  {									      \
+    HASHTYPE hashval;							      \
+    TYPE data;								      \
+    NEXT (name)								      \
+  } name##_ent
+#define DYNHASHENTTYPE(name) _DYNHASHENTTYPE (name)
+DYNHASHENTTYPE (NAME);
+
+
+/* Type of the dynamic hash table data structure.  */
+#define _DYNHASHTYPE(name) \
+typedef struct								      \
+{									      \
+  size_t size;								      \
+  size_t filled;							      \
+  name##_ent *table;							      \
+  FIRST	(name)								      \
+} name
+#define DYNHASHTYPE(name) _DYNHASHTYPE (name)
+DYNHASHTYPE (NAME);
+
+
+
+#define _FUNCTIONS(name) \
+/* Initialize the hash table.  */					      \
+extern int name##_init (name *htab, size_t init_size);			      \
+									      \
+/* Free resources allocated for hash table.  */				      \
+extern int name##_free (name *htab);					      \
+									      \
+/* Insert new entry.  */						      \
+extern int name##_insert (name *htab, HASHTYPE hval, TYPE data);	      \
+									      \
+/* Insert new entry, possibly overwrite old entry.  */			      \
+extern int name##_overwrite (name *htab, HASHTYPE hval, TYPE data);	      \
+									      \
+/* Find entry in hash table.  */					      \
+extern TYPE name##_find (name *htab, HASHTYPE hval, TYPE val);
+#define FUNCTIONS(name) _FUNCTIONS (name)
+FUNCTIONS (NAME)
+
+
+#ifdef ITERATE
+# define _XFUNCTIONS(name) \
+/* Get next element in table.  */					      \
+extern TYPE name##_iterate (name *htab, void **ptr);
+# define XFUNCTIONS(name) _XFUNCTIONS (name)
+XFUNCTIONS (NAME)
+#endif
+
+#ifndef NO_UNDEF
+# undef DYNHASHENTTYPE
+# undef DYNHASHTYPE
+# undef FUNCTIONS
+# undef _FUNCTIONS
+# undef XFUNCTIONS
+# undef _XFUNCTIONS
+# undef NAME
+# undef TYPE
+# undef ITERATE
+# undef COMPARE
+# undef FIRST
+# undef NEXT
+#endif
diff --git a/third_party/elfutils/lib/eu-config.h b/third_party/elfutils/lib/eu-config.h
new file mode 100644
index 0000000..84b22d7
--- /dev/null
+++ b/third_party/elfutils/lib/eu-config.h
@@ -0,0 +1,209 @@
+/* Configuration definitions.
+   Copyright (C) 2008, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef EU_CONFIG_H
+#define EU_CONFIG_H	1
+
+#ifdef USE_LOCKS
+# include <pthread.h>
+# include <assert.h>
+# define rwlock_define(class,name)	class pthread_rwlock_t name
+# define RWLOCK_CALL(call)		\
+  ({ int _err = pthread_rwlock_ ## call; assert_perror (_err); })
+# define rwlock_init(lock)		RWLOCK_CALL (init (&lock, NULL))
+# define rwlock_fini(lock)		RWLOCK_CALL (destroy (&lock))
+# define rwlock_rdlock(lock)		RWLOCK_CALL (rdlock (&lock))
+# define rwlock_wrlock(lock)		RWLOCK_CALL (wrlock (&lock))
+# define rwlock_unlock(lock)		RWLOCK_CALL (unlock (&lock))
+#else
+/* Eventually we will allow multi-threaded applications to use the
+   libraries.  Therefore we will add the necessary locking although
+   the macros used expand to nothing for now.  */
+# define rwlock_define(class,name) class int name
+# define rwlock_init(lock) ((void) (lock))
+# define rwlock_fini(lock) ((void) (lock))
+# define rwlock_rdlock(lock) ((void) (lock))
+# define rwlock_wrlock(lock) ((void) (lock))
+# define rwlock_unlock(lock) ((void) (lock))
+#endif	/* USE_LOCKS */
+
+/* gettext helper macro.  */
+#define N_(Str) Str
+
+/* Compiler-specific definitions.  */
+#define strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+
+#ifdef __i386__
+# define internal_function __attribute__ ((regparm (3), stdcall))
+#else
+# define internal_function /* nothing */
+#endif
+
+#define internal_strong_alias(name, aliasname) \
+  extern __typeof (name) aliasname __attribute__ ((alias (#name))) internal_function;
+
+#ifdef HAVE_VISIBILITY
+#define attribute_hidden \
+  __attribute__ ((visibility ("hidden")))
+#else
+#define attribute_hidden /* empty */
+#endif
+
+#ifdef HAVE_GCC_STRUCT
+#define attribute_packed \
+  __attribute__ ((packed, gcc_struct))
+#else
+#define attribute_packed \
+  __attribute__ ((packed))
+#endif
+
+/* Define ALLOW_UNALIGNED if the architecture allows operations on
+   unaligned memory locations.  */
+#define SANITIZE_UNDEFINED 1
+#if (defined __i386__ || defined __x86_64__) && ! CHECK_UNDEFINED
+# define ALLOW_UNALIGNED	1
+#else
+# define ALLOW_UNALIGNED	0
+#endif
+
+#if DEBUGPRED
+# ifdef __x86_64__
+asm (".section predict_data, \"aw\"; .previous\n"
+     ".section predict_line, \"a\"; .previous\n"
+     ".section predict_file, \"a\"; .previous");
+#  ifndef PIC
+#   define debugpred__(e, E) \
+  ({ long int _e = !!(e); \
+     asm volatile (".pushsection predict_data; ..predictcnt%=: .quad 0; .quad 0\n" \
+                   ".section predict_line; .quad %c1\n" \
+                   ".section predict_file; .quad %c2; .popsection\n" \
+                   "addq $1,..predictcnt%=(,%0,8)" \
+                   : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \
+    __builtin_expect (_e, E); \
+  })
+#  endif
+# elif defined __i386__
+asm (".section predict_data, \"aw\"; .previous\n"
+     ".section predict_line, \"a\"; .previous\n"
+     ".section predict_file, \"a\"; .previous");
+#  ifndef PIC
+#   define debugpred__(e, E) \
+  ({ long int _e = !!(e); \
+     asm volatile (".pushsection predict_data; ..predictcnt%=: .long 0; .long 0\n" \
+                   ".section predict_line; .long %c1\n" \
+                   ".section predict_file; .long %c2; .popsection\n" \
+                   "incl ..predictcnt%=(,%0,8)" \
+                   : : "r" (_e == E), "i" (__LINE__), "i" (__FILE__)); \
+    __builtin_expect (_e, E); \
+  })
+#  endif
+# endif
+# ifdef debugpred__
+#  define unlikely(e) debugpred__ (e,0)
+#  define likely(e) debugpred__ (e,1)
+# endif
+#endif
+#ifndef likely
+# define unlikely(expr) __builtin_expect (!!(expr), 0)
+# define likely(expr) __builtin_expect (!!(expr), 1)
+#endif
+
+#define obstack_calloc(ob, size) \
+  ({ size_t _s = (size); memset (obstack_alloc (ob, _s), '\0', _s); })
+#define obstack_strdup(ob, str) \
+  ({ const char *_s = (str); obstack_copy0 (ob, _s, strlen (_s)); })
+#define obstack_strndup(ob, str, n) \
+  ({ const char *_s = (str); obstack_copy0 (ob, _s, strnlen (_s, n)); })
+
+#if __STDC_VERSION__ >= 199901L
+# define flexarr_size /* empty */
+#else
+# define flexarr_size 0
+#endif
+
+/* Calling conventions.  */
+#ifdef __i386__
+# define CALLING_CONVENTION regparm (3), stdcall
+# define AND_CALLING_CONVENTION , regparm (3), stdcall
+#else
+# define CALLING_CONVENTION
+# define AND_CALLING_CONVENTION
+#endif
+
+/* Avoid PLT entries.  */
+#ifdef PIC
+# define INTUSE(name) _INTUSE(name)
+# define _INTUSE(name) __##name##_internal
+# define INTDEF(name) _INTDEF(name)
+# define _INTDEF(name) \
+  extern __typeof__ (name) __##name##_internal __attribute__ ((alias (#name)));
+# define INTDECL(name) _INTDECL(name)
+# define _INTDECL(name) \
+  extern __typeof__ (name) __##name##_internal attribute_hidden;
+#else
+# define INTUSE(name) name
+# define INTDEF(name) /* empty */
+# define INTDECL(name) /* empty */
+#endif
+
+/* This macro is used by the tests conditionalize for standalone building.  */
+#define ELFUTILS_HEADER(name) <lib##name.h>
+
+
+#ifdef SYMBOL_VERSIONING
+# define OLD_VERSION(name, version) \
+  asm (".globl _compat." #version "." #name "\n" \
+       "_compat." #version "." #name " = " #name "\n" \
+       ".symver _compat." #version "." #name "," #name "@" #version);
+# define NEW_VERSION(name, version) \
+  asm (".symver " #name "," #name "@@@" #version);
+# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
+  asm (".symver _compat." #version "." #name "," #name "@" #version); \
+  __typeof (_compat_##prefix##_##name) _compat_##prefix##_##name \
+    asm ("_compat." #version "." #name);
+# define COMPAT_VERSION(name, version, prefix) \
+  asm (".symver _compat." #version "." #name "," #name "@" #version); \
+  __typeof (name) _compat_##prefix##_##name asm ("_compat." #version "." #name);
+#else
+# define OLD_VERSION(name, version) /* Nothing for static linking.  */
+# define NEW_VERSION(name, version) /* Nothing for static linking.  */
+# define COMPAT_VERSION_NEWPROTO(name, version, prefix) \
+  error "should use #ifdef SYMBOL_VERSIONING"
+# define COMPAT_VERSION(name, version, prefix) error "should use #ifdef SYMBOL_VERSIONING"
+#endif
+
+#ifndef FALLTHROUGH
+# ifdef HAVE_FALLTHROUGH
+#  define FALLTHROUGH __attribute__ ((fallthrough))
+# else
+#  define FALLTHROUGH ((void) 0)
+# endif
+#endif
+
+#endif	/* eu-config.h */
diff --git a/third_party/elfutils/lib/fixedsizehash.h b/third_party/elfutils/lib/fixedsizehash.h
new file mode 100644
index 0000000..dac2a5f
--- /dev/null
+++ b/third_party/elfutils/lib/fixedsizehash.h
@@ -0,0 +1,272 @@
+/* Fixed size hash table with internal linking.
+   Copyright (C) 2000, 2001, 2002, 2004, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/cdefs.h>
+
+#include <system.h>
+
+#ifdef __CONCAT
+#define CONCAT(t1,t2) __CONCAT (t1,t2)
+#else
+#define STROF(t2) t2
+#define CONCAT_EXPANDED(t1,t2) t1 ## t2
+#define CONCAT(t1,t2) CONCAT_EXPANDED(t1,t2)
+#endif
+
+/* Before including this file the following macros must be defined:
+
+   TYPE           data type of the hash table entries
+   HASHFCT        name of the hashing function to use
+   HASHTYPE       type used for the hashing value
+   COMPARE        comparison function taking two pointers to TYPE objects
+   CLASS          can be defined to `static' to avoid exporting the functions
+   PREFIX         prefix to be used for function and data type names
+   STORE_POINTER  if defined the table stores a pointer and not an element
+                  of type TYPE
+   INSERT_HASH    if defined alternate insert function which takes a hash
+                  value is defined
+   NO_FINI_FCT    if defined the fini function is not defined
+*/
+
+
+/* Defined separately.  */
+extern size_t next_prime (size_t seed);
+
+
+/* Set default values.  */
+#ifndef HASHTYPE
+# define HASHTYPE size_t
+#endif
+
+#ifndef CLASS
+# define CLASS
+#endif
+
+#ifndef PREFIX
+# define PREFIX
+#endif
+
+
+/* The data structure.  */
+struct CONCAT(PREFIX,fshash)
+{
+  size_t nslots;
+  struct CONCAT(PREFIX,fshashent)
+  {
+    HASHTYPE hval;
+#ifdef STORE_POINTER
+# define ENTRYP(el) (el).entry
+    TYPE *entry;
+#else
+# define ENTRYP(el) &(el).entry
+    TYPE entry;
+#endif
+  } table[0];
+};
+
+
+/* Constructor for the hashing table.  */
+CLASS struct CONCAT(PREFIX,fshash) *
+CONCAT(PREFIX,fshash_init) (size_t nelems)
+{
+  struct CONCAT(PREFIX,fshash) *result;
+  /* We choose a size for the hashing table 150% over the number of
+     entries.  This will guarantee short medium search lengths.  */
+  const size_t max_size_t = ~((size_t) 0);
+
+  if (nelems >= (max_size_t / 3) * 2)
+    {
+      errno = EINVAL;
+      return NULL;
+    }
+
+  /* Adjust the size to be used for the hashing table.  */
+  nelems = next_prime (MAX ((nelems * 3) / 2, 10));
+
+  /* Allocate the data structure for the result.  */
+  result = (struct CONCAT(PREFIX,fshash) *)
+    xcalloc (sizeof (struct CONCAT(PREFIX,fshash))
+	     + (nelems + 1) * sizeof (struct CONCAT(PREFIX,fshashent)), 1);
+  if (result == NULL)
+    return NULL;
+
+  result->nslots = nelems;
+
+  return result;
+}
+
+
+#ifndef NO_FINI_FCT
+CLASS void
+CONCAT(PREFIX,fshash_fini) (struct CONCAT(PREFIX,fshash) *htab)
+{
+  free (htab);
+}
+#endif
+
+
+static struct CONCAT(PREFIX,fshashent) *
+CONCAT(PREFIX,fshash_lookup) (struct CONCAT(PREFIX,fshash) *htab,
+			      HASHTYPE hval, TYPE *data)
+{
+  size_t idx = 1 + hval % htab->nslots;
+
+  if (htab->table[idx].hval != 0)
+    {
+      HASHTYPE hash;
+
+      /* See whether this is the same entry.  */
+      if (htab->table[idx].hval == hval
+	  && COMPARE (data, ENTRYP (htab->table[idx])) == 0)
+	return &htab->table[idx];
+
+      /* Second hash function as suggested in [Knuth].  */
+      hash = 1 + hval % (htab->nslots - 2);
+
+      do
+	{
+	  if (idx <= hash)
+	    idx = htab->nslots + idx - hash;
+	  else
+	    idx -= hash;
+
+	  if (htab->table[idx].hval == hval
+	      && COMPARE (data, ENTRYP(htab->table[idx])) == 0)
+	    return &htab->table[idx];
+	}
+      while (htab->table[idx].hval != 0);
+    }
+
+  return &htab->table[idx];
+}
+
+
+CLASS int
+__attribute__ ((unused))
+CONCAT(PREFIX,fshash_insert) (struct CONCAT(PREFIX,fshash) *htab,
+			      const char *str,
+			      size_t len __attribute__ ((unused)), TYPE *data)
+{
+  HASHTYPE hval = HASHFCT (str, len ?: strlen (str));
+  struct CONCAT(PREFIX,fshashent) *slot;
+
+  slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data);
+ if (slot->hval != 0)
+    /* We don't want to overwrite the old value.  */
+    return -1;
+
+  slot->hval = hval;
+#ifdef STORE_POINTER
+  slot->entry = data;
+#else
+  slot->entry = *data;
+#endif
+
+  return 0;
+}
+
+
+#ifdef INSERT_HASH
+CLASS int
+__attribute__ ((unused))
+CONCAT(PREFIX,fshash_insert_hash) (struct CONCAT(PREFIX,fshash) *htab,
+				   HASHTYPE hval, TYPE *data)
+{
+  struct CONCAT(PREFIX,fshashent) *slot;
+
+  slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data);
+  if (slot->hval != 0)
+    /* We don't want to overwrite the old value.  */
+    return -1;
+
+  slot->hval = hval;
+#ifdef STORE_POINTER
+  slot->entry = data;
+#else
+  slot->entry = *data;
+#endif
+
+  return 0;
+}
+#endif
+
+
+CLASS int
+__attribute__ ((unused))
+CONCAT(PREFIX,fshash_overwrite) (struct CONCAT(PREFIX,fshash) *htab,
+				 const char *str,
+				 size_t len __attribute__ ((unused)),
+				 TYPE *data)
+{
+  HASHTYPE hval = HASHFCT (str, len ?: strlen (str));
+  struct CONCAT(PREFIX,fshashent) *slot;
+
+  slot = CONCAT(PREFIX,fshash_lookup) (htab, hval, data);
+  slot->hval = hval;
+#ifdef STORE_POINTER
+  slot->entry = data;
+#else
+  slot->entry = *data;
+#endif
+
+  return 0;
+}
+
+
+CLASS const TYPE *
+CONCAT(PREFIX,fshash_find) (const struct CONCAT(PREFIX,fshash) *htab,
+			    const char *str,
+			    size_t len __attribute__ ((unused)), TYPE *data)
+{
+  HASHTYPE hval = HASHFCT (str, len ?: strlen (str));
+  struct CONCAT(PREFIX,fshashent) *slot;
+
+  slot = CONCAT(PREFIX,fshash_lookup) ((struct CONCAT(PREFIX,fshash) *) htab,
+				       hval, data);
+  if (slot->hval == 0)
+    /* Not found.  */
+    return NULL;
+
+  return ENTRYP(*slot);
+}
+
+
+/* Unset the macros we expect.  */
+#undef TYPE
+#undef HASHFCT
+#undef HASHTYPE
+#undef COMPARE
+#undef CLASS
+#undef PREFIX
+#undef INSERT_HASH
+#undef STORE_POINTER
+#undef NO_FINI_FCT
diff --git a/third_party/elfutils/lib/libeu.h b/third_party/elfutils/lib/libeu.h
new file mode 100644
index 0000000..ecb4d01
--- /dev/null
+++ b/third_party/elfutils/lib/libeu.h
@@ -0,0 +1,46 @@
+/* Declarations for the common library.
+   Copyright (C) 2006-2011 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef LIBEU_H
+#define LIBEU_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+extern void *xmalloc (size_t) __attribute__ ((__malloc__));
+extern void *xcalloc (size_t, size_t) __attribute__ ((__malloc__));
+extern void *xrealloc (void *, size_t) __attribute__ ((__malloc__));
+
+extern char *xstrdup (const char *) __attribute__ ((__malloc__));
+extern char *xstrndup (const char *, size_t) __attribute__ ((__malloc__));
+
+
+extern uint32_t crc32 (uint32_t crc, unsigned char *buf, size_t len);
+extern int crc32_file (int fd, uint32_t *resp);
+
+#endif
diff --git a/third_party/elfutils/lib/list.h b/third_party/elfutils/lib/list.h
new file mode 100644
index 0000000..fc5c73c
--- /dev/null
+++ b/third_party/elfutils/lib/list.h
@@ -0,0 +1,100 @@
+/* Copyright (C) 2001, 2002, 2003 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef LIST_H
+#define LIST_H	1
+
+/* Add element to the end of a circular, double-linked list.  */
+#define CDBL_LIST_ADD_REAR(first, newp) \
+  do {									      \
+    __typeof (newp) _newp = (newp);					      \
+    assert (_newp->next == NULL);					      \
+    assert (_newp->previous == NULL);					      \
+    if (unlikely ((first) == NULL))					      \
+      (first) = _newp->next = _newp->previous = _newp;			      \
+    else								      \
+      {									      \
+	_newp->next = (first);						      \
+	_newp->previous = (first)->previous;				      \
+	_newp->previous->next = _newp->next->previous = _newp;		      \
+      }									      \
+  } while (0)
+
+/* Remove element from circular, double-linked list.  */
+#define CDBL_LIST_DEL(first, elem) \
+  do {									      \
+    __typeof (elem) _elem = (elem);					      \
+    /* Check whether the element is indeed on the list.  */		      \
+    assert (first != NULL && _elem != NULL				      \
+	    && (first != elem						      \
+		|| ({ __typeof (elem) _runp = first->next;		      \
+		      while (_runp != first)				      \
+			if (_runp == _elem)				      \
+			  break;					      \
+			else						      \
+		          _runp = _runp->next;				      \
+		      _runp == _elem; })));				      \
+    if (unlikely (_elem->next == _elem))				      \
+      first = NULL;							      \
+    else								      \
+      {									      \
+	_elem->next->previous = _elem->previous;			      \
+	_elem->previous->next = _elem->next;				      \
+	if (unlikely (first == _elem))					      \
+	  first = _elem->next;						      \
+      }									      \
+     assert ((_elem->next = _elem->previous = NULL, 1));		      \
+  } while (0)
+
+
+/* Add element to the front of a single-linked list.  */
+#define SNGL_LIST_PUSH(first, newp) \
+  do {									      \
+    __typeof (newp) _newp = (newp);					      \
+    assert (_newp->next == NULL);					      \
+    _newp->next = first;						      \
+    first = _newp;							      \
+  } while (0)
+
+
+/* Add element to the rear of a circular single-linked list.  */
+#define CSNGL_LIST_ADD_REAR(first, newp) \
+  do {									      \
+    __typeof (newp) _newp = (newp);					      \
+    assert (_newp->next == NULL);					      \
+    if (unlikely ((first) == NULL))					      \
+      (first) = _newp->next = _newp;					      \
+    else								      \
+      {									      \
+	_newp->next = (first)->next;					      \
+	(first) = (first)->next = _newp;				      \
+      }									      \
+  } while (0)
+
+
+#endif	/* list.h */
diff --git a/third_party/elfutils/lib/next_prime.c b/third_party/elfutils/lib/next_prime.c
new file mode 100644
index 0000000..f2c921e
--- /dev/null
+++ b/third_party/elfutils/lib/next_prime.c
@@ -0,0 +1,66 @@
+/* Determine prime number.
+   Copyright (C) 2006 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+
+
+/* Test whether CANDIDATE is a prime.  */
+static int
+is_prime (size_t candidate)
+{
+  /* No even number and none less than 10 will be passed here.  */
+  size_t divn = 3;
+  size_t sq = divn * divn;
+
+  while (sq < candidate && candidate % divn != 0)
+    {
+      size_t old_sq = sq;
+      ++divn;
+      sq += 4 * divn;
+      if (sq < old_sq)
+	return 1;
+      ++divn;
+    }
+
+  return candidate % divn != 0;
+}
+
+
+/* We need primes for the table size.  */
+size_t
+next_prime (size_t seed)
+{
+  /* Make it definitely odd.  */
+  seed |= 1;
+
+  while (!is_prime (seed))
+    seed += 2;
+
+  return seed;
+}
diff --git a/third_party/elfutils/lib/printversion.c b/third_party/elfutils/lib/printversion.c
new file mode 100644
index 0000000..263c106
--- /dev/null
+++ b/third_party/elfutils/lib/printversion.c
@@ -0,0 +1,45 @@
+/* Common argp_print_version_hook for all tools.
+   Copyright (C) 2016, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libintl.h>
+#include "printversion.h"
+
+void
+print_version (FILE *stream, struct argp_state *state)
+{
+  fprintf (stream, "%s (%s) %s\n", state->name, PACKAGE_NAME, PACKAGE_VERSION);
+  fprintf (stream, gettext ("\
+Copyright (C) %s The elfutils developers <%s>.\n\
+This is free software; see the source for copying conditions.  There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"), "2017", PACKAGE_URL);
+}
diff --git a/third_party/elfutils/lib/printversion.h b/third_party/elfutils/lib/printversion.h
new file mode 100644
index 0000000..a9e059f
--- /dev/null
+++ b/third_party/elfutils/lib/printversion.h
@@ -0,0 +1,49 @@
+/* Common argp_print_version_hook for all tools.
+   Copyright (C) 2017 The Qt Company Ltd.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef PRINTVERSION_H
+#define PRINTVERSION_H 1
+
+#include <argp.h>
+#include <stdio.h>
+
+/* Defined in version.c.  Common ARGP_PROGRAM_VERSION_HOOK_DEF.  */
+void print_version (FILE *stream, struct argp_state *state);
+
+/* We need define two variables, argp_program_version_hook and
+   argp_program_bug_address, in all programs.  argp.h declares these
+   variables as non-const (which is correct in general).  But we can
+   do better, it is not going to change.  So we want to move them into
+   the .rodata section.  Define macros to do the trick.  */
+#define ARGP_PROGRAM_VERSION_HOOK_DEF \
+  void (*const apvh) (FILE *, struct argp_state *) \
+   __asm ("argp_program_version_hook")
+#define ARGP_PROGRAM_BUG_ADDRESS_DEF \
+  const char *const apba__ __asm ("argp_program_bug_address")
+
+#endif // PRINTVERSION_H
diff --git a/third_party/elfutils/lib/system.h b/third_party/elfutils/lib/system.h
new file mode 100644
index 0000000..9203335
--- /dev/null
+++ b/third_party/elfutils/lib/system.h
@@ -0,0 +1,154 @@
+/* Declarations for common convenience functions.
+   Copyright (C) 2006-2011 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef LIB_SYSTEM_H
+#define LIB_SYSTEM_H	1
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/param.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <unistd.h>
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define LE32(n)	(n)
+# define LE64(n)	(n)
+# define BE32(n)	bswap_32 (n)
+# define BE64(n)	bswap_64 (n)
+#elif __BYTE_ORDER == __BIG_ENDIAN
+# define BE32(n)	(n)
+# define BE64(n)	(n)
+# define LE32(n)	bswap_32 (n)
+# define LE64(n)	bswap_64 (n)
+#else
+# error "Unknown byte order"
+#endif
+
+#ifndef MAX
+#define MAX(m, n) ((m) < (n) ? (n) : (m))
+#endif
+
+#ifndef MIN
+#define MIN(m, n) ((m) < (n) ? (m) : (n))
+#endif
+
+#if !HAVE_DECL_POWEROF2
+#define powerof2(x) (((x) & ((x) - 1)) == 0)
+#endif
+
+#if !HAVE_DECL_MEMPCPY
+#define mempcpy(dest, src, n) \
+    ((void *) ((char *) memcpy (dest, src, n) + (size_t) n))
+#endif
+
+/* A special gettext function we use if the strings are too short.  */
+#define sgettext(Str) \
+  ({ const char *__res = strrchr (gettext (Str), '|');			      \
+     __res ? __res + 1 : Str; })
+
+#define gettext_noop(Str) Str
+
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(expression) \
+  ({ ssize_t __res; \
+     do \
+       __res = expression; \
+     while (__res == -1 && errno == EINTR); \
+     __res; })
+#endif
+
+static inline ssize_t __attribute__ ((unused))
+pwrite_retry (int fd, const void *buf, size_t len, off_t off)
+{
+  ssize_t recvd = 0;
+
+  do
+    {
+      ssize_t ret = TEMP_FAILURE_RETRY (pwrite (fd, buf + recvd, len - recvd,
+						off + recvd));
+      if (ret <= 0)
+	return ret < 0 ? ret : recvd;
+
+      recvd += ret;
+    }
+  while ((size_t) recvd < len);
+
+  return recvd;
+}
+
+static inline ssize_t __attribute__ ((unused))
+write_retry (int fd, const void *buf, size_t len)
+{
+  ssize_t recvd = 0;
+
+  do
+    {
+      ssize_t ret = TEMP_FAILURE_RETRY (write (fd, buf + recvd, len - recvd));
+      if (ret <= 0)
+	return ret < 0 ? ret : recvd;
+
+      recvd += ret;
+    }
+  while ((size_t) recvd < len);
+
+  return recvd;
+}
+
+static inline ssize_t __attribute__ ((unused))
+pread_retry (int fd, void *buf, size_t len, off_t off)
+{
+  ssize_t recvd = 0;
+
+  do
+    {
+      ssize_t ret = TEMP_FAILURE_RETRY (pread (fd, buf + recvd, len - recvd,
+					       off + recvd));
+      if (ret <= 0)
+	return ret < 0 ? ret : recvd;
+
+      recvd += ret;
+    }
+  while ((size_t) recvd < len);
+
+  return recvd;
+}
+
+/* The demangler from libstdc++.  */
+extern char *__cxa_demangle (const char *mangled_name, char *output_buffer,
+			     size_t *length, int *status);
+
+/* A static assertion.  This will cause a compile-time error if EXPR,
+   which must be a compile-time constant, is false.  */
+
+#define eu_static_assert(expr)						\
+  extern int never_defined_just_used_for_checking[(expr) ? 1 : -1]	\
+    __attribute__ ((unused))
+
+#endif /* system.h */
diff --git a/third_party/elfutils/lib/xmalloc.c b/third_party/elfutils/lib/xmalloc.c
new file mode 100644
index 0000000..0cde384
--- /dev/null
+++ b/third_party/elfutils/lib/xmalloc.c
@@ -0,0 +1,80 @@
+/* Convenience functions for allocation.
+   Copyright (C) 2006, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <error.h>
+#include <libintl.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include "system.h"
+
+#ifndef _
+# define _(str) gettext (str)
+#endif
+
+
+/* Allocate N bytes of memory dynamically, with error checking.  */
+void *
+xmalloc (size_t n)
+{
+  void *p;
+
+  p = malloc (n);
+  if (p == NULL)
+    error (EXIT_FAILURE, 0, _("memory exhausted"));
+  return p;
+}
+
+
+/* Allocate memory for N elements of S bytes, with error checking.  */
+void *
+xcalloc (size_t n, size_t s)
+{
+  void *p;
+
+  p = calloc (n, s);
+  if (p == NULL)
+    error (EXIT_FAILURE, 0, _("memory exhausted"));
+  return p;
+}
+
+
+/* Change the size of an allocated block of memory P to N bytes,
+   with error checking.  */
+void *
+xrealloc (void *p, size_t n)
+{
+  p = realloc (p, n);
+  if (p == NULL)
+    error (EXIT_FAILURE, 0, _("memory exhausted"));
+  return p;
+}
diff --git a/third_party/elfutils/lib/xstrdup.c b/third_party/elfutils/lib/xstrdup.c
new file mode 100644
index 0000000..ff1e3d4
--- /dev/null
+++ b/third_party/elfutils/lib/xstrdup.c
@@ -0,0 +1,42 @@
+/* Convenience function for string allocation.
+   Copyright (C) 2006, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libeu.h"
+
+
+/* Return a newly allocated copy of STRING.  */
+char *
+xstrdup (const char *string)
+{
+  return strcpy (xmalloc (strlen (string) + 1), string);
+}
diff --git a/third_party/elfutils/lib/xstrndup.c b/third_party/elfutils/lib/xstrndup.c
new file mode 100644
index 0000000..a257aa9
--- /dev/null
+++ b/third_party/elfutils/lib/xstrndup.c
@@ -0,0 +1,46 @@
+/* Convenience function for string allocation.
+   Copyright (C) 2006, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdint.h>
+#include <string.h>
+#include "libeu.h"
+#include "system.h"
+
+/* Return a newly allocated copy of STRING.  */
+char *
+xstrndup (const char *string, size_t n)
+{
+  char *res;
+  size_t len = strnlen (string, n);
+  *((char *) mempcpy ((res = xmalloc (len + 1)), string, len)) = '\0';
+  return res;
+}
diff --git a/third_party/elfutils/libasm/ChangeLog b/third_party/elfutils/libasm/ChangeLog
new file mode 100644
index 0000000..fffcced
--- /dev/null
+++ b/third_party/elfutils/libasm/ChangeLog
@@ -0,0 +1,220 @@
+2017-02-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use dso_LDFLAGS.
+
+2017-02-17  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Add libasm_so_DEPS to specify external libraries
+	that have to be linked in, and libasm_so_LIBS to specify the
+	archives libasm consists of. The dependencies include libeu.a.
+	(libasm_so_LDLIBS): Add $(libasm_so_DEPS).
+	(libasm_so$(EXEEXT): Use $(libasm_so_LIBS),
+	add --no-undefined,-z,defs,-z,relro,
+	drop the manual enumeration of dependencies,
+	specify the correct path for libasm.map.
+
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* asm_end.c (binary_end): Fix nesting of braces.
+
+2017-02-12  Mark Wielaard  <mjw@redhat.com>
+
+	* asm_newsym.c (asm_newsym): Increase TEMPSYMLEN to 13.
+
+2017-02-15  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* disasm_str.c: Include system.h.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* asm_align.c: Remove sys/param.h include.
+
+2016-07-08  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (AM_CPPFLAGS): Add libdwelf.
+	(libasm.so): Add libdw.
+	* asm_begin.c (prepare_binary_output): Use dwelf_strtab instead of
+	ebl_strtab.
+	* asm_end.c (binary_end): Likewise.
+	(__libasm_finictx): Likewise.
+	* asm_newabssym.c (asm_newabssym):  Likewise.
+	* asm_newcomsym.c (asm_newcomsym): Likewise.
+	* asm_newscn.c (binary_newscn): Likewise.
+	* asm_newscngrp.c (asm_newscngrp): Likewise.
+	* asm_newsym.c (asm_newsym): Likewise.
+	* libasmP.h: Likewise.
+	* symbolhash.c (COMPARE): Likewise.
+	* symbolhash.h (COMPARE): Likewise.
+
+2016-06-28  Richard Henderson <rth@redhat.com>
+
+	* disasm_cb.c (disasm_cb): Pass ebl to disasm hook.
+
+2016-02-12  Mark Wielaard  <mjw@redhat.com>
+
+	* asm_begin.c (prepare_text_output): Only call __fsetlocking when
+	result isn't NULL.
+
+2015-10-05  Josh Stone  <jistone@redhat.com>
+
+	* Makefile.am (libasm.so): Add AM_V_CCLD and AM_V_at silencers.
+
+2015-09-23  Mark Wielaard  <mjw@redhat.com>
+
+	* asm_align.c (__libasm_ensure_section_space): Mark as
+	internal_function.
+	* asm_end.c (__libasm_finictx): Likewise.
+	* asm_error.c (__libasm_seterrno): Likewise.
+
+2015-09-22  Mark Wielaard  <mjw@redhat.com>
+
+	* asm_*.c: Remove old-style function definitions.
+
+2015-09-04  Chih-Hung Hsieh  <chh@google.com>
+
+	* asm_addint8.c (FCT): Replace K&R function definition
+	with ansi-C definitions.
+	* asm_adduint8.c (UFCT): Likewise.
+	* asm_begin.c (asm_begin): Likewise.
+
+2014-12-18  Ulrich Drepper  <drepper@gmail.com>
+
+	* Makefile.am: Suppress output of textrel_check command.
+
+2014-11-27  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libasm.so): Use textrel_check.
+
+2014-04-13  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Remove !MUDFLAP conditions.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+
+2011-02-08  Roland McGrath  <roland@redhat.com>
+
+	* asm_newscn.c (asm_newscn): Remove unused variable.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Use config/eu.am for common stuff.
+
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Use USE_LOCKS instead of USE_TLS.
+	* asm_error.c: Always use __thread.  Remove all !USE_TLS code.
+
+2008-12-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am [USE_TLS]: Like libasm.so with libpthread.
+
+2008-01-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* libasm.h (DisasmGetSymCB_t): Change type of fourth and fifth
+	parameter.
+	* disasm_cb.c: Adjust accordingly.
+
+2008-01-08  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (euinclude): Variable removed.
+	(pkginclude_HEADERS): Set this instead of euinclude_HEADERS.
+
+2007-12-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* disasm_cb.c: Add initial support to resolve addresses to symbols.
+
+2007-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* disasm_begin.c: New file.
+	* disasm_cb.c: New file.
+	* disasm_end.c: New file.
+	* disasm_str.c: New file.
+
+2006-08-29  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (CLEANFILES): Add libasm.so.$(VERSION).
+
+2005-11-13  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (INCLUDES): Search in libdw.
+
+2005-09-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* asm_error.c (asm_errmsg): Unify error message.
+
+2005-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Use $(LINK) not $(CC) when creating DSO.
+	(%.os): Use COMPILE.os.
+	(COMPILE.os): Filter out gconv options.
+
+2005-08-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add -std=gnu99.
+	* asm_abort.c: Don't try to remove output file if there is none.
+	* asm_addint8.c: In print mode, print to file not stdout.
+	* asm_addsleb128.c: Likewise.
+	* asm_adduleb128.c: Likewise.
+	* asm_newscn.c: Likewise.
+	* asm_align.c: Implement print mode.
+	* asm_begin.c (asm_begin): Change interface.  Take binary class and
+	byte order information from new Ebl parameter.
+	* libasm.h: Adjust prototype.
+	* asm_end.c (text_end): Close file if necesary.
+	* asm_error.c: Add new error ASM_E_IOERROR.
+	* libasmP.h: Add ASM_E_IOERROR definition.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add -Wunused -Wextra -Wformat=2.
+
+	* asm_end.c (text_end): Mark parameter as possibly unused.
+
+2005-02-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Remove lint handling.
+
+2005-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* asm_end.c (binary_end): Don't terminate with error() in case
+	something goes wrong.
+
+	* Makefile.am: Check for text relocations in constructed DSO.
+
+	* Makefile.am (AM_CFLAGS): More warnings.  Add -fmudflap for MUDFLAP.
+
+	* asm_end.c (binary_end): Remove shadowing variables.
+	Little cleanups.
+
+	* asm_newsym.c: Allocate memory for the string parameter.
+
+2005-02-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* asm_newscn_ingrp.c (asm_newscn_ingrp): Use INTUSE to reference
+	asm_newscn.
+
+2004-09-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* asm_error.c: Make compile with gcc 4.0.
+
+2004-01-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support building with mudflap.
+
+2004-01-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* libasmP.h (_): Use elfutils domain.
+
+2004-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support building with mudflap.
+
+2003-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.in: Depend on libebl.a, not libebl.so.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* Moved to CVS archive.
diff --git a/third_party/elfutils/libasm/Makefile.am b/third_party/elfutils/libasm/Makefile.am
new file mode 100644
index 0000000..19fef50
--- /dev/null
+++ b/third_party/elfutils/libasm/Makefile.am
@@ -0,0 +1,90 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 2002-2010 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * 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
+##
+## or both in parallel, as here.
+##
+## elfutils 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.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+AM_CPPFLAGS += -I$(top_srcdir)/libelf -I$(top_srcdir)/libebl -I$(top_srcdir)/libdw -I$(top_srcdir)/libdwelf
+
+GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include)
+VERSION = 1
+
+lib_LIBRARIES = libasm.a
+noinst_LIBRARIES = libasm_pic.a
+noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so)
+pkginclude_HEADERS = libasm.h
+
+libasm_a_SOURCES = asm_begin.c asm_abort.c asm_end.c asm_error.c \
+		   asm_getelf.c asm_newscn.c asm_newscn_ingrp.c \
+		   asm_newsubscn.c asm_newsym.c asm_newcomsym.c \
+		   asm_newabssym.c \
+		   asm_newscngrp.c asm_scngrp_newsignature.c \
+		   asm_fill.c asm_align.c asm_addstrz.c \
+		   asm_addint8.c asm_adduint8.c \
+		   asm_addint16.c asm_adduint16.c \
+		   asm_addint32.c asm_adduint32.c \
+		   asm_addint64.c asm_adduint64.c \
+		   asm_adduleb128.c asm_addsleb128.c \
+		   disasm_begin.c disasm_cb.c disasm_end.c disasm_str.c \
+		   symbolhash.c
+
+libasm_pic_a_SOURCES =
+am_libasm_pic_a_OBJECTS = $(libasm_a_SOURCES:.c=.os)
+
+libasm_so_DEPS = ../lib/libeu.a ../libebl/libebl.a ../libelf/libelf.so ../libdw/libdw.so
+libasm_so_LDLIBS = $(libasm_so_DEPS)
+if USE_LOCKS
+libasm_so_LDLIBS += -lpthread
+endif
+
+libasm_so_LIBS = libasm_pic.a
+libasm_so_SOURCES =
+libasm.so$(EXEEXT): $(srcdir)/libasm.map $(libasm_so_LIBS) $(libasm_so_DEPS)
+	$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
+		-Wl,--soname,$@.$(VERSION) \
+		-Wl,--version-script,$<,--no-undefined \
+		-Wl,--whole-archive $(libasm_so_LIBS) -Wl,--no-whole-archive \
+		$(libasm_so_LDLIBS)
+	@$(textrel_check)
+	$(AM_V_at)ln -fs $@ $@.$(VERSION)
+
+install: install-am libasm.so
+	$(mkinstalldirs) $(DESTDIR)$(libdir)
+	$(INSTALL_PROGRAM) libasm.so $(DESTDIR)$(libdir)/libasm-$(PACKAGE_VERSION).so
+	ln -fs libasm-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libasm.so.$(VERSION)
+	ln -fs libasm.so.$(VERSION) $(DESTDIR)$(libdir)/libasm.so
+
+uninstall: uninstall-am
+	rm -f $(DESTDIR)$(libdir)/libasm-$(PACKAGE_VERSION).so
+	rm -f $(DESTDIR)$(libdir)/libasm.so.$(VERSION)
+	rm -f $(DESTDIR)$(libdir)/libasm.so
+	rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
+
+noinst_HEADERS = libasmP.h symbolhash.h
+EXTRA_DIST = libasm.map
+
+CLEANFILES += $(am_libasm_pic_a_OBJECTS) libasm.so.$(VERSION)
diff --git a/third_party/elfutils/libasm/asm_abort.c b/third_party/elfutils/libasm/asm_abort.c
new file mode 100644
index 0000000..12743dc
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_abort.c
@@ -0,0 +1,60 @@
+/* Abort operations on the assembler context, free all resources.
+   Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <libasmP.h>
+#include <libelf.h>
+
+
+int
+asm_abort (AsmCtx_t *ctx)
+{
+  if (ctx == NULL)
+    /* Something went wrong earlier.  */
+    return -1;
+
+  if (likely (! ctx->textp))
+    /* First free the ELF file.  We don't care about the result.  */
+    (void) elf_end (ctx->out.elf);
+
+  /* Now close the temporary file and remove it.  */
+  if (ctx->fd != -1)
+    (void) unlink (ctx->tmp_fname);
+
+  /* Free the resources.  */
+  __libasm_finictx (ctx);
+
+  return 0;
+}
diff --git a/third_party/elfutils/libasm/asm_addint16.c b/third_party/elfutils/libasm/asm_addint16.c
new file mode 100644
index 0000000..4ae4597
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_addint16.c
@@ -0,0 +1,32 @@
+/* Add integer to a section.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define SIZE 16
+
+#include "asm_addint8.c"
diff --git a/third_party/elfutils/libasm/asm_addint32.c b/third_party/elfutils/libasm/asm_addint32.c
new file mode 100644
index 0000000..776cf6f
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_addint32.c
@@ -0,0 +1,32 @@
+/* Add integer to a section.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define SIZE 32
+
+#include "asm_addint8.c"
diff --git a/third_party/elfutils/libasm/asm_addint64.c b/third_party/elfutils/libasm/asm_addint64.c
new file mode 100644
index 0000000..ee33834
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_addint64.c
@@ -0,0 +1,32 @@
+/* Add integer to a section.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define SIZE 64
+
+#include "asm_addint8.c"
diff --git a/third_party/elfutils/libasm/asm_addint8.c b/third_party/elfutils/libasm/asm_addint8.c
new file mode 100644
index 0000000..bb7d40f
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_addint8.c
@@ -0,0 +1,121 @@
+/* Add integer to a section.
+   Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <byteswap.h>
+#include <endian.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <libasmP.h>
+
+#ifndef SIZE
+# define SIZE 8
+#endif
+
+#define FCT(size) _FCT(size)
+#define _FCT(size) asm_addint##size
+#define TYPE(size) _TYPE(size)
+#define _TYPE(size) int##size##_t
+#define BSWAP(size) _BSWAP(size)
+#define _BSWAP(size) bswap_##size
+
+
+int
+FCT(SIZE) (AsmScn_t *asmscn, TYPE(SIZE) num)
+{
+  if (asmscn == NULL)
+    return -1;
+
+  if (asmscn->type == SHT_NOBITS && unlikely (num != 0))
+    {
+      __libasm_seterrno (ASM_E_TYPE);
+      return -1;
+    }
+
+  if (unlikely (asmscn->ctx->textp))
+    {
+      // XXX Needs to use backend specified pseudo-ops
+      if (SIZE == 8)
+	fprintf (asmscn->ctx->out.file, "\t.byte\t%" PRId8 "\n", (int8_t) num);
+      else if (SIZE == 16)
+	fprintf (asmscn->ctx->out.file, "\t.value\t%" PRId16 "\n",
+		 (int16_t) num);
+      else if (SIZE == 32)
+	fprintf (asmscn->ctx->out.file, "\t.long\t%" PRId32 "\n",
+		 (int32_t) num);
+      else
+	{
+	  // XXX This is not necessary for 64-bit machines
+	  bool is_leb = (elf_getident (asmscn->ctx->out.elf, NULL)[EI_DATA]
+			 == ELFDATA2LSB);
+
+	  fprintf (asmscn->ctx->out.file,
+		   "\t.long\t%" PRId32 "\n\t.long\t%" PRId32 "\n",
+		   (int32_t) (is_leb
+			      ? num % 0x100000000ll : num / 0x100000000ll),
+		   (int32_t) (is_leb
+			      ? num / 0x100000000ll : num % 0x100000000ll));
+	}
+    }
+  else
+    {
+#if SIZE > 8
+      bool is_leb = (elf_getident (asmscn->ctx->out.elf, NULL)[EI_DATA]
+		     == ELFDATA2LSB);
+#endif
+      TYPE(SIZE) var = num;
+
+      /* Make sure we have enough room.  */
+      if (__libasm_ensure_section_space (asmscn, SIZE / 8) != 0)
+	return -1;
+
+#if SIZE > 8
+      if ((BYTE_ORDER == LITTLE_ENDIAN && !is_leb)
+	  || (BYTE_ORDER == BIG_ENDIAN && is_leb))
+	var = BSWAP(SIZE) (var);
+#endif
+
+      /* Copy the variable value.  */
+      if (likely (asmscn->type == SHT_NOBITS))
+	memcpy (&asmscn->content->data[asmscn->content->len], &var, SIZE / 8);
+
+      /* Adjust the pointer in the data buffer.  */
+      asmscn->content->len += SIZE / 8;
+
+      /* Increment the offset in the (sub)section.  */
+      asmscn->offset += SIZE / 8;
+    }
+
+  return 0;
+}
+INTDEF(FCT(SIZE))
diff --git a/third_party/elfutils/libasm/asm_addsleb128.c b/third_party/elfutils/libasm/asm_addsleb128.c
new file mode 100644
index 0000000..dc62c95
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_addsleb128.c
@@ -0,0 +1,97 @@
+/* Add signed little endian base 128 integer to a section.
+   Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <string.h>
+
+#include <libasmP.h>
+
+
+int
+asm_addsleb128 (AsmScn_t *asmscn, int32_t num)
+{
+  if (asmscn == NULL)
+    return -1;
+
+  if (asmscn->type == SHT_NOBITS && unlikely (num != 0))
+    {
+      __libasm_seterrno (ASM_E_TYPE);
+      return -1;
+    }
+
+  if (unlikely (asmscn->ctx->textp))
+    fprintf (asmscn->ctx->out.file, "\t.sleb128\t%" PRId32 "\n", num);
+  else
+    {
+      char tmpbuf[(sizeof (num) * 8 + 6) / 7];
+      char *dest = tmpbuf;
+      uint32_t byte;
+      int32_t endval = num >> 31;
+
+      if (num == 0)
+	byte = 0;
+      else
+	while (1)
+	  {
+	    byte = num & 0x7f;
+
+	    num >>= 7;
+	    if (num == endval)
+	      /* This is the last byte.  */
+	      break;
+
+	    *dest++ = byte | 0x80;
+	  }
+
+      *dest++ = byte;
+
+      /* Number of bytes produced.  */
+      size_t nbytes = dest - tmpbuf;
+
+      /* Make sure we have enough room.  */
+      if (__libasm_ensure_section_space (asmscn, nbytes) != 0)
+	return -1;
+
+      /* Copy the bytes.  */
+      if (likely (asmscn->type != SHT_NOBITS))
+	memcpy (&asmscn->content->data[asmscn->content->len], tmpbuf, nbytes);
+
+      /* Adjust the pointer in the data buffer.  */
+      asmscn->content->len += nbytes;
+
+      /* Increment the offset in the (sub)section.  */
+      asmscn->offset += nbytes;
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/libasm/asm_addstrz.c b/third_party/elfutils/libasm/asm_addstrz.c
new file mode 100644
index 0000000..26e06bb
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_addstrz.c
@@ -0,0 +1,125 @@
+/* Add string to a section.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libasmP.h>
+
+
+/* Add zero terminated string STR of size LEN to (sub)section ASMSCN.  */
+int
+asm_addstrz (AsmScn_t *asmscn, const char *str, size_t len)
+{
+  if (asmscn == NULL)
+    return -1;
+
+  if (unlikely (asmscn->type == SHT_NOBITS))
+    {
+      if (len == 0)
+	{
+	  if (str[0] != '\0')
+	    {
+	      __libasm_seterrno (ASM_E_TYPE);
+	      return -1;
+	    }
+	}
+      else
+	{
+	  size_t cnt;
+
+	  for (cnt = 0; cnt < len; ++cnt)
+	    if (str[cnt] != '\0')
+	      {
+		__libasm_seterrno (ASM_E_TYPE);
+		return -1;
+	      }
+	}
+    }
+
+  if (len == 0)
+    len = strlen (str) + 1;
+
+  if (unlikely (asmscn->ctx->textp))
+    {
+      bool nextline = true;
+
+      do
+	{
+	  if (nextline)
+	    {
+	      fputs ("\t.string\t\"", asmscn->ctx->out.file);
+	      nextline = false;
+	    }
+
+	  if (*str == '\0')
+	    fputs ("\\000", asmscn->ctx->out.file);
+	  else if (! isascii (*str))
+	    fprintf (asmscn->ctx->out.file, "\\%03o",
+		     (unsigned int) *((unsigned char *)str));
+	  else if (*str == '\\')
+	    fputs ("\\\\", asmscn->ctx->out.file);
+	  else if (*str == '\n')
+	    {
+	      fputs ("\\n\"", asmscn->ctx->out.file);
+	      nextline = true;
+	    }
+	  else
+	    fputc (*str, asmscn->ctx->out.file);
+
+	  ++str;
+	}
+      while (--len > 0 && (len > 1 || *str != '\0'));
+
+      if (! nextline)
+	fputs ("\"\n", asmscn->ctx->out.file);
+    }
+  else
+    {
+      /* Make sure there is enough room.  */
+      if (__libasm_ensure_section_space (asmscn, len) != 0)
+	return -1;
+
+      /* Copy the string.  */
+      memcpy (&asmscn->content->data[asmscn->content->len], str, len);
+
+      /* Adjust the pointer in the data buffer.  */
+      asmscn->content->len += len;
+
+      /* Increment the offset in the (sub)section.  */
+      asmscn->offset += len;
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/libasm/asm_adduint16.c b/third_party/elfutils/libasm/asm_adduint16.c
new file mode 100644
index 0000000..65a1303
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_adduint16.c
@@ -0,0 +1,32 @@
+/* Add unsigned integer to a section.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define SIZE 16
+
+#include "asm_adduint8.c"
diff --git a/third_party/elfutils/libasm/asm_adduint32.c b/third_party/elfutils/libasm/asm_adduint32.c
new file mode 100644
index 0000000..9a3ec6d
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_adduint32.c
@@ -0,0 +1,32 @@
+/* Add unsigned integer to a section.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define SIZE 32
+
+#include "asm_adduint8.c"
diff --git a/third_party/elfutils/libasm/asm_adduint64.c b/third_party/elfutils/libasm/asm_adduint64.c
new file mode 100644
index 0000000..b2c57a4
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_adduint64.c
@@ -0,0 +1,32 @@
+/* Add unsigned integer to a section.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define SIZE 64
+
+#include "asm_adduint8.c"
diff --git a/third_party/elfutils/libasm/asm_adduint8.c b/third_party/elfutils/libasm/asm_adduint8.c
new file mode 100644
index 0000000..18b67dd
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_adduint8.c
@@ -0,0 +1,54 @@
+/* Add unsigned integer to a section.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libasmP.h>
+
+#ifndef SIZE
+# define SIZE 8
+#endif
+
+#define UFCT(size) _UFCT(size)
+#define _UFCT(size) asm_adduint##size
+#define FCT(size) _FCT(size)
+#define _FCT(size) asm_addint##size
+#define UTYPE(size) _UTYPE(size)
+#define _UTYPE(size) uint##size##_t
+#define TYPE(size) _TYPE(size)
+#define _TYPE(size) int##size##_t
+
+
+int
+UFCT(SIZE) (AsmScn_t *asmscn, UTYPE(SIZE) num)
+{
+  return INTUSE(FCT(SIZE)) (asmscn, (TYPE(SIZE)) num);
+}
diff --git a/third_party/elfutils/libasm/asm_adduleb128.c b/third_party/elfutils/libasm/asm_adduleb128.c
new file mode 100644
index 0000000..96438cc
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_adduleb128.c
@@ -0,0 +1,93 @@
+/* Add integer to a section.
+   Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <string.h>
+
+#include "libasmP.h"
+
+
+int
+asm_adduleb128 (AsmScn_t *asmscn, uint32_t num)
+{
+  if (asmscn == NULL)
+    return -1;
+
+  if (asmscn->type == SHT_NOBITS && unlikely (num != 0))
+    {
+      __libasm_seterrno (ASM_E_TYPE);
+      return -1;
+    }
+
+  if (unlikely (asmscn->ctx->textp))
+    fprintf (asmscn->ctx->out.file, "\t.uleb128\t%" PRIu32 "\n", num);
+  else
+    {
+      char tmpbuf[(sizeof (num) * 8 + 6) / 7];
+      char *dest = tmpbuf;
+      uint32_t byte;
+
+      while (1)
+	{
+	  byte = num & 0x7f;
+
+	  num >>= 7;
+	  if (num == 0)
+	    /* This is the last byte.  */
+	    break;
+
+	  *dest++ = byte | 0x80;
+	}
+
+      *dest++ = byte;
+
+      /* Number of bytes produced.  */
+      size_t nbytes = dest - tmpbuf;
+
+      /* Make sure we have enough room.  */
+      if (__libasm_ensure_section_space (asmscn, nbytes) != 0)
+	return -1;
+
+      /* Copy the bytes.  */
+      if (likely (asmscn->type != SHT_NOBITS))
+	memcpy (&asmscn->content->data[asmscn->content->len], tmpbuf, nbytes);
+
+      /* Adjust the pointer in the data buffer.  */
+      asmscn->content->len += nbytes;
+
+      /* Increment the offset in the (sub)section.  */
+      asmscn->offset += nbytes;
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/libasm/asm_align.c b/third_party/elfutils/libasm/asm_align.c
new file mode 100644
index 0000000..e59a070
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_align.c
@@ -0,0 +1,175 @@
+/* Align section.
+   Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdlib.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+int
+asm_align (AsmScn_t *asmscn, GElf_Word value)
+{
+  if (asmscn == NULL)
+    /* An earlier error.  */
+    return -1;
+
+      /* The alignment value must be a power of two.  */
+  if (unlikely (! powerof2 (value)))
+    {
+      __libasm_seterrno (ASM_E_INVALID);
+      return -1;
+    }
+
+  if (unlikely (asmscn->ctx->textp))
+    {
+      fprintf (asmscn->ctx->out.file, "\t.align %" PRId32 ", ",
+	       (int32_t) value);
+      if (asmscn->pattern->len == 1)
+	fprintf (asmscn->ctx->out.file, "%02hhx\n", asmscn->pattern->bytes[0]);
+      else
+	{
+	  fputc_unlocked ('"', asmscn->ctx->out.file);
+
+	  for (size_t cnt = 0; cnt < asmscn->pattern->len; ++cnt)
+	    fprintf (asmscn->ctx->out.file, "\\x%02hhx",
+		     asmscn->pattern->bytes[cnt]);
+
+	  fputs_unlocked ("\"\n", asmscn->ctx->out.file);
+	}
+      return 0;
+    }
+
+  rwlock_wrlock (asmscn->ctx->lock);
+
+  int result = 0;
+
+  /* Fillbytes necessary?  */
+  if ((asmscn->offset & (value - 1)) != 0)
+    {
+      /* Add fillbytes.  */
+      size_t cnt = value - (asmscn->offset & (value - 1));
+
+      /* Ensure there is enough room to add the fill bytes.  */
+      result = __libasm_ensure_section_space (asmscn, cnt);
+      if (result != 0)
+	goto out;
+
+      /* Fill in the bytes.  We align the pattern according to the
+	 current offset.  */
+      size_t byteptr = asmscn->offset % asmscn->pattern->len;
+
+      /* Update the total size.  */
+      asmscn->offset += cnt;
+
+      do
+	{
+	  asmscn->content->data[asmscn->content->len++]
+	    = asmscn->pattern->bytes[byteptr++];
+
+	  if (byteptr == asmscn->pattern->len)
+	    byteptr = 0;
+	}
+      while (--cnt > 0);
+    }
+
+  /* Remember the maximum alignment for this subsection.  */
+  if (asmscn->max_align < value)
+    {
+      asmscn->max_align = value;
+
+      /* Update the parent as well (if it exists).  */
+      if (asmscn->subsection_id != 0)
+	{
+	  rwlock_wrlock (asmscn->data.up->ctx->lock);
+
+	  if (asmscn->data.up->max_align < value)
+	    asmscn->data.up->max_align = value;
+
+	  rwlock_unlock (asmscn->data.up->ctx->lock);
+	}
+    }
+
+ out:
+  rwlock_unlock (asmscn->ctx->lock);
+
+  return result;
+}
+
+
+/* Ensure there are at least LEN bytes available in the output buffer
+   for ASMSCN.  */
+int
+internal_function
+__libasm_ensure_section_space (AsmScn_t *asmscn, size_t len)
+{
+  /* The blocks with the section content are kept in a circular
+     single-linked list.  */
+  size_t size;
+
+  if (asmscn->content == NULL)
+    {
+      /* This is the first block.  */
+      size = MAX (2 * len, 960);
+
+      asmscn->content = (struct AsmData *) malloc (sizeof (struct AsmData)
+						   + size);
+      if (asmscn->content == NULL)
+	return -1;
+
+      asmscn->content->next = asmscn->content;
+    }
+  else
+    {
+      struct AsmData *newp;
+
+      if (asmscn->content->maxlen - asmscn->content->len >= len)
+	/* Nothing to do, there is enough space.  */
+	return 0;
+
+      size = MAX (2 *len, MIN (32768, 2 * asmscn->offset));
+
+      newp = (struct AsmData *) malloc (sizeof (struct AsmData) + size);
+      if (newp == NULL)
+	return -1;
+
+      newp->next = asmscn->content->next;
+      asmscn->content = asmscn->content->next = newp;
+    }
+
+  asmscn->content->len = 0;
+  asmscn->content->maxlen = size;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libasm/asm_begin.c b/third_party/elfutils/libasm/asm_begin.c
new file mode 100644
index 0000000..6248786
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_begin.c
@@ -0,0 +1,181 @@
+/* Create descriptor for assembling.
+   Copyright (C) 2002, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gelf.h>
+#include "libasmP.h"
+#include <system.h>
+
+
+static AsmCtx_t *
+prepare_text_output (AsmCtx_t *result)
+{
+  if (result->fd == -1)
+    result->out.file = stdout;
+  else
+    {
+      result->out.file = fdopen (result->fd, "a");
+      if (result->out.file == NULL)
+	{
+	  close (result->fd);
+	  free (result);
+	  result = NULL;
+	}
+      else
+	__fsetlocking (result->out.file, FSETLOCKING_BYCALLER);
+    }
+
+  return result;
+}
+
+
+static AsmCtx_t *
+prepare_binary_output (AsmCtx_t *result, Ebl *ebl)
+{
+  GElf_Ehdr *ehdr;
+  GElf_Ehdr ehdr_mem;
+
+  /* Create the ELF descriptor for the file.  */
+  result->out.elf = elf_begin (result->fd, ELF_C_WRITE_MMAP, NULL);
+  if (result->out.elf == NULL)
+    {
+    err_libelf:
+      unlink (result->tmp_fname);
+      close (result->fd);
+      free (result);
+      __libasm_seterrno (ASM_E_LIBELF);
+      return NULL;
+    }
+
+  /* Create the ELF header for the output file.  */
+  int class = ebl_get_elfclass (ebl);
+  if (gelf_newehdr (result->out.elf, class) == 0)
+    goto err_libelf;
+
+  ehdr = gelf_getehdr (result->out.elf, &ehdr_mem);
+  /* If this failed we are in trouble.  */
+  assert (ehdr != NULL);
+
+  /* We create an object file.  */
+  ehdr->e_type = ET_REL;
+  /* Set the ELF version.  */
+  ehdr->e_version = EV_CURRENT;
+
+  /* Use the machine, class, and endianess values from the Ebl descriptor.  */
+  ehdr->e_machine = ebl_get_elfmachine (ebl);
+  ehdr->e_ident[EI_CLASS] = class;
+  ehdr->e_ident[EI_DATA] = ebl_get_elfdata (ebl);
+
+  memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG);
+
+  /* Write the ELF header information back.  */
+  (void) gelf_update_ehdr (result->out.elf, ehdr);
+
+  /* No section so far.  */
+  result->section_list = NULL;
+
+  /* Initialize the hash table.  */
+  asm_symbol_tab_init (&result->symbol_tab, 67);
+  result->nsymbol_tab = 0;
+  /* And the string tables.  */
+  result->section_strtab = dwelf_strtab_init (true);
+  result->symbol_strtab = dwelf_strtab_init (true);
+
+  /* We have no section groups so far.  */
+  result->groups = NULL;
+  result->ngroups = 0;
+
+  return result;
+}
+
+
+AsmCtx_t *
+asm_begin (const char *fname, Ebl *ebl, bool textp)
+{
+  if (fname == NULL && ! textp)
+    return NULL;
+
+  size_t fname_len = fname != NULL ? strlen (fname) : 0;
+
+  /* Create the file descriptor.  We do not generate the output file
+     right away.  Instead we create a temporary file in the same
+     directory which, if everything goes alright, will replace a
+     possibly existing file with the given name.  */
+  AsmCtx_t *result
+    = (AsmCtx_t *) malloc (sizeof (AsmCtx_t) + 2 * fname_len + 9);
+  if (result == NULL)
+    return NULL;
+
+      /* Initialize the lock.  */
+      rwlock_init (result->lock);
+
+  if (fname != NULL)
+    {
+      /* Create the name of the temporary file.  */
+      result->fname = stpcpy (mempcpy (result->tmp_fname, fname, fname_len),
+			      ".XXXXXX") + 1;
+      memcpy (result->fname, fname, fname_len + 1);
+
+      /* Create the temporary file.  */
+      result->fd = mkstemp (result->tmp_fname);
+      if (result->fd == -1)
+	{
+	  int save_errno = errno;
+	  free (result);
+	  __libasm_seterrno (ASM_E_CANNOT_CREATE);
+	  errno = save_errno;
+	  return NULL;
+	}
+    }
+  else
+    result->fd = -1;
+
+  /* Initialize the counter for temporary symbols.  */
+  result->tempsym_count = 0;
+
+  /* Now we differentiate between textual and binary output.   */
+  result->textp = textp;
+  if (textp)
+    result = prepare_text_output (result);
+  else
+    result = prepare_binary_output (result, ebl);
+
+  return result;
+}
diff --git a/third_party/elfutils/libasm/asm_end.c b/third_party/elfutils/libasm/asm_end.c
new file mode 100644
index 0000000..ced24f5
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_end.c
@@ -0,0 +1,614 @@
+/* Finalize operations on the assembler context, free all resources.
+   Copyright (C) 2002, 2003, 2005, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <error.h>
+#include <libintl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <libasmP.h>
+#include <libelf.h>
+#include <system.h>
+
+
+static int
+text_end (AsmCtx_t *ctx __attribute__ ((unused)))
+{
+  if (fclose (ctx->out.file) != 0)
+    {
+      __libasm_seterrno (ASM_E_IOERROR);
+      return -1;
+    }
+
+  return 0;
+}
+
+
+static int
+binary_end (AsmCtx_t *ctx)
+{
+  void *symtab = NULL;
+  Dwelf_Strent *symscn_strent = NULL;
+  Dwelf_Strent *strscn_strent = NULL;
+  Dwelf_Strent *xndxscn_strent = NULL;
+  Elf_Scn *shstrscn;
+  Dwelf_Strent *shstrscn_strent;
+  size_t shstrscnndx;
+  size_t symscnndx = 0;
+  size_t strscnndx = 0;
+  size_t xndxscnndx = 0;
+  Elf_Data *data;
+  Elf_Data *shstrtabdata;
+  Elf_Data *strtabdata = NULL;
+  Elf_Data *xndxdata = NULL;
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr;
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr;
+  AsmScn_t *asmscn;
+  int result = 0;
+
+  /* Iterate over the created sections and compute the offsets of the
+     various subsections and fill in the content.  */
+  for (asmscn = ctx->section_list; asmscn != NULL; asmscn = asmscn->allnext)
+    {
+#if 0
+      Elf_Scn *scn = elf_getscn (ctx->out.elf, asmscn->data.main.scnndx);
+#else
+      Elf_Scn *scn = asmscn->data.main.scn;
+#endif
+      off_t offset = 0;
+      AsmScn_t *asmsubscn = asmscn;
+
+      do
+	{
+	  struct AsmData *content = asmsubscn->content;
+	  bool first = true;
+
+	  offset = ((offset + asmsubscn->max_align - 1)
+		    & ~(asmsubscn->max_align - 1));
+
+	  /* Update the offset for this subsection.  This field now
+	     stores the offset of the first by in this subsection.  */
+	  asmsubscn->offset = offset;
+
+	  /* Note that the content list is circular.  */
+	  if (content != NULL)
+	    do
+	      {
+		Elf_Data *newdata = elf_newdata (scn);
+
+		if (newdata == NULL)
+		  {
+		    __libasm_seterrno (ASM_E_LIBELF);
+		    return -1;
+		  }
+
+		newdata->d_buf = content->data;
+		newdata->d_type = ELF_T_BYTE;
+		newdata->d_size = content->len;
+		newdata->d_off = offset;
+		newdata->d_align = first ? asmsubscn->max_align : 1;
+
+		offset += content->len;
+	      }
+	    while ((content = content->next) != asmsubscn->content);
+	}
+      while ((asmsubscn = asmsubscn->subnext) != NULL);
+    }
+
+
+  /* Create the symbol table if necessary.  */
+  if (ctx->nsymbol_tab > 0)
+    {
+      /* Create the symbol table and string table section names.  */
+      symscn_strent = dwelf_strtab_add_len (ctx->section_strtab, ".symtab", 8);
+      strscn_strent = dwelf_strtab_add_len (ctx->section_strtab, ".strtab", 8);
+
+      /* Create the symbol string table section.  */
+      Elf_Scn *strscn = elf_newscn (ctx->out.elf);
+      strtabdata = elf_newdata (strscn);
+      shdr = gelf_getshdr (strscn, &shdr_mem);
+      if (strtabdata == NULL || shdr == NULL)
+	{
+	  __libasm_seterrno (ASM_E_LIBELF);
+	  return -1;
+	}
+      strscnndx = elf_ndxscn (strscn);
+
+      dwelf_strtab_finalize (ctx->symbol_strtab, strtabdata);
+
+      shdr->sh_type = SHT_STRTAB;
+      assert (shdr->sh_entsize == 0);
+
+      (void) gelf_update_shdr (strscn, shdr);
+
+      /* Create the symbol table section.  */
+      Elf_Scn *symscn = elf_newscn (ctx->out.elf);
+      data = elf_newdata (symscn);
+      shdr = gelf_getshdr (symscn, &shdr_mem);
+      if (data == NULL || shdr == NULL)
+	{
+	  __libasm_seterrno (ASM_E_LIBELF);
+	  return -1;
+	}
+      symscnndx = elf_ndxscn (symscn);
+
+      /* We know how many symbols there will be in the symbol table.  */
+      data->d_size = gelf_fsize (ctx->out.elf, ELF_T_SYM,
+				 ctx->nsymbol_tab + 1, EV_CURRENT);
+      symtab = malloc (data->d_size);
+      if (symtab == NULL)
+	return -1;
+      data->d_buf = symtab;
+      data->d_type = ELF_T_SYM;
+      data->d_off = 0;
+
+      /* Clear the first entry.  */
+      GElf_Sym syment;
+      memset (&syment, '\0', sizeof (syment));
+      (void) gelf_update_sym (data, 0, &syment);
+
+      /* Iterate over the symbol table.  */
+      void *runp = NULL;
+      int ptr_local = 1;	/* Start with index 1; zero remains unused.  */
+      int ptr_nonlocal = ctx->nsymbol_tab;
+      uint32_t *xshndx = NULL;
+      AsmSym_t *sym;
+      while ((sym = asm_symbol_tab_iterate (&ctx->symbol_tab, &runp)) != NULL)
+	if (asm_emit_symbol_p (dwelf_strent_str (sym->strent)))
+	  {
+	    assert (ptr_local <= ptr_nonlocal);
+
+	    syment.st_name = dwelf_strent_off (sym->strent);
+	    syment.st_info = GELF_ST_INFO (sym->binding, sym->type);
+	    syment.st_other = 0;
+	    syment.st_value = sym->scn->offset + sym->offset;
+	    syment.st_size = sym->size;
+
+	    /* Add local symbols at the beginning, the other from
+	       the end.  */
+	    int ptr = sym->binding == STB_LOCAL ? ptr_local++ : ptr_nonlocal--;
+
+	    /* Determine the section index.  We have to handle the
+	       overflow correctly.  */
+	    Elf_Scn *scn = (sym->scn->subsection_id == 0
+			    ? sym->scn->data.main.scn
+			    : sym->scn->data.up->data.main.scn);
+
+	    Elf32_Word ndx;
+	    if (unlikely (scn == ASM_ABS_SCN))
+	      ndx = SHN_ABS;
+	    else if (unlikely (scn == ASM_COM_SCN))
+	      ndx = SHN_COMMON;
+	    else if (unlikely ((ndx = elf_ndxscn (scn)) >= SHN_LORESERVE))
+	      {
+		if (unlikely (xshndx == NULL))
+		  {
+		    /* The extended section index section does not yet
+		       exist.  */
+		    Elf_Scn *xndxscn;
+
+		    xndxscn = elf_newscn (ctx->out.elf);
+		    xndxdata = elf_newdata (xndxscn);
+		    shdr = gelf_getshdr (xndxscn, &shdr_mem);
+		    if (xndxdata == NULL || shdr == NULL)
+		      {
+			__libasm_seterrno (ASM_E_LIBELF);
+			return -1;
+		      }
+		    xndxscnndx = elf_ndxscn (xndxscn);
+
+		    shdr->sh_type = SHT_SYMTAB_SHNDX;
+		    shdr->sh_entsize = sizeof (Elf32_Word);
+		    shdr->sh_addralign = sizeof (Elf32_Word);
+		    shdr->sh_link = symscnndx;
+
+		    (void) gelf_update_shdr (xndxscn, shdr);
+
+		    xndxscn_strent = dwelf_strtab_add_len (ctx->section_strtab,
+							   ".symtab_shndx",
+							   14);
+
+		    /* Note that using 'elf32_fsize' instead of
+		       'gelf_fsize' here is correct.  */
+		    xndxdata->d_size = elf32_fsize (ELF_T_WORD,
+						    ctx->nsymbol_tab + 1,
+						    EV_CURRENT);
+		    xshndx = xndxdata->d_buf = calloc (1, xndxdata->d_size);
+		    if (xshndx == NULL)
+		      return -1;
+		    /* Using ELF_T_WORD here relies on the fact that the
+		       32- and 64-bit types are the same size.  */
+		    xndxdata->d_type = ELF_T_WORD;
+		    xndxdata->d_off = 0;
+		  }
+
+		/* Store the real section index in the extended setion
+		   index table.  */
+		assert ((size_t) ptr < ctx->nsymbol_tab + 1);
+		xshndx[ptr] = ndx;
+
+		/* And signal that this happened.  */
+		ndx = SHN_XINDEX;
+	      }
+	    syment.st_shndx = ndx;
+
+	    /* Remember where we put the symbol.  */
+	    sym->symidx = ptr;
+
+	    (void) gelf_update_sym (data, ptr, &syment);
+	  }
+
+      assert (ptr_local == ptr_nonlocal + 1);
+
+      shdr->sh_type = SHT_SYMTAB;
+      shdr->sh_link = strscnndx;
+      shdr->sh_info = ptr_local;
+      shdr->sh_entsize = gelf_fsize (ctx->out.elf, ELF_T_SYM, 1, EV_CURRENT);
+      shdr->sh_addralign = gelf_fsize (ctx->out.elf, ELF_T_ADDR, 1,
+				       EV_CURRENT);
+
+      (void) gelf_update_shdr (symscn, shdr);
+    }
+
+
+  /* Create the section header string table section and fill in the
+     references in the section headers.  */
+  shstrscn = elf_newscn (ctx->out.elf);
+  shstrtabdata = elf_newdata (shstrscn);
+  shdr = gelf_getshdr (shstrscn, &shdr_mem);
+  if (shstrscn == NULL || shstrtabdata == NULL || shdr == NULL)
+    {
+      __libasm_seterrno (ASM_E_LIBELF);
+      return -1;
+    }
+
+
+  /* Add the name of the section header string table.  */
+  shstrscn_strent = dwelf_strtab_add_len (ctx->section_strtab,
+					  ".shstrtab", 10);
+
+  dwelf_strtab_finalize (ctx->section_strtab, shstrtabdata);
+
+  shdr->sh_type = SHT_STRTAB;
+  assert (shdr->sh_entsize == 0);
+  shdr->sh_name = dwelf_strent_off (shstrscn_strent);
+
+  (void) gelf_update_shdr (shstrscn, shdr);
+
+
+  /* Create the section groups.  */
+  if (ctx->groups != NULL)
+    {
+      AsmScnGrp_t *runp = ctx->groups->next;
+
+      do
+	{
+	  Elf_Scn *scn;
+	  Elf32_Word *grpdata;
+
+	  scn = runp->scn;
+	  assert (scn != NULL);
+	  shdr = gelf_getshdr (scn, &shdr_mem);
+	  assert (shdr != NULL);
+
+	  data = elf_newdata (scn);
+	  if (data == NULL)
+	    {
+	      __libasm_seterrno (ASM_E_LIBELF);
+	      return -1;
+	    }
+
+	  /* It is correct to use 'elf32_fsize' instead of 'gelf_fsize'
+	     here.  */
+	  data->d_size = elf32_fsize (ELF_T_WORD, runp->nmembers + 1,
+				      EV_CURRENT);
+	  grpdata = data->d_buf = malloc (data->d_size);
+	  if (grpdata == NULL)
+	    return -1;
+	  data->d_type = ELF_T_WORD;
+	  data->d_off = 0;
+	  data->d_align = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT);
+
+	  /* The first word of the section is filled with the flag word.  */
+	  *grpdata++ = runp->flags;
+
+	  if (runp->members != NULL)
+	    {
+	      AsmScn_t *member = runp->members->data.main.next_in_group;
+
+	      do
+		{
+		  /* Only sections, not subsections, can be registered
+		     as member of a group.  The subsections get
+		     automatically included.  */
+		  assert (member->subsection_id == 0);
+
+		  *grpdata++ = elf_ndxscn (member->data.main.scn);
+		}
+	      while ((member = member->data.main.next_in_group)
+		     != runp->members->data.main.next_in_group);
+	    }
+
+	  /* Construct the section header.  */
+	  shdr->sh_name = dwelf_strent_off (runp->strent);
+	  shdr->sh_type = SHT_GROUP;
+	  shdr->sh_flags = 0;
+	  shdr->sh_link = symscnndx;
+	  /* If the user did not specify a signature we use the initial
+	     empty symbol in the symbol table as the signature.  */
+	  shdr->sh_info = (runp->signature != NULL
+			   ? runp->signature->symidx : 0);
+
+	  (void) gelf_update_shdr (scn, shdr);
+	}
+      while ((runp = runp->next) != ctx->groups->next);
+    }
+
+
+  /* Add the name to the symbol section.  */
+  if (likely (symscnndx != 0))
+    {
+      Elf_Scn *scn = elf_getscn (ctx->out.elf, symscnndx);
+
+      shdr = gelf_getshdr (scn, &shdr_mem);
+
+      shdr->sh_name = dwelf_strent_off (symscn_strent);
+
+      (void) gelf_update_shdr (scn, shdr);
+
+
+      /* Add the name to the string section.  */
+      assert (strscnndx != 0);
+      scn = elf_getscn (ctx->out.elf, strscnndx);
+
+      shdr = gelf_getshdr (scn, &shdr_mem);
+
+      shdr->sh_name = dwelf_strent_off (strscn_strent);
+
+      (void) gelf_update_shdr (scn, shdr);
+
+
+      /* Add the name to the extended symbol index section.  */
+      if (xndxscnndx != 0)
+	{
+	  scn = elf_getscn (ctx->out.elf, xndxscnndx);
+
+	  shdr = gelf_getshdr (scn, &shdr_mem);
+
+	  shdr->sh_name = dwelf_strent_off (xndxscn_strent);
+
+	  (void) gelf_update_shdr (scn, shdr);
+	}
+    }
+
+
+  /* Iterate over the created sections and fill in the names.  */
+  for (asmscn = ctx->section_list; asmscn != NULL; asmscn = asmscn->allnext)
+    {
+      shdr = gelf_getshdr (asmscn->data.main.scn, &shdr_mem);
+      /* This better should not fail.  */
+      assert (shdr != NULL);
+
+      shdr->sh_name = dwelf_strent_off (asmscn->data.main.strent);
+
+      /* We now know the maximum alignment.  */
+      shdr->sh_addralign = asmscn->max_align;
+
+      (void) gelf_update_shdr (asmscn->data.main.scn, shdr);
+    }
+
+  /* Put the reference to the section header string table in the ELF
+     header.  */
+  ehdr = gelf_getehdr (ctx->out.elf, &ehdr_mem);
+  assert (ehdr != NULL);
+
+  shstrscnndx = elf_ndxscn (shstrscn);
+  if (unlikely (shstrscnndx > SHN_HIRESERVE)
+      || unlikely (shstrscnndx == SHN_XINDEX))
+    {
+      /* The index of the section header string sectio is too large.  */
+      Elf_Scn *scn = elf_getscn (ctx->out.elf, 0);
+
+      /* Get the header for the zeroth section.  */
+      shdr = gelf_getshdr (scn, &shdr_mem);
+      /* This better does not fail.  */
+      assert (shdr != NULL);
+
+      /* The sh_link field of the zeroth section header contains the value.  */
+      shdr->sh_link = shstrscnndx;
+
+      (void) gelf_update_shdr (scn, shdr);
+
+      /* This is the sign for the overflow.  */
+      ehdr->e_shstrndx = SHN_XINDEX;
+    }
+  else
+    ehdr->e_shstrndx = elf_ndxscn (shstrscn);
+
+  gelf_update_ehdr (ctx->out.elf, ehdr);
+
+  /* Write out the ELF file.  */
+  if (unlikely (elf_update (ctx->out.elf, ELF_C_WRITE_MMAP) < 0))
+    {
+      __libasm_seterrno (ASM_E_LIBELF);
+      result = -1;
+    }
+
+  /* We do not need the section header and symbol string tables anymore.  */
+  free (shstrtabdata->d_buf);
+  if (strtabdata != NULL)
+    free (strtabdata->d_buf);
+  /* We might have allocated the extended symbol table index.  */
+  if (xndxdata != NULL)
+    free (xndxdata->d_buf);
+
+  /* Free section groups memory.  */
+  AsmScnGrp_t *scngrp = ctx->groups;
+  if (scngrp != NULL)
+    do
+      free (elf_getdata (scngrp->scn, NULL)->d_buf);
+    while ((scngrp = scngrp->next) != ctx->groups);
+
+  /* Finalize the ELF handling.  */
+  if (unlikely (elf_end (ctx->out.elf)) != 0)
+    {
+      __libasm_seterrno (ASM_E_LIBELF);
+      result = -1;
+    }
+
+  /* Free the temporary resources.  */
+  free (symtab);
+
+  return result;
+}
+
+
+int
+asm_end (AsmCtx_t *ctx)
+{
+  int result;
+
+  if (ctx == NULL)
+    /* Something went wrong earlier.  */
+    return -1;
+
+  result = unlikely (ctx->textp) ? text_end (ctx) : binary_end (ctx);
+  if (result != 0)
+    return result;
+
+  /* Make the new file globally readable and user/group-writable.  */
+  if (fchmod (ctx->fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH) != 0)
+    {
+      __libasm_seterrno (ASM_E_CANNOT_CHMOD);
+      return -1;
+    }
+
+  /* Rename output file.  */
+  if (rename (ctx->tmp_fname, ctx->fname) != 0)
+    {
+      __libasm_seterrno (ASM_E_CANNOT_RENAME);
+      return -1;
+    }
+
+  /* Free the resources.  */
+  __libasm_finictx (ctx);
+
+  return 0;
+}
+
+
+static void
+free_section (AsmScn_t *scnp)
+{
+  void *oldp;
+
+  if (scnp->subnext != NULL)
+    free_section (scnp->subnext);
+
+  struct AsmData *data = scnp->content;
+  if (data != NULL)
+    do
+      {
+	oldp = data;
+	data = data->next;
+	free (oldp);
+      }
+    while (oldp != scnp->content);
+
+  free (scnp);
+}
+
+
+void
+internal_function
+__libasm_finictx (AsmCtx_t *ctx)
+{
+  /* Iterate through section table and free individual entries.  */
+  AsmScn_t *scn = ctx->section_list;
+  while (scn != NULL)
+    {
+      AsmScn_t *oldp = scn;
+      scn = scn->allnext;
+      free_section (oldp);
+    }
+
+  /* Free the resources of the symbol table.  */
+  void *runp = NULL;
+  AsmSym_t *sym;
+  while ((sym = asm_symbol_tab_iterate (&ctx->symbol_tab, &runp)) != NULL)
+    free (sym);
+  asm_symbol_tab_free (&ctx->symbol_tab);
+
+
+  /* Free section groups.  */
+  AsmScnGrp_t *scngrp = ctx->groups;
+  if (scngrp != NULL)
+    do
+      {
+	AsmScnGrp_t *oldp = scngrp;
+
+	scngrp = scngrp->next;
+	free (oldp);
+      }
+    while (scngrp != ctx->groups);
+
+
+  if (unlikely (ctx->textp))
+    {
+      /* Close the stream.  */
+      fclose (ctx->out.file);
+    }
+  else
+    {
+      /* Close the output file.  */
+      /* XXX We should test for errors here but what would we do if we'd
+	 find any.  */
+      (void) close (ctx->fd);
+
+      /* And the string tables.  */
+      dwelf_strtab_free (ctx->section_strtab);
+      dwelf_strtab_free (ctx->symbol_strtab);
+    }
+
+  /* Initialize the lock.  */
+  rwlock_fini (ctx->lock);
+
+  /* Finally free the data structure.   */
+  free (ctx);
+}
diff --git a/third_party/elfutils/libasm/asm_error.c b/third_party/elfutils/libasm/asm_error.c
new file mode 100644
index 0000000..cc3e660
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_error.c
@@ -0,0 +1,95 @@
+/* Error handling in libasm.
+   Copyright (C) 2002, 2004, 2005, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include "libasmP.h"
+
+
+/* This is the key for the thread specific memory.  */
+static __thread int global_error;
+
+
+int
+asm_errno (void)
+{
+  int result = global_error;
+  global_error = ASM_E_NOERROR;
+  return result;
+}
+
+
+void
+internal_function
+__libasm_seterrno (int value)
+{
+  global_error = value;
+}
+
+
+/* Return the appropriate message for the error.  */
+static const char *msgs[ASM_E_NUM] =
+{
+  [ASM_E_NOERROR] = N_("no error"),
+  [ASM_E_NOMEM] = N_("out of memory"),
+  [ASM_E_CANNOT_CREATE] = N_("cannot create output file"),
+  [ASM_E_INVALID] = N_("invalid parameter"),
+  [ASM_E_CANNOT_CHMOD] = N_("cannot change mode of output file"),
+  [ASM_E_CANNOT_RENAME] = N_("cannot rename output file"),
+  [ASM_E_DUPLSYM] = N_("duplicate symbol"),
+  [ASM_E_TYPE] = N_("invalid section type for operation"),
+  [ASM_E_IOERROR] = N_("error during output of data"),
+  [ASM_E_ENOSUP] = N_("no backend support available"),
+};
+
+const char *
+asm_errmsg (int error)
+{
+  int last_error = global_error;
+
+  if (error < -1)
+    return _("unknown error");
+  if (error == 0 && last_error == 0)
+    /* No error.  */
+    return NULL;
+
+  if (error != -1)
+    last_error = error;
+
+  if (last_error == ASM_E_LIBELF)
+    return elf_errmsg (-1);
+
+  return _(msgs[last_error]);
+}
diff --git a/third_party/elfutils/libasm/asm_fill.c b/third_party/elfutils/libasm/asm_fill.c
new file mode 100644
index 0000000..62d9d73
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_fill.c
@@ -0,0 +1,74 @@
+/* Determine fill pattern for a section.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+int
+asm_fill (AsmScn_t *asmscn, void *bytes, size_t len)
+{
+  struct FillPattern *pattern;
+  struct FillPattern *old_pattern;
+
+  if (asmscn == NULL)
+    /* Some earlier error.  */
+    return -1;
+
+  if (bytes == NULL)
+    /* Use the default pattern.  */
+    pattern = (struct FillPattern *) __libasm_default_pattern;
+  else
+    {
+      /* Allocate appropriate memory.  */
+      pattern = (struct FillPattern *) malloc (sizeof (struct FillPattern)
+					       + len);
+      if (pattern == NULL)
+	return -1;
+
+      pattern->len = len;
+      memcpy (pattern->bytes, bytes, len);
+    }
+
+  old_pattern = asmscn->pattern;
+  asmscn->pattern = pattern;
+
+  /* Free the old data structure if we have allocated it.  */
+  if (old_pattern != __libasm_default_pattern)
+    free (old_pattern);
+
+  return 0;
+}
diff --git a/third_party/elfutils/libasm/asm_getelf.c b/third_party/elfutils/libasm/asm_getelf.c
new file mode 100644
index 0000000..2a5c37b
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_getelf.c
@@ -0,0 +1,43 @@
+/* Return ELF descriptor associated with the assembler context.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+
+#include <libasmP.h>
+
+
+Elf *
+asm_getelf (AsmCtx_t *ctx)
+{
+  return ctx != NULL ? ctx->out.elf : NULL;
+}
diff --git a/third_party/elfutils/libasm/asm_newabssym.c b/third_party/elfutils/libasm/asm_newabssym.c
new file mode 100644
index 0000000..34fef3e
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_newabssym.c
@@ -0,0 +1,131 @@
+/* Create new ABS symbol.
+   Copyright (C) 2002, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+/* Object for special COMMON section.  */
+static const AsmScn_t __libasm_abs_scn =
+  {
+    .data = {
+      .main = {
+	.scn = ASM_ABS_SCN
+      }
+    }
+  };
+
+
+AsmSym_t *
+asm_newabssym (AsmCtx_t *ctx, const char *name, GElf_Xword size,
+	       GElf_Addr value, int type, int binding)
+{
+  AsmSym_t *result;
+
+  if (ctx == NULL)
+    /* Something went wrong before.  */
+    return NULL;
+
+  /* Common symbols are public.  Therefore the user must provide a
+     name.  */
+  if (name == NULL)
+    {
+      __libasm_seterrno (ASM_E_INVALID);
+      return NULL;
+    }
+
+  rwlock_wrlock (ctx->lock);
+
+  result = (AsmSym_t *) malloc (sizeof (AsmSym_t));
+  if (result == NULL)
+    return NULL;
+
+  result->scn = (AsmScn_t *) &__libasm_abs_scn;
+  result->size = size;
+  result->type = type;
+  result->binding = binding;
+  result->symidx = 0;
+  result->strent = dwelf_strtab_add (ctx->symbol_strtab, name);
+
+  /* The value of an ABS symbol must not be modified.  Since there are
+     no subsection and the initial offset of the section is 0 we can
+     get the alignment recorded by storing it into the offset
+     field.  */
+  result->offset = value;
+
+  if (unlikely (ctx->textp))
+    {
+      /* An absolute symbol can be defined by giving a symbol a
+	 specific value.  */
+      if (binding == STB_GLOBAL)
+	fprintf (ctx->out.file, "\t.globl %s\n", name);
+      else if (binding == STB_WEAK)
+	fprintf (ctx->out.file, "\t.weak %s\n", name);
+
+      if (type == STT_OBJECT)
+	fprintf (ctx->out.file, "\t.type %s,@object\n", name);
+      else if (type == STT_FUNC)
+	fprintf (ctx->out.file, "\t.type %s,@function\n", name);
+
+      fprintf (ctx->out.file, "%s = %llu\n",
+	       name, (unsigned long long int) value);
+
+      if (size != 0)
+	fprintf (ctx->out.file, "\t.size %s, %llu\n",
+		 name, (unsigned long long int) size);
+    }
+  else
+    {
+      /* Put the symbol in the hash table so that we can later find it.  */
+      if (asm_symbol_tab_insert (&ctx->symbol_tab, elf_hash (name), result)
+	  != 0)
+	{
+	  /* The symbol already exists.  */
+	  __libasm_seterrno (ASM_E_DUPLSYM);
+	  free (result);
+	  result = NULL;
+	}
+      else if (name != NULL && asm_emit_symbol_p (name))
+	/* Only count non-private symbols.  */
+	++ctx->nsymbol_tab;
+    }
+
+  rwlock_unlock (ctx->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libasm/asm_newcomsym.c b/third_party/elfutils/libasm/asm_newcomsym.c
new file mode 100644
index 0000000..ee3b696
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_newcomsym.c
@@ -0,0 +1,114 @@
+/* Create new COMMON symbol.
+   Copyright (C) 2002, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+/* Object for special COMMON section.  */
+static const AsmScn_t __libasm_com_scn =
+  {
+    .data = {
+      .main = {
+	.scn = ASM_COM_SCN
+      }
+    }
+  };
+
+
+AsmSym_t *
+asm_newcomsym (AsmCtx_t *ctx, const char *name, GElf_Xword size,
+	       GElf_Addr align)
+{
+  AsmSym_t *result;
+
+  if (ctx == NULL)
+    /* Something went wrong before.  */
+    return NULL;
+
+  /* Common symbols are public.  Therefore the user must provide a
+     name.  */
+  if (name == NULL)
+    {
+      __libasm_seterrno (ASM_E_INVALID);
+      return NULL;
+    }
+
+  rwlock_wrlock (ctx->lock);
+
+  result = (AsmSym_t *) malloc (sizeof (AsmSym_t));
+  if (result == NULL)
+    return NULL;
+
+  result->scn = (AsmScn_t *) &__libasm_com_scn;
+  result->size = size;
+  /* XXX Do we have to allow a different type?  */
+  result->type = STT_OBJECT;
+  /* XXX Do we have to allow a different binding?  */
+  result->binding = STB_GLOBAL;
+  result->symidx = 0;
+  result->strent = dwelf_strtab_add (ctx->symbol_strtab, name);
+
+  /* The value of a COM symbol is the alignment.  Since there are no
+     subsection and the initial offset of the section is 0 we can get
+     the alignment recorded by storing it into the offset field.  */
+  result->offset = align;
+
+  if (unlikely (ctx->textp))
+    fprintf (ctx->out.file, "\t.comm %s, %" PRIuMAX ", %" PRIuMAX "\n",
+	     name, (uintmax_t) size, (uintmax_t) align);
+  else
+    {
+      /* Put the symbol in the hash table so that we can later find it.  */
+      if (asm_symbol_tab_insert (&ctx->symbol_tab, elf_hash (name), result)
+	  != 0)
+	{
+	  /* The symbol already exists.  */
+	  __libasm_seterrno (ASM_E_DUPLSYM);
+	  free (result);
+	  result = NULL;
+	}
+      else if (name != NULL && asm_emit_symbol_p (name))
+	/* Only count non-private symbols.  */
+	++ctx->nsymbol_tab;
+    }
+
+  rwlock_unlock (ctx->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libasm/asm_newscn.c b/third_party/elfutils/libasm/asm_newscn.c
new file mode 100644
index 0000000..ddbb25d
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_newscn.c
@@ -0,0 +1,212 @@
+/* Create new section in output file.
+   Copyright (C) 2002-2011, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <error.h>
+#include <libintl.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libasmP.h>
+#include <libelf.h>
+#include <system.h>
+
+
+/* Memory for the default pattern.  The type uses a flexible array
+   which does work well with a static initializer.  So we play some
+   dirty tricks here.  */
+static const struct
+{
+  struct FillPattern pattern;
+  char zero;
+} xdefault_pattern =
+  {
+    .pattern =
+    {
+      .len = 1
+    },
+    .zero = '\0'
+  };
+const struct FillPattern *__libasm_default_pattern = &xdefault_pattern.pattern;
+
+
+static AsmScn_t *
+text_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags)
+{
+  /* Buffer where we construct the flag string.  */
+  char flagstr[sizeof (GElf_Xword) * 8 + 5];
+  char *wp = flagstr;
+  const char *typestr = "";
+
+  /* Only write out the flag string if this is the first time the
+     section is selected.  Some assemblers cannot cope with the
+     .section pseudo-op otherwise.  */
+  wp = stpcpy (wp, ", \"");
+
+  if (flags & SHF_WRITE)
+    *wp++ = 'w';
+  if (flags & SHF_ALLOC)
+    *wp++ = 'a';
+  if (flags & SHF_EXECINSTR)
+    *wp++ = 'x';
+  if (flags & SHF_MERGE)
+    *wp++ = 'M';
+  if (flags & SHF_STRINGS)
+    *wp++ = 'S';
+  if (flags & SHF_LINK_ORDER)
+    *wp++ = 'L';
+
+  *wp++ = '"';
+
+  if (type == SHT_PROGBITS)
+    typestr = ",@progbits";
+  else if (type == SHT_NOBITS)
+    typestr = ",@nobits";
+
+  /* Terminate the string.  */
+  *wp = '\0';
+
+  fprintf (result->ctx->out.file, "\t.section \"%s\"%s%s\n",
+	   result->name, flagstr, typestr);
+
+  return result;
+}
+
+
+static AsmScn_t *
+binary_newscn (AsmScn_t *result, GElf_Word type, GElf_Xword flags,
+	       size_t scnname_len)
+{
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr;
+  Elf_Scn *scn;
+
+  /* The initial subsection has the number zero.  */
+  result->subsection_id = 0;
+
+  /* We start at offset zero.  */
+  result->offset = 0;
+  /* And generic alignment.  */
+  result->max_align = 1;
+
+  /* No output yet.  */
+  result->content = NULL;
+
+  /* Put the default fill pattern in place.  */
+  result->pattern = (struct FillPattern *) __libasm_default_pattern;
+
+  /* There are no subsections so far.  */
+  result->subnext = NULL;
+
+  /* Add the name to the section header string table.  */
+  result->data.main.strent = dwelf_strtab_add_len (result->ctx->section_strtab,
+						   result->name, scnname_len);
+  assert (result->data.main.strent != NULL);
+
+  /* Create the new ELF section.  */
+  result->data.main.scn = scn = elf_newscn (result->ctx->out.elf);
+  if (scn == NULL)
+    {
+      free (result);
+      __libasm_seterrno (ASM_E_LIBELF);
+      return NULL;
+    }
+
+  /* Not part of a section group (yet).  */
+  result->data.main.next_in_group = NULL;
+
+  /* Remember the flags.  */
+  shdr = gelf_getshdr (scn, &shdr_mem);
+
+  shdr->sh_flags = flags;
+  result->type = shdr->sh_type = type;
+
+  (void) gelf_update_shdr (scn, shdr);
+
+  return result;
+}
+
+
+AsmScn_t *
+asm_newscn (AsmCtx_t *ctx, const char *scnname, GElf_Word type,
+	    GElf_Xword flags)
+{
+  size_t scnname_len = strlen (scnname) + 1;
+  AsmScn_t *result;
+
+  /* If no context is given there might be an earlier error.  */
+  if (ctx == NULL)
+    return NULL;
+
+  /* Check whether only flags are set which areselectable by the user.  */
+  if (unlikely ((flags & ~(SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE
+			   | SHF_STRINGS | SHF_LINK_ORDER)) != 0)
+      /* We allow only two section types: data and data without file
+	 representation.  */
+      || (type != SHT_PROGBITS && unlikely (type != SHT_NOBITS)))
+    {
+      __libasm_seterrno (ASM_E_INVALID);
+      return NULL;
+    }
+
+  rwlock_wrlock (ctx->lock);
+
+  /* This is a new section.  */
+  result = (AsmScn_t *) malloc (sizeof (AsmScn_t) + scnname_len);
+  if (result != NULL)
+    {
+      /* Add the name.  */
+      memcpy (result->name, scnname, scnname_len);
+
+      /* Add the reference to the context.  */
+      result->ctx = ctx;
+
+      /* Perform operations according to output mode.  */
+      result = (unlikely (ctx->textp)
+		? text_newscn (result, type, flags)
+		: binary_newscn (result, type, flags, scnname_len));
+
+      /* If everything went well finally add the new section to the hash
+	 table.  */
+      if (result != NULL)
+	{
+	  result->allnext = ctx->section_list;
+	  ctx->section_list = result;
+	}
+    }
+
+  rwlock_unlock (ctx->lock);
+
+  return result;
+}
+INTDEF(asm_newscn)
diff --git a/third_party/elfutils/libasm/asm_newscn_ingrp.c b/third_party/elfutils/libasm/asm_newscn_ingrp.c
new file mode 100644
index 0000000..fd45be6
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_newscn_ingrp.c
@@ -0,0 +1,77 @@
+/* Create new section, which is member of a group, in output file.
+   Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+
+#include "libasmP.h"
+
+
+AsmScn_t *
+asm_newscn_ingrp (AsmCtx_t *ctx, const char *scnname, GElf_Word type,
+		  GElf_Xword flags, AsmScnGrp_t *grp)
+{
+  AsmScn_t *result = INTUSE (asm_newscn) (ctx, scnname, type, flags);
+
+  if (likely (result != NULL))
+    {
+      /* We managed to create a section group.  Add it to the section
+	 group.  */
+      if (grp->nmembers == 0)
+	{
+	  assert (grp->members == NULL);
+	  grp->members = result->data.main.next_in_group = result;
+	}
+      else
+	{
+	  result->data.main.next_in_group
+	    = grp->members->data.main.next_in_group;
+	  grp->members = grp->members->data.main.next_in_group = result;
+	}
+
+      ++grp->nmembers;
+
+      /* Set the SHF_GROUP flag.  */
+      if (likely (! ctx->textp))
+	{
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (result->data.main.scn, &shdr_mem);
+
+	  assert (shdr != NULL);
+	  shdr->sh_flags |= SHF_GROUP;
+
+	  (void) gelf_update_shdr (result->data.main.scn, shdr);
+	}
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/libasm/asm_newscngrp.c b/third_party/elfutils/libasm/asm_newscngrp.c
new file mode 100644
index 0000000..80757a9
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_newscngrp.c
@@ -0,0 +1,102 @@
+/* Create new section group.
+   Copyright (C) 2002, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libasmP.h"
+#include <system.h>
+
+
+
+AsmScnGrp_t *
+asm_newscngrp (AsmCtx_t *ctx, const char *grpname, AsmSym_t *signature,
+	       Elf32_Word flags)
+{
+  AsmScnGrp_t *result;
+  size_t grpname_len = strlen (grpname) + 1;
+
+  if (ctx == NULL)
+    return NULL;
+
+  if ((flags & ~GRP_COMDAT) != 0)
+    {
+      /* This is not a supported flag.  */
+      __libasm_seterrno (ASM_E_INVALID);
+      return NULL;
+    }
+
+  result = (AsmScnGrp_t *) malloc (sizeof (AsmScnGrp_t) + grpname_len);
+  if (result == NULL)
+    return NULL;
+
+  result->signature = signature;
+  result->members = NULL;
+  result->nmembers = 0;
+  result->flags = flags;
+
+  memcpy (result->name, grpname, grpname_len);
+  result->strent = dwelf_strtab_add_len (ctx->section_strtab, result->name,
+					 grpname_len);
+
+  if (unlikely (ctx->textp))
+    // XXX TBI.  What is the format?
+    abort ();
+  else
+    {
+      result->scn = elf_newscn (ctx->out.elf);
+      if (result->scn == NULL)
+	{
+	  /* Couldn't allocate a new section.  */
+	  __libasm_seterrno (ASM_E_LIBELF);
+	  free (result);
+	  return NULL;
+	}
+    }
+
+  /* Enqueue is the context data structure.  */
+  if (ctx->ngroups == 0)
+    {
+      assert (ctx->groups == NULL);
+      ctx->groups = result->next = result;
+    }
+  else
+    {
+      result->next = ctx->groups->next;
+      ctx->groups = ctx->groups->next = result;
+    }
+  ++ctx->ngroups;
+
+  return result;
+}
diff --git a/third_party/elfutils/libasm/asm_newsubscn.c b/third_party/elfutils/libasm/asm_newsubscn.c
new file mode 100644
index 0000000..906240a
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_newsubscn.c
@@ -0,0 +1,97 @@
+/* Create new subsection section in given section.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+AsmScn_t *
+asm_newsubscn (AsmScn_t *asmscn, unsigned int nr)
+{
+  AsmScn_t *runp;
+  AsmScn_t *newp;
+
+  /* Just return if no section is given.  The error must have been
+     somewhere else.  */
+  if (asmscn == NULL)
+    return NULL;
+
+  /* Determine whether there is already a subsection with this number.  */
+  runp = asmscn->subsection_id == 0 ? asmscn : asmscn->data.up;
+  while (1)
+    {
+      if (runp->subsection_id == nr)
+	/* Found it.  */
+	return runp;
+
+      if (runp->subnext == NULL || runp->subnext->subsection_id > nr)
+	break;
+
+      runp = runp->subnext;
+    }
+
+  newp = (AsmScn_t *) malloc (sizeof (AsmScn_t));
+  if (newp == NULL)
+    return NULL;
+
+  /* Same assembler context than the original section.  */
+  newp->ctx = runp->ctx;
+
+  /* User provided the subsectio nID.  */
+  newp->subsection_id = nr;
+
+  /* Inherit the parent's type.  */
+  newp->type = runp->type;
+
+  /* Pointer to the zeroth subsection.  */
+  newp->data.up = runp->subsection_id == 0 ? runp : runp->data.up;
+
+  /* We start at offset zero.  */
+  newp->offset = 0;
+  /* And generic alignment.  */
+  newp->max_align = 1;
+
+  /* No output yet.  */
+  newp->content = NULL;
+
+  /* Inherit the fill pattern from the section this one is derived from.  */
+  newp->pattern = asmscn->pattern;
+
+  /* Enqueue at the right position in the list.  */
+  newp->subnext = runp->subnext;
+  runp->subnext = newp;
+
+  return newp;
+}
diff --git a/third_party/elfutils/libasm/asm_newsym.c b/third_party/elfutils/libasm/asm_newsym.c
new file mode 100644
index 0000000..5389166
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_newsym.c
@@ -0,0 +1,136 @@
+/* Define new symbol for current position in given section.
+   Copyright (C) 2002, 2005, 2016, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libasmP.h>
+#include <system.h>
+
+
+AsmSym_t *
+asm_newsym (AsmScn_t *asmscn, const char *name, GElf_Xword size,
+	    int type, int binding)
+{
+/* We don't really expect labels with many digits, but in theory it could
+   be 10 digits (plus ".L" and a zero terminator).  */
+#define TEMPSYMLEN 13
+  char tempsym[TEMPSYMLEN];
+  AsmSym_t *result;
+
+  if (asmscn == NULL)
+    /* Something went wrong before.  */
+    return NULL;
+
+  /* Generate a temporary symbol if necessary.  */
+  if (name == NULL)
+    {
+      /* If a local symbol name is created the symbol better have
+	 local binding.  */
+      if (binding != STB_LOCAL)
+	{
+	  __libasm_seterrno (ASM_E_INVALID);
+	  return NULL;
+	}
+
+      // XXX This requires getting the format from the machine backend.  */
+      snprintf (tempsym, TEMPSYMLEN, ".L%07u", asmscn->ctx->tempsym_count++);
+
+      name = tempsym;
+    }
+
+  size_t name_len = strlen (name) + 1;
+
+  result = (AsmSym_t *) malloc (sizeof (AsmSym_t) + name_len);
+  if (result == NULL)
+    return NULL;
+
+  rwlock_wrlock (asmscn->ctx->lock);
+
+  result->scn = asmscn;
+  result->offset = asmscn->offset;
+  result->size = size;
+  result->type = type;
+  result->binding = binding;
+  result->symidx = 0;
+  result->strent = dwelf_strtab_add (asmscn->ctx->symbol_strtab,
+				     memcpy (result + 1, name, name_len));
+
+  if (unlikely (asmscn->ctx->textp))
+    {
+      /* We are only interested in the name and don't need to know whether
+	 it is a local name or not.  */
+      /* First print the binding pseudo-op.  */
+      if (binding == STB_GLOBAL)
+	fprintf (asmscn->ctx->out.file, "\t.globl\t%s\n", name);
+      else if (binding == STB_WEAK)
+	fprintf (asmscn->ctx->out.file, "\t.weak\t%s\n", name);
+
+      /* Next the symbol type.  */
+      if (type == STT_OBJECT)
+	fprintf (asmscn->ctx->out.file, "\t.type\t%s,@object\n", name);
+      else if (type == STT_FUNC)
+	fprintf (asmscn->ctx->out.file, "\t.type\t%s,@function\n", name);
+
+      /* Finally the size and the label.  */
+      fprintf (asmscn->ctx->out.file, "\t.size\t%s,%" PRIuMAX "\n%s:\n",
+	       name, (uintmax_t) size, name);
+    }
+  else
+    {
+      /* Put the symbol in the hash table so that we can later find it.  */
+      if (asm_symbol_tab_insert (&asmscn->ctx->symbol_tab, elf_hash (name),
+				 result) != 0)
+	{
+	  /* The symbol already exists.  */
+	  __libasm_seterrno (ASM_E_DUPLSYM);
+	  /* Note that we can free the entry since there must be no
+	     reference in the string table to the string.  We can only
+	     fail to insert the symbol into the symbol table if there
+	     is already a symbol with this name.  In this case the
+	     dwelf_strtab_add function would use the previously provided
+	     name.  */
+	  free (result);
+	  result = NULL;
+	}
+      else if (name != tempsym && asm_emit_symbol_p (name))
+	/* Only count non-private symbols.  */
+	++asmscn->ctx->nsymbol_tab;
+    }
+
+  rwlock_unlock (asmscn->ctx->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libasm/asm_scngrp_newsignature.c b/third_party/elfutils/libasm/asm_scngrp_newsignature.c
new file mode 100644
index 0000000..2fbb334
--- /dev/null
+++ b/third_party/elfutils/libasm/asm_scngrp_newsignature.c
@@ -0,0 +1,46 @@
+/* Update signature of section group.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libasmP.h"
+
+
+int
+asm_scngrp_newsignature (AsmScnGrp_t *grp, AsmSym_t *signature)
+{
+  if (grp == NULL || signature == NULL)
+    return 1;
+
+  grp->signature =  signature;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libasm/disasm_begin.c b/third_party/elfutils/libasm/disasm_begin.c
new file mode 100644
index 0000000..d00852b
--- /dev/null
+++ b/third_party/elfutils/libasm/disasm_begin.c
@@ -0,0 +1,64 @@
+/* Create context descriptor for disassembler.
+   Copyright (C) 2005, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "libasmP.h"
+#include "../libebl/libeblP.h"
+
+
+DisasmCtx_t *
+disasm_begin (Ebl *ebl, Elf *elf, DisasmGetSymCB_t symcb)
+{
+  if (ebl == NULL)
+    return NULL;
+
+  if (ebl->disasm == NULL)
+    {
+      __libasm_seterrno (ASM_E_ENOSUP);
+      return NULL;
+    }
+
+  DisasmCtx_t *ctx = (DisasmCtx_t *) malloc (sizeof (DisasmCtx_t));
+  if (ctx == NULL)
+    {
+      __libasm_seterrno (ASM_E_NOMEM);
+      return NULL;
+    }
+
+  ctx->ebl = ebl;
+  ctx->elf = elf;
+  ctx->symcb = symcb;
+
+  return ctx;
+}
diff --git a/third_party/elfutils/libasm/disasm_cb.c b/third_party/elfutils/libasm/disasm_cb.c
new file mode 100644
index 0000000..cf278c7
--- /dev/null
+++ b/third_party/elfutils/libasm/disasm_cb.c
@@ -0,0 +1,179 @@
+/* Copyright (C) 2005, 2007, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include "libasmP.h"
+#include "../libebl/libeblP.h"
+
+
+struct symtoken
+{
+  DisasmCtx_t *ctx;
+  void *symcbarg;
+};
+
+
+static int
+default_elf_getsym (GElf_Addr addr, Elf32_Word scnndx, GElf_Addr value,
+		    char **buf, size_t *buflen, void *arg)
+{
+  struct symtoken *symtoken = (struct symtoken *) arg;
+
+  /* First try the user provided function.  */
+  if (symtoken->ctx->symcb != NULL)
+    {
+      int res = symtoken->ctx->symcb (addr, scnndx, value, buf, buflen,
+				      symtoken->symcbarg);
+      if (res >= 0)
+	return res;
+    }
+
+  // XXX Look up in ELF file.
+
+  return -1;
+}
+
+
+struct symaddrpair
+{
+  GElf_Addr addr;
+  const char *name;
+};
+
+
+static void
+read_symtab_exec (DisasmCtx_t *ctx)
+{
+  /* We simply use all we can get our hands on.  This will produce
+     some duplicate information but this is no problem, we simply
+     ignore the latter definitions.  */
+  Elf_Scn *scn= NULL;
+  while ((scn = elf_nextscn (ctx->elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      Elf_Data *data;
+      if (shdr == NULL || shdr->sh_type != SHT_SYMTAB
+	  || (data = elf_getdata (scn, NULL)) == NULL)
+	continue;
+
+      int xndxscnidx = elf_scnshndx (scn);
+      Elf_Data *xndxdata = NULL;
+      if (xndxscnidx > 0)
+	xndxdata = elf_getdata (elf_getscn (ctx->elf, xndxscnidx), NULL);
+
+      /* Iterate over all symbols.  Add all defined symbols.  */
+      int nsyms = shdr->sh_size / shdr->sh_entsize;
+      for (int cnt = 1; cnt < nsyms; ++cnt)
+	{
+	  Elf32_Word xshndx;
+	  GElf_Sym sym_mem;
+	  GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem,
+					    &xshndx);
+	  if (sym == NULL)
+	    continue;
+
+	  /* Undefined symbols are useless here.  */
+	  if (sym->st_shndx == SHN_UNDEF)
+	    continue;
+
+
+	}
+    }
+}
+
+
+static void
+read_symtab (DisasmCtx_t *ctx)
+{
+  /* Find the symbol table(s).  */
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (ctx->elf, &ehdr_mem);
+  if (ehdr == NULL)
+    return;
+
+  switch (ehdr->e_type)
+    {
+    case ET_EXEC:
+    case ET_DYN:
+      read_symtab_exec (ctx);
+      break;
+
+    case ET_REL:
+      // XXX  Handle
+      break;
+
+    default:
+      break;
+    }
+}
+
+
+static int
+null_elf_getsym (GElf_Addr addr __attribute__ ((unused)),
+		 Elf32_Word scnndx __attribute__ ((unused)),
+		 GElf_Addr value __attribute__ ((unused)),
+		 char **buf __attribute__ ((unused)),
+		 size_t *buflen __attribute__ ((unused)),
+		 void *arg __attribute__ ((unused)))
+{
+  return -1;
+}
+
+
+int
+disasm_cb (DisasmCtx_t *ctx, const uint8_t **startp, const uint8_t *end,
+	   GElf_Addr addr, const char *fmt, DisasmOutputCB_t outcb,
+	   void *outcbarg, void *symcbarg)
+{
+  struct symtoken symtoken;
+  DisasmGetSymCB_t getsym = ctx->symcb ?: null_elf_getsym;
+
+  if (ctx->elf != NULL)
+    {
+      /* Read all symbols of the ELF file and stuff them into a hash
+	 table.  The key is the address and the section index.  */
+      read_symtab (ctx);
+
+      symtoken.ctx = ctx;
+      symtoken.symcbarg = symcbarg;
+
+      symcbarg = &symtoken;
+
+      getsym = default_elf_getsym;
+    }
+
+  return ctx->ebl->disasm (ctx->ebl, startp, end, addr, fmt, outcb,
+			   getsym, outcbarg, symcbarg);
+}
+INTDEF (disasm_cb)
diff --git a/third_party/elfutils/libasm/disasm_end.c b/third_party/elfutils/libasm/disasm_end.c
new file mode 100644
index 0000000..6878030
--- /dev/null
+++ b/third_party/elfutils/libasm/disasm_end.c
@@ -0,0 +1,45 @@
+/* Release descriptor for disassembler.
+   Copyright (C) 2005, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "libasmP.h"
+
+
+int
+disasm_end (DisasmCtx_t *ctx)
+{
+  free (ctx);
+
+  return 0;
+}
diff --git a/third_party/elfutils/libasm/disasm_str.c b/third_party/elfutils/libasm/disasm_str.c
new file mode 100644
index 0000000..c14e6d5
--- /dev/null
+++ b/third_party/elfutils/libasm/disasm_str.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 2005, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <system.h>
+#include "libasmP.h"
+
+
+struct buffer
+{
+  char *buf;
+  size_t len;
+};
+
+
+static int
+buffer_cb (char *str, size_t len, void *arg)
+{
+  struct buffer *buffer = (struct buffer *) arg;
+
+  if (len > buffer->len)
+    /* Return additional needed space.  */
+    return len - buffer->len;
+
+  buffer->buf = mempcpy (buffer->buf, str, len);
+  buffer->len = len;
+
+  return 0;
+}
+
+
+int
+disasm_str (DisasmCtx_t *ctx, const uint8_t **startp, const uint8_t *end,
+	    GElf_Addr addr, const char *fmt, char **bufp, size_t len,
+	    void *symcbarg)
+{
+  struct buffer buffer = { .buf = *bufp, .len = len };
+
+  int res = INTUSE(disasm_cb) (ctx, startp, end, addr, fmt, buffer_cb, &buffer,
+			       symcbarg);
+  *bufp = buffer.buf;
+  return res;
+}
diff --git a/third_party/elfutils/libasm/libasm.h b/third_party/elfutils/libasm/libasm.h
new file mode 100644
index 0000000..5c61224
--- /dev/null
+++ b/third_party/elfutils/libasm/libasm.h
@@ -0,0 +1,202 @@
+/* Interface for libasm.
+   Copyright (C) 2002, 2005, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBASM_H
+#define _LIBASM_H 1
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include <libebl.h>
+
+
+/* Opaque type for the assembler context descriptor.  */
+typedef struct AsmCtx AsmCtx_t;
+
+/* Opaque type for a section.  */
+typedef struct AsmScn AsmScn_t;
+
+/* Opaque type for a section group.  */
+typedef struct AsmScnGrp AsmScnGrp_t;
+
+/* Opaque type for a symbol.  */
+typedef struct AsmSym AsmSym_t;
+
+
+/* Opaque type for the disassembler context descriptor.  */
+typedef struct DisasmCtx DisasmCtx_t;
+
+/* Type used for callback functions to retrieve symbol name.  The
+   symbol reference is in the section designated by the second parameter
+   at an offset described by the first parameter.  The value is the
+   third parameter.  */
+typedef int (*DisasmGetSymCB_t) (GElf_Addr, Elf32_Word, GElf_Addr, char **,
+				 size_t *, void *);
+
+/* Output function callback.  */
+typedef int (*DisasmOutputCB_t) (char *, size_t, void *);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Create output file and return descriptor for assembler context.  If
+   TEXTP is true the output is an assembler format text file.
+   Otherwise an object file is created.  The MACHINE parameter
+   corresponds to an EM_ constant from <elf.h>, KLASS specifies the
+   class (32- or 64-bit), and DATA specifies the byte order (little or
+   big endian).  */
+extern AsmCtx_t *asm_begin (const char *fname, Ebl *ebl, bool textp);
+
+/* Abort the operation on the assembler context and free all resources.  */
+extern int asm_abort (AsmCtx_t *ctx);
+
+/* Finalize output file and free all resources.  */
+extern int asm_end (AsmCtx_t *ctx);
+
+
+/* Return handle for the named section.  If it was not used before
+   create it.  */
+extern AsmScn_t *asm_newscn (AsmCtx_t *ctx, const char *scnname,
+			     GElf_Word type, GElf_Xword flags);
+
+
+/* Similar to 'asm_newscn', but make it part of section group GRP.  */
+extern AsmScn_t *asm_newscn_ingrp (AsmCtx_t *ctx, const char *scnname,
+				   GElf_Word type, GElf_Xword flags,
+				   AsmScnGrp_t *grp);
+
+/* Create new subsection NR in the given section.  */
+extern AsmScn_t *asm_newsubscn (AsmScn_t *asmscn, unsigned int nr);
+
+
+/* Return handle for new section group.  The signature symbol can be
+   set later.  */
+extern AsmScnGrp_t *asm_newscngrp (AsmCtx_t *ctx, const char *grpname,
+				   AsmSym_t *signature, Elf32_Word flags);
+
+/* Set or overwrite signature symbol for group.  */
+extern int asm_scngrp_newsignature (AsmScnGrp_t *grp, AsmSym_t *signature);
+
+
+/* Add zero terminated string STR of size LEN to (sub)section ASMSCN.  */
+extern int asm_addstrz (AsmScn_t *asmscn, const char *str, size_t len);
+
+/* Add 8-bit signed integer NUM to (sub)section ASMSCN.  */
+extern int asm_addint8 (AsmScn_t *asmscn, int8_t num);
+
+/* Add 8-bit unsigned integer NUM to (sub)section ASMSCN.  */
+extern int asm_adduint8 (AsmScn_t *asmscn, uint8_t num);
+
+/* Add 16-bit signed integer NUM to (sub)section ASMSCN.  */
+extern int asm_addint16 (AsmScn_t *asmscn, int16_t num);
+
+/* Add 16-bit unsigned integer NUM to (sub)section ASMSCN.  */
+extern int asm_adduint16 (AsmScn_t *asmscn, uint16_t num);
+
+/* Add 32-bit signed integer NUM to (sub)section ASMSCN.  */
+extern int asm_addint32 (AsmScn_t *asmscn, int32_t num);
+
+/* Add 32-bit unsigned integer NUM to (sub)section ASMSCN.  */
+extern int asm_adduint32 (AsmScn_t *asmscn, uint32_t num);
+
+/* Add 64-bit signed integer NUM to (sub)section ASMSCN.  */
+extern int asm_addint64 (AsmScn_t *asmscn, int64_t num);
+
+/* Add 64-bit unsigned integer NUM to (sub)section ASMSCN.  */
+extern int asm_adduint64 (AsmScn_t *asmscn, uint64_t num);
+
+
+/* Add signed little endian base 128 integer NUM to (sub)section ASMSCN.  */
+extern int asm_addsleb128 (AsmScn_t *asmscn, int32_t num);
+
+/* Add unsigned little endian base 128 integer NUM to (sub)section ASMSCN.  */
+extern int asm_adduleb128 (AsmScn_t *asmscn, uint32_t num);
+
+
+/* Define new symbol NAME for current position in given section ASMSCN.  */
+extern AsmSym_t *asm_newsym (AsmScn_t *asmscn, const char *name,
+			     GElf_Xword size, int type, int binding);
+
+
+/* Define new common symbol NAME with given SIZE and alignment.  */
+extern AsmSym_t *asm_newcomsym (AsmCtx_t *ctx, const char *name,
+				GElf_Xword size, GElf_Addr align);
+
+/* Define new common symbol NAME with given SIZE, VALUE, TYPE, and BINDING.  */
+extern AsmSym_t *asm_newabssym (AsmCtx_t *ctx, const char *name,
+				GElf_Xword size, GElf_Addr value,
+				int type, int binding);
+
+
+/* Align (sub)section offset according to VALUE.  */
+extern int asm_align (AsmScn_t *asmscn, GElf_Word value);
+
+/* Set the byte pattern used to fill gaps created by alignment.  */
+extern int asm_fill (AsmScn_t *asmscn, void *bytes, size_t len);
+
+
+/* Return ELF descriptor created for the output file of the given context.  */
+extern Elf *asm_getelf (AsmCtx_t *ctx);
+
+
+/* Return error code of last failing function call.  This value is kept
+   separately for each thread.  */
+extern int asm_errno (void);
+
+/* Return error string for ERROR.  If ERROR is zero, return error string
+   for most recent error or NULL is none occurred.  If ERROR is -1 the
+   behaviour is similar to the last case except that not NULL but a legal
+   string is returned.  */
+extern const char *asm_errmsg (int __error);
+
+
+/* Create context descriptor for disassembler.  */
+extern DisasmCtx_t *disasm_begin (Ebl *ebl, Elf *elf, DisasmGetSymCB_t symcb);
+
+/* Release descriptor for disassembler.  */
+extern int disasm_end (DisasmCtx_t *ctx);
+
+/* Produce of disassembly output for given memory, store text in
+   provided buffer.  */
+extern int disasm_str (DisasmCtx_t *ctx, const uint8_t **startp,
+		       const uint8_t *end, GElf_Addr addr, const char *fmt,
+		       char **bufp, size_t len, void *symcbarg);
+
+/* Produce disassembly output for given memory and output it using the
+   given callback functions.  */
+extern int disasm_cb (DisasmCtx_t *ctx, const uint8_t **startp,
+		      const uint8_t *end, GElf_Addr addr, const char *fmt,
+		      DisasmOutputCB_t outcb, void *outcbarg, void *symcbarg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* libasm.h */
diff --git a/third_party/elfutils/libasm/libasm.map b/third_party/elfutils/libasm/libasm.map
new file mode 100644
index 0000000..a36cdbf
--- /dev/null
+++ b/third_party/elfutils/libasm/libasm.map
@@ -0,0 +1,38 @@
+ELFUTILS_1.0 {
+  global:
+    asm_abort;
+    asm_addint16;
+    asm_addint32;
+    asm_addint64;
+    asm_addint8;
+    asm_addsleb128;
+    asm_addstrz;
+    asm_adduint16;
+    asm_adduint32;
+    asm_adduint64;
+    asm_adduint8;
+    asm_adduleb128;
+    asm_align;
+    asm_begin;
+    asm_end;
+    asm_errmsg;
+    asm_errno;
+    asm_fill;
+    asm_getelf;
+    asm_newabssym;
+    asm_newcomsym;
+    asm_newscn;
+    asm_newscn_ingrp;
+    asm_newscngrp;
+    asm_newsubscn;
+    asm_newsym;
+    asm_scngrp_newsignature;
+
+    disasm_begin;
+    disasm_cb;
+    disasm_end;
+    disasm_str;
+
+  local:
+    *;
+};
diff --git a/third_party/elfutils/libasm/libasmP.h b/third_party/elfutils/libasm/libasmP.h
new file mode 100644
index 0000000..54460cf
--- /dev/null
+++ b/third_party/elfutils/libasm/libasmP.h
@@ -0,0 +1,309 @@
+/* Internal definitions for libasm.
+   Copyright (C) 2002, 2004, 2005, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBASMP_H
+#define _LIBASMP_H 1
+
+#include <stdio.h>
+
+#include <libasm.h>
+
+#include "libdwelf.h"
+
+/* gettext helper macros.  */
+#define _(Str) dgettext ("elfutils", Str)
+
+
+/* Known error codes.  */
+enum
+  {
+    ASM_E_NOERROR,
+    ASM_E_NOMEM,		/* No more memory.  */
+    ASM_E_CANNOT_CREATE,	/* Output file cannot be created.  */
+    ASM_E_INVALID,		/* Invalid parameters.  */
+    ASM_E_CANNOT_CHMOD,		/* Cannot change mode of output file.  */
+    ASM_E_CANNOT_RENAME,	/* Cannot rename output file.  */
+    ASM_E_DUPLSYM,		/* Duplicate symbol definition.  */
+    ASM_E_LIBELF,		/* Refer to error in libelf.  */
+    ASM_E_TYPE,			/* Invalid section type for operation.  */
+    ASM_E_IOERROR,		/* Error during output of data.  */
+    ASM_E_ENOSUP,		/* No backend support.  */
+    ASM_E_NUM			/* Keep this entry as the last.  */
+  };
+
+
+/* Special sections.  */
+#define ASM_ABS_SCN ((Elf_Scn *) 1)
+#define ASM_COM_SCN ((Elf_Scn *) 2)
+
+
+/* And the hash table for symbols.  */
+#include <symbolhash.h>
+
+
+/* Descriptor for a section.  */
+struct AsmScn
+{
+  /* The underlying assembler context.  */
+  AsmCtx_t *ctx;
+
+  /* Subsection ID.  */
+  unsigned int subsection_id;
+
+  /* Section type.  */
+  GElf_Word type;
+
+  union
+  {
+    /* Data only stored in the record for subsection zero.  */
+    struct
+    {
+      /* The ELF section.  */
+      Elf_Scn *scn;
+
+      /* Entry in the section header string table.  */
+      Dwelf_Strent *strent;
+
+      /* Next member of group.  */
+      struct AsmScn *next_in_group;
+    } main;
+
+    /* Pointer to the record for subsection zero.  */
+    AsmScn_t *up;
+  } data;
+
+  /* Current offset in the (sub)section.  */
+  GElf_Off offset;
+  /* Maximum alignment of the section so far.  */
+  GElf_Word max_align;
+
+  /* Section content.  */
+  struct AsmData
+  {
+    /* Currently used number of bytes in the block.  */
+    size_t len;
+
+    /* Number of bytes allocated.  */
+    size_t maxlen;
+
+    /* Pointer to the next block.  */
+    struct AsmData *next;
+
+    /* The actual data.  */
+    char data[flexarr_size];
+  } *content;
+
+  /* Fill pattern.  */
+  struct FillPattern
+  {
+    size_t len;
+    char bytes[flexarr_size];
+  } *pattern;
+
+  /* Next subsection.  */
+  AsmScn_t *subnext;
+
+  /* List of all allocated sections.  */
+  AsmScn_t *allnext;
+
+  /* Name of the section.  */
+  char name[flexarr_size];
+};
+
+
+/* Descriptor used for the assembling session.  */
+struct AsmCtx
+{
+  /* File descriptor of the temporary file.  */
+  int fd;
+
+  /* True if text output is wanted.  */
+  bool textp;
+
+  /* Output file handle.  */
+  union
+  {
+    /* ELF descriptor of the temporary file.  */
+    Elf *elf;
+    /* I/O stream for text output.  */
+    FILE *file;
+  } out;
+
+
+  /* List with defined sections.  */
+  AsmScn_t *section_list;
+  /* Section header string table.  */
+  Dwelf_Strtab *section_strtab;
+
+  /* Table with defined symbols.  */
+  asm_symbol_tab symbol_tab;
+  /* Number of symbols in the table.  */
+  unsigned int nsymbol_tab;
+  /* Symbol string table.  */
+  Dwelf_Strtab *symbol_strtab;
+
+  /* List of section groups.  */
+  struct AsmScnGrp *groups;
+  /* Number of section groups.  */
+  size_t ngroups;
+
+  /* Current required alignment for common symbols.  */
+  GElf_Word common_align;
+
+  /* Lock to handle multithreaded programs.  */
+  rwlock_define (,lock);
+
+  /* Counter for temporary symbols.  */
+  unsigned int tempsym_count;
+
+  /* Name of the output file.  */
+  char *fname;
+  /* The name of the temporary file.  */
+  char tmp_fname[flexarr_size];
+};
+
+
+/* Descriptor for a symbol.  */
+struct AsmSym
+{
+  /* Reference to the section which contains the symbol.  */
+  AsmScn_t *scn;
+
+  /* Type of the symbol.  */
+  int8_t type;
+  /* Binding of the symbol.  */
+  int8_t binding;
+
+  /* Size of the symbol.  */
+  GElf_Xword size;
+
+  /* Offset in the section.  */
+  GElf_Off offset;
+
+  /* Symbol table index of the symbol in the symbol table.  */
+  size_t symidx;
+
+  /* Reference to name of the symbol.  */
+  Dwelf_Strent *strent;
+};
+
+
+/* Descriptor for section group.  */
+struct AsmScnGrp
+{
+  /* Entry in the section header string table.  */
+  Dwelf_Strent *strent;
+
+  /* The ELF section.  */
+  Elf_Scn *scn;
+
+  /* The signature.  */
+  struct AsmSym *signature;
+
+  /* First member.  */
+  struct AsmScn *members;
+  /* Number of members.  */
+  size_t nmembers;
+
+  /* Flags.  */
+  Elf32_Word flags;
+
+  /* Next group.  */
+  struct AsmScnGrp *next;
+
+  /* Name of the section group.  */
+  char name[flexarr_size];
+};
+
+
+/* Descriptor for disassembler.   */
+struct DisasmCtx
+{
+  /* Handle for the backend library with the disassembler routine.  */
+  Ebl *ebl;
+
+  /* ELF file containing all the data passed to the function.  This
+     allows to look up symbols.  */
+  Elf *elf;
+
+  /* Callback function to determine symbol names.  */
+  DisasmGetSymCB_t symcb;
+};
+
+
+/* The default fill pattern: one zero byte.  */
+extern const struct FillPattern *__libasm_default_pattern
+     attribute_hidden;
+
+
+/* Ensure there are at least LEN bytes available in the output buffer
+   for ASMSCN.  */
+extern int __libasm_ensure_section_space (AsmScn_t *asmscn, size_t len)
+     internal_function;
+
+/* Free all resources associated with the assembler context.  */
+extern void __libasm_finictx (AsmCtx_t *ctx) internal_function;
+
+/* Set error code.  */
+extern void __libasm_seterrno (int err) internal_function;
+
+/* Return handle for the named section.  If it was not used before
+   create it.  */
+extern AsmScn_t *__asm_newscn_internal (AsmCtx_t *ctx, const char *scnname,
+					GElf_Word type, GElf_Xword flags)
+     attribute_hidden;
+
+
+/* Internal aliases of the asm_addintXX functions.  */
+extern int __asm_addint8_internal (AsmScn_t *asmscn, int8_t num)
+     attribute_hidden;
+extern int __asm_addint16_internal (AsmScn_t *asmscn, int16_t num)
+     attribute_hidden;
+extern int __asm_addint32_internal (AsmScn_t *asmscn, int32_t num)
+     attribute_hidden;
+extern int __asm_addint64_internal (AsmScn_t *asmscn, int64_t num)
+     attribute_hidden;
+
+
+/* Produce disassembly output for given memory and output it using the
+   given callback functions.  */
+extern int __disasm_cb_internal (DisasmCtx_t *ctx, const uint8_t **startp,
+				 const uint8_t *end, GElf_Addr addr,
+				 const char *fmt, DisasmOutputCB_t outcb,
+				 void *outcbarp, void *symcbarg)
+     attribute_hidden;
+
+
+/* Test whether given symbol is an internal symbol and if yes, whether
+   we should nevertheless emit it in the symbol table.  */
+// XXX The second part should probably be controlled by an option which
+// isn't implemented yet
+// XXX Also, the format will change with the backend.
+#define asm_emit_symbol_p(name) (strncmp (name, ".L", 2) != 0)
+
+#endif	/* libasmP.h */
diff --git a/third_party/elfutils/libasm/symbolhash.c b/third_party/elfutils/libasm/symbolhash.c
new file mode 100644
index 0000000..57c9e76
--- /dev/null
+++ b/third_party/elfutils/libasm/symbolhash.c
@@ -0,0 +1,54 @@
+/* Symbol hash table implementation.
+   Copyright (C) 2001, 2002, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <libasmP.h>
+#include <libebl.h>
+
+/* Definitions for the symbol hash table.  */
+#define TYPE AsmSym_t *
+#define NAME asm_symbol_tab
+#define ITERATE 1
+#define REVERSE 1
+#define COMPARE(a, b) \
+  strcmp (dwelf_strent_str ((a)->strent), dwelf_strent_str ((b)->strent))
+
+#define next_prime __libasm_next_prime
+extern size_t next_prime (size_t) attribute_hidden;
+
+#include "../lib/dynamicsizehash.c"
+
+#undef next_prime
+#define next_prime attribute_hidden __libasm_next_prime
+#include "../lib/next_prime.c"
diff --git a/third_party/elfutils/libasm/symbolhash.h b/third_party/elfutils/libasm/symbolhash.h
new file mode 100644
index 0000000..d05a40a
--- /dev/null
+++ b/third_party/elfutils/libasm/symbolhash.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 2001, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef SYMBOLHASH_H
+#define SYMBOLHASH_H	1
+
+/* Definitions for the symbol hash table.  */
+#define TYPE AsmSym_t *
+#define NAME asm_symbol_tab
+#define ITERATE 1
+#define COMPARE(a, b) \
+  strcmp (dwelf_strent_str ((a)->strent), dwelf_strent_str ((b)->strent))
+#include <dynamicsizehash.h>
+
+#endif	/* symbolhash.h */
diff --git a/third_party/elfutils/libcpu/ChangeLog b/third_party/elfutils/libcpu/ChangeLog
new file mode 100644
index 0000000..86d2947
--- /dev/null
+++ b/third_party/elfutils/libcpu/ChangeLog
@@ -0,0 +1,457 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* i386_disasm.c (i386_disasm): Use FALLTHOUGH macro instead of
+	comment.
+
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* memory-access.h: Use attribute_packed.
+
+2017-02-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpic_CFLAGS.
+
+2017-07-18  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am: Don't check HAVE_LINUX_BPF_H, just define libcpu_bpf.
+	* bpf_disasm.c: Include bpf.h instead of linux/bpf.h. Don't define
+	BPF_PSEUDO_MAP_FD.
+
+2017-04-20  Ulf Hermann <ulf.hermann@qt.io>
+
+	* Makefile.am: Add EXEEXT to gendis.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* i386_parse.y: Eliminate comparison_fn_t.
+
+2016-11-02  Mark Wielaard  <mjw@redhat.com>
+
+	* i386_disasm.c (i386_disasm): Add fallthrough comment.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* i386_lex.l: Remove system.h include, add libeu.h include.
+	* i386_parse.y: Remove sys/param.h include, add libeu.h include.
+	* i386_disasm.c: Remove sys/param.h.
+
+2016-09-05  Mark Wielaard  <mjw@redhat.com>
+
+	* bpf_disasm.c: Define BPF_PSEUDO_MAP_FD if undefined.
+
+2016-08-10  Richard Henderson  <rth@redhat.com>
+
+	* bpf_disasm.c (bpf_disasm): Rearrange the printing of instructions
+	to use exactly the operands required.
+
+2016-06-28  Richard Henderson  <rth@redhat.com>
+
+	* Makefile.am (noinst_LIBRARIES): Add libcpu_bpf.a.
+	(libcpu_bpf_a_SOURCES, libcpu_bpf_a_CFLAGS): New.
+	* bpf_disasm.c: New file.
+	* i386_disasm.c (i386_disasm): Add ebl parameter.
+
+2015-10-05  Josh Stone  <jistone@redhat.com>
+
+	* Makefile.am (%_defs): Add AM_V_GEN and AM_V_at silencers.
+	($(srcdir)/%_dis.h): Ditto.
+	(%.mnemonics): Add AM_V_GEN silencer.
+
+2014-10-29  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid
+	relocation overflows in some platforms.
+
+2014-04-13  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (i386_gendis_LDADD): Remove libmudflap.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+
+2012-10-10  Roland McGrath  <roland@hack.frob.com>
+
+	* Makefile.am (%_defs, $(srcdir)/%_dis.h): Redirect to temp file,
+	mv into place with separate command.
+
+2012-06-26  Roland McGrath  <roland@hack.frob.com>
+
+	* Makefile.am [!MAINTAINER_MODE] ($(srcdir)/%_dis.h): New rule.
+
+2012-02-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (CLEANFILES): Move %_dis.h to...
+	(MAINTAINERCLEANFILES): here.
+
+2012-01-21  Ulrich Drepper  <drepper@gmail.com>
+
+	* i386_disasm.c (ADD_NSTRING): Define.
+	(i386_disasm): Print color codes in the appropriate places.
+
+2011-10-16  Roland McGrath  <roland@hack.frob.com>
+
+	* Makefile.am (libcpu_i386_a_SOURCES): Add i386_dis.h.
+	(libcpu_x86_64_a_SOURCES): Add x86_64_dis.h.
+	(i386_disasm.o, x86_64_disasm.o): Depend on those in $(srcdir).
+	(%_dis.h): Renamed target pattern to ...
+	($(srcdir)/%_dis.h): ... this.
+	(noinst_HEADERS, noinst_PROGRAMS): Put under [MAINTAINER_MODE].
+
+2010-08-16  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (%_defs): New pattern rule.
+	(%_dis.h, %.mnemonics): Define as pattern rules using %_defs input.
+	(CLEANFILES): Include all those files.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Use config/eu.am for common stuff.
+
+2009-04-14  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add -fdollars-in-identifiers; it is not the
+	default on every machine.
+
+2009-01-23  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (i386_parse_CFLAGS): Use quotes around command
+	substitution that can produce leading whitespace.
+
+2009-01-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_parse.y (instrtable_out): Optimize match_data table by not
+	emitting 0xff masks for leading bytes.
+	* i386_disasm.c (i386_disasm): Adjust reader of match_data.
+
+	* i386_disasm.c (i386_disasm): Reset bufcnt when not matched.  We
+	don't expect snprintf to fail.
+
+2008-12-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Add dppd, dpps, insertps, movntdqa, mpsadbw, packusdw,
+	pblendvb, pblendw, pcmpeqq, pcmpestri, pcmpestrm, pcmpistri, pcmpistrm,
+	pcmpgtq, phminposuw, pinsrb, pinsrd, pmaxsb, pmaxsd, pmaxud, pmaxuw,
+	pminsb, pminsd, pminud, pminuw, pmovsxbw, pmovsxbd, pmovsxbq, pmovsxwd,
+	pmovsxwq, pmovsxdq, pmovzxbw, pmovzxbd, pmovzxbq, pmovzxwd, pmovzxwq,
+	pmovzxdq, pmuldq, pmulld, popcnt, ptest, roundss, roundps, roundpd,
+	and roundsd opcodes.
+
+	* i386_disasm.c (i386_disasm): Correct resizing of buffer.
+
+	* i386_parse.y (struct argstring): Add off element.
+	(off_op_str): New global variable.
+	(print_op_str): Print strings as concatenated strings.  Keep track
+	of index and length.  Update ->off element.
+	(print_op_str_idx): New function.
+	(instrtable_out): Mark op%d_fct as const.
+	Emit two tables for the strings: the string itself (op%d_str) and the
+	index table (op%d_str_idx).
+	* i386_disasm.c (i386_disasm): Adjust for new op%d_str definition.
+
+	* i386_disasm.c [X86_64] (i386_disasm): Handle rex prefix when
+	printing only prefix.
+
+	* i386_disasm.c (i386_disasm): Minor optimizations.
+
+	* i386_parse.y (instrtable_out): No need to emit index, the reader can
+	keep track.
+	* i386_disasm.c (i386_disasm): The index is not emitted anymore, no
+	need to skip it.
+
+	* i386_disasm.c (amd3dnow): Mark as const.
+
+	* defs/i386: Add blendvpd and blendvps opcodes.
+
+2008-12-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Add blendpd and blendps opcodes.
+
+2008-12-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Add entry for AMD 3DNOW.
+	* i386_disasm.c: Implement AMD 3DNOW disassembly.
+
+2008-12-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_disasm.c (i386_disasm): If instruction matches prefix,
+	undoing the prefix match finishes the instruction.
+
+2008-01-21  Roland McGrath  <roland@redhat.com>
+
+	* defs/i386: Fix typo in comment.
+	* i386_disasm.c (i386_disasm): Handle cltq, cqto.
+
+	* i386_parse.y: Add sanity check for NMNES macro value.
+	* Makefile.am (i386_parse.o): Fix target in dependency rule.
+	(i386_parse.h): New target with empty commands.
+	(i386_lex.o): Depend on it in place of i386_parse.c.
+
+2008-01-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Remove defs/x86_64.
+
+2008-01-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Add fixes for opcodes with register number in opcode,
+	64-bit immediate forms, nop with rex.B.
+	* i386_data.h [X86_64] (FCT_imm64$w): New function.
+	(FCT_oreg): New function.
+	(FCT_oreg$w): New function.
+	* i386_disasm.c (i386_disasm): Reinitialize fmt always before
+	starting the loop to process the string.  Handle 0x90 special for
+	x86-64.
+	* i386_parse.y (fillin_arg): Expand synonyms before concatening to
+	form the function name.
+
+2008-01-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_disasm.c (struct output_buffer): Remove symcb and symcbarg.
+	(i386_disasm): Remove appropriate initializers.
+	Use symcb to lookup symbol strings.
+
+	* i386_disasm.c (struct output_buffer): Add labelbuf, labelbufsize,
+	symaddr_use, and symaddr fields.
+	(i386_disasm): Remove labelbuf and labelbufsize variables.
+	Add back %e format.  Implement %a and %l formats.
+
+	* i386_data.h (general_mod$r_m): Set symaddr_use and symaddr for %rip
+	base addressing.
+
+	* i386_disasm.c (i386_disasm): Resize output buffer if necessary.
+	Optimize output_data initialization.  Free buffers before return.
+	(struct output_data): Remove op1str field.  Adjust code.
+	(i386_disasm): Store final NUL btye at end of functions.
+
+2008-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_data.h (FCT_crdb): New function.
+	(FCT_ccc): Use FCT_crdb.
+	(FCT_ddd): Likewise.
+
+	* defs/i386: Fix a few instructions with immediate arguments.
+
+	* i386_disasm.c: Rewrite interface to callback functions for operands
+	to take a single pointer to a structure.
+	* i386_data.h: Adjust all functions.
+
+2008-01-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Enable x86-64 again.
+	* defs/i386: Lots of changes for x86-64.
+	* i386_data.h: Add support for use in x86-64 disassembler.
+	* i386_disasm.c: Likewise.
+	* i386_parse.y: Likewise.
+	* defs/x86_64: Removed.
+
+2008-01-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Cleanups, remove masks which are not needed.
+	Add remaining Intel opcodes.
+	* i386_data.h (FCT_imm8): Check for input buffer overrun.
+	* i386_disasm.c (i386_disasm): Likewise.
+	* i386_parse.y: Remove suffixes which are not needed anymore.
+
+2008-01-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Add yet more SSE instructions.
+
+2008-01-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_disasm.c (i386_disasm): Extend matcher to allow tables to
+	contain instructions with prefixes.
+	* defs/i386: Use for many SSE operations.
+	* i386_data.h (FCT_mmxreg2): Removed.
+
+2008-01-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: More 0f prefix support.
+	* i386_data.h (FCT_mmxreg): Implement.
+	(FCT_mmxreg2): Implement.
+	(FCT_mmreg): Remove.
+	* i386_disasm.c (i386_disasm): More special instructions.
+	Fix tttn suffix for cmov.
+	* i386_parse.y: Simplify test for mod/r_m mode.
+
+2007-12-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Fix order or arguments for mov of control/debug registers.
+	* i386_data.h (FCT_ccc): Implement
+	(FCT_ddd): Implement
+
+2007-12-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Fix 0f groups 6 and 7.
+	* i386_data.c (FCT_mod$16r_m): Implement.
+	* i386_disasm.c (i386_disasm): Third parameter can also have string.
+
+2007-12-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Add lots of floating point ops.
+	* i386_data.h (FCT_fmod$fr_m): Removed.
+	(FCT_freg): Implement.
+	* i386_disasm.c (i386_disasm): Implement suffix_D.
+	* i386_parse.y: Emit suffix_D.
+
+	* defs/i386: Use rel instead of dispA.
+	Fix lcall, dec, div, idiv, imul, inc, jmp, ljmp, mul, neg, not, push,
+	test.
+
+	* i386_data.h (FCT_dispA): Removed.
+	(FCT_ds_xx): Add test for end of input buffer.
+	* i386_disasm.c (ABORT_ENTRY): Removed.
+	(i386_disasm): Fix handling of SIB.  Pass correct address value to
+	operand callbacks.
+
+	* Makefile.am (*.mnemonics): Filter out INVALID entry.
+	* defs/i386: Define imms8 and use in appropriate places.
+	Add INVALID entries for special opcodes with special mnemonics.
+	Fix int3.  Fix typo in shl.  Correct xlat.
+	* i386_data.h (FCT_ds_xx): New function.
+	(FCT_ds_si): Use it.
+	(FCT_ds_bx): New function.
+	(FCT_imms8): New function.
+	* i386_disasm.c (MNE_INVALID): Define.
+	(i386_disasm): Handle invalid opcodes in mnemonics printing, not
+	separately.  Fix address value passed to operand handlers.
+	* i386_parse.y (bx_reg): Define.
+	(instrtable_out): Handle INVALID entries differently, just use
+	MNE_INVALID value for .mnemonic.
+
+2007-12-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Fix shift and mov immediate instructions.
+	* i386_data.h (FCT_imm16): Implement.
+
+	* defs/i386: Use absval instead of abs of lcall and ljmp.
+	Add parameters for cmps.  Fix test and mov immediate.
+	* i386_data.h: Implement FCT_absval.
+	* i386_disasm.c: Handle data16 for suffix_w  and FCT_imm.
+
+	* defs/i386: Move entries with 0x9b prefix together.
+	* i386_disasm.c (i386_disasm): Fix recognizing insufficient bytes in
+	input.  Handle data16 with suffix_W.
+
+	* i386_data.h (FCT_*): Add end parameter to all functions.  Check
+	before using more bytes.
+	(FCT_sel): Implement.
+	* i386_disasm.c (i386_disasm): Better handle end of input buffer.
+	Specal opcode 0x99.
+
+	* Makefile.am: Use m4 to preprocess defs/* files.
+	* defs/i386: Adjust appropriately.
+	* i386_data.c (FCT_ax): Implement.
+	(FCT_ax$w): Use FCT_ax.
+	* i386_disasm.c (ADD_STRING): Use _len instead of len.
+	(i386_disasm): If no instruction can be matched because of lack of
+	input and prefixes have been matched, print prefixes.
+	Recognize abort entries.
+	Handle special cases.
+	* i386_gendis.c: Recognize - input file name.
+	* i386_lex.c: Recognize INVALID token.
+	* i386_parse.y: Handle INVALID token input.
+
+	* defs/i386: Fix mov, pop.
+	* i386_data.h (FCT_sreg3): Implement.
+
+2007-12-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Fix adc, add, cmp, or, sbb, sub, xchg, xor.
+	* i386_data.h (FCT_imms): New function.
+	(FCT_imm$s): Use FCT_imms for handling of signed values.
+	(FCT_imm8): Sign extend values.
+	* i386_disasm.c (i386_disasm): Implement suffix_w0.
+	* i386_parse.y: Emit suffix w0.
+
+	* i386_data.h (FCT_disp8): Add 0x prefix.
+	(FCT_ds_si): Implement.
+	* i386_disasm.c (i386_disasm): Increment addr for invalid prefixes.
+	Implement tttn suffix.
+	* i386_parse.y: Emit tttn suffix definition.
+
+2007-12-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_data.h (struct instr_enc): Use suffix field.
+	(FCT_dx): Fill in body.
+	(FCT_es_di): Likewise.
+	(FCT_imm$s): Sign-extended byte values.
+	* i386_disasm.c: Protect ADD_CHAR and ADD_STRING macros.  Adjust uses.
+	(i386_disasm): Handle suffix.
+	* i386_parse.y: Emit suffix information.
+	* defs/i386: Remove unnecessary suffixes.
+
+	* Makefile.am: Disable building x86-64 version for now.
+
+	* defs/i386: Fix and, bound, cmp, or, pop, sbb, sub, xor.
+	* i386_data.h: Pass pointer to prefix to functions.  If not prefixes
+	are consumed this means invalid input.
+	* i386_disasm.c: Fix prefix printing.  Adjust function calls for
+	parameter change.
+	* i386_parse.y: Recognize moda prefix.
+
+2007-12-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_data.h: Fix SIB handling.
+	* i386_disasm.c: Likewise.
+
+2007-12-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* defs/i386: Fix up 'and' opcode.
+
+2007-10-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Add dependencies of the generated files on the source
+	files.
+	(i386_lex_CFLAGS): Add -Wno-sign-compare.
+
+	* defs/i386: A lot more data.
+	* defs/x86_64: Likewise.
+	* i386_data.h (struct instr_enc): Add off1_3, off2_3, and off3_3
+	fields.
+	(opfct_t): Add parameter for third operand.
+	(FCT_*): Likewise.
+	(data_prefix): New function.
+	(FCT_abs): Implement.
+	(FCT_ax): Renamed to FCT_ax$w amd implement.
+	(FCT_disp8): Implement.
+	(FCT_dispA): Implement.
+	(FCT_imm): Implement.
+	(FCT_imm$w): Implement.
+	(FCT_imm$s): Don't zero-pad numbers.
+	(FCT_imm8): Likewise.
+	(FCT_rel): Likewise.
+	(general_mod$r_m): New function.
+	(FCT_mod$r_m): Use it.
+	(FCT_mod$r_m$w): New function.
+	(FCT_mod$8r_m): New function.
+	(FCT_reg): Correctly handle 16-bit registers.
+	(FCT_reg$w): New function.
+	* i386_disasm.c (i386_disasm): Handle prefixes better.
+	Pass third parameter to operand functions.
+	* i386_parse.y (struct instruction): Add off3 field.
+	Handle third operand throughout.
+
+2007-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_disasm.c: New file.
+	* i386_data.h: New file.
+	* i386_gendis.c: New file.
+	* i386_lex.l: New file.
+	* i386_parse.y: New file.
+	* memory-access.h: New file.
+	* x86_64_disasm.c: New file.
+	* defs/i386: New file.
+	* defs/i386.doc: New file.
+	* defs/x86_64: New file.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile (AM_CFLAGS): Add -Wunused -Wextra -Wformat=2.
+
+2005-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Define, instead of adding things to DEFS.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* Moved to CVS archive.
diff --git a/third_party/elfutils/libcpu/Makefile.am b/third_party/elfutils/libcpu/Makefile.am
new file mode 100644
index 0000000..4c8778d
--- /dev/null
+++ b/third_party/elfutils/libcpu/Makefile.am
@@ -0,0 +1,92 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 2002-2012 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * 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
+##
+## or both in parallel, as here.
+##
+## elfutils 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.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+	    -I$(srcdir)/../libdw -I$(srcdir)/../libasm
+AM_CFLAGS += $(fpic_CFLAGS) -fdollars-in-identifiers
+LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) -P$(<F:lex.l=)
+LEX_OUTPUT_ROOT = lex.$(<F:lex.l=)
+AM_YFLAGS = -p$(<F:parse.y=)
+
+noinst_LIBRARIES = libcpu_i386.a libcpu_x86_64.a
+
+libcpu_i386_a_SOURCES = i386_disasm.c i386_dis.h
+libcpu_x86_64_a_SOURCES = x86_64_disasm.c x86_64_dis.h
+
+i386_gendis_SOURCES = i386_gendis.c i386_lex.l i386_parse.y
+
+i386_disasm.o: i386.mnemonics $(srcdir)/i386_dis.h
+x86_64_disasm.o: x86_64.mnemonics $(srcdir)/x86_64_dis.h
+
+noinst_LIBRARIES += libcpu_bpf.a
+libcpu_bpf_a_SOURCES = bpf_disasm.c
+libcpu_bpf_a_CFLAGS = $(AM_CFLAGS) -Wno-format-nonliteral
+
+%_defs: $(srcdir)/defs/i386
+	$(AM_V_GEN)m4 -D$* -DDISASSEMBLER $< > $@T
+	$(AM_V_at)mv -f $@T $@
+
+if MAINTAINER_MODE
+noinst_HEADERS = memory-access.h i386_parse.h i386_data.h
+
+noinst_PROGRAMS = i386_gendis$(EXEEXT)
+
+$(srcdir)/%_dis.h: %_defs i386_gendis$(EXEEXT)
+	$(AM_V_GEN)./i386_gendis$(EXEEXT) $< > $@T
+	$(AM_V_at)mv -f $@T $@
+
+else
+
+$(srcdir)/%_dis.h:
+	@echo '*** missing $@; configure with --enable-maintainer-mode'
+	@false
+
+endif
+
+%.mnemonics: %_defs
+	$(AM_V_GEN)sed '1,/^%%/d;/^#/d;/^[[:space:]]*$$/d;s/[^:]*:\([^[:space:]]*\).*/MNE(\1)/;s/{[^}]*}//g;/INVALID/d' \
+	  $< | sort -u > $@
+
+i386_lex_no_Werror = yes
+
+libeu = ../lib/libeu.a
+
+i386_lex_CFLAGS = -Wno-unused-label -Wno-unused-function -Wno-sign-compare
+i386_parse.o: i386_parse.c i386.mnemonics
+i386_parse_CFLAGS = -DNMNES="`wc -l < i386.mnemonics`"
+i386_lex.o: i386_parse.h
+i386_gendis_LDADD = $(libeu) -lm
+
+i386_parse.h: i386_parse.c ;
+
+EXTRA_DIST = defs/i386
+
+CLEANFILES += $(foreach P,i386 x86_64,$P_defs $P.mnemonics)
+MAINTAINERCLEANFILES = $(foreach P,i386 x86_64, $P_dis.h)
diff --git a/third_party/elfutils/libcpu/bpf_disasm.c b/third_party/elfutils/libcpu/bpf_disasm.c
new file mode 100644
index 0000000..054aba2
--- /dev/null
+++ b/third_party/elfutils/libcpu/bpf_disasm.c
@@ -0,0 +1,480 @@
+/* Disassembler for BPF.
+   Copyright (C) 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include "bpf.h"
+
+#include "../libelf/common.h"
+#include "../libebl/libeblP.h"
+
+static const char class_string[8][8] = {
+  [BPF_LD]    = "ld",
+  [BPF_LDX]   = "ldx",
+  [BPF_ST]    = "st",
+  [BPF_STX]   = "stx",
+  [BPF_ALU]   = "alu",
+  [BPF_JMP]   = "jmp",
+  [BPF_RET]   = "6",		/* completely unused in ebpf */
+  [BPF_ALU64] = "alu64",
+};
+
+
+#define REG(N)		"r%" #N "$d"
+#define REGU(N)		"(u32)" REG(N)
+#define REGS(N)		"(s64)" REG(N)
+
+#define IMMS(N)		"%" #N "$d"
+#define IMMX(N)		"%" #N "$#x"
+
+#define OFF(N)		"%" #N "$+d"
+#define JMP(N)		"%" #N "$#x"
+
+#define A32(O, S)	REG(1) " = " REGU(1) " " #O " " S
+#define A64(O, S)	REG(1) " " #O "= " S
+#define J64(D, O, S)	"if " D " " #O " " S " goto " JMP(3)
+#define LOAD(T)		REG(1) " = *(" #T " *)(" REG(2) OFF(3) ")"
+#define STORE(T, S)	"*(" #T " *)(" REG(1) OFF(3) ") = " S
+#define XADD(T, S)	"lock *(" #T " *)(" REG(1) OFF(3) ") += " S
+#define LDSKB(T, S)	"r0 = *(" #T " *)skb[" S "]"
+
+static void
+bswap_bpf_insn (struct bpf_insn *p)
+{
+  /* Note that the dst_reg and src_reg fields are 4-bit bitfields.
+     That means these two nibbles are (typically) layed out in the
+     opposite order between big- and little-endian hosts.  This is
+     not required by any standard, but does happen to be true for
+     at least ppc, s390, arm and mips as big-endian hosts.  */
+  int t = p->dst_reg;
+  p->dst_reg = p->src_reg;
+  p->src_reg = t;
+
+  /* The other 2 and 4 byte fields are trivially converted.  */
+  CONVERT (p->off);
+  CONVERT (p->imm);
+}
+
+int
+bpf_disasm (Ebl *ebl, const uint8_t **startp, const uint8_t *end,
+	    GElf_Addr addr, const char *fmt __attribute__((unused)),
+	    DisasmOutputCB_t outcb,
+	    DisasmGetSymCB_t symcb __attribute__((unused)),
+	    void *outcbarg,
+	    void *symcbarg __attribute__((unused)))
+{
+  const bool need_bswap = MY_ELFDATA != ebl->data;
+  const uint8_t *start = *startp;
+  char buf[128];
+  int len, retval = 0;
+
+  while (start + sizeof(struct bpf_insn) <= end)
+    {
+      struct bpf_insn i;
+      unsigned code, class, jmp;
+      const char *code_fmt;
+
+      memcpy(&i, start, sizeof(struct bpf_insn));
+      if (need_bswap)
+	bswap_bpf_insn (&i);
+
+      start += sizeof(struct bpf_insn);
+      addr += sizeof(struct bpf_insn);
+      jmp = addr + i.off * sizeof(struct bpf_insn);
+
+      code = i.code;
+      switch (code)
+	{
+	case BPF_LD | BPF_IMM | BPF_DW:
+	  {
+	    struct bpf_insn i2;
+	    uint64_t imm64;
+
+	    if (start + sizeof(struct bpf_insn) > end)
+	      {
+		start -= sizeof(struct bpf_insn);
+		*startp = start;
+		goto done;
+	      }
+	    memcpy(&i2, start, sizeof(struct bpf_insn));
+	    if (need_bswap)
+	      bswap_bpf_insn (&i2);
+	    start += sizeof(struct bpf_insn);
+	    addr += sizeof(struct bpf_insn);
+
+	    imm64 = (uint32_t)i.imm | ((uint64_t)i2.imm << 32);
+	    switch (i.src_reg)
+	      {
+	      case 0:
+		code_fmt = REG(1) " = %2$#" PRIx64;
+		break;
+	      case BPF_PSEUDO_MAP_FD:
+		code_fmt = REG(1) " = map_fd(%2$#" PRIx64 ")";
+		break;
+	      default:
+		code_fmt = REG(1) " = ld_pseudo(%3$d, %2$#" PRIx64 ")";
+		break;
+	      }
+	    len = snprintf(buf, sizeof(buf), code_fmt,
+			   i.dst_reg, imm64, i.src_reg);
+	  }
+	  break;
+
+	case BPF_JMP | BPF_EXIT:
+	  len = snprintf(buf, sizeof(buf), "exit");
+	  break;
+	case BPF_JMP | BPF_JA:
+	  len = snprintf(buf, sizeof(buf), "goto " JMP(1), jmp);
+	  break;
+	case BPF_JMP | BPF_CALL:
+	  code_fmt = "call " IMMS(1);
+	  goto do_imm;
+
+	case BPF_ALU | BPF_END | BPF_TO_LE:
+	  /* The imm field contains {16,32,64}.  */
+	  code_fmt = REG(1) " = le" IMMS(2) "(" REG(1) ")";
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_END | BPF_TO_BE:
+	  code_fmt = REG(1) " = be" IMMS(2) "(" REG(1) ")";
+	  goto do_dst_imm;
+
+	case BPF_ALU | BPF_ADD | BPF_K:
+	  code_fmt = A32(+, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_SUB | BPF_K:
+	  code_fmt = A32(-, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_MUL | BPF_K:
+	  code_fmt = A32(*, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_DIV | BPF_K:
+	  code_fmt = A32(/, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_OR | BPF_K:
+	  code_fmt = A32(|, IMMX(2));
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_AND | BPF_K:
+	  code_fmt = A32(&, IMMX(2));
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_LSH | BPF_K:
+	  code_fmt = A32(<<, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_RSH | BPF_K:
+	  code_fmt = A32(>>, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_MOD | BPF_K:
+	  code_fmt = A32(%%, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_XOR | BPF_K:
+	  code_fmt = A32(^, IMMX(2));
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_MOV | BPF_K:
+	  code_fmt = REG(1) " = " IMMX(2);
+	  goto do_dst_imm;
+	case BPF_ALU | BPF_ARSH | BPF_K:
+	  code_fmt = REG(1) " = (u32)((s32)" REG(1) " >> " IMMS(2) ")";
+	  goto do_dst_imm;
+
+	case BPF_ALU | BPF_ADD | BPF_X:
+	  code_fmt = A32(+, REGU(2));
+	  goto do_dst_src;
+	case BPF_ALU | BPF_SUB | BPF_X:
+	  code_fmt = A32(-, REGU(2));
+	  goto do_dst_src;
+	case BPF_ALU | BPF_MUL | BPF_X:
+	  code_fmt = A32(*, REGU(2));
+	  goto do_dst_src;
+	case BPF_ALU | BPF_DIV | BPF_X:
+	  code_fmt = A32(/, REGU(2));
+	  goto do_dst_src;
+	case BPF_ALU | BPF_OR | BPF_X:
+	  code_fmt = A32(|, REGU(2));
+	  goto do_dst_src;
+	case BPF_ALU | BPF_AND | BPF_X:
+	  code_fmt = A32(&, REGU(2));
+	  goto do_dst_src;
+	case BPF_ALU | BPF_LSH | BPF_X:
+	  code_fmt = A32(<<, REGU(2));
+	  goto do_dst_src;
+	case BPF_ALU | BPF_RSH | BPF_X:
+	  code_fmt = A32(>>, REGU(2));
+	  goto do_dst_src;
+	case BPF_ALU | BPF_MOD | BPF_X:
+	  code_fmt = A32(%%, REGU(2));
+	  goto do_dst_src;
+	case BPF_ALU | BPF_XOR | BPF_X:
+	  code_fmt = A32(^, REGU(2));
+	  goto do_dst_src;
+	case BPF_ALU | BPF_MOV | BPF_X:
+	  code_fmt = REG(1) " = " REGU(2);
+	  goto do_dst_src;
+	case BPF_ALU | BPF_ARSH | BPF_X:
+	  code_fmt = REG(1) " = (u32)((s32)" REG(1) " >> " REG(2) ")";
+	  goto do_dst_src;
+
+	case BPF_ALU64 | BPF_ADD | BPF_K:
+	  code_fmt = A64(+, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU64 | BPF_SUB | BPF_K:
+	  code_fmt = A64(-, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU64 | BPF_MUL | BPF_K:
+	  code_fmt = A64(*, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU64 | BPF_DIV | BPF_K:
+	  code_fmt = A64(/, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU64 | BPF_OR | BPF_K:
+	  code_fmt = A64(|, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU64 | BPF_AND | BPF_K:
+	  code_fmt = A64(&, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU64 | BPF_LSH | BPF_K:
+	  code_fmt = A64(<<, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU64 | BPF_RSH | BPF_K:
+	  code_fmt = A64(>>, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU64 | BPF_MOD | BPF_K:
+	  code_fmt = A64(%%, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU64 | BPF_XOR | BPF_K:
+	  code_fmt = A64(^, IMMS(2));
+	  goto do_dst_imm;
+	case BPF_ALU64 | BPF_MOV | BPF_K:
+	  code_fmt = REG(1) " = " IMMS(2);
+	  goto do_dst_imm;
+	case BPF_ALU64 | BPF_ARSH | BPF_K:
+	  code_fmt = REG(1) " = (s64)" REG(1) " >> " IMMS(2);
+	  goto do_dst_imm;
+
+	case BPF_ALU64 | BPF_ADD | BPF_X:
+	  code_fmt = A64(+, REG(2));
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_SUB | BPF_X:
+	  code_fmt = A64(-, REG(2));
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_MUL | BPF_X:
+	  code_fmt = A64(*, REG(2));
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_DIV | BPF_X:
+	  code_fmt = A64(/, REG(2));
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_OR | BPF_X:
+	  code_fmt = A64(|, REG(2));
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_AND | BPF_X:
+	  code_fmt = A64(&, REG(2));
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_LSH | BPF_X:
+	  code_fmt = A64(<<, REG(2));
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_RSH | BPF_X:
+	  code_fmt = A64(>>, REG(2));
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_MOD | BPF_X:
+	  code_fmt = A64(%%, REG(2));
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_XOR | BPF_X:
+	  code_fmt = A64(^, REG(2));
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_MOV | BPF_X:
+	  code_fmt = REG(1) " = " REG(2);
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_ARSH | BPF_X:
+	  code_fmt = REG(1) " = (s64)" REG(1) " >> " REG(2);
+	  goto do_dst_src;
+
+	case BPF_ALU | BPF_NEG:
+	  code_fmt = REG(1) " = (u32)-" REG(1);
+	  goto do_dst_src;
+	case BPF_ALU64 | BPF_NEG:
+	  code_fmt = REG(1) " = -" REG(1);
+	  goto do_dst_src;
+
+	case BPF_JMP | BPF_JEQ | BPF_K:
+	  code_fmt = J64(REG(1), ==, IMMS(2));
+	  goto do_dst_imm_jmp;
+	case BPF_JMP | BPF_JGT | BPF_K:
+	  code_fmt = J64(REG(1), >, IMMS(2));
+	  goto do_dst_imm_jmp;
+	case BPF_JMP | BPF_JGE | BPF_K:
+	  code_fmt = J64(REG(1), >=, IMMS(2));
+	  goto do_dst_imm_jmp;
+	case BPF_JMP | BPF_JSET | BPF_K:
+	  code_fmt = J64(REG(1), &, IMMS(2));
+	  goto do_dst_imm_jmp;
+	case BPF_JMP | BPF_JNE | BPF_K:
+	  code_fmt = J64(REG(1), !=, IMMS(2));
+	  goto do_dst_imm_jmp;
+	case BPF_JMP | BPF_JSGT | BPF_K:
+	  code_fmt = J64(REGS(1), >, IMMS(2));
+	  goto do_dst_imm_jmp;
+	case BPF_JMP | BPF_JSGE | BPF_K:
+	  code_fmt = J64(REGS(1), >=, IMMS(2));
+	  goto do_dst_imm_jmp;
+
+	case BPF_JMP | BPF_JEQ | BPF_X:
+	  code_fmt = J64(REG(1), ==, REG(2));
+	  goto do_dst_src_jmp;
+	case BPF_JMP | BPF_JGT | BPF_X:
+	  code_fmt = J64(REG(1), >, REG(2));
+	  goto do_dst_src_jmp;
+	case BPF_JMP | BPF_JGE | BPF_X:
+	  code_fmt = J64(REG(1), >=, REG(2));
+	  goto do_dst_src_jmp;
+	case BPF_JMP | BPF_JSET | BPF_X:
+	  code_fmt = J64(REG(1), &, REG(2));
+	  goto do_dst_src_jmp;
+	case BPF_JMP | BPF_JNE | BPF_X:
+	  code_fmt = J64(REG(1), !=, REG(2));
+	  goto do_dst_src_jmp;
+	case BPF_JMP | BPF_JSGT | BPF_X:
+	  code_fmt = J64(REGS(1), >, REGS(2));
+	  goto do_dst_src_jmp;
+	case BPF_JMP | BPF_JSGE | BPF_X:
+	  code_fmt = J64(REGS(1), >=, REGS(2));
+	  goto do_dst_src_jmp;
+
+	case BPF_LDX | BPF_MEM | BPF_B:
+	  code_fmt = LOAD(u8);
+	  goto do_dst_src_off;
+	case BPF_LDX | BPF_MEM | BPF_H:
+	  code_fmt = LOAD(u16);
+	  goto do_dst_src_off;
+	case BPF_LDX | BPF_MEM | BPF_W:
+	  code_fmt = LOAD(u32);
+	  goto do_dst_src_off;
+	case BPF_LDX | BPF_MEM | BPF_DW:
+	  code_fmt = LOAD(u64);
+	  goto do_dst_src_off;
+
+	case BPF_STX | BPF_MEM | BPF_B:
+	  code_fmt = STORE(u8, REG(2));
+	  goto do_dst_src_off;
+	case BPF_STX | BPF_MEM | BPF_H:
+	  code_fmt = STORE(u16, REG(2));
+	  goto do_dst_src_off;
+	case BPF_STX | BPF_MEM | BPF_W:
+	  code_fmt = STORE(u32, REG(2));
+	  goto do_dst_src_off;
+	case BPF_STX | BPF_MEM | BPF_DW:
+	  code_fmt = STORE(u64, REG(2));
+	  goto do_dst_src_off;
+
+	case BPF_STX | BPF_XADD | BPF_W:
+	  code_fmt = XADD(u32, REG(2));
+	  goto do_dst_src_off;
+	case BPF_STX | BPF_XADD | BPF_DW:
+	  code_fmt = XADD(u64, REG(2));
+	  goto do_dst_src_off;
+
+	case BPF_ST | BPF_MEM | BPF_B:
+	  code_fmt = STORE(u8, IMMS(2));
+	  goto do_dst_imm_off;
+	case BPF_ST | BPF_MEM | BPF_H:
+	  code_fmt = STORE(u16, IMMS(2));
+	  goto do_dst_imm_off;
+	case BPF_ST | BPF_MEM | BPF_W:
+	  code_fmt = STORE(u32, IMMS(2));
+	  goto do_dst_imm_off;
+	case BPF_ST | BPF_MEM | BPF_DW:
+	  code_fmt = STORE(u64, IMMS(2));
+	  goto do_dst_imm_off;
+
+	case BPF_LD | BPF_ABS | BPF_B:
+	  code_fmt = LDSKB(u8, IMMS(1));
+	  goto do_imm;
+	case BPF_LD | BPF_ABS | BPF_H:
+	  code_fmt = LDSKB(u16, IMMS(1));
+	  goto do_imm;
+	case BPF_LD | BPF_ABS | BPF_W:
+	  code_fmt = LDSKB(u32, IMMS(1));
+	  goto do_imm;
+
+	case BPF_LD | BPF_IND | BPF_B:
+	  code_fmt = LDSKB(u8, REG(1) "+" IMMS(2));
+	  goto do_src_imm;
+	case BPF_LD | BPF_IND | BPF_H:
+	  code_fmt = LDSKB(u16, REG(1) "+" IMMS(2));
+	  goto do_src_imm;
+	case BPF_LD | BPF_IND | BPF_W:
+	  code_fmt = LDSKB(u32, REG(1) "+" IMMS(2));
+	  goto do_src_imm;
+
+	do_imm:
+	  len = snprintf(buf, sizeof(buf), code_fmt, i.imm);
+	  break;
+	do_dst_imm:
+	  len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm);
+	  break;
+	do_src_imm:
+	  len = snprintf(buf, sizeof(buf), code_fmt, i.src_reg, i.imm);
+	  break;
+	do_dst_src:
+	  len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.src_reg);
+	  break;
+	do_dst_imm_jmp:
+	  len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm, jmp);
+	  break;
+	do_dst_src_jmp:
+	  len = snprintf(buf, sizeof(buf), code_fmt,
+			 i.dst_reg, i.src_reg, jmp);
+	  break;
+	do_dst_imm_off:
+	  len = snprintf(buf, sizeof(buf), code_fmt, i.dst_reg, i.imm, i.off);
+	  break;
+	do_dst_src_off:
+	  len = snprintf(buf, sizeof(buf), code_fmt,
+			 i.dst_reg, i.src_reg, i.off);
+	  break;
+
+	default:
+	  class = BPF_CLASS(code);
+	  len = snprintf(buf, sizeof(buf), "invalid class %s",
+			 class_string[class]);
+	  break;
+        }
+
+      *startp = start;
+      retval = outcb (buf, len, outcbarg);
+      if (retval != 0)
+	goto done;
+    }
+
+ done:
+  return retval;
+}
diff --git a/third_party/elfutils/libcpu/defs/i386 b/third_party/elfutils/libcpu/defs/i386
new file mode 100644
index 0000000..e0db28d
--- /dev/null
+++ b/third_party/elfutils/libcpu/defs/i386
@@ -0,0 +1,970 @@
+%mask {s}	1
+%mask {w}	1
+%mask {w1}	1
+%mask {W1}	1
+%mask {W2}	1
+dnl floating point reg suffix
+%mask {D}	1
+%mask {imm8}	8
+%mask {imms8}	8
+%mask {imm16}	16
+%mask {reg}	3
+%mask {oreg}	3
+%mask {reg16}	3
+%mask {reg64}	3
+%mask {tttn}	4
+%mask {mod}	2
+%mask {moda}	2
+%mask {MOD}	2
+%mask {r_m}	3
+dnl like {r_m} but referencing byte register
+%mask {8r_m}	3
+dnl like {r_m} but referencing 16-bit register
+%mask {16r_m}	3
+dnl like {r_m} but referencing 32- or 64-bit register
+%mask {64r_m}	3
+%mask {disp8}	8
+dnl imm really is 8/16/32 bit depending on the situation.
+%mask {imm}	8
+%mask {imm64}	8
+%mask {imms}	8
+%mask {rel}	32
+%mask {abs}	32
+%mask {absval}	32
+%mask {sel}	16
+%mask {imm32}	32
+%mask {ccc}	3
+%mask {ddd}	3
+%mask {sreg3}	3
+%mask {sreg2}	2
+%mask {mmxreg}	3
+%mask {R_M}	3
+%mask {Mod}	2
+%mask {xmmreg}	3
+%mask {R_m}	3
+%mask {xmmreg1} 3
+%mask {xmmreg2} 3
+%mask {mmxreg1} 3
+%mask {mmxreg2} 3
+%mask {predps}	8
+%mask {freg}	3
+%mask {fmod}	2
+%mask {fr_m}	3
+%prefix {R}
+%prefix {RE}
+%suffix {W}
+%suffix {w0}
+%synonym {xmmreg1} {xmmreg}
+%synonym {xmmreg2} {xmmreg}
+%synonym {mmxreg1} {mmxreg}
+%synonym {mmxreg2} {mmxreg}
+ifdef(`i386',
+`%synonym {oreg} {reg}
+%synonym {imm64} {imm}
+')dnl
+
+%%
+ifdef(`i386',
+`00110111:aaa
+11010101,00001010:aad
+11010100,00001010:aam
+00111111:aas
+')dnl
+0001010{w},{imm}:adc {imm}{w},{ax}{w}
+1000000{w},{mod}010{r_m},{imm}:adc{w} {imm}{w},{mod}{r_m}{w}
+1000001{w},{mod}010{r_m},{imms8}:adc{w} {imms8},{mod}{r_m}
+0001000{w},{mod}{reg}{r_m}:adc {reg}{w},{mod}{r_m}{w}
+0001001{w},{mod}{reg}{r_m}:adc {mod}{r_m}{w},{reg}{w}
+0000010{w},{imm}:add {imm}{w},{ax}{w}
+1000000{w},{mod}000{r_m},{imm}:add{w} {imm}{w},{mod}{r_m}{w}
+10000011,{mod}000{r_m},{imms8}:add{w} {imms8},{mod}{r_m}
+0000000{w},{mod}{reg}{r_m}:add {reg}{w},{mod}{r_m}{w}
+0000001{w},{mod}{reg}{r_m}:add {mod}{r_m}{w},{reg}{w}
+01100110,00001111,11010000,{Mod}{xmmreg}{R_m}:addsubpd {Mod}{R_m},{xmmreg}
+11110010,00001111,11010000,{Mod}{xmmreg}{R_m}:addsubps {Mod}{R_m},{xmmreg}
+0010010{w},{imm}:and {imm}{w},{ax}{w}
+1000000{w},{mod}100{r_m},{imm}:and{w} {imm}{w},{mod}{r_m}{w}
+1000001{w},{mod}100{r_m},{imms8}:and{w} {imms8},{mod}{r_m}
+0010000{w},{mod}{reg}{r_m}:and {reg}{w},{mod}{r_m}{w}
+0010001{w},{mod}{reg}{r_m}:and {mod}{r_m}{w},{reg}{w}
+01100110,00001111,01010100,{Mod}{xmmreg}{R_m}:andpd {Mod}{R_m},{xmmreg}
+00001111,01010100,{Mod}{xmmreg}{R_m}:andps {Mod}{R_m},{xmmreg}
+01100110,00001111,01010101,{Mod}{xmmreg}{R_m}:andnpd {Mod}{R_m},{xmmreg}
+00001111,01010101,{Mod}{xmmreg}{R_m}:andnps {Mod}{R_m},{xmmreg}
+ifdef(`i386',
+`01100011,{mod}{reg16}{r_m}:arpl {reg16},{mod}{r_m}
+01100010,{moda}{reg}{r_m}:bound {reg},{moda}{r_m}
+',
+`01100011,{mod}{reg64}{r_m}:movslq {mod}{r_m},{reg64}
+')dnl
+00001111,10111100,{mod}{reg}{r_m}:bsf {mod}{r_m},{reg}
+00001111,10111101,{mod}{reg}{r_m}:bsr {mod}{r_m},{reg}
+00001111,11001{reg}:bswap {reg}
+00001111,10100011,{mod}{reg}{r_m}:bt {reg},{mod}{r_m}
+00001111,10111010,{mod}100{r_m},{imm8}:bt{w} {imm8},{mod}{r_m}
+00001111,10111011,{mod}{reg}{r_m}:btc {reg},{mod}{r_m}
+00001111,10111010,{mod}111{r_m},{imm8}:btc{w} {imm8},{mod}{r_m}
+00001111,10110011,{mod}{reg}{r_m}:btr {reg},{mod}{r_m}
+00001111,10111010,{mod}110{r_m},{imm8}:btr{w} {imm8},{mod}{r_m}
+00001111,10101011,{mod}{reg}{r_m}:bts {reg},{mod}{r_m}
+00001111,10111010,{mod}101{r_m},{imm8}:bts{w} {imm8},{mod}{r_m}
+11101000,{rel}:call{W} {rel}
+11111111,{mod}010{64r_m}:call{W} *{mod}{64r_m}
+ifdef(`i386',
+`10011010,{absval},{sel}:lcall {sel},{absval}
+')dnl
+11111111,{mod}011{64r_m}:lcall{W} *{mod}{64r_m}
+# SPECIAL 10011000:[{rex.w}?cltq:{dpfx}?cbtw:cwtl]
+10011000:INVALID
+# SPECIAL 10011001:[{rex.w}?cqto:{dpfx}?cltd:cwtd]
+10011001:INVALID
+11111000:clc
+11111100:cld
+11111010:cli
+00001111,00000101:syscall
+00001111,00000110:clts
+00001111,00000111:sysret
+00001111,00110100:sysenter
+00001111,00110101:sysexit
+11110101:cmc
+00001111,0100{tttn},{mod}{reg}{r_m}:cmov{tttn} {mod}{r_m},{reg}
+0011110{w},{imm}:cmp {imm}{w},{ax}{w}
+1000000{w},{mod}111{r_m},{imm}:cmp{w} {imm}{w},{mod}{r_m}{w}
+10000011,{mod}111{r_m},{imms8}:cmp{w} {imms8},{mod}{r_m}
+0011100{w},{mod}{reg}{r_m}:cmp {reg}{w},{mod}{r_m}{w}
+0011101{w},{mod}{reg}{r_m}:cmp {mod}{r_m}{w},{reg}{w}
+ifdef(`ASSEMBLER',
+`11110010,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmpsd {imm8},{Mod}{R_m},{xmmreg}
+11110011,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmpss {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmppd {imm8},{Mod}{R_m},{xmmreg}
+00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:cmpps {imm8},{Mod}{R_m},{xmmreg}
+',
+`11110010,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:INVALID {Mod}{R_m},{xmmreg}
+11110011,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:INVALID {Mod}{R_m},{xmmreg}
+01100110,00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:INVALID {Mod}{R_m},{xmmreg}
+00001111,11000010,{Mod}{xmmreg}{R_m},{imm8}:INVALID {Mod}{R_m},{xmmreg}
+')dnl
+1010011{w}:{RE}cmps{w} {es_di},{ds_si}
+00001111,1011000{w},{mod}{reg}{r_m}:cmpxchg {reg}{w},{mod}{r_m}{w}
+ifdef(`i386',
+`00001111,11000111,{mod}001{r_m}:cmpxchg8b {mod}{r_m}
+',
+`# SPECIAL 00001111,11000111,{mod}001{r_m}:[{rex.w}?cmpxchg16b:cmpxchg8b] {reg},{mod}{r_m}
+00001111,11000111,{mod}001{r_m}:INVALID {mod}{r_m}
+')dnl
+00001111,10100010:cpuid
+11110011,00001111,11100110,{Mod}{xmmreg}{R_m}:cvtdq2pd {Mod}{R_m},{xmmreg}
+11110010,00001111,11100110,{Mod}{xmmreg}{R_m}:cvtpd2dq {Mod}{R_m},{xmmreg}
+01100110,00001111,11100110,{Mod}{xmmreg}{R_m}:cvttpd2dq {Mod}{R_m},{xmmreg}
+ifdef(`i386',
+`00100111:daa
+00101111:das
+')dnl
+1111111{w},{mod}001{r_m}:dec{w} {mod}{r_m}{w}
+ifdef(`i386',
+`01001{reg}:dec {reg}
+')dnl
+1111011{w},{mod}110{r_m}:div{w} {mod}{r_m}{w}
+00001111,01110111:emms
+11001000,{imm16},{imm8}:enter{W} {imm16},{imm8}
+11011001,11010000:fnop
+11011001,11100000:fchs
+11011001,11100001:fabs
+11011001,11100100:ftst
+11011001,11100101:fxam
+11011001,11101000:fld1
+11011001,11101001:fldl2t
+11011001,11101010:fldl2e
+11011001,11101011:fldpi
+11011001,11101100:fldlg2
+11011001,11101101:fldln2
+11011001,11101110:fldz
+11011001,11110000:f2xm1
+11011001,11110001:fyl2x
+11011001,11110010:fptan
+11011001,11110011:fpatan
+11011001,11110100:fxtract
+11011001,11110101:fprem1
+11011001,11110110:fdecstp
+11011001,11110111:fincstp
+11011001,11111000:fprem
+11011001,11111001:fyl2xp1
+11011001,11111010:fsqrt
+11011001,11111011:fsincos
+11011001,11111100:frndint
+11011001,11111101:fscale
+11011001,11111110:fsin
+11011001,11111111:fcos
+# ORDER
+11011000,11000{freg}:fadd {freg},%st
+11011100,11000{freg}:fadd %st,{freg}
+11011{D}00,{mod}000{r_m}:fadd{D} {mod}{r_m}
+# ORDER END
+# ORDER
+11011000,11001{freg}:fmul {freg},%st
+11011100,11001{freg}:fmul %st,{freg}
+11011{D}00,{mod}001{r_m}:fmul{D} {mod}{r_m}
+# ORDER END
+# ORDER
+11011000,11100{freg}:fsub {freg},%st
+11011100,11100{freg}:fsub %st,{freg}
+11011{D}00,{mod}100{r_m}:fsub{D} {mod}{r_m}
+# ORDER END
+# ORDER
+11011000,11101{freg}:fsubr {freg},%st
+11011100,11101{freg}:fsubr %st,{freg}
+11011{D}00,{mod}101{r_m}:fsubr{D} {mod}{r_m}
+# ORDER END
+# ORDER
+11011101,11010{freg}:fst {freg}
+11011{D}01,{mod}010{r_m}:fst{D} {mod}{r_m}
+# ORDER END
+# ORDER
+11011101,11011{freg}:fstp {freg}
+11011{D}01,{mod}011{r_m}:fstp{D} {mod}{r_m}
+# ORDER END
+11011001,{mod}100{r_m}:fldenv {mod}{r_m}
+11011001,{mod}101{r_m}:fldcw {mod}{r_m}
+11011001,{mod}110{r_m}:fnstenv {mod}{r_m}
+11011001,{mod}111{r_m}:fnstcw {mod}{r_m}
+11011001,11001{freg}:fxch {freg}
+# ORDER
+11011110,11000{freg}:faddp %st,{freg}
+ifdef(`ASSEMBLER',
+`11011110,11000001:faddp
+')dnl
+# ORDER
+11011010,11000{freg}:fcmovb {freg},%st
+11011{w1}10,{mod}000{r_m}:fiadd{w1} {mod}{r_m}
+# ORDER END
+# ORDER
+11011010,11001{freg}:fcmove {freg},%st
+11011110,11001{freg}:fmulp %st,{freg}
+11011{w1}10,{mod}001{r_m}:fimul{w1} {mod}{r_m}
+# ORDER END
+# ORDER
+11011110,11100{freg}:fsubp %st,{freg}
+11011{w1}10,{mod}100{r_m}:fisub{w1} {mod}{r_m}
+# ORDER END
+# ORDER
+11011110,11101{freg}:fsubrp %st,{freg}
+11011{w1}10,{mod}101{r_m}:fisubr{w1} {mod}{r_m}
+# ORDER END
+# ORDER
+11011111,11100000:fnstsw %ax
+11011111,{mod}100{r_m}:fbld {mod}{r_m}
+# ORDER END
+# ORDER
+11011111,11110{freg}:fcomip {freg},%st
+11011111,{mod}110{r_m}:fbstp {mod}{r_m}
+# ORDER END
+11011001,11100000:fchs
+# ORDER
+10011011,11011011,11100010:fclex
+10011011,11011011,11100011:finit
+10011011:fwait
+# END ORDER
+11011011,11100010:fnclex
+11011010,11000{freg}:fcmovb {freg},%st
+11011010,11001{freg}:fcmove {freg},%st
+11011010,11010{freg}:fcmovbe {freg},%st
+11011010,11011{freg}:fcmovu {freg},%st
+11011011,11000{freg}:fcmovnb {freg},%st
+11011011,11001{freg}:fcmovne {freg},%st
+11011011,11010{freg}:fcmovnbe {freg},%st
+11011011,11011{freg}:fcmovnu {freg},%st
+# ORDER
+11011000,11010{freg}:fcom {freg}
+ifdef(`ASSEMBLER',
+`11011000,11010001:fcom
+')dnl
+11011{D}00,{mod}010{r_m}:fcom{D} {mod}{r_m}
+# END ORDER
+# ORDER
+11011000,11011{freg}:fcomp {freg}
+ifdef(`ASSEMBLER',
+`11011000,11011001:fcomp
+')dnl
+11011{D}00,{mod}011{r_m}:fcomp{D} {mod}{r_m}
+# END ORDER
+11011110,11011001:fcompp
+11011011,11110{freg}:fcomi {freg},%st
+11011111,11110{freg}:fcomip {freg},%st
+11011011,11101{freg}:fucomi {freg},%st
+11011111,11101{freg}:fucomip {freg},%st
+11011001,11111111:fcos
+11011001,11110110:fdecstp
+# ORDER
+11011000,11110{freg}:fdiv {freg},%st
+11011100,11110{freg}:fdiv %st,{freg}
+11011{D}00,{mod}110{r_m}:fdiv{D} {mod}{r_m}
+# END ORDER
+11011010,{mod}110{r_m}:fidivl {mod}{r_m}
+# ORDER
+11011110,11110{freg}:fdivp %st,{freg}
+11011110,{mod}110{r_m}:fidiv {mod}{r_m}
+# END ORDER
+11011110,11111{freg}:fdivrp %st,{freg}
+ifdef(`ASSEMBLER',
+`11011110,11111001:fdivp
+')dnl
+# ORDER
+11011000,11111{freg}:fdivr {freg},%st
+11011100,11111{freg}:fdivr %st,{freg}
+11011{D}00,{mod}111{r_m}:fdivr{D} {mod}{r_m}
+# END ORDER
+11011010,{mod}111{r_m}:fidivrl {mod}{r_m}
+11011110,{mod}111{r_m}:fidivr {mod}{r_m}
+11011110,11110{freg}:fdivrp %st,{freg}
+ifdef(`ASSEMBLER',
+`11011110,11110001:fdivrp
+')dnl
+11011101,11000{freg}:ffree {freg}
+11011010,11010{freg}:fcmovbe {freg}
+11011{w1}10,{mod}010{r_m}:ficom{w1} {mod}{r_m}
+11011010,11011{freg}:fcmovu {freg}
+11011{w1}10,{mod}011{r_m}:ficomp{w1} {mod}{r_m}
+11011111,{mod}000{r_m}:fild {mod}{r_m}
+11011011,{mod}000{r_m}:fildl {mod}{r_m}
+11011111,{mod}101{r_m}:fildll {mod}{r_m}
+11011001,11110111:fincstp
+11011011,11100011:fninit
+11011{w1}11,{mod}010{r_m}:fist{w1} {mod}{r_m}
+11011{w1}11,{mod}011{r_m}:fistp{w1} {mod}{r_m}
+11011111,{mod}111{r_m}:fistpll {mod}{r_m}
+11011{w1}11,{mod}001{r_m}:fisttp{w1} {mod}{r_m}
+11011101,{mod}001{r_m}:fisttpll {mod}{r_m}
+11011011,{mod}101{r_m}:fldt {mod}{r_m}
+11011011,{mod}111{r_m}:fstpt {mod}{r_m}
+# ORDER
+11011001,11000{freg}:fld {freg}
+11011{D}01,{mod}000{r_m}:fld{D} {mod}{r_m}
+# ORDER END
+# ORDER
+11011101,11100{freg}:fucom {freg}
+11011101,{mod}100{r_m}:frstor {mod}{r_m}
+# ORDER END
+11011101,11101{freg}:fucomp {freg}
+11011101,{mod}110{r_m}:fnsave {mod}{r_m}
+11011101,{mod}111{r_m}:fnstsw {mod}{r_m}
+#
+#
+#
+11110100:hlt
+1111011{w},{mod}111{r_m}:idiv{w} {mod}{r_m}{w}
+1111011{w},{mod}101{r_m}:imul{w} {mod}{r_m}{w}
+00001111,10101111,{mod}{reg}{r_m}:imul {mod}{r_m},{reg}
+011010{s}1,{mod}{reg}{r_m},{imm}:imul {imm}{s},{mod}{r_m},{reg}
+1110010{w},{imm8}:in {imm8},{ax}{w}
+1110110{w}:in {dx},{ax}{w}
+1111111{w},{mod}000{r_m}:inc{w} {mod}{r_m}{w}
+ifdef(`i386',
+`01000{reg}:inc {reg}
+')dnl
+0110110{w}:{R}ins{w} {dx},{es_di}
+11001101,{imm8}:int {imm8}
+11001100:int3
+ifdef(`i386',
+`11001110:into
+')dnl
+00001111,00001000:invd
+# ORDER
+00001111,00000001,11111000:swapgs
+00001111,00000001,{mod}111{r_m}:invlpg {mod}{r_m}
+# ORDER END
+11001111:iret{W1}
+0111{tttn},{disp8}:j{tttn} {disp8}
+00001111,1000{tttn},{rel}:j{tttn} {rel}
+00001111,1001{tttn},{mod}000{8r_m}:set{tttn} {mod}{8r_m}
+# SPECIAL 11100011,{disp8}:[{dpfx}?jcxz:jecxz] {disp8}
+11100011,{disp8}:INVALID {disp8}
+11101011,{disp8}:jmp {disp8}
+11101001,{rel}:jmp{W} {rel}
+11111111,{mod}100{64r_m}:jmp{W} *{mod}{64r_m}
+11101010,{absval},{sel}:ljmp {sel},{absval}
+11111111,{mod}101{64r_m}:ljmp{W} *{mod}{64r_m}
+10011111:lahf
+00001111,00000010,{mod}{reg}{16r_m}:lar {mod}{16r_m},{reg}
+ifdef(`i386',
+`11000101,{mod}{reg}{r_m}:lds {mod}{r_m},{reg}
+')dnl
+10001101,{mod}{reg}{r_m}:lea {mod}{r_m},{reg}
+11001001:leave{W}
+ifdef(`i386',
+`11000100,{mod}{reg}{r_m}:les {mod}{r_m},{reg}
+')dnl
+00001111,10110100,{mod}{reg}{r_m}:lfs {mod}{r_m},{reg}
+00001111,10110101,{mod}{reg}{r_m}:lgs {mod}{r_m},{reg}
+ifdef(`i386',
+`00001111,00000001,{mod}010{r_m}:lgdt{w0} {mod}{r_m}
+00001111,00000001,{mod}011{r_m}:lidt{w0} {mod}{r_m}
+',
+`00001111,00000001,{mod}010{r_m}:lgdt {mod}{r_m}
+00001111,00000001,{mod}011{r_m}:lidt {mod}{r_m}
+')dnl
+00001111,00000000,{mod}010{16r_m}:lldt {mod}{16r_m}
+00001111,00000001,{mod}110{16r_m}:lmsw {mod}{16r_m}
+11110000:lock
+1010110{w}:{R}lods {ds_si},{ax}{w}
+11100010,{disp8}:loop {disp8}
+11100001,{disp8}:loope {disp8}
+11100000,{disp8}:loopne {disp8}
+00001111,00000011,{mod}{reg}{16r_m}:lsl {mod}{16r_m},{reg}
+00001111,10110010,{mod}{reg}{r_m}:lss {mod}{r_m},{reg}
+00001111,00000000,{mod}011{16r_m}:ltr {mod}{16r_m}
+1000100{w},{mod}{reg}{r_m}:mov {reg}{w},{mod}{r_m}{w}
+1000101{w},{mod}{reg}{r_m}:mov {mod}{r_m}{w},{reg}{w}
+1100011{w},{mod}000{r_m},{imm}:mov{w} {imm}{w},{mod}{r_m}{w}
+1011{w}{oreg},{imm64}:mov {imm64}{w},{oreg}{w}
+1010000{w},{abs}:mov {abs},{ax}{w}
+1010001{w},{abs}:mov {ax}{w},{abs}
+00001111,00100000,11{ccc}{reg64}:mov {ccc},{reg64}
+00001111,00100010,11{ccc}{reg64}:mov {reg64},{ccc}
+00001111,00100001,11{ddd}{reg64}:mov {ddd},{reg64}
+00001111,00100011,11{ddd}{reg64}:mov {reg64},{ddd}
+10001100,{mod}{sreg3}{r_m}:mov {sreg3},{mod}{r_m}
+10001110,{mod}{sreg3}{r_m}:mov {mod}{r_m},{sreg3}
+1010010{w}:{R}movs{w} {ds_si},{es_di}
+00001111,10111110,{mod}{reg}{8r_m}:movsbl {mod}{8r_m},{reg}
+00001111,10111111,{mod}{reg}{16r_m}:movswl {mod}{16r_m},{reg}
+00001111,10110110,{mod}{reg}{8r_m}:movzbl {mod}{8r_m},{reg}
+00001111,10110111,{mod}{reg}{16r_m}:movzwl {mod}{16r_m},{reg}
+1111011{w},{mod}100{r_m}:mul{w} {mod}{r_m}{w}
+1111011{w},{mod}011{r_m}:neg{w} {mod}{r_m}{w}
+11110011,10010000:pause
+ifdef(`i386',
+`10010000:nop
+',
+`10010000:INVALID
+')dnl
+# ORDER before out
+11110011,00001111,10111000,{mod}{reg}{r_m}:popcnt {mod}{r_m},{reg}
+# END ORDER
+1111011{w},{mod}010{r_m}:not{w} {mod}{r_m}{w}
+0000100{w},{mod}{reg}{r_m}:or {reg}{w},{mod}{r_m}{w}
+0000101{w},{mod}{reg}{r_m}:or {mod}{r_m}{w},{reg}{w}
+1000000{w},{mod}001{r_m},{imm}:or{w} {imm}{w},{mod}{r_m}{w}
+1000001{w},{mod}001{r_m},{imms8}:or{w} {imms8},{mod}{r_m}{w}
+0000110{w},{imm}:or {imm}{w},{ax}{w}
+1110011{w},{imm8}:out {ax}{w},{imm8}
+1110111{w}:out {ax}{w},{dx}
+0110111{w}:{R}outs{w} {ds_si},{dx}
+ifdef(`i386',
+`10001111,{mod}000{r_m}:pop{w} {mod}{r_m}
+',
+# XXX This is not the cleanest way...
+`10001111,11000{reg64}:pop {reg64}
+10001111,{mod}000{r_m}:pop{W} {mod}{r_m}
+')dnl
+00001111,10{sreg3}001:pop{W} {sreg3}
+10011101:popf{W}
+# XXX This is not the cleanest way...
+ifdef(`i386',
+`11111111,{mod}110{r_m}:push{w} {mod}{r_m}
+',
+`11111111,11110{reg64}:push {reg64}
+11111111,{mod}110{r_m}:pushq {mod}{r_m}
+')dnl
+ifdef(`i386',
+`01010{reg}:push {reg}
+01011{reg}:pop {reg}
+',
+`01010{reg64}:push {reg64}
+01011{reg64}:pop {reg64}
+')dnl
+011010{s}0,{imm}:push{W} {imm}{s}
+000{sreg2}110:push {sreg2}
+00001111,10{sreg3}000:push{W} {sreg3}
+ifdef(`i386',
+`01100000:pusha{W}
+01100001:popa{W}
+')dnl
+10011100:pushf{W}
+1101000{w},{mod}010{r_m}:rcl{w} {mod}{r_m}{w}
+1101001{w},{mod}010{r_m}:rcl{w} %cl,{mod}{r_m}{w}
+1100000{w},{mod}010{r_m},{imm8}:rcl{w} {imm8},{mod}{r_m}{w}
+1101000{w},{mod}011{r_m}:rcr{w} {mod}{r_m}{w}
+1101001{w},{mod}011{r_m}:rcr{w} %cl,{mod}{r_m}{w}
+1100000{w},{mod}011{r_m},{imm8}:rcr{w} {imm8},{mod}{r_m}{w}
+00001111,00110010:rdmsr
+00001111,00110011:rdpmc
+00001111,00110001:rdtsc
+11000011:ret{W}
+11000010,{imm16}:ret{W} {imm16}
+11001011:lret
+11001010,{imm16}:lret {imm16}
+1101000{w},{mod}000{r_m}:rol{w} {mod}{r_m}{w}
+1101001{w},{mod}000{r_m}:rol{w} %cl,{mod}{r_m}{w}
+1100000{w},{mod}000{r_m},{imm8}:rol{w} {imm8},{mod}{r_m}{w}
+1101000{w},{mod}001{r_m}:ror{w} {mod}{r_m}{w}
+1101001{w},{mod}001{r_m}:ror{w} %cl,{mod}{r_m}{w}
+1100000{w},{mod}001{r_m},{imm8}:ror{w} {imm8},{mod}{r_m}{w}
+00001111,10101010:rsm
+10011110:sahf
+1101000{w},{mod}111{r_m}:sar{w} {mod}{r_m}{w}
+1101001{w},{mod}111{r_m}:sar{w} %cl,{mod}{r_m}{w}
+1100000{w},{mod}111{r_m},{imm8}:sar{w} {imm8},{mod}{r_m}{w}
+0001100{w},{mod}{reg}{r_m}:sbb {reg}{w},{mod}{r_m}{w}
+0001101{w},{mod}{reg}{r_m}:sbb {mod}{r_m}{w},{reg}{w}
+0001110{w},{imm}:sbb {imm}{w},{ax}{w}
+1000000{w},{mod}011{r_m},{imm}:sbb{w} {imm}{w},{mod}{r_m}{w}
+1000001{w},{mod}011{r_m},{imms8}:sbb{w} {imms8},{mod}{r_m}
+1010111{w}:{RE}scas {es_di},{ax}{w}
+00001111,1001{tttn},{mod}000{r_m}:set{tttn} {mod}{r_m}
+1101000{w},{mod}100{r_m}:shl{w} {mod}{r_m}{w}
+1101001{w},{mod}100{r_m}:shl{w} %cl,{mod}{r_m}{w}
+1100000{w},{mod}100{r_m},{imm8}:shl{w} {imm8},{mod}{r_m}{w}
+1101000{w},{mod}101{r_m}:shr{w} {mod}{r_m}{w}
+00001111,10100100,{mod}{reg}{r_m},{imm8}:shld {imm8},{reg},{mod}{r_m}
+00001111,10100101,{mod}{reg}{r_m}:shld %cl,{reg},{mod}{r_m}
+1101001{w},{mod}101{r_m}:shr{w} %cl,{mod}{r_m}{w}
+1100000{w},{mod}101{r_m},{imm8}:shr{w} {imm8},{mod}{r_m}{w}
+00001111,10101100,{mod}{reg}{r_m},{imm8}:shrd {imm8},{reg},{mod}{r_m}
+00001111,10101101,{mod}{reg}{r_m}:shrd %cl,{reg},{mod}{r_m}
+# ORDER
+00001111,00000001,11000001:vmcall
+00001111,00000001,11000010:vmlaunch
+00001111,00000001,11000011:vmresume
+00001111,00000001,11000100:vmxoff
+00001111,01111000,{mod}{reg64}{64r_m}:vmread {reg64},{mod}{64r_m}
+00001111,01111001,{mod}{reg64}{64r_m}:vmwrite {mod}{64r_m},{reg64}
+ifdef(`i386',
+`00001111,00000001,{mod}000{r_m}:sgdtl {mod}{r_m}
+',
+`00001111,00000001,{mod}000{r_m}:sgdt {mod}{r_m}
+')dnl
+# ORDER END
+# ORDER
+ifdef(`i386',
+`00001111,00000001,11001000:monitor %eax,%ecx,%edx
+00001111,00000001,11001001:mwait %eax,%ecx
+',
+`00001111,00000001,11001000:monitor %rax,%rcx,%rdx
+00001111,00000001,11001001:mwait %rax,%rcx
+')dnl
+ifdef(`i386',
+`00001111,00000001,{mod}001{r_m}:sidtl {mod}{r_m}
+',
+`00001111,00000001,{mod}001{r_m}:sidt {mod}{r_m}
+')dnl
+# ORDER END
+00001111,00000000,{mod}000{r_m}:sldt {mod}{r_m}
+00001111,00000001,{mod}100{r_m}:smsw {mod}{r_m}
+11111001:stc
+11111101:std
+11111011:sti
+1010101{w}:{R}stos {ax}{w},{es_di}
+00001111,00000000,{mod}001{r_m}:str {mod}{r_m}
+0010100{w},{mod}{reg}{r_m}:sub {reg}{w},{mod}{r_m}{w}
+0010101{w},{mod}{reg}{r_m}:sub {mod}{r_m}{w},{reg}{w}
+0010110{w},{imm}:sub {imm}{w},{ax}{w}
+1000000{w},{mod}101{r_m},{imm}:sub{w} {imm}{w},{mod}{r_m}{w}
+1000001{w},{mod}101{r_m},{imms8}:sub{w} {imms8},{mod}{r_m}
+1000010{w},{mod}{reg}{r_m}:test {reg}{w},{mod}{r_m}{w}
+1010100{w},{imm}:test {imm}{w},{ax}{w}
+1111011{w},{mod}000{r_m},{imm}:test{w} {imm}{w},{mod}{r_m}{w}
+00001111,00001011:ud2a
+00001111,00000000,{mod}100{16r_m}:verr {mod}{16r_m}
+00001111,00000000,{mod}101{16r_m}:verw {mod}{16r_m}
+00001111,00001001:wbinvd
+00001111,00001101,{mod}000{8r_m}:prefetch {mod}{8r_m}
+00001111,00001101,{mod}001{8r_m}:prefetchw {mod}{8r_m}
+00001111,00011000,{mod}000{r_m}:prefetchnta {mod}{r_m}
+00001111,00011000,{mod}001{r_m}:prefetcht0 {mod}{r_m}
+00001111,00011000,{mod}010{r_m}:prefetcht1 {mod}{r_m}
+00001111,00011000,{mod}011{r_m}:prefetcht2 {mod}{r_m}
+00001111,00011111,{mod}{reg}{r_m}:nop{w} {mod}{r_m}
+00001111,00110000:wrmsr
+00001111,1100000{w},{mod}{reg}{r_m}:xadd {reg}{w},{mod}{r_m}{w}
+1000011{w},{mod}{reg}{r_m}:xchg {reg}{w},{mod}{r_m}{w}
+10010{oreg}:xchg {ax},{oreg}
+11010111:xlat {ds_bx}
+0011000{w},{mod}{reg}{r_m}:xor {reg}{w},{mod}{r_m}{w}
+0011001{w},{mod}{reg}{r_m}:xor {mod}{r_m}{w},{reg}{w}
+0011010{w},{imm}:xor {imm}{w},{ax}{w}
+1000000{w},{mod}110{r_m},{imm}:xor{w} {imm}{w},{mod}{r_m}{w}
+1000001{w},{mod}110{r_m},{imms8}:xor{w} {imms8},{mod}{r_m}
+00001111,01110111:emms
+01100110,00001111,11011011,{Mod}{xmmreg}{R_m}:pand {Mod}{R_m},{xmmreg}
+00001111,11011011,{MOD}{mmxreg}{R_M}:pand {MOD}{R_M},{mmxreg}
+01100110,00001111,11011111,{Mod}{xmmreg}{R_m}:pandn {Mod}{R_m},{xmmreg}
+00001111,11011111,{MOD}{mmxreg}{R_M}:pandn {MOD}{R_M},{mmxreg}
+01100110,00001111,11110101,{Mod}{xmmreg}{R_m}:pmaddwd {Mod}{R_m},{xmmreg}
+00001111,11110101,{MOD}{mmxreg}{R_M}:pmaddwd {MOD}{R_M},{mmxreg}
+01100110,00001111,11101011,{Mod}{xmmreg}{R_m}:por {Mod}{R_m},{xmmreg}
+00001111,11101011,{MOD}{mmxreg}{R_M}:por {MOD}{R_M},{mmxreg}
+01100110,00001111,11101111,{Mod}{xmmreg}{R_m}:pxor {Mod}{R_m},{xmmreg}
+00001111,11101111,{MOD}{mmxreg}{R_M}:pxor {MOD}{R_M},{mmxreg}
+00001111,01010101,{Mod}{xmmreg}{R_m}:andnps {Mod}{R_m},{xmmreg}
+00001111,01010100,{Mod}{xmmreg}{R_m}:andps {Mod}{R_m},{xmmreg}
+00001111,11000010,{Mod}{xmmreg}{R_m},00000000:cmpeqps {Mod}{R_m},{xmmreg}
+00001111,11000010,{Mod}{xmmreg}{R_m},00000001:cmpltps {Mod}{R_m},{xmmreg}
+00001111,11000010,{Mod}{xmmreg}{R_m},00000010:cmpleps {Mod}{R_m},{xmmreg}
+00001111,11000010,{Mod}{xmmreg}{R_m},00000011:cmpunordps {Mod}{R_m},{xmmreg}
+00001111,11000010,{Mod}{xmmreg}{R_m},00000100:cmpneqps {Mod}{R_m},{xmmreg}
+00001111,11000010,{Mod}{xmmreg}{R_m},00000101:cmpnltps {Mod}{R_m},{xmmreg}
+00001111,11000010,{Mod}{xmmreg}{R_m},00000110:cmpnleps {Mod}{R_m},{xmmreg}
+00001111,11000010,{Mod}{xmmreg}{R_m},00000111:cmpordps {Mod}{R_m},{xmmreg}
+11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000000:cmpeqss {Mod}{R_m},{xmmreg}
+11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000001:cmpltss {Mod}{R_m},{xmmreg}
+11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000010:cmpless {Mod}{R_m},{xmmreg}
+11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000011:cmpunordss {Mod}{R_m},{xmmreg}
+11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000100:cmpneqss {Mod}{R_m},{xmmreg}
+11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000101:cmpnltss {Mod}{R_m},{xmmreg}
+11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000110:cmpnless {Mod}{R_m},{xmmreg}
+11110011,00001111,11000010,{Mod}{xmmreg}{R_m},00000111:cmpordss {Mod}{R_m},{xmmreg}
+00001111,10101110,{mod}001{r_m}:fxrstor {mod}{r_m}
+00001111,10101110,{mod}000{r_m}:fxsave {mod}{r_m}
+00001111,10101110,{mod}010{r_m}:ldmxcsr {mod}{r_m}
+00001111,10101110,{mod}011{r_m}:stmxcsr {mod}{r_m}
+11110010,00001111,00010000,{Mod}{xmmreg}{R_m}:movsd {Mod}{R_m},{xmmreg}
+11110011,00001111,00010000,{Mod}{xmmreg}{R_m}:movss {Mod}{R_m},{xmmreg}
+01100110,00001111,00010000,{Mod}{xmmreg}{R_m}:movupd {Mod}{R_m},{xmmreg}
+00001111,00010000,{Mod}{xmmreg}{R_m}:movups {Mod}{R_m},{xmmreg}
+11110010,00001111,00010001,{Mod}{xmmreg}{R_m}:movsd {xmmreg},{Mod}{R_m}
+11110011,00001111,00010001,{Mod}{xmmreg}{R_m}:movss {xmmreg},{Mod}{R_m}
+01100110,00001111,00010001,{Mod}{xmmreg}{R_m}:movupd {xmmreg},{Mod}{R_m}
+00001111,00010001,{Mod}{xmmreg}{R_m}:movups {xmmreg},{Mod}{R_m}
+11110010,00001111,00010010,{Mod}{xmmreg}{R_m}:movddup {Mod}{R_m},{xmmreg}
+11110011,00001111,00010010,{Mod}{xmmreg}{R_m}:movsldup {Mod}{R_m},{xmmreg}
+01100110,00001111,00010010,{Mod}{xmmreg}{R_m}:movlpd {Mod}{R_m},{xmmreg}
+00001111,00010010,11{xmmreg1}{xmmreg2}:movhlps {xmmreg2},{xmmreg1}
+00001111,00010010,{Mod}{xmmreg}{R_m}:movlps {Mod}{R_m},{xmmreg}
+01100110,00001111,00010011,11{xmmreg1}{xmmreg2}:movhlpd {xmmreg1},{xmmreg2}
+00001111,00010011,11{xmmreg1}{xmmreg2}:movhlps {xmmreg1},{xmmreg2}
+01100110,00001111,00010011,{Mod}{xmmreg}{R_m}:movlpd {xmmreg},{Mod}{R_m}
+00001111,00010011,{Mod}{xmmreg}{R_m}:movlps {xmmreg},{Mod}{R_m}
+01100110,00001111,00010100,{Mod}{xmmreg}{R_m}:unpcklpd {Mod}{R_m},{xmmreg}
+00001111,00010100,{Mod}{xmmreg}{R_m}:unpcklps {Mod}{R_m},{xmmreg}
+01100110,00001111,00010101,{Mod}{xmmreg}{R_m}:unpckhpd {Mod}{R_m},{xmmreg}
+00001111,00010101,{Mod}{xmmreg}{R_m}:unpckhps {Mod}{R_m},{xmmreg}
+11110011,00001111,00010110,{Mod}{xmmreg}{R_m}:movshdup {Mod}{R_m},{xmmreg}
+01100110,00001111,00010110,{Mod}{xmmreg}{R_m}:movhpd {Mod}{R_m},{xmmreg}
+00001111,00010110,11{xmmreg1}{xmmreg2}:movlhps {xmmreg2},{xmmreg1}
+00001111,00010110,{Mod}{xmmreg}{R_m}:movhps {Mod}{R_m},{xmmreg}
+01100110,00001111,00010111,11{xmmreg1}{xmmreg2}:movlhpd {xmmreg1},{xmmreg2}
+00001111,00010111,11{xmmreg1}{xmmreg2}:movlhps {xmmreg1},{xmmreg2}
+01100110,00001111,00010111,{Mod}{xmmreg}{R_m}:movhpd {xmmreg},{Mod}{R_m}
+00001111,00010111,{Mod}{xmmreg}{R_m}:movhps {xmmreg},{Mod}{R_m}
+01100110,00001111,00101000,{Mod}{xmmreg}{R_m}:movapd {Mod}{R_m},{xmmreg}
+00001111,00101000,{Mod}{xmmreg}{R_m}:movaps {Mod}{R_m},{xmmreg}
+01100110,00001111,00101001,{Mod}{xmmreg}{R_m}:movapd {xmmreg},{Mod}{R_m}
+00001111,00101001,{Mod}{xmmreg}{R_m}:movaps {xmmreg},{Mod}{R_m}
+11110010,00001111,00101010,{mod}{xmmreg}{r_m}:cvtsi2sd {mod}{r_m},{xmmreg}
+11110011,00001111,00101010,{mod}{xmmreg}{r_m}:cvtsi2ss {mod}{r_m},{xmmreg}
+01100110,00001111,00101010,{MOD}{xmmreg}{R_M}:cvtpi2pd {MOD}{R_M},{xmmreg}
+00001111,00101010,{MOD}{xmmreg}{R_M}:cvtpi2ps {MOD}{R_M},{xmmreg}
+01100110,00001111,00101011,{mod}{xmmreg}{r_m}:movntpd {xmmreg},{mod}{r_m}
+00001111,00101011,{mod}{xmmreg}{r_m}:movntps {xmmreg},{mod}{r_m}
+11110010,00001111,00101100,{Mod}{reg}{R_m}:cvttsd2si {Mod}{R_m},{reg}
+11110011,00001111,00101100,{Mod}{reg}{R_m}:cvttss2si {Mod}{R_m},{reg}
+01100110,00001111,00101100,{Mod}{mmxreg}{R_m}:cvttpd2pi {Mod}{R_m},{mmxreg}
+00001111,00101100,{Mod}{mmxreg}{R_m}:cvttps2pi {Mod}{R_m},{mmxreg}
+01100110,00001111,00101101,{Mod}{mmxreg}{R_m}:cvtpd2pi {Mod}{R_m},{mmxreg}
+11110010,00001111,00101101,{Mod}{reg}{R_m}:cvtsd2si {Mod}{R_m},{reg}
+11110011,00001111,00101101,{Mod}{reg}{R_m}:cvtss2si {Mod}{R_m},{reg}
+00001111,00101101,{Mod}{mmxreg}{R_m}:cvtps2pi {Mod}{R_m},{mmxreg}
+01100110,00001111,00101110,{Mod}{xmmreg}{R_m}:ucomisd {Mod}{R_m},{xmmreg}
+00001111,00101110,{Mod}{xmmreg}{R_m}:ucomiss {Mod}{R_m},{xmmreg}
+01100110,00001111,00101111,{Mod}{xmmreg}{R_m}:comisd {Mod}{R_m},{xmmreg}
+00001111,00101111,{Mod}{xmmreg}{R_m}:comiss {Mod}{R_m},{xmmreg}
+00001111,00110111:getsec
+01100110,00001111,01010000,11{reg}{xmmreg}:movmskpd {xmmreg},{reg}
+00001111,01010000,11{reg}{xmmreg}:movmskps {xmmreg},{reg}
+01100110,00001111,01010001,{Mod}{xmmreg}{R_m}:sqrtpd {Mod}{R_m},{xmmreg}
+11110010,00001111,01010001,{Mod}{xmmreg}{R_m}:sqrtsd {Mod}{R_m},{xmmreg}
+11110011,00001111,01010001,{Mod}{xmmreg}{R_m}:sqrtss {Mod}{R_m},{xmmreg}
+00001111,01010001,{Mod}{xmmreg}{R_m}:sqrtps {Mod}{R_m},{xmmreg}
+11110011,00001111,01010010,{Mod}{xmmreg}{R_m}:rsqrtss {Mod}{R_m},{xmmreg}
+00001111,01010010,{Mod}{xmmreg}{R_m}:rsqrtps {Mod}{R_m},{xmmreg}
+11110011,00001111,01010011,{Mod}{xmmreg}{R_m}:rcpss {Mod}{R_m},{xmmreg}
+00001111,01010011,{Mod}{xmmreg}{R_m}:rcpps {Mod}{R_m},{xmmreg}
+01100110,00001111,01010100,{Mod}{xmmreg}{R_m}:andpd {Mod}{R_m},{xmmreg}
+00001111,01010100,{Mod}{xmmreg}{R_m}:andps {Mod}{R_m},{xmmreg}
+01100110,00001111,01010101,{Mod}{xmmreg}{R_m}:andnpd {Mod}{R_m},{xmmreg}
+00001111,01010101,{Mod}{xmmreg}{R_m}:andnps {Mod}{R_m},{xmmreg}
+01100110,00001111,01010110,{Mod}{xmmreg}{R_m}:orpd {Mod}{R_m},{xmmreg}
+00001111,01010110,{Mod}{xmmreg}{R_m}:orps {Mod}{R_m},{xmmreg}
+01100110,00001111,01010111,{Mod}{xmmreg}{R_m}:xorpd {Mod}{R_m},{xmmreg}
+00001111,01010111,{Mod}{xmmreg}{R_m}:xorps {Mod}{R_m},{xmmreg}
+11110010,00001111,01011000,{Mod}{xmmreg}{R_m}:addsd {Mod}{R_m},{xmmreg}
+11110011,00001111,01011000,{Mod}{xmmreg}{R_m}:addss {Mod}{R_m},{xmmreg}
+01100110,00001111,01011000,{Mod}{xmmreg}{R_m}:addpd {Mod}{R_m},{xmmreg}
+00001111,01011000,{Mod}{xmmreg}{R_m}:addps {Mod}{R_m},{xmmreg}
+11110010,00001111,01011001,{Mod}{xmmreg}{R_m}:mulsd {Mod}{R_m},{xmmreg}
+11110011,00001111,01011001,{Mod}{xmmreg}{R_m}:mulss {Mod}{R_m},{xmmreg}
+01100110,00001111,01011001,{Mod}{xmmreg}{R_m}:mulpd {Mod}{R_m},{xmmreg}
+00001111,01011001,{Mod}{xmmreg}{R_m}:mulps {Mod}{R_m},{xmmreg}
+11110010,00001111,01011010,{Mod}{xmmreg}{R_m}:cvtsd2ss {Mod}{R_m},{xmmreg}
+11110011,00001111,01011010,{Mod}{xmmreg}{R_m}:cvtss2sd {Mod}{R_m},{xmmreg}
+01100110,00001111,01011010,{Mod}{xmmreg}{R_m}:cvtpd2ps {Mod}{R_m},{xmmreg}
+00001111,01011010,{Mod}{xmmreg}{R_m}:cvtps2pd {Mod}{R_m},{xmmreg}
+01100110,00001111,01011011,{Mod}{xmmreg}{R_m}:cvtps2dq {Mod}{R_m},{xmmreg}
+11110011,00001111,01011011,{Mod}{xmmreg}{R_m}:cvttps2dq {Mod}{R_m},{xmmreg}
+00001111,01011011,{Mod}{xmmreg}{R_m}:cvtdq2ps {Mod}{R_m},{xmmreg}
+11110010,00001111,01011100,{Mod}{xmmreg}{R_m}:subsd {Mod}{R_m},{xmmreg}
+11110011,00001111,01011100,{Mod}{xmmreg}{R_m}:subss {Mod}{R_m},{xmmreg}
+01100110,00001111,01011100,{Mod}{xmmreg}{R_m}:subpd {Mod}{R_m},{xmmreg}
+00001111,01011100,{Mod}{xmmreg}{R_m}:subps {Mod}{R_m},{xmmreg}
+11110010,00001111,01011101,{Mod}{xmmreg}{R_m}:minsd {Mod}{R_m},{xmmreg}
+11110011,00001111,01011101,{Mod}{xmmreg}{R_m}:minss {Mod}{R_m},{xmmreg}
+01100110,00001111,01011101,{Mod}{xmmreg}{R_m}:minpd {Mod}{R_m},{xmmreg}
+00001111,01011101,{Mod}{xmmreg}{R_m}:minps {Mod}{R_m},{xmmreg}
+11110010,00001111,01011110,{Mod}{xmmreg}{R_m}:divsd {Mod}{R_m},{xmmreg}
+11110011,00001111,01011110,{Mod}{xmmreg}{R_m}:divss {Mod}{R_m},{xmmreg}
+01100110,00001111,01011110,{Mod}{xmmreg}{R_m}:divpd {Mod}{R_m},{xmmreg}
+00001111,01011110,{Mod}{xmmreg}{R_m}:divps {Mod}{R_m},{xmmreg}
+11110010,00001111,01011111,{Mod}{xmmreg}{R_m}:maxsd {Mod}{R_m},{xmmreg}
+11110011,00001111,01011111,{Mod}{xmmreg}{R_m}:maxss {Mod}{R_m},{xmmreg}
+01100110,00001111,01011111,{Mod}{xmmreg}{R_m}:maxpd {Mod}{R_m},{xmmreg}
+00001111,01011111,{Mod}{xmmreg}{R_m}:maxps {Mod}{R_m},{xmmreg}
+01100110,00001111,01100000,{Mod}{xmmreg}{R_m}:punpcklbw {Mod}{R_m},{xmmreg}
+00001111,01100000,{MOD}{mmxreg}{R_M}:punpcklbw {MOD}{R_M},{mmxreg}
+01100110,00001111,01100001,{Mod}{xmmreg}{R_m}:punpcklwd {Mod}{R_m},{xmmreg}
+00001111,01100001,{MOD}{mmxreg}{R_M}:punpcklwd {MOD}{R_M},{mmxreg}
+01100110,00001111,01100010,{Mod}{xmmreg}{R_m}:punpckldq {Mod}{R_m},{xmmreg}
+00001111,01100010,{MOD}{mmxreg}{R_M}:punpckldq {MOD}{R_M},{mmxreg}
+01100110,00001111,01100011,{Mod}{xmmreg}{R_m}:packsswb {Mod}{R_m},{xmmreg}
+00001111,01100011,{MOD}{mmxreg}{R_M}:packsswb {MOD}{R_M},{mmxreg}
+01100110,00001111,01100100,{Mod}{xmmreg}{R_m}:pcmpgtb {Mod}{R_m},{xmmreg}
+00001111,01100100,{MOD}{mmxreg}{R_M}:pcmpgtb {MOD}{R_M},{mmxreg}
+01100110,00001111,01100101,{Mod}{xmmreg}{R_m}:pcmpgtw {Mod}{R_m},{xmmreg}
+00001111,01100101,{MOD}{mmxreg}{R_M}:pcmpgtw {MOD}{R_M},{mmxreg}
+01100110,00001111,01100110,{Mod}{xmmreg}{R_m}:pcmpgtd {Mod}{R_m},{xmmreg}
+00001111,01100110,{MOD}{mmxreg}{R_M}:pcmpgtd {MOD}{R_M},{mmxreg}
+01100110,00001111,01100111,{Mod}{xmmreg}{R_m}:packuswb {Mod}{R_m},{xmmreg}
+00001111,01100111,{MOD}{mmxreg}{R_M}:packuswb {MOD}{R_M},{mmxreg}
+01100110,00001111,01101000,{Mod}{xmmreg}{R_m}:punpckhbw {Mod}{R_m},{xmmreg}
+00001111,01101000,{MOD}{mmxreg}{R_M}:punpckhbw {MOD}{R_M},{mmxreg}
+01100110,00001111,01101001,{Mod}{xmmreg}{R_m}:punpckhwd {Mod}{R_m},{xmmreg}
+00001111,01101001,{MOD}{mmxreg}{R_M}:punpckhwd {MOD}{R_M},{mmxreg}
+01100110,00001111,01101010,{Mod}{xmmreg}{R_m}:punpckhdq {Mod}{R_m},{xmmreg}
+00001111,01101010,{MOD}{mmxreg}{R_M}:punpckhdq {MOD}{R_M},{mmxreg}
+01100110,00001111,01101011,{Mod}{xmmreg}{R_m}:packssdw {Mod}{R_m},{xmmreg}
+00001111,01101011,{MOD}{mmxreg}{R_M}:packssdw {MOD}{R_M},{mmxreg}
+01100110,00001111,01101100,{Mod}{xmmreg}{R_m}:punpcklqdq {Mod}{R_m},{xmmreg}
+01100110,00001111,01101101,{Mod}{xmmreg}{R_m}:punpckhqdq {Mod}{R_m},{xmmreg}
+01100110,00001111,01101110,{mod}{xmmreg}{r_m}:movd {mod}{r_m},{xmmreg}
+00001111,01101110,{mod}{mmxreg}{r_m}:movd {mod}{r_m},{mmxreg}
+01100110,00001111,01101111,{Mod}{xmmreg}{R_m}:movdqa {Mod}{R_m},{xmmreg}
+11110011,00001111,01101111,{Mod}{xmmreg}{R_m}:movdqu {Mod}{R_m},{xmmreg}
+00001111,01101111,{MOD}{mmxreg}{R_M}:movq {MOD}{R_M},{mmxreg}
+01100110,00001111,01110000,{Mod}{xmmreg}{R_m},{imm8}:pshufd {imm8},{Mod}{R_m},{xmmreg}
+11110010,00001111,01110000,{Mod}{xmmreg}{R_m},{imm8}:pshuflw {imm8},{Mod}{R_m},{xmmreg}
+11110011,00001111,01110000,{Mod}{xmmreg}{R_m},{imm8}:pshufhw {imm8},{Mod}{R_m},{xmmreg}
+00001111,01110000,{MOD}{mmxreg}{R_M},{imm8}:pshufw {imm8},{MOD}{R_M},{mmxreg}
+01100110,00001111,01110100,{Mod}{xmmreg}{R_m}:pcmpeqb {Mod}{R_m},{xmmreg}
+00001111,01110100,{MOD}{mmxreg}{R_M}:pcmpeqb {MOD}{R_M},{mmxreg}
+01100110,00001111,01110101,{Mod}{xmmreg}{R_m}:pcmpeqw {Mod}{R_m},{xmmreg}
+00001111,01110101,{MOD}{mmxreg}{R_M}:pcmpeqw {MOD}{R_M},{mmxreg}
+01100110,00001111,01110110,{Mod}{xmmreg}{R_m}:pcmpeqd {Mod}{R_m},{xmmreg}
+00001111,01110110,{MOD}{mmxreg}{R_M}:pcmpeqd {MOD}{R_M},{mmxreg}
+01100110,00001111,01111100,{Mod}{xmmreg}{R_m}:haddpd {Mod}{R_m},{xmmreg}
+11110010,00001111,01111100,{Mod}{xmmreg}{R_m}:haddps {Mod}{R_m},{xmmreg}
+01100110,00001111,01111101,{Mod}{xmmreg}{R_m}:hsubpd {Mod}{R_m},{xmmreg}
+11110010,00001111,01111101,{Mod}{xmmreg}{R_m}:hsubps {Mod}{R_m},{xmmreg}
+01100110,00001111,01111110,{mod}{xmmreg}{r_m}:movd {xmmreg},{mod}{r_m}
+11110011,00001111,01111110,{Mod}{xmmreg}{R_m}:movq {Mod}{R_m},{xmmreg}
+00001111,01111110,{mod}{mmxreg}{r_m}:movd {mmxreg},{mod}{r_m}
+01100110,00001111,01111111,{Mod}{xmmreg}{R_m}:movdqa {xmmreg},{Mod}{R_m}
+11110011,00001111,01111111,{Mod}{xmmreg}{R_m}:movdqu {xmmreg},{Mod}{R_m}
+00001111,01111111,{MOD}{mmxreg}{R_M}:movq {mmxreg},{MOD}{R_M}
+00001111,11000011,{mod}{reg}{r_m}:movnti {reg},{mod}{r_m}
+01100110,00001111,11000100,{mod}{xmmreg}{r_m},{imm8}:pinsrw {imm8},{mod}{r_m},{xmmreg}
+00001111,11000100,{mod}{mmxreg}{r_m},{imm8}:pinsrw {imm8},{mod}{r_m},{mmxreg}
+01100110,00001111,11000101,11{reg}{xmmreg},{imm8}:pextrw {imm8},{xmmreg},{reg}
+00001111,11000101,11{reg}{mmxreg},{imm8}:pextrw {imm8},{mmxreg},{reg}
+01100110,00001111,11000110,{Mod}{xmmreg}{R_m},{imm8}:shufpd {imm8},{Mod}{R_m},{xmmreg}
+00001111,11000110,{Mod}{xmmreg}{R_m},{imm8}:shufps {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,11010001,{Mod}{xmmreg}{R_m}:psrlw {Mod}{R_m},{xmmreg}
+00001111,11010001,{MOD}{mmxreg}{R_M}:psrlw {MOD}{R_M},{mmxreg}
+01100110,00001111,11010010,{Mod}{xmmreg}{R_m}:psrld {Mod}{R_m},{xmmreg}
+00001111,11010010,{MOD}{mmxreg}{R_M}:psrld {MOD}{R_M},{mmxreg}
+01100110,00001111,11010011,{Mod}{xmmreg}{R_m}:psrlq {Mod}{R_m},{xmmreg}
+00001111,11010011,{MOD}{mmxreg}{R_M}:psrlq {MOD}{R_M},{mmxreg}
+01100110,00001111,11010100,{Mod}{xmmreg}{R_m}:paddq {Mod}{R_m},{xmmreg}
+00001111,11010100,{MOD}{mmxreg}{R_M}:paddq {MOD}{R_M},{mmxreg}
+01100110,00001111,11010101,{Mod}{xmmreg}{R_m}:pmullw {Mod}{R_m},{xmmreg}
+00001111,11010101,{MOD}{mmxreg}{R_M}:pmullw {MOD}{R_M},{mmxreg}
+01100110,00001111,11010110,{Mod}{xmmreg}{R_m}:movq {xmmreg},{Mod}{R_m}
+11110010,00001111,11010110,11{mmxreg}{xmmreg}:movdq2q {xmmreg},{mmxreg}
+11110011,00001111,11010110,11{xmmreg}{mmxreg}:movq2dq {mmxreg},{xmmreg}
+01100110,00001111,11010111,11{reg}{xmmreg}:pmovmskb {xmmreg},{reg}
+00001111,11010111,11{reg}{mmxreg}:pmovmskb {mmxreg},{reg}
+01100110,00001111,11011000,{Mod}{xmmreg}{R_m}:psubusb {Mod}{R_m},{xmmreg}
+00001111,11011000,{MOD}{mmxreg}{R_M}:psubusb {MOD}{R_M},{mmxreg}
+01100110,00001111,11011001,{Mod}{xmmreg}{R_m}:psubusw {Mod}{R_m},{xmmreg}
+00001111,11011001,{MOD}{mmxreg}{R_M}:psubusw {MOD}{R_M},{mmxreg}
+01100110,00001111,11011010,{Mod}{xmmreg}{R_m}:pminub {Mod}{R_m},{xmmreg}
+00001111,11011010,{MOD}{mmxreg}{R_M}:pminub {MOD}{R_M},{mmxreg}
+01100110,00001111,11011100,{Mod}{xmmreg}{R_m}:paddusb {Mod}{R_m},{xmmreg}
+00001111,11011100,{MOD}{mmxreg}{R_M}:paddusb {MOD}{R_M},{mmxreg}
+01100110,00001111,11011101,{Mod}{xmmreg}{R_m}:paddusw {Mod}{R_m},{xmmreg}
+00001111,11011101,{MOD}{mmxreg}{R_M}:paddusw {MOD}{R_M},{mmxreg}
+01100110,00001111,11011110,{Mod}{xmmreg}{R_m}:pmaxub {Mod}{R_m},{xmmreg}
+00001111,11011110,{MOD}{mmxreg}{R_M}:pmaxub {MOD}{R_M},{mmxreg}
+01100110,00001111,11100000,{Mod}{xmmreg}{R_m}:pavgb {Mod}{R_m},{xmmreg}
+00001111,11100000,{MOD}{mmxreg}{R_M}:pavgb {MOD}{R_M},{mmxreg}
+01100110,00001111,11100001,{Mod}{xmmreg}{R_m}:psraw {Mod}{R_m},{xmmreg}
+00001111,11100001,{MOD}{mmxreg}{R_M}:psraw {MOD}{R_M},{mmxreg}
+01100110,00001111,11100010,{Mod}{xmmreg}{R_m}:psrad {Mod}{R_m},{xmmreg}
+00001111,11100010,{MOD}{mmxreg}{R_M}:psrad {MOD}{R_M},{mmxreg}
+01100110,00001111,11100011,{Mod}{xmmreg}{R_m}:pavgw {Mod}{R_m},{xmmreg}
+00001111,11100011,{MOD}{mmxreg}{R_M}:pavgw {MOD}{R_M},{mmxreg}
+01100110,00001111,11100100,{Mod}{xmmreg}{R_m}:pmulhuw {Mod}{R_m},{xmmreg}
+00001111,11100100,{MOD}{mmxreg}{R_M}:pmulhuw {MOD}{R_M},{mmxreg}
+01100110,00001111,11100101,{Mod}{xmmreg}{R_m}:pmulhw {Mod}{R_m},{xmmreg}
+00001111,11100101,{MOD}{mmxreg}{R_M}:pmulhw {MOD}{R_M},{mmxreg}
+01100110,00001111,11100111,{Mod}{xmmreg}{R_m}:movntdq {xmmreg},{Mod}{R_m}
+00001111,11100111,{MOD}{mmxreg}{R_M}:movntq {mmxreg},{MOD}{R_M}
+01100110,00001111,11101000,{Mod}{xmmreg}{R_m}:psubsb {Mod}{R_m},{xmmreg}
+00001111,11101000,{MOD}{mmxreg}{R_M}:psubsb {MOD}{R_M},{mmxreg}
+01100110,00001111,11101001,{Mod}{xmmreg}{R_m}:psubsw {Mod}{R_m},{xmmreg}
+00001111,11101001,{MOD}{mmxreg}{R_M}:psubsw {MOD}{R_M},{mmxreg}
+01100110,00001111,11101010,{Mod}{xmmreg}{R_m}:pminsw {Mod}{R_m},{xmmreg}
+00001111,11101010,{MOD}{mmxreg}{R_M}:pminsw {MOD}{R_M},{mmxreg}
+01100110,00001111,11101100,{Mod}{xmmreg}{R_m}:paddsb {Mod}{R_m},{xmmreg}
+00001111,11101100,{MOD}{mmxreg}{R_M}:paddsb {MOD}{R_M},{mmxreg}
+01100110,00001111,11101101,{Mod}{xmmreg}{R_m}:paddsw {Mod}{R_m},{xmmreg}
+00001111,11101101,{MOD}{mmxreg}{R_M}:paddsw {MOD}{R_M},{mmxreg}
+01100110,00001111,11101110,{Mod}{xmmreg}{R_m}:pmaxsw {Mod}{R_m},{xmmreg}
+00001111,11101110,{MOD}{mmxreg}{R_M}:pmaxsw {MOD}{R_M},{mmxreg}
+11110010,00001111,11110000,{mod}{xmmreg}{r_m}:lddqu {mod}{r_m},{xmmreg}
+01100110,00001111,11110001,{Mod}{xmmreg}{R_m}:psllw {Mod}{R_m},{xmmreg}
+00001111,11110001,{MOD}{mmxreg}{R_M}:psllw {MOD}{R_M},{mmxreg}
+01100110,00001111,11110010,{Mod}{xmmreg}{R_m}:pslld {Mod}{R_m},{xmmreg}
+00001111,11110010,{MOD}{mmxreg}{R_M}:pslld {MOD}{R_M},{mmxreg}
+01100110,00001111,11110011,{Mod}{xmmreg}{R_m}:psllq {Mod}{R_m},{xmmreg}
+00001111,11110011,{MOD}{mmxreg}{R_M}:psllq {MOD}{R_M},{mmxreg}
+01100110,00001111,11110100,{Mod}{xmmreg}{R_m}:pmuludq {Mod}{R_m},{xmmreg}
+00001111,11110100,{MOD}{mmxreg}{R_M}:pmuludq {MOD}{R_M},{mmxreg}
+01100110,00001111,11110110,{Mod}{xmmreg}{R_m}:psadbw {Mod}{R_m},{xmmreg}
+00001111,11110110,{MOD}{mmxreg}{R_M}:psadbw {MOD}{R_M},{mmxreg}
+01100110,00001111,11110111,11{xmmreg1}{xmmreg2}:maskmovdqu {xmmreg2},{xmmreg1}
+00001111,11110111,11{mmxreg1}{mmxreg2}:maskmovq {mmxreg2},{mmxreg1}
+01100110,00001111,11111000,{Mod}{xmmreg}{R_m}:psubb {Mod}{R_m},{xmmreg}
+00001111,11111000,{MOD}{mmxreg}{R_M}:psubb {MOD}{R_M},{mmxreg}
+01100110,00001111,11111001,{Mod}{xmmreg}{R_m}:psubw {Mod}{R_m},{xmmreg}
+00001111,11111001,{MOD}{mmxreg}{R_M}:psubw {MOD}{R_M},{mmxreg}
+01100110,00001111,11111010,{Mod}{xmmreg}{R_m}:psubd {Mod}{R_m},{xmmreg}
+00001111,11111010,{MOD}{mmxreg}{R_M}:psubd {MOD}{R_M},{mmxreg}
+01100110,00001111,11111011,{Mod}{xmmreg}{R_m}:psubq {Mod}{R_m},{xmmreg}
+00001111,11111011,{MOD}{mmxreg}{R_M}:psubq {MOD}{R_M},{mmxreg}
+01100110,00001111,11111100,{Mod}{xmmreg}{R_m}:paddb {Mod}{R_m},{xmmreg}
+00001111,11111100,{MOD}{mmxreg}{R_M}:paddb {MOD}{R_M},{mmxreg}
+01100110,00001111,11111101,{Mod}{xmmreg}{R_m}:paddw {Mod}{R_m},{xmmreg}
+00001111,11111101,{MOD}{mmxreg}{R_M}:paddw {MOD}{R_M},{mmxreg}
+01100110,00001111,11111110,{Mod}{xmmreg}{R_m}:paddd {Mod}{R_m},{xmmreg}
+00001111,11111110,{MOD}{mmxreg}{R_M}:paddd {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00000000,{Mod}{xmmreg}{R_m}:pshufb {Mod}{R_m},{xmmreg}
+00001111,00111000,00000000,{MOD}{mmxreg}{R_M}:pshufb {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00000001,{Mod}{xmmreg}{R_m}:phaddw {Mod}{R_m},{xmmreg}
+00001111,00111000,00000001,{MOD}{mmxreg}{R_M}:phaddw {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00000010,{Mod}{xmmreg}{R_m}:phaddd {Mod}{R_m},{xmmreg}
+00001111,00111000,00000010,{MOD}{mmxreg}{R_M}:phaddd {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00000011,{Mod}{xmmreg}{R_m}:phaddsw {Mod}{R_m},{xmmreg}
+00001111,00111000,00000011,{MOD}{mmxreg}{R_M}:phaddsw {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00000100,{Mod}{xmmreg}{R_m}:pmaddubsw {Mod}{R_m},{xmmreg}
+00001111,00111000,00000100,{MOD}{mmxreg}{R_M}:pmaddubsw {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00000101,{Mod}{xmmreg}{R_m}:phsubw {Mod}{R_m},{xmmreg}
+00001111,00111000,00000101,{MOD}{mmxreg}{R_M}:phsubw {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00000110,{Mod}{xmmreg}{R_m}:phsubd {Mod}{R_m},{xmmreg}
+00001111,00111000,00000110,{MOD}{mmxreg}{R_M}:phsubd {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00000111,{Mod}{xmmreg}{R_m}:phsubsw {Mod}{R_m},{xmmreg}
+00001111,00111000,00000111,{MOD}{mmxreg}{R_M}:phsubsw {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00001000,{Mod}{xmmreg}{R_m}:psignb {Mod}{R_m},{xmmreg}
+00001111,00111000,00001000,{MOD}{mmxreg}{R_M}:psignb {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00001001,{Mod}{xmmreg}{R_m}:psignw {Mod}{R_m},{xmmreg}
+00001111,00111000,00001001,{MOD}{mmxreg}{R_M}:psignw {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00001010,{Mod}{xmmreg}{R_m}:psignd {Mod}{R_m},{xmmreg}
+00001111,00111000,00001010,{MOD}{mmxreg}{R_M}:psignd {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00001011,{Mod}{xmmreg}{R_m}:pmulhrsw {Mod}{R_m},{xmmreg}
+00001111,00111000,00001011,{MOD}{mmxreg}{R_M}:pmulhrsw {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00011100,{Mod}{xmmreg}{R_m}:pabsb {Mod}{R_m},{xmmreg}
+00001111,00111000,00011100,{MOD}{mmxreg}{R_M}:pabsb {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00011101,{Mod}{xmmreg}{R_m}:pabsw {Mod}{R_m},{xmmreg}
+00001111,00111000,00011101,{MOD}{mmxreg}{R_M}:pabsw {MOD}{R_M},{mmxreg}
+01100110,00001111,00111000,00011110,{Mod}{xmmreg}{R_m}:pabsd {Mod}{R_m},{xmmreg}
+00001111,00111000,00011110,{MOD}{mmxreg}{R_M}:pabsd {MOD}{R_M},{mmxreg}
+01100110,00001111,00111010,00001111,{Mod}{xmmreg}{R_m},{imm8}:palignr {imm8},{Mod}{R_m},{xmmreg}
+00001111,00111010,00001111,{MOD}{mmxreg}{R_M},{imm8}:palignr {imm8},{MOD}{R_M},{mmxreg}
+01100110,00001111,11000111,{mod}110{r_m}:vmclear {mod}{r_m}
+11110011,00001111,11000111,{mod}110{r_m}:vmxon {mod}{r_m}
+00001111,11000111,{mod}110{r_m}:vmptrld {mod}{r_m}
+00001111,11000111,{mod}111{r_m}:vmptrst {mod}{r_m}
+01100110,00001111,01110001,11010{xmmreg},{imm8}:psrlw {imm8},{xmmreg}
+00001111,01110001,11010{mmxreg},{imm8}:psrlw {imm8},{mmxreg}
+01100110,00001111,01110001,11100{xmmreg},{imm8}:psraw {imm8},{xmmreg}
+00001111,01110001,11100{mmxreg},{imm8}:psraw {imm8},{mmxreg}
+01100110,00001111,01110001,11110{xmmreg},{imm8}:psllw {imm8},{xmmreg}
+00001111,01110001,11110{mmxreg},{imm8}:psllw {imm8},{mmxreg}
+01100110,00001111,01110010,11010{xmmreg},{imm8}:psrld {imm8},{xmmreg}
+00001111,01110010,11010{mmxreg},{imm8}:psrld {imm8},{mmxreg}
+01100110,00001111,01110010,11100{xmmreg},{imm8}:psrad {imm8},{xmmreg}
+00001111,01110010,11100{mmxreg},{imm8}:psrad {imm8},{mmxreg}
+01100110,00001111,01110010,11110{xmmreg},{imm8}:pslld {imm8},{xmmreg}
+00001111,01110010,11110{mmxreg},{imm8}:pslld {imm8},{mmxreg}
+01100110,00001111,01110011,11010{xmmreg},{imm8}:psrlq {imm8},{xmmreg}
+00001111,01110011,11010{mmxreg},{imm8}:psrlq {imm8},{mmxreg}
+01100110,00001111,01110011,11011{xmmreg},{imm8}:psrldq {imm8},{xmmreg}
+01100110,00001111,01110011,11110{xmmreg},{imm8}:psllq {imm8},{xmmreg}
+00001111,01110011,11110{mmxreg},{imm8}:psllq {imm8},{mmxreg}
+01100110,00001111,01110011,11111{xmmreg},{imm8}:pslldq {imm8},{xmmreg}
+00001111,10101110,11101000:lfence
+00001111,10101110,11110000:mfence
+00001111,10101110,11111000:sfence
+00001111,10101110,{mod}111{r_m}:clflush {mod}{r_m}
+00001111,00001111,{MOD}{mmxreg}{R_M}:INVALID {MOD}{R_M},{mmxreg}
+01100110,00001111,00111010,00001100,{Mod}{xmmreg}{R_m},{imm8}:blendps {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,00001101,{Mod}{xmmreg}{R_m},{imm8}:blendpd {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00010100,{Mod}{xmmreg}{R_m}:blendvps %xmm0,{Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00010101,{Mod}{xmmreg}{R_m}:blendvpd %xmm0,{Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,01000000,{Mod}{xmmreg}{R_m},{imm8}:dpps {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,01000001,{Mod}{xmmreg}{R_m},{imm8}:dppd {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,00100001,{Mod}{xmmreg}{R_m},{imm8}:insertps {imm8},{Mod}{R_m},{xmmreg}
+# Mod == 11 is not valid
+01100110,00001111,00111000,00101010,{Mod}{xmmreg}{R_m}:movntdqa {Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,01000010,{Mod}{xmmreg}{R_m},{imm8}:mpsadbw {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00101011,{Mod}{xmmreg}{R_m}:packusdw {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00010000,{Mod}{xmmreg}{R_m}:pblendvb %xmm0,{Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,00001110,{Mod}{xmmreg}{R_m},{imm8}:pblendw {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00101001,{Mod}{xmmreg}{R_m}:pcmpeqq {Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,01100001,{Mod}{xmmreg}{R_m},{imm8}:pcmpestri {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,01100000,{Mod}{xmmreg}{R_m},{imm8}:pcmpestrm {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,01100011,{Mod}{xmmreg}{R_m},{imm8}:pcmpistri {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,01100010,{Mod}{xmmreg}{R_m},{imm8}:pcmpistrm {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00110111,{Mod}{xmmreg}{R_m}:pcmpgtq {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,01000001,{Mod}{xmmreg}{R_m}:phminposuw {Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,00100000,{mod}{xmmreg}{r_m},{imm8}:pinsrb {imm8},{mod}{r_m},{xmmreg}
+01100110,00001111,00111010,00100010,{mod}{xmmreg}{r_m},{imm8}:pinsrd {imm8},{mod}{r_m},{xmmreg}
+01100110,00001111,00111000,00111100,{Mod}{xmmreg}{R_m}:pmaxsb {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00111101,{Mod}{xmmreg}{R_m}:pmaxsd {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00111111,{Mod}{xmmreg}{R_m}:pmaxud {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00111110,{Mod}{xmmreg}{R_m}:pmaxuw {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00111000,{Mod}{xmmreg}{R_m}:pminsb {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00111001,{Mod}{xmmreg}{R_m}:pminsd {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00111011,{Mod}{xmmreg}{R_m}:pminud {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00111010,{Mod}{xmmreg}{R_m}:pminuw {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00100000,{Mod}{xmmreg}{R_m}:pmovsxbw {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00100001,{Mod}{xmmreg}{R_m}:pmovsxbd {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00100010,{Mod}{xmmreg}{R_m}:pmovsxbq {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00100011,{Mod}{xmmreg}{R_m}:pmovsxwd {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00100100,{Mod}{xmmreg}{R_m}:pmovsxwq {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00100101,{Mod}{xmmreg}{R_m}:pmovsxdq {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00110000,{Mod}{xmmreg}{R_m}:pmovzxbw {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00110001,{Mod}{xmmreg}{R_m}:pmovzxbd {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00110010,{Mod}{xmmreg}{R_m}:pmovzxbq {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00110011,{Mod}{xmmreg}{R_m}:pmovzxwd {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00110100,{Mod}{xmmreg}{R_m}:pmovzxwq {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00110101,{Mod}{xmmreg}{R_m}:pmovzxdq {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00101000,{Mod}{xmmreg}{R_m}:pmuldq {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,01000000,{Mod}{xmmreg}{R_m}:pmulld {Mod}{R_m},{xmmreg}
+01100110,00001111,00111000,00010111,{Mod}{xmmreg}{R_m}:ptest {Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,00001000,{Mod}{xmmreg}{R_m},{imm8}:roundps {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,00001001,{Mod}{xmmreg}{R_m},{imm8}:roundpd {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,00001010,{Mod}{xmmreg}{R_m},{imm8}:roundss {imm8},{Mod}{R_m},{xmmreg}
+01100110,00001111,00111010,00001011,{Mod}{xmmreg}{R_m},{imm8}:roundsd {imm8},{Mod}{R_m},{xmmreg}
+# ORDER:
+dnl Many previous entries depend on this being last.
+000{sreg2}111:pop {sreg2}
+# ORDER END:
diff --git a/third_party/elfutils/libcpu/defs/i386.doc b/third_party/elfutils/libcpu/defs/i386.doc
new file mode 100644
index 0000000..732cd23
--- /dev/null
+++ b/third_party/elfutils/libcpu/defs/i386.doc
@@ -0,0 +1,74 @@
+{imm} only parameter:
+  - is {s} in opcode: {s} == 0, unsigned (8/)16/32 bit immediate
+                      {s} == 1, signed 8 bit immediate
+
+{es:di}: segment register normally %es, can be overwritten
+         edi/di depending on apfx
+
+{ds:si}: segment register normally %ds, can be overwritten
+         esi/si depending on apfx
+
+{ax}     al/ax/eax depending of dpfx and w
+
+{dx}     (%edx) or (%dx) depending on apfx
+
+
+{w}      0 = b, 1 = { no dpfx = l, dpfx = w }
+
+{W}      no dpfx = <empty>, dpfx = w
+{WW}     no dpfx = l, dpfx = w
+
+{R} rep prefix possible
+{RE} repe or repne prefix possible
+
+{ccc} CRx registers
+{ddd} DRx registers
+
+{gg}  00 = b, 01 = w, 10 = d, 11 = <illegal>
+{0g}  00 = b, 01 = w, 10 = <illegal>, 11 = <illegal>
+{GG}  00 = <illegal>, 01 = w, 10 = d, 11 = q
+{gG}  00 = <illegal>, 01 = w, 10 = d, 11 = <illegal>
+
+{modr/m} normal registers
+{MODR/M} MMX registers
+{ModR/m} XMM registers
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Special opcodes (prefixes):
+
+
+01100111:{apfx}
+01100110:{dpfx}
+
+00101110:{cs}
+00111110:{ds}
+00100110:{es}
+01100100:{fs}
+01100101:{gs}
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+table format
+
+1bit RE flag
+1bit R flag
+16bit mnemonic
+3bit suffix
+
+5bit fct
+2bit string
+6bit offset1
+5bit offset2
+
+4bit fct
+1bit string
+6bit offset1
+4bit offset2
+
+2bit fct
+1bit string
+3bit offset1
+1bit offset2
+
+61bit
diff --git a/third_party/elfutils/libcpu/i386_data.h b/third_party/elfutils/libcpu/i386_data.h
new file mode 100644
index 0000000..b8a34c3
--- /dev/null
+++ b/third_party/elfutils/libcpu/i386_data.h
@@ -0,0 +1,1418 @@
+/* Helper routines for disassembler for x86/x86-64.
+   Copyright (C) 2007, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <libasm.h>
+
+struct instr_enc
+{
+  /* The mnemonic.  Especially encoded for the optimized table.  */
+  unsigned int mnemonic : MNEMONIC_BITS;
+
+  /* The rep/repe prefixes.  */
+  unsigned int rep : 1;
+  unsigned int repe : 1;
+
+  /* Mnemonic suffix.  */
+  unsigned int suffix : SUFFIX_BITS;
+
+  /* Nonzero if the instruction uses modr/m.  */
+  unsigned int modrm : 1;
+
+  /* 1st parameter.  */
+  unsigned int fct1 : FCT1_BITS;
+#ifdef STR1_BITS
+  unsigned int str1 : STR1_BITS;
+#endif
+  unsigned int off1_1 : OFF1_1_BITS;
+  unsigned int off1_2 : OFF1_2_BITS;
+  unsigned int off1_3 : OFF1_3_BITS;
+
+  /* 2nd parameter.  */
+  unsigned int fct2 : FCT2_BITS;
+#ifdef STR2_BITS
+  unsigned int str2 : STR2_BITS;
+#endif
+  unsigned int off2_1 : OFF2_1_BITS;
+  unsigned int off2_2 : OFF2_2_BITS;
+  unsigned int off2_3 : OFF2_3_BITS;
+
+  /* 3rd parameter.  */
+  unsigned int fct3 : FCT3_BITS;
+#ifdef STR3_BITS
+  unsigned int str3 : STR3_BITS;
+#endif
+  unsigned int off3_1 : OFF3_1_BITS;
+#ifdef OFF3_2_BITS
+  unsigned int off3_2 : OFF3_2_BITS;
+#endif
+#ifdef OFF3_3_BITS
+  unsigned int off3_3 : OFF3_3_BITS;
+#endif
+};
+
+
+typedef int (*opfct_t) (struct output_data *);
+
+
+static int
+data_prefix (struct output_data *d)
+{
+  char ch = '\0';
+  if (*d->prefixes & has_cs)
+    {
+      ch = 'c';
+      *d->prefixes &= ~has_cs;
+    }
+  else if (*d->prefixes & has_ds)
+    {
+      ch = 'd';
+      *d->prefixes &= ~has_ds;
+    }
+  else if (*d->prefixes & has_es)
+    {
+      ch = 'e';
+      *d->prefixes &= ~has_es;
+    }
+  else if (*d->prefixes & has_fs)
+    {
+      ch = 'f';
+      *d->prefixes &= ~has_fs;
+    }
+  else if (*d->prefixes & has_gs)
+    {
+      ch = 'g';
+      *d->prefixes &= ~has_gs;
+    }
+  else if (*d->prefixes & has_ss)
+    {
+      ch = 's';
+      *d->prefixes &= ~has_ss;
+    }
+  else
+    return 0;
+
+  if (*d->bufcntp + 4 > d->bufsize)
+    return *d->bufcntp + 4 - d->bufsize;
+
+  d->bufp[(*d->bufcntp)++] = '%';
+  d->bufp[(*d->bufcntp)++] = ch;
+  d->bufp[(*d->bufcntp)++] = 's';
+  d->bufp[(*d->bufcntp)++] = ':';
+
+  return 0;
+}
+
+#ifdef X86_64
+static const char hiregs[8][4] =
+  {
+    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+  };
+static const char aregs[8][4] =
+  {
+    "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"
+  };
+static const char dregs[8][4] =
+  {
+    "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
+  };
+#else
+static const char aregs[8][4] =
+  {
+    "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
+  };
+# define dregs aregs
+#endif
+
+static int
+general_mod$r_m (struct output_data *d)
+{
+  int r = data_prefix (d);
+  if (r != 0)
+    return r;
+
+  int prefixes = *d->prefixes;
+  const uint8_t *data = &d->data[d->opoff1 / 8];
+  char *bufp = d->bufp;
+  size_t *bufcntp = d->bufcntp;
+  size_t bufsize = d->bufsize;
+
+  uint_fast8_t modrm = data[0];
+#ifndef X86_64
+  if (unlikely ((prefixes & has_addr16) != 0))
+    {
+      int16_t disp = 0;
+      bool nodisp = false;
+
+      if ((modrm & 0xc7) == 6 || (modrm & 0xc0) == 0x80)
+	/* 16 bit displacement.  */
+	disp = read_2sbyte_unaligned (&data[1]);
+      else if ((modrm & 0xc0) == 0x40)
+	/* 8 bit displacement.  */
+	disp = *(const int8_t *) &data[1];
+      else if ((modrm & 0xc0) == 0)
+	nodisp = true;
+
+      char tmpbuf[sizeof ("-0x1234(%rr,%rr)")];
+      int n;
+      if ((modrm & 0xc7) == 6)
+	n = snprintf (tmpbuf, sizeof (tmpbuf), "0x%" PRIx16, disp);
+      else
+	{
+	  n = 0;
+	  if (!nodisp)
+	    n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx16,
+			  disp < 0 ? "-" : "", disp < 0 ? -disp : disp);
+
+	  if ((modrm & 0x4) == 0)
+	    n += snprintf (tmpbuf + n, sizeof (tmpbuf) - n, "(%%b%c,%%%ci)",
+			   "xp"[(modrm >> 1) & 1], "sd"[modrm & 1]);
+	  else
+	    n += snprintf (tmpbuf + n, sizeof (tmpbuf) - n, "(%%%s)",
+			   ((const char [4][3]) { "si", "di", "bp", "bx" })[modrm & 3]);
+	}
+
+      if (*bufcntp + n + 1 > bufsize)
+	return *bufcntp + n + 1 - bufsize;
+
+      memcpy (&bufp[*bufcntp], tmpbuf, n + 1);
+      *bufcntp += n;
+    }
+  else
+#endif
+    {
+      if ((modrm & 7) != 4)
+	{
+	  int32_t disp = 0;
+	  bool nodisp = false;
+
+	  if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80)
+	    /* 32 bit displacement.  */
+	    disp = read_4sbyte_unaligned (&data[1]);
+	  else if ((modrm & 0xc0) == 0x40)
+	    /* 8 bit displacement.  */
+	    disp = *(const int8_t *) &data[1];
+	  else if ((modrm & 0xc0) == 0)
+	    nodisp = true;
+
+	  char tmpbuf[sizeof ("-0x12345678(%rrrr)")];
+	  int n;
+	  if (nodisp)
+	    {
+	      n = snprintf (tmpbuf, sizeof (tmpbuf), "(%%%s)",
+#ifdef X86_64
+			    (prefixes & has_rex_b) ? hiregs[modrm & 7] :
+#endif
+			    aregs[modrm & 7]);
+#ifdef X86_64
+	      if (prefixes & has_addr16)
+		{
+		  if (prefixes & has_rex_b)
+		    tmpbuf[n++] = 'd';
+		  else
+		    tmpbuf[2] = 'e';
+		}
+#endif
+	    }
+	  else if ((modrm & 0xc7) != 5)
+	    {
+	      int p;
+	      n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx32 "(%%%n%s)",
+			    disp < 0 ? "-" : "", disp < 0 ? -disp : disp, &p,
+#ifdef X86_64
+			    (prefixes & has_rex_b) ? hiregs[modrm & 7] :
+#endif
+			    aregs[modrm & 7]);
+#ifdef X86_64
+	      if (prefixes & has_addr16)
+		{
+		  if (prefixes & has_rex_b)
+		    tmpbuf[n++] = 'd';
+		  else
+		    tmpbuf[p] = 'e';
+		}
+#endif
+	    }
+	  else
+	    {
+#ifdef X86_64
+	      n = snprintf (tmpbuf, sizeof (tmpbuf), "%s0x%" PRIx32 "(%%rip)",
+			    disp < 0 ? "-" : "", disp < 0 ? -disp : disp);
+
+	      d->symaddr_use = addr_rel_always;
+	      d->symaddr = disp;
+#else
+	      n = snprintf (tmpbuf, sizeof (tmpbuf), "0x%" PRIx32, disp);
+#endif
+	    }
+
+	  if (*bufcntp + n + 1 > bufsize)
+	    return *bufcntp + n + 1 - bufsize;
+
+	  memcpy (&bufp[*bufcntp], tmpbuf, n + 1);
+	  *bufcntp += n;
+	}
+      else
+	{
+	  /* SIB */
+	  uint_fast8_t sib = data[1];
+	  int32_t disp = 0;
+	  bool nodisp = false;
+
+	  if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80
+	      || ((modrm & 0xc7) == 0x4 && (sib & 0x7) == 0x5))
+	    /* 32 bit displacement.  */
+	    disp = read_4sbyte_unaligned (&data[2]);
+	  else if ((modrm & 0xc0) == 0x40)
+	    /* 8 bit displacement.  */
+	    disp = *(const int8_t *) &data[2];
+	  else
+	    nodisp = true;
+
+	  char tmpbuf[sizeof ("-0x12345678(%rrrr,%rrrr,N)")];
+	  char *cp = tmpbuf;
+	  int n;
+	  if ((modrm & 0xc0) != 0 || (sib & 0x3f) != 0x25
+#ifdef X86_64
+	      || (prefixes & has_rex_x) != 0
+#endif
+	      )
+	    {
+	      if (!nodisp)
+		{
+		  n = snprintf (cp, sizeof (tmpbuf), "%s0x%" PRIx32,
+				disp < 0 ? "-" : "", disp < 0 ? -disp : disp);
+		  cp += n;
+		}
+
+	      *cp++ = '(';
+
+	      if ((modrm & 0xc7) != 0x4 || (sib & 0x7) != 0x5)
+		{
+		  *cp++ = '%';
+		  cp = stpcpy (cp,
+#ifdef X86_64
+			       (prefixes & has_rex_b) ? hiregs[sib & 7] :
+			       (prefixes & has_addr16) ? dregs[sib & 7] :
+#endif
+			       aregs[sib & 7]);
+#ifdef X86_64
+		  if ((prefixes & (has_rex_b | has_addr16))
+		      == (has_rex_b | has_addr16))
+		    *cp++ = 'd';
+#endif
+		}
+
+	      if ((sib & 0x38) != 0x20
+#ifdef X86_64
+		  || (prefixes & has_rex_x) != 0
+#endif
+		  )
+		{
+		  *cp++ = ',';
+		  *cp++ = '%';
+		  cp = stpcpy (cp,
+#ifdef X86_64
+			       (prefixes & has_rex_x)
+			       ? hiregs[(sib >> 3) & 7] :
+			       (prefixes & has_addr16)
+			       ? dregs[(sib >> 3) & 7] :
+#endif
+			       aregs[(sib >> 3) & 7]);
+#ifdef X86_64
+		  if ((prefixes & (has_rex_b | has_addr16))
+		      == (has_rex_b | has_addr16))
+		    *cp++ = 'd';
+#endif
+
+		  *cp++ = ',';
+		  *cp++ = '0' + (1 << (sib >> 6));
+		}
+
+	      *cp++ = ')';
+	    }
+	  else
+	    {
+	      assert (! nodisp);
+#ifdef X86_64
+	      if ((prefixes & has_addr16) == 0)
+		n = snprintf (cp, sizeof (tmpbuf), "0x%" PRIx64,
+			      (int64_t) disp);
+	      else
+#endif
+		n = snprintf (cp, sizeof (tmpbuf), "0x%" PRIx32, disp);
+	      cp += n;
+	    }
+
+	  if (*bufcntp + (cp - tmpbuf) > bufsize)
+	    return *bufcntp + (cp - tmpbuf) - bufsize;
+
+	  memcpy (&bufp[*bufcntp], tmpbuf, cp - tmpbuf);
+	  *bufcntp += cp - tmpbuf;
+	}
+    }
+  return 0;
+}
+
+
+static int
+FCT_MOD$R_M (struct output_data *d)
+{
+  assert (d->opoff1 % 8 == 0);
+  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  if ((modrm & 0xc0) == 0xc0)
+    {
+      assert (d->opoff1 / 8 == d->opoff2 / 8);
+      assert (d->opoff2 % 8 == 5);
+      //uint_fast8_t byte = d->data[d->opoff2 / 8] & 7;
+      uint_fast8_t byte = modrm & 7;
+
+      size_t *bufcntp = d->bufcntp;
+      char *buf = d->bufp + *bufcntp;
+      size_t avail = d->bufsize - *bufcntp;
+      int needed;
+      if (*d->prefixes & (has_rep | has_repne))
+	needed = snprintf (buf, avail, "%%%s", dregs[byte]);
+      else
+	needed = snprintf (buf, avail, "%%mm%" PRIxFAST8, byte);
+      if ((size_t) needed > avail)
+	return needed - avail;
+      *bufcntp += needed;
+      return 0;
+    }
+
+  return general_mod$r_m (d);
+}
+
+
+static int
+FCT_Mod$R_m (struct output_data *d)
+{
+  assert (d->opoff1 % 8 == 0);
+  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  if ((modrm & 0xc0) == 0xc0)
+    {
+      assert (d->opoff1 / 8 == d->opoff2 / 8);
+      assert (d->opoff2 % 8 == 5);
+      //uint_fast8_t byte = data[opoff2 / 8] & 7;
+      uint_fast8_t byte = modrm & 7;
+
+      size_t *bufcntp = d->bufcntp;
+      size_t avail = d->bufsize - *bufcntp;
+      int needed = snprintf (&d->bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8,
+			     byte);
+      if ((size_t) needed > avail)
+	return needed - avail;
+      *d->bufcntp += needed;
+      return 0;
+    }
+
+  return general_mod$r_m (d);
+}
+
+static int
+generic_abs (struct output_data *d, const char *absstring
+#ifdef X86_64
+	     , int abslen
+#else
+# define abslen 4
+#endif
+	     )
+{
+  int r = data_prefix (d);
+  if (r != 0)
+    return r;
+
+  assert (d->opoff1 % 8 == 0);
+  assert (d->opoff1 / 8 == 1);
+  if (*d->param_start + abslen > d->end)
+    return -1;
+  *d->param_start += abslen;
+#ifndef X86_64
+  uint32_t absval;
+# define ABSPRIFMT PRIx32
+#else
+  uint64_t absval;
+# define ABSPRIFMT PRIx64
+  if (abslen == 8)
+    absval = read_8ubyte_unaligned (&d->data[1]);
+  else
+#endif
+    absval = read_4ubyte_unaligned (&d->data[1]);
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "%s0x%" ABSPRIFMT,
+			 absstring, absval);
+  if ((size_t) needed > avail)
+    return needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+static int
+FCT_absval (struct output_data *d)
+{
+  return generic_abs (d, "$"
+#ifdef X86_64
+		      , 4
+#endif
+		      );
+}
+
+static int
+FCT_abs (struct output_data *d)
+{
+  return generic_abs (d, ""
+#ifdef X86_64
+		      , 8
+#endif
+		      );
+}
+
+static int
+FCT_ax (struct output_data *d)
+{
+  int is_16bit = (*d->prefixes & has_data16) != 0;
+
+  size_t *bufcntp = d->bufcntp;
+  char *bufp = d->bufp;
+  size_t bufsize = d->bufsize;
+
+  if (*bufcntp + 4 - is_16bit > bufsize)
+    return *bufcntp + 4 - is_16bit - bufsize;
+
+  bufp[(*bufcntp)++] = '%';
+  if (! is_16bit)
+    bufp[(*bufcntp)++] = (
+#ifdef X86_64
+			  (*d->prefixes & has_rex_w) ? 'r' :
+#endif
+			  'e');
+  bufp[(*bufcntp)++] = 'a';
+  bufp[(*bufcntp)++] = 'x';
+
+  return 0;
+}
+
+
+static int
+FCT_ax$w (struct output_data *d)
+{
+  if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) != 0)
+    return FCT_ax (d);
+
+  size_t *bufcntp = d->bufcntp;
+  char *bufp = d->bufp;
+  size_t bufsize = d->bufsize;
+
+  if (*bufcntp + 3 > bufsize)
+    return *bufcntp + 3 - bufsize;
+
+  bufp[(*bufcntp)++] = '%';
+  bufp[(*bufcntp)++] = 'a';
+  bufp[(*bufcntp)++] = 'l';
+
+  return 0;
+}
+
+
+static int
+__attribute__ ((noinline))
+FCT_crdb (struct output_data *d, const char *regstr)
+{
+  if (*d->prefixes & has_data16)
+    return -1;
+
+  size_t *bufcntp = d->bufcntp;
+
+  // XXX If this assert is true, use absolute offset below
+  assert (d->opoff1 / 8 == 2);
+  assert (d->opoff1 % 8 == 2);
+  size_t avail = d->bufsize - *bufcntp;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "%%%s%" PRIx32,
+			 regstr, (uint32_t) (d->data[d->opoff1 / 8] >> 3) & 7);
+  if ((size_t) needed > avail)
+    return needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+static int
+FCT_ccc (struct output_data *d)
+{
+  return FCT_crdb (d, "cr");
+}
+
+
+static int
+FCT_ddd (struct output_data *d)
+{
+  return FCT_crdb (d, "db");
+}
+
+
+static int
+FCT_disp8 (struct output_data *d)
+{
+  assert (d->opoff1 % 8 == 0);
+  if (*d->param_start >= d->end)
+    return -1;
+  int32_t offset = *(const int8_t *) (*d->param_start)++;
+
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx32,
+			 (uint32_t) (d->addr + (*d->param_start - d->data)
+				     + offset));
+  if ((size_t) needed > avail)
+    return needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+static int
+__attribute__ ((noinline))
+FCT_ds_xx (struct output_data *d, const char *reg)
+{
+  int prefix = *d->prefixes & SEGMENT_PREFIXES;
+
+  if (prefix == 0)
+    *d->prefixes |= prefix = has_ds;
+  /* Make sure only one bit is set.  */
+  else if ((prefix - 1) & prefix)
+    return -1;
+
+  int r = data_prefix (d);
+
+  assert ((*d->prefixes & prefix) == 0);
+
+  if (r != 0)
+    return r;
+
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "(%%%s%s)",
+#ifdef X86_64
+			 *d->prefixes & idx_addr16 ? "e" : "r",
+#else
+			 *d->prefixes & idx_addr16 ? "" : "e",
+#endif
+			 reg);
+  if ((size_t) needed > avail)
+    return (size_t) needed - avail;
+  *bufcntp += needed;
+
+  return 0;
+}
+
+
+static int
+FCT_ds_bx (struct output_data *d)
+{
+  return FCT_ds_xx (d, "bx");
+}
+
+
+static int
+FCT_ds_si (struct output_data *d)
+{
+  return FCT_ds_xx (d, "si");
+}
+
+
+static int
+FCT_dx (struct output_data *d)
+{
+  size_t *bufcntp = d->bufcntp;
+
+  if (*bufcntp + 7 > d->bufsize)
+    return *bufcntp + 7 - d->bufsize;
+
+  memcpy (&d->bufp[*bufcntp], "(%dx)", 5);
+  *bufcntp += 5;
+
+  return 0;
+}
+
+
+static int
+FCT_es_di (struct output_data *d)
+{
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "%%es:(%%%sdi)",
+#ifdef X86_64
+			 *d->prefixes & idx_addr16 ? "e" : "r"
+#else
+			 *d->prefixes & idx_addr16 ? "" : "e"
+#endif
+			 );
+  if ((size_t) needed > avail)
+    return (size_t) needed - avail;
+  *bufcntp += needed;
+
+  return 0;
+}
+
+
+static int
+FCT_imm (struct output_data *d)
+{
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  int needed;
+  if (*d->prefixes & has_data16)
+    {
+      if (*d->param_start + 2 > d->end)
+	return -1;
+      uint16_t word = read_2ubyte_unaligned_inc (*d->param_start);
+      needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word);
+    }
+  else
+    {
+      if (*d->param_start + 4 > d->end)
+	return -1;
+      int32_t word = read_4sbyte_unaligned_inc (*d->param_start);
+#ifdef X86_64
+      if (*d->prefixes & has_rex_w)
+	needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
+			   (int64_t) word);
+      else
+#endif
+	needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word);
+    }
+  if ((size_t) needed > avail)
+    return (size_t) needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+static int
+FCT_imm$w (struct output_data *d)
+{
+  if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) != 0)
+    return FCT_imm (d);
+
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  if (*d->param_start>= d->end)
+    return -1;
+  uint_fast8_t word = *(*d->param_start)++;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIxFAST8, word);
+  if ((size_t) needed > avail)
+    return (size_t) needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+#ifdef X86_64
+static int
+FCT_imm64$w (struct output_data *d)
+{
+  if ((d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7)))) == 0
+      || (*d->prefixes & has_data16) != 0)
+    return FCT_imm$w (d);
+
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  int needed;
+  if (*d->prefixes & has_rex_w)
+    {
+      if (*d->param_start + 8 > d->end)
+	return -1;
+      uint64_t word = read_8ubyte_unaligned_inc (*d->param_start);
+      needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64, word);
+    }
+  else
+    {
+      if (*d->param_start + 4 > d->end)
+	return -1;
+      int32_t word = read_4sbyte_unaligned_inc (*d->param_start);
+      needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word);
+    }
+  if ((size_t) needed > avail)
+    return (size_t) needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+#endif
+
+
+static int
+FCT_imms (struct output_data *d)
+{
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  if (*d->param_start>= d->end)
+    return -1;
+  int8_t byte = *(*d->param_start)++;
+#ifdef X86_64
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
+			 (int64_t) byte);
+#else
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32,
+			 (int32_t) byte);
+#endif
+  if ((size_t) needed > avail)
+    return (size_t) needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+static int
+FCT_imm$s (struct output_data *d)
+{
+  uint_fast8_t opcode = d->data[d->opoff2 / 8];
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  if ((opcode & 2) != 0)
+    return FCT_imms (d);
+
+  if ((*d->prefixes & has_data16) == 0)
+    {
+      if (*d->param_start + 4 > d->end)
+	return -1;
+      int32_t word = read_4sbyte_unaligned_inc (*d->param_start);
+#ifdef X86_64
+      int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
+			     (int64_t) word);
+#else
+      int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32, word);
+#endif
+      if ((size_t) needed > avail)
+	return (size_t) needed - avail;
+      *bufcntp += needed;
+    }
+  else
+    {
+      if (*d->param_start + 2 > d->end)
+	return -1;
+      uint16_t word = read_2ubyte_unaligned_inc (*d->param_start);
+      int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word);
+      if ((size_t) needed > avail)
+	return (size_t) needed - avail;
+      *bufcntp += needed;
+    }
+  return 0;
+}
+
+
+static int
+FCT_imm16 (struct output_data *d)
+{
+  if (*d->param_start + 2 > d->end)
+    return -1;
+  uint16_t word = read_2ubyte_unaligned_inc (*d->param_start);
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, word);
+  if ((size_t) needed > avail)
+    return (size_t) needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+static int
+FCT_imms8 (struct output_data *d)
+{
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  if (*d->param_start >= d->end)
+    return -1;
+  int_fast8_t byte = *(*d->param_start)++;
+  int needed;
+#ifdef X86_64
+  if (*d->prefixes & has_rex_w)
+    needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx64,
+		       (int64_t) byte);
+  else
+#endif
+    needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32,
+		       (int32_t) byte);
+  if ((size_t) needed > avail)
+    return (size_t) needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+static int
+FCT_imm8 (struct output_data *d)
+{
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  if (*d->param_start >= d->end)
+    return -1;
+  uint_fast8_t byte = *(*d->param_start)++;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx32,
+			 (uint32_t) byte);
+  if ((size_t) needed > avail)
+    return (size_t) needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+static int
+FCT_rel (struct output_data *d)
+{
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  if (*d->param_start + 4 > d->end)
+    return -1;
+  int32_t rel = read_4sbyte_unaligned_inc (*d->param_start);
+#ifdef X86_64
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx64,
+			 (uint64_t) (d->addr + rel
+				     + (*d->param_start - d->data)));
+#else
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "0x%" PRIx32,
+			 (uint32_t) (d->addr + rel
+				     + (*d->param_start - d->data)));
+#endif
+  if ((size_t) needed > avail)
+    return (size_t) needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+static int
+FCT_mmxreg (struct output_data *d)
+{
+  uint_fast8_t byte = d->data[d->opoff1 / 8];
+  assert (d->opoff1 % 8 == 2 || d->opoff1 % 8 == 5);
+  byte = (byte >> (5 - d->opoff1 % 8)) & 7;
+  size_t *bufcntp =  d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "%%mm%" PRIxFAST8, byte);
+  if ((size_t) needed > avail)
+    return needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+static int
+FCT_mod$r_m (struct output_data *d)
+{
+  assert (d->opoff1 % 8 == 0);
+  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  if ((modrm & 0xc0) == 0xc0)
+    {
+      int prefixes = *d->prefixes;
+      if (prefixes & has_addr16)
+	return -1;
+
+      int is_16bit = (prefixes & has_data16) != 0;
+
+      size_t *bufcntp = d->bufcntp;
+      char *bufp = d->bufp;
+      if (*bufcntp + 5 - is_16bit > d->bufsize)
+	return *bufcntp + 5 - is_16bit - d->bufsize;
+      bufp[(*bufcntp)++] = '%';
+
+      char *cp;
+#ifdef X86_64
+      if ((prefixes & has_rex_b) != 0 && !is_16bit)
+	{
+	  cp = stpcpy (&bufp[*bufcntp], hiregs[modrm & 7]);
+	  if ((prefixes & has_rex_w) == 0)
+	    *cp++ = 'd';
+	}
+      else
+#endif
+	{
+	  cp = stpcpy (&bufp[*bufcntp], dregs[modrm & 7] + is_16bit);
+#ifdef X86_64
+	  if ((prefixes & has_rex_w) != 0)
+	    bufp[*bufcntp] = 'r';
+#endif
+	}
+      *bufcntp = cp - bufp;
+      return 0;
+    }
+
+  return general_mod$r_m (d);
+}
+
+
+#ifndef X86_64
+static int
+FCT_moda$r_m (struct output_data *d)
+{
+  assert (d->opoff1 % 8 == 0);
+  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  if ((modrm & 0xc0) == 0xc0)
+    {
+      if (*d->prefixes & has_addr16)
+	return -1;
+
+      size_t *bufcntp = d->bufcntp;
+      if (*bufcntp + 3 > d->bufsize)
+	return *bufcntp + 3 - d->bufsize;
+
+      memcpy (&d->bufp[*bufcntp], "???", 3);
+      *bufcntp += 3;
+
+      return 0;
+    }
+
+  return general_mod$r_m (d);
+}
+#endif
+
+
+#ifdef X86_64
+static const char rex_8bit[8][3] =
+  {
+    [0] = "a", [1] = "c", [2] = "d", [3] = "b",
+    [4] = "sp", [5] = "bp", [6] = "si", [7] = "di"
+  };
+#endif
+
+
+static int
+FCT_mod$r_m$w (struct output_data *d)
+{
+  assert (d->opoff1 % 8 == 0);
+  const uint8_t *data = d->data;
+  uint_fast8_t modrm = data[d->opoff1 / 8];
+  if ((modrm & 0xc0) == 0xc0)
+    {
+      int prefixes = *d->prefixes;
+
+      if (prefixes & has_addr16)
+	return -1;
+
+      size_t *bufcntp = d->bufcntp;
+      char *bufp = d->bufp;
+      if (*bufcntp + 5 > d->bufsize)
+	return *bufcntp + 5 - d->bufsize;
+
+      if ((data[d->opoff3 / 8] & (1 << (7 - (d->opoff3 & 7)))) == 0)
+	{
+	  bufp[(*bufcntp)++] = '%';
+
+#ifdef X86_64
+	  if (prefixes & has_rex)
+	    {
+	      if (prefixes & has_rex_r)
+		*bufcntp += snprintf (bufp + *bufcntp, d->bufsize - *bufcntp,
+				      "r%db", 8 + (modrm & 7));
+	      else
+		{
+		  char *cp = stpcpy (bufp + *bufcntp, hiregs[modrm & 7]);
+		  *cp++ = 'l';
+		  *bufcntp = cp - bufp;
+		}
+	    }
+	  else
+#endif
+	    {
+	      bufp[(*bufcntp)++] = "acdb"[modrm & 3];
+	      bufp[(*bufcntp)++] = "lh"[(modrm & 4) >> 2];
+	    }
+	}
+      else
+	{
+	  int is_16bit = (prefixes & has_data16) != 0;
+
+	  bufp[(*bufcntp)++] = '%';
+
+	  char *cp;
+#ifdef X86_64
+	  if ((prefixes & has_rex_b) != 0 && !is_16bit)
+	    {
+	      cp = stpcpy (&bufp[*bufcntp], hiregs[modrm & 7]);
+	      if ((prefixes & has_rex_w) == 0)
+		*cp++ = 'd';
+	    }
+	  else
+#endif
+	    {
+	      cp = stpcpy (&bufp[*bufcntp], dregs[modrm & 7] + is_16bit);
+#ifdef X86_64
+	      if ((prefixes & has_rex_w) != 0)
+		bufp[*bufcntp] = 'r';
+#endif
+	    }
+	  *bufcntp = cp - bufp;
+	}
+      return 0;
+    }
+
+  return general_mod$r_m (d);
+}
+
+
+static int
+FCT_mod$8r_m (struct output_data *d)
+{
+  assert (d->opoff1 % 8 == 0);
+  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  if ((modrm & 0xc0) == 0xc0)
+    {
+      size_t *bufcntp = d->bufcntp;
+      char *bufp = d->bufp;
+      if (*bufcntp + 3 > d->bufsize)
+	return *bufcntp + 3 - d->bufsize;
+      bufp[(*bufcntp)++] = '%';
+      bufp[(*bufcntp)++] = "acdb"[modrm & 3];
+      bufp[(*bufcntp)++] = "lh"[(modrm & 4) >> 2];
+      return 0;
+    }
+
+  return general_mod$r_m (d);
+}
+
+
+static int
+FCT_mod$16r_m (struct output_data *d)
+{
+  assert (d->opoff1 % 8 == 0);
+  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  if ((modrm & 0xc0) == 0xc0)
+    {
+      assert (d->opoff1 / 8 == d->opoff2 / 8);
+      //uint_fast8_t byte = data[opoff2 / 8] & 7;
+      uint_fast8_t byte = modrm & 7;
+
+      size_t *bufcntp = d->bufcntp;
+      if (*bufcntp + 3 > d->bufsize)
+	return *bufcntp + 3 - d->bufsize;
+      d->bufp[(*bufcntp)++] = '%';
+      memcpy (&d->bufp[*bufcntp], dregs[byte] + 1, sizeof (dregs[0]) - 1);
+      *bufcntp += 2;
+      return 0;
+    }
+
+  return general_mod$r_m (d);
+}
+
+
+#ifdef X86_64
+static int
+FCT_mod$64r_m (struct output_data *d)
+{
+  assert (d->opoff1 % 8 == 0);
+  uint_fast8_t modrm = d->data[d->opoff1 / 8];
+  if ((modrm & 0xc0) == 0xc0)
+    {
+      assert (d->opoff1 / 8 == d->opoff2 / 8);
+      //uint_fast8_t byte = data[opoff2 / 8] & 7;
+      uint_fast8_t byte = modrm & 7;
+
+      size_t *bufcntp = d->bufcntp;
+      if (*bufcntp + 4 > d->bufsize)
+	return *bufcntp + 4 - d->bufsize;
+      char *cp = &d->bufp[*bufcntp];
+      *cp++ = '%';
+      cp = stpcpy (cp,
+		   (*d->prefixes & has_rex_b) ? hiregs[byte] : aregs[byte]);
+      *bufcntp = cp - d->bufp;
+      return 0;
+    }
+
+  return general_mod$r_m (d);
+}
+#else
+static typeof (FCT_mod$r_m) FCT_mod$64r_m __attribute__ ((alias ("FCT_mod$r_m")));
+#endif
+
+
+static int
+FCT_reg (struct output_data *d)
+{
+  uint_fast8_t byte = d->data[d->opoff1 / 8];
+  assert (d->opoff1 % 8 + 3 <= 8);
+  byte >>= 8 - (d->opoff1 % 8 + 3);
+  byte &= 7;
+  int is_16bit = (*d->prefixes & has_data16) != 0;
+  size_t *bufcntp = d->bufcntp;
+  if (*bufcntp + 5 > d->bufsize)
+    return *bufcntp + 5 - d->bufsize;
+  d->bufp[(*bufcntp)++] = '%';
+#ifdef X86_64
+  if ((*d->prefixes & has_rex_r) != 0 && !is_16bit)
+    {
+      *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d",
+			    8 + byte);
+      if ((*d->prefixes & has_rex_w) == 0)
+	d->bufp[(*bufcntp)++] = 'd';
+    }
+  else
+#endif
+    {
+      memcpy (&d->bufp[*bufcntp], dregs[byte] + is_16bit, 3 - is_16bit);
+#ifdef X86_64
+      if ((*d->prefixes & has_rex_w) != 0 && !is_16bit)
+	d->bufp[*bufcntp] = 'r';
+#endif
+      *bufcntp += 3 - is_16bit;
+    }
+  return 0;
+}
+
+
+#ifdef X86_64
+static int
+FCT_oreg (struct output_data *d)
+{
+  /* Special form where register comes from opcode.  The rex.B bit is used,
+     rex.R and rex.X are ignored.  */
+  int save_prefixes = *d->prefixes;
+
+  *d->prefixes = ((save_prefixes & ~has_rex_r)
+		  | ((save_prefixes & has_rex_b) << (idx_rex_r - idx_rex_b)));
+
+  int r = FCT_reg (d);
+
+  *d->prefixes = save_prefixes;
+
+  return r;
+}
+#endif
+
+
+static int
+FCT_reg64 (struct output_data *d)
+{
+  uint_fast8_t byte = d->data[d->opoff1 / 8];
+  assert (d->opoff1 % 8 + 3 <= 8);
+  byte >>= 8 - (d->opoff1 % 8 + 3);
+  byte &= 7;
+  if ((*d->prefixes & has_data16) != 0)
+    return -1;
+  size_t *bufcntp = d->bufcntp;
+  if (*bufcntp + 5 > d->bufsize)
+    return *bufcntp + 5 - d->bufsize;
+  d->bufp[(*bufcntp)++] = '%';
+#ifdef X86_64
+  if ((*d->prefixes & has_rex_r) != 0)
+    {
+      *bufcntp += snprintf (&d->bufp[*bufcntp], d->bufsize - *bufcntp, "r%d",
+			    8 + byte);
+      if ((*d->prefixes & has_rex_w) == 0)
+	d->bufp[(*bufcntp)++] = 'd';
+    }
+  else
+#endif
+    {
+      memcpy (&d->bufp[*bufcntp], aregs[byte], 3);
+      *bufcntp += 3;
+    }
+  return 0;
+}
+
+
+static int
+FCT_reg$w (struct output_data *d)
+{
+  if (d->data[d->opoff2 / 8] & (1 << (7 - (d->opoff2 & 7))))
+    return FCT_reg (d);
+
+  uint_fast8_t byte = d->data[d->opoff1 / 8];
+  assert (d->opoff1 % 8 + 3 <= 8);
+  byte >>= 8 - (d->opoff1 % 8 + 3);
+  byte &= 7;
+
+  size_t *bufcntp = d->bufcntp;
+  if (*bufcntp + 4 > d->bufsize)
+    return *bufcntp + 4 - d->bufsize;
+
+  d->bufp[(*bufcntp)++] = '%';
+
+#ifdef X86_64
+  if (*d->prefixes & has_rex)
+    {
+      if (*d->prefixes & has_rex_r)
+	*bufcntp += snprintf (d->bufp + *bufcntp, d->bufsize - *bufcntp,
+			      "r%db", 8 + byte);
+      else
+	{
+	  char* cp = stpcpy (d->bufp + *bufcntp, rex_8bit[byte]);
+	  *cp++ = 'l';
+	  *bufcntp = cp - d->bufp;
+	}
+    }
+  else
+#endif
+    {
+      d->bufp[(*bufcntp)++] = "acdb"[byte & 3];
+      d->bufp[(*bufcntp)++] = "lh"[byte >> 2];
+    }
+  return 0;
+}
+
+
+#ifdef X86_64
+static int
+FCT_oreg$w (struct output_data *d)
+{
+  /* Special form where register comes from opcode.  The rex.B bit is used,
+     rex.R and rex.X are ignored.  */
+  int save_prefixes = *d->prefixes;
+
+  *d->prefixes = ((save_prefixes & ~has_rex_r)
+		  | ((save_prefixes & has_rex_b) << (idx_rex_r - idx_rex_b)));
+
+  int r = FCT_reg$w (d);
+
+  *d->prefixes = save_prefixes;
+
+  return r;
+}
+#endif
+
+
+static int
+FCT_freg (struct output_data *d)
+{
+  assert (d->opoff1 / 8 == 1);
+  assert (d->opoff1 % 8 == 5);
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "%%st(%" PRIx32 ")",
+			 (uint32_t) (d->data[1] & 7));
+  if ((size_t) needed > avail)
+    return (size_t) needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+#ifndef X86_64
+static int
+FCT_reg16 (struct output_data *d)
+{
+  if (*d->prefixes & has_data16)
+    return -1;
+
+  *d->prefixes |= has_data16;
+  return FCT_reg (d);
+}
+#endif
+
+
+static int
+FCT_sel (struct output_data *d)
+{
+  assert (d->opoff1 % 8 == 0);
+  assert (d->opoff1 / 8 == 5);
+  if (*d->param_start + 2 > d->end)
+    return -1;
+  *d->param_start += 2;
+  uint16_t absval = read_2ubyte_unaligned (&d->data[5]);
+
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "$0x%" PRIx16, absval);
+  if ((size_t) needed > avail)
+    return needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
+
+
+static int
+FCT_sreg2 (struct output_data *d)
+{
+  uint_fast8_t byte = d->data[d->opoff1 / 8];
+  assert (d->opoff1 % 8 + 3 <= 8);
+  byte >>= 8 - (d->opoff1 % 8 + 2);
+
+  size_t *bufcntp = d->bufcntp;
+  char *bufp = d->bufp;
+  if (*bufcntp + 3 > d->bufsize)
+    return *bufcntp + 3 - d->bufsize;
+
+  bufp[(*bufcntp)++] = '%';
+  bufp[(*bufcntp)++] = "ecsd"[byte & 3];
+  bufp[(*bufcntp)++] = 's';
+
+  return 0;
+}
+
+
+static int
+FCT_sreg3 (struct output_data *d)
+{
+  uint_fast8_t byte = d->data[d->opoff1 / 8];
+  assert (d->opoff1 % 8 + 4 <= 8);
+  byte >>= 8 - (d->opoff1 % 8 + 3);
+
+  if ((byte & 7) >= 6)
+    return -1;
+
+  size_t *bufcntp = d->bufcntp;
+  char *bufp = d->bufp;
+  if (*bufcntp + 3 > d->bufsize)
+    return *bufcntp + 3 - d->bufsize;
+
+  bufp[(*bufcntp)++] = '%';
+  bufp[(*bufcntp)++] = "ecsdfg"[byte & 7];
+  bufp[(*bufcntp)++] = 's';
+
+  return 0;
+}
+
+
+static int
+FCT_string (struct output_data *d __attribute__ ((unused)))
+{
+  return 0;
+}
+
+
+static int
+FCT_xmmreg (struct output_data *d)
+{
+  uint_fast8_t byte = d->data[d->opoff1 / 8];
+  assert (d->opoff1 % 8 == 2 || d->opoff1 % 8 == 5);
+  byte = (byte >> (5 - d->opoff1 % 8)) & 7;
+
+  size_t *bufcntp = d->bufcntp;
+  size_t avail = d->bufsize - *bufcntp;
+  int needed = snprintf (&d->bufp[*bufcntp], avail, "%%xmm%" PRIxFAST8, byte);
+  if ((size_t) needed > avail)
+    return needed - avail;
+  *bufcntp += needed;
+  return 0;
+}
diff --git a/third_party/elfutils/libcpu/i386_disasm.c b/third_party/elfutils/libcpu/i386_disasm.c
new file mode 100644
index 0000000..a7e03f9
--- /dev/null
+++ b/third_party/elfutils/libcpu/i386_disasm.c
@@ -0,0 +1,1149 @@
+/* Disassembler for x86.
+   Copyright (C) 2007, 2008, 2009, 2011 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <config.h>
+#include <ctype.h>
+#include <endian.h>
+#include <errno.h>
+#include <gelf.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../libebl/libeblP.h"
+
+#define MACHINE_ENCODING __LITTLE_ENDIAN
+#include "memory-access.h"
+
+
+#ifndef MNEFILE
+# define MNEFILE "i386.mnemonics"
+#endif
+
+#define MNESTRFIELD(line) MNESTRFIELD1 (line)
+#define MNESTRFIELD1(line) str##line
+static const union mnestr_t
+{
+  struct
+  {
+#define MNE(name) char MNESTRFIELD (__LINE__)[sizeof (#name)];
+#include MNEFILE
+#undef MNE
+  };
+  char str[0];
+} mnestr =
+  {
+    {
+#define MNE(name) #name,
+#include MNEFILE
+#undef MNE
+    }
+  };
+
+/* The index can be stored in the instrtab.  */
+enum
+  {
+#define MNE(name) MNE_##name,
+#include MNEFILE
+#undef MNE
+    MNE_INVALID
+  };
+
+static const unsigned short int mneidx[] =
+  {
+#define MNE(name) \
+  [MNE_##name] = offsetof (union mnestr_t, MNESTRFIELD (__LINE__)),
+#include MNEFILE
+#undef MNE
+  };
+
+
+enum
+  {
+    idx_rex_b = 0,
+    idx_rex_x,
+    idx_rex_r,
+    idx_rex_w,
+    idx_rex,
+    idx_cs,
+    idx_ds,
+    idx_es,
+    idx_fs,
+    idx_gs,
+    idx_ss,
+    idx_data16,
+    idx_addr16,
+    idx_rep,
+    idx_repne,
+    idx_lock
+  };
+
+enum
+  {
+#define prefbit(pref) has_##pref = 1 << idx_##pref
+    prefbit (rex_b),
+    prefbit (rex_x),
+    prefbit (rex_r),
+    prefbit (rex_w),
+    prefbit (rex),
+    prefbit (cs),
+    prefbit (ds),
+    prefbit (es),
+    prefbit (fs),
+    prefbit (gs),
+    prefbit (ss),
+    prefbit (data16),
+    prefbit (addr16),
+    prefbit (rep),
+    prefbit (repne),
+    prefbit (lock)
+#undef prefbit
+  };
+#define SEGMENT_PREFIXES \
+  (has_cs | has_ds | has_es | has_fs | has_gs | has_ss)
+
+#define prefix_cs	0x2e
+#define prefix_ds	0x3e
+#define prefix_es	0x26
+#define prefix_fs	0x64
+#define prefix_gs	0x65
+#define prefix_ss	0x36
+#define prefix_data16	0x66
+#define prefix_addr16	0x67
+#define prefix_rep	0xf3
+#define prefix_repne	0xf2
+#define prefix_lock	0xf0
+
+
+static const uint8_t known_prefixes[] =
+  {
+#define newpref(pref) [idx_##pref] = prefix_##pref
+    newpref (cs),
+    newpref (ds),
+    newpref (es),
+    newpref (fs),
+    newpref (gs),
+    newpref (ss),
+    newpref (data16),
+    newpref (addr16),
+    newpref (rep),
+    newpref (repne),
+    newpref (lock)
+#undef newpref
+  };
+#define nknown_prefixes (sizeof (known_prefixes) / sizeof (known_prefixes[0]))
+
+
+#if 0
+static const char *prefix_str[] =
+  {
+#define newpref(pref) [idx_##pref] = #pref
+    newpref (cs),
+    newpref (ds),
+    newpref (es),
+    newpref (fs),
+    newpref (gs),
+    newpref (ss),
+    newpref (data16),
+    newpref (addr16),
+    newpref (rep),
+    newpref (repne),
+    newpref (lock)
+#undef newpref
+  };
+#endif
+
+
+static const char amd3dnowstr[] =
+#define MNE_3DNOW_PAVGUSB 1
+  "pavgusb\0"
+#define MNE_3DNOW_PFADD (MNE_3DNOW_PAVGUSB + 8)
+  "pfadd\0"
+#define MNE_3DNOW_PFSUB (MNE_3DNOW_PFADD + 6)
+  "pfsub\0"
+#define MNE_3DNOW_PFSUBR (MNE_3DNOW_PFSUB + 6)
+  "pfsubr\0"
+#define MNE_3DNOW_PFACC (MNE_3DNOW_PFSUBR + 7)
+  "pfacc\0"
+#define MNE_3DNOW_PFCMPGE (MNE_3DNOW_PFACC + 6)
+  "pfcmpge\0"
+#define MNE_3DNOW_PFCMPGT (MNE_3DNOW_PFCMPGE + 8)
+  "pfcmpgt\0"
+#define MNE_3DNOW_PFCMPEQ (MNE_3DNOW_PFCMPGT + 8)
+  "pfcmpeq\0"
+#define MNE_3DNOW_PFMIN (MNE_3DNOW_PFCMPEQ + 8)
+  "pfmin\0"
+#define MNE_3DNOW_PFMAX (MNE_3DNOW_PFMIN + 6)
+  "pfmax\0"
+#define MNE_3DNOW_PI2FD (MNE_3DNOW_PFMAX + 6)
+  "pi2fd\0"
+#define MNE_3DNOW_PF2ID (MNE_3DNOW_PI2FD + 6)
+  "pf2id\0"
+#define MNE_3DNOW_PFRCP (MNE_3DNOW_PF2ID + 6)
+  "pfrcp\0"
+#define MNE_3DNOW_PFRSQRT (MNE_3DNOW_PFRCP + 6)
+  "pfrsqrt\0"
+#define MNE_3DNOW_PFMUL (MNE_3DNOW_PFRSQRT + 8)
+  "pfmul\0"
+#define MNE_3DNOW_PFRCPIT1 (MNE_3DNOW_PFMUL + 6)
+  "pfrcpit1\0"
+#define MNE_3DNOW_PFRSQIT1 (MNE_3DNOW_PFRCPIT1 + 9)
+  "pfrsqit1\0"
+#define MNE_3DNOW_PFRCPIT2 (MNE_3DNOW_PFRSQIT1 + 9)
+  "pfrcpit2\0"
+#define MNE_3DNOW_PMULHRW (MNE_3DNOW_PFRCPIT2 + 9)
+  "pmulhrw";
+
+#define AMD3DNOW_LOW_IDX 0x0d
+#define AMD3DNOW_HIGH_IDX (sizeof (amd3dnow) + AMD3DNOW_LOW_IDX - 1)
+#define AMD3DNOW_IDX(val) ((val) - AMD3DNOW_LOW_IDX)
+static const unsigned char amd3dnow[] =
+  {
+    [AMD3DNOW_IDX (0xbf)] = MNE_3DNOW_PAVGUSB,
+    [AMD3DNOW_IDX (0x9e)] = MNE_3DNOW_PFADD,
+    [AMD3DNOW_IDX (0x9a)] = MNE_3DNOW_PFSUB,
+    [AMD3DNOW_IDX (0xaa)] = MNE_3DNOW_PFSUBR,
+    [AMD3DNOW_IDX (0xae)] = MNE_3DNOW_PFACC,
+    [AMD3DNOW_IDX (0x90)] = MNE_3DNOW_PFCMPGE,
+    [AMD3DNOW_IDX (0xa0)] = MNE_3DNOW_PFCMPGT,
+    [AMD3DNOW_IDX (0xb0)] = MNE_3DNOW_PFCMPEQ,
+    [AMD3DNOW_IDX (0x94)] = MNE_3DNOW_PFMIN,
+    [AMD3DNOW_IDX (0xa4)] = MNE_3DNOW_PFMAX,
+    [AMD3DNOW_IDX (0x0d)] = MNE_3DNOW_PI2FD,
+    [AMD3DNOW_IDX (0x1d)] = MNE_3DNOW_PF2ID,
+    [AMD3DNOW_IDX (0x96)] = MNE_3DNOW_PFRCP,
+    [AMD3DNOW_IDX (0x97)] = MNE_3DNOW_PFRSQRT,
+    [AMD3DNOW_IDX (0xb4)] = MNE_3DNOW_PFMUL,
+    [AMD3DNOW_IDX (0xa6)] = MNE_3DNOW_PFRCPIT1,
+    [AMD3DNOW_IDX (0xa7)] = MNE_3DNOW_PFRSQIT1,
+    [AMD3DNOW_IDX (0xb6)] = MNE_3DNOW_PFRCPIT2,
+    [AMD3DNOW_IDX (0xb7)] = MNE_3DNOW_PMULHRW
+  };
+
+
+struct output_data
+{
+  GElf_Addr addr;
+  int *prefixes;
+  size_t opoff1;
+  size_t opoff2;
+  size_t opoff3;
+  char *bufp;
+  size_t *bufcntp;
+  size_t bufsize;
+  const uint8_t *data;
+  const uint8_t **param_start;
+  const uint8_t *end;
+  char *labelbuf;
+  size_t labelbufsize;
+  enum
+    {
+      addr_none = 0,
+      addr_abs_symbolic,
+      addr_abs_always,
+      addr_rel_symbolic,
+      addr_rel_always
+    } symaddr_use;
+  GElf_Addr symaddr;
+};
+
+
+#ifndef DISFILE
+# define DISFILE "i386_dis.h"
+#endif
+#include DISFILE
+
+
+#define ADD_CHAR(ch) \
+  do {									      \
+    if (unlikely (bufcnt == bufsize))					      \
+      goto enomem;							      \
+    buf[bufcnt++] = (ch);						      \
+  } while (0)
+
+#define ADD_STRING(str) \
+  do {									      \
+    const char *_str0 = (str);						      \
+    size_t _len0 = strlen (_str0);					      \
+    ADD_NSTRING (_str0, _len0);						      \
+  } while (0)
+
+#define ADD_NSTRING(str, len) \
+  do {									      \
+    const char *_str = (str);						      \
+    size_t _len = (len);						      \
+    if (unlikely (bufcnt + _len > bufsize))				      \
+      goto enomem;							      \
+    memcpy (buf + bufcnt, _str, _len);					      \
+    bufcnt += _len;							      \
+  } while (0)
+
+
+int
+i386_disasm (Ebl *ebl __attribute__((unused)),
+	     const uint8_t **startp, const uint8_t *end, GElf_Addr addr,
+	     const char *fmt, DisasmOutputCB_t outcb, DisasmGetSymCB_t symcb,
+	     void *outcbarg, void *symcbarg)
+{
+  const char *save_fmt = fmt;
+
+#define BUFSIZE 512
+  char initbuf[BUFSIZE];
+  int prefixes;
+  size_t bufcnt;
+  size_t bufsize = BUFSIZE;
+  char *buf = initbuf;
+  const uint8_t *param_start;
+
+  struct output_data output_data =
+    {
+      .prefixes = &prefixes,
+      .bufp = buf,
+      .bufsize = bufsize,
+      .bufcntp = &bufcnt,
+      .param_start = &param_start,
+      .end = end
+    };
+
+  int retval = 0;
+  while (1)
+    {
+      prefixes = 0;
+
+      const uint8_t *data = *startp;
+      const uint8_t *begin = data;
+
+      /* Recognize all prefixes.  */
+      int last_prefix_bit = 0;
+      while (data < end)
+	{
+	  unsigned int i;
+	  for (i = idx_cs; i < nknown_prefixes; ++i)
+	    if (known_prefixes[i] == *data)
+	      break;
+	  if (i == nknown_prefixes)
+	    break;
+
+	  prefixes |= last_prefix_bit = 1 << i;
+
+	  ++data;
+	}
+
+#ifdef X86_64
+      if (data < end && (*data & 0xf0) == 0x40)
+	prefixes |= ((*data++) & 0xf) | has_rex;
+#endif
+
+      bufcnt = 0;
+      size_t cnt = 0;
+
+      const uint8_t *curr = match_data;
+      const uint8_t *const match_end = match_data + sizeof (match_data);
+
+      assert (data <= end);
+      if (data == end)
+	{
+	  if (prefixes != 0)
+	    goto print_prefix;
+
+	  retval = -1;
+	  goto do_ret;
+	}
+
+    next_match:
+      while (curr < match_end)
+	{
+	  uint_fast8_t len = *curr++;
+	  uint_fast8_t clen = len >> 4;
+	  len &= 0xf;
+	  const uint8_t *next_curr = curr + clen + (len - clen) * 2;
+
+	  assert (len > 0);
+	  assert (curr + clen + 2 * (len - clen) <= match_end);
+
+	  const uint8_t *codep = data;
+	  int correct_prefix = 0;
+	  int opoff = 0;
+
+	  if (data > begin && codep[-1] == *curr && clen > 0)
+	    {
+	      /* We match a prefix byte.  This is exactly one byte and
+		 is matched exactly, without a mask.  */
+	      --len;
+	      --clen;
+	      opoff = 8;
+
+	      ++curr;
+
+	      assert (last_prefix_bit != 0);
+	      correct_prefix = last_prefix_bit;
+	    }
+
+	  size_t avail = len;
+	  while (clen > 0)
+	    {
+	      if (*codep++ != *curr++)
+		goto not;
+	      --avail;
+	      --clen;
+	      if (codep == end && avail > 0)
+		goto do_ret;
+	    }
+
+	  while (avail > 0)
+	    {
+	      uint_fast8_t masked = *codep++ & *curr++;
+	      if (masked != *curr++)
+		{
+		not:
+		  curr = next_curr;
+		  ++cnt;
+		  bufcnt = 0;
+		  goto next_match;
+		}
+
+	      --avail;
+	      if (codep == end && avail > 0)
+		goto do_ret;
+	    }
+
+	  if (len > end - data)
+	    /* There is not enough data for the entire instruction.  The
+	       caller can figure this out by looking at the pointer into
+	       the input data.  */
+	    goto do_ret;
+
+	  assert (correct_prefix == 0
+		  || (prefixes & correct_prefix) != 0);
+	  prefixes ^= correct_prefix;
+
+	  if (0)
+	    {
+	      /* Resize the buffer.  */
+	      char *oldbuf;
+	    enomem:
+	      oldbuf = buf;
+	      if (buf == initbuf)
+		buf = malloc (2 * bufsize);
+	      else
+		buf = realloc (buf, 2 * bufsize);
+	      if (buf == NULL)
+		{
+		  buf = oldbuf;
+		  retval = ENOMEM;
+		  goto do_ret;
+		}
+	      bufsize *= 2;
+
+	      output_data.bufp = buf;
+	      output_data.bufsize = bufsize;
+	      bufcnt = 0;
+
+	      if (data == end)
+		{
+		  assert (prefixes != 0);
+		  goto print_prefix;
+		}
+
+	      /* gcc is not clever enough to see the following variables
+		 are not used uninitialized.  */
+	      asm (""
+		   : "=mr" (opoff), "=mr" (correct_prefix), "=mr" (codep),
+		     "=mr" (next_curr), "=mr" (len));
+	    }
+
+	  size_t prefix_size = 0;
+
+	  // XXXonly print as prefix if valid?
+	  if ((prefixes & has_lock) != 0)
+	    {
+	      ADD_STRING ("lock ");
+	      prefix_size += 5;
+	    }
+
+	  if (instrtab[cnt].rep)
+	    {
+	      if ((prefixes & has_rep) !=  0)
+		{
+		  ADD_STRING ("rep ");
+		  prefix_size += 4;
+		}
+	    }
+	  else if (instrtab[cnt].repe
+		   && (prefixes & (has_rep | has_repne)) != 0)
+	    {
+	      if ((prefixes & has_repne) != 0)
+		{
+		  ADD_STRING ("repne ");
+		  prefix_size += 6;
+		}
+	      else if ((prefixes & has_rep) != 0)
+		{
+		  ADD_STRING ("repe ");
+		  prefix_size += 5;
+		}
+	    }
+	  else if ((prefixes & (has_rep | has_repne)) != 0)
+	    {
+	      uint_fast8_t byte;
+	    print_prefix:
+	      bufcnt = 0;
+	      byte = *begin;
+	      /* This is a prefix byte.  Print it.  */
+	      switch (byte)
+		{
+		case prefix_rep:
+		  ADD_STRING ("rep");
+		  break;
+		case prefix_repne:
+		  ADD_STRING ("repne");
+		  break;
+		case prefix_cs:
+		  ADD_STRING ("cs");
+		  break;
+		case prefix_ds:
+		  ADD_STRING ("ds");
+		  break;
+		case prefix_es:
+		  ADD_STRING ("es");
+		  break;
+		case prefix_fs:
+		  ADD_STRING ("fs");
+		  break;
+		case prefix_gs:
+		  ADD_STRING ("gs");
+		  break;
+		case prefix_ss:
+		  ADD_STRING ("ss");
+		  break;
+		case prefix_data16:
+		  ADD_STRING ("data16");
+		  break;
+		case prefix_addr16:
+		  ADD_STRING ("addr16");
+		  break;
+		case prefix_lock:
+		  ADD_STRING ("lock");
+		  break;
+#ifdef X86_64
+		case 0x40 ... 0x4f:
+		  ADD_STRING ("rex");
+		  if (byte != 0x40)
+		    {
+		      ADD_CHAR ('.');
+		      if (byte & 0x8)
+			ADD_CHAR ('w');
+		      if (byte & 0x4)
+			ADD_CHAR ('r');
+		      if (byte & 0x3)
+			ADD_CHAR ('x');
+		      if (byte & 0x1)
+			ADD_CHAR ('b');
+		    }
+		  break;
+#endif
+		default:
+		  /* Cannot happen.  */
+		  puts ("unknown prefix");
+		  abort ();
+		}
+	      data = begin + 1;
+	      ++addr;
+
+	      goto out;
+	    }
+
+	  /* We have a match.  First determine how many bytes are
+	     needed for the adressing mode.  */
+	  param_start = codep;
+	  if (instrtab[cnt].modrm)
+	    {
+	      uint_fast8_t modrm = codep[-1];
+
+#ifndef X86_64
+	      if (likely ((prefixes & has_addr16) != 0))
+		{
+		  /* Account for displacement.  */
+		  if ((modrm & 0xc7) == 6 || (modrm & 0xc0) == 0x80)
+		    param_start += 2;
+		  else if ((modrm & 0xc0) == 0x40)
+		    param_start += 1;
+		}
+	      else
+#endif
+		{
+		  /* Account for SIB.  */
+		  if ((modrm & 0xc0) != 0xc0 && (modrm & 0x7) == 0x4)
+		    param_start += 1;
+
+		  /* Account for displacement.  */
+		  if ((modrm & 0xc7) == 5 || (modrm & 0xc0) == 0x80
+		      || ((modrm & 0xc7) == 0x4 && (codep[0] & 0x7) == 0x5))
+		    param_start += 4;
+		  else if ((modrm & 0xc0) == 0x40)
+		    param_start += 1;
+		}
+
+	      if (unlikely (param_start > end))
+		goto not;
+	    }
+
+	  output_data.addr = addr + (data - begin);
+	  output_data.data = data;
+
+	  unsigned long string_end_idx = 0;
+	  fmt = save_fmt;
+	  const char *deferred_start = NULL;
+	  size_t deferred_len = 0;
+	  // XXX Can we get this from color.c?
+	  static const char color_off[] = "\e[0m";
+	  while (*fmt != '\0')
+	    {
+	      if (*fmt != '%')
+		{
+		  char ch = *fmt++;
+		  if (ch == '\\')
+		    {
+		      switch ((ch = *fmt++))
+			{
+			case '0' ... '7':
+			  {
+			    int val = ch - '0';
+			    ch = *fmt;
+			    if (ch >= '0' && ch <= '7')
+			      {
+				val *= 8;
+				val += ch - '0';
+				ch = *++fmt;
+				if (ch >= '0' && ch <= '7' && val < 32)
+				  {
+				    val *= 8;
+				    val += ch - '0';
+				    ++fmt;
+				  }
+			      }
+			    ch = val;
+			  }
+			  break;
+
+			case 'n':
+			  ch = '\n';
+			  break;
+
+			case 't':
+			  ch = '\t';
+			  break;
+
+			default:
+			  retval = EINVAL;
+			  goto do_ret;
+			}
+		    }
+		  else if (ch == '\e' && *fmt == '[')
+		    {
+		      deferred_start = fmt - 1;
+		      do
+			++fmt;
+		      while (*fmt != 'm' && *fmt != '\0');
+
+		      if (*fmt == 'm')
+			{
+			  deferred_len = ++fmt - deferred_start;
+			  continue;
+			}
+
+		      fmt = deferred_start + 1;
+		      deferred_start = NULL;
+		    }
+		  ADD_CHAR (ch);
+		  continue;
+		}
+	      ++fmt;
+
+	      int width = 0;
+	      while (isdigit (*fmt))
+		width = width * 10 + (*fmt++ - '0');
+
+	      int prec = 0;
+	      if (*fmt == '.')
+		while (isdigit (*++fmt))
+		  prec = prec * 10 + (*fmt - '0');
+
+	      size_t start_idx = bufcnt;
+	      size_t non_printing = 0;
+	      switch (*fmt++)
+		{
+		  char mnebuf[16];
+		  const char *str;
+
+		case 'm':
+		  /* Mnemonic.  */
+
+		  if (unlikely (instrtab[cnt].mnemonic == MNE_INVALID))
+		    {
+		      switch (*data)
+			{
+#ifdef X86_64
+			case 0x90:
+			  if (prefixes & has_rex_b)
+			    goto not;
+			  str = "nop";
+			  break;
+#endif
+
+			case 0x98:
+#ifdef X86_64
+			  if (prefixes == (has_rex_w | has_rex))
+			    {
+			      str = "cltq";
+			      break;
+			    }
+#endif
+			  if (prefixes & ~has_data16)
+			    goto print_prefix;
+			  str = prefixes & has_data16 ? "cbtw" : "cwtl";
+			  break;
+
+			case 0x99:
+#ifdef X86_64
+			  if (prefixes == (has_rex_w | has_rex))
+			    {
+			      str = "cqto";
+			      break;
+			    }
+#endif
+			  if (prefixes & ~has_data16)
+			    goto print_prefix;
+			  str = prefixes & has_data16 ? "cwtd" : "cltd";
+			  break;
+
+			case 0xe3:
+			  if (prefixes & ~has_addr16)
+			    goto print_prefix;
+#ifdef X86_64
+			  str = prefixes & has_addr16 ? "jecxz" : "jrcxz";
+#else
+			  str = prefixes & has_addr16 ? "jcxz" : "jecxz";
+#endif
+			  break;
+
+			case 0x0f:
+			  if (data[1] == 0x0f)
+			    {
+			      /* AMD 3DNOW.  We need one more byte.  */
+			      if (param_start >= end)
+				goto not;
+			      if (*param_start < AMD3DNOW_LOW_IDX
+				  || *param_start > AMD3DNOW_HIGH_IDX)
+				goto not;
+			      unsigned int idx
+				= amd3dnow[AMD3DNOW_IDX (*param_start)];
+			      if (idx == 0)
+				goto not;
+			      str = amd3dnowstr + idx - 1;
+			      /* Eat the immediate byte indicating the
+				 operation.  */
+			      ++param_start;
+			      break;
+			    }
+#ifdef X86_64
+			  if (data[1] == 0xc7)
+			    {
+			      str = ((prefixes & has_rex_w)
+				     ? "cmpxchg16b" : "cmpxchg8b");
+			      break;
+			    }
+#endif
+			  if (data[1] == 0xc2)
+			    {
+			      if (param_start >= end)
+				goto not;
+			      if (*param_start > 7)
+				goto not;
+			      static const char cmpops[][9] =
+				{
+				  [0] = "cmpeq",
+				  [1] = "cmplt",
+				  [2] = "cmple",
+				  [3] = "cmpunord",
+				  [4] = "cmpneq",
+				  [5] = "cmpnlt",
+				  [6] = "cmpnle",
+				  [7] = "cmpord"
+				};
+			      char *cp = stpcpy (mnebuf, cmpops[*param_start]);
+			      if (correct_prefix & (has_rep | has_repne))
+				*cp++ = 's';
+			      else
+				*cp++ = 'p';
+			      if (correct_prefix & (has_data16 | has_repne))
+				*cp++ = 'd';
+			      else
+				*cp++ = 's';
+			      *cp = '\0';
+			      str = mnebuf;
+			      /* Eat the immediate byte indicating the
+				 operation.  */
+			      ++param_start;
+			      break;
+			    }
+			  FALLTHROUGH;
+			default:
+			  assert (! "INVALID not handled");
+			}
+		    }
+		  else
+		    str = mnestr.str + mneidx[instrtab[cnt].mnemonic];
+
+		  if (deferred_start != NULL)
+		    {
+		      ADD_NSTRING (deferred_start, deferred_len);
+		      non_printing += deferred_len;
+		    }
+
+		  ADD_STRING (str);
+
+		  switch (instrtab[cnt].suffix)
+		    {
+		    case suffix_none:
+		      break;
+
+		    case suffix_w:
+		      if ((codep[-1] & 0xc0) != 0xc0)
+			{
+			  char ch;
+
+			  if (data[0] & 1)
+			    {
+			      if (prefixes & has_data16)
+				ch = 'w';
+#ifdef X86_64
+			      else if (prefixes & has_rex_w)
+				ch = 'q';
+#endif
+			      else
+				ch = 'l';
+			    }
+			  else
+			    ch = 'b';
+
+			  ADD_CHAR (ch);
+			}
+		      break;
+
+		    case suffix_w0:
+		      if ((codep[-1] & 0xc0) != 0xc0)
+			ADD_CHAR ('l');
+		      break;
+
+		    case suffix_w1:
+		      if ((data[0] & 0x4) == 0)
+			ADD_CHAR ('l');
+		      break;
+
+		    case suffix_W:
+		      if (prefixes & has_data16)
+			{
+			  ADD_CHAR ('w');
+			  prefixes &= ~has_data16;
+			}
+#ifdef X86_64
+		      else
+			ADD_CHAR ('q');
+#endif
+		      break;
+
+		    case suffix_W1:
+		      if (prefixes & has_data16)
+			{
+			  ADD_CHAR ('w');
+			  prefixes &= ~has_data16;
+			}
+#ifdef X86_64
+		      else if (prefixes & has_rex_w)
+			ADD_CHAR ('q');
+#endif
+		      break;
+
+		    case suffix_tttn:;
+		      static const char tttn[16][3] =
+			{
+			  "o", "no", "b", "ae", "e", "ne", "be", "a",
+			  "s", "ns", "p", "np", "l", "ge", "le", "g"
+			};
+		      ADD_STRING (tttn[codep[-1 - instrtab[cnt].modrm] & 0x0f]);
+		      break;
+
+		    case suffix_D:
+		      if ((codep[-1] & 0xc0) != 0xc0)
+			ADD_CHAR ((data[0] & 0x04) == 0 ? 's' : 'l');
+		      break;
+
+		    default:
+		      printf("unknown suffix %d\n", instrtab[cnt].suffix);
+		      abort ();
+		    }
+
+		  if (deferred_start != NULL)
+		    {
+		      ADD_STRING (color_off);
+		      non_printing += strlen (color_off);
+		    }
+
+		  string_end_idx = bufcnt;
+		  break;
+
+		case 'o':
+		  if (prec == 1 && instrtab[cnt].fct1 != 0)
+		    {
+		      /* First parameter.  */
+		      if (deferred_start != NULL)
+			{
+			  ADD_NSTRING (deferred_start, deferred_len);
+			  non_printing += deferred_len;
+			}
+
+		      if (instrtab[cnt].str1 != 0)
+			ADD_STRING (op1_str
+				    + op1_str_idx[instrtab[cnt].str1 - 1]);
+
+		      output_data.opoff1 = (instrtab[cnt].off1_1
+					    + OFF1_1_BIAS - opoff);
+		      output_data.opoff2 = (instrtab[cnt].off1_2
+					    + OFF1_2_BIAS - opoff);
+		      output_data.opoff3 = (instrtab[cnt].off1_3
+					    + OFF1_3_BIAS - opoff);
+		      int r = op1_fct[instrtab[cnt].fct1] (&output_data);
+		      if (r < 0)
+			goto not;
+		      if (r > 0)
+			goto enomem;
+
+		      if (deferred_start != NULL)
+			{
+			  ADD_STRING (color_off);
+			  non_printing += strlen (color_off);
+			}
+
+		      string_end_idx = bufcnt;
+		    }
+		  else if (prec == 2 && instrtab[cnt].fct2 != 0)
+		    {
+		      /* Second parameter.  */
+		      if (deferred_start != NULL)
+			{
+			  ADD_NSTRING (deferred_start, deferred_len);
+			  non_printing += deferred_len;
+			}
+
+		      if (instrtab[cnt].str2 != 0)
+			ADD_STRING (op2_str
+				    + op2_str_idx[instrtab[cnt].str2 - 1]);
+
+		      output_data.opoff1 = (instrtab[cnt].off2_1
+					    + OFF2_1_BIAS - opoff);
+		      output_data.opoff2 = (instrtab[cnt].off2_2
+					    + OFF2_2_BIAS - opoff);
+		      output_data.opoff3 = (instrtab[cnt].off2_3
+					    + OFF2_3_BIAS - opoff);
+		      int r = op2_fct[instrtab[cnt].fct2] (&output_data);
+		      if (r < 0)
+			goto not;
+		      if (r > 0)
+			goto enomem;
+
+		      if (deferred_start != NULL)
+			{
+			  ADD_STRING (color_off);
+			  non_printing += strlen (color_off);
+			}
+
+		      string_end_idx = bufcnt;
+		    }
+		  else if (prec == 3 && instrtab[cnt].fct3 != 0)
+		    {
+		      /* Third parameter.  */
+		      if (deferred_start != NULL)
+			{
+			  ADD_NSTRING (deferred_start, deferred_len);
+			  non_printing += deferred_len;
+			}
+
+		      if (instrtab[cnt].str3 != 0)
+			ADD_STRING (op3_str
+				    + op3_str_idx[instrtab[cnt].str3 - 1]);
+
+		      output_data.opoff1 = (instrtab[cnt].off3_1
+					    + OFF3_1_BIAS - opoff);
+		      output_data.opoff2 = (instrtab[cnt].off3_2
+					    + OFF3_2_BIAS - opoff);
+#ifdef OFF3_3_BITS
+		      output_data.opoff3 = (instrtab[cnt].off3_3
+					    + OFF3_3_BIAS - opoff);
+#else
+		      output_data.opoff3 = 0;
+#endif
+		      int r = op3_fct[instrtab[cnt].fct3] (&output_data);
+		      if (r < 0)
+			goto not;
+		      if (r > 0)
+			goto enomem;
+
+		      if (deferred_start != NULL)
+			{
+			  ADD_STRING (color_off);
+			  non_printing += strlen (color_off);
+			}
+
+		      string_end_idx = bufcnt;
+		    }
+		  else
+		    bufcnt = string_end_idx;
+		  break;
+
+		case 'e':
+		  string_end_idx = bufcnt;
+		  break;
+
+		case 'a':
+		  /* Pad to requested column.  */
+		  while (bufcnt - non_printing < (size_t) width)
+		    ADD_CHAR (' ');
+		  width = 0;
+		  break;
+
+		case 'l':
+		  if (deferred_start != NULL)
+		    {
+		      ADD_NSTRING (deferred_start, deferred_len);
+		      non_printing += deferred_len;
+		    }
+
+		  if (output_data.labelbuf != NULL
+		      && output_data.labelbuf[0] != '\0')
+		    {
+		      ADD_STRING (output_data.labelbuf);
+		      output_data.labelbuf[0] = '\0';
+		      string_end_idx = bufcnt;
+		    }
+		  else if (output_data.symaddr_use != addr_none)
+		    {
+		      GElf_Addr symaddr = output_data.symaddr;
+		      if (output_data.symaddr_use >= addr_rel_symbolic)
+			symaddr += addr + param_start - begin;
+
+		      // XXX Lookup symbol based on symaddr
+		      const char *symstr = NULL;
+		      if (symcb != NULL
+			  && symcb (0 /* XXX */, 0 /* XXX */, symaddr,
+				    &output_data.labelbuf,
+				    &output_data.labelbufsize, symcbarg) == 0)
+			symstr = output_data.labelbuf;
+
+		      size_t bufavail = bufsize - bufcnt;
+		      int r = 0;
+		      if (symstr != NULL)
+			r = snprintf (&buf[bufcnt], bufavail, "# <%s>",
+				      symstr);
+		      else if (output_data.symaddr_use == addr_abs_always
+			       || output_data.symaddr_use == addr_rel_always)
+			r = snprintf (&buf[bufcnt], bufavail, "# %#" PRIx64,
+				      (uint64_t) symaddr);
+
+		      assert (r >= 0);
+		      if ((size_t) r >= bufavail)
+			goto enomem;
+		      bufcnt += r;
+		      string_end_idx = bufcnt;
+
+		      output_data.symaddr_use = addr_none;
+		    }
+		  if (deferred_start != NULL)
+		    {
+		      ADD_STRING (color_off);
+		      non_printing += strlen (color_off);
+		    }
+		  break;
+
+		default:
+		  abort ();
+		}
+
+	      deferred_start = NULL;
+
+	      /* Pad according to the specified width.  */
+	      while (bufcnt + prefix_size - non_printing < start_idx + width)
+		ADD_CHAR (' ');
+	      prefix_size = 0;
+	    }
+
+	  if ((prefixes & SEGMENT_PREFIXES) != 0)
+	    goto print_prefix;
+
+	  assert (string_end_idx != ~0ul);
+	  bufcnt = string_end_idx;
+
+	  addr += param_start - begin;
+	  data = param_start;
+
+	  goto out;
+	}
+
+      /* Invalid (or at least unhandled) opcode.  */
+      if (prefixes != 0)
+	goto print_prefix;
+      assert (*startp == data);
+      ++data;
+      ADD_STRING ("(bad)");
+      addr += data - begin;
+
+    out:
+      if (bufcnt == bufsize)
+	goto enomem;
+      buf[bufcnt] = '\0';
+
+      *startp = data;
+      retval = outcb (buf, bufcnt, outcbarg);
+      if (retval != 0)
+	goto do_ret;
+    }
+
+ do_ret:
+  free (output_data.labelbuf);
+  if (buf != initbuf)
+    free (buf);
+
+  return retval;
+}
diff --git a/third_party/elfutils/libcpu/i386_gendis.c b/third_party/elfutils/libcpu/i386_gendis.c
new file mode 100644
index 0000000..aae5eae
--- /dev/null
+++ b/third_party/elfutils/libcpu/i386_gendis.c
@@ -0,0 +1,72 @@
+/* Generate tables for x86 disassembler.
+   Copyright (C) 2007, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <error.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+extern int i386_parse (void);
+
+
+extern FILE *i386_in;
+extern int i386_debug;
+char *infname;
+
+FILE *outfile;
+
+int
+main (int argc, char *argv[argc])
+{
+  outfile = stdout;
+
+  if (argc == 1)
+    error (EXIT_FAILURE, 0, "usage: %s <MNEDEFFILE>", argv[0]);
+
+  //i386_debug = 1;
+  infname = argv[1];
+  if (strcmp (infname, "-") == 0)
+    i386_in = stdin;
+  else
+    {
+      i386_in = fopen (infname, "r");
+      if (i386_in == NULL)
+	error (EXIT_FAILURE, errno, "cannot open %s", argv[1]);
+    }
+
+  i386_parse ();
+
+  return error_message_count != 0;
+}
diff --git a/third_party/elfutils/libcpu/i386_lex.l b/third_party/elfutils/libcpu/i386_lex.l
new file mode 100644
index 0000000..ef1b53b
--- /dev/null
+++ b/third_party/elfutils/libcpu/i386_lex.l
@@ -0,0 +1,129 @@
+%{
+/* Copyright (C) 2004, 2005, 2007, 2008 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ctype.h>
+#include <error.h>
+#include <libintl.h>
+
+#include <libeu.h>
+#include "i386_parse.h"
+
+
+static void eat_to_eol (void);
+static void invalid_char (int ch);
+%}
+
+ID              [a-zA-Z_][a-zA-Z0-9_/]*
+ID2             [a-zA-Z0-9_:/]*
+NUMBER		[0-9]+
+WHITE		[[:space:]]+
+
+%option yylineno
+%option never-interactive
+%option noyywrap
+
+
+%x MAIN
+
+%%
+
+"%mask"				{ return kMASK; }
+
+"%prefix"			{ return kPREFIX; }
+"%suffix"			{ return kSUFFIX; }
+
+"%synonym"			{ return kSYNONYM; }
+
+{NUMBER}			{ i386_lval.num = strtoul (yytext, NULL, 10);
+				  return kNUMBER; }
+
+"%%"				{ BEGIN (MAIN); return kPERCPERC; }
+
+
+<MAIN>"0"			{ return '0'; }
+<MAIN>"1"			{ return '1'; }
+
+<INITIAL,MAIN>"{"{ID2}"}"	{ i386_lval.str = xstrndup (yytext + 1,
+							    yyleng - 2);
+				  return kBITFIELD; }
+
+<MAIN>"INVALID"			{ i386_lval.str = (void *) -1l;
+				  return kID; }
+
+<MAIN>{ID}			{ i386_lval.str = xstrndup (yytext, yyleng);
+				  return kID; }
+
+<MAIN>","			{ return ','; }
+
+<MAIN>":"			{ return ':'; }
+
+<INITIAL,MAIN>^"\n"		{ /* IGNORE */ }
+
+<INITIAL,MAIN>"\n"		{ return '\n'; }
+
+<INITIAL,MAIN>^"#"		{ eat_to_eol (); }
+
+{WHITE}				{ /* IGNORE */ }
+
+<MAIN>{WHITE}			{ return kSPACE; }
+
+<MAIN>.				{ i386_lval.ch = *yytext; return kCHAR; }
+
+.				{ invalid_char (*yytext); }
+
+
+%%
+
+static void
+eat_to_eol (void)
+{
+  while (1)
+    {
+      int c = input ();
+
+      if (c == EOF || c == '\n')
+	break;
+    }
+}
+
+static void
+invalid_char (int ch)
+{
+  error (0, 0, (isascii (ch)
+		? gettext ("invalid character '%c' at line %d; ignored")
+		: gettext ("invalid character '\\%o' at line %d; ignored")),
+	 ch, yylineno);
+}
+
+// Local Variables:
+// mode: C
+// End:
diff --git a/third_party/elfutils/libcpu/i386_parse.y b/third_party/elfutils/libcpu/i386_parse.y
new file mode 100644
index 0000000..5fc0682
--- /dev/null
+++ b/third_party/elfutils/libcpu/i386_parse.y
@@ -0,0 +1,1687 @@
+%{
+/* Parser for i386 CPU description.
+   Copyright (C) 2004, 2005, 2007, 2008, 2009 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <error.h>
+#include <inttypes.h>
+#include <libintl.h>
+#include <math.h>
+#include <obstack.h>
+#include <search.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libeu.h>
+#include <system.h>
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+
+/* The error handler.  */
+static void yyerror (const char *s);
+
+extern int yylex (void);
+extern int i386_lineno;
+extern char *infname;
+
+
+struct known_bitfield
+{
+  char *name;
+  unsigned long int bits;
+  int tmp;
+};
+
+
+struct bitvalue
+{
+  enum bittype { zeroone, field, failure } type;
+  union
+  {
+    unsigned int value;
+    struct known_bitfield *field;
+  };
+  struct bitvalue *next;
+};
+
+
+struct argname
+{
+  enum nametype { string, nfield } type;
+  union
+  {
+    char *str;
+    struct known_bitfield *field;
+  };
+  struct argname *next;
+};
+
+
+struct argument
+{
+  struct argname *name;
+  struct argument *next;
+};
+
+
+struct instruction
+{
+  /* The byte encoding.  */
+  struct bitvalue *bytes;
+
+  /* Prefix possible.  */
+  int repe;
+  int rep;
+
+  /* Mnemonic.  */
+  char *mnemonic;
+
+  /* Suffix.  */
+  enum { suffix_none = 0, suffix_w, suffix_w0, suffix_W, suffix_tttn,
+	 suffix_w1, suffix_W1, suffix_D } suffix;
+
+  /* Flag set if modr/m is used.  */
+  int modrm;
+
+  /* Operands.  */
+  struct operand
+  {
+    char *fct;
+    char *str;
+    int off1;
+    int off2;
+    int off3;
+  } operands[3];
+
+  struct instruction *next;
+};
+
+
+struct synonym
+{
+  char *from;
+  char *to;
+};
+
+
+struct suffix
+{
+  char *name;
+  int idx;
+};
+
+
+struct argstring
+{
+  char *str;
+  int idx;
+  int off;
+};
+
+
+static struct known_bitfield ax_reg =
+  {
+    .name = "ax", .bits = 0, .tmp = 0
+  };
+
+static struct known_bitfield dx_reg =
+  {
+    .name = "dx", .bits = 0, .tmp = 0
+  };
+
+static struct known_bitfield di_reg =
+  {
+    .name = "es_di", .bits = 0, .tmp = 0
+  };
+
+static struct known_bitfield si_reg =
+  {
+    .name = "ds_si", .bits = 0, .tmp = 0
+  };
+
+static struct known_bitfield bx_reg =
+  {
+    .name = "ds_bx", .bits = 0, .tmp = 0
+  };
+
+
+static int bitfield_compare (const void *p1, const void *p2);
+static void new_bitfield (char *name, unsigned long int num);
+static void check_bits (struct bitvalue *value);
+static int check_duplicates (struct bitvalue *val);
+static int check_argsdef (struct bitvalue *bitval, struct argument *args);
+static int check_bitsused (struct bitvalue *bitval,
+			   struct known_bitfield *suffix,
+			   struct argument *args);
+static struct argname *combine (struct argname *name);
+static void fillin_arg (struct bitvalue *bytes, struct argname *name,
+			struct instruction *instr, int n);
+static void find_numbers (void);
+static int compare_syn (const void *p1, const void *p2);
+static int compare_suf (const void *p1, const void *p2);
+static void instrtable_out (void);
+#if 0
+static void create_mnemonic_table (void);
+#endif
+
+static void *bitfields;
+static struct instruction *instructions;
+static size_t ninstructions;
+static void *synonyms;
+static void *suffixes;
+static int nsuffixes;
+static void *mnemonics;
+size_t nmnemonics;
+extern FILE *outfile;
+
+/* Number of bits used mnemonics.  */
+#if 0
+static size_t best_mnemonic_bits;
+#endif
+%}
+
+%union {
+  unsigned long int num;
+  char *str;
+  char ch;
+  struct known_bitfield *field;
+  struct bitvalue *bit;
+  struct argname *name;
+  struct argument *arg;
+}
+
+%token kMASK
+%token kPREFIX
+%token kSUFFIX
+%token kSYNONYM
+%token <str> kID
+%token <num> kNUMBER
+%token kPERCPERC
+%token <str> kBITFIELD
+%token <ch> kCHAR
+%token kSPACE
+
+%type <bit> bit byte bytes
+%type <field> bitfieldopt
+%type <name> argcomp arg
+%type <arg> args optargs
+
+%defines
+
+%%
+
+spec:		  masks kPERCPERC '\n' instrs
+		    {
+		      if (error_message_count != 0)
+			error (EXIT_FAILURE, 0,
+			       "terminated due to previous error");
+
+		      instrtable_out ();
+		    }
+		;
+
+masks:		  masks '\n' mask
+		| mask
+		;
+
+mask:		  kMASK kBITFIELD kNUMBER
+		    { new_bitfield ($2, $3); }
+		| kPREFIX kBITFIELD
+		    { new_bitfield ($2, -1); }
+		| kSUFFIX kBITFIELD
+		    { new_bitfield ($2, -2); }
+		| kSYNONYM kBITFIELD kBITFIELD
+		    {
+		      struct synonym *newp = xmalloc (sizeof (*newp));
+		      newp->from = $2;
+		      newp->to = $3;
+		      if (tfind (newp, &synonyms, compare_syn) != NULL)
+			error (0, 0,
+			       "%d: duplicate definition for synonym '%s'",
+			       i386_lineno, $2);
+		      else if (tsearch ( newp, &synonyms, compare_syn) == NULL)
+			error (EXIT_FAILURE, 0, "tsearch");
+		    }
+		|
+		;
+
+instrs:		  instrs '\n' instr
+		| instr
+		;
+
+instr:		  bytes ':' bitfieldopt kID bitfieldopt optargs
+		    {
+		      if ($3 != NULL && strcmp ($3->name, "RE") != 0
+			  && strcmp ($3->name, "R") != 0)
+			{
+			  error (0, 0, "%d: only 'R' and 'RE' prefix allowed",
+				 i386_lineno - 1);
+			}
+		      if (check_duplicates ($1) == 0
+			  && check_argsdef ($1, $6) == 0
+			  && check_bitsused ($1, $5, $6) == 0)
+			{
+			  struct instruction *newp = xcalloc (sizeof (*newp),
+							      1);
+			  if ($3 != NULL)
+			    {
+			      if (strcmp ($3->name, "RE") == 0)
+				newp->repe = 1;
+			      else if (strcmp ($3->name, "R") == 0)
+				newp->rep = 1;
+			    }
+
+			  newp->bytes = $1;
+			  newp->mnemonic = $4;
+			  if (newp->mnemonic != (void *) -1l
+			      && tfind ($4, &mnemonics,
+					(int (*)(const void *, const void *)) strcmp) == NULL)
+			    {
+			      if (tsearch ($4, &mnemonics,
+					   (int (*)(const void *, const void *)) strcmp) == NULL)
+				error (EXIT_FAILURE, errno, "tsearch");
+			      ++nmnemonics;
+			    }
+
+			  if ($5 != NULL)
+			    {
+			      if (strcmp ($5->name, "w") == 0)
+				newp->suffix = suffix_w;
+			      else if (strcmp ($5->name, "w0") == 0)
+				newp->suffix = suffix_w0;
+			      else if (strcmp ($5->name, "tttn") == 0)
+				newp->suffix = suffix_tttn;
+			      else if (strcmp ($5->name, "w1") == 0)
+				newp->suffix = suffix_w1;
+			      else if (strcmp ($5->name, "W") == 0)
+				newp->suffix = suffix_W;
+			      else if (strcmp ($5->name, "W1") == 0)
+				newp->suffix = suffix_W1;
+			      else if (strcmp ($5->name, "D") == 0)
+				newp->suffix = suffix_D;
+			      else
+				error (EXIT_FAILURE, 0,
+				       "%s: %d: unknown suffix '%s'",
+				       infname, i386_lineno - 1, $5->name);
+
+			      struct suffix search = { .name = $5->name };
+			      if (tfind (&search, &suffixes, compare_suf)
+				  == NULL)
+				{
+				  struct suffix *ns = xmalloc (sizeof (*ns));
+				  ns->name = $5->name;
+				  ns->idx = ++nsuffixes;
+				  if (tsearch (ns, &suffixes, compare_suf)
+				      == NULL)
+				    error (EXIT_FAILURE, errno, "tsearch");
+				}
+			    }
+
+			  struct argument *args = $6;
+			  int n = 0;
+			  while (args != NULL)
+			    {
+			      fillin_arg ($1, args->name, newp, n);
+
+			      args = args->next;
+			      ++n;
+			    }
+
+			  newp->next = instructions;
+			  instructions = newp;
+			  ++ninstructions;
+			}
+		    }
+		|
+		;
+
+bitfieldopt:	  kBITFIELD
+		    {
+		      struct known_bitfield search;
+		      search.name = $1;
+		      struct known_bitfield **res;
+		      res = tfind (&search, &bitfields, bitfield_compare);
+		      if (res == NULL)
+			{
+			  error (0, 0, "%d: unknown bitfield '%s'",
+				 i386_lineno, search.name);
+			  $$ = NULL;
+			}
+		      else
+			$$ = *res;
+		    }
+		|
+		    { $$ = NULL; }
+		;
+
+bytes:		  bytes ',' byte
+		    {
+		      check_bits ($3);
+
+		      struct bitvalue *runp = $1;
+		      while (runp->next != NULL)
+			runp = runp->next;
+		      runp->next = $3;
+		      $$ = $1;
+		    }
+		| byte
+		    {
+		      check_bits ($1);
+		      $$ = $1;
+		    }
+		;
+
+byte:		  byte bit
+		    {
+		      struct bitvalue *runp = $1;
+		      while (runp->next != NULL)
+			runp = runp->next;
+		      runp->next = $2;
+		      $$ = $1;
+		    }
+		| bit
+		    { $$ = $1; }
+		;
+
+bit:		  '0'
+		    {
+		      $$ = xmalloc (sizeof (struct bitvalue));
+		      $$->type = zeroone;
+		      $$->value = 0;
+		      $$->next = NULL;
+		    }
+		| '1'
+		    {
+		      $$ = xmalloc (sizeof (struct bitvalue));
+		      $$->type = zeroone;
+		      $$->value = 1;
+		      $$->next = NULL;
+		    }
+		| kBITFIELD
+		    {
+		      $$ = xmalloc (sizeof (struct bitvalue));
+		      struct known_bitfield search;
+		      search.name = $1;
+		      struct known_bitfield **res;
+		      res = tfind (&search, &bitfields, bitfield_compare);
+		      if (res == NULL)
+			{
+			  error (0, 0, "%d: unknown bitfield '%s'",
+				 i386_lineno, search.name);
+			  $$->type = failure;
+			}
+		      else
+			{
+			  $$->type = field;
+			  $$->field = *res;
+			}
+		      $$->next = NULL;
+		    }
+		;
+
+optargs:	  kSPACE args
+		    { $$ = $2; }
+		|
+		    { $$ = NULL; }
+		;
+
+args:		  args ',' arg
+		    {
+		      struct argument *runp = $1;
+		      while (runp->next != NULL)
+			runp = runp->next;
+		      runp->next = xmalloc (sizeof (struct argument));
+		      runp->next->name = combine ($3);
+		      runp->next->next = NULL;
+		      $$ = $1;
+		    }
+		| arg
+		    {
+		      $$ = xmalloc (sizeof (struct argument));
+		      $$->name = combine ($1);
+		      $$->next = NULL;
+		    }
+		;
+
+arg:		  arg argcomp
+		    {
+		      struct argname *runp = $1;
+		      while (runp->next != NULL)
+			runp = runp->next;
+		      runp->next = $2;
+		      $$ = $1;
+		    }
+		| argcomp
+		    { $$ = $1; }
+		;
+argcomp:	  kBITFIELD
+		    {
+		      $$ = xmalloc (sizeof (struct argname));
+		      $$->type = nfield;
+		      $$->next = NULL;
+
+		      struct known_bitfield search;
+		      search.name = $1;
+		      struct known_bitfield **res;
+		      res = tfind (&search, &bitfields, bitfield_compare);
+		      if (res == NULL)
+			{
+			  if (strcmp ($1, "ax") == 0)
+			    $$->field = &ax_reg;
+			  else if (strcmp ($1, "dx") == 0)
+			    $$->field = &dx_reg;
+			  else if (strcmp ($1, "es_di") == 0)
+			    $$->field = &di_reg;
+			  else if (strcmp ($1, "ds_si") == 0)
+			    $$->field = &si_reg;
+			  else if (strcmp ($1, "ds_bx") == 0)
+			    $$->field = &bx_reg;
+			  else
+			    {
+			      error (0, 0, "%d: unknown bitfield '%s'",
+				     i386_lineno, search.name);
+			      $$->field = NULL;
+			    }
+			}
+		      else
+			$$->field = *res;
+		    }
+		| kCHAR
+		    {
+		      $$ = xmalloc (sizeof (struct argname));
+		      $$->type = string;
+		      $$->next = NULL;
+		      $$->str = xmalloc (2);
+		      $$->str[0] = $1;
+		      $$->str[1] = '\0';
+		    }
+		| kID
+		    {
+		      $$ = xmalloc (sizeof (struct argname));
+		      $$->type = string;
+		      $$->next = NULL;
+		      $$->str = $1;
+		    }
+		| ':'
+		    {
+		      $$ = xmalloc (sizeof (struct argname));
+		      $$->type = string;
+		      $$->next = NULL;
+		      $$->str = xmalloc (2);
+		      $$->str[0] = ':';
+		      $$->str[1] = '\0';
+		    }
+		;
+
+%%
+
+static void
+yyerror (const char *s)
+{
+  error (0, 0, gettext ("while reading i386 CPU description: %s at line %d"),
+         gettext (s), i386_lineno);
+}
+
+
+static int
+bitfield_compare (const void *p1, const void *p2)
+{
+  struct known_bitfield *f1 = (struct known_bitfield *) p1;
+  struct known_bitfield *f2 = (struct known_bitfield *) p2;
+
+  return strcmp (f1->name, f2->name);
+}
+
+
+static void
+new_bitfield (char *name, unsigned long int num)
+{
+  struct known_bitfield *newp = xmalloc (sizeof (struct known_bitfield));
+  newp->name = name;
+  newp->bits = num;
+  newp->tmp = 0;
+
+  if (tfind (newp, &bitfields, bitfield_compare) != NULL)
+    {
+      error (0, 0, "%d: duplicated definition of bitfield '%s'",
+	     i386_lineno, name);
+      free (name);
+      return;
+    }
+
+  if (tsearch (newp, &bitfields, bitfield_compare) == NULL)
+    error (EXIT_FAILURE, errno, "%d: cannot insert new bitfield '%s'",
+	   i386_lineno, name);
+}
+
+
+/* Check that the number of bits is a multiple of 8.  */
+static void
+check_bits (struct bitvalue *val)
+{
+  struct bitvalue *runp = val;
+  unsigned int total = 0;
+
+  while (runp != NULL)
+    {
+      if (runp->type == zeroone)
+	++total;
+      else if (runp->field == NULL)
+	/* No sense doing anything, the field is not known.  */
+	return;
+      else
+	total += runp->field->bits;
+
+      runp = runp->next;
+    }
+
+  if (total % 8 != 0)
+    {
+      struct obstack os;
+      obstack_init (&os);
+
+      while (val != NULL)
+	{
+	  if (val->type == zeroone)
+	    obstack_printf (&os, "%u", val->value);
+	  else
+	    obstack_printf (&os, "{%s}", val->field->name);
+	  val = val->next;
+	}
+      obstack_1grow (&os, '\0');
+
+      error (0, 0, "%d: field '%s' not a multiple of 8 bits in size",
+	     i386_lineno, (char *) obstack_finish (&os));
+
+      obstack_free (&os, NULL);
+    }
+}
+
+
+static int
+check_duplicates (struct bitvalue *val)
+{
+  static int testcnt;
+  ++testcnt;
+
+  int result = 0;
+  while (val != NULL)
+    {
+      if (val->type == field && val->field != NULL)
+	{
+	  if (val->field->tmp == testcnt)
+	    {
+	      error (0, 0, "%d: bitfield '%s' used more than once",
+		     i386_lineno - 1, val->field->name);
+	      result = 1;
+	    }
+	  val->field->tmp = testcnt;
+	}
+
+      val = val->next;
+    }
+
+  return result;
+}
+
+
+static int
+check_argsdef (struct bitvalue *bitval, struct argument *args)
+{
+  int result = 0;
+
+  while (args != NULL)
+    {
+      for (struct argname *name = args->name; name != NULL; name = name->next)
+	if (name->type == nfield && name->field != NULL
+	    && name->field != &ax_reg && name->field != &dx_reg
+	    && name->field != &di_reg && name->field != &si_reg
+	    && name->field != &bx_reg)
+	  {
+	    struct bitvalue *runp = bitval;
+
+	    while (runp != NULL)
+	      if (runp->type == field && runp->field == name->field)
+		break;
+	      else
+		runp = runp->next;
+
+	    if (runp == NULL)
+	      {
+		error (0, 0, "%d: unknown bitfield '%s' used in output format",
+		       i386_lineno - 1, name->field->name);
+		result = 1;
+	      }
+	  }
+
+      args = args->next;
+    }
+
+  return result;
+}
+
+
+static int
+check_bitsused (struct bitvalue *bitval, struct known_bitfield *suffix,
+		struct argument *args)
+{
+  int result = 0;
+
+  while (bitval != NULL)
+    {
+      if (bitval->type == field && bitval->field != NULL
+	  && bitval->field != suffix
+	  /* {w} is handled special.  */
+	  && strcmp (bitval->field->name, "w") != 0)
+	{
+	  struct argument *runp;
+	  for (runp = args; runp != NULL; runp = runp->next)
+	    {
+	      struct argname *name = runp->name;
+
+	      while (name != NULL)
+		if (name->type == nfield && name->field == bitval->field)
+		  break;
+		else
+		  name = name->next;
+
+	      if (name != NULL)
+		break;
+	    }
+
+#if 0
+	  if (runp == NULL)
+	    {
+	      error (0, 0, "%d: bitfield '%s' not used",
+		     i386_lineno - 1, bitval->field->name);
+	      result = 1;
+	    }
+#endif
+	}
+
+      bitval = bitval->next;
+    }
+
+  return result;
+}
+
+
+static struct argname *
+combine (struct argname *name)
+{
+  struct argname *last_str = NULL;
+  for (struct argname *runp = name; runp != NULL; runp = runp->next)
+    {
+      if (runp->type == string)
+	{
+	  if (last_str == NULL)
+	    last_str = runp;
+	  else
+	    {
+	      last_str->str = xrealloc (last_str->str,
+					strlen (last_str->str)
+					+ strlen (runp->str) + 1);
+	      strcat (last_str->str, runp->str);
+	      last_str->next = runp->next;
+	    }
+	}
+      else
+	last_str = NULL;
+    }
+  return name;
+}
+
+
+#define obstack_grow_str(ob, str) obstack_grow (ob, str, strlen (str))
+
+
+static void
+fillin_arg (struct bitvalue *bytes, struct argname *name,
+	    struct instruction *instr, int n)
+{
+  static struct obstack ob;
+  static int initialized;
+  if (! initialized)
+    {
+      initialized = 1;
+      obstack_init (&ob);
+    }
+
+  struct argname *runp = name;
+  int cnt = 0;
+  while (runp != NULL)
+    {
+      /* We ignore strings in the function name.  */
+      if (runp->type == string)
+	{
+	  if (instr->operands[n].str != NULL)
+	    error (EXIT_FAILURE, 0,
+		   "%d: cannot have more than one string parameter",
+		   i386_lineno - 1);
+
+	  instr->operands[n].str = runp->str;
+	}
+      else
+	{
+	  assert (runp->type == nfield);
+
+	  /* Construct the function name.  */
+	  if (cnt++ > 0)
+	    obstack_1grow (&ob, '$');
+
+	  if (runp->field == NULL)
+	    /* Add some string which contains invalid characters.  */
+	    obstack_grow_str (&ob, "!!!INVALID!!!");
+	  else
+	    {
+	      char *fieldname = runp->field->name;
+
+	      struct synonym search = { .from = fieldname };
+
+	      struct synonym **res = tfind (&search, &synonyms, compare_syn);
+	      if (res != NULL)
+		fieldname = (*res)->to;
+
+	      obstack_grow_str (&ob, fieldname);
+	    }
+
+	  /* Now compute the bit offset of the field.  */
+	  struct bitvalue *b = bytes;
+	  int bitoff = 0;
+	  if (runp->field != NULL)
+	    while (b != NULL)
+	      {
+		if (b->type == field && b->field != NULL)
+		  {
+		    if (strcmp (b->field->name, runp->field->name) == 0)
+		      break;
+		    bitoff += b->field->bits;
+		  }
+		else
+		  ++bitoff;
+
+		b = b->next;
+	      }
+	  if (instr->operands[n].off1 == 0)
+	    instr->operands[n].off1 = bitoff;
+	  else if (instr->operands[n].off2 == 0)
+	    instr->operands[n].off2 = bitoff;
+	  else if (instr->operands[n].off3 == 0)
+	    instr->operands[n].off3 = bitoff;
+	  else
+	    error (EXIT_FAILURE, 0,
+		   "%d: cannot have more than three fields in parameter",
+		   i386_lineno - 1);
+
+	  if  (runp->field != NULL
+	       && strncasecmp (runp->field->name, "mod", 3) == 0)
+	    instr->modrm = 1;
+	}
+
+      runp = runp->next;
+    }
+  if (obstack_object_size (&ob) == 0)
+    obstack_grow_str (&ob, "string");
+  obstack_1grow (&ob, '\0');
+  char *fct = obstack_finish (&ob);
+
+  instr->operands[n].fct = fct;
+}
+
+
+#if 0
+static void
+nameout (const void *nodep, VISIT value, int level)
+{
+  if (value == leaf || value == postorder)
+    printf ("  %s\n", *(const char **) nodep);
+}
+#endif
+
+
+static int
+compare_argstring (const void *p1, const void *p2)
+{
+  const struct argstring *a1 = (const struct argstring *) p1;
+  const struct argstring *a2 = (const struct argstring *) p2;
+
+  return strcmp (a1->str, a2->str);
+}
+
+
+static int maxoff[3][3];
+static int minoff[3][3] = { { 1000, 1000, 1000 },
+			    { 1000, 1000, 1000 },
+			    { 1000, 1000, 1000 } };
+static int nbitoff[3][3];
+static void *fct_names[3];
+static int nbitfct[3];
+static int nbitsuf;
+static void *strs[3];
+static int nbitstr[3];
+static int total_bits = 2;	// Already counted the rep/repe bits.
+
+static void
+find_numbers (void)
+{
+  int nfct_names[3] = { 0, 0, 0 };
+  int nstrs[3] = { 0, 0, 0 };
+
+  /* We reverse the order of the instruction list while processing it.
+     Later phases need it in the order in which the input file has
+     them.  */
+  struct instruction *reversed = NULL;
+
+  struct instruction *runp = instructions;
+  while (runp != NULL)
+    {
+      for (int i = 0; i < 3; ++i)
+	if (runp->operands[i].fct != NULL)
+	  {
+	    struct argstring search = { .str = runp->operands[i].fct };
+	    if (tfind (&search, &fct_names[i], compare_argstring) == NULL)
+	      {
+		struct argstring *newp = xmalloc (sizeof (*newp));
+		newp->str = runp->operands[i].fct;
+		newp->idx = 0;
+		if (tsearch (newp, &fct_names[i], compare_argstring) == NULL)
+		  error (EXIT_FAILURE, errno, "tsearch");
+		++nfct_names[i];
+	      }
+
+	    if (runp->operands[i].str != NULL)
+	      {
+		search.str = runp->operands[i].str;
+		if (tfind (&search, &strs[i], compare_argstring) == NULL)
+		  {
+		    struct argstring *newp = xmalloc (sizeof (*newp));
+		    newp->str = runp->operands[i].str;
+		    newp->idx = 0;
+		    if (tsearch (newp, &strs[i], compare_argstring) == NULL)
+		      error (EXIT_FAILURE, errno, "tsearch");
+		    ++nstrs[i];
+		  }
+	      }
+
+	    maxoff[i][0] = MAX (maxoff[i][0], runp->operands[i].off1);
+	    maxoff[i][1] = MAX (maxoff[i][1], runp->operands[i].off2);
+	    maxoff[i][2] = MAX (maxoff[i][2], runp->operands[i].off3);
+
+	    if (runp->operands[i].off1 > 0)
+	      minoff[i][0] = MIN (minoff[i][0], runp->operands[i].off1);
+	    if (runp->operands[i].off2 > 0)
+	      minoff[i][1] = MIN (minoff[i][1], runp->operands[i].off2);
+	    if (runp->operands[i].off3 > 0)
+	      minoff[i][2] = MIN (minoff[i][2], runp->operands[i].off3);
+	  }
+
+      struct instruction *old = runp;
+      runp = runp->next;
+
+      old->next = reversed;
+      reversed = old;
+    }
+  instructions = reversed;
+
+  int d;
+  int c;
+  for (int i = 0; i < 3; ++i)
+    {
+      // printf ("min1 = %d, min2 = %d, min3 = %d\n", minoff[i][0], minoff[i][1], minoff[i][2]);
+      // printf ("max1 = %d, max2 = %d, max3 = %d\n", maxoff[i][0], maxoff[i][1], maxoff[i][2]);
+
+      if (minoff[i][0] == 1000)
+	nbitoff[i][0] = 0;
+      else
+	{
+	  nbitoff[i][0] = 1;
+	  d = maxoff[i][0] - minoff[i][0];
+	  c = 1;
+	  while (c < d)
+	    {
+	      ++nbitoff[i][0];
+	      c *= 2;
+	    }
+	  total_bits += nbitoff[i][0];
+	}
+
+      if (minoff[i][1] == 1000)
+	nbitoff[i][1] = 0;
+      else
+	{
+	  nbitoff[i][1] = 1;
+	  d = maxoff[i][1] - minoff[i][1];
+	  c = 1;
+	  while (c < d)
+	    {
+	      ++nbitoff[i][1];
+	      c *= 2;
+	    }
+	  total_bits += nbitoff[i][1];
+	}
+
+      if (minoff[i][2] == 1000)
+	nbitoff[i][2] = 0;
+      else
+	{
+	  nbitoff[i][2] = 1;
+	  d = maxoff[i][2] - minoff[i][2];
+	  c = 1;
+	  while (c < d)
+	    {
+	      ++nbitoff[i][2];
+	      c *= 2;
+	    }
+	  total_bits += nbitoff[i][2];
+	}
+      // printf ("off1 = %d, off2 = %d, off3 = %d\n", nbitoff[i][0], nbitoff[i][1], nbitoff[i][2]);
+
+      nbitfct[i] = 1;
+      d = nfct_names[i];
+      c = 1;
+      while (c < d)
+	{
+	  ++nbitfct[i];
+	  c *= 2;
+	}
+      total_bits += nbitfct[i];
+      // printf ("%d fct[%d], %d bits\n", nfct_names[i], i, nbitfct[i]);
+
+      if (nstrs[i] != 0)
+	{
+	  nbitstr[i] = 1;
+	  d = nstrs[i];
+	  c = 1;
+	  while (c < d)
+	    {
+	      ++nbitstr[i];
+	      c *= 2;
+	    }
+	  total_bits += nbitstr[i];
+	}
+
+      // twalk (fct_names[i], nameout);
+    }
+
+  nbitsuf = 0;
+  d = nsuffixes;
+  c = 1;
+  while (c < d)
+    {
+      ++nbitsuf;
+      c *= 2;
+    }
+  total_bits += nbitsuf;
+  // printf ("%d suffixes, %d bits\n", nsuffixes, nbitsuf);
+}
+
+
+static int
+compare_syn (const void *p1, const void *p2)
+{
+  const struct synonym *s1 = (const struct synonym *) p1;
+  const struct synonym *s2 = (const struct synonym *) p2;
+
+  return strcmp (s1->from, s2->from);
+}
+
+
+static int
+compare_suf (const void *p1, const void *p2)
+{
+  const struct suffix *s1 = (const struct suffix *) p1;
+  const struct suffix *s2 = (const struct suffix *) p2;
+
+  return strcmp (s1->name, s2->name);
+}
+
+
+static int count_op_str;
+static int off_op_str;
+static void
+print_op_str (const void *nodep, VISIT value,
+	      int level __attribute__ ((unused)))
+{
+  if (value == leaf || value == postorder)
+    {
+      const char *str = (*(struct argstring **) nodep)->str;
+      fprintf (outfile, "%s\n  \"%s",
+	       count_op_str == 0 ? "" : "\\0\"", str);
+      (*(struct argstring **) nodep)->idx = ++count_op_str;
+      (*(struct argstring **) nodep)->off = off_op_str;
+      off_op_str += strlen (str) + 1;
+    }
+}
+
+
+static void
+print_op_str_idx (const void *nodep, VISIT value,
+		  int level __attribute__ ((unused)))
+{
+  if (value == leaf || value == postorder)
+    printf ("  %d,\n", (*(struct argstring **) nodep)->off);
+}
+
+
+static void
+print_op_fct (const void *nodep, VISIT value,
+	      int level __attribute__ ((unused)))
+{
+  if (value == leaf || value == postorder)
+    {
+      fprintf (outfile, "  FCT_%s,\n", (*(struct argstring **) nodep)->str);
+      (*(struct argstring **) nodep)->idx = ++count_op_str;
+    }
+}
+
+
+#if NMNES < 2
+# error "bogus NMNES value"
+#endif
+
+static void
+instrtable_out (void)
+{
+  find_numbers ();
+
+#if 0
+  create_mnemonic_table ();
+
+  fprintf (outfile, "#define MNEMONIC_BITS %zu\n", best_mnemonic_bits);
+#else
+  fprintf (outfile, "#define MNEMONIC_BITS %ld\n",
+	   lrint (ceil (log2 (NMNES))));
+#endif
+  fprintf (outfile, "#define SUFFIX_BITS %d\n", nbitsuf);
+  for (int i = 0; i < 3; ++i)
+    {
+      fprintf (outfile, "#define FCT%d_BITS %d\n", i + 1, nbitfct[i]);
+      if (nbitstr[i] != 0)
+	fprintf (outfile, "#define STR%d_BITS %d\n", i + 1, nbitstr[i]);
+      fprintf (outfile, "#define OFF%d_1_BITS %d\n", i + 1, nbitoff[i][0]);
+      fprintf (outfile, "#define OFF%d_1_BIAS %d\n", i + 1, minoff[i][0]);
+      if (nbitoff[i][1] != 0)
+	{
+	  fprintf (outfile, "#define OFF%d_2_BITS %d\n", i + 1, nbitoff[i][1]);
+	  fprintf (outfile, "#define OFF%d_2_BIAS %d\n", i + 1, minoff[i][1]);
+	}
+      if (nbitoff[i][2] != 0)
+	{
+	  fprintf (outfile, "#define OFF%d_3_BITS %d\n", i + 1, nbitoff[i][2]);
+	  fprintf (outfile, "#define OFF%d_3_BIAS %d\n", i + 1, minoff[i][2]);
+	}
+    }
+
+  fputs ("\n#include <i386_data.h>\n\n", outfile);
+
+
+#define APPEND(a, b) APPEND_ (a, b)
+#define APPEND_(a, b) a##b
+#define EMIT_SUFFIX(suf) \
+  fprintf (outfile, "#define suffix_%s %d\n", #suf, APPEND (suffix_, suf))
+  EMIT_SUFFIX (none);
+  EMIT_SUFFIX (w);
+  EMIT_SUFFIX (w0);
+  EMIT_SUFFIX (W);
+  EMIT_SUFFIX (tttn);
+  EMIT_SUFFIX (D);
+  EMIT_SUFFIX (w1);
+  EMIT_SUFFIX (W1);
+
+  fputc_unlocked ('\n', outfile);
+
+  for (int i = 0; i < 3; ++i)
+    {
+      /* Functions.  */
+      count_op_str = 0;
+      fprintf (outfile, "static const opfct_t op%d_fct[] =\n{\n  NULL,\n",
+	       i + 1);
+      twalk (fct_names[i], print_op_fct);
+      fputs ("};\n", outfile);
+
+      /* The operand strings.  */
+      if (nbitstr[i] != 0)
+	{
+	  count_op_str = 0;
+	  off_op_str = 0;
+	  fprintf (outfile, "static const char op%d_str[] =", i + 1);
+	  twalk (strs[i], print_op_str);
+	  fputs ("\";\n", outfile);
+
+	  fprintf (outfile, "static const uint8_t op%d_str_idx[] = {\n",
+		   i + 1);
+	  twalk (strs[i], print_op_str_idx);
+	  fputs ("};\n", outfile);
+	}
+    }
+
+
+  fputs ("static const struct instr_enc instrtab[] =\n{\n", outfile);
+  struct instruction *instr;
+  for (instr = instructions; instr != NULL; instr = instr->next)
+    {
+      fputs ("  {", outfile);
+      if (instr->mnemonic == (void *) -1l)
+	fputs (" .mnemonic = MNE_INVALID,", outfile);
+      else
+	fprintf (outfile, " .mnemonic = MNE_%s,", instr->mnemonic);
+      fprintf (outfile, " .rep = %d,", instr->rep);
+      fprintf (outfile, " .repe = %d,", instr->repe);
+      fprintf (outfile, " .suffix = %d,", instr->suffix);
+      fprintf (outfile, " .modrm = %d,", instr->modrm);
+
+      for (int i = 0; i < 3; ++i)
+	{
+	  int idx = 0;
+	  if (instr->operands[i].fct != NULL)
+	    {
+	      struct argstring search = { .str = instr->operands[i].fct };
+	      struct argstring **res = tfind (&search, &fct_names[i],
+					      compare_argstring);
+	      assert (res != NULL);
+	      idx = (*res)->idx;
+	    }
+	  fprintf (outfile, " .fct%d = %d,", i + 1, idx);
+
+	  idx = 0;
+	  if (instr->operands[i].str != NULL)
+	    {
+	      struct argstring search = { .str = instr->operands[i].str };
+	      struct argstring **res = tfind (&search, &strs[i],
+					      compare_argstring);
+	      assert (res != NULL);
+	      idx = (*res)->idx;
+	    }
+	  if (nbitstr[i] != 0)
+	    fprintf (outfile, " .str%d = %d,", i + 1, idx);
+
+	  fprintf (outfile, " .off%d_1 = %d,", i + 1,
+		   MAX (0, instr->operands[i].off1 - minoff[i][0]));
+
+	  if (nbitoff[i][1] != 0)
+	    fprintf (outfile, " .off%d_2 = %d,", i + 1,
+		     MAX (0, instr->operands[i].off2 - minoff[i][1]));
+
+	  if (nbitoff[i][2] != 0)
+	    fprintf (outfile, " .off%d_3 = %d,", i + 1,
+		     MAX (0, instr->operands[i].off3 - minoff[i][2]));
+	}
+
+      fputs (" },\n", outfile);
+    }
+  fputs ("};\n", outfile);
+
+  fputs ("static const uint8_t match_data[] =\n{\n", outfile);
+  size_t cnt = 0;
+  for (instr = instructions; instr != NULL; instr = instr->next, ++cnt)
+    {
+      /* First count the number of bytes.  */
+      size_t totalbits = 0;
+      size_t zerobits = 0;
+      bool leading_p = true;
+      size_t leadingbits = 0;
+      struct bitvalue *b = instr->bytes;
+      while (b != NULL)
+	{
+	  if (b->type == zeroone)
+	    {
+	      ++totalbits;
+	      zerobits = 0;
+	      if (leading_p)
+		++leadingbits;
+	    }
+	  else
+	    {
+	      totalbits += b->field->bits;
+	      /* We must always count the mod/rm byte.  */
+	      if (strncasecmp (b->field->name, "mod", 3) == 0)
+		zerobits = 0;
+	      else
+		zerobits += b->field->bits;
+	      leading_p = false;
+	    }
+	  b = b->next;
+	}
+      size_t nbytes = (totalbits - zerobits + 7) / 8;
+      assert (nbytes > 0);
+      size_t leadingbytes = leadingbits / 8;
+
+      fprintf (outfile, "  %#zx,", nbytes | (leadingbytes << 4));
+
+      /* Now create the mask and byte values.  */
+      uint8_t byte = 0;
+      uint8_t mask = 0;
+      int nbits = 0;
+      b = instr->bytes;
+      while (b != NULL)
+	{
+	  if (b->type == zeroone)
+	    {
+	      byte = (byte << 1) | b->value;
+	      mask = (mask << 1) | 1;
+	      if (++nbits == 8)
+		{
+		  if (leadingbytes > 0)
+		    {
+		      assert (mask == 0xff);
+		      fprintf (outfile, " %#" PRIx8 ",", byte);
+		      --leadingbytes;
+		    }
+		  else
+		    fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",",
+			     mask, byte);
+		  byte = mask = nbits = 0;
+		  if (--nbytes == 0)
+		    break;
+		}
+	    }
+	  else
+	    {
+	      assert (leadingbytes == 0);
+
+	      unsigned long int remaining = b->field->bits;
+	      while (nbits + remaining > 8)
+		{
+		  fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",",
+			   mask << (8 - nbits), byte << (8 - nbits));
+		  remaining = nbits + remaining - 8;
+		  byte = mask = nbits = 0;
+		  if (--nbytes == 0)
+		    break;
+		}
+	      byte <<= remaining;
+	      mask <<= remaining;
+	      nbits += remaining;
+	      if (nbits == 8)
+		{
+		  fprintf (outfile, " %#" PRIx8 ", %#" PRIx8 ",", mask, byte);
+		  byte = mask = nbits = 0;
+		  if (--nbytes == 0)
+		    break;
+		}
+	    }
+	  b = b->next;
+	}
+
+      fputc_unlocked ('\n', outfile);
+    }
+  fputs ("};\n", outfile);
+}
+
+
+#if 0
+static size_t mnemonic_maxlen;
+static size_t mnemonic_minlen;
+static size_t
+which_chars (const char *str[], size_t nstr)
+{
+  char used_char[256];
+  memset (used_char, '\0', sizeof (used_char));
+  mnemonic_maxlen = 0;
+  mnemonic_minlen = 10000;
+  for (size_t cnt = 0; cnt < nstr; ++cnt)
+    {
+      const unsigned char *cp = (const unsigned char *) str[cnt];
+      mnemonic_maxlen = MAX (mnemonic_maxlen, strlen ((char *) cp));
+      mnemonic_minlen = MIN (mnemonic_minlen, strlen ((char *) cp));
+      do
+        used_char[*cp++] = 1;
+      while (*cp != '\0');
+    }
+  size_t nused_char = 0;
+  for (size_t cnt = 0; cnt < 256; ++cnt)
+    if (used_char[cnt] != 0)
+      ++nused_char;
+  return nused_char;
+}
+
+
+static const char **mnemonic_strs;
+static size_t nmnemonic_strs;
+static void
+add_mnemonics (const void *nodep, VISIT value,
+	       int level __attribute__ ((unused)))
+{
+  if (value == leaf || value == postorder)
+    mnemonic_strs[nmnemonic_strs++] = *(const char **) nodep;
+}
+
+
+struct charfreq
+{
+  char ch;
+  int freq;
+};
+static struct charfreq pfxfreq[256];
+static struct charfreq sfxfreq[256];
+
+
+static int
+compare_freq (const void *p1, const void *p2)
+{
+  const struct charfreq *c1 = (const struct charfreq *) p1;
+  const struct charfreq *c2 = (const struct charfreq *) p2;
+
+  if (c1->freq > c2->freq)
+    return -1;
+  if (c1->freq < c2->freq)
+    return 1;
+  return 0;
+}
+
+
+static size_t
+compute_pfxfreq (const char *str[], size_t nstr)
+{
+  memset (pfxfreq, '\0', sizeof (pfxfreq));
+
+  for (size_t i = 0; i < nstr; ++i)
+    pfxfreq[i].ch = i;
+
+  for (size_t i = 0; i < nstr; ++i)
+    ++pfxfreq[*((const unsigned char *) str[i])].freq;
+
+  qsort (pfxfreq, 256, sizeof (struct charfreq), compare_freq);
+
+  size_t n = 0;
+  while (n < 256 && pfxfreq[n].freq != 0)
+    ++n;
+  return n;
+}
+
+
+struct strsnlen
+{
+  const char *str;
+  size_t len;
+};
+
+static size_t
+compute_sfxfreq (size_t nstr, struct strsnlen *strsnlen)
+{
+  memset (sfxfreq, '\0', sizeof (sfxfreq));
+
+  for (size_t i = 0; i < nstr; ++i)
+    sfxfreq[i].ch = i;
+
+  for (size_t i = 0; i < nstr; ++i)
+    ++sfxfreq[((const unsigned char *) strchrnul (strsnlen[i].str, '\0'))[-1]].freq;
+
+  qsort (sfxfreq, 256, sizeof (struct charfreq), compare_freq);
+
+  size_t n = 0;
+  while (n < 256 && sfxfreq[n].freq != 0)
+    ++n;
+  return n;
+}
+
+
+static void
+create_mnemonic_table (void)
+{
+  mnemonic_strs = xmalloc (nmnemonics * sizeof (char *));
+
+  twalk (mnemonics, add_mnemonics);
+
+  (void) which_chars (mnemonic_strs, nmnemonic_strs);
+
+  size_t best_so_far = 100000000;
+  char *best_prefix = NULL;
+  char *best_suffix = NULL;
+  char *best_table = NULL;
+  size_t best_table_size = 0;
+  size_t best_table_bits = 0;
+  size_t best_prefix_bits = 0;
+
+  /* We can precompute the prefix characters.  */
+  size_t npfx_char = compute_pfxfreq (mnemonic_strs, nmnemonic_strs);
+
+  /* Compute best size for string representation including explicit NUL.  */
+  for (size_t pfxbits = 0; (1u << pfxbits) < 2 * npfx_char; ++pfxbits)
+    {
+      char prefix[1 << pfxbits];
+      size_t i;
+      for (i = 0; i < (1u << pfxbits) - 1; ++i)
+	prefix[i] = pfxfreq[i].ch;
+      prefix[i] = '\0';
+
+      struct strsnlen strsnlen[nmnemonic_strs];
+
+      for (i = 0; i < nmnemonic_strs; ++i)
+	{
+	  if (strchr (prefix, *mnemonic_strs[i]) != NULL)
+	    strsnlen[i].str = mnemonic_strs[i] + 1;
+	  else
+	    strsnlen[i].str = mnemonic_strs[i];
+	  strsnlen[i].len = strlen (strsnlen[i].str);
+	}
+
+      /* With the prefixes gone, try to combine strings.  */
+      size_t nstrsnlen = 1;
+      for (i = 1; i < nmnemonic_strs; ++i)
+	{
+	  size_t j;
+	  for (j = 0; j < nstrsnlen; ++j)
+	    if (strsnlen[i].len > strsnlen[j].len
+		&& strcmp (strsnlen[j].str,
+			   strsnlen[i].str + (strsnlen[i].len
+					      - strsnlen[j].len)) == 0)
+	      {
+		strsnlen[j] = strsnlen[i];
+		break;
+	      }
+	    else if (strsnlen[i].len < strsnlen[j].len
+		     && strcmp (strsnlen[i].str,
+				strsnlen[j].str + (strsnlen[j].len
+						   - strsnlen[i].len)) == 0)
+	      break;
+;
+	  if (j == nstrsnlen)
+	      strsnlen[nstrsnlen++] = strsnlen[i];
+	}
+
+      size_t nsfx_char = compute_sfxfreq (nstrsnlen, strsnlen);
+
+      for (size_t sfxbits = 0; (1u << sfxbits) < 2 * nsfx_char; ++sfxbits)
+	{
+	  char suffix[1 << sfxbits];
+
+	  for (i = 0; i < (1u << sfxbits) - 1; ++i)
+	    suffix[i] = sfxfreq[i].ch;
+	  suffix[i] = '\0';
+
+	  size_t newlen[nstrsnlen];
+
+	  for (i = 0; i < nstrsnlen; ++i)
+	    if (strchr (suffix, strsnlen[i].str[strsnlen[i].len - 1]) != NULL)
+	      newlen[i] = strsnlen[i].len - 1;
+	    else
+	      newlen[i] = strsnlen[i].len;
+
+	  char charused[256];
+	  memset (charused, '\0', sizeof (charused));
+	  size_t ncharused = 0;
+
+	  const char *tablestr[nstrsnlen];
+	  size_t ntablestr = 1;
+	  tablestr[0] = strsnlen[0].str;
+	  size_t table = newlen[0] + 1;
+	  for (i = 1; i < nstrsnlen; ++i)
+	    {
+	      size_t j;
+	      for (j = 0; j < ntablestr; ++j)
+		if (newlen[i] > newlen[j]
+		    && memcmp (tablestr[j],
+			       strsnlen[i].str + (newlen[i] - newlen[j]),
+			       newlen[j]) == 0)
+		  {
+		    table += newlen[i] - newlen[j];
+		    tablestr[j] = strsnlen[i].str;
+		    newlen[j] = newlen[i];
+		    break;
+		  }
+		else if (newlen[i] < newlen[j]
+		     && memcmp (strsnlen[i].str,
+				tablestr[j] + (newlen[j] - newlen[i]),
+				newlen[i]) == 0)
+		  break;
+
+	      if (j == ntablestr)
+		{
+		  table += newlen[i] + 1;
+		  tablestr[ntablestr] = strsnlen[i].str;
+		  newlen[ntablestr] = newlen[i];
+
+		  ++ntablestr;
+		}
+
+	      for (size_t x = 0; x < newlen[j]; ++x)
+		if (charused[((const unsigned char *) tablestr[j])[x]]++ == 0)
+		  ++ncharused;
+	    }
+
+	  size_t ncharused_bits = 0;
+	  i = 1;
+	  while (i < ncharused)
+	    {
+	      i *= 2;
+	      ++ncharused_bits;
+	    }
+
+	  size_t table_bits = 0;
+	  i = 1;
+	  while (i < table)
+	    {
+	      i *= 2;
+	      ++table_bits;
+	    }
+
+	  size_t mnemonic_bits = table_bits + pfxbits + sfxbits;
+	  size_t new_total = (((table + 7) / 8) * ncharused_bits + ncharused
+			      + (pfxbits == 0 ? 0 : (1 << pfxbits) - 1)
+			      + (sfxbits == 0 ? 0 : (1 << sfxbits) - 1)
+			      + (((total_bits + mnemonic_bits + 7) / 8)
+				 * ninstructions));
+
+	  if (new_total < best_so_far)
+	    {
+	      best_so_far = new_total;
+	      best_mnemonic_bits = mnemonic_bits;
+
+	      free (best_suffix);
+	      best_suffix = xstrdup (suffix);
+
+	      free (best_prefix);
+	      best_prefix = xstrdup (prefix);
+	      best_prefix_bits = pfxbits;
+
+	      best_table_size = table;
+	      best_table_bits = table_bits;
+	      char *cp = best_table = xrealloc (best_table, table);
+	      for (i = 0; i < ntablestr; ++i)
+		{
+		  assert (cp + newlen[i] + 1 <= best_table + table);
+		  cp = mempcpy (cp, tablestr[i], newlen[i]);
+		  *cp++ = '\0';
+		}
+	      assert (cp == best_table + table);
+	    }
+	}
+    }
+
+  fputs ("static const char mnemonic_table[] =\n\"", outfile);
+  for (size_t i = 0; i < best_table_size; ++i)
+    {
+      if (((i + 1) % 60) == 0)
+	fputs ("\"\n\"", outfile);
+      if (!isascii (best_table[i]) || !isprint (best_table[i]))
+	fprintf (outfile, "\\%03o", best_table[i]);
+      else
+	fputc (best_table[i], outfile);
+    }
+  fputs ("\";\n", outfile);
+
+  if (best_prefix[0] != '\0')
+    fprintf (outfile,
+	     "static const char prefix[%zu] = \"%s\";\n"
+	     "#define PREFIXCHAR_BITS %zu\n",
+	     strlen (best_prefix), best_prefix, best_prefix_bits);
+  else
+    fputs ("#define NO_PREFIX\n", outfile);
+
+  if (best_suffix[0] != '\0')
+    fprintf (outfile, "static const char suffix[%zu] = \"%s\";\n",
+	     strlen (best_suffix), best_suffix);
+  else
+    fputs ("#define NO_SUFFIX\n", outfile);
+
+  for (size_t i = 0; i < nmnemonic_strs; ++i)
+    {
+      const char *mne = mnemonic_strs[i];
+
+      size_t pfxval = 0;
+      char *cp = strchr (best_prefix, *mne);
+      if (cp != NULL)
+	{
+	  pfxval = 1 + (cp - best_prefix);
+	  ++mne;
+	}
+
+      size_t l = strlen (mne);
+
+      size_t sfxval = 0;
+      cp = strchr (best_suffix, mne[l - 1]);
+      if (cp != NULL)
+	{
+	  sfxval = 1 + (cp - best_suffix);
+	  --l;
+	}
+
+      char *off = memmem (best_table, best_table_size, mne, l);
+      while (off[l] != '\0')
+	{
+	  off = memmem (off + 1, best_table_size, mne, l);
+	  assert (off != NULL);
+	}
+
+      fprintf (outfile, "#define MNE_%s %#zx\n",
+	       mnemonic_strs[i],
+	       (off - best_table)
+	       + ((pfxval + (sfxval << best_prefix_bits)) << best_table_bits));
+    }
+}
+#endif
diff --git a/third_party/elfutils/libcpu/memory-access.h b/third_party/elfutils/libcpu/memory-access.h
new file mode 100644
index 0000000..779825f
--- /dev/null
+++ b/third_party/elfutils/libcpu/memory-access.h
@@ -0,0 +1,182 @@
+/* Unaligned memory access functionality.
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008 Red Hat, Inc.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MEMORY_ACCESS_H
+#define _MEMORY_ACCESS_H 1
+
+#include <byteswap.h>
+#include <endian.h>
+#include <limits.h>
+#include <stdint.h>
+
+
+/* When loading this file we require the macro MACHINE_ENCODING to be
+   defined to signal the endianness of the architecture which is
+   defined.  */
+#ifndef MACHINE_ENCODING
+# error "MACHINE_ENCODING needs to be defined"
+#endif
+#if MACHINE_ENCODING != __BIG_ENDIAN && MACHINE_ENCODING != __LITTLE_ENDIAN
+# error "MACHINE_ENCODING must signal either big or little endian"
+#endif
+
+
+/* We use simple memory access functions in case the hardware allows it.
+   The caller has to make sure we don't have alias problems.  */
+#if ALLOW_UNALIGNED
+
+# define read_2ubyte_unaligned(Addr) \
+  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
+   ? bswap_16 (*((const uint16_t *) (Addr)))				      \
+   : *((const uint16_t *) (Addr)))
+# define read_2sbyte_unaligned(Addr) \
+  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
+   ? (int16_t) bswap_16 (*((const int16_t *) (Addr)))			      \
+   : *((const int16_t *) (Addr)))
+
+# define read_4ubyte_unaligned_noncvt(Addr) \
+   *((const uint32_t *) (Addr))
+# define read_4ubyte_unaligned(Addr) \
+  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
+   ? bswap_32 (*((const uint32_t *) (Addr)))				      \
+   : *((const uint32_t *) (Addr)))
+# define read_4sbyte_unaligned(Addr) \
+  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
+   ? (int32_t) bswap_32 (*((const int32_t *) (Addr)))			      \
+   : *((const int32_t *) (Addr)))
+
+# define read_8ubyte_unaligned(Addr) \
+  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
+   ? bswap_64 (*((const uint64_t *) (Addr)))				      \
+   : *((const uint64_t *) (Addr)))
+# define read_8sbyte_unaligned(Addr) \
+  (unlikely (MACHINE_ENCODING != __BYTE_ORDER)				      \
+   ? (int64_t) bswap_64 (*((const int64_t *) (Addr)))			      \
+   : *((const int64_t *) (Addr)))
+
+#else
+
+union unaligned
+  {
+    void *p;
+    uint16_t u2;
+    uint32_t u4;
+    uint64_t u8;
+    int16_t s2;
+    int32_t s4;
+    int64_t s8;
+  } attribute_packed;
+
+static inline uint16_t
+read_2ubyte_unaligned (const void *p)
+{
+  const union unaligned *up = p;
+  if (MACHINE_ENCODING != __BYTE_ORDER)
+    return bswap_16 (up->u2);
+  return up->u2;
+}
+static inline int16_t
+read_2sbyte_unaligned (const void *p)
+{
+  const union unaligned *up = p;
+  if (MACHINE_ENCODING != __BYTE_ORDER)
+    return (int16_t) bswap_16 (up->u2);
+  return up->s2;
+}
+
+static inline uint32_t
+read_4ubyte_unaligned_noncvt (const void *p)
+{
+  const union unaligned *up = p;
+  return up->u4;
+}
+static inline uint32_t
+read_4ubyte_unaligned (const void *p)
+{
+  const union unaligned *up = p;
+  if (MACHINE_ENCODING != __BYTE_ORDER)
+    return bswap_32 (up->u4);
+  return up->u4;
+}
+static inline int32_t
+read_4sbyte_unaligned (const void *p)
+{
+  const union unaligned *up = p;
+  if (MACHINE_ENCODING != __BYTE_ORDER)
+    return (int32_t) bswap_32 (up->u4);
+  return up->s4;
+}
+
+static inline uint64_t
+read_8ubyte_unaligned (const void *p)
+{
+  const union unaligned *up = p;
+  if (MACHINE_ENCODING != __BYTE_ORDER)
+    return bswap_64 (up->u8);
+  return up->u8;
+}
+static inline int64_t
+read_8sbyte_unaligned (const void *p)
+{
+  const union unaligned *up = p;
+  if (MACHINE_ENCODING != __BYTE_ORDER)
+    return (int64_t) bswap_64 (up->u8);
+  return up->s8;
+}
+
+#endif	/* allow unaligned */
+
+
+#define read_2ubyte_unaligned_inc(Addr) \
+  ({ uint16_t t_ = read_2ubyte_unaligned (Addr);			      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2);		      \
+     t_; })
+#define read_2sbyte_unaligned_inc(Addr) \
+  ({ int16_t t_ = read_2sbyte_unaligned (Addr);				      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2);		      \
+     t_; })
+
+#define read_4ubyte_unaligned_inc(Addr) \
+  ({ uint32_t t_ = read_4ubyte_unaligned (Addr);			      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4);		      \
+     t_; })
+#define read_4sbyte_unaligned_inc(Addr) \
+  ({ int32_t t_ = read_4sbyte_unaligned (Addr);				      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4);		      \
+     t_; })
+
+#define read_8ubyte_unaligned_inc(Addr) \
+  ({ uint64_t t_ = read_8ubyte_unaligned (Addr);			      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8);		      \
+     t_; })
+#define read_8sbyte_unaligned_inc(Addr) \
+  ({ int64_t t_ = read_8sbyte_unaligned (Addr);				      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8);		      \
+     t_; })
+
+#endif	/* memory-access.h */
diff --git a/third_party/elfutils/libcpu/x86_64_disasm.c b/third_party/elfutils/libcpu/x86_64_disasm.c
new file mode 100644
index 0000000..947bc94
--- /dev/null
+++ b/third_party/elfutils/libcpu/x86_64_disasm.c
@@ -0,0 +1,34 @@
+/* Disassembler for x86-64.
+   Copyright (C) 2007, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define i386_disasm x86_64_disasm
+#define DISFILE "x86_64_dis.h"
+#define MNEFILE "x86_64.mnemonics"
+#define X86_64
+#include "i386_disasm.c"
diff --git a/third_party/elfutils/libdw/ChangeLog b/third_party/elfutils/libdw/ChangeLog
new file mode 100644
index 0000000..7a6d311
--- /dev/null
+++ b/third_party/elfutils/libdw/ChangeLog
@@ -0,0 +1,2856 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* cfi.c (execute_cfi): Use FALLTHROUGH macro instead of comment.
+	* dwarf_frame_register.c (dwarf_frame_register): Likewise.
+
+2018-01-22  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am (AM_CPPFLAGS): Add -I libdwelf.
+	* dwarf_begin_elf.c (dwarf_begin_elf): Initialize Dwarf alt_fd to -1.
+	* dwarf_end.c (dwarf_end): Call dwarf_end and close on the alt_dwarf
+	and alt_fd if we allocated them.
+	* dwarf_fromref_die.c (dwarf_formref_die): Call dwarf_getalt.
+	* dwarf_formstring.c (dwarf_formstring): Likewise.
+	* dwarf_getalt.c (__libdw_filepath): New internal function.
+	(find_debug_altlink): New static function.
+	(dwarf_getalt): Check Dwarf alt_dwarf and call find_debug_altlink.
+	Cache result.
+	* dwarf_setalt.c (dwarf_setalt): Clean up Dwarf alt_dwarf and alt_fd
+	if we allocated.
+	* libdw.h (dwarf_getalt): Extend documentation.
+	(dwarf_setalt): Likewise.
+	* libdwP.h (struct Dwarf): Add alt_fd field.
+	(filepath): Declare new internal function.
+
+2018-01-14  Petr Machata  <pmachata@gmail.com>
+
+	* dwarf_formsdata.c (dwarf_formsdata):
+	<DW_FORM_data1>: Cast to signed char.
+	<DW_FORM_data2,4,8>: Use read_*sbyte_unaligned instead of
+	read_*ubyte_unaligned.
+
+2017-12-26  Mark Wielaard  <mark@klomp.org>
+
+	* libdwP.h (struct Dwarf_Abbrev): Pack struct. Remove attrcnt,
+	use bitfields for has_children and code.
+	* dwarf_getabbrev.c (__libdw_getabbrev): Don't count attrs.
+	* dwarf_getattrcnt.c (dwarf_getattrcnt): Count attrs.
+
+2017-12-26  Mark Wielaard  <mark@klomp.org>
+
+	* memory-access.h (__libdw_get_uleb128_unchecked): New function.
+	(get_uleb128_unchecked): New define.
+	* dwarf_child.c (__libdw_find_attr): Use get_uleb128_unchecked to
+	read attr name and form.
+	* dwarf_getabbrevattr.c (dwarf_getabbrevattr): Likewise.
+	* dwarf_getattrs.c (dwarf_getattrs): Likewise.
+	* dwarf_hasattr.c (dwarf_hasattr): Likewise.
+
+2017-12-28  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf_offdie.c (__libdw_offdie): Check sectiondata exists.
+
+2017-05-09  Ulf Hermann  <ulf.hermann@qt.io>
+	    Mark Wielaard  <mark@klomp.org>
+
+	* libdwP.h (__libdw_in_section): Fix check for the upper border of
+	the range.
+	(__libdw_offset_in_section): Likewise.
+
+2017-12-20  Mark Wielaard  <mark@klomp.org>
+
+	* libdwP.h (struct Dwarf_CU): Add sec_idx field.
+	(cu_sec_idx): Return cu->sec_idx.
+	* libdw_findcu.c (__libdw_intern_next_unit): Set cu sec_idx to
+	IDX_debug_info or IDX_debug_types.
+	* dwarf_begin_elf.c (valid_p): Set fake_loc_cu->sec_idx to
+	IDX_debug_loc.
+	* dwarf_getmacros.c (read_macros): Set fake_cu->sec_idx to
+	IDX_debug_macro or IDX_debug_macinfo.
+
+2017-12-12  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf_aggregate_size.c (dwarf_aggregate_size): Don't peel the
+	given DIE. Reserve memory for a new DIE first.
+
+2017-12-11  Dima Kogan  <dima@secretsauce.net>
+
+	* dwarf_aggregate_size.c (array_size): Handle multi-dimensional
+	arrays properly.
+
+2017-11-03  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf_getlocation.c (__libdw_intern_expression): Handle
+	DW_OP_GNU_variable_value.
+	* dwarf_getlocation_attr.c (dwarf_getlocation_attr): Likewise.
+	* dwarf_getlocation_die.c (dwarf_getlocation_die): Likewise.
+
+2017-11-03  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf_getlocation.c (attr_ok): Always accept DW_FORM_exprloc.
+	Update list of acceptable attribute codes based on DWARF5.
+
+2017-11-03  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf.h: Add DW_OP_GNU_variable_value.
+
+2017-10-03  Mark Wielaard  <mark@klomp.org>
+
+	* libdw.h: Define LIBDW_CIE_ID and use it in dwarf_cfi_cie_p.
+
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* memory-access.h: Use attribute_packed.
+
+2017-02-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* libdwP.h: Use attribute_hidden.
+	* libdw_alloc.c: Likewise.
+
+2017-02-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf.h: Add DW_MACRO_* and compat defines for DW_MACRO_GNU_*.
+	* dwarf_getmacros.c (get_table_for_offset): Accept either version
+	4 or 5. Use DW_MACRO names instead of DW_MACRO_GNU names.
+	(read_macros): Use table version for fake_cu.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf_peel_type.c (dwarf_peel_type): Handle DW_TAG_immutable_type,
+	DW_TAG_packed_type and DW_TAG_shared_type.
+	* libdw.h (dwarf_peel_type): Extend documentation.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf.h: Add DW_DEFAULTED_no, DW_DEFAULTED_in_class and
+	DW_DEFAULTED_out_of_class.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf.h: Add DW_CC_pass_by_reference and DW_CC_pass_by_reference.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf_default_lower_bound.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_default_lower_bound.c.
+	* dwarf_aggregate_size.c (array_size): Use dwarf_default_lower_bound.
+	* dwarf_error.c (errmsgs): Add DWARF_E_UNKNOWN_LANGUAGE.
+	* libdw.h: Add dwarf_default_lower_bound.
+	* libdw.map (ELFUTILS_0.170): Add dwarf_default_lower_bound.
+	* libdwP.h: Add DWARF_E_UNKNOWN_LANGUAGE and
+	dwarf_default_lower_bound INTDECL.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf.h: Add DW_LANG_OpenCL, DW_LANG_Modula3,
+	DW_LANG_C_plus_plus_03, DW_LANG_OCaml, DW_LANG_Rust, DW_LANG_Swift,
+	DW_LANG_Julia, DW_LANG_Dylan, DW_LANG_RenderScript, DW_LANG_BLISS.
+	* dwarf_aggregate_size.c (array_size): Add lower bound for
+	DW_LANG_C_plus_plus_03, DW_LANG_Python, DW_LANG_OpenCL,
+	DW_LANG_Haskell, DW_LANG_OCaml, DW_LANG_Rust, DW_LANG_Swift,
+	DW_LANG_Dylan, DW_LANG_RenderScript, DW_LANG_Modula3,
+	DW_LANG_Julia and DW_LANG_BLISS.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf.h: Add DW_ATE_UCS and DW_ATE_ASCII.
+
+2017-07-25  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf.h: Add DW_TAG_coarray_type, DW_TAG_generic_subrange,
+	DW_TAG_dynamic_type, DW_TAG_call_site, DW_TAG_call_site_parameter,
+	DW_TAG_skeleton_unit, DW_TAG_immutable_type. Add reserved comments
+	for currently unused numbers.
+
+2017-07-25  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf.h (DWARF attributes enum): Remove DW_AT_subscr_data,
+	DW_AT_element_list and DW_AT_member. Add DWARF5 attribute constants.
+	(DW_AT_subscr_data, DW_AT_element_list, DW_AT_member): New defines.
+
+2017-07-21  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf_line_file.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_line_file.c.
+	* libdw.h (dwarf_line_file): New function declaration.
+	* libdw.map (ELFUTILS_0.170): New. Add dwarf_line_file.
+
+2017-02-17  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Add libdw_so_LIBS to specify the archives libdw is is
+	made of, libdw_so_DEPS for libraries it depends on (including
+	libeu.a), libdw_so_LDLIBS to specify libraries libdw links against.
+	(libdw.so$(EXEEXT)): Add $(libdw_so_LDLIBS), remove enumeration of
+	library dependencies, use libdw_so_LIBS rather than relying on the
+	order of dependencies specified, add -z,relro.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* libdw.h: Remove attribute macro declarations and use
+	__noreturn_attribute__ as defined in libelf.h.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* dwarf_begin_elf.c: Include endian.h.
+
+2017-03-30  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_peel_type.c (dwarf_peel_type): Call dwarf_attr_integrate on
+	result.
+
+2016-10-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Correct spelling of DW_LANG_PLI. Add compatibility define.
+	* dwarf_aggregate_size.c (array_size): Use correct spelling of
+	DW_LANG_PLI.
+
+2016-11-02  Mark Wielaard  <mjw@redhat.com>
+
+	* cfi.c (execute_cfi): Add fallthrough comments.
+	* encoded-value.h (encoded_value_size): Add explicit return instead
+	of relying on fallthrough.
+	* dwfl_report_elf.c (__libdwfl_elf_address_range): Add fallthrough
+	comment.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* dwarf_getpubnames.c: Remove sys/param.h include, add system.h.
+	* libdw_alloc.c: Likewise.
+
+2016-07-08  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw.map (ELFUTILS_0.167): New. Add dwelf_strtab_init,
+	dwelf_strtab_add, dwelf_strtab_add_len, dwelf_strtab_finalize,
+	dwelf_strent_off, dwelf_strent_str and dwelf_strtab_free.
+
+2016-02-13  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (read_srclines): Calculate ndirs first, then
+	assign to ndirlist.
+
+2015-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwP.h (struct Dwarf): Remove sectiondata_gzip_mask.
+	(__libdw_free_zdata): Remove.
+	* dwarf_begin_elf.c (inflate_section): Remove.
+	(check_section): Remove __libdw_free_zdata calls. Use elf_compress
+	and elf_compress_gnu to decompress if necessary.
+	(valid_p): Remove __libdw_free_zdata calls.
+	(scngrp_read): Use elf_compress if section is compressed. Remove
+	__libdw_free_zdata calls.
+	* dwarf_end.c (__libdw_free_zdata): Remove.
+	(dwarf_end): Don't call __libdw_free_zdata.
+
+2015-10-28  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw.map (ELFUTILS_0.165): New. Add dwelf_scn_gnu_compressed_size.
+
+2015-12-02  Mark Wielaard  <mjw@redhat.com>
+
+	* fde.c (intern_fde): Don't leak duplicate FDEs.
+
+2015-12-01  Mark Wielaard  <mjw@redhat.com>
+
+	* fde.c (intern_fde): Don't intern an fde that doesn't cover a
+	valid code range.
+
+2015-12-01  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_end.c (dwarf_end): Call cu_free on fake_loc_cu if it exists.
+
+2015-10-14  Chih-Hung Hsieh  <chh@google.com>
+
+	* dwarf_entry_breakpoints.c (dwarf_entry_breakpoints): Move recursive
+	functions 'add_bkpt', 'entrypc_bkpt', and 'search_range' to file scope.
+
+2015-10-14  Chih-Hung Hsieh  <chh@google.com>
+
+	* libdw_visit_scopes.c (__libdw_visit_scopes): Move recursive nested
+	function 'walk_children' to file scope; inline 'recurse' at its call
+	site.
+
+2015-10-19  Mark Wielaard  <mjw@redhat.com>
+
+	* frame-cache.c (__libdw_destroy_frame_cache): Call ebl_closebackend
+	if necessary.
+
+2015-10-16  Dmitry V. Levin  <ldv@altlinux.org>
+
+	* dwarf_getsrclines.c (read_srclines): Initialize state early.
+
+2015-10-13  Chih-Hung Hsieh  <chh@google.com>
+
+	* dwarf_getsrclines.c (read_srclines): Move nested functions
+	'advance_pc' and 'add_new_line' to file scope and keep many
+	local state variables within one structure.
+
+2015-10-13  Chih-Hung Hsieh  <chh@google.com>
+
+	* dwarf_getscopevar.c (dwarf_getscopevar): Move nested
+	function 'file_matches' to file scope.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libdw.so): Add -lz.
+
+2015-10-14  Chih-Hung Hsieh  <chh@google.com>
+
+	* cfi.c (execute_cfi): Move nested functions 'enough_registers'
+	and 'require_cfa_offset' to file scope.
+
+2015-10-09  Josh Stone  <jistone@redhat.com>
+
+	* dwarf_begin.c (dwarf_begin): Replace stat64 and fstat64 with stat
+	and fstat.
+
+2015-10-05  Josh Stone  <jistone@redhat.com>
+
+	* Makefile.am (libdw.so): Add AM_V_CCLD and AM_V_at silencers.
+
+2015-09-24  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid
+	relocation overflows in some platforms.
+
+2015-09-23  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_error.c (__libdw_seterrno): Mark as internal_function.
+	* dwarf_formref.c (__libdw_formref): Likewise.
+	* libdw_findcu.c (__libdw_findcu): Likewise.
+	* libdw_visit_scopes.c (__libdw_visit_scopes): Likewise.
+
+2015-09-22  Mark Wielaard  <mjw@redhat.com>
+
+	* *.c: Remove old-style function definitions.
+
+2015-09-15  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_peel_type.c (dwarf_peel_type): Don't reassign result pointer.
+
+2015-09-09  Chih-Hung Hsieh  <chh@google.com>
+
+	* dwarf_macro_getsrcfiles.c (dwarf_macro_getsrcfiles): Remove
+	redundant NULL tests on parameters declared with __nonnull_attribute__.
+	* dwarf_siblingof.c (dwarf_siblingof): Likewise.
+	* libdw_visit_scopes.c (__libdw_visit_scopes): Likewise.
+
+2015-09-04  Chih-Hung Hsieh  <chh@google.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getlocation.c (getlocations_addr): Replace K&R function
+	definition with ansi-C definition and add const qualifier to
+	locs argument.
+
+2015-09-04  Chih-Hung Hsieh  <chh@google.com>
+
+	* libdw_findcu.c (__libdw_intern_next_unit): Replace K&R function
+	definition with ansi-C definitions.
+	(__libdw_findcu): Likewise.
+
+2015-08-25  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Add DW_LANG_Haskell.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_begin_elf.c (dwarf_begin_elf): Assert page size is big enough
+	to hold a Dwarf.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getpubnames.c (get_offsets): Always free mem on error.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getmacros.c (get_macinfo_table): Return NULL when
+	dwarf_formudata reports an error.
+	(get_table_for_offset): Likewise.
+
+2015-06-08  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (read_srclines): Initialize dirarray early.
+
+2015-06-06  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (read_srclines): Initialize filelist early.
+
+2015-05-27  Mark Wielaard  <mjw@redhat.com>
+
+	* encoded-value.h (read_encoded_value): Check data d_size contains
+	at least enough data to hold a pointer for DW_EH_PE_indirect.
+
+2015-05-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (read_srclines): Limit stack usage of lines
+	with MAX_STACK_LINES, files with MAX_STACK_LINES and dirs with
+	MAX_STACK_DIRS. Calculate number of dirs needed first, then
+	create dirarray directly, without needing the next field. Free
+	not stack allocated lines and files at the end.
+
+2015-05-19  Mark Wielaard <mjw@redhat.com>
+
+	* dwarf_getlocation.c (__libdw_intern_expression): Create a stack
+	allocated array to hold locs. Allocate locs bigger than the array
+	with malloc and free them when done.
+
+2015-05-11  Jonathan Lebon  <jlebon@redhat.com>
+
+	* libdwP.h (DWARF_E_COMPRESSED_ERROR): New enumerator.
+	* dwarf_error.c (errmsgs): Add DWARF_E_COMPRESSED_ERROR message.
+	* dwarf_begin_elf.c (inflate_section): New static function, lifted
+	from...
+	(check_section): ... here. Call inflate_section, set libdw errno to
+	DWARF_E_COMPRESSED_ERROR if .debug_info section couldn't be inflated.
+
+2015-05-11  Jonathan Lebon  <jlebon@redhat.com>
+
+	* dwarf_begin_elf.c (check_section): Add compressed flag. Always
+	check for .zdebug sections. Only wrap decompression in #if USE_ZLIB.
+
+2015-05-06  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (read_srclines): Use an int64_t to store and
+	check the line number.
+
+2015-05-05  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getaranges.c (dwarf_getaranges): Check there is enough data
+	left before reading values.
+
+2015-05-04  Anthony G. Basile  <blueness@gentoo.org>
+
+	* Makefile.am (libdw_so_SOURCES): Append $(argp_LDADD) to link
+	command.
+
+2015-04-22  Mark Wielaard  <mjw@redhat.com>
+
+	* memory-access.h (__libdw_max_len_leb128): Take type_len as argument.
+	(__libdw_max_len_uleb128): New function.
+	(__libdw_max_len_sleb128): Likewise.
+	(__libdw_get_uleb128): Use __libdw_max_len_uleb128.
+	(__libdw_get_sleb128): Use __libdw_max_len_sleb128.
+
+2015-04-21  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getmacros.c (read_macros): Allocate attributes dynamically
+	when there are more than 8.
+
+2015-04-01  Petr Machata  <pmachata@redhat.com>
+
+	* libdwP.h (DWARF_E_NOT_CUDIE): New enumerator.
+	(is_cudie): New function.
+	* dwarf_error.c (errmsgs): Add message for DWARF_E_NOT_CUDIE.
+	* dwarf_getsrcfiles.c (dwarf_getsrcfiles): Call is_cudie instead
+	of white-listing valid tags.
+	* dwarf_getsrclines.c (dwarf_getsrclines): Likewise.
+
+2015-03-18  Petr Machata  <pmachata@redhat.com>
+
+	* Makefile.am (pkginclude_HEADERS): Add known-dwarf.h.
+	(EXTRA_DIST): Remove known-dwarf.h.
+
+2015-02-09  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Add DW_LANG_Fortran03 and DW_LANG_Fortran08.
+	* dwarf_aggregate_size.c (array_size): Recognize array lower bound
+	for new Fortran language codes is 1.
+
+2015-02-09  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Add DW_TAG_atomic_type.
+	* libdw.h (dwarf_peel_type): Document DW_TAG_atomic_type.
+	* dwarf_peel_type.c (dwarf_peel_type): Handle DW_TAG_atomic_type.
+
+2015-02-11  Josh Stone  <jistone@redhat.com>
+
+	* encoded-value.h (read_encoded_value): Initialize value.
+
+2015-02-11  Petr Machata  <pmachata@redhat.com>
+
+	* dwarf_ranges.c (dwarf_ranges): Do not bail out when neither
+	DW_AT_entry_pc nor DW_AT_low_pc are available.  Instead remember
+	the fact in *BASEP and bail out later if it hasn't been updated by
+	__libdw_read_begin_end_pair_inc.
+
+2014-12-24  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrc_die.c (dwarf_getsrc_die): Return the last line record
+	smaller than or equal to addr, rather than returning immediately on
+	a match.
+
+2015-01-07  Mark Wielaard  <mjw@redhat.com>
+
+	* cfi.h (struct Dwarf_CFI_s): Add search_table_len.
+	* dwarf_getcfi_elf.c (getcfi_gnu_eh_frame): Check there is enough
+	room in the search table for all entries. Store search_table_len.
+	(getcfi_scn_eh_frame): Likewise.
+	* encoded-value.h (encoded_value_size): Don't abort, return zero.
+	(__libdw_cfi_read_address_inc): Check there is enough room to read
+	values. Pass other byte order to read functions.
+	(read_encoded_value): Check encoded_value_size. Don't abort, but
+	set libdw errno and report failure. Check there is enough room to
+	read values.
+	* fde.c (binary_search_fde): Check encoded value size. Add hdr
+	data buf and size to dummy_cfi.
+
+2015-01-04  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_siblingof.c (dwarf_siblingof): Check sibling attribute
+	is after current DIE.
+
+2015-01-04  Mark Wielaard  <mjw@redhat.com>
+
+	* cfi.c (enough_registers): Check reg < INT32_MAX / sizeof
+	(dwarf_frame_register).
+
+2015-01-02  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getcfi_elf.c (parse_eh_frame_hdr): Add size check.
+	(getcfi_gnu_eh_frame): Remove size check. Check d_buf is not NULL.
+	(getcfi_scn_eh_frame): Check d_buf is not NULL.
+
+2015-01-02  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getlocation.c (__libdw_intern_expression): Check dbg is not
+	NULL for DW_OP_call_ref and DW_OP_GNU_implicit_pointer. For
+	DW_OP_addr if dbg is NULL then read argument directly.
+
+2015-01-14  Jason P. Leasure <jpleasu@super.org>
+
+	* dwarf_formref_die.c (dwarf_formref_die): Offset is cu->type_offset
+	plus cu->start.
+
+2014-12-27  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_siblingof.c (dwarf_siblingof): Check sibling attribute offset
+	still falls inside CU data.
+
+2015-01-11  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_func_inline.c (dwarf_func_inline_instances): Call
+	__libdw_visit_scopes with NULL imports.
+	* dwarf_getfuncs.c (dwarf_getfuncs): Likewise.
+	* dwarf_getscopes.c (pc_record): Likewise.
+	(dwarf_getscopes): Likewise.
+	* dwarf_getscopes_die.c (dwarf_getscopes_die): Likewise.
+	* libdwP.h (__libdw_visit_scopes): Add imports argument.
+	* libdw_visit_scopes.c (__libdw_visit_scopes): Likewise. Add new
+	function imports_contains. Push and pop imports around walk_children
+	when processing DW_TAG_imported_unit.
+
+2014-12-18  Ulrich Drepper  <drepper@gmail.com>
+
+	* Makefile.am: Suppress output of textrel_check command.
+
+2014-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (read_srclines): Check diridx is valid under
+	DW_LNE_define_file.
+
+2014-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getpubnames.c (dwarf_getpubnames): Make sure there is enough
+	space to read die offset.
+
+2014-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (read_srclines): Correct overflow check for
+	unit_length.
+
+2014-12-15  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getpubnames.c (get_offsets): Make sure whole unit fall inside
+	section data. Set error to DWARF_E_NO_ENTRY if cnt is zero.
+	(dwarf_getpubnames): Make sure section data contains string zero
+	terminator.
+
+2014-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* memory-access.h (__libdw_get_sleb128): Unroll the first step to help
+	the compiler optimize for the common single-byte case.
+
+2014-12-15  Josh Stone  <jistone@redhat.com>
+
+	* memory-access.h (__libdw_max_len_leb128): New.
+	(__libdw_get_uleb128): Use __libdw_max_len_leb128.
+	(__libdw_get_sleb128): Likewise.
+
+2014-12-14  Mark Wielaard  <mjw@redhat.com>
+
+	* cfi.c (execute_cfi): Add program bounds checks.
+	* dwarf_child.c (__libdw_find_attr): Add attrp bounds checks.
+	* dwarf_formblock.c (dwarf_formblock): Call get_uleb128 with endp.
+	* dwarf_formref.c (__libdw_formref): Add datap bounds checks.
+	* dwarf_formsdata.c (dwarf_formsdata): Likewise.
+	* dwarf_formudata.c (dwarf_formudata): Likewise.
+	* dwarf_frame_register.c (dwarf_frame_register): Call get_uleb128
+	with end of data buf.
+	* dwarf_getabbrev.c (__libdw_getabbrev): Add abbrevp bounds checks.
+	* dwarf_getabbrevattr.c (dwarf_getabbrevattr): Assume get_uleb128
+	call gets enough data.
+	* dwarf_getattrs,c (dwarf_getattrs): Call get_uleb128 with endp.
+	* dwarf_getlocation.c (store_implicit_value): Call get_uleb128
+	with enough data.
+	(__libdw_intern_expression): Call get_uleb128/get_sleb128 with
+	end_data.
+	* dwarf_getmacros.c (get_table_for_offset): Add nforms bounds check.
+	* dwarf_getsrclines.c (read_srclines): Bounds check linep and call
+	get_uleb128 with lineendp.
+	* dwarf_hasattr.c (dwarf_hasattr): Bounds check attrp and call
+	get_uleb128 with endp.
+	* dwarf_next_cfi.c (dwarf_next_cfi): Bounds check bytes and call
+	get_uleb128/get_sleb128 with limit.
+	* encoded-value.h (read_encoded_value): Assume get_uleb128 and
+	get_sleb128 get called with enough data.
+	* fde.c (intern_fde): Call get_uleb128 with instructions_end.
+	* libdwP.h (__libdw_dieabbrev): Call get_uleb128 with die->cu->endp.
+	* libdw_form.c (__libdw_form_val_compute_len): Call get_uleb128 with
+	endp.
+	* memory-access.h (__libdw_get_uleb128): Take an extra endp.
+	Don't call get_uleb128_step if out of data.
+	(__libdw_get_sleb128): Likewise for get_sleb128_step.
+
+2014-12-12  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwP.h (struct Dwarf): Add fake_loc_cu.
+	(cu_data): Removed.
+	(DIE_OFFSET_FROM_CU_OFFSET): Don't use cu_data, use cu_sec_idx.
+	(__libdw_form_val_compute_len): Drop dbg and endp arguments.
+	(__libdw_form_val_len): Likewise.
+	* libdw_form.c (__libdw_form_val_compute_len): Likewise.
+	* libdw_findcu.c (__libdw_intern_next_unit): Don't use cu_data, use
+	the already found data buffer directly.
+	* dwarf_begin_elf.c (valid_p): Setup fake_loc_cu.
+	* dwarf_end.c (dwarf_end): Free fake_loc_cu.
+	* dwarf_child.c (__libdw_find_attr): Call __libdw_form_val_len with
+	just cu.
+	* dwarf_getattrs.c (dwarf_getattrs): Likewise.
+	* dwarf_formblock.c (dwarf_formblock): Add bounds checking.
+	* dwarf_getlocation_attr.c (attr_form_cu): New function.
+	(dwarf_getlocation_attr): Use attr_form_cu to set result->cu.
+	(getlocation): Handle empty blocks immediately.
+	* dwarf_getlocation_implicit_pointer.c (empty_cu): New static var.
+	(__libdw_empty_loc_attr): Drop cu argument, use empty_cu.
+	(dwarf_getlocation_implicit_pointer): Call __libdw_empty_loc_attr with
+	one argument.
+	* dwarf_getmacros.c (read_macros): Also setup startp and endp for
+	fake_cu. Call __libdw_form_val_len with just fake_cu.
+	* dwarf_formref_die.c (dwarf_formref_die): Don't use cu_data, get
+	datap and size directly from cu startp and endp.
+
+2014-12-11  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw_findcu.c (__libdw_intern_next_unit): Sanity check offset.
+
+2014-12-13  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getaranges.c (compare_aranges): Make sure Dwarf_Addr
+	difference doesn't wrap around before returning as int.
+
+2014-12-11  Josh Stone  <jistone@redhat.com>
+
+	* dwarf_getsrclines.c (struct linelist): Add sequence.
+	(compare_lines): Take linelists, and break ties by sequence.
+	(read_srclines): Use linelists for sorting.
+	(read_srclines::add_new_line): Set sequence.
+
+2014-12-10  Josh Stone  <jistone@redhat.com>
+
+	* libdwP.h (Dwarf_CU): Add startp and endp boundaries.
+	* libdw_findcu.c (__libdw_intern_next_unit): Set startp and endp.
+	* dwarf_child.c (dwarf_child): Use cu->endp.
+	* dwarf_cuoffset.c (dwarf_cuoffset): Use cu->startp.
+	* dwarf_dieoffset.c (dwarf_dieoffset): Use cu->startp.
+	* dwarf_siblingof.c (dwarf_siblingof): Use both.
+
+2014-12-10  Josh Stone  <jistone@redhat.com>
+
+	* dwarf_hasattr.c (dwarf_hasattr): Just walk abbrev for presence.
+
+2014-12-10  Josh Stone  <jistone@redhat.com>
+
+	* libdwP.h (__libdw_dieabbrev): New die->abbrev lookup function.
+	* dwarf_child.c (__libdw_find_attr, dwarf_child): Use it.
+	* dwarf_getattrs.c (dwarf_getattrs): Likewise.
+	* dwarf_haschildren.c (dwarf_haschildren): Likewise.
+	* dwarf_tag.c (dwarf_tag): Likewise.
+
+2014-12-04  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwP.h (__libdw_form_val_compute_len): Add endp argument.
+	(__libdw_form_val_len): Likewise and check len doesn't overflow.
+	* libdw_form.c (__libdw_form_val_compute_len): Likewise.
+	* dwarf_child.c (__libdw_find_attr): Call __libdw_form_val_len
+	with endp.
+	* dwarf_getattrs.c (dwarf_getattrs): Likewise.
+	* dwarf_getmacros.c (read_macros): Likewise and check for errors.
+
+2014-12-02  Petr Machata  <pmachata@redhat.com>
+
+	* dwarf_getmacros.c (token_from_offset, offset_from_token): New
+	helper functions.
+	(do_dwarf_getmacros_die): Merge into dwarf_getmacros.
+	* libdw.h (DWARF_GETMACROS_START): New macro.
+
+2014-11-27  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libdw.so): Use textrel_check.
+
+2014-11-27  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getcfi_elf.c (getcfi_gnu_eh_frame): Initialize
+	search_table_entries and search_table_encoding.
+
+2014-11-24  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (read_srclines): Check line_range is not zero
+	before usage.
+
+2014-11-23  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_attr.c (dwarf_attr): Check __libdw_find_attr return value.
+	* dwarf_hasattr.c (dwarf_hasattr): Likewise.
+	* dwarf_siblingof.c (dwarf_siblingof): Likewise.
+
+2014-11-23  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getabbrev.c (__libdw_getabbrev): Don't assert on bad DWARF.
+	Set libdw errno and return NULL.
+
+2014-11-24  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h (DW_LANG_C_plus_plus_11): Added.
+	(DW_LANG_C11): Likewise.
+	(DW_LANG_C_plus_plus_14): Likewise.
+	* dwarf_aggregate_size.c (array_size): Handle DW_LANG_C11,
+	DW_LANG_C_plus_plus_11, DW_LANG_C_plus_plus_14 and DW_LANG_Go
+	lower bound.
+	* dwarf_getfuncs.c (dwarf_getfuncs): Set c_cu to true for
+	DW_LANG_C11.
+
+2014-11-26  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h (DW_AT_noreturn): Added.
+
+2014-11-11  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (read_srclines): Do address_size comparison
+	explicitly as uint8_t.
+	(__libdw_getsrclines): Add internal_function to declaration.
+
+2014-09-10  Petr Machata  <pmachata@redhat.com>
+
+	* dwarf_macro_getparamcnt.c: New file.
+	* dwarf_macro_param.c: New file.
+	* dwarf_macro_getsrcfiles.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add the new files.
+	* libdwP.h (struct files_lines_s): New structure.
+	(DWARF_E_INVALID_OPCODE): New enumerator.
+	(struct Dwarf): New fields macro_ops, files_lines.
+	(Dwarf_Macro_Op_Proto, Dwarf_Macro_Op_Table): New structures for
+	keeping macro opcode prototypes in.
+	(Dwarf_Macro_s): Redefine from scratch.
+	(__libdw_getsrclines, __libdw_getcompdir, libdw_macro_nforms): New
+	internal interfaces.
+	* dwarf_error.c (errmsgs): Add a message for
+	DWARF_E_INVALID_OPCODE.
+	* dwarf_end.c (dwarf_end): Destroy struct Dwarf.macro_ops and
+	files_lines.
+	* libdw.h (dwarf_getmacros_off, dwarf_macro_getparamcnt)
+	(dwarf_macro_getsrcfiles, dwarf_macro_param): New public
+	interfaces.
+	* dwarf_getmacros.c (dwarf_getmacros_off): New function,
+	(get_offset_from, macro_op_compare, build_table)
+	(init_macinfo_table, get_macinfo_table, get_table_for_offset)
+	(cache_op_table, read_macros, gnu_macros_getmacros_off)
+	(macro_info_getmacros_off, do_dwarf_getmacros_die): New helper
+	functions.
+	(dwarf_getmacros): Adjust to dispatch to the new interfaces.
+	* dwarf_getsrclines.c (read_srclines): New function with guts
+	taken from dwarf_getsrclines.
+	(__libdw_getsrclines): Likewise.
+	(__libdw_getcompdir, files_lines_compare): New functions.
+	(dwarf_getsrclines): Make it dispatch to the new interfaces.
+	* dwarf_macro_param1.c (dwarf_macro_param1): Adjust to dispatch to
+	the new interfaces.
+	* dwarf_macro_param2.c (dwarf_macro_param2): Likewise.
+	* libdw.map (ELFUTILS_0.161): New. Add dwarf_getmacros_off,
+	dwarf_macro_getsrcfiles, dwarf_macro_getparamcnt, dwarf_macro_param.
+
+2014-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_peel_type.c.
+	* dwarf_aggregate_size.c (get_type): Use dwarf_peel_type.
+	(aggregate_size): Likewise. Add old and new version.
+	* dwarf_peel_type.c: New file.
+	* libdw.h (dwarf_peel_type): New function declaration.
+	* libdwP.h (dwarf_peel_type): New internal declaration.
+	* libdw.map (ELFUTILS_0.161): New section.
+
+2014-10-15  Petr Machata  <pmachata@redhat.com>
+
+	* libdwP.h (struct Dwarf_Files_s.cu): Drop field.
+	* dwarf_getsrclines.c (dwarf_getsrclines): Don't set it.
+
+2014-10-05  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Add DW_AT_GNU_deleted.
+
+2014-10-02  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_aggregate_size.c (aggregate_size): Return CU address_size
+	for sizeless DW_TAG_pointer_type, DW_TAG_reference_type or
+	DW_TAG_rvalue_reference_type.
+
+2014-09-12  Petr Machata  <pmachata@redhat.com>
+
+	* memory-access.h (read_ubyte_unaligned_inc): Allow only 4- and
+	8-byte quantities.  Consequently, rename to...
+	(read_addr_unaligned_inc): ... this.
+	(read_sbyte_unaligned_inc, read_ubyte_unaligned): Drop.
+	(read_sbyte_unaligned): Drop.
+
+2014-09-10  Petr Machata  <pmachata@redhat.com>
+
+	* dwarf_getlocation.c (attr_ok): Also accept
+	DW_AT_GNU_call_site_value, DW_AT_GNU_call_site_data_value,
+	DW_AT_GNU_call_site_target, DW_AT_GNU_call_site_target_clobbered.
+
+2014-08-15  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_cu_die.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_cu_die.c.
+	* libdw.h (dwarf_cu_die): New function declaration.
+	* libdw.map (ELFUTILS_0.160): Add dwarf_cu_die.
+
+2014-08-15  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_cu_getdwarf.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_cu_getdwarf.c.
+	* libdw.h (Dwarf_CU): New typedef.
+	(dwarf_cu_getdwarf): New function declaration.
+	* libdw.map (ELFUTILS_0.160): New. Add dwarf_cu_getdwarf.
+
+2014-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Remove DW_TAG_mutable_type.
+
+2014-05-02  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwP.h (__check_build_id): Removed now unused.
+
+2014-05-01  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwP.h (struct Dwarf): Remove free_alt.
+	* dwarf_end.c (dwarf_end): Don't check free_alt, don't end alt_dwarf.
+	* dwarf_setalt.c (dwarf_setalt): Don't check or set free_alt.
+
+2014-04-30  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw.map (ELFUTILS_0.159): Add dwelf_elf_gnu_build_id.
+
+2014-04-15  Florian Weimer  <fweimer@redhat.com>
+
+	* dwarf_begin_elf.c (__check_build_id, try_debugaltlink)
+	(open_debugaltlink): Move to libdwfl.
+	(check_section): Do not locate alternate debuginfo.
+
+2014-04-24  Florian Weimer  <fweimer@redhat.com>
+
+	* libdw.map (ELFUTILS_0.159): Export dwelf_dwarf_gnu_debugaltlink.
+
+2014-04-22  Florian Weimer  <fweimer@redhat.com>
+
+	* dwarf_getalt.c, dwarf_setalt.c: New files.
+	* Makefile.am (libdw_a_SOURCES): Add them.
+	* libdw.h (dwarf_getalt, dwarf_setalt): Add function declarations.
+	* libdwP.h (dwarf_getalt, dwarf_setalt): Add internal function
+	declarations.
+	* libdw.map (ELFUTILS_0.159): Export the two new functions.
+
+2014-04-15  Florian Weimer  <fweimer@redhat.com>
+
+	* libdwP.h (enum IDX_gnu_debugaltlink): New.
+	* dwarf_begin_elf.c (dwarf_scnnames): Increase string size and add
+	.gnu_debugaltlink.
+	(check_section): Obtain .gnu_debugaltlink section from the
+	setiondata array.
+
+2014-04-11  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw.map (ELFUTILS_0.159): New. Add dwelf_elf_gnu_debuglink.
+	* Makefile.am (libdw.so): Depend on libdwelf_pic.a.
+	(libdwelf_objects): New variable.
+	(libdw_a_LIBADD): Add libdwelf objects.
+
+2014-04-22  Mark Wielaard  <mjw@redhat.com>
+
+	* memory-access.h (get_sleb128_step): Remove undefined behavior
+	of left shifting a signed value. Replace it with a multiplication.
+
+2014-04-13  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Remove !MUDFLAP conditions.
+
+2014-04-09  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_begin_elf.c (check_section): Check for unsigned overflow
+	before calling malloc to uncompress data.
+
+2014-03-03  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Fix abort() on missing section headers.
+	* dwarf_begin_elf.c (check_section): Replace abort call by goto err.
+	New label err to return NULL.
+
+2014-02-05  Josh Stone  <jistone@redhat.com>
+
+	* dwarf_decl_file.c (dwarf_decl_file): Read the idx as unsigned.
+	* dwarf_decl_line.c (__libdw_attr_intval): Read the line/column as
+	unsigned.  Change the range assert to DWARF_E_INVALID_DWARF.
+
+2013-12-30  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw.map (ELFUTILS_0.158): Add dwfl_core_file_attach and
+	dwfl_linux_proc_attach.
+
+2013-12-20  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw.map (ELFUTILS_0.158): Add dwfl_getthread_frames.
+
+2013-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw.map (ELFUTILS_0.158): Remove dwfl_module_addrsym_elf and
+	dwfl_module_getsym_elf. Add dwfl_module_addrinfo and
+	dwfl_module_getsym_info.
+
+2013-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw.map (ELFUTILS_0.158): Add dwfl_module_getsymtab_first_global.
+
+2013-12-10  Josh Stone  <jistone@redhat.com>
+
+	* memory-access.h (get_uleb128_rest_return): Removed.
+	(get_sleb128_rest_return): Removed.
+	(get_uleb128_step): Make this a self-contained block.
+	(get_sleb128_step): Ditto, and use a bitfield to extend signs.
+	(get_uleb128): Make this wholly implemented by __libdw_get_uleb128.
+	(get_sleb128): Make this wholly implemented by __libdw_get_sleb128.
+	(__libdw_get_uleb128): Simplify and inline for all callers.
+	(__libdw_get_sleb128): Ditto.
+	* dwarf_getlocation.c (store_implicit_value): Void the unused uleb128.
+	* memory-access.c: Delete file.
+	* Makefile.am (libdw_a_SOURCES): Remove it.
+	(DEFS): Remove the now unused -DIS_LIBDW.
+
+2013-12-09  Josh Stone  <jistone@redhat.com>
+
+	* libdw_form.c (__libdw_form_val_compute_len): Renamed function from
+	__libdw_form_val_len, now handling only non-constant form lengths.
+	* libdwP.h (__libdw_form_val_len): New inlined function.
+
+2013-12-09  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getlocation.c (__libdw_intern_expression): Handle empty
+	location expressions.
+	* dwarf_getlocation_attr.c (dwarf_getlocation_attr): When no
+	location found, return empty location expression.
+	* dwarf_getlocation_implicit_pointer.c
+	(dwarf_getlocation_implicit_pointer): Likewise.
+	(__libdw_empty_loc_attr): New internal function.
+	* libdwP.h (__libdw_empty_loc_attr): Define.
+
+2013-11-27  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw.map (ELFUTILS_0.158): Add dwfl_module_addrsym_elf and
+	dwfl_module_getsym_elf.
+
+2013-11-26  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw.map (ELFUTILS_0.156): Move dwfl_attach_state, dwfl_pid,
+	dwfl_thread_dwfl, dwfl_thread_tid, dwfl_frame_thread,
+	dwfl_thread_state_registers, dwfl_thread_state_register_pc,
+	dwfl_getthreads, dwfl_thread_getframes and dwfl_frame_pc to ...
+	(ELFUTILS_0.158): ... here.
+
+2013-11-09  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getaranges.c (dwarf_getaranges): Read segment_size and
+	check that it is zero.
+
+2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* cfi.h (struct Dwarf_Frame_s): Make the comment more specific.
+	* libdw.map (ELFUTILS_0.156): Add dwfl_attach_state, dwfl_pid,
+	dwfl_thread_dwfl, dwfl_thread_tid, dwfl_frame_thread,
+	dwfl_thread_state_registers, dwfl_thread_state_register_pc,
+	dwfl_getthreads, dwfl_thread_getframes and dwfl_frame_pc.
+
+2013-11-01  Michael Forney  <mforney@mforney.org>
+
+	* Makefile.am (libdwfl_objects): New definition.
+	(libdw_a_LIBADD): Use libdwfl_objects.
+
+2013-11-01  Michael Forney  <mforney@mforney.org>
+
+	* Makefile.am: Use READELF.
+
+2013-10-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* libdw.map (ELFUTILS_0.158): New.
+
+2013-10-10  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getfuncs.c (struct visitor_info): Rename start_offset to
+	start_addr and rename last_offset to last_addr. Now both void *.
+	(tree_visitor): Use start_add and die_addr instead of start_offset
+	and die_offset.
+	(dwarf_getfuncs): Use last_addr instead of last_offset.
+
+2013-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* cfi.c (execute_cfi): Make sure DW_CFA_expression and
+	DW_CFA_val_expression are not used with abi_cfi.
+
+2013-10-03  Josh Stone  <jistone@redhat.com>
+
+	* dwarf_formref_die.c (dwarf_formref_die): Don't hash the sig8 here.
+	* libdw_findcu.c (__libdw_intern_next_unit): Since this never revisits
+	a unit, make sure to always hash the sig8 here, so none are missed.
+
+2013-09-29  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getlocation.c (store_implicit_value): Cast op->number2 to
+	uintptr_t before casting to char *.
+	(__libdw_intern_expression): Cast data to uintptr_t before casting
+	to Dwarf_Word.
+	* dwarf_getlocation_attr.c (dwarf_getlocation_attr): Cast
+	op->number2 to uintptr_t before casting to char *.
+
+2013-09-24  Josh Stone  <jistone@redhat.com>
+
+	* libdw_visit_scopes.c (classify_die): Removed.
+	(may_have_scopes): New function to replace classify_die.  There's no
+	need for full classification; just find tags that may contain scopes.
+	(__libdw_visit_scopes): Use a direct tag comparison for imported
+	units, and use may_have_scopes to test if recursion is needed.
+
+2013-09-20  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getfuncs.c (visitor_info): New struct.
+	(tree_visitor): New function.
+	(dwarf_getfuncs): Use __libdw_visit_scopes with tree_visitor.
+	* libdw.h (dwarf_getfuncs): Expand function documentation.
+
+2013-09-12  Mark Wielaard  <mjw@redhat.com>
+
+	* fde.c (intern_fde): Free fde and set libdw errno when start
+	or end could not be read.
+
+2013-08-24  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getlocation.c (store_implicit_value): Don't take data
+	as argument, get block data from op number2. Return false when
+	block data length and op number don't match up.
+	(__libdw_intern_expression): Store start of block for
+	DW_OP_implicit_value and DW_OP_GNU_entry_value instead of
+	relative data offset. Also store block start (including length)
+	for DW_OP_GNU_const_type. Don't pass data to store_implicit_value.
+	* dwarf_getlocation_attr.c: New file.
+	* dwarf_getlocation_die.c: Likewise.
+	* libdw.h (dwarf_getlocation_die): New function definition.
+	(dwarf_getlocation_attr): Likewise.
+	* libdwP.h: Declare internal dwarf_getlocation_die.
+	* libdw.map (ELFUTILS_0.157): Add dwarf_getlocation_die and
+	dwarf_getlocation_attr.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_getlocation_die.c and
+	dwarf_getlocation_attr.c.
+
+2013-08-23  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getlocation.c (attr_ok): Also accept DW_AT_segment.
+	(attr_base_address): New function.
+	(initial_offset_base): New function.
+	(getlocations_addr): New function. Taken from...
+	(dwarf_getlocation_addr): here. Use new initial_offset_base and
+	getlocations_addr.
+	(dwarf_getlocations): New function.
+	* libdw.h (dwarf_getlocations): New function definition.
+	* libdw.map (ELFUTILS_0.157): New.
+
+2013-07-02  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (dwarf_getsrclines): Add new stack allocation
+	limit MAX_STACK_ALLOC.  After MAX_STACK_ALLOC lines use malloc in
+	NEW_LINE macro.  Free malloced line records if any at the end.
+
+2013-07-02  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getcfi_elf.c (getcfi_shdr): Check sh_type == SHT_PROGBITS.
+
+2013-06-26  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw_visit_scopes.c (__libdw_visit_scopes): Don't reject root
+	DIEs without children. Return an error whenever dwarf_child or
+	dwarf_siblingof return an error. Don't call recurse and increase
+	the depth for an imported unit. Walk the children of an imported
+	unit as if they are logical children of the parent root DIE.
+
+2013-05-03  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (dwarf_getsrclines): Only set end_sequence
+	when nlinelist > 0.
+
+2013-04-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* libdw.map (ELFUTILS_0.156): New.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+
+2013-04-10  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_formref_die.c (dwarf_formref_die): Reference size is only
+	equal to address size when we have a DW_FORM_ref_addr for DWARF
+	version 2.
+
+2013-03-25  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrclines.c (dwarf_getsrclines): Mark highest address as
+	end_sequence.
+
+2013-03-12  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getsrcfiles.c (dwarf_getsrcfiles): Allow DW_TAG_partial_unit.
+	* dwarf_getsrclines.c (dwarf_getsrclines): Likewise.
+
+2013-02-15  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_formstring.c (dwarf_formstring): Check dbg_ret->sectiondata,
+	not dbg->sectiondata.
+
+2013-01-07  Roland McGrath  <roland@hack.frob.com>
+
+	* memory-access.h
+	[ALLOW_UNALIGNED] (read_8ubyte_unaligned_noncvt): New macro.
+	[!ALLOW_UNALIGNED] (read_8ubyte_unaligned_noncvt): New inline function.
+
+2012-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_begin_elf.c (valid_p): Call Dwarf_Sig8_Hash_free if invalid.
+	(check_section): Likewise on error.
+	(scngrp_read): Likewise.
+	(dwarf_begin_elf): Likewise.
+
+2012-10-09  Petr Machata  <pmachata@redhat.com>
+
+	* dwarf_getlocation.c (__libdw_intern_expression): Handle
+	DW_OP_GNU_parameter_ref, DW_OP_GNU_convert, DW_OP_GNU_reinterpret,
+	DW_OP_GNU_regval_type, DW_OP_GNU_entry_value,
+	DW_OP_GNU_deref_type, DW_OP_GNU_const_type.
+
+2012-10-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* cfi.c: New include system.h.
+	(execute_cfi) (enough_registers): Clear new memory after realloc.
+
+2012-10-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* fde.c (__libdw_find_fde): Change <fde != NULL> to likely.  Return
+	DWARF_E_NO_MATCH if .eh_frame_hdr points to FDE which is too short for
+	searched PC.
+
+2012-10-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwarf_getlocation.c (__libdw_intern_expression) <cfap>: Make new
+	loclist element DW_OP_call_frame_cfa before decoding the opcodes.
+	Remove the later DW_OP_call_frame_cfa push to RESULT.
+
+2012-10-08  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Code cleanup.
+	* fde.c (binary_search_fde): Remove always true <address >= start>
+	conditional.  Move L initialization upwards.
+
+2012-08-24  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_begin_elf.c (check_section): Only probe for dwz multi files
+	when ENABLE_DWZ is defined.
+	* libdwP.h (__check_build_id): Only declare when ENABLE_DWZ is
+	defined.
+
+2012-08-16  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add known-dwarf.h.
+	* dwarf.h (DW_LANG_Go): Update comment.
+	(DW_LANG_Mips_Assembler): Likewise.
+
+2012-06-27  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Add DW_FORM_GNU_ref_alt and DW_FORM_GNU_strp_alt.
+	* dwarf_begin.c (dwarf_begin): Add INTDEF.
+	* dwarf_begin_elf.c (__check_build_id): New internal_function.
+	(try_debugaltlink): New function.
+	(open_debugaltlink): Likewise.
+	(check_section): Try open_debugaltlink for .gnu_debugaltlink.
+	* dwarf_end.c (dwarf_end): Free the alternative Dwarf descriptor if
+	necessary.
+	* dwarf_error.c (errmsgs): Add DWARF_E_NO_ALT_DEBUGLINK.
+	* dwarf_formref.c (__libdw_formref): Using DW_FORM_GNU_ref_alt
+	is an error here.
+	* dwarf_formref_die.c (dwarf_formref_die): Handle DW_FORM_GNU_ref_alt.
+	* dwarf_formstring.c (dwarf_formstring): Handle DW_FORM_GNU_strp_alt.
+	* dwarf_formudata.c (__libdw_formptr): Adjust __libdw_read_offset
+	calls.
+	* dwarf_getpubnames.c (get_offsets): Adjust __libdw_read_offset call.
+	* libdwP.h: Add DWARF_E_NO_ALT_DEBUGLINK.
+	(struct Dwarf): Add alt_dwarf and free_alt fields.
+	(__libdw_read_offset): Add dbg_ret argument, use to check with
+	__libdw_offset_in_section.
+	(__check_build_id): New function declaration.
+	(dwarf_begin): Define as INTDECL.
+	* libdw_form.c (__libdw_form_val_len): Handle DW_FORM_GNU_ref_alt
+	and DW_FORM_GNU_strp_alt.
+
+2012-07-19  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Add DW_OP_GNU_parameter_ref.
+
+2012-07-24  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Correct spelling of DW_LANG_ObjC.
+	* dwarf_aggregate_size.c (array_size): Use correct spelling of
+	DW_LANG_ObjC.
+
+2012-07-24  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Add DW_ATE_UTF.
+
+2012-06-27  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Add DW_MACRO_GNU .debug_macro type encodings.
+
+2012-06-26  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwP.h: Add IDX_debug_macro.
+	* dwarf.h: Add DW_AT_GNU_macros.
+	* dwarf_begin_elf.c (dwarf_scnnames): Add .debug_macro.
+	* dwarf_formudata.c (dwarf_formudata): Recognize DW_AT_GNU_macros.
+
+2012-04-27  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw/dwarf_highpc.c (dwarf_highpc): Handle DW_AT_high_pc being
+	a constant offset from DW_AT_low_pc.
+
+2012-03-19  Tom Tromey  <tromey@redhat.com>
+
+	* libdw_findcu.c (findcu_cb): Move earlier.
+	(__libdw_intern_next_unit): Add new CU to search tree here...
+	(__libdw_findcu): ... not here.
+
+2012-01-31  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_formudata.c (dwarf_formudata): Handle DW_FORM_sec_offset.
+
+2011-11-31  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (known-dwarf.h): Run gawk on config/known-dwarf.awk.
+
+2011-07-14  Mark Wielaard  <mjw@redhat.com>
+
+	* libdw.h (dwarf_offdie): Fix documentation to mention .debug_info.
+
+2011-05-16  Jakub Jelinek  <jakub@redhat.com>
+
+	* dwarf.h (DW_OP_GNU_const_type, DW_OP_GNU_regval_type,
+	DW_OP_GNU_deref_type, DW_OP_GNU_convert, DW_OP_GNU_reinterpret):
+	New.
+
+2011-04-26  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_child (dwarf_child): Sanity check end of section against
+	cu_data () of die->cu.
+
+2011-03-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Add DW_TAG_GNU_call_site,
+	DW_TAG_GNU_call_site_parameter,
+	DW_AT_GNU_call_site_value,
+	DW_AT_GNU_call_site_data_value,
+	DW_AT_GNU_call_site_target,
+	DW_AT_GNU_call_site_target_clobbered,
+	DW_AT_GNU_tail_call,
+	DW_AT_GNU_all_tail_call_sites,
+	DW_AT_GNU_all_call_sites,
+	DW_AT_GNU_all_source_call_sites,
+	and DW_OP_GNU_entry_value.
+
+2011-03-10  Petr Machata  <pmachata@redhat.com>
+
+	* libdw/dwarf_tag.c (__libdw_findabbrev): Reject requests for
+	abbreviation with code 0.
+
+2011-03-09  Petr Machata  <pmachata@redhat.com>
+
+	* libdw/dwarf_child.c (dwarf_child): Check for section overrun.
+
+2011-02-23  Roland McGrath  <roland@redhat.com>
+
+	* libdwP.h (struct Dwarf) [USE_ZLIB]: New member sectiondata_gzip_mask.
+	Declare __libdw_free_zdata.
+	* dwarf_end.c [USE_ZLIB] (__libdw_free_zdata): New function.
+	(dwarf_end): Call it.
+
+	* dwarf_begin_elf.c (valid_p): Likewise.
+	(check_section, scngrp_read): Likewise.
+	(check_section) [USE_ZLIB]: Grok .z* flavors of sections.
+
+2010-10-13  Roland McGrath  <roland@redhat.com>
+
+	* dwarf.h: Add DW_LANG_Go.
+
+2010-10-05  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getaranges.c: Use malloc rather than alloca,
+	since the total number of elements can be quite huge.
+
+2010-07-26  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getlocation_implicit_pointer.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.map (ELFUTILS_0.149): New set.
+	Add dwarf_getlocation_implicit_pointer.
+	* libdw.h: Declare it.
+
+	* dwarf_offdie.c (do_offdie): Renamed to __libdw_offdie, made global.
+	(dwarf_offdie, dwarf_offdie_types): Update callers.
+	* libdwP.h: Declare it.
+
+	* dwarf.h: Add DW_OP_GNU_implicit_pointer.
+	* dwarf_getlocation.c (__libdw_intern_expression): Handle it.
+
+2010-08-24  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map (ELFUTILS_0.149): New set.  Add dwfl_dwarf_line.
+
+2010-07-27  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_formref_die.c: Fix sig8 hash insertion.
+
+2010-06-23  Roland McGrath  <roland@redhat.com>
+
+	* cfi.c (dwarf_cfi_validate_fde): Function removed.
+	* libdw.h: Remove it.
+	* libdw.map: Likewise.
+
+2010-06-22  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getlocation.c (check_constant_offset): data[48] are constant.
+
+	* dwarf_getsrclines.c: Fix signed comparison warning in extended
+	opcode parsing.
+
+2010-06-21  Roland McGrath  <roland@redhat.com>
+
+	* dwarf.h: Add DW_TAG_GNU_* constants.
+
+	* memory-access.h (get_sleb128_rest_return): Fix sign extension for
+	10-byte case.
+
+2010-06-20  Roland McGrath  <roland@redhat.com>
+
+	* libdw_findcu.c (__libdw_findcu): Take new flag argument,
+	to search TUs instead of CUs.
+	* libdwP.h: Update decl.
+	(struct Dwarf): New member tu_tree.
+	* dwarf_end.c (dwarf_end): Clean up tu_tree.
+	* dwarf_offdie.c (do_offdie): New function, broken out of ...
+	(dwarf_offdie): ... here.
+	(dwarf_offdie_types): New function.
+	* libdw.h: Declare it.
+	* libdw.map (ELFUTILS_0.148): Add it.
+
+	* libdwP.h (CUDIE): Use cu_data.
+	* dwarf_formblock.c: Likewise.
+	* dwarf_formref_die.c: Likewise.
+	* dwarf_diecu.c: Use CUDIE macro.
+	* dwarf_formaddr.c: Use cu_sec_idx.
+
+2010-06-16  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_formref_die.c: Use dwarf_offdie only for DW_FORM_ref_addr, so
+	we don't repeat a CU lookup we've already done.  Handle
+	DW_FORM_ref_sig8 using sig8_hash table and __libdw_intern_next_unit.
+
+	* libdw_findcu.c (__libdw_intern_next_unit): New function,
+	broken out of ...
+	(__libdw_findcu): ... here.  Call it.
+	* libdwP.h: Declare it.
+	(struct Dwarf): New member next_tu_offset.
+
+	* dwarf_sig8_hash.c: New file.
+	* dwarf_sig8_hash.h: New file.
+	* Makefile.am (libdw_a_SOURCES, noinst_HEADERS): Add them.
+	* dwarf_abbrev_hash.c: Include dwarf_sig8_hash.h before
+	defining NO_UNDEF.
+	* libdwP.h (struct Dwarf): New member sig8_hash.
+	* dwarf_begin_elf.c: Call Dwarf_Sig8_Hash_init on it.
+	* dwarf_end.c: Call Dwarf_Sig8_Hash_free on it.
+
+	* dwarf_nextcu.c (dwarf_next_unit): New function, broken out of ...
+	(dwarf_nextcu): ... here.  Call it.
+	* libdw.h: Declare it.
+	* libdwP.h: Add INTDECL.
+	* libdw_findcu.c (__libdw_findcu): Use it instead of dwarf_nextcu.
+	* libdw.map (ELFUTILS_0.148): New set, add dwarf_next_unit.
+
+	* libdwP.h (cu_sec_idx, cu_data): New functions.
+	Use .debug_types when CU is a TU.
+	* dwarf_cuoffset.c: Use that instead of assuming IDX_debug_info.
+	* dwarf_siblingof.c: Likewise.
+	* dwarf_formstring.c: Likewise.
+	* dwarf_formudata.c (__libdw_formptr, dwarf_formudata): Likewise.
+	* dwarf_getlocation.c (dwarf_getlocation): Likewise.
+	(dwarf_getlocation_addr): Likewise.
+
+	* libdwP.h (struct Dwarf_CU): Add new members type_offset, type_sig8.
+	(DIE_OFFSET_FROM_CU_OFFSET): Take flag argument; if true, compute
+	.debug_types header size instead of .debug_info header size.
+	(CUDIE): Use it.
+	* dwarf_diecu.c: Update caller.
+	* dwarf_getaranges.c: Likewise.
+	* dwarf_nextcu.c: Likewise.
+	* libdw_findcu.c (__libdw_findcu): Initialize new members.
+
+	* fde.c (fde_by_offset): Renamed to ...
+	(__libdw_fde_by_offset): ... this, made global and internal_function.
+	Don't take ADDRESS argument.
+	(__libdw_find_fde): Update caller.  Do address sanity check here.
+	* cfi.h: Declare __libdw_fde_by_offset.
+	* cfi.c (dwarf_cfi_validate_fde): New function.
+	* libdw.h: Declare it.
+	* libdw.map (ELFUTILS_0.148): Add it.
+
+	* cie.c (intern_new_cie): Canonicalize DW_EH_PE_absptr FDE encoding to
+	either DW_EH_PE_udata8 or DW_EH_PE_udata4.
+
+	* encoded-value.h (read_encoded_value): Handle DW_EH_PE_indirect.
+	Don't assume DW_EH_PE_aligned refers to native address size.
+
+	* cfi.c (execute_cfi): Barf on CIE initial instructions changing the
+	address.
+
+2010-06-17  Roland McGrath  <roland@redhat.com>
+
+	* libdwP.h (struct Dwarf_Line_s): Add members isa, discriminator, and
+	op_index.
+	* dwarf_getsrclines.c (dwarf_getsrclines): Move NEW_FILE macro guts
+	into an inner inline function.  Set new fields.  Check all fields for
+	overflow when setting.
+	* dwarf_lineisa.c: New file.
+	* dwarf_linediscriminator.c: New file.
+	* dwarf_lineop_index.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add them.
+	* libdw.map (ELFUTILS_0.148): Add them.
+	* libdw.h: Declare them.
+
+2010-06-16  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_next_cfi.c: Fix version 4 return_address_register decoding.
+
+	* fde.c (fde_by_offset): Renamed to ...
+	(__libdw_fde_by_offset): ... this, made global and internal_function.
+	Don't take ADDRESS argument.
+	(__libdw_find_fde): Update caller.  Do address sanity check here.
+	* cfi.h: Declare __libdw_fde_by_offset.
+	* cfi.c (dwarf_cfi_validate_fde): New function.
+	* libdw.h: Declare it.
+	* libdw.map (ELFUTILS_0.148): Add it.
+
+	* cie.c (intern_new_cie): Canonicalize DW_EH_PE_absptr FDE encoding to
+	either DW_EH_PE_udata8 or DW_EH_PE_udata4.
+
+	* encoded-value.h (read_encoded_value): Handle DW_EH_PE_indirect.
+	Don't assume DW_EH_PE_aligned refers to native address size.
+
+	* cfi.c (execute_cfi): Barf on CIE initial instructions changing the
+	address.
+
+2010-06-15  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_formref.c (__libdw_formref): Diagnose DW_FORM_ref_sig8 like
+	DW_FORM_ref_addr.
+	* dwarf_formref_die.c (dwarf_formref_die): Diagnose it the same way
+	here, since we don't support it yet.
+
+	* dwarf_next_cfi.c: Handle version 4 format.
+
+	* dwarf_getsrclines.c: Handle version 4 format.
+
+2010-06-01  Roland McGrath  <roland@redhat.com>
+
+	* libdwP.h: Remove unused IDX_debug_*names, add IDX_debug_types.
+	* dwarf_begin_elf.c (dwarf_scnnames): Likewise.
+
+	* libdwP.h (CIE_VERSION): Remove unused macro.
+
+	* dwarf_getsrclines.c: Fix version field test.
+	* libdwP.h (DWARF_VERSION): Remove useless macro.
+
+	* dwarf_formudata.c (__libdw_formptr): Fix DW_FORM_sec_offset handling.
+
+	* dwarf_formblock.c (dwarf_formblock): Handle DW_FORM_exprloc.
+
+	* libdw_findcu.c (__libdw_findcu): Accept version 4.
+
+2010-05-31  Mark Wielaard  <mjw@redhat.com>
+
+	* cfi.h (dwarf_cfi_cie_p): Move definition from here, to ..
+	* libdw.h (dwarf_cfi_cie_p): ... here.
+
+2010-05-31  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf.h: Fix DW_LANG_Python constant.
+
+2010-05-28  Eduardo Santiago  <santiago@redhat.com>
+
+	* dwarf_getlocation.c (dwarf_getlocation): Do attr_ok check first
+	thing.
+
+2010-05-27  Roland McGrath  <roland@redhat.com>
+
+	* dwarf.h: Add DW_AT_enum_class, DW_AT_linkage_name,
+	DW_TAG_template_alias, DW_LANG_Python, DW_LNE_set_discriminator.
+
+2010-05-08  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getlocation.c (__libdw_intern_expression): Take new argument
+	REF_SIZE.  Use that to handle DW_OP_call_ref correctly.
+	(getlocation): Update caller.
+	* dwarf_frame_cfa.c (dwarf_frame_cfa): Likewise.
+	* dwarf_frame_register.c (dwarf_frame_register): Likewise.
+	* libdwP.h: Update decl.
+
+2010-04-26  Roland McGrath  <roland@redhat.com>
+
+	* cfi.h (struct Dwarf_Frame_s): Add cfa_invalid alternative in cfa_rule.
+	* cfi.c (execute_cfi): Set that instead of doing cfi_assert for
+	DW_CFA_def_cfa_{offset*,register} when a non-offset rule is in force.
+	* dwarf_frame_cfa.c (dwarf_frame_cfa): Handle cfa_invalid.
+
+	* dwarf_getlocation.c (__libdw_intern_expression): Take new arg CFAP.
+	Prepend DW_OP_call_frame_cfa if true.
+	(getlocation): Update caller.
+	* dwarf_frame_cfa.c (dwarf_frame_cfa): Likewise.
+	* dwarf_frame_register.c (dwarf_frame_register): Likewise.
+	* libdwP.h: Update decl.
+
+2010-04-22  Roland McGrath  <roland@redhat.com>
+
+	* cfi.c (execute_cfi): Never return without cleanup.
+	Free FS on failure.
+	(cie_cache_initial_state): Adjust caller to expect that free.
+	(__libdw_frame_at_address): Likewise.
+
+2010-03-10  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map (ELFUTILS_0.146): New set.  Add dwfl_core_file_report.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Use config/eu.am for common stuff.
+
+2010-02-02  Mark Wielaard  <mjw@redhat.com>
+
+	* fde.c (intern_fde): Fix length check for sized_augmentation_data.
+
+2010-01-07  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getcfi_elf.c (getcfi_phdr): Use elf_getphdrnum.
+
+2010-01-05  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_aggregate_size.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h: Declare it.
+	* libdwP.h: Add INTDECL.
+	* libdw.map (ELFUTILS_0.144): New set.  Add dwarf_aggregate_size.
+
+	* dwarf_srclang.c: Add INTDEF.
+	* libdwP.h: Add INTDECL.
+
+	* dwarf.h: Add some more DW_AT_GNU_* types from gcc.
+
+	* dwarf.h: Add DW_AT_GNU_vector, DW_AT_GNU_template_name.
+
+2009-11-21  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getlocation.c (check_constant_offset): Return 1 for all
+	non-constant forms.
+
+2009-10-15  Roland McGrath  <roland@redhat.com>
+
+	* libdw_form.c (__libdw_form_val_len): Grok DW_FORM_sec_offset,
+	DW_FORM_exprloc, DW_FORM_flag_present, and DW_FORM_ref_sig8.
+
+2009-09-17  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getlocation.c (dwarf_getlocation_implicit_value): Make OP
+	argument a pointer to const.
+	* libdw.h: Update decl.
+
+2009-09-10  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getlocation.c (store_implicit_value): New function.
+	(__libdw_intern_expression): Use it, handle DW_OP_implicit_value.
+	(dwarf_getlocation_implicit_value): New function.
+	* libdw.h: Declare it.
+	* libdw.map (ELFUTILS_0.143): Add it.
+
+2009-09-09  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_getcfi.c (dwarf_getcfi): Clear cfi->ebl.
+
+2009-08-21  Josh Stone  <jistone@redhat.com>
+
+	* dwarf_hasattr_integrate.c: Integrate DW_AT_specification too.
+
+2009-08-10  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getscopevar.c: Use dwarf_diename.
+
+2009-08-09  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map (ELFUTILS_0.143): New version set,
+	inherits from ELFUTILS_0.142.
+	* dwarf_arrayorder.c: Use OLD_VERSION and NEW_VERSION to define an
+	alias in the ELFUTILS_0.122 version set and the default in the new set.
+	* dwarf_srclang.c: Likewise.
+	* dwarf_decl_file.c: Likewise.
+	* dwarf_decl_line.c: Likewise.
+	* dwarf_decl_column.c: Likewise.
+	* dwarf_bytesize.c: Likewise.
+	* dwarf_bitsize.c: Likewise.
+	* dwarf_bitoffset.c: Likewise.
+
+2009-08-07  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_arrayorder.c: Use dwarf_attr_integrate.
+	* dwarf_srclang.c: Likewise.
+	* dwarf_decl_file.c: Likewise.
+	* dwarf_decl_line.c (__libdw_attr_intval): Likewise.
+	* dwarf_bytesize.c: Likewise.
+	* dwarf_bitsize.c: Likewise.
+	* dwarf_bitoffset.c: Likewise.
+
+2009-07-22  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_frame_cfa.c: Change calling convention.
+	* libdw.h: Update decl.
+
+	* dwarf_frame_register.c: Change calling/return-value convention for
+	value-only results and undefined/same_value.
+	* libdw.h: Update decl.
+
+	* dwarf_getlocation.c (__libdw_intern_expression): Take new bool
+	argument, append DW_OP_stack_value if set.  Don't take NOPS argument,
+	return that value instead.
+	(getlocation): Update caller.
+	* dwarf_frame_cfa.c: Likewise.
+	* libdwP.h: Update decl.
+
+2009-07-21  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getsrc_file.c: Ignore a CU that just has no DW_AT_stmt_list.
+	Fix loop iteration after skipping a bogus or useless CU.
+
+	* dwarf_entry_breakpoints.c: Handle 0 dwarf_errno () as harmless
+	absence, not DWARF_E_NO_DEBUG_LINE.
+
+2009-07-20  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getlocation.c (__libdw_intern_expression):
+	Handle DW_OP_stack_value.
+
+2009-07-16  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_formudata.c (__libdw_formptr): Handle DW_FORM_sec_offset,
+	reject others when CU's version > 3.
+
+	* dwarf_formflag.c: Handle DW_FORM_flag_present.
+
+	* dwarf.h: Add DW_OP_{implicit,stack}_value from DWARF 4 draft.
+	Also DW_TAG_type_unit and DW_TAG_rvalue_reference_type.
+	Also DW_AT_signature, DW_AT_main_subprogram, DW_AT_data_bit_offset,
+	and DW_AT_const_expr.
+	Also DW_FORM_sec_offset, DW_FORM_exprloc, DW_FORM_flag_present,
+	and DW_FORM_ref_sig8.
+
+2009-07-15  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getlocation.c: Grok DW_OP_form_tls_address,
+	DW_OP_GNU_push_tls_address, and DW_OP_bit_piece.
+
+2009-07-13  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getlocation.c: Grok DW_OP_call_frame_cfa.
+
+2009-07-08  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map (ELFUTILS_0.142): Add dwfl_module_dwarf_cfi,
+	dwfl_module_eh_cfi.
+
+	* libdwP.h (struct Dwarf): Add member `cfi'.
+	* dwarf_end.c (dwarf_end): Call __libdw_destroy_frame_cache on it.
+	* dwarf_getcfi.c: New file.
+	* dwarf_getcfi_elf.c: New file.
+	* dwarf_cfi_end.c: New file.
+	* dwarf_cfi_addrframe.c: New file.
+	* dwarf_frame_cfa.c: New file.
+	* dwarf_frame_register.c: New file.
+	* dwarf_frame_return_address_register.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add them.
+	* unwind.h: Declare those functions.
+	* libdw.map (ELFUTILS_0.142): Export them.
+
+	* dwarf_getlocation.c (__libdw_intern_expression): New function,
+	broken out of ...
+	(getlocation): ... here, call it.
+	* libdwP.h: Declare it.
+
+	* cie.c: New file.
+	* fde.c: New file.
+	* frame-cache.c: New file.
+	* cfi.c: New file.
+	* cfi.h: New file.
+	* encoded-value.h: New file.
+	* Makefile.am (libdw_a_SOURCES, noinst_HEADERS): Add them.
+	* libdwP.h: Add DWARF_E_INVALID_CFI to errors enum.
+	* dwarf_error.c (errmsgs): Add element for it.
+
+	* dwarf_next_cfi.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h (Dwarf_CIE, Dwarf_FDE, Dwarf_CIE_Entry): New types.
+	Declare dwarf_next_cfi.
+	* libdw.map (ELFUTILS_0.142): New set, inherits from ELFUTILS_0.136.
+	Add dwarf_next_cfi.
+
+	* memory-access.h [! ALLOW_UNALIGNED]
+	(read_2ubyte_unaligned): Renamed to ...
+	(read_2ubyte_unaligned_1): ... this.  Take bool rather than Dwarf *.
+	(read_2ubyte_unaligned): Define as macro passing dbg->other_byte_order.
+	(read_2sbyte_unaligned): Likewise.
+	(read_4ubyte_unaligned): Likewise.
+	(read_4sbyte_unaligned): Likewise.
+	(read_8ubyte_unaligned): Likewise.
+	(read_8sbyte_unaligned): Likewise.
+
+	* libdwP.h (IDX_eh_frame): Remove it.
+	* dwarf_begin_elf.c (dwarf_scnnames): Remove its element.
+
+2009-07-08  Roland McGrath  <roland@redhat.com>
+
+	* libdwP.h (struct Dwarf_Line_s): Reorder members to pack better.
+
+	* dwarf_getlocation.c (check_constant_offset): New function.
+	(dwarf_getlocation, dwarf_getlocation_addr): Call it to
+	handle DW_AT_data_member_location of data[48] as constant offset.
+
+2009-06-18  Roland McGrath  <roland@redhat.com>
+
+	* libdwP.h (__libdw_read_address_inc): Constify.
+	(__libdw_read_offset_inc): Likewise.
+	* dwarf_getaranges.c: Likewise.
+	* dwarf_getlocation.c: Likewise.
+	* dwarf_getsrclines.c: Likewise.
+	* dwarf_nextcu.c: Likewise.
+
+2009-05-05  Petr Machata  <pmachata@redhat.com>
+
+	* libdwP.h (__libdw_formptr): Declare new function.
+	* dwarf_formudata.c: Implement it here.
+	* dwarf_getlocation.c (dwarf_getlocation_addr):
+	Call it instead of hand-rolled offset handling code.
+	* dwarf_getsrclines.c (dwarf_getsrclines): Likewise.
+	* dwarf_ranges.c (dwarf_ranges): Likewise.
+
+2009-05-04  Petr Machata  <pmachata@redhat.com>
+
+	* libdwP.h (__libdw_read_begin_end_pair_inc): Declare new function.
+	* dwarf_ranges.c: Implement it here.
+	(dwarf_ranges): Call it.
+	* dwarf_getlocation.c (dwarf_getlocation_addr): Call it also here.
+
+2009-04-23  Petr Machata  <pmachata@redhat.com>
+
+	* dwarf_formaddr.c (dwarf_formaddr): Call __libdw_read_* instead
+	of read_*ubyte_unaligned.
+	* dwarf_formref_die.c (dwarf_formref_die): Likewise.
+	* dwarf_formstring.c (dwarf_formstring): Likewise.
+	* dwarf_formudate.c (dwarf_formudata): Likewise.
+	* dwarf_getaranges.c (dwarf_getaranges): Likewise.
+	* dwarf_getlocation.c (dwarf_getlocation_addr): Likewise.
+	* dwarf_getpubnames.c (get_offsets): Likewise.
+	* dwarf_nextcu.c (dwarf_nextcu): Likewise.
+
+2009-04-23  Petr Machata  <pmachata@redhat.com>
+
+	* libdwP.h (__libdw_read_addr_inc, __libdw_read_off_inc,
+	__libdw_read_addr, __libdw_read_off): Add four new internal
+	functions.
+
+2009-05-07  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getmacros.c (dwarf_getmacros): Use absolute section offset in
+	return value and OFFSET argument, not CU-relative.  Only fetch the
+	attribute data when called with OFFSET of 0.
+
+2009-05-07  Petr Machata  <pmachata@redhat.com>
+
+	* dwarf_getmacros.c (dwarf_getmacros): Take into account offset in
+	DW_AT_macro_info attribute of CU DIE.
+
+2009-04-15  Roland McGrath  <roland@redhat.com>
+
+	* dwarf.h (DW_CIE_ID): Removed.
+	(DW_CIE_ID_32, DW_CIE_ID_64): New constants replace it.
+
+2009-04-01  Roland McGrath  <roland@redhat.com>
+
+	* dwarf.h: Add DW_CFA_GNU_negative_offset_extended.
+
+2009-01-28  Roland McGrath  <roland@redhat.com>
+
+	* libdwP.h (struct Dwarf_Line_s): Move out of struct Dwarf_Lines_s
+	defn so C++ doesn't scope the name to not match the Dwarf_Line typedef.
+
+	* libdwP.h (struct Dwarf_Files_s): Replace dbg field with cu field.
+
+2009-01-26  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_ranges.c: Return 0 when no ranges or *_pc attrs at all.
+
+2009-01-25  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getattrs.c: Correctly skip attribute values when restarting.
+
+2009-01-23  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am ($(srcdir)/known-dwarf.h): Target renamed back.
+	Put these rules under if MAINTAINER_MODE.
+
+2009-01-22  Roland McGrath  <roland@redhat.com>
+
+	* dwarf.h: Add DW_OP_GNU_encoded_addr.
+
+2009-01-21  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (CLEANFILES): Renamed to ...
+	(MOSTLYCLEANFILES): ... here.
+	(CLEANFILES): New variable, add known-dwarf.h.
+
+2009-01-17  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (known-dwarf.h): Target renamed, not in $(srcdir).
+	Make it unconditional.
+	(BUILT_SOURCES): Updated.
+
+	* dwarf.h: Add description comments for DW_LANG_* values.
+
+	* Makefile.am [MAINTAINER_MODE]
+	($(srcdir)/known-dwarf.h): New target.
+	(BUILT_SOURCES): Add it.
+
+	* dwarf.h: Add DW_OP_GNU_push_tls_address, DW_OP_GNU_uninit.
+
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_error.c: Always use __thread.  Remove all !USE_TLS code.
+
+2009-01-08  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (libdw.so): Don't depend on $(zip_LIBS), just link it in.
+
+2008-01-06  Roland McGrath  <roland@redhat.com>
+
+	* libdwP.h (struct Dwarf_Abbrev): Change type of 'has_children' to bool.
+	Reorder members.
+	* dwarf_haschildren.c: Return -1 for error case, not 0.
+
+	* Makefile.am (libdw.so): Link in $(zip_LIBS).
+
+2009-01-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf.h: Add definition for unwind and call frame information.
+
+	* memory-access.h: Define read_ubyte_unaligned, read_sbyte_unaligned,
+	read_ubyte_unaligned_inc, and read_sbyte_unaligned_inc.
+
+2008-08-15  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map (ELFUTILS_0.136): New version set, inherits from
+	ELFUTILS_0.130.  Add dwfl_addrsegment, dwfl_report_segment.
+
+2008-01-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_child.c: Minor optimizations.
+	* dwarf_getattrs.c: Likewise.
+	* dwarf_getpubnames.c: Likewise.
+	* dwarf_siblingof.c: Likewise.
+	* dwarf_tag.c: Likewise.
+
+2008-01-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_getsrclines.c (dwarf_getsrclines): Don't require exact match
+	of DWARF_VERSION comparison, just fail if the file's version is newer.
+
+2008-01-17  Nick Clifton  <nickc@redhat.com>
+
+	* dwarf.h (DWARF3_LENGTH_MIN_ESCAPE_CODE): New define.
+	(DWARF3_LENGTH_MAX_ESCAPE_CODE): New define.
+	(DWARF3_LENGTH_64_BIT): New define.
+	* dwarf_getaranges (dwarf_getaranges): Use the new definitions.
+	* dwarf_getpubnames: Include dwarf.h.
+	(get_offsets): Use the new definitions.
+	* dwarf_getsrclines.c (dwarf_getsrclines): Use the new defintions.
+	* dwarf_nextcu.c: Include dwarf.h.  Correct comment.
+	(dwarf_nextcu): Use the new definitions.
+
+	* libdwP.h (DIE_OFFSET_FROM_CU_OFFSET): New macro.
+	* dwarf_diecu.c (dwarf_diecu): Use the new macro.
+	* dwarf_getaranges (dwarf_getaranges): Use the new macro.
+	* dwarf_nextcu.c (dwarf_nextcu): Use the new macro.
+
+	* dwarf_getpubnames (get_offsets): Replace assertion with test and
+	error return.
+
+	* dwarf_entry_breakpoints.c (dwarf_entry_breakpoints): Use CUDIE.
+
+	* dwarf_siblingof (dwarf_siblingof): Detect a NULL return pointer.
+	Set the address in the return structure to the address of the next
+	non-sibling die, if there is no sibling and the return pointer is
+	not the same as the die pointer.
+	* libdw.h: Expand the description of the dwarf_siblingof prototype.
+
+	* dwarf_child.c: Fix typo in comment.
+
+	* libdwP.h (DWARF_VERSION): Change to 3.
+
+	* dwarf_formref.c (__libdw_formref.c): Handle attributes which do
+	not have a initialised valp pointer.
+
+	* dwarf_getattrs.c (dwarf_getattrs): Return 1 rather than 0 when
+	the end of the attributes is reached.  When the callback fails,
+	return the address of the failing attribute, not the address of
+	its successor.
+	* libdw.h: Expand the description of the dwarf_getattrs prototype.
+
+	* dwarf_child.c (__libdw_find_attr): Use the new definition.
+	(dwarf_child): Likewise.
+	* dwarf_tag.c (__libdw_findabbrev): Likewise.
+	(dwarf_tag): Likewise.
+
+2008-01-08  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (euinclude): Variable removed.
+	(pkginclude_HEADERS): Set this instead of euinclude_HEADERS.
+	(libdw.so): Pass -Wl,--enable-new-dtags,-rpath,$(pkglibdir).
+
+2007-10-17  Roland McGrath  <roland@redhat.com>
+
+	* libdw.h (__deprecated_attribute__): New macro.
+	(dwarf_formref): Mark it deprecated.
+	* dwarf_formref.c (__libdw_formref): New function, broken out of ...
+	(dwarf_formref): ... here.  Call it.  Remove INTDEF.
+	* libdwP.h: Remove INTDECL.
+	Declare __libdw_formref.
+	* dwarf_siblingof.c (dwarf_siblingof): Call __libdw_formref instead.
+	* dwarf_formref_die.c: Likewise.  Handle DW_FORM_ref_addr here.
+
+	* libdw_form.c (__libdw_form_val_len): Fix DW_FORM_ref_addr result,
+	needs to check CU->version.
+
+	* libdwP.h (struct Dwarf_CU): New member `version'.
+	* libdw_findcu.c (__libdw_findcu): Initialize it.
+
+	* dwarf_child.c: Return 1 for null entry as first child.
+
+2007-10-05  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_begin_elf.c (check_section): Punt on SHT_NOBITS sections.
+
+	* libdw.h (__extern_inline): Rename to __libdw_extern_inline.
+	[__OPTIMIZE__] (dwarf_whatattr, dwarf_whatform): Update uses.
+
+2007-10-03  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map (ELFUTILS_0.130: Add dwfl_build_id_find_elf
+	and dwfl_build_id_find_debuginfo.
+
+	* libdw.map (ELFUTILS_0.130): New version set, inherits from
+	ELFUTILS_0.127.  Add dwfl_module_build_id, dwfl_module_report_build_id.
+
+2007-10-02  Roland McGrath  <roland@redhat.com>
+
+	* libdw_visit_scopes.c (classify_die): Return walk for class_type and
+	structure_type.
+
+2007-08-07  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getscopes.c (pc_match): Swallow dwarf_haspc error return when
+	error code is DWARF_E_NOERROR (0).
+
+	* dwarf_getscopes.c (pc_record): Always bail early if DIE->prune.
+	Fix typo in __libdw_visit_scopes argument.
+
+	* dwarf_getscopes.c (pc_match): Check dwarf_haspc error return,
+	swallow DWARF_E_NO_DEBUG_RANGES but not other errors.
+
+2007-07-03  Roland McGrath  <roland@redhat.com>
+
+	* libdw.h (__extern_inline): New macro.
+	[__OPTIMIZE__] (dwarf_whatattr, dwarf_whatform): Use it.
+
+2007-04-16  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map (ELFUTILS_0.127): Add dwfl_module_address_section.
+
+2007-04-05  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getsrcdirs.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h: Declare dwarf_getsrcdirs.
+	* libdw.map (ELFUTILS_0.127): Add it.
+
+	* libdwP.h (struct Dwarf_Files_s): New member ndirs.
+	* dwarf_getsrclines.c (dwarf_getsrclines): Don't clobber NDIRLIST to
+	zero before we use it to check for DWARF_E_INVALID_DIR_IDX.
+	Save DIRARRAY in the Dwarf_Files.
+
+	* dwarf_ranges.c (dwarf_ranges): Don't sign-extend 32-bit BEGIN
+	address to check for all-ones base address entry.  Check directly.
+	Reported by Sébastien Dugué <sebastien.dugue@bull.net>.
+
+2007-03-25  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_begin_elf.c (check_section): Return Dwarf * instead of void.
+	Return NULL when freeing RESULT on error.
+	(global_read, scngrp_read): Check return value from check_section,
+	break out of loop after it has freed RESULT.
+	(valid_p): Handle null argument.
+
+2007-03-12  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map (ELFUTILS_0.127): Add dwfl_report_begin_add.
+
+2007-03-04  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map (ELFUTILS_0.127): New version set, inherits from
+	ELFUTILS_0.126.  Add dwfl_module_addrsym.
+
+2007-02-10  Roland McGrath  <roland@redhat.com>
+
+	* dwarf.h (DW_OP_fbreg): Comment fix.
+
+2007-02-03  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getelf.c (dwarf_getelf): Renamed from dwarf_get_elf.
+	* libdw.map (ELFUTILS_0.126): New version set, inherits from
+	ELFUTILS_0.122.  Move dwarf_getelf there; it was never truly
+	exported in the past.
+
+2006-12-17  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getlocation.c (dwarf_getlocation_addr): Use zero as base
+	address when the CU is missing attributes due to buggy GCC.
+
+2006-08-29  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (CLEANFILES): Add libdw.so.$(VERSION).
+
+	* libdw.h (dwarf_diecu): Add __nonnull_attribute__.
+	(dwarf_child): Don't list arg 1 in __nonnull_attribute__.
+
+	* libdw_alloc.c (__libdw_allocate): Take new ALIGN argument, make sure
+	result is aligned.  Adjust NEWP->remaining here for this allocation.
+	* libdwP.h: Update decl.
+	(libdw_alloc): Update caller.
+
+2006-07-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_child.c: Adjust for internal_function_def removal.
+	* dwarf_getabbrev.c: Likewise.
+	* dwarf_tag.c: Likewise.
+	* libdw_form.c: Likewise.
+	* memory-access.c: Likewise.
+
+2006-06-28  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map: Export dwfl_linecu, dwfl_line_comp_dir.
+
+	* libdw.map: Bump to 0.122; export dwfl_module_getsymtab and
+	dwfl_module_getsym.
+
+2006-05-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* libdw.h: Add extern "C".
+
+2006-05-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_getaranges.c (dwarf_getaranges): Handle files without
+	aranges information.
+
+2006-05-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* libdw.h: Add nonnull attributes to dwarf_tag, dwarf_getattrs,
+	dwarf_haschildren.
+
+2006-02-28  Roland McGrath  <roland@redhat.com>
+
+	* dwarf.h: Add missing DW_ATE_*, DW_TAG_*, DW_LANG_*, DW_CFA_*,
+	DW_OP_* values, to match DWARF 3.0.  Add new DW_DS_*, DW_END_*
+	values from DWARF 3.0.
+
+2006-02-22  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map: Bump to 0.120; export dwfl_version.
+
+2005-12-22  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map: Bump to 0.119; export dwfl_linux_proc_maps_report.
+
+2005-12-12  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_ranges.c: Copy CU base address-finding code from
+	dwarf_getlocation.
+
+2005-12-09  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getlocation.c (dwarf_getlocation_addr): Add some unlikelys.
+	Delay CU base lookup until it's needed.
+	If CU base lookup fails with no error, flag invalid DWARF.
+
+2005-11-25  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map: Bump to 0.118; export dwfl_module_register_names.
+
+2005-11-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am [BUILD_STATIC] (AM_CFLAGS): Add -fpic.
+
+2005-11-13  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map: Bump to 0.117; export dwfl_module_return_value_location.
+
+2005-10-27  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_entry_breakpoints.c (search_range): Fix binary search code;
+	don't match end_sequence markers.
+
+	* dwarf_getsrclines.c (compare_lines): Sort end_sequence markers
+	before normal records at the same address.
+	* dwarf_getsrc_die.c (dwarf_getsrc_die): Don't match an end_sequence
+	marker.
+
+2005-10-26  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getfuncs.c (dwarf_getfuncs): Use Dwarf_Die, not Dwarf_Func.
+	* dwarf_func_file.c: Renamed to ...
+	* dwarf_decl_file.c: ... here.
+	* dwarf_func_col.c: Renamed to ...
+	* dwarf_decl_column.c: ... here.
+	* dwarf_func_line.c: Renamed to ...
+	* dwarf_decl_line.c: ... here.
+	(dwarf_func_line): Renamed to ...
+	(dwarf_decl_line): ... this.  Take a Dwarf_Die * argument.
+	(__libdw_func_intval): Renamed __libdw_attr_intval.
+	* dwarf_func_name.c: File removed.
+	* dwarf_func_lowpc.c: File removed.
+	* dwarf_func_highpc.c: File removed.
+	* dwarf_func_entrypc.c: File removed.
+	* dwarf_func_die.c: File removed.
+	* Makefile.am (libdw_a_SOURCES): Updated.
+	* libdw.h: Update decls.
+	(Dwarf_Func): Type removed.
+	* libdwP.h: Update decls.
+	(struct Dwarf_Func_s): Type removed.
+	* libdw.map: Updated.
+
+	* libdwP.h (CUDIE): New macro.
+	* dwarf_getlocation.c (dwarf_getlocation_addr): Use it.
+	* dwarf_getscopes_die.c (dwarf_getscopes_die): Likewise.
+	* dwarf_ranges.c (dwarf_ranges): Likewise.
+
+	* dwarf_getloclist.c: Renamed to ...
+	* dwarf_getlocation.c: ... here.
+	(getloclist): Renamed to getlocation.
+	(dwarf_getloclist): Renamed to dwarf_getlocation.
+	(dwarf_addrloclists): Renamed to dwarf_getlocation_addr.
+	* Makefile.am (libdw_a_SOURCES): Updated.
+	* libdw.h (dwarf_getloclist): Renamed to dwarf_getlocation.
+	(dwarf_addrloclists): Renamed dwarf_getlocation_addr.
+	(Dwarf_Loc): Renamed Dwarf_Op.
+	* libdwP.h (struct loc_s): Update use.
+	* libdw.map: Update map.
+
+	* dwarf_entry_breakpoints.c: Use the second line record within the
+	function, regardless of its source location data.
+
+2005-10-25  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_entry_breakpoints.c: Fall back to entrypc for contiguous too.
+
+	* libdw.map: Add dwarf_entrypc, dwarf_entry_breakpoints.
+
+2005-10-14  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_diecu.c (dwarf_diecu): New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h: Declare dwarf_diecu.
+	* libdw.map: Export it.
+
+	* libdw.map: Bump to 0.116; export dwarf_ranges.
+
+2005-09-20  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_haspc.c: Use dwarf_ranges.
+	* dwarf_entry_breakpoints.c: Likewise.
+
+	* dwarf_ranges.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h: Declare dwarf_ranges.
+	* libdwP.h: Add INTDECL.
+
+2005-09-14  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_entry_breakpoints.c (dwarf_entry_breakpoints): Fix braino in
+	prologue_end marker scanning loop.
+
+2005-09-11  Roland McGrath  <roland@redhat.com>
+
+	* dwarf.h: Comment typo fix.
+
+2005-09-07  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_entry_breakpoints.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h: Declare dwarf_entry_breakpoints.
+
+	* dwarf_entrypc.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h: Declare dwarf_entrypc.
+	* libdwP.h: Add INTDECL.
+
+2005-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Use $(LINK) not $(CC) when creating DSO.
+	(%.os): Use COMPILE.os.
+	(COMPILE.os): Filter out gconv options.
+
+2005-08-27  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getscopes.c (dwarf_getscopes): Rewritten using
+	__libdw_visit_scopes.
+
+	* dwarf_getscopes_die.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h: Declare dwarf_getscopes_die.
+	* libdw.map: Bump to 0.115 and add it.
+
+	* libdw_visit_scopes.c (__libdw_visit_scopes): Pass a struct
+	containing a DIE and its parent pointer, instead of just Dwarf_Die.
+	Take two functions for both preorder and postorder visitors.
+	* libdwP.h: Update decl.
+	(struct Dwarf_Die_Chain): New type.
+	* dwarf_func_inline.c: Update uses.
+
+	* dwarf_diename.c (dwarf_diename): Use dwarf_attr_integrate.
+	Add INTDEF.
+	* libdwP.h: Add INTDECL.
+	* dwarf_func_name.c (dwarf_func_name): Use dwarf_diename.
+
+2005-08-23  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_attr_integrate.c (dwarf_attr_integrate): Treat
+	DW_AT_specification the same as DW_AT_abstract_origin.
+
+2005-08-20  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map: Add dwfl_cumodule, remove dwfl_linecu.
+	Add dwfl_linux_kernel_report_offline, dwfl_offline_section_address,
+	and dwfl_report_offline.
+
+2005-08-19  Roland McGrath  <roland@redhat.com>
+
+	* libdw.map: Bump version to ELFUTILS_0.114 for libdwfl changes.
+	Add dwfl_module_relocate_address, dwfl_module_relocations,
+	dwfl_module_relocation_info.
+
+2005-08-18  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getscopes.c (dwarf_getscopes): Include the CU itself as
+	outermost scope in the results.
+
+2005-08-15  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_func_inline.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h: Declare dwarf_func_inline, dwarf_func_inline_instances.
+	* libdw.map: Add them.
+
+	* dwarf_func_die.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h: Declare dwarf_func_die.
+	* libdw.map: Add it.  Bump version to ELFUTILS_0.114.
+
+2005-08-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_getsrclines.c (dwarf_getsrclines): Correct fallout of renaming
+	of DW_LNS_set_epilog_begin.
+
+2005-08-09  Roland McGrath  <roland@redhat.com>
+
+	* dwarf.h (DW_LNS_set_epilog_begin): Renamed DW_LNS_set_epilogue_begin.
+
+	* dwarf_end.c: Add INTDEF.
+	* dwarf_error.c (dwarf_errmsg): Likewise.
+	* libdwP.h (dwarf_end, dwarf_errmsg): Add INTDECLs.
+
+2005-08-01  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getaranges.c (dwarf_getaranges): Check for bogus offset.
+	* dwarf_getabbrev.c (__libdw_getabbrev): Likewise.
+
+2005-07-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (libdw.so): No need to link with libeu.a anymore.
+	(libdw_a_LIBADD): Add all files from libdwfl.a.
+
+2005-07-27  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (libdw.so): Link ../libdwfl/libdwfl_pic.a in,
+	along with ../libebl/libebl.a and ../lib/libeu.a;
+	depend on ../libelf/libelf.so.
+	(libdw_so_LDADD): New variable.
+	* libdw.map: Add dwfl_* symbols formerly in ../libdwfl/libdwfl.map.
+
+	* libdw.map: Define an empty base version and move all symbols to
+	version ELFUTILS_0.111; don't define ELFUTILS_1.0 at all yet.
+
+2005-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_error.c: Add internal alias for dwarf_errno.
+	* libdwP.h: Declare __dwarf_errno_internal.
+	* dwarf_getloclist.c: Use INTDEF for dwarf_errno.
+
+	* dwarf_error.c [USE_TLS]: Actually use __thread in definition of
+	global_error.
+
+2005-06-01  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getaranges.c (dwarf_getaranges): Sort result array.
+	* dwarf_getarange_addr.c (dwarf_getarange_addr): Use binary search.
+
+2005-06-08  Roland McGrath  <roland@redhat.com>
+
+	* memory-access.h (get_uleb128_step, get_uleb128): Remove casts.
+	(get_sleb128_step, get_sleb128): Likewise.
+	* dwarf_getattrs.c (dwarf_getattrs): Add consts.
+	* dwarf_getloclist.c (getloclist): Likewise.
+	* dwarf_formblock.c (dwarf_formblock): Likewise.
+	* dwarf_getsrclines.c (dwarf_getsrclines): Likewise.
+	* dwarf_getabbrevattr.c (dwarf_getabbrevattr): Likewise.
+	* dwarf_formref.c (dwarf_formref): Likewise.
+	* dwarf_formsdata.c (dwarf_formsdata): Likewise.
+	* dwarf_formudata.c (dwarf_formudata): Likewise.
+	* dwarf_haschildren.c (dwarf_haschildren): Likewise.
+	* dwarf_child.c (__libdw_find_attr, __libdw_find_attr): Likewise.
+	* dwarf_tag.c (dwarf_tag): Likewise.
+	* dwarf_getabbrev.c (__libdw_getabbrev): Likewise.
+	* memory-access.c (__libdw_get_uleb128, __libdw_get_sleb128): Likewise.
+	* libdw_form.c (__libdw_form_val_len): Likewise.
+	* libdwP.h: Update decl.
+
+2005-06-04  Roland McGrath  <roland@redhat.com>
+
+	* memory-access.h (get_uleb128_rest_return): New macro.
+	[! IS_LIBDW] (__libdw_get_uleb128): New static, defined using it.
+	(get_sleb128_rest_return): New macro.
+	[! IS_LIBDW] (__libdw_get_sleb128): New static, defined using it.
+	* memory-access.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	(DEFS): Add -DIS_LIBDW.
+
+2005-05-31  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_formref_die.c (dwarf_formref_die): Add CU header offset to
+	formref offset.
+
+2005-05-30  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getloclist.c (dwarf_addrloclists): Use DW_AT_entry_pc for base
+	address if DW_AT_low_pc is missing.  Not to spec, but GCC generates it.
+
+	* dwarf_getloclist.c (dwarf_addrloclists): Don't sign-extend 4-byte
+	BEGIN value.  Instead, match base address entries separately for
+	32/64 size cases.
+
+2005-05-28  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getloclist.c (dwarf_addrloclists): Fix decoding to advance
+	past location expression contents.
+
+2005-05-23  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getsrclines.c: Comment typo fix.
+
+	* dwarf_haspc.c (dwarf_haspc): Fix CU DIE address calculation.
+	* dwarf_getloclist.c (dwarf_addrloclists): Likewise.
+
+2005-05-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* libdwP.h: Only use INTDECL for alias prototypes.
+
+2005-05-19  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getloclist.c (attr_ok): Permit DW_AT_static_link too.
+
+	* dwarf_getscopevar.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h: Declare dwarf_getscopevar.
+
+	* dwarf_getsrcfiles.c: Add INTDEF.
+	* dwarf_haschildren.c: Likewise.
+	* libdwP.h (dwarf_getsrcfiles, dwarf_haschildren): Add INTDECL.
+
+	* dwarf_getscopes.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h: Declare dwarf_getscopes.
+	* libdw.map: Add it.
+
+2005-05-18  Roland McGrath  <roland@redhat.com>
+
+	* libdwP.h (IDX_debug_ranges): New enum constant.
+	* dwarf_begin_elf.c (dwarf_scnnames): Add it for ".debug_ranges".
+	* libdwP.h (DWARF_E_NO_DEBUG_RANGES): New enum constant.
+	* dwarf_error.c (errmsgs): Add it.
+	* dwarf_haspc.c: New file.
+	* libdw.h: Declare dwarf_haspc.
+	* libdw.map: Add it.
+	* libdwP.h: Add INTDECL.
+
+	* dwarf_attr_integrate.c: New file.
+	* dwarf_hasattr_integrate.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add them.
+	* libdw.h: Declare dwarf_attr_integrate, dwarf_hasattr_integrate.
+	* libdw.map: Add them.
+
+	* dwarf_hasattr.c: Add INTDEF.
+	* libdwP.h: Add INTDECL for it.
+
+	* dwarf_formref_die.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add it.
+	* libdw.h (dwarf_formref_die): Declare it.
+	* libdwP.h (dwarf_formref_die): Add INTDECL.
+	* libdw.map: Add it.
+
+	* dwarf_getloclist.c (attr_ok, getloclist): New functions, broken out
+	of ...
+	(dwarf_getloclist): ... here.  Call them.
+	(dwarf_addrloclists): New function.
+	* libdw.h: Declare it.
+	* libdw.map: Add it.
+
+	* dwarf_getmacros.c (dwarf_getmacros): Don't bail at
+	DW_MACINFO_end_file.  Recognize type 0 as terminator.
+
+2005-05-05  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getsrc_die.c (dwarf_getsrc_die): Use binary search.
+
+	* dwarf_getsrclines.c (dwarf_getsrclines): Sort result array, since
+	the line program does not produce all entries in ascending order.
+
+2005-04-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_getsrc_file.c (dwarf_getsrc_file): Handle multiple
+	occurences (e.g., inlines) better.
+
+2005-04-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* libdw.h (DWARF_END_ABBREV): Define.
+	* dwarf_getabbrev.c (__libdw_getabbrev): Return DWARF_END_ABBREV if
+	end is reached.
+	* dwarf_offabbrev.c (dwarf_offabbrev): Return -1 on error, 1 if end
+	of records reached.
+	* dwarf_tag.c (__libdw_findabbrev): Also recognize DWARF_END_ABBREV
+	as error of __libdw_getabbrev.
+
+2005-04-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_getsrc_file.c (dwarf_getsrc_file): Minor optimization.
+
+	* dwarf_getsrc_file.c (dwarf_getsrc_file): Always pass number of
+	results back to caller.
+
+2005-04-04  Roland McGrath  <roland@redhat.com>
+
+	* dwarf_getsrc_file.c (dwarf_getsrc_file): Use size_t for CUHL.
+
+	* dwarf_func_line.c (__libdw_func_intval): Use internal_function in
+	defn.
+
+2005-04-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_getsrc_file.c (dwarf_getsrc_file): Use INTUSE.
+
+	* dwarf_getsrc_file.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_getsrc_file.c.
+	* libdw.h: Declare dwarf_getsrc_file.
+	* libdw.map: Add dwarf_getsrc_file.
+
+2005-04-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_func_entrypc.c: New file.
+	* dwarf_func_col.c: New file.
+	* dwarf_func_line.c: New file.
+	* dwarf_func_file.c: New file.
+	* libdw.h: Add prototypes for new functions.
+	* libdw.map: Add dwarf_func_entrypc, dwarf_func_col, dwarf_func_line,
+	dwarf_func_file.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_func_entrypc.c,
+	dwarf_func_col.c, dwarf_func_line.c, dwarf_func_file.c.
+	* libdwP.h (struct Dwarf_Func_s): Add cudie element.
+	Declare __libdw_func_intval and __dwarf_formsdata_internal.
+	* dwarf_getfuncs.c: Also fill in cudie in Dwarf_Func object.
+	* dwarf_formsdata.c: Use INTUSE and INTDEF to avoid PLTs.
+
+	* dwarf.h: Add some DWARF3 definitions.
+
+2005-04-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_getfuncs.c: New file.
+	* dwarf_func_highpc.c: New file.
+	* dwarf_func_lowpc.c: New file.
+	* dwarf_func_name.c: New file.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_getfuncs.c,
+	dwarf_func_highpc.c, dwarf_func_lowpc.c, and dwarf_func_name.c.
+	* libdw.map: Add dwarf_getfuncs, dwarf_func_highpc, dwarf_func_lowpc,
+	and dwarf_func_name.
+	* libdw.h: Add prototypes for new functions.
+	* dwarf_child.c: Use INTUSE and INTDEF to avoid PLTs.
+	* dwarf_siblingof.c: Likewise.
+	* dwarf_dieoffset.c: Likewise.
+	* dwarf_highpc.c: Likewise.
+	* dwarf_lowpc.c: Likewise.
+	* libdwP.h: Add prototypes for internal functions.
+	Define Dwarf_Func_s structure.
+
+2005-03-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* libdw.h: Add padding in Dwarf_die.
+
+	* dwarf_arrayorder.c: Use INTUSE and INTDEF to avoid PLTs.
+	* dwarf_attr.c: Likewise.
+	* dwarf_begin.c: Likewise.
+	* dwarf_begin_elf.c: Likewise.
+	* dwarf_bitoffset.c: Likewise.
+	* dwarf_bitsize.c: Likewise.
+	* dwarf_bytesize.c: Likewise.
+	* dwarf_diename.c: Likewise.
+	* dwarf_formaddr.c: Likewise.
+	* dwarf_formblock.c: Likewise.
+	* dwarf_formref.c: Likewise.
+	* dwarf_formstring.c: Likewise.
+	* dwarf_formudata.c: Likewise.
+	* dwarf_getarange_addr.c: Likewise.
+	* dwarf_getarangeinfo.c: Likewise.
+	* dwarf_getaranges.c: Likewise.
+	* dwarf_getloclist.c: Likewise.
+	* dwarf_getmacros.c: Likewise.
+	* dwarf_getsrc_die.c: Likewise.
+	* dwarf_getsrcfiles.c: Likewise.
+	* dwarf_getsrclines.c: Likewise.
+	* dwarf_highpc.c: Likewise.
+	* dwarf_lowpc.c: Likewise.
+	* dwarf_nextcu.c: Likewise.
+	* dwarf_offdie.c: Likewise.
+	* dwarf_siblingof.c: Likewise.
+	* dwarf_srclang.c: Likewise.
+	* dwarf_tag.c: Likewise.
+	* libdw_findcu.c: Likewise.
+	* libdwP.h: Add prototypes for internal functions.
+
+	* dwarf_addrdie.c: New file.
+	* dwarf_macro_opcode.c: New file.
+	* dwarf_macro_param1.c: New file.
+	* dwarf_macro_param2.c: New file.
+	* libdw.h: Add declarations.  Move Dwarf_Macro definition to libdwP.h.
+	* libdwP.h: Remove Dwarf_Macro definition.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_addrdie.c,
+	dwarf_macro_opcode.c, dwarf_macro_param1.c, and dwarf_macro_param2.c.
+	* libdw.map: Add entries for new functions.
+
+2005-03-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* libdw.h: Handle broken gcc < 4.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile (AM_CFLAGS): Add -Wunused -Wextra -Wformat=2.
+
+	* dwarf_begin_elf.c: Fix warnings.
+	* dwarf_dieoffset.c: Likewise.
+	* dwarf_end.c: Likewise.
+	* dwarf_error.c: Likewise.
+	* dwarf_getpubnames.c: Likewise.
+
+	* libdwP.h: Add new error values.
+	* dwarf_error.c: Support new error values.
+	* dwarf_getpubnames.c: Check parameter value.
+
+2005-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Check for text relocations in constructed DSO.
+
+	* Makefile.am [MUDFLAP] (AM_CFLAGS): Add -fmudflap.
+
+2005-02-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_siblingof.c (dwarf_siblingof): Add some buffer boundary
+	checks to not read over buffer boundaries for ill-formed DWARF data.
+
+2004-09-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_child.c: Make compile with gcc 4.0.
+	* dwarf_error.c: Likewise.
+	* dwarf_formblock.c: Likewise.
+	* dwarf_getabbrev.c: Likewise.
+	* dwarf_getattrs.c: Likewise.
+	* dwarf_getsrclines.c: Likewise.
+	* dwarf_tag.c: Likewise.
+	* libdw_form.c: Likewise.
+
+2004-01-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support building with mudflap.
+
+	* dwarf_getloclist.c: Fix warnings gcc 3.4 spits out.
+	* dwarf_getsrclines.c: Likewise.
+	* dwarf_memory-access.h: Likewise.
+
+2004-01-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_getsrcfiles.c: Third parameter can be NULL.
+
+	* libdw.h: Define Dwarf_macro.  Declare dwarf_getmacros.
+	Third parameter of dwarf_getsrcfiles can be NULL.
+
+	* libdw.map: Add dwarf_getmacros.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_getmacros.
+	* dwarf_getmacros.c: New file.
+
+2004-01-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* libdw.h: Second parameter of dwarf_getaranges can be NULL.
+
+	* dwarf_nextcu.c: Return -1 if dwarf parameter is NULL.
+
+	* dwarf_getsrclines.c:
+	Use read_2ubyte_unaligned_inc instead of _inc-less variant.
+
+	* dwarf_getaranges.c: Allow naranges parameter to be NULL.
+
+	* libdwP.h (_): Use elfutils domain.
+
+	* dwarf_getsrclines.c (dwarf_getsrclines): Add more branch prediction.
+
+	* dwarf_getsrclines.c: Fix typo in comment.
+
+2004-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support building with mudflap.
+
+2004-01-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* memory-access.h: Add lots of const in case a pointer passed is const.
+
+	* dwarf_formflag.c: New file.
+	* dwarf_getattrs.c: New file.
+	* dwarf_error.c: Add new error value.
+	* libdw.h: Add prototypes for new functions.  Adjust prototype for
+	dwarf_getpubnames.
+	* libdw.map: Add new functions.
+	* dwarf_getpubnames.c: Change type of return value and fourth parameter
+	to ptrdiff_t.
+	* libdwP.h: Add new error value.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_getattrs.c and
+	dwarf_formflag.c.
+
+	* dwarf_getpubnames.c (dwarf_getpubnames): Just fail if dbg is NULL.
+
+2004-01-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_getarange_addr.c: New file
+	* dwarf_getarangeinfo.c: New file.
+	* dwarf_getaranges.c: New file.
+	* dwarf_onerange.c: New file.
+	* libdw.h: Declare new functions.  Define Dwarf_Arange and
+	Dwarf_Aranges.
+	* libdw.map: Add new functions.
+	* libdwP.h: Add new errors.  Add aranges member to struct Dwarf.
+	Define Dwarf_Aranges_s and Dwarf_Arange_s.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_getaranges.c,
+	dwarf_onearange.c, dwarf_getarangeinfo.c, dwarf_getarange_addr.c.
+	* dwarf_error.c: Add new message.
+
+2004-01-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_lineaddr.c, dwarf_linecol.c,
+	dwarf_linebeginstatement.c, dwarf_lineendsequence.c, dwarf_lineblock.c,
+	dwarf_lineprologueend.c, dwarf_lineepiloguebegin.c, dwarf_onesrcline.c.
+	* dwarf_error.c: Add another message.
+	* dwarf_getsrc_die.c: Adjust for Dwarf_Files and Dwarf_Lines
+	introduction.
+	* dwarf_filesrc.c: Likewise.
+	* dwarf_getsrcfiles.c: Likewise.
+	* dwarf_getsrclines.c: Likewise.
+	* dwarf_lineaddr.c: New file.
+	* dwarf_linebeginstatement.c: New file.
+	* dwarf_lineblock.c: New file.
+	* dwarf_linecol.c: New file.
+	* dwarf_lineendsequence.c: New file.
+	* dwarf_lineepiloguebegin.c: New file.
+	* dwarf_lineno.c: New file.
+	* dwarf_lineprologueend.c: New file.
+	* dwarf_onesrcline.c: New file.
+	* dwarf_lineno.c: Change interface to store result in object pointed
+	to by second parameter.
+	* libdw.h: Add prototypes for new functions.  Change dwarf_lineno
+	prototype.  Define Dwarf_Files and Dwarf_Lines.
+	* libdw.map: Add new functions.
+	* libdwP.h: Define Dwarf_Files_s and Dwarf_Lines_s.
+	* libdw_findcu.c: Don't initialize nlines field.
+
+	* dwarf_siblingof: Little optimization.
+
+	* dwarf_begin.c: Remember that the ELF descriptor must be closed.
+	* dwarf_end.c: Close ELF descriptor if free_elf is set.
+	* libdwP.h (struct Dwarf): Add free_elf field.
+
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_getstring.c and
+	dwarf_offabbrev.c.
+	* dwarf_getstring.c: New file.
+	* dwarf_offabbrev.c: New file.
+	* libdw.map: Add dwarf_getstring and dwarf_offabbrev.
+	* dwarf_getabbrev.c (__libdw_getabbrev): Add new dbg and result
+	parameters.  Don't allocate memory if not necessary and don't lookup
+	previous results if no CU given.
+	(dwarf_getabbrev): Adjust call to __libdw_getabbrev.
+	* dwarf_tag.c: Adjust call to __libdw_getabbrev.
+	* libdw.h: Declare dwarf_offabbrev and dwarf_getstring.
+	* libdwP.h: Change prototype for __libdw_getabbrev.
+
+	* dwarf_getabbrevattr.c: Add offsetp parameter.  Fill in before
+	returning if this is wanted.
+
+2004-01-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_nextcu.c: Add new parameter offset_sizep.  Initialize it
+	with offset_size value.
+	* libdw.h: Adjust dwarf_nextcu prototype.
+	* libdwP.h (struct Dwarf_CU): Add offset_size member.
+	* libdw_findcu.c: Adjust dwarf_nextcu call.  Initialize offset_size
+	member of new CU struct.
+	* dwarf_formstring.c: Depend on offset_size not address_size for
+	DW_FORM_strp handling.
+	* dwarf_form.c: Likewise for DW_FORM_strp and DW_FORM_ref_addr.
+
+	* dwarf_tag.c (__libdw_findabbrev): Return correct value for
+	failing lookup.
+	(dwarf_tag): Correctly recognize failed lookup.
+
+	* dwarf_end.c (cu_free):  Call tdestroy for locs member.  Use new
+	function noop_free.
+	* dwarf_error.c: Add message for DWARF_E_NO_BLOCK.
+	* dwarf_formblock.c: New file.
+	* dwarf_getloclist.c: Rewrite to handle a single block.
+	* libdw.h: Define Dwarf_Block.  Rename Dwarf_Loc members.  Remove
+	Dwarf_Locdesc definition.  Declare dwarf_formblock.  Remove
+	dwarf_getloclistent declaration.
+	* libdw.map: Add dwarf_formblock, remove dwarf_getloclistent.
+	* libdwP.h: Define struct loc_s and DWARF_E_NO_BLOCK.
+	Add locs member to struct Dwarf_CU.
+	* libdw_fundcu.c: Initialize locs member of new CU.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_formblock.c.
+	Remove dwarf_getloclistent.c.
+
+2004-01-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* libdw.h: Use __nonnull__ attribute only for gcc >= 3.3.
+	* libdwP.h: Likewise.
+
+	* dwarf_getloclist.c: New file.
+	* dwarf_getloclistent.c: New file.
+	* libdw.h: Define Dwarf_Loc and Dwarf_Locdesc.
+	Declare dwarf_getloclistent and dwarf_getloclist.
+	* libdw.map: Add dwarf_getloclistent and dwarf_getloclist.
+	* libdwP.h: Define DWARF_E_NO_LOCLIST.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_getloclistent.c and
+	dwarf_getloclist.c.
+
+	* dwarf_error.c: More error messages.
+
+2004-01-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwarf_getsrclines.c: Remove debugging support.
+
+	* dwarf_getsrcfiles.c: New file.
+	* dwarf_filesrc.c: New file.
+	* libdw.h: Declare these functions.  Define Dwarf_File.
+	* libdwP.c: Adjust Dwarf_File_s definition.
+	* libdw.map: Add these functions.
+	* Makefile.am (libdw_a_SOURCES): Add dwarf_getsrcfiles.c and
+	dwarf_filesrc.c.
+	* dwarf_getsrclines.c: Initialize cu->files.
+
+2004-01-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* libdw.h: Add more nonnull function attributes.
+
+	* dwarf_begin_elf.c (dwarf_begin_elf): Don't initialize mem_tail->next.
+	* dwarf_end.c (cu_free): New function.
+	(dwarf_end): Also free CU tree.  Correct freeing of memory blocks.
+	* dwarf_error.c (errmsgs): Add new messages.
+	* dwarf_getsrc_die.c: New file.
+	* dwarf_getsrclines.c: New file.
+	* dwarf_lineno.c: New file.
+	* dwarf_linesrc.c: New file.
+	* dwarf_nextcu.c (dwarf_nextcu): Use read_*byte_unaligned_inc
+	instead of the *_inc-less variants.
+	* libdw.h: Define Dwarf_Line.  Add some function attributes.  Declare
+	dwarf_getsrclines, dwarf_getsrc_die, dwarf_lineno, and dwarf_linesrc.
+	* libdw.map: Add dwarf_getsrclines, dwarf_getsrc_die, dwarf_lineno,
+	and dwarf_linesrc.
+	* libdwP.h: Add more error codes.
+	(struct Dwarf): Remove mem_tail.next member.
+	(Dwarf_File): Define type.
+	(struct Dwarf_Line_s): Define type.
+	(struct Dwarf_CU): Add lines and nlines members.
+	(libdw_alloc): Define local variable _tail and use it.
+	Add some function attributes.
+	* libdw_alloc.c (__libdw_allocate): Don't initialize next member.
+	* libdw_findcu.c (__libdw_findcu): Initialize lines and nlines members.
+	* memory-access.h: Add unlikely for the endian conversion paths.
+	* Makefile.am (AM_CFLAGS): Add -std parameter.
+	(libdw_a_SOURCES): Add dwarf_getsrclines, dwarf_getsrc_die,
+	dwarf_lineno, and dwarf_linesrc.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* Moved to CVS archive.
diff --git a/third_party/elfutils/libdw/Makefile.am b/third_party/elfutils/libdw/Makefile.am
new file mode 100644
index 0000000..8545b5b
--- /dev/null
+++ b/third_party/elfutils/libdw/Makefile.am
@@ -0,0 +1,145 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 2002-2010, 2012, 2014, 2016, 2018 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * 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
+##
+## or both in parallel, as here.
+##
+## elfutils 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.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+if BUILD_STATIC
+AM_CFLAGS += $(fpic_CFLAGS)
+endif
+AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libdwelf
+VERSION = 1
+
+lib_LIBRARIES = libdw.a
+noinst_LIBRARIES = libdw_pic.a
+noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so)
+
+include_HEADERS = dwarf.h
+pkginclude_HEADERS = libdw.h known-dwarf.h
+
+libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
+		  dwarf_getpubnames.c dwarf_getabbrev.c dwarf_tag.c \
+		  dwarf_error.c dwarf_nextcu.c dwarf_diename.c dwarf_offdie.c \
+		  dwarf_attr.c dwarf_formstring.c \
+		  dwarf_abbrev_hash.c dwarf_sig8_hash.c \
+		  dwarf_attr_integrate.c dwarf_hasattr_integrate.c \
+		  dwarf_child.c dwarf_haschildren.c dwarf_formaddr.c \
+		  dwarf_formudata.c dwarf_formsdata.c dwarf_lowpc.c \
+		  dwarf_entrypc.c dwarf_haspc.c dwarf_highpc.c dwarf_ranges.c \
+		  dwarf_formref.c dwarf_formref_die.c dwarf_siblingof.c \
+		  dwarf_dieoffset.c dwarf_cuoffset.c dwarf_diecu.c \
+		  dwarf_hasattr.c dwarf_hasform.c \
+		  dwarf_whatform.c dwarf_whatattr.c \
+		  dwarf_bytesize.c dwarf_arrayorder.c dwarf_bitsize.c \
+		  dwarf_bitoffset.c dwarf_srclang.c dwarf_getabbrevtag.c \
+		  dwarf_getabbrevcode.c dwarf_abbrevhaschildren.c \
+		  dwarf_getattrcnt.c dwarf_getabbrevattr.c \
+		  dwarf_getsrclines.c dwarf_getsrc_die.c \
+		  dwarf_getscopes.c dwarf_getscopes_die.c dwarf_getscopevar.c \
+		  dwarf_linesrc.c dwarf_lineno.c dwarf_lineaddr.c \
+		  dwarf_linecol.c dwarf_linebeginstatement.c \
+		  dwarf_lineendsequence.c dwarf_lineblock.c \
+		  dwarf_lineprologueend.c dwarf_lineepiloguebegin.c \
+		  dwarf_lineisa.c dwarf_linediscriminator.c \
+		  dwarf_lineop_index.c dwarf_line_file.c \
+		  dwarf_onesrcline.c dwarf_formblock.c \
+		  dwarf_getsrcfiles.c dwarf_filesrc.c dwarf_getsrcdirs.c \
+		  dwarf_getlocation.c dwarf_getstring.c dwarf_offabbrev.c \
+		  dwarf_getaranges.c dwarf_onearange.c dwarf_getarangeinfo.c \
+		  dwarf_getarange_addr.c dwarf_getattrs.c dwarf_formflag.c \
+		  dwarf_getmacros.c dwarf_macro_getparamcnt.c	\
+		  dwarf_macro_opcode.c dwarf_macro_param.c	\
+		  dwarf_macro_param1.c dwarf_macro_param2.c	\
+		  dwarf_macro_getsrcfiles.c			\
+		  dwarf_addrdie.c dwarf_getfuncs.c \
+		  dwarf_decl_file.c dwarf_decl_line.c dwarf_decl_column.c \
+		  dwarf_func_inline.c dwarf_getsrc_file.c \
+		  libdw_findcu.c libdw_form.c libdw_alloc.c \
+		  libdw_visit_scopes.c \
+		  dwarf_entry_breakpoints.c \
+		  dwarf_next_cfi.c \
+		  cie.c fde.c cfi.c frame-cache.c \
+		  dwarf_frame_info.c dwarf_frame_cfa.c dwarf_frame_register.c \
+		  dwarf_cfi_addrframe.c \
+		  dwarf_getcfi.c dwarf_getcfi_elf.c dwarf_cfi_end.c \
+		  dwarf_aggregate_size.c dwarf_getlocation_implicit_pointer.c \
+		  dwarf_getlocation_die.c dwarf_getlocation_attr.c \
+		  dwarf_getalt.c dwarf_setalt.c dwarf_cu_getdwarf.c \
+		  dwarf_cu_die.c dwarf_peel_type.c dwarf_default_lower_bound.c
+
+if MAINTAINER_MODE
+BUILT_SOURCES = $(srcdir)/known-dwarf.h
+MAINTAINERCLEANFILES = $(srcdir)/known-dwarf.h
+$(srcdir)/known-dwarf.h: $(top_srcdir)/config/known-dwarf.awk $(srcdir)/dwarf.h
+	gawk -f $^ > $@.new
+	mv -f $@.new $@
+endif
+
+libdw_pic_a_SOURCES =
+am_libdw_pic_a_OBJECTS = $(libdw_a_SOURCES:.c=.os)
+
+libdw_so_LIBS = libdw_pic.a ../libdwelf/libdwelf_pic.a \
+	  ../libdwfl/libdwfl_pic.a ../libebl/libebl.a
+libdw_so_DEPS = ../lib/libeu.a ../libelf/libelf.so
+libdw_so_LDLIBS = $(libdw_so_DEPS) -ldl -lz $(argp_LDADD) $(zip_LIBS)
+libdw_so_SOURCES =
+libdw.so$(EXEEXT): $(srcdir)/libdw.map $(libdw_so_LIBS) $(libdw_so_DEPS)
+# The rpath is necessary for libebl because its $ORIGIN use will
+# not fly in a setuid executable that links in libdw.
+	$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
+		-Wl,--soname,$@.$(VERSION) \
+		-Wl,--enable-new-dtags,-rpath,$(pkglibdir) \
+		-Wl,--version-script,$<,--no-undefined \
+		-Wl,--whole-archive $(libdw_so_LIBS) -Wl,--no-whole-archive \
+		$(libdw_so_LDLIBS)
+	@$(textrel_check)
+	$(AM_V_at)ln -fs $@ $@.$(VERSION)
+
+install: install-am libdw.so
+	$(mkinstalldirs) $(DESTDIR)$(libdir)
+	$(INSTALL_PROGRAM) libdw.so $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so
+	ln -fs libdw-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdw.so.$(VERSION)
+	ln -fs libdw.so.$(VERSION) $(DESTDIR)$(libdir)/libdw.so
+
+uninstall: uninstall-am
+	rm -f $(DESTDIR)$(libdir)/libdw-$(PACKAGE_VERSION).so
+	rm -f $(DESTDIR)$(libdir)/libdw.so.$(VERSION)
+	rm -f $(DESTDIR)$(libdir)/libdw.so
+	rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
+
+libdwfl_objects = $(shell $(AR) t ../libdwfl/libdwfl.a)
+libdw_a_LIBADD = $(addprefix ../libdwfl/,$(libdwfl_objects))
+
+libdwelf_objects = $(shell $(AR) t ../libdwelf/libdwelf.a)
+libdw_a_LIBADD += $(addprefix ../libdwelf/,$(libdwelf_objects))
+
+noinst_HEADERS = libdwP.h memory-access.h dwarf_abbrev_hash.h \
+		 dwarf_sig8_hash.h cfi.h encoded-value.h
+
+EXTRA_DIST = libdw.map
+
+MOSTLYCLEANFILES = $(am_libdw_pic_a_OBJECTS) libdw.so.$(VERSION)
diff --git a/third_party/elfutils/libdw/cfi.c b/third_party/elfutils/libdw/cfi.c
new file mode 100644
index 0000000..341e055
--- /dev/null
+++ b/third_party/elfutils/libdw/cfi.c
@@ -0,0 +1,518 @@
+/* CFI program execution.
+   Copyright (C) 2009-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "../libebl/libebl.h"
+#include "cfi.h"
+#include "memory-access.h"
+#include "encoded-value.h"
+#include "system.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CFI_PRIMARY_MAX	0x3f
+
+static Dwarf_Frame *
+duplicate_frame_state (const Dwarf_Frame *original,
+		       Dwarf_Frame *prev)
+{
+  size_t size = offsetof (Dwarf_Frame, regs[original->nregs]);
+  Dwarf_Frame *copy = malloc (size);
+  if (likely (copy != NULL))
+    {
+      memcpy (copy, original, size);
+      copy->prev = prev;
+    }
+  return copy;
+}
+
+static inline bool
+enough_registers (Dwarf_Word reg, Dwarf_Frame **pfs, int *result)
+{
+  /* Don't allow insanely large register numbers.  268435456 registers
+     should be enough for anybody.  And very large values might overflow
+     the array size and offsetof calculations below.  */
+  if (unlikely (reg >= INT32_MAX / sizeof ((*pfs)->regs[0])))
+    {
+      *result = DWARF_E_INVALID_CFI;
+      return false;
+    }
+
+  if ((*pfs)->nregs <= reg)
+    {
+       size_t size = offsetof (Dwarf_Frame, regs[reg + 1]);
+       Dwarf_Frame *bigger = realloc (*pfs, size);
+       if (unlikely (bigger == NULL))
+         {
+           *result = DWARF_E_NOMEM;
+           return false;
+         }
+       else
+         {
+           eu_static_assert (reg_unspecified == 0);
+           memset (bigger->regs + bigger->nregs, 0,
+                   (reg + 1 - bigger->nregs) * sizeof bigger->regs[0]);
+           bigger->nregs = reg + 1;
+           *pfs = bigger;
+         }
+     }
+  return true;
+}
+
+static inline void
+require_cfa_offset (Dwarf_Frame *fs)
+{
+  if (unlikely (fs->cfa_rule != cfa_offset))
+    fs->cfa_rule = cfa_invalid;
+}
+
+/* Returns a DWARF_E_* error code, usually NOERROR or INVALID_CFI.
+   Frees *STATE on failure.  */
+static int
+execute_cfi (Dwarf_CFI *cache,
+	     const struct dwarf_cie *cie,
+	     Dwarf_Frame **state,
+	     const uint8_t *program, const uint8_t *const end, bool abi_cfi,
+	     Dwarf_Addr loc, Dwarf_Addr find_pc)
+{
+  /* The caller should not give us anything out of range.  */
+  assert (loc <= find_pc);
+
+  int result = DWARF_E_NOERROR;
+
+#define cfi_assert(ok) do {						      \
+    if (likely (ok)) break;						      \
+    result = DWARF_E_INVALID_CFI;					      \
+    goto out;								      \
+  } while (0)
+
+  Dwarf_Frame *fs = *state;
+
+#define register_rule(regno, r_rule, r_value) do {	\
+    if (unlikely (! enough_registers (regno, &fs, &result)))	\
+      goto out;						\
+    fs->regs[regno].rule = reg_##r_rule;		\
+    fs->regs[regno].value = (r_value);			\
+  } while (0)
+
+  while (program < end)
+    {
+      uint8_t opcode = *program++;
+      Dwarf_Word regno;
+      Dwarf_Word offset;
+      Dwarf_Word sf_offset;
+      Dwarf_Word operand = opcode & CFI_PRIMARY_MAX;
+      switch (opcode)
+	{
+	  /* These cases move LOC, i.e. "create a new table row".  */
+
+	case DW_CFA_advance_loc1:
+	  operand = *program++;
+	  FALLTHROUGH;
+	case DW_CFA_advance_loc + 0 ... DW_CFA_advance_loc + CFI_PRIMARY_MAX:
+	advance_loc:
+	  loc += operand * cie->code_alignment_factor;
+	  break;
+
+	case DW_CFA_advance_loc2:
+	  cfi_assert (program + 2 <= end);
+	  operand = read_2ubyte_unaligned_inc (cache, program);
+	  goto advance_loc;
+	case DW_CFA_advance_loc4:
+	  cfi_assert (program + 4 <= end);
+	  operand = read_4ubyte_unaligned_inc (cache, program);
+	  goto advance_loc;
+	case DW_CFA_MIPS_advance_loc8:
+	  cfi_assert (program + 8 <= end);
+	  operand = read_8ubyte_unaligned_inc (cache, program);
+	  goto advance_loc;
+
+	case DW_CFA_set_loc:
+	  if (likely (!read_encoded_value (cache, cie->fde_encoding,
+					   &program, &loc)))
+	    break;
+	  result = INTUSE(dwarf_errno) ();
+	  goto out;
+
+	  /* Now all following cases affect this row, but do not touch LOC.
+	     These cases end with 'continue'.  We only get out of the
+	     switch block for the row-copying (LOC-moving) cases above.  */
+
+	case DW_CFA_def_cfa:
+	  get_uleb128 (operand, program, end);
+	  cfi_assert (program < end);
+	  get_uleb128 (offset, program, end);
+	def_cfa:
+	  fs->cfa_rule = cfa_offset;
+	  fs->cfa_val_reg = operand;
+	  fs->cfa_val_offset = offset;
+	  /* Prime the rest of the Dwarf_Op so dwarf_frame_cfa can use it.  */
+	  fs->cfa_data.offset.atom = DW_OP_bregx;
+	  fs->cfa_data.offset.offset = 0;
+	  continue;
+
+	case DW_CFA_def_cfa_register:
+	  get_uleb128 (regno, program, end);
+	  require_cfa_offset (fs);
+	  fs->cfa_val_reg = regno;
+	  continue;
+
+	case DW_CFA_def_cfa_sf:
+	  get_uleb128 (operand, program, end);
+	  cfi_assert (program < end);
+	  get_sleb128 (sf_offset, program, end);
+	  offset = sf_offset * cie->data_alignment_factor;
+	  goto def_cfa;
+
+	case DW_CFA_def_cfa_offset:
+	  get_uleb128 (offset, program, end);
+	def_cfa_offset:
+	  require_cfa_offset (fs);
+	  fs->cfa_val_offset = offset;
+	  continue;
+
+	case DW_CFA_def_cfa_offset_sf:
+	  get_sleb128 (sf_offset, program, end);
+	  offset = sf_offset * cie->data_alignment_factor;
+	  goto def_cfa_offset;
+
+	case DW_CFA_def_cfa_expression:
+	  /* DW_FORM_block is a ULEB128 length followed by that many bytes.  */
+	  get_uleb128 (operand, program, end);
+	  cfi_assert (operand <= (Dwarf_Word) (end - program));
+	  fs->cfa_rule = cfa_expr;
+	  fs->cfa_data.expr.data = (unsigned char *) program;
+	  fs->cfa_data.expr.length = operand;
+	  program += operand;
+	  continue;
+
+	case DW_CFA_undefined:
+	  get_uleb128 (regno, program, end);
+	  register_rule (regno, undefined, 0);
+	  continue;
+
+	case DW_CFA_same_value:
+	  get_uleb128 (regno, program, end);
+	  register_rule (regno, same_value, 0);
+	  continue;
+
+	case DW_CFA_offset_extended:
+	  get_uleb128 (operand, program, end);
+	  cfi_assert (program < end);
+	case DW_CFA_offset + 0 ... DW_CFA_offset + CFI_PRIMARY_MAX:
+	  get_uleb128 (offset, program, end);
+	  offset *= cie->data_alignment_factor;
+	offset_extended:
+	  register_rule (operand, offset, offset);
+	  continue;
+
+	case DW_CFA_offset_extended_sf:
+	  get_uleb128 (operand, program, end);
+	  get_sleb128 (sf_offset, program, end);
+	offset_extended_sf:
+	  offset = sf_offset * cie->data_alignment_factor;
+	  goto offset_extended;
+
+	case DW_CFA_GNU_negative_offset_extended:
+	  /* GNU extension obsoleted by DW_CFA_offset_extended_sf.  */
+	  get_uleb128 (operand, program, end);
+	  cfi_assert (program < end);
+	  get_uleb128 (offset, program, end);
+	  sf_offset = -offset;
+	  goto offset_extended_sf;
+
+	case DW_CFA_val_offset:
+	  get_uleb128 (operand, program, end);
+	  cfi_assert (program < end);
+	  get_uleb128 (offset, program, end);
+	  offset *= cie->data_alignment_factor;
+	val_offset:
+	  register_rule (operand, val_offset, offset);
+	  continue;
+
+	case DW_CFA_val_offset_sf:
+	  get_uleb128 (operand, program, end);
+	  cfi_assert (program < end);
+	  get_sleb128 (sf_offset, program, end);
+	  offset = sf_offset * cie->data_alignment_factor;
+	  goto val_offset;
+
+	case DW_CFA_register:
+	  get_uleb128 (regno, program, end);
+	  cfi_assert (program < end);
+	  get_uleb128 (operand, program, end);
+	  register_rule (regno, register, operand);
+	  continue;
+
+	case DW_CFA_expression:
+	  /* Expression rule relies on section data, abi_cfi cannot use it.  */
+	  assert (! abi_cfi);
+	  get_uleb128 (regno, program, end);
+	  offset = program - (const uint8_t *) cache->data->d.d_buf;
+	  /* DW_FORM_block is a ULEB128 length followed by that many bytes.  */
+	  cfi_assert (program < end);
+	  get_uleb128 (operand, program, end);
+	  cfi_assert (operand <= (Dwarf_Word) (end - program));
+	  program += operand;
+	  register_rule (regno, expression, offset);
+	  continue;
+
+	case DW_CFA_val_expression:
+	  /* Expression rule relies on section data, abi_cfi cannot use it.  */
+	  assert (! abi_cfi);
+	  get_uleb128 (regno, program, end);
+	  /* DW_FORM_block is a ULEB128 length followed by that many bytes.  */
+	  offset = program - (const uint8_t *) cache->data->d.d_buf;
+	  get_uleb128 (operand, program, end);
+	  cfi_assert (operand <= (Dwarf_Word) (end - program));
+	  program += operand;
+	  register_rule (regno, val_expression, offset);
+	  continue;
+
+	case DW_CFA_restore_extended:
+	  get_uleb128 (operand, program, end);
+	  FALLTHROUGH;
+	case DW_CFA_restore + 0 ... DW_CFA_restore + CFI_PRIMARY_MAX:
+
+	  if (unlikely (abi_cfi) && likely (opcode == DW_CFA_restore))
+	    {
+	      /* Special case hack to give backend abi_cfi a shorthand.  */
+	      cache->default_same_value = true;
+	      continue;
+	    }
+
+	  /* This can't be used in the CIE's own initial instructions.  */
+	  cfi_assert (cie->initial_state != NULL);
+
+	  /* Restore the CIE's initial rule for this register.  */
+	  if (unlikely (! enough_registers (operand, &fs, &result)))
+	    goto out;
+	  if (cie->initial_state->nregs > operand)
+	    fs->regs[operand] = cie->initial_state->regs[operand];
+	  else
+	    fs->regs[operand].rule = reg_unspecified;
+	  continue;
+
+	case DW_CFA_remember_state:
+	  {
+	    /* Duplicate the state and chain the copy on.  */
+	    Dwarf_Frame *copy = duplicate_frame_state (fs, fs);
+	    if (unlikely (copy == NULL))
+	      {
+		result = DWARF_E_NOMEM;
+		goto out;
+	      }
+	    fs = copy;
+	    continue;
+	  }
+
+	case DW_CFA_restore_state:
+	  {
+	    /* Pop the current state off and use the old one instead.  */
+	    Dwarf_Frame *prev = fs->prev;
+	    cfi_assert (prev != NULL);
+	    free (fs);
+	    fs = prev;
+	    continue;
+	  }
+
+	case DW_CFA_nop:
+	  continue;
+
+	case DW_CFA_GNU_window_save:
+	  /* This is magic shorthand used only by SPARC.  It's equivalent
+	     to a bunch of DW_CFA_register and DW_CFA_offset operations.  */
+	  if (unlikely (! enough_registers (31, &fs, &result)))
+	    goto out;
+	  for (regno = 8; regno < 16; ++regno)
+	    {
+	      /* Find each %oN in %iN.  */
+	      fs->regs[regno].rule = reg_register;
+	      fs->regs[regno].value = regno + 16;
+	    }
+	  unsigned int address_size = (cache->e_ident[EI_CLASS] == ELFCLASS32
+				       ? 4 : 8);
+	  for (; regno < 32; ++regno)
+	    {
+	      /* Find %l0..%l7 and %i0..%i7 in a block at the CFA.  */
+	      fs->regs[regno].rule = reg_offset;
+	      fs->regs[regno].value = (regno - 16) * address_size;
+	    }
+	  continue;
+
+	case DW_CFA_GNU_args_size:
+	  /* XXX is this useful for anything? */
+	  get_uleb128 (operand, program, end);
+	  continue;
+
+	default:
+	  cfi_assert (false);
+	  continue;
+	}
+
+      /* We get here only for the cases that have just moved LOC.  */
+      cfi_assert (cie->initial_state != NULL);
+      if (find_pc >= loc)
+	/* This advance has not yet reached FIND_PC.  */
+	fs->start = loc;
+      else
+	{
+	  /* We have just advanced past the address we're looking for.
+	     The state currently described is what we want to see.  */
+	  fs->end = loc;
+	  break;
+	}
+    }
+
+  /* "The end of the instruction stream can be thought of as a
+     DW_CFA_set_loc (initial_location + address_range) instruction."
+     (DWARF 3.0 Section 6.4.3)
+
+     When we fall off the end of the program without an advance_loc/set_loc
+     that put us past FIND_PC, the final state left by the FDE program
+     applies to this address (the caller ensured it was inside the FDE).
+     This address (FDE->end) is already in FS->end as set by the caller.  */
+
+#undef register_rule
+#undef cfi_assert
+
+ out:
+
+  /* Pop any remembered states left on the stack.  */
+  while (fs->prev != NULL)
+    {
+      Dwarf_Frame *prev = fs->prev;
+      fs->prev = prev->prev;
+      free (prev);
+    }
+
+  if (likely (result == DWARF_E_NOERROR))
+    *state = fs;
+  else
+    free (fs);
+
+  return result;
+}
+
+static int
+cie_cache_initial_state (Dwarf_CFI *cache, struct dwarf_cie *cie)
+{
+  int result = DWARF_E_NOERROR;
+
+  if (likely (cie->initial_state != NULL))
+    return result;
+
+  /* This CIE has not been used before.  Play out its initial
+     instructions and cache the initial state that results.
+     First we'll let the backend fill in the default initial
+     state for this machine's ABI.  */
+
+  Dwarf_CIE abi_info = { DW_CIE_ID_64, NULL, NULL, 1, 1, -1, "", NULL, 0, 0 };
+
+  /* Make sure we have a backend handle cached.  */
+  if (unlikely (cache->ebl == NULL))
+    {
+      cache->ebl = ebl_openbackend (cache->data->s->elf);
+      if (unlikely (cache->ebl == NULL))
+	cache->ebl = (void *) -1l;
+    }
+
+  /* Fetch the ABI's default CFI program.  */
+  if (likely (cache->ebl != (void *) -1l)
+      && unlikely (ebl_abi_cfi (cache->ebl, &abi_info) < 0))
+    return DWARF_E_UNKNOWN_ERROR;
+
+  Dwarf_Frame *cie_fs = calloc (1, sizeof (Dwarf_Frame));
+  if (unlikely (cie_fs == NULL))
+    return DWARF_E_NOMEM;
+
+  /* If the default state of any register is not "undefined"
+     (i.e. call-clobbered), then the backend supplies instructions
+     for the standard initial state.  */
+  if (abi_info.initial_instructions_end > abi_info.initial_instructions)
+    {
+      /* Dummy CIE for backend's instructions.  */
+      struct dwarf_cie abi_cie =
+	{
+	  .code_alignment_factor = abi_info.code_alignment_factor,
+	  .data_alignment_factor = abi_info.data_alignment_factor,
+	};
+      result = execute_cfi (cache, &abi_cie, &cie_fs,
+			    abi_info.initial_instructions,
+			    abi_info.initial_instructions_end, true,
+			    0, (Dwarf_Addr) -1l);
+    }
+
+  /* Now run the CIE's initial instructions.  */
+  if (cie->initial_instructions_end > cie->initial_instructions
+      && likely (result == DWARF_E_NOERROR))
+    result = execute_cfi (cache, cie, &cie_fs,
+			  cie->initial_instructions,
+			  cie->initial_instructions_end, false,
+			  0, (Dwarf_Addr) -1l);
+
+  if (likely (result == DWARF_E_NOERROR))
+    {
+      /* Now we have the initial state of things that all
+	 FDEs using this CIE will start from.  */
+      cie_fs->cache = cache;
+      cie->initial_state = cie_fs;
+    }
+
+  return result;
+}
+
+int
+internal_function
+__libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde,
+			  Dwarf_Addr address, Dwarf_Frame **frame)
+{
+  int result = cie_cache_initial_state (cache, fde->cie);
+  if (likely (result == DWARF_E_NOERROR))
+    {
+      Dwarf_Frame *fs = duplicate_frame_state (fde->cie->initial_state, NULL);
+      if (unlikely (fs == NULL))
+	return DWARF_E_NOMEM;
+
+      fs->fde = fde;
+      fs->start = fde->start;
+      fs->end = fde->end;
+
+      result = execute_cfi (cache, fde->cie, &fs,
+			    fde->instructions, fde->instructions_end, false,
+			    fde->start, address);
+      if (likely (result == DWARF_E_NOERROR))
+	*frame = fs;
+    }
+  return result;
+}
diff --git a/third_party/elfutils/libdw/cfi.h b/third_party/elfutils/libdw/cfi.h
new file mode 100644
index 0000000..1ebf2dc
--- /dev/null
+++ b/third_party/elfutils/libdw/cfi.h
@@ -0,0 +1,236 @@
+/* Internal definitions for libdw CFI interpreter.
+   Copyright (C) 2009-2010, 2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _UNWINDP_H
+#define _UNWINDP_H 1
+
+#include "libdwP.h"
+#include "libelfP.h"
+struct ebl;
+
+/* Cached CIE representation.  */
+struct dwarf_cie
+{
+  Dwarf_Off offset;	 /* Our position, as seen in FDEs' CIE_pointer.  */
+
+  Dwarf_Word code_alignment_factor;
+  Dwarf_Sword data_alignment_factor;
+  Dwarf_Word return_address_register;
+
+  size_t fde_augmentation_data_size;
+
+  // play out to initial state
+  const uint8_t *initial_instructions;
+  const uint8_t *initial_instructions_end;
+
+  const Dwarf_Frame *initial_state;
+
+  uint8_t fde_encoding;		/* DW_EH_PE_* for addresses in FDEs.  */
+  uint8_t lsda_encoding;    /* DW_EH_PE_* for LSDA in FDE augmentation.  */
+
+  bool sized_augmentation_data;	/* Saw 'z': FDEs have self-sized data.  */
+  bool signal_frame;		/* Saw 'S': FDE is for a signal frame.  */
+};
+
+/* Cached FDE representation.  */
+struct dwarf_fde
+{
+  struct dwarf_cie *cie;
+
+  /* This FDE describes PC values in [start, end).  */
+  Dwarf_Addr start;
+  Dwarf_Addr end;
+
+  const uint8_t *instructions;
+  const uint8_t *instructions_end;
+};
+
+/* This holds everything we cache about the CFI from each ELF file's
+   .debug_frame or .eh_frame section.  */
+struct Dwarf_CFI_s
+{
+  /* Dwarf handle we came from.  If null, this is .eh_frame data.  */
+  Dwarf *dbg;
+#define CFI_IS_EH(cfi)	((cfi)->dbg == NULL)
+
+  /* Data of the .debug_frame or .eh_frame section.  */
+  Elf_Data_Scn *data;
+  const unsigned char *e_ident;	/* For EI_DATA and EI_CLASS.  */
+
+  Dwarf_Addr frame_vaddr;  /* DW_EH_PE_pcrel, address of frame section.  */
+  Dwarf_Addr textrel;		/* DW_EH_PE_textrel base address.  */
+  Dwarf_Addr datarel;		/* DW_EH_PE_datarel base address.  */
+
+  /* Location of next unread entry in the section.  */
+  Dwarf_Off next_offset;
+
+  /* Search tree for the CIEs, indexed by CIE_pointer (section offset).  */
+  void *cie_tree;
+
+  /* Search tree for the FDEs, indexed by PC address.  */
+  void *fde_tree;
+
+  /* Search tree for parsed DWARF expressions, indexed by raw pointer.  */
+  void *expr_tree;
+
+  /* Backend hook.  */
+  struct ebl *ebl;
+
+  /* Binary search table in .eh_frame_hdr section.  */
+  const uint8_t *search_table;
+  size_t search_table_len;
+  Dwarf_Addr search_table_vaddr;
+  size_t search_table_entries;
+  uint8_t search_table_encoding;
+
+  /* True if the file has a byte order different from the host.  */
+  bool other_byte_order;
+
+  /* Default rule for registers not previously mentioned
+     is same_value, not undefined.  */
+  bool default_same_value;
+};
+
+
+enum dwarf_frame_rule
+  {
+    reg_unspecified,		/* Uninitialized state.  */
+    reg_undefined,		/* DW_CFA_undefined */
+    reg_same_value,		/* DW_CFA_same_value */
+    reg_offset,			/* DW_CFA_offset_extended et al */
+    reg_val_offset,		/* DW_CFA_val_offset et al */
+    reg_register,		/* DW_CFA_register */
+    reg_expression,		/* DW_CFA_expression */
+    reg_val_expression,		/* DW_CFA_val_expression */
+  };
+
+/* This describes what we know about an individual register.  */
+struct dwarf_frame_register
+{
+  enum dwarf_frame_rule rule:3;
+
+  /* The meaning of the value bits depends on the rule:
+
+	Rule			Value
+	----			-----
+	undefined		unused
+	same_value		unused
+	offset(N)		N	(register saved at CFA + value)
+	val_offset(N)		N	(register = CFA + value)
+	register(R)		R	(register = register #value)
+	expression(E)		section offset of DW_FORM_block containing E
+					(register saved at address E computes)
+	val_expression(E)	section offset of DW_FORM_block containing E
+					(register = value E computes)
+  */
+  Dwarf_Sword value:(sizeof (Dwarf_Sword) * 8 - 3);
+};
+
+/* This holds instructions for unwinding frame at a particular PC location
+   described by an FDE.  */
+struct Dwarf_Frame_s
+{
+  /* This frame description covers PC values in [start, end).  */
+  Dwarf_Addr start;
+  Dwarf_Addr end;
+
+  Dwarf_CFI *cache;
+
+  /* Previous state saved by DW_CFA_remember_state, or .cie->initial_state,
+     or NULL in an initial_state pseudo-frame.  */
+  Dwarf_Frame *prev;
+
+  /* The FDE that generated this frame state.  This points to its CIE,
+     which has the return_address_register and signal_frame flag.  */
+  struct dwarf_fde *fde;
+
+  /* The CFA is unknown, is R+N, or is computed by a DWARF expression.
+     A bogon in the CFI can indicate an invalid/incalculable rule.
+     We store that as cfa_invalid rather than barfing when processing it,
+     so callers can ignore the bogon unless they really need that CFA.  */
+  enum { cfa_undefined, cfa_offset, cfa_expr, cfa_invalid } cfa_rule;
+  union
+  {
+    Dwarf_Op offset;
+    Dwarf_Block expr;
+  } cfa_data;
+  /* We store an offset rule as a DW_OP_bregx operation.  */
+#define cfa_val_reg	cfa_data.offset.number
+#define cfa_val_offset	cfa_data.offset.number2
+
+  size_t nregs;
+  struct dwarf_frame_register regs[];
+};
+
+
+/* Clean up the data structure and all it points to.  */
+extern void __libdw_destroy_frame_cache (Dwarf_CFI *cache)
+  __nonnull_attribute__ (1) internal_function;
+
+/* Enter a CIE encountered while reading through for FDEs.  */
+extern void __libdw_intern_cie (Dwarf_CFI *cache, Dwarf_Off offset,
+				const Dwarf_CIE *info)
+  __nonnull_attribute__ (1, 3) internal_function;
+
+/* Look up a CIE_pointer for random access.  */
+extern struct dwarf_cie *__libdw_find_cie (Dwarf_CFI *cache, Dwarf_Off offset)
+  __nonnull_attribute__ (1) internal_function;
+
+
+/* Look for an FDE covering the given PC address.  */
+extern struct dwarf_fde *__libdw_find_fde (Dwarf_CFI *cache,
+					   Dwarf_Addr address)
+  __nonnull_attribute__ (1) internal_function;
+
+/* Look for an FDE by its offset in the section.  */
+extern struct dwarf_fde *__libdw_fde_by_offset (Dwarf_CFI *cache,
+						Dwarf_Off offset)
+  __nonnull_attribute__ (1) internal_function;
+
+/* Process the FDE that contains the given PC address,
+   to yield the frame state when stopped there.
+   The return value is a DWARF_E_* error code.  */
+extern int __libdw_frame_at_address (Dwarf_CFI *cache, struct dwarf_fde *fde,
+				     Dwarf_Addr address, Dwarf_Frame **frame)
+  __nonnull_attribute__ (1, 2, 4) internal_function;
+
+
+/* Dummy struct for memory-access.h macros.  */
+#define BYTE_ORDER_DUMMY(var, e_ident)					      \
+  const struct { bool other_byte_order; } var =				      \
+    { ((BYTE_ORDER == LITTLE_ENDIAN && e_ident[EI_DATA] == ELFDATA2MSB)       \
+       || (BYTE_ORDER == BIG_ENDIAN && e_ident[EI_DATA] == ELFDATA2LSB)) }
+
+
+INTDECL (dwarf_next_cfi)
+INTDECL (dwarf_getcfi)
+INTDECL (dwarf_getcfi_elf)
+INTDECL (dwarf_cfi_end)
+INTDECL (dwarf_cfi_addrframe)
+
+#endif	/* unwindP.h */
diff --git a/third_party/elfutils/libdw/cie.c b/third_party/elfutils/libdw/cie.c
new file mode 100644
index 0000000..1b0aae7
--- /dev/null
+++ b/third_party/elfutils/libdw/cie.c
@@ -0,0 +1,196 @@
+/* CIE reading.
+   Copyright (C) 2009-2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include "encoded-value.h"
+#include <assert.h>
+#include <search.h>
+#include <stdlib.h>
+
+
+static int
+compare_cie (const void *a, const void *b)
+{
+  const struct dwarf_cie *cie1 = a;
+  const struct dwarf_cie *cie2 = b;
+  if (cie1->offset < cie2->offset)
+    return -1;
+  if (cie1->offset > cie2->offset)
+    return 1;
+  return 0;
+}
+
+/* There is no CIE at OFFSET in the tree.  Add it.  */
+static struct dwarf_cie *
+intern_new_cie (Dwarf_CFI *cache, Dwarf_Off offset, const Dwarf_CIE *info)
+{
+  struct dwarf_cie *cie = malloc (sizeof (struct dwarf_cie));
+  if (cie == NULL)
+    {
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return NULL;
+    }
+
+  cie->offset = offset;
+  cie->code_alignment_factor = info->code_alignment_factor;
+  cie->data_alignment_factor = info->data_alignment_factor;
+  cie->return_address_register = info->return_address_register;
+
+  cie->fde_augmentation_data_size = 0;
+  cie->sized_augmentation_data = false;
+  cie->signal_frame = false;
+
+  cie->fde_encoding = DW_EH_PE_absptr;
+  cie->lsda_encoding = DW_EH_PE_omit;
+
+  /* Grok the augmentation string and its data.  */
+  const uint8_t *data = info->augmentation_data;
+  for (const char *ap = info->augmentation; *ap != '\0'; ++ap)
+    {
+      uint8_t encoding;
+      switch (*ap)
+	{
+	case 'z':
+	  cie->sized_augmentation_data = true;
+	  continue;
+
+	case 'S':
+	  cie->signal_frame = true;
+	  continue;
+
+	case 'L':		/* LSDA pointer encoding byte.  */
+	  cie->lsda_encoding = *data++;
+	  if (!cie->sized_augmentation_data)
+	    cie->fde_augmentation_data_size
+	      += encoded_value_size (&cache->data->d, cache->e_ident,
+				     cie->lsda_encoding, NULL);
+	  continue;
+
+	case 'R':		/* FDE address encoding byte.  */
+	  cie->fde_encoding = *data++;
+	  continue;
+
+	case 'P':		/* Skip personality routine.  */
+	  encoding = *data++;
+	  data += encoded_value_size (&cache->data->d, cache->e_ident,
+				      encoding, data);
+	  continue;
+
+	default:
+	  /* Unknown augmentation string.  If we have 'z' we can ignore it,
+	     otherwise we must bail out.  */
+	  if (cie->sized_augmentation_data)
+	    continue;
+	}
+      /* We only get here when we need to bail out.  */
+      break;
+    }
+
+  if ((cie->fde_encoding & 0x0f) == DW_EH_PE_absptr)
+    {
+      /* Canonicalize encoding to a specific size.  */
+      assert (DW_EH_PE_absptr == 0);
+
+      /* XXX should get from dwarf_next_cfi with v4 header.  */
+      uint_fast8_t address_size
+	= cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+      switch (address_size)
+	{
+	case 8:
+	  cie->fde_encoding |= DW_EH_PE_udata8;
+	  break;
+	case 4:
+	  cie->fde_encoding |= DW_EH_PE_udata4;
+	  break;
+	default:
+	  free (cie);
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  return NULL;
+	}
+    }
+
+  /* Save the initial instructions to be played out into initial state.  */
+  cie->initial_instructions = info->initial_instructions;
+  cie->initial_instructions_end = info->initial_instructions_end;
+  cie->initial_state = NULL;
+
+  /* Add the new entry to the search tree.  */
+  if (tsearch (cie, &cache->cie_tree, &compare_cie) == NULL)
+    {
+      free (cie);
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return NULL;
+    }
+
+  return cie;
+}
+
+/* Look up a CIE_pointer for random access.  */
+struct dwarf_cie *
+internal_function
+__libdw_find_cie (Dwarf_CFI *cache, Dwarf_Off offset)
+{
+  const struct dwarf_cie cie_key = { .offset = offset };
+  struct dwarf_cie **found = tfind (&cie_key, &cache->cie_tree, &compare_cie);
+  if (found != NULL)
+    return *found;
+
+  /* We have not read this CIE yet.  Go find it.  */
+  Dwarf_Off next_offset = offset;
+  Dwarf_CFI_Entry entry;
+  int result = INTUSE(dwarf_next_cfi) (cache->e_ident,
+				       &cache->data->d, CFI_IS_EH (cache),
+				       offset, &next_offset, &entry);
+  if (result != 0 || entry.cie.CIE_id != DW_CIE_ID_64)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  /* If this happened to be what we would have read next, notice it.  */
+  if (cache->next_offset == offset)
+    cache->next_offset = next_offset;
+
+  return intern_new_cie (cache, offset, &entry.cie);
+}
+
+/* Enter a CIE encountered while reading through for FDEs.  */
+void
+internal_function
+__libdw_intern_cie (Dwarf_CFI *cache, Dwarf_Off offset, const Dwarf_CIE *info)
+{
+  const struct dwarf_cie cie_key = { .offset = offset };
+  struct dwarf_cie **found = tfind (&cie_key, &cache->cie_tree, &compare_cie);
+  if (found == NULL)
+    /* We have not read this CIE yet.  Enter it.  */
+    (void) intern_new_cie (cache, offset, info);
+}
diff --git a/third_party/elfutils/libdw/dwarf.h b/third_party/elfutils/libdw/dwarf.h
new file mode 100644
index 0000000..8edf719
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf.h
@@ -0,0 +1,911 @@
+/* This file defines standard DWARF types, structures, and macros.
+   Copyright (C) 2000-2011, 2014, 2016, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _DWARF_H
+#define	_DWARF_H 1
+
+/* DWARF tags.  */
+enum
+  {
+    DW_TAG_array_type = 0x01,
+    DW_TAG_class_type = 0x02,
+    DW_TAG_entry_point = 0x03,
+    DW_TAG_enumeration_type = 0x04,
+    DW_TAG_formal_parameter = 0x05,
+    /* 0x06 reserved.  */
+    /* 0x07 reserved.  */
+    DW_TAG_imported_declaration = 0x08,
+    /* 0x09 reserved.  */
+    DW_TAG_label = 0x0a,
+    DW_TAG_lexical_block = 0x0b,
+    /* 0x0c reserved.  */
+    DW_TAG_member = 0x0d,
+    /* 0x0e reserved.  */
+    DW_TAG_pointer_type = 0x0f,
+    DW_TAG_reference_type = 0x10,
+    DW_TAG_compile_unit = 0x11,
+    DW_TAG_string_type = 0x12,
+    DW_TAG_structure_type = 0x13,
+    /* 0x14 reserved.  */
+    DW_TAG_subroutine_type = 0x15,
+    DW_TAG_typedef = 0x16,
+    DW_TAG_union_type = 0x17,
+    DW_TAG_unspecified_parameters = 0x18,
+    DW_TAG_variant = 0x19,
+    DW_TAG_common_block = 0x1a,
+    DW_TAG_common_inclusion = 0x1b,
+    DW_TAG_inheritance = 0x1c,
+    DW_TAG_inlined_subroutine = 0x1d,
+    DW_TAG_module = 0x1e,
+    DW_TAG_ptr_to_member_type = 0x1f,
+    DW_TAG_set_type = 0x20,
+    DW_TAG_subrange_type = 0x21,
+    DW_TAG_with_stmt = 0x22,
+    DW_TAG_access_declaration = 0x23,
+    DW_TAG_base_type = 0x24,
+    DW_TAG_catch_block = 0x25,
+    DW_TAG_const_type = 0x26,
+    DW_TAG_constant = 0x27,
+    DW_TAG_enumerator = 0x28,
+    DW_TAG_file_type = 0x29,
+    DW_TAG_friend = 0x2a,
+    DW_TAG_namelist = 0x2b,
+    DW_TAG_namelist_item = 0x2c,
+    DW_TAG_packed_type = 0x2d,
+    DW_TAG_subprogram = 0x2e,
+    DW_TAG_template_type_parameter = 0x2f,
+    DW_TAG_template_value_parameter = 0x30,
+    DW_TAG_thrown_type = 0x31,
+    DW_TAG_try_block = 0x32,
+    DW_TAG_variant_part = 0x33,
+    DW_TAG_variable = 0x34,
+    DW_TAG_volatile_type = 0x35,
+    DW_TAG_dwarf_procedure = 0x36,
+    DW_TAG_restrict_type = 0x37,
+    DW_TAG_interface_type = 0x38,
+    DW_TAG_namespace = 0x39,
+    DW_TAG_imported_module = 0x3a,
+    DW_TAG_unspecified_type = 0x3b,
+    DW_TAG_partial_unit = 0x3c,
+    DW_TAG_imported_unit = 0x3d,
+    /* 0x3e reserved.  Was DW_TAG_mutable_type.  */
+    DW_TAG_condition = 0x3f,
+    DW_TAG_shared_type = 0x40,
+    DW_TAG_type_unit = 0x41,
+    DW_TAG_rvalue_reference_type = 0x42,
+    DW_TAG_template_alias = 0x43,
+    DW_TAG_coarray_type = 0x44,
+    DW_TAG_generic_subrange = 0x45,
+    DW_TAG_dynamic_type = 0x46,
+    DW_TAG_atomic_type = 0x47,
+    DW_TAG_call_site = 0x48,
+    DW_TAG_call_site_parameter = 0x49,
+    DW_TAG_skeleton_unit = 0x4a,
+    DW_TAG_immutable_type = 0x4b,
+
+    DW_TAG_lo_user = 0x4080,
+
+    DW_TAG_MIPS_loop = 0x4081,
+    DW_TAG_format_label = 0x4101,
+    DW_TAG_function_template = 0x4102,
+    DW_TAG_class_template = 0x4103,
+
+    DW_TAG_GNU_BINCL = 0x4104,
+    DW_TAG_GNU_EINCL = 0x4105,
+
+    DW_TAG_GNU_template_template_param = 0x4106,
+    DW_TAG_GNU_template_parameter_pack = 0x4107,
+    DW_TAG_GNU_formal_parameter_pack = 0x4108,
+    DW_TAG_GNU_call_site = 0x4109,
+    DW_TAG_GNU_call_site_parameter = 0x410a,
+
+    DW_TAG_hi_user = 0xffff
+  };
+
+
+/* Children determination encodings.  */
+enum
+  {
+    DW_CHILDREN_no = 0,
+    DW_CHILDREN_yes = 1
+  };
+
+
+/* DWARF attributes encodings.  */
+enum
+  {
+    DW_AT_sibling = 0x01,
+    DW_AT_location = 0x02,
+    DW_AT_name = 0x03,
+    /* 0x04 reserved.  */
+    /* 0x05 reserved.  */
+    /* 0x06 reserved.  */
+    /* 0x07 reserved.  */
+    /* 0x08 reserved.  */
+    DW_AT_ordering = 0x09,
+    /* 0x0a reserved.  */
+    DW_AT_byte_size = 0x0b,
+    DW_AT_bit_offset = 0x0c,  /* Deprecated in DWARF4.  */
+    DW_AT_bit_size = 0x0d,
+    /* 0x0e reserved.  */
+    /* 0x0f reserved.  */
+    DW_AT_stmt_list = 0x10,
+    DW_AT_low_pc = 0x11,
+    DW_AT_high_pc = 0x12,
+    DW_AT_language = 0x13,
+    /* 0x14 reserved.  */
+    DW_AT_discr = 0x15,
+    DW_AT_discr_value = 0x16,
+    DW_AT_visibility = 0x17,
+    DW_AT_import = 0x18,
+    DW_AT_string_length = 0x19,
+    DW_AT_common_reference = 0x1a,
+    DW_AT_comp_dir = 0x1b,
+    DW_AT_const_value = 0x1c,
+    DW_AT_containing_type = 0x1d,
+    DW_AT_default_value = 0x1e,
+    /* 0x1f reserved.  */
+    DW_AT_inline = 0x20,
+    DW_AT_is_optional = 0x21,
+    DW_AT_lower_bound = 0x22,
+    /* 0x23 reserved.  */
+    /* 0x24 reserved.  */
+    DW_AT_producer = 0x25,
+    /* 0x26 reserved.  */
+    DW_AT_prototyped = 0x27,
+    /* 0x28 reserved.  */
+    /* 0x29 reserved.  */
+    DW_AT_return_addr = 0x2a,
+    /* 0x2b reserved.  */
+    DW_AT_start_scope = 0x2c,
+    /* 0x2d reserved.  */
+    DW_AT_bit_stride = 0x2e,
+    DW_AT_upper_bound = 0x2f,
+    /* 0x30 reserved.  */
+    DW_AT_abstract_origin = 0x31,
+    DW_AT_accessibility = 0x32,
+    DW_AT_address_class = 0x33,
+    DW_AT_artificial = 0x34,
+    DW_AT_base_types = 0x35,
+    DW_AT_calling_convention = 0x36,
+    DW_AT_count = 0x37,
+    DW_AT_data_member_location = 0x38,
+    DW_AT_decl_column = 0x39,
+    DW_AT_decl_file = 0x3a,
+    DW_AT_decl_line = 0x3b,
+    DW_AT_declaration = 0x3c,
+    DW_AT_discr_list = 0x3d,
+    DW_AT_encoding = 0x3e,
+    DW_AT_external = 0x3f,
+    DW_AT_frame_base = 0x40,
+    DW_AT_friend = 0x41,
+    DW_AT_identifier_case = 0x42,
+    DW_AT_macro_info = 0x43, /* Deprecated in DWARF5.  */
+    DW_AT_namelist_item = 0x44,
+    DW_AT_priority = 0x45,
+    DW_AT_segment = 0x46,
+    DW_AT_specification = 0x47,
+    DW_AT_static_link = 0x48,
+    DW_AT_type = 0x49,
+    DW_AT_use_location = 0x4a,
+    DW_AT_variable_parameter = 0x4b,
+    DW_AT_virtuality = 0x4c,
+    DW_AT_vtable_elem_location = 0x4d,
+    DW_AT_allocated = 0x4e,
+    DW_AT_associated = 0x4f,
+    DW_AT_data_location = 0x50,
+    DW_AT_byte_stride = 0x51,
+    DW_AT_entry_pc = 0x52,
+    DW_AT_use_UTF8 = 0x53,
+    DW_AT_extension = 0x54,
+    DW_AT_ranges = 0x55,
+    DW_AT_trampoline = 0x56,
+    DW_AT_call_column = 0x57,
+    DW_AT_call_file = 0x58,
+    DW_AT_call_line = 0x59,
+    DW_AT_description = 0x5a,
+    DW_AT_binary_scale = 0x5b,
+    DW_AT_decimal_scale = 0x5c,
+    DW_AT_small = 0x5d,
+    DW_AT_decimal_sign = 0x5e,
+    DW_AT_digit_count = 0x5f,
+    DW_AT_picture_string = 0x60,
+    DW_AT_mutable = 0x61,
+    DW_AT_threads_scaled = 0x62,
+    DW_AT_explicit = 0x63,
+    DW_AT_object_pointer = 0x64,
+    DW_AT_endianity = 0x65,
+    DW_AT_elemental = 0x66,
+    DW_AT_pure = 0x67,
+    DW_AT_recursive = 0x68,
+    DW_AT_signature = 0x69,
+    DW_AT_main_subprogram = 0x6a,
+    DW_AT_data_bit_offset = 0x6b,
+    DW_AT_const_expr = 0x6c,
+    DW_AT_enum_class = 0x6d,
+    DW_AT_linkage_name = 0x6e,
+    DW_AT_string_length_bit_size = 0x6f,
+    DW_AT_string_length_byte_size = 0x70,
+    DW_AT_rank = 0x71,
+    DW_AT_str_offsets_base = 0x72,
+    DW_AT_addr_base = 0x73,
+    DW_AT_rnglists_base = 0x74,
+    /* 0x75 reserved.  */
+    DW_AT_dwo_name = 0x76,
+    DW_AT_reference = 0x77,
+    DW_AT_rvalue_reference = 0x78,
+    DW_AT_macros = 0x79,
+    DW_AT_call_all_calls = 0x7a,
+    DW_AT_call_all_source_calls = 0x7b,
+    DW_AT_call_all_tail_calls = 0x7c,
+    DW_AT_call_return_pc = 0x7d,
+    DW_AT_call_value = 0x7e,
+    DW_AT_call_origin = 0x7f,
+    DW_AT_call_parameter = 0x80,
+    DW_AT_call_pc = 0x81,
+    DW_AT_call_tail_call = 0x82,
+    DW_AT_call_target = 0x83,
+    DW_AT_call_target_clobbered = 0x84,
+    DW_AT_call_data_location = 0x85,
+    DW_AT_call_data_value = 0x86,
+    DW_AT_noreturn = 0x87,
+    DW_AT_alignment = 0x88,
+    DW_AT_export_symbols = 0x89,
+    DW_AT_deleted = 0x8a,
+    DW_AT_defaulted = 0x8b,
+    DW_AT_loclists_base = 0x8c,
+
+    DW_AT_lo_user = 0x2000,
+
+    DW_AT_MIPS_fde = 0x2001,
+    DW_AT_MIPS_loop_begin = 0x2002,
+    DW_AT_MIPS_tail_loop_begin = 0x2003,
+    DW_AT_MIPS_epilog_begin = 0x2004,
+    DW_AT_MIPS_loop_unroll_factor = 0x2005,
+    DW_AT_MIPS_software_pipeline_depth = 0x2006,
+    DW_AT_MIPS_linkage_name = 0x2007,
+    DW_AT_MIPS_stride = 0x2008,
+    DW_AT_MIPS_abstract_name = 0x2009,
+    DW_AT_MIPS_clone_origin = 0x200a,
+    DW_AT_MIPS_has_inlines = 0x200b,
+    DW_AT_MIPS_stride_byte = 0x200c,
+    DW_AT_MIPS_stride_elem = 0x200d,
+    DW_AT_MIPS_ptr_dopetype = 0x200e,
+    DW_AT_MIPS_allocatable_dopetype = 0x200f,
+    DW_AT_MIPS_assumed_shape_dopetype = 0x2010,
+    DW_AT_MIPS_assumed_size = 0x2011,
+
+    /* GNU extensions.  */
+    DW_AT_sf_names = 0x2101,
+    DW_AT_src_info = 0x2102,
+    DW_AT_mac_info = 0x2103,
+    DW_AT_src_coords = 0x2104,
+    DW_AT_body_begin = 0x2105,
+    DW_AT_body_end = 0x2106,
+    DW_AT_GNU_vector = 0x2107,
+    DW_AT_GNU_guarded_by = 0x2108,
+    DW_AT_GNU_pt_guarded_by = 0x2109,
+    DW_AT_GNU_guarded = 0x210a,
+    DW_AT_GNU_pt_guarded = 0x210b,
+    DW_AT_GNU_locks_excluded = 0x210c,
+    DW_AT_GNU_exclusive_locks_required = 0x210d,
+    DW_AT_GNU_shared_locks_required = 0x210e,
+    DW_AT_GNU_odr_signature = 0x210f,
+    DW_AT_GNU_template_name = 0x2110,
+    DW_AT_GNU_call_site_value = 0x2111,
+    DW_AT_GNU_call_site_data_value = 0x2112,
+    DW_AT_GNU_call_site_target = 0x2113,
+    DW_AT_GNU_call_site_target_clobbered = 0x2114,
+    DW_AT_GNU_tail_call = 0x2115,
+    DW_AT_GNU_all_tail_call_sites = 0x2116,
+    DW_AT_GNU_all_call_sites = 0x2117,
+    DW_AT_GNU_all_source_call_sites = 0x2118,
+    DW_AT_GNU_macros = 0x2119,
+    DW_AT_GNU_deleted = 0x211a,
+
+    DW_AT_hi_user = 0x3fff
+  };
+
+/* Old unofficially attribute names.  Should not be used.
+   Will not appear in known-dwarf.h  */
+
+/* DWARF1 array subscripts and element data types.  */
+#define DW_AT_subscr_data	0x0a
+/* DWARF1 enumeration literals.  */
+#define DW_AT_element_list	0x0f
+/* DWARF1 reference for variable to member structure, class or union.  */
+#define DW_AT_member		0x14
+
+/* DWARF form encodings.  */
+enum
+  {
+    DW_FORM_addr = 0x01,
+    DW_FORM_block2 = 0x03,
+    DW_FORM_block4 = 0x04,
+    DW_FORM_data2 = 0x05,
+    DW_FORM_data4 = 0x06,
+    DW_FORM_data8 = 0x07,
+    DW_FORM_string = 0x08,
+    DW_FORM_block = 0x09,
+    DW_FORM_block1 = 0x0a,
+    DW_FORM_data1 = 0x0b,
+    DW_FORM_flag = 0x0c,
+    DW_FORM_sdata = 0x0d,
+    DW_FORM_strp = 0x0e,
+    DW_FORM_udata = 0x0f,
+    DW_FORM_ref_addr = 0x10,
+    DW_FORM_ref1 = 0x11,
+    DW_FORM_ref2 = 0x12,
+    DW_FORM_ref4 = 0x13,
+    DW_FORM_ref8 = 0x14,
+    DW_FORM_ref_udata = 0x15,
+    DW_FORM_indirect = 0x16,
+    DW_FORM_sec_offset = 0x17,
+    DW_FORM_exprloc = 0x18,
+    DW_FORM_flag_present = 0x19,
+    DW_FORM_ref_sig8 = 0x20,
+
+    DW_FORM_GNU_ref_alt = 0x1f20, /* offset in alternate .debuginfo.  */
+    DW_FORM_GNU_strp_alt = 0x1f21 /* offset in alternate .debug_str. */
+  };
+
+
+/* DWARF location operation encodings.  */
+enum
+  {
+    DW_OP_addr = 0x03,		/* Constant address.  */
+    DW_OP_deref = 0x06,
+    DW_OP_const1u = 0x08,	/* Unsigned 1-byte constant.  */
+    DW_OP_const1s = 0x09,	/* Signed 1-byte constant.  */
+    DW_OP_const2u = 0x0a,	/* Unsigned 2-byte constant.  */
+    DW_OP_const2s = 0x0b,	/* Signed 2-byte constant.  */
+    DW_OP_const4u = 0x0c,	/* Unsigned 4-byte constant.  */
+    DW_OP_const4s = 0x0d,	/* Signed 4-byte constant.  */
+    DW_OP_const8u = 0x0e,	/* Unsigned 8-byte constant.  */
+    DW_OP_const8s = 0x0f,	/* Signed 8-byte constant.  */
+    DW_OP_constu = 0x10,	/* Unsigned LEB128 constant.  */
+    DW_OP_consts = 0x11,	/* Signed LEB128 constant.  */
+    DW_OP_dup = 0x12,
+    DW_OP_drop = 0x13,
+    DW_OP_over = 0x14,
+    DW_OP_pick = 0x15,		/* 1-byte stack index.  */
+    DW_OP_swap = 0x16,
+    DW_OP_rot = 0x17,
+    DW_OP_xderef = 0x18,
+    DW_OP_abs = 0x19,
+    DW_OP_and = 0x1a,
+    DW_OP_div = 0x1b,
+    DW_OP_minus = 0x1c,
+    DW_OP_mod = 0x1d,
+    DW_OP_mul = 0x1e,
+    DW_OP_neg = 0x1f,
+    DW_OP_not = 0x20,
+    DW_OP_or = 0x21,
+    DW_OP_plus = 0x22,
+    DW_OP_plus_uconst = 0x23,	/* Unsigned LEB128 addend.  */
+    DW_OP_shl = 0x24,
+    DW_OP_shr = 0x25,
+    DW_OP_shra = 0x26,
+    DW_OP_xor = 0x27,
+    DW_OP_bra = 0x28,		/* Signed 2-byte constant.  */
+    DW_OP_eq = 0x29,
+    DW_OP_ge = 0x2a,
+    DW_OP_gt = 0x2b,
+    DW_OP_le = 0x2c,
+    DW_OP_lt = 0x2d,
+    DW_OP_ne = 0x2e,
+    DW_OP_skip = 0x2f,		/* Signed 2-byte constant.  */
+    DW_OP_lit0 = 0x30,		/* Literal 0.  */
+    DW_OP_lit1 = 0x31,		/* Literal 1.  */
+    DW_OP_lit2 = 0x32,		/* Literal 2.  */
+    DW_OP_lit3 = 0x33,		/* Literal 3.  */
+    DW_OP_lit4 = 0x34,		/* Literal 4.  */
+    DW_OP_lit5 = 0x35,		/* Literal 5.  */
+    DW_OP_lit6 = 0x36,		/* Literal 6.  */
+    DW_OP_lit7 = 0x37,		/* Literal 7.  */
+    DW_OP_lit8 = 0x38,		/* Literal 8.  */
+    DW_OP_lit9 = 0x39,		/* Literal 9.  */
+    DW_OP_lit10 = 0x3a,		/* Literal 10.  */
+    DW_OP_lit11 = 0x3b,		/* Literal 11.  */
+    DW_OP_lit12 = 0x3c,		/* Literal 12.  */
+    DW_OP_lit13 = 0x3d,		/* Literal 13.  */
+    DW_OP_lit14 = 0x3e,		/* Literal 14.  */
+    DW_OP_lit15 = 0x3f,		/* Literal 15.  */
+    DW_OP_lit16 = 0x40,		/* Literal 16.  */
+    DW_OP_lit17 = 0x41,		/* Literal 17.  */
+    DW_OP_lit18 = 0x42,		/* Literal 18.  */
+    DW_OP_lit19 = 0x43,		/* Literal 19.  */
+    DW_OP_lit20 = 0x44,		/* Literal 20.  */
+    DW_OP_lit21 = 0x45,		/* Literal 21.  */
+    DW_OP_lit22 = 0x46,		/* Literal 22.  */
+    DW_OP_lit23 = 0x47,		/* Literal 23.  */
+    DW_OP_lit24 = 0x48,		/* Literal 24.  */
+    DW_OP_lit25 = 0x49,		/* Literal 25.  */
+    DW_OP_lit26 = 0x4a,		/* Literal 26.  */
+    DW_OP_lit27 = 0x4b,		/* Literal 27.  */
+    DW_OP_lit28 = 0x4c,		/* Literal 28.  */
+    DW_OP_lit29 = 0x4d,		/* Literal 29.  */
+    DW_OP_lit30 = 0x4e,		/* Literal 30.  */
+    DW_OP_lit31 = 0x4f,		/* Literal 31.  */
+    DW_OP_reg0 = 0x50,		/* Register 0.  */
+    DW_OP_reg1 = 0x51,		/* Register 1.  */
+    DW_OP_reg2 = 0x52,		/* Register 2.  */
+    DW_OP_reg3 = 0x53,		/* Register 3.  */
+    DW_OP_reg4 = 0x54,		/* Register 4.  */
+    DW_OP_reg5 = 0x55,		/* Register 5.  */
+    DW_OP_reg6 = 0x56,		/* Register 6.  */
+    DW_OP_reg7 = 0x57,		/* Register 7.  */
+    DW_OP_reg8 = 0x58,		/* Register 8.  */
+    DW_OP_reg9 = 0x59,		/* Register 9.  */
+    DW_OP_reg10 = 0x5a,		/* Register 10.  */
+    DW_OP_reg11 = 0x5b,		/* Register 11.  */
+    DW_OP_reg12 = 0x5c,		/* Register 12.  */
+    DW_OP_reg13 = 0x5d,		/* Register 13.  */
+    DW_OP_reg14 = 0x5e,		/* Register 14.  */
+    DW_OP_reg15 = 0x5f,		/* Register 15.  */
+    DW_OP_reg16 = 0x60,		/* Register 16.  */
+    DW_OP_reg17 = 0x61,		/* Register 17.  */
+    DW_OP_reg18 = 0x62,		/* Register 18.  */
+    DW_OP_reg19 = 0x63,		/* Register 19.  */
+    DW_OP_reg20 = 0x64,		/* Register 20.  */
+    DW_OP_reg21 = 0x65,		/* Register 21.  */
+    DW_OP_reg22 = 0x66,		/* Register 22.  */
+    DW_OP_reg23 = 0x67,		/* Register 24.  */
+    DW_OP_reg24 = 0x68,		/* Register 24.  */
+    DW_OP_reg25 = 0x69,		/* Register 25.  */
+    DW_OP_reg26 = 0x6a,		/* Register 26.  */
+    DW_OP_reg27 = 0x6b,		/* Register 27.  */
+    DW_OP_reg28 = 0x6c,		/* Register 28.  */
+    DW_OP_reg29 = 0x6d,		/* Register 29.  */
+    DW_OP_reg30 = 0x6e,		/* Register 30.  */
+    DW_OP_reg31 = 0x6f,		/* Register 31.  */
+    DW_OP_breg0 = 0x70,		/* Base register 0.  */
+    DW_OP_breg1 = 0x71,		/* Base register 1.  */
+    DW_OP_breg2 = 0x72,		/* Base register 2.  */
+    DW_OP_breg3 = 0x73,		/* Base register 3.  */
+    DW_OP_breg4 = 0x74,		/* Base register 4.  */
+    DW_OP_breg5 = 0x75,		/* Base register 5.  */
+    DW_OP_breg6 = 0x76,		/* Base register 6.  */
+    DW_OP_breg7 = 0x77,		/* Base register 7.  */
+    DW_OP_breg8 = 0x78,		/* Base register 8.  */
+    DW_OP_breg9 = 0x79,		/* Base register 9.  */
+    DW_OP_breg10 = 0x7a,	/* Base register 10.  */
+    DW_OP_breg11 = 0x7b,	/* Base register 11.  */
+    DW_OP_breg12 = 0x7c,	/* Base register 12.  */
+    DW_OP_breg13 = 0x7d,	/* Base register 13.  */
+    DW_OP_breg14 = 0x7e,	/* Base register 14.  */
+    DW_OP_breg15 = 0x7f,	/* Base register 15.  */
+    DW_OP_breg16 = 0x80,	/* Base register 16.  */
+    DW_OP_breg17 = 0x81,	/* Base register 17.  */
+    DW_OP_breg18 = 0x82,	/* Base register 18.  */
+    DW_OP_breg19 = 0x83,	/* Base register 19.  */
+    DW_OP_breg20 = 0x84,	/* Base register 20.  */
+    DW_OP_breg21 = 0x85,	/* Base register 21.  */
+    DW_OP_breg22 = 0x86,	/* Base register 22.  */
+    DW_OP_breg23 = 0x87,	/* Base register 23.  */
+    DW_OP_breg24 = 0x88,	/* Base register 24.  */
+    DW_OP_breg25 = 0x89,	/* Base register 25.  */
+    DW_OP_breg26 = 0x8a,	/* Base register 26.  */
+    DW_OP_breg27 = 0x8b,	/* Base register 27.  */
+    DW_OP_breg28 = 0x8c,	/* Base register 28.  */
+    DW_OP_breg29 = 0x8d,	/* Base register 29.  */
+    DW_OP_breg30 = 0x8e,	/* Base register 30.  */
+    DW_OP_breg31 = 0x8f,	/* Base register 31.  */
+    DW_OP_regx = 0x90,		/* Unsigned LEB128 register.  */
+    DW_OP_fbreg = 0x91,		/* Signed LEB128 offset.  */
+    DW_OP_bregx = 0x92,		/* ULEB128 register followed by SLEB128 off. */
+    DW_OP_piece = 0x93,		/* ULEB128 size of piece addressed. */
+    DW_OP_deref_size = 0x94,	/* 1-byte size of data retrieved.  */
+    DW_OP_xderef_size = 0x95,	/* 1-byte size of data retrieved.  */
+    DW_OP_nop = 0x96,
+    DW_OP_push_object_address = 0x97,
+    DW_OP_call2 = 0x98,
+    DW_OP_call4 = 0x99,
+    DW_OP_call_ref = 0x9a,
+    DW_OP_form_tls_address = 0x9b,/* TLS offset to address in current thread */
+    DW_OP_call_frame_cfa = 0x9c,/* CFA as determined by CFI.  */
+    DW_OP_bit_piece = 0x9d,	/* ULEB128 size and ULEB128 offset in bits.  */
+    DW_OP_implicit_value = 0x9e, /* DW_FORM_block follows opcode.  */
+    DW_OP_stack_value = 0x9f,	 /* No operands, special like DW_OP_piece.  */
+
+    /* GNU extensions.  */
+    DW_OP_GNU_push_tls_address = 0xe0,
+    DW_OP_GNU_uninit = 0xf0,
+    DW_OP_GNU_encoded_addr = 0xf1,
+    DW_OP_GNU_implicit_pointer = 0xf2,
+    DW_OP_GNU_entry_value = 0xf3,
+    DW_OP_GNU_const_type = 0xf4,
+    DW_OP_GNU_regval_type = 0xf5,
+    DW_OP_GNU_deref_type = 0xf6,
+    DW_OP_GNU_convert = 0xf7,
+    DW_OP_GNU_reinterpret = 0xf9,
+    DW_OP_GNU_parameter_ref = 0xfa,
+    DW_OP_GNU_variable_value = 0xfd,
+
+    DW_OP_lo_user = 0xe0,	/* Implementation-defined range start.  */
+    DW_OP_hi_user = 0xff	/* Implementation-defined range end.  */
+  };
+
+
+/* DWARF base type encodings.  */
+enum
+  {
+    DW_ATE_void = 0x0,
+    DW_ATE_address = 0x1,
+    DW_ATE_boolean = 0x2,
+    DW_ATE_complex_float = 0x3,
+    DW_ATE_float = 0x4,
+    DW_ATE_signed = 0x5,
+    DW_ATE_signed_char = 0x6,
+    DW_ATE_unsigned = 0x7,
+    DW_ATE_unsigned_char = 0x8,
+    DW_ATE_imaginary_float = 0x9,
+    DW_ATE_packed_decimal = 0xa,
+    DW_ATE_numeric_string = 0xb,
+    DW_ATE_edited = 0xc,
+    DW_ATE_signed_fixed = 0xd,
+    DW_ATE_unsigned_fixed = 0xe,
+    DW_ATE_decimal_float = 0xf,
+    DW_ATE_UTF = 0x10,
+    DW_ATE_UCS = 0x11,
+    DW_ATE_ASCII = 0x12,
+
+    DW_ATE_lo_user = 0x80,
+    DW_ATE_hi_user = 0xff
+  };
+
+
+/* DWARF decimal sign encodings.  */
+enum
+  {
+    DW_DS_unsigned = 1,
+    DW_DS_leading_overpunch = 2,
+    DW_DS_trailing_overpunch = 3,
+    DW_DS_leading_separate = 4,
+    DW_DS_trailing_separate = 5,
+  };
+
+
+/* DWARF endianity encodings.  */
+enum
+  {
+    DW_END_default = 0,
+    DW_END_big = 1,
+    DW_END_little = 2,
+
+    DW_END_lo_user = 0x40,
+    DW_END_hi_user = 0xff
+  };
+
+
+/* DWARF accessibility encodings.  */
+enum
+  {
+    DW_ACCESS_public = 1,
+    DW_ACCESS_protected = 2,
+    DW_ACCESS_private = 3
+  };
+
+
+/* DWARF visibility encodings.  */
+enum
+  {
+    DW_VIS_local = 1,
+    DW_VIS_exported = 2,
+    DW_VIS_qualified = 3
+  };
+
+
+/* DWARF virtuality encodings.  */
+enum
+  {
+    DW_VIRTUALITY_none = 0,
+    DW_VIRTUALITY_virtual = 1,
+    DW_VIRTUALITY_pure_virtual = 2
+  };
+
+
+/* DWARF language encodings.  */
+enum
+  {
+    DW_LANG_C89 = 0x0001,	     /* ISO C:1989 */
+    DW_LANG_C = 0x0002,		     /* C */
+    DW_LANG_Ada83 = 0x0003,	     /* ISO Ada:1983 */
+    DW_LANG_C_plus_plus	= 0x0004,    /* ISO C++:1998 */
+    DW_LANG_Cobol74 = 0x0005,	     /* ISO Cobol:1974 */
+    DW_LANG_Cobol85 = 0x0006,	     /* ISO Cobol:1985 */
+    DW_LANG_Fortran77 = 0x0007,	     /* ISO FORTRAN 77 */
+    DW_LANG_Fortran90 = 0x0008,	     /* ISO Fortran 90 */
+    DW_LANG_Pascal83 = 0x0009,	     /* ISO Pascal:1983 */
+    DW_LANG_Modula2 = 0x000a,	     /* ISO Modula-2:1996 */
+    DW_LANG_Java = 0x000b,	     /* Java */
+    DW_LANG_C99 = 0x000c,	     /* ISO C:1999 */
+    DW_LANG_Ada95 = 0x000d,	     /* ISO Ada:1995 */
+    DW_LANG_Fortran95 = 0x000e,	     /* ISO Fortran 95 */
+    DW_LANG_PLI = 0x000f,	     /* ISO PL/1:1976 */
+    DW_LANG_ObjC = 0x0010,	     /* Objective-C */
+    DW_LANG_ObjC_plus_plus = 0x0011, /* Objective-C++ */
+    DW_LANG_UPC = 0x0012,	     /* Unified Parallel C */
+    DW_LANG_D = 0x0013,		     /* D */
+    DW_LANG_Python = 0x0014,	     /* Python */
+    DW_LANG_OpenCL = 0x0015,	     /* OpenCL */
+    DW_LANG_Go = 0x0016,	     /* Go */
+    DW_LANG_Modula3 = 0x0017,	     /* Modula-3 */
+    DW_LANG_Haskell = 0x0018,	     /* Haskell */
+    DW_LANG_C_plus_plus_03 = 0x0019, /* ISO C++:2003 */
+    DW_LANG_C_plus_plus_11 = 0x001a, /* ISO C++:2011 */
+    DW_LANG_OCaml = 0x001b,	     /* OCaml */
+    DW_LANG_Rust = 0x001c,	     /* Rust */
+    DW_LANG_C11 = 0x001d,	     /* ISO C:2011 */
+    DW_LANG_Swift = 0x001e,	     /* Swift */
+    DW_LANG_Julia = 0x001f,	     /* Julia */
+    DW_LANG_Dylan = 0x0020,	     /* Dylan */
+    DW_LANG_C_plus_plus_14 = 0x0021, /* ISO C++:2014 */
+    DW_LANG_Fortran03 = 0x0022,	     /* ISO/IEC 1539-1:2004 */
+    DW_LANG_Fortran08 = 0x0023,	     /* ISO/IEC 1539-1:2010 */
+    DW_LANG_RenderScript = 0x0024,   /* RenderScript Kernal Language */
+    DW_LANG_BLISS = 0x0025,	     /* BLISS */
+
+    DW_LANG_lo_user = 0x8000,
+    DW_LANG_Mips_Assembler = 0x8001, /* Assembler */
+    DW_LANG_hi_user = 0xffff
+  };
+
+/* Old (typo) '1' != 'I'.  */
+#define DW_LANG_PL1 DW_LANG_PLI
+
+/* DWARF identifier case encodings.  */
+enum
+  {
+    DW_ID_case_sensitive = 0,
+    DW_ID_up_case = 1,
+    DW_ID_down_case = 2,
+    DW_ID_case_insensitive = 3
+  };
+
+
+/* DWARF calling conventions encodings.
+   Used as values of DW_AT_calling_convention for subroutines
+   (normal, program or nocall) or structures, unions and class types
+   (normal, reference or value).  */
+enum
+  {
+    DW_CC_normal = 0x1,
+    DW_CC_program = 0x2,
+    DW_CC_nocall = 0x3,
+    DW_CC_pass_by_reference = 0x4,
+    DW_CC_pass_by_value = 0x5,
+    DW_CC_lo_user = 0x40,
+    DW_CC_hi_user = 0xff
+  };
+
+
+/* DWARF inline encodings.  */
+enum
+  {
+    DW_INL_not_inlined = 0,
+    DW_INL_inlined = 1,
+    DW_INL_declared_not_inlined = 2,
+    DW_INL_declared_inlined = 3
+  };
+
+
+/* DWARF ordering encodings.  */
+enum
+  {
+    DW_ORD_row_major = 0,
+    DW_ORD_col_major = 1
+  };
+
+
+/* DWARF discriminant descriptor encodings.  */
+enum
+  {
+    DW_DSC_label = 0,
+    DW_DSC_range = 1
+  };
+
+/* DWARF defaulted member function encodings.  */
+enum
+  {
+    DW_DEFAULTED_no = 0,
+    DW_DEFAULTED_in_class = 1,
+    DW_DEFAULTED_out_of_class = 2
+  };
+
+
+/* DWARF standard opcode encodings.  */
+enum
+  {
+    DW_LNS_copy = 1,
+    DW_LNS_advance_pc = 2,
+    DW_LNS_advance_line = 3,
+    DW_LNS_set_file = 4,
+    DW_LNS_set_column = 5,
+    DW_LNS_negate_stmt = 6,
+    DW_LNS_set_basic_block = 7,
+    DW_LNS_const_add_pc = 8,
+    DW_LNS_fixed_advance_pc = 9,
+    DW_LNS_set_prologue_end = 10,
+    DW_LNS_set_epilogue_begin = 11,
+    DW_LNS_set_isa = 12
+  };
+
+
+/* DWARF extended opcode encodings.  */
+enum
+  {
+    DW_LNE_end_sequence = 1,
+    DW_LNE_set_address = 2,
+    DW_LNE_define_file = 3,
+    DW_LNE_set_discriminator = 4,
+
+    DW_LNE_lo_user = 128,
+    DW_LNE_hi_user = 255
+  };
+
+
+/* DWARF macinfo type encodings.  */
+enum
+  {
+    DW_MACINFO_define = 1,
+    DW_MACINFO_undef = 2,
+    DW_MACINFO_start_file = 3,
+    DW_MACINFO_end_file = 4,
+    DW_MACINFO_vendor_ext = 255
+  };
+
+
+/* DWARF debug_macro type encodings.  */
+enum
+  {
+    DW_MACRO_define = 0x01,
+    DW_MACRO_undef = 0x02,
+    DW_MACRO_start_file = 0x03,
+    DW_MACRO_end_file = 0x04,
+    DW_MACRO_define_strp = 0x05,
+    DW_MACRO_undef_strp = 0x06,
+    DW_MACRO_import = 0x07,
+    DW_MACRO_define_sup = 0x08,
+    DW_MACRO_undef_sup = 0x09,
+    DW_MACRO_import_sup = 0x0a,
+    DW_MACRO_define_strx = 0x0b,
+    DW_MACRO_undef_strx = 0x0c,
+    DW_MACRO_lo_user = 0xe0,
+    DW_MACRO_hi_user = 0xff
+  };
+
+/* Old GNU extension names for DWARF5 debug_macro type encodings.
+   There are no equivalents for the supplementary object file (sup)
+   and indirect string references (strx).  */
+#define DW_MACRO_GNU_define		 DW_MACRO_define
+#define DW_MACRO_GNU_undef		 DW_MACRO_undef
+#define DW_MACRO_GNU_start_file		 DW_MACRO_start_file
+#define DW_MACRO_GNU_end_file		 DW_MACRO_end_file
+#define DW_MACRO_GNU_define_indirect	 DW_MACRO_define_strp
+#define DW_MACRO_GNU_undef_indirect	 DW_MACRO_undef_strp
+#define DW_MACRO_GNU_transparent_include DW_MACRO_import
+#define DW_MACRO_GNU_lo_user		 DW_MACRO_lo_user
+#define DW_MACRO_GNU_hi_user		 DW_MACRO_hi_user
+
+
+/* DWARF call frame instruction encodings.  */
+enum
+  {
+    DW_CFA_advance_loc = 0x40,
+    DW_CFA_offset = 0x80,
+    DW_CFA_restore = 0xc0,
+    DW_CFA_extended = 0,
+
+    DW_CFA_nop = 0x00,
+    DW_CFA_set_loc = 0x01,
+    DW_CFA_advance_loc1 = 0x02,
+    DW_CFA_advance_loc2 = 0x03,
+    DW_CFA_advance_loc4 = 0x04,
+    DW_CFA_offset_extended = 0x05,
+    DW_CFA_restore_extended = 0x06,
+    DW_CFA_undefined = 0x07,
+    DW_CFA_same_value = 0x08,
+    DW_CFA_register = 0x09,
+    DW_CFA_remember_state = 0x0a,
+    DW_CFA_restore_state = 0x0b,
+    DW_CFA_def_cfa = 0x0c,
+    DW_CFA_def_cfa_register = 0x0d,
+    DW_CFA_def_cfa_offset = 0x0e,
+    DW_CFA_def_cfa_expression = 0x0f,
+    DW_CFA_expression = 0x10,
+    DW_CFA_offset_extended_sf = 0x11,
+    DW_CFA_def_cfa_sf = 0x12,
+    DW_CFA_def_cfa_offset_sf = 0x13,
+    DW_CFA_val_offset = 0x14,
+    DW_CFA_val_offset_sf = 0x15,
+    DW_CFA_val_expression = 0x16,
+
+    DW_CFA_low_user = 0x1c,
+    DW_CFA_MIPS_advance_loc8 = 0x1d,
+    DW_CFA_GNU_window_save = 0x2d,
+    DW_CFA_GNU_args_size = 0x2e,
+    DW_CFA_GNU_negative_offset_extended = 0x2f,
+    DW_CFA_high_user = 0x3f
+  };
+
+/* ID indicating CIE as opposed to FDE in .debug_frame.  */
+enum
+  {
+    DW_CIE_ID_32 = 0xffffffffU,		 /* In 32-bit format CIE header.  */
+    DW_CIE_ID_64 = 0xffffffffffffffffULL /* In 64-bit format CIE header.  */
+  };
+
+
+/* Information for GNU unwind information.  */
+enum
+  {
+    DW_EH_PE_absptr = 0x00,
+    DW_EH_PE_omit = 0xff,
+
+    /* FDE data encoding.  */
+    DW_EH_PE_uleb128 = 0x01,
+    DW_EH_PE_udata2 = 0x02,
+    DW_EH_PE_udata4 = 0x03,
+    DW_EH_PE_udata8 = 0x04,
+    DW_EH_PE_sleb128 = 0x09,
+    DW_EH_PE_sdata2 = 0x0a,
+    DW_EH_PE_sdata4 = 0x0b,
+    DW_EH_PE_sdata8 = 0x0c,
+    DW_EH_PE_signed = 0x08,
+
+    /* FDE flags.  */
+    DW_EH_PE_pcrel = 0x10,
+    DW_EH_PE_textrel = 0x20,
+    DW_EH_PE_datarel = 0x30,
+    DW_EH_PE_funcrel = 0x40,
+    DW_EH_PE_aligned = 0x50,
+
+    DW_EH_PE_indirect = 0x80
+  };
+
+
+/* DWARF XXX.  */
+#define DW_ADDR_none	0
+
+/* Section 7.2.2 of the DWARF3 specification defines a range of escape
+   codes that can appear in the length field of certain DWARF structures.
+
+   These defines enumerate the minium and maximum values of this range.
+   Currently only the maximum value is used (to indicate that 64-bit
+   values are going to be used in the dwarf data that accompanies the
+   structure).  The other values are reserved.
+
+   Note: There is a typo in DWARF3 spec (published Dec 20, 2005).  In
+   sections 7.4, 7.5.1, 7.19, 7.20 the minimum escape code is referred to
+   as 0xffffff00 whereas in fact it should be 0xfffffff0.  */
+#define DWARF3_LENGTH_MIN_ESCAPE_CODE 0xfffffff0u
+#define DWARF3_LENGTH_MAX_ESCAPE_CODE 0xffffffffu
+#define DWARF3_LENGTH_64_BIT          DWARF3_LENGTH_MAX_ESCAPE_CODE
+
+#endif	/* dwarf.h */
diff --git a/third_party/elfutils/libdw/dwarf_abbrev_hash.c b/third_party/elfutils/libdw/dwarf_abbrev_hash.c
new file mode 100644
index 0000000..f52f5ad
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_abbrev_hash.c
@@ -0,0 +1,45 @@
+/* Implementation of hash table for DWARF .debug_abbrev section content.
+   Copyright (C) 2000-2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "dwarf_sig8_hash.h"
+#define NO_UNDEF
+#include "libdwP.h"
+
+#define next_prime __libdwarf_next_prime
+extern size_t next_prime (size_t) attribute_hidden;
+
+#include <dynamicsizehash.c>
+
+#undef next_prime
+#define next_prime attribute_hidden __libdwarf_next_prime
+#include "../lib/next_prime.c"
diff --git a/third_party/elfutils/libdw/dwarf_abbrev_hash.h b/third_party/elfutils/libdw/dwarf_abbrev_hash.h
new file mode 100644
index 0000000..d2f02cc
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_abbrev_hash.h
@@ -0,0 +1,39 @@
+/* Hash table for DWARF .debug_abbrev section content.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _DWARF_ABBREV_HASH_H
+#define _DWARF_ABBREV_HASH_H	1
+
+#define NAME Dwarf_Abbrev_Hash
+#define TYPE Dwarf_Abbrev *
+#define COMPARE(a, b) (0)
+
+#include <dynamicsizehash.h>
+
+#endif	/* dwarf_abbrev_hash.h */
diff --git a/third_party/elfutils/libdw/dwarf_abbrevhaschildren.c b/third_party/elfutils/libdw/dwarf_abbrevhaschildren.c
new file mode 100644
index 0000000..0f17c7e
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_abbrevhaschildren.c
@@ -0,0 +1,43 @@
+/* Return true if abbreviation is children flag set.
+   Copyright (C) 2003 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_abbrevhaschildren (Dwarf_Abbrev *abbrev)
+{
+  return abbrev == NULL ? -1 : abbrev->has_children;
+}
diff --git a/third_party/elfutils/libdw/dwarf_addrdie.c b/third_party/elfutils/libdw/dwarf_addrdie.c
new file mode 100644
index 0000000..3a08ab7
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_addrdie.c
@@ -0,0 +1,51 @@
+/* Return CU DIE containing given address.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+Dwarf_Die *
+dwarf_addrdie (Dwarf *dbg, Dwarf_Addr addr, Dwarf_Die *result)
+{
+  Dwarf_Aranges *aranges;
+  size_t naranges;
+  Dwarf_Off off;
+
+  if (INTUSE(dwarf_getaranges) (dbg, &aranges, &naranges) != 0
+      || INTUSE(dwarf_getarangeinfo) (INTUSE(dwarf_getarange_addr) (aranges,
+								    addr),
+				      NULL, NULL, &off) != 0)
+    return NULL;
+
+  return INTUSE(dwarf_offdie) (dbg, off, result);
+}
diff --git a/third_party/elfutils/libdw/dwarf_aggregate_size.c b/third_party/elfutils/libdw/dwarf_aggregate_size.c
new file mode 100644
index 0000000..6e50185
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_aggregate_size.c
@@ -0,0 +1,211 @@
+/* Compute size of an aggregate type from DWARF.
+   Copyright (C) 2010, 2014, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+static Dwarf_Die *
+get_type (Dwarf_Die *die, Dwarf_Attribute *attr_mem, Dwarf_Die *type_mem)
+{
+  Dwarf_Die *type = INTUSE(dwarf_formref_die)
+    (INTUSE(dwarf_attr_integrate) (die, DW_AT_type, attr_mem), type_mem);
+
+  if (INTUSE(dwarf_peel_type) (type, type) != 0)
+    return NULL;
+
+  return type;
+}
+
+static int
+array_size (Dwarf_Die *die, Dwarf_Word *size,
+	    Dwarf_Attribute *attr_mem, Dwarf_Die *type_mem)
+{
+  Dwarf_Word eltsize;
+  if (INTUSE(dwarf_aggregate_size) (get_type (die, attr_mem, type_mem),
+				    &eltsize) != 0)
+      return -1;
+
+  /* An array can have DW_TAG_subrange_type or DW_TAG_enumeration_type
+     children instead that give the size of each dimension.  */
+
+  Dwarf_Die child;
+  if (INTUSE(dwarf_child) (die, &child) != 0)
+    return -1;
+
+  bool any = false;
+  Dwarf_Word count_total = 1;
+  do
+    {
+      Dwarf_Word count;
+      switch (INTUSE(dwarf_tag) (&child))
+	{
+	case DW_TAG_subrange_type:
+	  /* This has either DW_AT_count or DW_AT_upper_bound.  */
+	  if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_count,
+					    attr_mem) != NULL)
+	    {
+	      if (INTUSE(dwarf_formudata) (attr_mem, &count) != 0)
+		return -1;
+	    }
+	  else
+	    {
+	      Dwarf_Sword upper;
+	      Dwarf_Sword lower;
+	      if (INTUSE(dwarf_formsdata) (INTUSE(dwarf_attr_integrate)
+					   (&child, DW_AT_upper_bound,
+					    attr_mem), &upper) != 0)
+		return -1;
+
+	      /* Having DW_AT_lower_bound is optional.  */
+	      if (INTUSE(dwarf_attr_integrate) (&child, DW_AT_lower_bound,
+						attr_mem) != NULL)
+		{
+		  if (INTUSE(dwarf_formsdata) (attr_mem, &lower) != 0)
+		    return -1;
+		}
+	      else
+		{
+		  Dwarf_Die cu = CUDIE (die->cu);
+		  int lang = INTUSE(dwarf_srclang) (&cu);
+		  if (lang == -1
+		      || INTUSE(dwarf_default_lower_bound) (lang, &lower) != 0)
+		    return -1;
+		}
+	      if (unlikely (lower > upper))
+		return -1;
+	      count = upper - lower + 1;
+	    }
+	  break;
+
+	case DW_TAG_enumeration_type:
+	  /* We have to find the DW_TAG_enumerator child with the
+	     highest value to know the array's element count.  */
+	  count = 0;
+	  Dwarf_Die enum_child;
+	  int has_children = INTUSE(dwarf_child) (die, &enum_child);
+	  if (has_children < 0)
+	    return -1;
+	  if (has_children > 0)
+	    do
+	      if (INTUSE(dwarf_tag) (&enum_child) == DW_TAG_enumerator)
+		{
+		  Dwarf_Word value;
+		  if (INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate)
+					       (&enum_child, DW_AT_const_value,
+						attr_mem), &value) != 0)
+		    return -1;
+		  if (value >= count)
+		    count = value + 1;
+		}
+	    while (INTUSE(dwarf_siblingof) (&enum_child, &enum_child) > 0);
+	  break;
+
+	default:
+	  continue;
+	}
+
+      count_total *= count;
+
+      any = true;
+    }
+  while (INTUSE(dwarf_siblingof) (&child, &child) == 0);
+
+  if (!any)
+    return -1;
+
+  /* This is a subrange_type or enumeration_type and we've set COUNT.
+     Now determine the stride for this array.  */
+  Dwarf_Word stride = eltsize;
+  if (INTUSE(dwarf_attr_integrate) (die, DW_AT_byte_stride,
+                                    attr_mem) != NULL)
+    {
+      if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
+        return -1;
+    }
+  else if (INTUSE(dwarf_attr_integrate) (die, DW_AT_bit_stride,
+                                         attr_mem) != NULL)
+    {
+      if (INTUSE(dwarf_formudata) (attr_mem, &stride) != 0)
+        return -1;
+      if (stride % 8) 	/* XXX maybe compute in bits? */
+        return -1;
+      stride /= 8;
+    }
+
+  *size = count_total * stride;
+  return 0;
+}
+
+static int
+aggregate_size (Dwarf_Die *die, Dwarf_Word *size, Dwarf_Die *type_mem)
+{
+  Dwarf_Attribute attr_mem;
+
+  if (INTUSE(dwarf_attr_integrate) (die, DW_AT_byte_size, &attr_mem) != NULL)
+    return INTUSE(dwarf_formudata) (&attr_mem, size);
+
+  switch (INTUSE(dwarf_tag) (die))
+    {
+    case DW_TAG_subrange_type:
+      return aggregate_size (get_type (die, &attr_mem, type_mem),
+			     size, type_mem); /* Tail call.  */
+
+    case DW_TAG_array_type:
+      return array_size (die, size, &attr_mem, type_mem);
+
+    /* Assume references and pointers have pointer size if not given an
+       explicit DW_AT_byte_size.  */
+    case DW_TAG_pointer_type:
+    case DW_TAG_reference_type:
+    case DW_TAG_rvalue_reference_type:
+      *size = die->cu->address_size;
+      return 0;
+    }
+
+  /* Most types must give their size directly.  */
+  return -1;
+}
+
+int
+dwarf_aggregate_size (Dwarf_Die *die, Dwarf_Word *size)
+{
+  Dwarf_Die die_mem, type_mem;
+
+  if (INTUSE (dwarf_peel_type) (die, &die_mem) != 0)
+    return -1;
+
+  return aggregate_size (&die_mem, size, &type_mem);
+}
+INTDEF (dwarf_aggregate_size)
+OLD_VERSION (dwarf_aggregate_size, ELFUTILS_0.144)
+NEW_VERSION (dwarf_aggregate_size, ELFUTILS_0.161)
diff --git a/third_party/elfutils/libdw/dwarf_arrayorder.c b/third_party/elfutils/libdw/dwarf_arrayorder.c
new file mode 100644
index 0000000..da64f99
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_arrayorder.c
@@ -0,0 +1,49 @@
+/* Return array order attribute of DIE.
+   Copyright (C) 2003, 2005, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_arrayorder (Dwarf_Die *die)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Word value;
+
+  return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate)
+				  (die, DW_AT_ordering, &attr_mem),
+				  &value) == 0 ? (int) value : -1;
+}
+OLD_VERSION (dwarf_arrayorder, ELFUTILS_0.122)
+NEW_VERSION (dwarf_arrayorder, ELFUTILS_0.143)
diff --git a/third_party/elfutils/libdw/dwarf_attr.c b/third_party/elfutils/libdw/dwarf_attr.c
new file mode 100644
index 0000000..db8acfe
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_attr.c
@@ -0,0 +1,52 @@
+/* Return specific DWARF attribute of a DIE.
+   Copyright (C) 2003, 2005, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+Dwarf_Attribute *
+dwarf_attr (Dwarf_Die *die, unsigned int search_name, Dwarf_Attribute *result)
+{
+  if (die == NULL)
+    return NULL;
+
+  /* Search for the attribute with the given name.  */
+  result->valp = __libdw_find_attr (die, search_name, &result->code,
+				    &result->form);
+  /* Always fill in the CU information.  */
+  result->cu = die->cu;
+
+  return result->valp != NULL && result->code == search_name ? result : NULL;
+}
+INTDEF(dwarf_attr)
diff --git a/third_party/elfutils/libdw/dwarf_attr_integrate.c b/third_party/elfutils/libdw/dwarf_attr_integrate.c
new file mode 100644
index 0000000..812d74b
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_attr_integrate.c
@@ -0,0 +1,60 @@
+/* Return specific DWARF attribute of a DIE, integrating indirections.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+Dwarf_Attribute *
+dwarf_attr_integrate (Dwarf_Die *die, unsigned int search_name,
+		      Dwarf_Attribute *result)
+{
+  Dwarf_Die die_mem;
+
+  do
+    {
+      Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, search_name, result);
+      if (attr != NULL)
+	return attr;
+
+      attr = INTUSE(dwarf_attr) (die, DW_AT_abstract_origin, result);
+      if (attr == NULL)
+	attr = INTUSE(dwarf_attr) (die, DW_AT_specification, result);
+      if (attr == NULL)
+	break;
+
+      die = INTUSE(dwarf_formref_die) (attr, &die_mem);
+    }
+  while (die != NULL);
+
+  return NULL;
+}
+INTDEF (dwarf_attr_integrate)
diff --git a/third_party/elfutils/libdw/dwarf_begin.c b/third_party/elfutils/libdw/dwarf_begin.c
new file mode 100644
index 0000000..19d16e5
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_begin.c
@@ -0,0 +1,99 @@
+/* Create descriptor from file descriptor for processing file.
+   Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include <libdwP.h>
+
+
+Dwarf *
+dwarf_begin (int fd, Dwarf_Cmd cmd)
+{
+  Elf *elf;
+  Elf_Cmd elfcmd;
+  Dwarf *result = NULL;
+
+  switch (cmd)
+    {
+    case DWARF_C_READ:
+      elfcmd = ELF_C_READ_MMAP;
+      break;
+    case DWARF_C_WRITE:
+      elfcmd = ELF_C_WRITE;
+      break;
+    case DWARF_C_RDWR:
+      elfcmd = ELF_C_RDWR;
+      break;
+    default:
+      /* No valid mode.  */
+      __libdw_seterrno (DWARF_E_INVALID_CMD);
+      return NULL;
+    }
+
+  /* We have to call `elf_version' here since the user might have not
+     done it or initialized libelf with a different version.  This
+     would break libdwarf since we are using the ELF data structures
+     in a certain way.  */
+  elf_version (EV_CURRENT);
+
+  /* Get an ELF descriptor.  */
+  elf = elf_begin (fd, elfcmd, NULL);
+  if (elf == NULL)
+    {
+      /* Test why the `elf_begin" call failed.  */
+      struct stat st;
+
+      if (fstat (fd, &st) == 0 && ! S_ISREG (st.st_mode))
+	__libdw_seterrno (DWARF_E_NO_REGFILE);
+      else if (errno == EBADF)
+	__libdw_seterrno (DWARF_E_INVALID_FILE);
+      else
+	__libdw_seterrno (DWARF_E_IO_ERROR);
+    }
+  else
+    {
+      /* Do the real work now that we have an ELF descriptor.  */
+      result = INTUSE(dwarf_begin_elf) (elf, cmd, NULL);
+
+      /* If this failed, free the resources.  */
+      if (result == NULL)
+	elf_end (elf);
+      else
+	result->free_elf = true;
+    }
+
+  return result;
+}
+INTDEF(dwarf_begin)
diff --git a/third_party/elfutils/libdw/dwarf_begin_elf.c b/third_party/elfutils/libdw/dwarf_begin_elf.c
new file mode 100644
index 0000000..6834ac5
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_begin_elf.c
@@ -0,0 +1,365 @@
+/* Create descriptor from ELF descriptor for processing file.
+   Copyright (C) 2002-2011, 2014, 2015, 2018 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <endian.h>
+
+#include "libdwP.h"
+
+
+/* Section names.  */
+static const char dwarf_scnnames[IDX_last][18] =
+{
+  [IDX_debug_info] = ".debug_info",
+  [IDX_debug_types] = ".debug_types",
+  [IDX_debug_abbrev] = ".debug_abbrev",
+  [IDX_debug_aranges] = ".debug_aranges",
+  [IDX_debug_line] = ".debug_line",
+  [IDX_debug_frame] = ".debug_frame",
+  [IDX_debug_loc] = ".debug_loc",
+  [IDX_debug_pubnames] = ".debug_pubnames",
+  [IDX_debug_str] = ".debug_str",
+  [IDX_debug_macinfo] = ".debug_macinfo",
+  [IDX_debug_macro] = ".debug_macro",
+  [IDX_debug_ranges] = ".debug_ranges",
+  [IDX_gnu_debugaltlink] = ".gnu_debugaltlink"
+};
+#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
+
+static Dwarf *
+check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
+{
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr;
+
+  /* Get the section header data.  */
+  shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr == NULL)
+    /* We may read /proc/PID/mem with only program headers mapped and section
+       headers out of the mapped pages.  */
+    goto err;
+
+  /* Ignore any SHT_NOBITS sections.  Debugging sections should not
+     have been stripped, but in case of a corrupt file we won't try
+     to look at the missing data.  */
+  if (unlikely (shdr->sh_type == SHT_NOBITS))
+    return result;
+
+  /* Make sure the section is part of a section group only iff we
+     really need it.  If we are looking for the global (= non-section
+     group debug info) we have to ignore all the info in section
+     groups.  If we are looking into a section group we cannot look at
+     a section which isn't part of the section group.  */
+  if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
+    /* Ignore the section.  */
+    return result;
+
+
+  /* We recognize the DWARF section by their names.  This is not very
+     safe and stable but the best we can do.  */
+  const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx,
+				    shdr->sh_name);
+  if (scnname == NULL)
+    {
+      /* The section name must be valid.  Otherwise is the ELF file
+	 invalid.  */
+    err:
+      Dwarf_Sig8_Hash_free (&result->sig8_hash);
+      __libdw_seterrno (DWARF_E_INVALID_ELF);
+      free (result);
+      return NULL;
+    }
+
+  /* Recognize the various sections.  Most names start with .debug_.  */
+  size_t cnt;
+  bool gnu_compressed = false;
+  for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
+    if (strcmp (scnname, dwarf_scnnames[cnt]) == 0)
+      break;
+    else if (scnname[0] == '.' && scnname[1] == 'z'
+	     && strcmp (&scnname[2], &dwarf_scnnames[cnt][1]) == 0)
+      {
+        gnu_compressed = true;
+        break;
+      }
+
+  if (cnt >= ndwarf_scnnames)
+    /* Not a debug section; ignore it. */
+    return result;
+
+  if (unlikely (result->sectiondata[cnt] != NULL))
+    /* A section appears twice.  That's bad.  We ignore the section.  */
+    return result;
+
+  /* We cannot know whether or not a GNU compressed section has already
+     been uncompressed or not, so ignore any errors.  */
+  if (gnu_compressed)
+    elf_compress_gnu (scn, 0, 0);
+
+  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+    {
+      if (elf_compress (scn, 0, 0) < 0)
+	{
+	  /* If we failed to decompress the section and it's the
+	     debug_info section, then fail with specific error rather
+	     than the generic NO_DWARF. Without debug_info we can't do
+	     anything (see also valid_p()). */
+	  if (cnt == IDX_debug_info)
+	    {
+	      Dwarf_Sig8_Hash_free (&result->sig8_hash);
+	      __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
+	      free (result);
+	      return NULL;
+	    }
+	  return result;
+	}
+    }
+
+  /* Get the section data.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    goto err;
+
+  if (data->d_buf == NULL || data->d_size == 0)
+    /* No data actually available, ignore it. */
+    return result;
+
+  /* We can now read the section data into results. */
+  result->sectiondata[cnt] = data;
+
+  return result;
+}
+
+
+/* Check whether all the necessary DWARF information is available.  */
+static Dwarf *
+valid_p (Dwarf *result)
+{
+  /* We looked at all the sections.  Now determine whether all the
+     sections with debugging information we need are there.
+
+     XXX Which sections are absolutely necessary?  Add tests if
+     necessary.  For now we require only .debug_info.  Hopefully this
+     is correct.  */
+  if (likely (result != NULL)
+      && unlikely (result->sectiondata[IDX_debug_info] == NULL))
+    {
+      Dwarf_Sig8_Hash_free (&result->sig8_hash);
+      __libdw_seterrno (DWARF_E_NO_DWARF);
+      free (result);
+      result = NULL;
+    }
+
+  if (result != NULL && result->sectiondata[IDX_debug_loc] != NULL)
+    {
+      result->fake_loc_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU));
+      if (unlikely (result->fake_loc_cu == NULL))
+	{
+	  Dwarf_Sig8_Hash_free (&result->sig8_hash);
+	  __libdw_seterrno (DWARF_E_NOMEM);
+	  free (result);
+	  result = NULL;
+	}
+      else
+	{
+	  result->fake_loc_cu->sec_idx = IDX_debug_loc;
+	  result->fake_loc_cu->dbg = result;
+	  result->fake_loc_cu->startp
+	    = result->sectiondata[IDX_debug_loc]->d_buf;
+	  result->fake_loc_cu->endp
+	    = (result->sectiondata[IDX_debug_loc]->d_buf
+	       + result->sectiondata[IDX_debug_loc]->d_size);
+	}
+    }
+
+  return result;
+}
+
+
+static Dwarf *
+global_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr)
+{
+  Elf_Scn *scn = NULL;
+
+  while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
+    result = check_section (result, ehdr, scn, false);
+
+  return valid_p (result);
+}
+
+
+static Dwarf *
+scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
+{
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem);
+  if (shdr == NULL)
+    {
+      Dwarf_Sig8_Hash_free (&result->sig8_hash);
+      __libdw_seterrno (DWARF_E_INVALID_ELF);
+      free (result);
+      return NULL;
+    }
+
+  if ((shdr->sh_flags & SHF_COMPRESSED) != 0
+      && elf_compress (scngrp, 0, 0) < 0)
+    {
+      Dwarf_Sig8_Hash_free (&result->sig8_hash);
+      __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
+      free (result);
+      return NULL;
+    }
+
+  /* SCNGRP is the section descriptor for a section group which might
+     contain debug sections.  */
+  Elf_Data *data = elf_getdata (scngrp, NULL);
+  if (data == NULL)
+    {
+      /* We cannot read the section content.  Fail!  */
+      Dwarf_Sig8_Hash_free (&result->sig8_hash);
+      free (result);
+      return NULL;
+    }
+
+  /* The content of the section is a number of 32-bit words which
+     represent section indices.  The first word is a flag word.  */
+  Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
+  size_t cnt;
+  for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
+    {
+      Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
+      if (scn == NULL)
+	{
+	  /* A section group refers to a non-existing section.  Should
+	     never happen.  */
+	  Dwarf_Sig8_Hash_free (&result->sig8_hash);
+	  __libdw_seterrno (DWARF_E_INVALID_ELF);
+	  free (result);
+	  return NULL;
+	}
+
+      result = check_section (result, ehdr, scn, true);
+      if (result == NULL)
+	break;
+    }
+
+  return valid_p (result);
+}
+
+
+Dwarf *
+dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
+{
+  GElf_Ehdr *ehdr;
+  GElf_Ehdr ehdr_mem;
+
+  /* Get the ELF header of the file.  We need various pieces of
+     information from it.  */
+  ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      if (elf_kind (elf) != ELF_K_ELF)
+	__libdw_seterrno (DWARF_E_NOELF);
+      else
+	__libdw_seterrno (DWARF_E_GETEHDR_ERROR);
+
+      return NULL;
+    }
+
+
+  /* Default memory allocation size.  */
+  size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
+  assert (sizeof (struct Dwarf) < mem_default_size);
+
+  /* Allocate the data structure.  */
+  Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf) + mem_default_size);
+  if (unlikely (result == NULL)
+      || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0))
+    {
+      free (result);
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return NULL;
+    }
+
+  /* Fill in some values.  */
+  if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
+      || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
+    result->other_byte_order = true;
+
+  result->elf = elf;
+  result->alt_fd = -1;
+
+  /* Initialize the memory handling.  */
+  result->mem_default_size = mem_default_size;
+  result->oom_handler = __libdw_oom;
+  result->mem_tail = (struct libdw_memblock *) (result + 1);
+  result->mem_tail->size = (result->mem_default_size
+			    - offsetof (struct libdw_memblock, mem));
+  result->mem_tail->remaining = result->mem_tail->size;
+  result->mem_tail->prev = NULL;
+
+  if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
+    {
+      /* If the caller provides a section group we get the DWARF
+	 sections only from this setion group.  Otherwise we search
+	 for the first section with the required name.  Further
+	 sections with the name are ignored.  The DWARF specification
+	 does not really say this is allowed.  */
+      if (scngrp == NULL)
+	return global_read (result, elf, ehdr);
+      else
+	return scngrp_read (result, elf, ehdr, scngrp);
+    }
+  else if (cmd == DWARF_C_WRITE)
+    {
+      Dwarf_Sig8_Hash_free (&result->sig8_hash);
+      __libdw_seterrno (DWARF_E_UNIMPL);
+      free (result);
+      return NULL;
+    }
+
+  Dwarf_Sig8_Hash_free (&result->sig8_hash);
+  __libdw_seterrno (DWARF_E_INVALID_CMD);
+  free (result);
+  return NULL;
+}
+INTDEF(dwarf_begin_elf)
diff --git a/third_party/elfutils/libdw/dwarf_bitoffset.c b/third_party/elfutils/libdw/dwarf_bitoffset.c
new file mode 100644
index 0000000..c1a3a34
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_bitoffset.c
@@ -0,0 +1,49 @@
+/* Return bit offset attribute of DIE.
+   Copyright (C) 2003, 2005, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_bitoffset (Dwarf_Die *die)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Word value;
+
+  return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate)
+				  (die, DW_AT_bit_offset, &attr_mem),
+				  &value) == 0 ? (int) value : -1;
+}
+OLD_VERSION (dwarf_bitoffset, ELFUTILS_0.122)
+NEW_VERSION (dwarf_bitoffset, ELFUTILS_0.143)
diff --git a/third_party/elfutils/libdw/dwarf_bitsize.c b/third_party/elfutils/libdw/dwarf_bitsize.c
new file mode 100644
index 0000000..0ed9b71
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_bitsize.c
@@ -0,0 +1,49 @@
+/* Return bit size attribute of DIE.
+   Copyright (C) 2003, 2005, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_bitsize (Dwarf_Die *die)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Word value;
+
+  return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate)
+				  (die, DW_AT_bit_size, &attr_mem),
+				  &value) == 0 ? (int) value : -1;
+}
+OLD_VERSION (dwarf_bitsize, ELFUTILS_0.122)
+NEW_VERSION (dwarf_bitsize, ELFUTILS_0.143)
diff --git a/third_party/elfutils/libdw/dwarf_bytesize.c b/third_party/elfutils/libdw/dwarf_bytesize.c
new file mode 100644
index 0000000..116cd32
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_bytesize.c
@@ -0,0 +1,49 @@
+/* Return byte size attribute of DIE.
+   Copyright (C) 2003, 2005, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_bytesize (Dwarf_Die *die)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Word value;
+
+  return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate)
+				  (die, DW_AT_byte_size, &attr_mem),
+				  &value) == 0 ? (int) value : -1;
+}
+OLD_VERSION (dwarf_bytesize, ELFUTILS_0.122)
+NEW_VERSION (dwarf_bytesize, ELFUTILS_0.143)
diff --git a/third_party/elfutils/libdw/dwarf_cfi_addrframe.c b/third_party/elfutils/libdw/dwarf_cfi_addrframe.c
new file mode 100644
index 0000000..4424027
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_cfi_addrframe.c
@@ -0,0 +1,54 @@
+/* Compute frame state at PC.
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+
+int
+dwarf_cfi_addrframe (Dwarf_CFI *cache, Dwarf_Addr address, Dwarf_Frame **frame)
+{
+  /* Maybe there was a previous error.  */
+  if (cache == NULL)
+    return -1;
+
+  struct dwarf_fde *fde = __libdw_find_fde (cache, address);
+  if (fde == NULL)
+    return -1;
+
+  int error = __libdw_frame_at_address (cache, fde, address, frame);
+  if (error != DWARF_E_NOERROR)
+    {
+      __libdw_seterrno (error);
+      return -1;
+    }
+  return 0;
+}
+INTDEF (dwarf_cfi_addrframe)
diff --git a/third_party/elfutils/libdw/dwarf_cfi_end.c b/third_party/elfutils/libdw/dwarf_cfi_end.c
new file mode 100644
index 0000000..d68e2db
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_cfi_end.c
@@ -0,0 +1,48 @@
+/* Clean up Dwarf_CFI structure.
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include "cfi.h"
+#include <stdlib.h>
+
+int
+dwarf_cfi_end (Dwarf_CFI *cache)
+{
+  if (cache != NULL)
+    {
+      __libdw_destroy_frame_cache (cache);
+      free (cache);
+    }
+
+  return 0;
+}
+INTDEF (dwarf_cfi_end)
diff --git a/third_party/elfutils/libdw/dwarf_child.c b/third_party/elfutils/libdw/dwarf_child.c
new file mode 100644
index 0000000..248338e
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_child.c
@@ -0,0 +1,165 @@
+/* Return child of current DIE.
+   Copyright (C) 2003-2011, 2014, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <string.h>
+
+/* Some arbitrary value not conflicting with any existing code.  */
+#define INVALID 0xffffe444
+
+
+unsigned char *
+internal_function
+__libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
+		   unsigned int *codep, unsigned int *formp)
+{
+  const unsigned char *readp;
+
+  /* Find the abbreviation entry.  */
+  Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &readp);
+  if (unlikely (abbrevp == DWARF_END_ABBREV))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  /* Search the name attribute.  Attribute has been checked when
+     Dwarf_Abbrev was created, we can read unchecked.  */
+  const unsigned char *attrp = abbrevp->attrp;
+  while (1)
+    {
+      /* Get attribute name and form.  */
+      unsigned int attr_name;
+      get_uleb128_unchecked (attr_name, attrp);
+
+      unsigned int attr_form;
+      get_uleb128_unchecked (attr_form, attrp);
+
+      /* We can stop if we found the attribute with value zero.  */
+      if (attr_name == 0 && attr_form == 0)
+	break;
+
+      /* Is this the name attribute?  */
+      if (attr_name == search_name && search_name != INVALID)
+	{
+	  if (codep != NULL)
+	    *codep = attr_name;
+	  if (formp != NULL)
+	    *formp = attr_form;
+
+	  return (unsigned char *) readp;
+	}
+
+      /* Skip over the rest of this attribute (if there is any).  */
+      if (attr_form != 0)
+	{
+	  size_t len = __libdw_form_val_len (die->cu, attr_form, readp);
+	  if (unlikely (len == (size_t) -1l))
+	    {
+	      readp = NULL;
+	      break;
+	    }
+
+	  // __libdw_form_val_len will have done a bounds check.
+	  readp += len;
+	}
+    }
+
+  // XXX Do we need other values?
+  if (codep != NULL)
+    *codep = INVALID;
+  if (formp != NULL)
+    *formp = INVALID;
+
+  return (unsigned char *) readp;
+}
+
+
+int
+dwarf_child (Dwarf_Die *die, Dwarf_Die *result)
+{
+  /* Ignore previous errors.  */
+  if (die == NULL)
+    return -1;
+
+  /* Find the abbreviation entry.  */
+  Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL);
+  if (unlikely (abbrevp == DWARF_END_ABBREV))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return -1;
+    }
+
+  /* If there are no children, do not search.  */
+  if (! abbrevp->has_children)
+    return 1;
+
+  /* Skip past the last attribute.  */
+  void *addr = __libdw_find_attr (die, INVALID, NULL, NULL);
+
+  if (addr == NULL)
+    return -1;
+
+  /* RESULT can be the same as DIE.  So preserve what we need.  */
+  struct Dwarf_CU *cu = die->cu;
+
+  /* It's kosher (just suboptimal) to have a null entry first thing (7.5.3).
+     So if this starts with ULEB128 of 0 (even with silly encoding of 0),
+     it is a kosher null entry and we do not really have any children.  */
+  const unsigned char *code = addr;
+  const unsigned char *endp = cu->endp;
+  while (1)
+    {
+      if (unlikely (code >= endp)) /* Truncated section.  */
+	return 1;
+      if (unlikely (*code == 0x80))
+	++code;
+      else
+	break;
+    }
+  if (unlikely (*code == '\0'))
+    return 1;
+
+  /* Clear the entire DIE structure.  This signals we have not yet
+     determined any of the information.  */
+  memset (result, '\0', sizeof (Dwarf_Die));
+
+  /* We have the address.  */
+  result->addr = addr;
+
+  /* Same CU as the parent.  */
+  result->cu = cu;
+
+  return 0;
+}
+INTDEF(dwarf_child)
diff --git a/third_party/elfutils/libdw/dwarf_cu_die.c b/third_party/elfutils/libdw/dwarf_cu_die.c
new file mode 100644
index 0000000..194da58
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_cu_die.c
@@ -0,0 +1,62 @@
+/* Internal definitions for libdwarf.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+#include "libdwP.h"
+
+
+Dwarf_Die *
+dwarf_cu_die (Dwarf_CU *cu, Dwarf_Die *result, Dwarf_Half *versionp,
+	      Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep,
+	      uint8_t *offset_sizep, uint64_t *type_signaturep,
+	      Dwarf_Off *type_offsetp)
+{
+  if (cu == NULL)
+    return NULL;
+
+  *result = CUDIE (cu);
+
+  if (versionp != NULL)
+    *versionp = cu->version;
+  if (abbrev_offsetp != NULL)
+    *abbrev_offsetp = cu->orig_abbrev_offset;
+  if (address_sizep != NULL)
+    *address_sizep = cu->address_size;
+  if (offset_sizep != NULL)
+    *offset_sizep = cu->offset_size;
+  if (type_signaturep != NULL)
+    *type_signaturep = cu->type_sig8;
+  if (type_offsetp != NULL)
+    *type_offsetp = cu->type_offset;
+
+  return result;
+}
diff --git a/third_party/elfutils/libdw/dwarf_cu_getdwarf.c b/third_party/elfutils/libdw/dwarf_cu_getdwarf.c
new file mode 100644
index 0000000..562460f
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_cu_getdwarf.c
@@ -0,0 +1,46 @@
+/* Retrieve Dwarf descriptor underlying a Dwarf_CU.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+
+#include "libdwP.h"
+
+
+Dwarf *
+dwarf_cu_getdwarf (Dwarf_CU *cu)
+{
+  if (cu == NULL)
+    /* Some error occurred before.  */
+    return NULL;
+
+  return cu->dbg;
+}
diff --git a/third_party/elfutils/libdw/dwarf_cuoffset.c b/third_party/elfutils/libdw/dwarf_cuoffset.c
new file mode 100644
index 0000000..ba37648
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_cuoffset.c
@@ -0,0 +1,44 @@
+/* Return offset of DIE in CU.
+   Copyright (C) 2003-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+Dwarf_Off
+dwarf_cuoffset (Dwarf_Die *die)
+{
+  return (die == NULL
+	  ? (Dwarf_Off) -1l
+	  : (Dwarf_Off) (die->addr - die->cu->startp));
+}
diff --git a/third_party/elfutils/libdw/dwarf_decl_column.c b/third_party/elfutils/libdw/dwarf_decl_column.c
new file mode 100644
index 0000000..08d36b8
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_decl_column.c
@@ -0,0 +1,44 @@
+/* Get column number of beginning of given declaration.
+   Copyright (C) 2005-2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_decl_column (Dwarf_Die *decl, int *colp)
+{
+  return __libdw_attr_intval (decl, colp, DW_AT_decl_column);
+}
+OLD_VERSION (dwarf_decl_column, ELFUTILS_0.122)
+NEW_VERSION (dwarf_decl_column, ELFUTILS_0.143)
diff --git a/third_party/elfutils/libdw/dwarf_decl_file.c b/third_party/elfutils/libdw/dwarf_decl_file.c
new file mode 100644
index 0000000..5657132
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_decl_file.c
@@ -0,0 +1,89 @@
+/* Return file name containing definition of the given function.
+   Copyright (C) 2005, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+const char *
+dwarf_decl_file (Dwarf_Die *die)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Word idx = 0;
+
+  if (INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate)
+			       (die, DW_AT_decl_file, &attr_mem),
+			       &idx) != 0)
+    return NULL;
+
+  /* Zero means no source file information available.  */
+  if (idx == 0)
+    {
+      __libdw_seterrno (DWARF_E_NO_ENTRY);
+      return NULL;
+    }
+
+  /* Get the array of source files for the CU.  */
+  struct Dwarf_CU *cu = die->cu;
+  if (cu->lines == NULL)
+    {
+      Dwarf_Lines *lines;
+      size_t nlines;
+
+      /* Let the more generic function do the work.  It'll create more
+	 data but that will be needed in an real program anyway.  */
+      (void) INTUSE(dwarf_getsrclines) (&CUDIE (cu), &lines, &nlines);
+      assert (cu->lines != NULL);
+    }
+
+  if (cu->lines == (void *) -1l)
+    {
+      /* If the file index is not zero, there must be file information
+	 available.  */
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  assert (cu->files != NULL && cu->files != (void *) -1l);
+
+  if (idx >= cu->files->nfiles)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  return cu->files->info[idx].name;
+}
+OLD_VERSION (dwarf_decl_file, ELFUTILS_0.122)
+NEW_VERSION (dwarf_decl_file, ELFUTILS_0.143)
diff --git a/third_party/elfutils/libdw/dwarf_decl_line.c b/third_party/elfutils/libdw/dwarf_decl_line.c
new file mode 100644
index 0000000..80fae6c
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_decl_line.c
@@ -0,0 +1,70 @@
+/* Get line number of beginning of given function.
+   Copyright (C) 2005, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include <limits.h>
+#include "libdwP.h"
+
+
+int
+dwarf_decl_line (Dwarf_Die *func, int *linep)
+{
+  return __libdw_attr_intval (func, linep, DW_AT_decl_line);
+}
+OLD_VERSION (dwarf_decl_line, ELFUTILS_0.122)
+NEW_VERSION (dwarf_decl_line, ELFUTILS_0.143)
+
+
+int internal_function
+__libdw_attr_intval (Dwarf_Die *die, int *linep, int attval)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Word line;
+
+  int res = INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate)
+				     (die, attval, &attr_mem),
+				     &line);
+  if (res == 0)
+    {
+      if (line > INT_MAX)
+	{
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  res = -1;
+	}
+      else
+	*linep = line;
+    }
+
+  return res;
+}
diff --git a/third_party/elfutils/libdw/dwarf_default_lower_bound.c b/third_party/elfutils/libdw/dwarf_default_lower_bound.c
new file mode 100644
index 0000000..a33a343
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_default_lower_bound.c
@@ -0,0 +1,91 @@
+/* Get the default subrange lower bound for a given language.
+   Copyright (C) 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+/* Determine default lower bound from language, as per the DWARF5
+   "Subrange Type Entries" table.  */
+int
+dwarf_default_lower_bound (int lang, Dwarf_Sword *result)
+{
+  switch (lang)
+    {
+    case DW_LANG_C:
+    case DW_LANG_C89:
+    case DW_LANG_C99:
+    case DW_LANG_C11:
+    case DW_LANG_C_plus_plus:
+    case DW_LANG_C_plus_plus_03:
+    case DW_LANG_C_plus_plus_11:
+    case DW_LANG_C_plus_plus_14:
+    case DW_LANG_ObjC:
+    case DW_LANG_ObjC_plus_plus:
+    case DW_LANG_Java:
+    case DW_LANG_D:
+    case DW_LANG_Python:
+    case DW_LANG_UPC:
+    case DW_LANG_OpenCL:
+    case DW_LANG_Go:
+    case DW_LANG_Haskell:
+    case DW_LANG_OCaml:
+    case DW_LANG_Rust:
+    case DW_LANG_Swift:
+    case DW_LANG_Dylan:
+    case DW_LANG_RenderScript:
+    case DW_LANG_BLISS:
+      *result = 0;
+      return 0;
+
+    case DW_LANG_Ada83:
+    case DW_LANG_Ada95:
+    case DW_LANG_Cobol74:
+    case DW_LANG_Cobol85:
+    case DW_LANG_Fortran77:
+    case DW_LANG_Fortran90:
+    case DW_LANG_Fortran95:
+    case DW_LANG_Fortran03:
+    case DW_LANG_Fortran08:
+    case DW_LANG_Pascal83:
+    case DW_LANG_Modula2:
+    case DW_LANG_Modula3:
+    case DW_LANG_PLI:
+    case DW_LANG_Julia:
+      *result = 1;
+      return 0;
+
+    default:
+      __libdw_seterrno (DWARF_E_UNKNOWN_LANGUAGE);
+      return -1;
+    }
+}
+INTDEF (dwarf_default_lower_bound)
diff --git a/third_party/elfutils/libdw/dwarf_diecu.c b/third_party/elfutils/libdw/dwarf_diecu.c
new file mode 100644
index 0000000..5281c35
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_diecu.c
@@ -0,0 +1,52 @@
+/* Return CU DIE containing given DIE.
+   Copyright (C) 2005-2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libdwP.h"
+
+
+Dwarf_Die *
+dwarf_diecu (Dwarf_Die *die, Dwarf_Die *result, uint8_t *address_sizep,
+	     uint8_t *offset_sizep)
+{
+  if (die == NULL)
+    return NULL;
+
+  *result = CUDIE (die->cu);
+
+  if (address_sizep != NULL)
+    *address_sizep = die->cu->address_size;
+  if (offset_sizep != NULL)
+    *offset_sizep = die->cu->offset_size;
+
+  return result;
+}
diff --git a/third_party/elfutils/libdw/dwarf_diename.c b/third_party/elfutils/libdw/dwarf_diename.c
new file mode 100644
index 0000000..96450c1
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_diename.c
@@ -0,0 +1,47 @@
+/* Return string in name attribute of DIE.
+   Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+const char *
+dwarf_diename (Dwarf_Die *die)
+{
+  Dwarf_Attribute attr_mem;
+
+  return INTUSE(dwarf_formstring) (INTUSE(dwarf_attr_integrate) (die,
+								 DW_AT_name,
+								 &attr_mem));
+}
+INTDEF (dwarf_diename)
diff --git a/third_party/elfutils/libdw/dwarf_dieoffset.c b/third_party/elfutils/libdw/dwarf_dieoffset.c
new file mode 100644
index 0000000..8028f6d
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_dieoffset.c
@@ -0,0 +1,45 @@
+/* Return offset of DIE.
+   Copyright (C) 2003-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+Dwarf_Off
+dwarf_dieoffset (Dwarf_Die *die)
+{
+  return (die == NULL
+	  ? ~0ul
+	  : (Dwarf_Off) (die->addr - die->cu->startp + die->cu->start));
+}
+INTDEF(dwarf_dieoffset)
diff --git a/third_party/elfutils/libdw/dwarf_end.c b/third_party/elfutils/libdw/dwarf_end.c
new file mode 100644
index 0000000..f6915ab
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_end.c
@@ -0,0 +1,120 @@
+/* Release debugging handling context.
+   Copyright (C) 2002-2011, 2014, 2018 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <search.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libdwP.h"
+#include "cfi.h"
+
+
+static void
+noop_free (void *arg __attribute__ ((unused)))
+{
+}
+
+
+static void
+cu_free (void *arg)
+{
+  struct Dwarf_CU *p = (struct Dwarf_CU *) arg;
+
+  Dwarf_Abbrev_Hash_free (&p->abbrev_hash);
+
+  tdestroy (p->locs, noop_free);
+}
+
+
+int
+dwarf_end (Dwarf *dwarf)
+{
+  if (dwarf != NULL)
+    {
+      if (dwarf->cfi != NULL)
+	/* Clean up the CFI cache.  */
+	__libdw_destroy_frame_cache (dwarf->cfi);
+
+      Dwarf_Sig8_Hash_free (&dwarf->sig8_hash);
+
+      /* The search tree for the CUs.  NB: the CU data itself is
+	 allocated separately, but the abbreviation hash tables need
+	 to be handled.  */
+      tdestroy (dwarf->cu_tree, cu_free);
+      tdestroy (dwarf->tu_tree, cu_free);
+
+      /* Search tree for macro opcode tables.  */
+      tdestroy (dwarf->macro_ops, noop_free);
+
+      /* Search tree for decoded .debug_lines units.  */
+      tdestroy (dwarf->files_lines, noop_free);
+
+      struct libdw_memblock *memp = dwarf->mem_tail;
+      /* The first block is allocated together with the Dwarf object.  */
+      while (memp->prev != NULL)
+	{
+	  struct libdw_memblock *prevp = memp->prev;
+	  free (memp);
+	  memp = prevp;
+	}
+
+      /* Free the pubnames helper structure.  */
+      free (dwarf->pubnames_sets);
+
+      /* Free the ELF descriptor if necessary.  */
+      if (dwarf->free_elf)
+	elf_end (dwarf->elf);
+
+      /* Free the fake location list CU.  */
+      if (dwarf->fake_loc_cu != NULL)
+	{
+	  cu_free (dwarf->fake_loc_cu);
+	  free (dwarf->fake_loc_cu);
+	}
+
+      /* Did we find and allocate the alt Dwarf ourselves?  */
+      if (dwarf->alt_fd != -1)
+	{
+	  INTUSE(dwarf_end) (dwarf->alt_dwarf);
+	  close (dwarf->alt_fd);
+	}
+
+      /* Free the context descriptor.  */
+      free (dwarf);
+    }
+
+  return 0;
+}
+INTDEF(dwarf_end)
diff --git a/third_party/elfutils/libdw/dwarf_entry_breakpoints.c b/third_party/elfutils/libdw/dwarf_entry_breakpoints.c
new file mode 100644
index 0000000..c3c0f39
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_entry_breakpoints.c
@@ -0,0 +1,163 @@
+/* Find entry breakpoint locations for a function.
+   Copyright (C) 2005-2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "libdwP.h"
+#include <dwarf.h>
+#include <stdlib.h>
+
+
+/* Add one breakpoint location to the result vector.  */
+static inline int
+add_bkpt (Dwarf_Addr pc, Dwarf_Addr **bkpts, int *pnbkpts)
+{
+  Dwarf_Addr *newlist = realloc (*bkpts, ++(*pnbkpts) * sizeof newlist[0]);
+  if (newlist == NULL)
+    {
+      free (*bkpts);
+      *bkpts = NULL;
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return -1;
+    }
+  newlist[*pnbkpts - 1] = pc;
+  *bkpts = newlist;
+  return *pnbkpts;
+}
+
+/* Fallback result, break at the entrypc/lowpc value.  */
+static inline int
+entrypc_bkpt (Dwarf_Die *die, Dwarf_Addr **bkpts, int *pnbkpts)
+{
+  Dwarf_Addr pc;
+  return INTUSE(dwarf_entrypc) (die, &pc) < 0 ? -1 : add_bkpt (pc, bkpts, pnbkpts);
+}
+
+/* Search a contiguous PC range for prologue-end markers.
+   If DWARF, look for proper markers.
+   Failing that, if ADHOC, look for the ad hoc convention.  */
+static inline int
+search_range (Dwarf_Addr low, Dwarf_Addr high,
+	      bool dwarf, bool adhoc,
+              Dwarf_Lines *lines, size_t nlines,
+              Dwarf_Addr **bkpts, int *pnbkpts)
+{
+      size_t l = 0, u = nlines;
+      while (l < u)
+	{
+	  size_t idx = (l + u) / 2;
+	  if (lines->info[idx].addr < low)
+	    l = idx + 1;
+	  else if (lines->info[idx].addr > low)
+	    u = idx;
+	  else if (lines->info[idx].end_sequence)
+	    l = idx + 1;
+	  else
+	    {
+	      l = idx;
+	      break;
+	    }
+	}
+      if (l < u)
+	{
+	  if (dwarf)
+	    for (size_t i = l; i < u && lines->info[i].addr < high; ++i)
+	      if (lines->info[i].prologue_end
+		  && add_bkpt (lines->info[i].addr, bkpts, pnbkpts) < 0)
+		return -1;
+	  if (adhoc && *pnbkpts == 0)
+	    while (++l < nlines && lines->info[l].addr < high)
+	      if (!lines->info[l].end_sequence)
+		return add_bkpt (lines->info[l].addr, bkpts, pnbkpts);
+	  return *pnbkpts;
+	}
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return -1;
+}
+
+int
+dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts)
+{
+  int nbkpts = 0;
+  *bkpts = NULL;
+
+  /* Fetch the CU's line records to look for this DIE's addresses.  */
+  Dwarf_Die cudie = CUDIE (die->cu);
+  Dwarf_Lines *lines;
+  size_t nlines;
+  if (INTUSE(dwarf_getsrclines) (&cudie, &lines, &nlines) < 0)
+    {
+      int error = INTUSE (dwarf_errno) ();
+      if (error == 0)		/* CU has no DW_AT_stmt_list.  */
+	return entrypc_bkpt (die, bkpts, &nbkpts);
+      __libdw_seterrno (error);
+      return -1;
+    }
+
+  /* Search each contiguous address range for DWARF prologue_end markers.  */
+
+  Dwarf_Addr base;
+  Dwarf_Addr begin;
+  Dwarf_Addr end;
+  ptrdiff_t offset = INTUSE(dwarf_ranges) (die, 0, &base, &begin, &end);
+  if (offset < 0)
+    return -1;
+
+  /* Most often there is a single contiguous PC range for the DIE.  */
+  if (offset == 1)
+    return search_range (begin, end, true, true, lines, nlines, bkpts, &nbkpts)
+        ?: entrypc_bkpt (die, bkpts, &nbkpts);
+
+  Dwarf_Addr lowpc = (Dwarf_Addr) -1l;
+  Dwarf_Addr highpc = (Dwarf_Addr) -1l;
+  while (offset > 0)
+    {
+      /* We have an address range entry.  */
+      if (search_range (begin, end, true, false,
+                        lines, nlines, bkpts, &nbkpts) < 0)
+	return -1;
+
+      if (begin < lowpc)
+	{
+	  lowpc = begin;
+	  highpc = end;
+	}
+
+      offset = INTUSE(dwarf_ranges) (die, offset, &base, &begin, &end);
+    }
+
+  /* If we didn't find any proper DWARF markers, then look in the
+     lowest-addressed range for an ad hoc marker.  Failing that,
+     fall back to just using the entrypc value.  */
+  return (nbkpts
+	  ?: (lowpc == (Dwarf_Addr) -1l ? 0
+	      : search_range (lowpc, highpc, false, true,
+	                      lines, nlines, bkpts, &nbkpts))
+	  ?: entrypc_bkpt (die, bkpts, &nbkpts));
+}
diff --git a/third_party/elfutils/libdw/dwarf_entrypc.c b/third_party/elfutils/libdw/dwarf_entrypc.c
new file mode 100644
index 0000000..0ef3b0e
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_entrypc.c
@@ -0,0 +1,48 @@
+/* Return entry PC attribute of DIE.
+   Copyright (C) 2003, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_entrypc (Dwarf_Die *die, Dwarf_Addr *return_addr)
+{
+  Dwarf_Attribute attr_mem;
+
+  return INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (die, DW_AT_entry_pc,
+						     &attr_mem)
+				 ?: INTUSE(dwarf_attr) (die, DW_AT_low_pc,
+							&attr_mem),
+				 return_addr);
+}
+INTDEF(dwarf_entrypc)
diff --git a/third_party/elfutils/libdw/dwarf_error.c b/third_party/elfutils/libdw/dwarf_error.c
new file mode 100644
index 0000000..939ec04
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_error.c
@@ -0,0 +1,124 @@
+/* Retrieve ELF descriptor used for DWARF access.
+   Copyright (C) 2002, 2003, 2004, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+
+#include "libdwP.h"
+
+
+/* The error number.  */
+static __thread int global_error;
+
+
+int
+dwarf_errno (void)
+{
+  int result = global_error;
+  global_error = DWARF_E_NOERROR;
+  return result;
+}
+INTDEF(dwarf_errno)
+
+
+/* XXX For now we use string pointers.  Once the table stablelizes
+   make it more DSO-friendly.  */
+static const char *errmsgs[] =
+  {
+    [DWARF_E_NOERROR] = N_("no error"),
+    [DWARF_E_UNKNOWN_ERROR] = N_("unknown error"),
+    [DWARF_E_INVALID_ACCESS] = N_("invalid access"),
+    [DWARF_E_NO_REGFILE] = N_("no regular file"),
+    [DWARF_E_IO_ERROR] = N_("I/O error"),
+    [DWARF_E_INVALID_ELF] = N_("invalid ELF file"),
+    [DWARF_E_NO_DWARF] = N_("no DWARF information"),
+    [DWARF_E_COMPRESSED_ERROR] = N_("cannot decompress DWARF"),
+    [DWARF_E_NOELF] = N_("no ELF file"),
+    [DWARF_E_GETEHDR_ERROR] = N_("cannot get ELF header"),
+    [DWARF_E_NOMEM] = N_("out of memory"),
+    [DWARF_E_UNIMPL] = N_("not implemented"),
+    [DWARF_E_INVALID_CMD] = N_("invalid command"),
+    [DWARF_E_INVALID_VERSION] = N_("invalid version"),
+    [DWARF_E_INVALID_FILE] = N_("invalid file"),
+    [DWARF_E_NO_ENTRY] = N_("no entries found"),
+    [DWARF_E_INVALID_DWARF] = N_("invalid DWARF"),
+    [DWARF_E_NO_STRING] = N_("no string data"),
+    [DWARF_E_NO_ADDR] = N_("no address value"),
+    [DWARF_E_NO_CONSTANT] = N_("no constant value"),
+    [DWARF_E_NO_REFERENCE] = N_("no reference value"),
+    [DWARF_E_INVALID_REFERENCE] = N_("invalid reference value"),
+    [DWARF_E_NO_DEBUG_LINE] = N_(".debug_line section missing"),
+    [DWARF_E_INVALID_DEBUG_LINE] = N_("invalid .debug_line section"),
+    [DWARF_E_TOO_BIG] = N_("debug information too big"),
+    [DWARF_E_VERSION] = N_("invalid DWARF version"),
+    [DWARF_E_INVALID_DIR_IDX] = N_("invalid directory index"),
+    [DWARF_E_ADDR_OUTOFRANGE] = N_("address out of range"),
+    [DWARF_E_NO_LOCLIST] = N_("no location list value"),
+    [DWARF_E_NO_BLOCK] = N_("no block data"),
+    [DWARF_E_INVALID_LINE_IDX] = N_("invalid line index"),
+    [DWARF_E_INVALID_ARANGE_IDX] = N_("invalid address range index"),
+    [DWARF_E_NO_MATCH] = N_("no matching address range"),
+    [DWARF_E_NO_FLAG] = N_("no flag value"),
+    [DWARF_E_INVALID_OFFSET] = N_("invalid offset"),
+    [DWARF_E_NO_DEBUG_RANGES] = N_(".debug_ranges section missing"),
+    [DWARF_E_INVALID_CFI] = N_("invalid CFI section"),
+    [DWARF_E_NO_ALT_DEBUGLINK] = N_("no alternative debug link found"),
+    [DWARF_E_INVALID_OPCODE] = N_("invalid opcode"),
+    [DWARF_E_NOT_CUDIE] = N_("not a CU (unit) DIE"),
+    [DWARF_E_UNKNOWN_LANGUAGE] = N_("unknown language code")
+  };
+#define nerrmsgs (sizeof (errmsgs) / sizeof (errmsgs[0]))
+
+
+void
+internal_function
+__libdw_seterrno (int value)
+{
+  global_error = (value >= 0 && value < (int) nerrmsgs
+		  ? value : DWARF_E_UNKNOWN_ERROR);
+}
+
+
+const char *
+dwarf_errmsg (int error)
+{
+  int last_error = global_error;
+
+  if (error == 0)
+    return last_error != 0 ? _(errmsgs[last_error]) : NULL;
+  else if (error < -1 || error >= (int) nerrmsgs)
+    return _(errmsgs[DWARF_E_UNKNOWN_ERROR]);
+
+  return _(errmsgs[error == -1 ? last_error : error]);
+}
+INTDEF(dwarf_errmsg)
diff --git a/third_party/elfutils/libdw/dwarf_filesrc.c b/third_party/elfutils/libdw/dwarf_filesrc.c
new file mode 100644
index 0000000..d866ce7
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_filesrc.c
@@ -0,0 +1,51 @@
+/* Find source file information.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+const char *
+dwarf_filesrc (Dwarf_Files *file, size_t idx, Dwarf_Word *mtime,
+	       Dwarf_Word *length)
+{
+  if (file == NULL || idx >= file->nfiles)
+    return NULL;
+
+  if (mtime != NULL)
+    *mtime = file->info[idx].mtime;
+
+  if (length != NULL)
+    *length = file->info[idx].length;
+
+  return file->info[idx].name;
+}
diff --git a/third_party/elfutils/libdw/dwarf_formaddr.c b/third_party/elfutils/libdw/dwarf_formaddr.c
new file mode 100644
index 0000000..ddc4838
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_formaddr.c
@@ -0,0 +1,57 @@
+/* Return address represented by attribute.
+   Copyright (C) 2003-2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
+{
+  if (attr == NULL)
+    return -1;
+
+  if (unlikely (attr->form != DW_FORM_addr))
+    {
+      __libdw_seterrno (DWARF_E_NO_ADDR);
+      return -1;
+    }
+
+  if (__libdw_read_address (attr->cu->dbg,
+			    cu_sec_idx (attr->cu), attr->valp,
+			    attr->cu->address_size, return_addr))
+    return -1;
+
+  return 0;
+}
+INTDEF(dwarf_formaddr)
diff --git a/third_party/elfutils/libdw/dwarf_formblock.c b/third_party/elfutils/libdw/dwarf_formblock.c
new file mode 100644
index 0000000..13f9e72
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_formblock.c
@@ -0,0 +1,93 @@
+/* Return block represented by attribute.
+   Copyright (C) 2004-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_formblock (Dwarf_Attribute *attr, Dwarf_Block *return_block)
+{
+  if (attr == NULL)
+    return -1;
+
+  const unsigned char *datap = attr->valp;
+  const unsigned char *endp = attr->cu->endp;
+
+  switch (attr->form)
+    {
+    case DW_FORM_block1:
+      if (unlikely (endp - datap < 1))
+	goto invalid;
+      return_block->length = *(uint8_t *) attr->valp;
+      return_block->data = attr->valp + 1;
+      break;
+
+    case DW_FORM_block2:
+      if (unlikely (endp - datap < 2))
+	goto invalid;
+      return_block->length = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
+      return_block->data = attr->valp + 2;
+      break;
+
+    case DW_FORM_block4:
+      if (unlikely (endp - datap < 4))
+	goto invalid;
+      return_block->length = read_4ubyte_unaligned (attr->cu->dbg, attr->valp);
+      return_block->data = attr->valp + 4;
+      break;
+
+    case DW_FORM_block:
+    case DW_FORM_exprloc:
+      if (unlikely (endp - datap < 1))
+	goto invalid;
+      get_uleb128 (return_block->length, datap, endp);
+      return_block->data = (unsigned char *) datap;
+      break;
+
+    default:
+      __libdw_seterrno (DWARF_E_NO_BLOCK);
+      return -1;
+    }
+
+  if (unlikely (return_block->length > (size_t) (endp - return_block->data)))
+    {
+      /* Block does not fit.  */
+    invalid:
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return -1;
+    }
+
+  return 0;
+}
+INTDEF(dwarf_formblock)
diff --git a/third_party/elfutils/libdw/dwarf_formflag.c b/third_party/elfutils/libdw/dwarf_formflag.c
new file mode 100644
index 0000000..b48ede4
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_formflag.c
@@ -0,0 +1,59 @@
+/* Return flag represented by attribute.
+   Copyright (C) 2004-2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_formflag (Dwarf_Attribute *attr, bool *return_bool)
+{
+  if (attr == NULL)
+    return -1;
+
+  if (attr->form == DW_FORM_flag_present)
+    {
+      *return_bool = true;
+      return 0;
+    }
+
+  if (unlikely (attr->form != DW_FORM_flag))
+    {
+      __libdw_seterrno (DWARF_E_NO_FLAG);
+      return -1;
+    }
+
+  *return_bool = *attr->valp != 0;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_formref.c b/third_party/elfutils/libdw/dwarf_formref.c
new file mode 100644
index 0000000..2240a25
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_formref.c
@@ -0,0 +1,110 @@
+/* Return reference offset represented by attribute.
+   Copyright (C) 2003-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+int
+internal_function
+__libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
+{
+  const unsigned char *datap = attr->valp;
+  const unsigned char *endp = attr->cu->endp;
+
+  if (attr->valp == NULL)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_REFERENCE);
+      return -1;
+    }
+
+  switch (attr->form)
+    {
+    case DW_FORM_ref1:
+      if (datap + 1 > endp)
+	{
+	invalid:
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  return -1;
+	}
+      *return_offset = *attr->valp;
+      break;
+
+    case DW_FORM_ref2:
+      if (datap + 2 > endp)
+	goto invalid;
+      *return_offset = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
+      break;
+
+    case DW_FORM_ref4:
+      if (datap + 4 > endp)
+	goto invalid;
+      *return_offset = read_4ubyte_unaligned (attr->cu->dbg, attr->valp);
+      break;
+
+    case DW_FORM_ref8:
+      if (datap + 8 > endp)
+	goto invalid;
+      *return_offset = read_8ubyte_unaligned (attr->cu->dbg, attr->valp);
+      break;
+
+    case DW_FORM_ref_udata:
+      if (datap + 1 > endp)
+	goto invalid;
+      get_uleb128 (*return_offset, datap, endp);
+      break;
+
+    case DW_FORM_ref_addr:
+    case DW_FORM_ref_sig8:
+    case DW_FORM_GNU_ref_alt:
+      /* These aren't handled by dwarf_formref, only by dwarf_formref_die.  */
+      __libdw_seterrno (DWARF_E_INVALID_REFERENCE);
+      return -1;
+
+    default:
+      __libdw_seterrno (DWARF_E_NO_REFERENCE);
+      return -1;
+    }
+
+  return 0;
+}
+
+/* This is the old public entry point.
+   It is now deprecated in favor of dwarf_formref_die.  */
+int
+dwarf_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
+{
+  if (attr == NULL)
+    return -1;
+
+  return __libdw_formref (attr, return_offset);
+}
diff --git a/third_party/elfutils/libdw/dwarf_formref_die.c b/third_party/elfutils/libdw/dwarf_formref_die.c
new file mode 100644
index 0000000..704816f
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_formref_die.c
@@ -0,0 +1,119 @@
+/* Look up the DIE in a reference-form attribute.
+   Copyright (C) 2005-2010, 2018 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+Dwarf_Die *
+dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *result)
+{
+  if (attr == NULL)
+    return NULL;
+
+  struct Dwarf_CU *cu = attr->cu;
+
+  Dwarf_Off offset;
+  if (attr->form == DW_FORM_ref_addr || attr->form == DW_FORM_GNU_ref_alt)
+    {
+      /* This has an absolute offset.  */
+
+      uint8_t ref_size = (cu->version == 2 && attr->form == DW_FORM_ref_addr
+			  ? cu->address_size
+			  : cu->offset_size);
+
+      Dwarf *dbg_ret = (attr->form == DW_FORM_GNU_ref_alt
+			? INTUSE(dwarf_getalt) (cu->dbg) : cu->dbg);
+
+      if (dbg_ret == NULL)
+	{
+	  __libdw_seterrno (DWARF_E_NO_ALT_DEBUGLINK);
+	  return NULL;
+	}
+
+      if (__libdw_read_offset (cu->dbg, dbg_ret, IDX_debug_info, attr->valp,
+			       ref_size, &offset, IDX_debug_info, 0))
+	return NULL;
+
+      return INTUSE(dwarf_offdie) (dbg_ret, offset, result);
+    }
+
+  const unsigned char *datap;
+  size_t size;
+  if (attr->form == DW_FORM_ref_sig8)
+    {
+      /* This doesn't have an offset, but instead a value we
+	 have to match in the .debug_types type unit headers.  */
+
+      uint64_t sig = read_8ubyte_unaligned (cu->dbg, attr->valp);
+      cu = Dwarf_Sig8_Hash_find (&cu->dbg->sig8_hash, sig, NULL);
+      if (cu == NULL)
+	/* Not seen before.  We have to scan through the type units.  */
+	do
+	  {
+	    cu = __libdw_intern_next_unit (attr->cu->dbg, true);
+	    if (cu == NULL)
+	      {
+		__libdw_seterrno (INTUSE(dwarf_errno) ()
+				  ?: DWARF_E_INVALID_REFERENCE);
+		return NULL;
+	      }
+	  }
+	while (cu->type_sig8 != sig);
+
+      datap = cu->dbg->sectiondata[IDX_debug_types]->d_buf;
+      size = cu->dbg->sectiondata[IDX_debug_types]->d_size;
+      offset = cu->start + cu->type_offset;
+    }
+  else
+    {
+      /* Other forms produce an offset from the CU.  */
+      if (unlikely (__libdw_formref (attr, &offset) != 0))
+	return NULL;
+
+      datap = cu->startp;
+      size = cu->endp - cu->startp;
+    }
+
+  if (unlikely (offset >= size))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  memset (result, '\0', sizeof (Dwarf_Die));
+  result->addr = (char *) datap + offset;
+  result->cu = cu;
+  return result;
+}
+INTDEF (dwarf_formref_die)
diff --git a/third_party/elfutils/libdw/dwarf_formsdata.c b/third_party/elfutils/libdw/dwarf_formsdata.c
new file mode 100644
index 0000000..bc2b508
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_formsdata.c
@@ -0,0 +1,96 @@
+/* Return signed constant represented by attribute.
+   Copyright (C) 2003, 2005, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_formsdata (Dwarf_Attribute *attr, Dwarf_Sword *return_sval)
+{
+  if (attr == NULL)
+    return -1;
+
+  const unsigned char *datap = attr->valp;
+  const unsigned char *endp = attr->cu->endp;
+
+  switch (attr->form)
+    {
+    case DW_FORM_data1:
+      if (datap + 1 > endp)
+	{
+	invalid:
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  return -1;
+	}
+      *return_sval = (signed char) *attr->valp;
+      break;
+
+    case DW_FORM_data2:
+      if (datap + 2 > endp)
+	goto invalid;
+      *return_sval = read_2sbyte_unaligned (attr->cu->dbg, attr->valp);
+      break;
+
+    case DW_FORM_data4:
+      if (datap + 4 > endp)
+	goto invalid;
+      *return_sval = read_4sbyte_unaligned (attr->cu->dbg, attr->valp);
+      break;
+
+    case DW_FORM_data8:
+      if (datap + 8 > endp)
+	goto invalid;
+      *return_sval = read_8sbyte_unaligned (attr->cu->dbg, attr->valp);
+      break;
+
+    case DW_FORM_sdata:
+      if (datap + 1 > endp)
+	goto invalid;
+      get_sleb128 (*return_sval, datap, endp);
+      break;
+
+    case DW_FORM_udata:
+      if (datap + 1 > endp)
+	goto invalid;
+      get_uleb128 (*return_sval, datap, endp);
+      break;
+
+    default:
+      __libdw_seterrno (DWARF_E_NO_CONSTANT);
+      return -1;
+    }
+
+  return 0;
+}
+INTDEF(dwarf_formsdata)
diff --git a/third_party/elfutils/libdw/dwarf_formstring.c b/third_party/elfutils/libdw/dwarf_formstring.c
new file mode 100644
index 0000000..4eae0ed
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_formstring.c
@@ -0,0 +1,76 @@
+/* Return string associated with given attribute.
+   Copyright (C) 2003-2010, 2013, 2018 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+const char *
+dwarf_formstring (Dwarf_Attribute *attrp)
+{
+  /* Ignore earlier errors.  */
+  if (attrp == NULL)
+    return NULL;
+
+  /* We found it.  Now determine where the string is stored.  */
+  if (attrp->form == DW_FORM_string)
+    /* A simple inlined string.  */
+    return (const char *) attrp->valp;
+
+  Dwarf *dbg = attrp->cu->dbg;
+  Dwarf *dbg_ret = (attrp->form == DW_FORM_GNU_strp_alt
+		    ? INTUSE(dwarf_getalt) (dbg) : dbg);
+
+  if (unlikely (dbg_ret == NULL))
+    {
+      __libdw_seterrno (DWARF_E_NO_ALT_DEBUGLINK);
+      return NULL;
+    }
+
+
+  if (unlikely (attrp->form != DW_FORM_strp
+		   && attrp->form != DW_FORM_GNU_strp_alt)
+      || dbg_ret->sectiondata[IDX_debug_str] == NULL)
+    {
+      __libdw_seterrno (DWARF_E_NO_STRING);
+      return NULL;
+    }
+
+  uint64_t off;
+  if (__libdw_read_offset (dbg, dbg_ret, cu_sec_idx (attrp->cu), attrp->valp,
+			   attrp->cu->offset_size, &off, IDX_debug_str, 1))
+    return NULL;
+
+  return (const char *) dbg_ret->sectiondata[IDX_debug_str]->d_buf + off;
+}
+INTDEF(dwarf_formstring)
diff --git a/third_party/elfutils/libdw/dwarf_formudata.c b/third_party/elfutils/libdw/dwarf_formudata.c
new file mode 100644
index 0000000..e41981a
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_formudata.c
@@ -0,0 +1,231 @@
+/* Return unsigned constant represented by attribute.
+   Copyright (C) 2003-2012, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+internal_function unsigned char *
+__libdw_formptr (Dwarf_Attribute *attr, int sec_index,
+		 int err_nodata, unsigned char **endpp,
+		 Dwarf_Off *offsetp)
+{
+  if (attr == NULL)
+    return NULL;
+
+  const Elf_Data *d = attr->cu->dbg->sectiondata[sec_index];
+  if (unlikely (d == NULL))
+    {
+      __libdw_seterrno (err_nodata);
+      return NULL;
+    }
+
+  Dwarf_Word offset;
+  if (attr->form == DW_FORM_sec_offset)
+    {
+      if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg,
+			       cu_sec_idx (attr->cu), attr->valp,
+			       attr->cu->offset_size, &offset, sec_index, 0))
+	return NULL;
+    }
+  else if (attr->cu->version > 3)
+    goto invalid;
+  else
+    switch (attr->form)
+      {
+      case DW_FORM_data4:
+      case DW_FORM_data8:
+	if (__libdw_read_offset (attr->cu->dbg, attr->cu->dbg,
+				 cu_sec_idx (attr->cu),
+				 attr->valp,
+				 attr->form == DW_FORM_data4 ? 4 : 8,
+				 &offset, sec_index, 0))
+	  return NULL;
+	break;
+
+      default:
+	if (INTUSE(dwarf_formudata) (attr, &offset))
+	  return NULL;
+      };
+
+  unsigned char *readp = d->d_buf + offset;
+  unsigned char *endp = d->d_buf + d->d_size;
+  if (unlikely (readp >= endp))
+    {
+    invalid:
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  if (endpp != NULL)
+    *endpp = endp;
+  if (offsetp != NULL)
+    *offsetp = offset;
+  return readp;
+}
+
+int
+dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
+{
+  if (attr == NULL)
+    return -1;
+
+  const unsigned char *datap = attr->valp;
+  const unsigned char *endp = attr->cu->endp;
+
+  switch (attr->form)
+    {
+    case DW_FORM_data1:
+      if (datap + 1 > endp)
+	{
+	invalid:
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  return -1;
+	}
+      *return_uval = *attr->valp;
+      break;
+
+    case DW_FORM_data2:
+      if (datap + 2 > endp)
+	goto invalid;
+      *return_uval = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
+      break;
+
+    case DW_FORM_data4:
+    case DW_FORM_data8:
+    case DW_FORM_sec_offset:
+      /* Before DWARF4 data4 and data8 are pure constants unless the
+	 attribute also allows offsets (*ptr classes), since DWARF4
+	 they are always just constants (start_scope is special though,
+	 since it only could express a rangelist since DWARF4).  */
+      if (attr->form == DW_FORM_sec_offset
+	  || (attr->cu->version < 4 && attr->code != DW_AT_start_scope))
+	{
+	  switch (attr->code)
+	    {
+	    case DW_AT_data_member_location:
+	    case DW_AT_frame_base:
+	    case DW_AT_location:
+	    case DW_AT_return_addr:
+	    case DW_AT_segment:
+	    case DW_AT_static_link:
+	    case DW_AT_string_length:
+	    case DW_AT_use_location:
+	    case DW_AT_vtable_elem_location:
+	      /* loclistptr */
+	      if (__libdw_formptr (attr, IDX_debug_loc,
+				   DWARF_E_NO_LOCLIST, NULL,
+				   return_uval) == NULL)
+		return -1;
+	      break;
+
+	    case DW_AT_macro_info:
+	      /* macptr into .debug_macinfo */
+	      if (__libdw_formptr (attr, IDX_debug_macinfo,
+				   DWARF_E_NO_ENTRY, NULL,
+				   return_uval) == NULL)
+		return -1;
+	      break;
+
+	    case DW_AT_GNU_macros:
+	      /* macptr into .debug_macro */
+	      if (__libdw_formptr (attr, IDX_debug_macro,
+				   DWARF_E_NO_ENTRY, NULL,
+				   return_uval) == NULL)
+		return -1;
+	      break;
+
+	    case DW_AT_ranges:
+	    case DW_AT_start_scope:
+	      /* rangelistptr */
+	      if (__libdw_formptr (attr, IDX_debug_ranges,
+				   DWARF_E_NO_DEBUG_RANGES, NULL,
+				   return_uval) == NULL)
+		return -1;
+	      break;
+
+	    case DW_AT_stmt_list:
+	      /* lineptr */
+	      if (__libdw_formptr (attr, IDX_debug_line,
+				   DWARF_E_NO_DEBUG_LINE, NULL,
+				   return_uval) == NULL)
+		return -1;
+	      break;
+
+	    default:
+	      /* sec_offset can only be used by one of the above attrs.  */
+	      if (attr->form == DW_FORM_sec_offset)
+		{
+		  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+		  return -1;
+		}
+
+	      /* Not one of the special attributes, just a constant.  */
+	      if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
+					attr->valp,
+					attr->form == DW_FORM_data4 ? 4 : 8,
+					return_uval))
+		return -1;
+	      break;
+	    }
+	}
+      else
+	{
+	  /* We are dealing with a constant data4 or data8.  */
+	  if (__libdw_read_address (attr->cu->dbg, cu_sec_idx (attr->cu),
+				    attr->valp,
+				    attr->form == DW_FORM_data4 ? 4 : 8,
+				    return_uval))
+	    return -1;
+	}
+      break;
+
+    case DW_FORM_sdata:
+      if (datap + 1 > endp)
+	goto invalid;
+      get_sleb128 (*return_uval, datap, endp);
+      break;
+
+    case DW_FORM_udata:
+      if (datap + 1 > endp)
+	goto invalid;
+      get_uleb128 (*return_uval, datap, endp);
+      break;
+
+    default:
+      __libdw_seterrno (DWARF_E_NO_CONSTANT);
+      return -1;
+    }
+
+  return 0;
+}
+INTDEF(dwarf_formudata)
diff --git a/third_party/elfutils/libdw/dwarf_frame_cfa.c b/third_party/elfutils/libdw/dwarf_frame_cfa.c
new file mode 100644
index 0000000..07f998c
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_frame_cfa.c
@@ -0,0 +1,77 @@
+/* Get CFA expression for frame.
+   Copyright (C) 2009-2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include <dwarf.h>
+#include <stdlib.h>
+
+int
+dwarf_frame_cfa (Dwarf_Frame *fs, Dwarf_Op **ops, size_t *nops)
+{
+  /* Maybe there was a previous error.  */
+  if (fs == NULL)
+    return -1;
+
+  int result = 0;
+  switch (fs->cfa_rule)
+    {
+    case cfa_undefined:
+      *ops = NULL;
+      *nops = 0;
+      break;
+
+    case cfa_offset:
+      /* The Dwarf_Op was already fully initialized by execute_cfi.  */
+      *ops = &fs->cfa_data.offset;
+      *nops = 1;
+      break;
+
+    case cfa_expr:
+      /* Parse the expression into internal form.  */
+      result = __libdw_intern_expression
+	(NULL, fs->cache->other_byte_order,
+	 fs->cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8, 4,
+	 &fs->cache->expr_tree, &fs->cfa_data.expr, false, false,
+	 ops, nops, IDX_debug_frame);
+      break;
+
+    case cfa_invalid:
+      __libdw_seterrno (DWARF_E_INVALID_CFI);
+      result = -1;
+      break;
+
+    default:
+      abort ();
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/libdw/dwarf_frame_info.c b/third_party/elfutils/libdw/dwarf_frame_info.c
new file mode 100644
index 0000000..9ba560f
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_frame_info.c
@@ -0,0 +1,50 @@
+/* Get return address register for frame.
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+
+int
+dwarf_frame_info (Dwarf_Frame *fs, Dwarf_Addr *start, Dwarf_Addr *end,
+		  bool *signalp)
+{
+  /* Maybe there was a previous error.  */
+  if (fs == NULL)
+    return -1;
+
+  if (start != NULL)
+    *start = fs->start;
+  if (end != NULL)
+    *end = fs->end;
+  if (signalp != NULL)
+    *signalp = fs->fde->cie->signal_frame;
+  return fs->fde->cie->return_address_register;
+}
diff --git a/third_party/elfutils/libdw/dwarf_frame_register.c b/third_party/elfutils/libdw/dwarf_frame_register.c
new file mode 100644
index 0000000..d0159fb
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_frame_register.c
@@ -0,0 +1,119 @@
+/* Get register location expression for frame.
+   Copyright (C) 2009-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include <dwarf.h>
+
+int
+dwarf_frame_register (Dwarf_Frame *fs, int regno, Dwarf_Op *ops_mem,
+		      Dwarf_Op **ops, size_t *nops)
+{
+  /* Maybe there was a previous error.  */
+  if (fs == NULL)
+    return -1;
+
+  if (unlikely (regno < 0))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_ACCESS);
+      return -1;
+    }
+
+  *ops = ops_mem;
+  *nops = 0;
+
+  if (unlikely ((size_t) regno >= fs->nregs))
+    goto default_rule;
+
+  const struct dwarf_frame_register *reg = &fs->regs[regno];
+
+  switch (reg->rule)
+    {
+    case reg_unspecified:
+    default_rule:
+      /* Use the default rule for registers not yet mentioned in CFI.  */
+      if (fs->cache->default_same_value)
+	goto same_value;
+      FALLTHROUGH;
+    case reg_undefined:
+      /* The value is known to be unavailable.  */
+      break;
+
+    case reg_same_value:
+    same_value:
+      /* The location is not known here, but the caller might know it.  */
+      *ops = NULL;
+      break;
+
+    case reg_offset:
+    case reg_val_offset:
+      ops_mem[(*nops)++] = (Dwarf_Op) { .atom = DW_OP_call_frame_cfa };
+      if (reg->value != 0)
+	ops_mem[(*nops)++] = (Dwarf_Op) { .atom = DW_OP_plus_uconst,
+					  .number = reg->value };
+      if (reg->rule == reg_val_offset)
+	/* A value, not a location.  */
+	ops_mem[(*nops)++] = (Dwarf_Op) { .atom = DW_OP_stack_value };
+      *ops = ops_mem;
+      break;
+
+    case reg_register:
+      ops_mem[(*nops)++] = (Dwarf_Op) { .atom = DW_OP_regx,
+					.number = reg->value };
+      break;
+
+    case reg_val_expression:
+    case reg_expression:
+      {
+	unsigned int address_size = (fs->cache->e_ident[EI_CLASS] == ELFCLASS32
+				     ? 4 : 8);
+
+	Dwarf_Block block;
+	const uint8_t *p = fs->cache->data->d.d_buf + reg->value;
+	const uint8_t *end = (fs->cache->data->d.d_buf
+			      + fs->cache->data->d.d_size);
+	get_uleb128 (block.length, p, end);
+	block.data = (void *) p;
+
+	/* Parse the expression into internal form.  */
+	if (__libdw_intern_expression (NULL,
+				       fs->cache->other_byte_order,
+				       address_size, 4,
+				       &fs->cache->expr_tree, &block,
+				       true, reg->rule == reg_val_expression,
+				       ops, nops, IDX_debug_frame) < 0)
+	  return -1;
+	break;
+      }
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_func_inline.c b/third_party/elfutils/libdw/dwarf_func_inline.c
new file mode 100644
index 0000000..1f04adf
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_func_inline.c
@@ -0,0 +1,101 @@
+/* Convenience functions for handling DWARF descriptions of inline functions.
+   Copyright (C) 2005,2006,2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+struct visitor_info
+{
+  void *die_addr;
+  int (*callback) (Dwarf_Die *, void *);
+  void *arg;
+};
+
+static int
+scope_visitor (unsigned int depth __attribute__ ((unused)),
+	       struct Dwarf_Die_Chain *die, void *arg)
+{
+  struct visitor_info *const v = arg;
+
+  if (INTUSE(dwarf_tag) (&die->die) != DW_TAG_inlined_subroutine)
+    return DWARF_CB_OK;
+
+  Dwarf_Attribute attr_mem;
+  Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&die->die, DW_AT_abstract_origin,
+					      &attr_mem);
+  if (attr == NULL)
+    return DWARF_CB_OK;
+
+  Dwarf_Die origin_mem;
+  Dwarf_Die *origin = INTUSE(dwarf_formref_die) (attr, &origin_mem);
+  if (origin == NULL)
+    return DWARF_CB_ABORT;
+
+  if (origin->addr != v->die_addr)
+    return DWARF_CB_OK;
+
+  return (*v->callback) (&die->die, v->arg);
+}
+
+int
+dwarf_func_inline (Dwarf_Die *func)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Word val;
+  if (INTUSE(dwarf_formudata) (INTUSE(dwarf_attr) (func, DW_AT_inline,
+						   &attr_mem),
+			       &val) == 0)
+  switch (val)
+    {
+    case DW_INL_not_inlined:
+      return 0;
+
+    case DW_INL_declared_not_inlined:
+      return -1;
+
+    case DW_INL_inlined:
+    case DW_INL_declared_inlined:
+      return 1;
+    }
+
+  return 0;
+}
+
+int
+dwarf_func_inline_instances (Dwarf_Die *func,
+			     int (*callback) (Dwarf_Die *, void *),
+			     void *arg)
+{
+  struct visitor_info v = { func->addr, callback, arg };
+  struct Dwarf_Die_Chain cu = { .die = CUDIE (func->cu), .parent = NULL };
+  return __libdw_visit_scopes (0, &cu, NULL, &scope_visitor, NULL, &v);
+}
diff --git a/third_party/elfutils/libdw/dwarf_getabbrev.c b/third_party/elfutils/libdw/dwarf_getabbrev.c
new file mode 100644
index 0000000..a3a68b3
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getabbrev.c
@@ -0,0 +1,157 @@
+/* Get abbreviation at given offset.
+   Copyright (C) 2003, 2004, 2005, 2006, 2014, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+Dwarf_Abbrev *
+internal_function
+__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset,
+		   size_t *lengthp, Dwarf_Abbrev *result)
+{
+  /* Don't fail if there is not .debug_abbrev section.  */
+  if (dbg->sectiondata[IDX_debug_abbrev] == NULL)
+    return NULL;
+
+  if (offset >= dbg->sectiondata[IDX_debug_abbrev]->d_size)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+      return NULL;
+    }
+
+  const unsigned char *abbrevp
+    = (unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf + offset;
+
+  if (*abbrevp == '\0')
+    /* We are past the last entry.  */
+    return DWARF_END_ABBREV;
+
+  /* 7.5.3 Abbreviations Tables
+
+     [...] Each declaration begins with an unsigned LEB128 number
+     representing the abbreviation code itself.  [...]  The
+     abbreviation code is followed by another unsigned LEB128
+     number that encodes the entry's tag.  [...]
+
+     [...] Following the tag encoding is a 1-byte value that
+     determines whether a debugging information entry using this
+     abbreviation has child entries or not. [...]
+
+     [...] Finally, the child encoding is followed by a series of
+     attribute specifications. Each attribute specification
+     consists of two parts. The first part is an unsigned LEB128
+     number representing the attribute's name. The second part is
+     an unsigned LEB128 number representing the attribute's form.  */
+  const unsigned char *end = (dbg->sectiondata[IDX_debug_abbrev]->d_buf
+			      + dbg->sectiondata[IDX_debug_abbrev]->d_size);
+  const unsigned char *start_abbrevp = abbrevp;
+  unsigned int code;
+  get_uleb128 (code, abbrevp, end);
+
+  /* Check whether this code is already in the hash table.  */
+  bool foundit = false;
+  Dwarf_Abbrev *abb = NULL;
+  if (cu == NULL
+      || (abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code, NULL)) == NULL)
+    {
+      if (result == NULL)
+	abb = libdw_typed_alloc (dbg, Dwarf_Abbrev);
+      else
+	abb = result;
+    }
+  else
+    {
+      foundit = true;
+
+      if (unlikely (abb->offset != offset))
+	{
+	  /* A duplicate abbrev code at a different offset,
+	     that should never happen.  */
+	invalid:
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  return NULL;
+	}
+
+      /* If the caller doesn't need the length we are done.  */
+      if (lengthp == NULL)
+	goto out;
+    }
+
+  /* If there is already a value in the hash table we are going to
+     overwrite its content.  This must not be a problem, since the
+     content better be the same.  */
+  abb->code = code;
+  if (abbrevp >= end)
+    goto invalid;
+  get_uleb128 (abb->tag, abbrevp, end);
+  if (abbrevp + 1 >= end)
+    goto invalid;
+  abb->has_children = *abbrevp++ == DW_CHILDREN_yes;
+  abb->attrp = (unsigned char *) abbrevp;
+  abb->offset = offset;
+
+  /* Skip over all the attributes and check rest of the abbrev is valid.  */
+  unsigned int attrname;
+  unsigned int attrform;
+  do
+    {
+      if (abbrevp >= end)
+	goto invalid;
+      get_uleb128 (attrname, abbrevp, end);
+      if (abbrevp >= end)
+	goto invalid;
+      get_uleb128 (attrform, abbrevp, end);
+    }
+  while (attrname != 0 && attrform != 0);
+
+  /* Return the length to the caller if she asked for it.  */
+  if (lengthp != NULL)
+    *lengthp = abbrevp - start_abbrevp;
+
+  /* Add the entry to the hash table.  */
+  if (cu != NULL && ! foundit)
+    (void) Dwarf_Abbrev_Hash_insert (&cu->abbrev_hash, abb->code, abb);
+
+ out:
+  return abb;
+}
+
+
+Dwarf_Abbrev *
+dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset, size_t *lengthp)
+{
+  return __libdw_getabbrev (die->cu->dbg, die->cu,
+			    die->cu->orig_abbrev_offset + offset, lengthp,
+			    NULL);
+}
diff --git a/third_party/elfutils/libdw/dwarf_getabbrevattr.c b/third_party/elfutils/libdw/dwarf_getabbrevattr.c
new file mode 100644
index 0000000..57fe363
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getabbrevattr.c
@@ -0,0 +1,76 @@
+/* Get specific attribute of abbreviation.
+   Copyright (C) 2003, 2004, 2005, 2014, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_getabbrevattr (Dwarf_Abbrev *abbrev, size_t idx, unsigned int *namep,
+		     unsigned int *formp, Dwarf_Off *offsetp)
+{
+  if (abbrev == NULL)
+    return -1;
+
+  size_t cnt = 0;
+  const unsigned char *attrp = abbrev->attrp;
+  const unsigned char *start_attrp;
+  unsigned int name;
+  unsigned int form;
+
+  do
+    {
+      start_attrp = attrp;
+
+      /* Attribute code and form are encoded as ULEB128 values.
+         Already checked when Dwarf_Abbrev was created, read unchecked.  */
+      get_uleb128_unchecked (name, attrp);
+      get_uleb128_unchecked (form, attrp);
+
+      /* If both values are zero the index is out of range.  */
+      if (name == 0 && form == 0)
+	return -1;
+    }
+  while (cnt++ < idx);
+
+  /* Store the result if requested.  */
+  if (namep != NULL)
+    *namep = name;
+  if (formp != NULL)
+    *formp = form;
+  if (offsetp != NULL)
+    *offsetp = (start_attrp - abbrev->attrp) + abbrev->offset;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getabbrevcode.c b/third_party/elfutils/libdw/dwarf_getabbrevcode.c
new file mode 100644
index 0000000..8691708
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getabbrevcode.c
@@ -0,0 +1,43 @@
+/* Get abbreviation code.
+   Copyright (C) 2003 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+unsigned int
+dwarf_getabbrevcode (Dwarf_Abbrev *abbrev)
+{
+  return abbrev == NULL ? 0 : abbrev->code;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getabbrevtag.c b/third_party/elfutils/libdw/dwarf_getabbrevtag.c
new file mode 100644
index 0000000..52aaa3f
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getabbrevtag.c
@@ -0,0 +1,43 @@
+/* Get abbreviation tag.
+   Copyright (C) 2003 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+unsigned int
+dwarf_getabbrevtag (Dwarf_Abbrev *abbrev)
+{
+  return abbrev == NULL ? 0 : abbrev->tag;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getalt.c b/third_party/elfutils/libdw/dwarf_getalt.c
new file mode 100644
index 0000000..3e5af15
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getalt.c
@@ -0,0 +1,196 @@
+/* Retrieves the DWARF descriptor for debugaltlink data.
+   Copyright (C) 2014, 2018 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include "libelfP.h"
+#include "libdwelfP.h"
+#include "system.h"
+
+#include <inttypes.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+char *
+internal_function
+__libdw_filepath (int fd, const char *dir, const char *file)
+{
+  if (file == NULL)
+    return NULL;
+
+  if (file[0] == '/')
+    return strdup (file);
+
+  if (dir != NULL && dir[0] == '/')
+    {
+      size_t dirlen = strlen (dir);
+      size_t filelen = strlen (file);
+      size_t len = dirlen + 1 + filelen + 1;
+      char *path = malloc (len);
+      if (path != NULL)
+	{
+	  char *c = mempcpy (path, dir, dirlen);
+	  if (dir[dirlen - 1] != '/')
+	    *c++ = '/';
+	  mempcpy (c, file, filelen + 1);
+	}
+      return path;
+    }
+
+  if (fd >= 0)
+    {
+      /* strlen ("/proc/self/fd/") = 14 + strlen (<MAXINT>) = 10 + 1 = 25.  */
+      char devfdpath[25];
+      sprintf (devfdpath, "/proc/self/fd/%u", fd);
+      char *fdpath = realpath (devfdpath, NULL);
+      char *path = NULL;
+      char *fddir;
+      if (fdpath != NULL && fdpath[0] == '/'
+	  && (fddir = strrchr (fdpath, '/')) != NULL)
+	{
+	  *++fddir = '\0';
+	  size_t fdpathlen = strlen (fdpath);
+	  size_t dirlen = dir != NULL ? strlen (dir) : 0;
+	  size_t filelen = strlen (file);
+	  size_t len = fdpathlen + 1 + dirlen + 1 + filelen + 1;
+	  path = malloc (len);
+	  if (path != NULL)
+	    {
+	      char *c = mempcpy (path, fdpath, fdpathlen);
+	      if (dirlen > 0)
+		{
+		  c = mempcpy (c, dir, dirlen);
+		  if (dir[dirlen - 1] != '/')
+		    *c++ = '/';
+		}
+	      mempcpy (c, file, filelen + 1);
+	    }
+	}
+      free (fdpath);
+      return path;
+    }
+
+  return NULL;
+}
+
+static void
+find_debug_altlink (Dwarf *dbg)
+{
+  const char *altname;
+  const void *build_id;
+  ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (dbg,
+							       &altname,
+							       &build_id);
+
+  /* Couldn't even get the debugaltlink.  It probably doesn't exist.  */
+  if (build_id_len <= 0)
+    return;
+
+  const uint8_t *id = (const uint8_t *) build_id;
+  size_t id_len = build_id_len;
+  int fd = -1;
+
+  /* We only look in the standard path.  And relative to the dbg file.  */
+#define DEBUGINFO_PATH "/usr/lib/debug"
+
+  /* We don't handle very short or really large build-ids.  We need at
+     at least 3 and allow for up to 64 (normally ids are 20 long).  */
+#define MIN_BUILD_ID_BYTES 3
+#define MAX_BUILD_ID_BYTES 64
+  if (id_len >= MIN_BUILD_ID_BYTES && id_len <= MAX_BUILD_ID_BYTES)
+    {
+      /* Note sizeof a string literal includes the trailing zero.  */
+      char id_path[sizeof DEBUGINFO_PATH - 1 + sizeof "/.build-id/" - 1
+		   + 2 + 1 + (MAX_BUILD_ID_BYTES - 2) * 2 + sizeof ".debug"];
+      sprintf (&id_path[0], "%s%s", DEBUGINFO_PATH, "/.build-id/");
+      sprintf (&id_path[sizeof DEBUGINFO_PATH - 1 + sizeof "/.build-id/" - 1],
+	       "%02" PRIx8 "/", (uint8_t) id[0]);
+      for (size_t i = 1; i < id_len; ++i)
+	sprintf (&id_path[sizeof DEBUGINFO_PATH - 1 + sizeof "/.build-id/" - 1
+			  + 3 + (i - 1) * 2], "%02" PRIx8, (uint8_t) id[i]);
+      strcpy (&id_path[sizeof DEBUGINFO_PATH - 1 + sizeof "/.build-id/" - 1
+		       + 3 + (id_len - 1) * 2], ".debug");
+
+      fd = TEMP_FAILURE_RETRY (open (id_path, O_RDONLY));
+    }
+
+  /* Fall back on (possible relative) alt file path.  */
+  if (fd < 0)
+    {
+      char *altpath = __libdw_filepath (dbg->elf->fildes, NULL, altname);
+      if (altpath != NULL)
+	{
+	  fd = TEMP_FAILURE_RETRY (open (altpath, O_RDONLY));
+	  free (altpath);
+	}
+    }
+
+  if (fd >= 0)
+    {
+      Dwarf *alt = dwarf_begin (fd, O_RDONLY);
+      if (alt != NULL)
+	{
+	  dbg->alt_dwarf = alt;
+	  dbg->alt_fd = fd;
+	}
+      else
+	close (fd);
+    }
+}
+
+Dwarf *
+dwarf_getalt (Dwarf *main)
+{
+  /* Only try once.  */
+  if (main == NULL || main->alt_dwarf == (void *) -1)
+    return NULL;
+
+  if (main->alt_dwarf != NULL)
+    return main->alt_dwarf;
+
+  find_debug_altlink (main);
+
+  /* If we found nothing, make sure we don't try again.  */
+  if (main->alt_dwarf == NULL)
+    {
+      main->alt_dwarf = (void *) -1;
+      return NULL;
+    }
+
+  return main->alt_dwarf;
+}
+INTDEF (dwarf_getalt)
diff --git a/third_party/elfutils/libdw/dwarf_getarange_addr.c b/third_party/elfutils/libdw/dwarf_getarange_addr.c
new file mode 100644
index 0000000..d383e22
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getarange_addr.c
@@ -0,0 +1,60 @@
+/* Get address range which includes given address.
+   Copyright (C) 2004, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwP.h>
+
+
+Dwarf_Arange *
+dwarf_getarange_addr (Dwarf_Aranges *aranges, Dwarf_Addr addr)
+{
+  if (aranges == NULL)
+    return NULL;
+
+  /* The ranges are sorted by address, so we can use binary search.  */
+  size_t l = 0, u = aranges->naranges;
+  while (l < u)
+    {
+      size_t idx = (l + u) / 2;
+      if (addr < aranges->info[idx].addr)
+	u = idx;
+      else if (addr > aranges->info[idx].addr
+	       && addr - aranges->info[idx].addr >= aranges->info[idx].length)
+	l = idx + 1;
+      else
+	return &aranges->info[idx];
+    }
+
+  __libdw_seterrno (DWARF_E_NO_MATCH);
+  return NULL;
+}
+INTDEF(dwarf_getarange_addr)
diff --git a/third_party/elfutils/libdw/dwarf_getarangeinfo.c b/third_party/elfutils/libdw/dwarf_getarangeinfo.c
new file mode 100644
index 0000000..67b6e67
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getarangeinfo.c
@@ -0,0 +1,53 @@
+/* Return list address ranges.
+   Copyright (C) 2000, 2001, 2002, 2004, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwP.h>
+
+
+int
+dwarf_getarangeinfo (Dwarf_Arange *arange, Dwarf_Addr *addrp,
+		     Dwarf_Word *lengthp, Dwarf_Off *offsetp)
+{
+  if (arange == NULL)
+    return -1;
+
+  if (addrp != NULL)
+    *addrp = arange->addr;
+  if (lengthp != NULL)
+    *lengthp = arange->length;
+  if (offsetp != NULL)
+    *offsetp = arange->offset;
+
+  return 0;
+}
+INTDEF(dwarf_getarangeinfo)
diff --git a/third_party/elfutils/libdw/dwarf_getaranges.c b/third_party/elfutils/libdw/dwarf_getaranges.c
new file mode 100644
index 0000000..4252746
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getaranges.c
@@ -0,0 +1,274 @@
+/* Return list address ranges.
+   Copyright (C) 2000-2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+#include "libdwP.h"
+#include <dwarf.h>
+
+struct arangelist
+{
+  Dwarf_Arange arange;
+  struct arangelist *next;
+};
+
+/* Compare by Dwarf_Arange.addr, given pointers into an array of pointeers.  */
+static int
+compare_aranges (const void *a, const void *b)
+{
+  struct arangelist *const *p1 = a, *const *p2 = b;
+  struct arangelist *l1 = *p1, *l2 = *p2;
+  if (l1->arange.addr != l2->arange.addr)
+    return (l1->arange.addr < l2->arange.addr) ? -1 : 1;
+  return 0;
+}
+
+int
+dwarf_getaranges (Dwarf *dbg, Dwarf_Aranges **aranges, size_t *naranges)
+{
+  if (dbg == NULL)
+    return -1;
+
+  if (dbg->aranges != NULL)
+    {
+      *aranges = dbg->aranges;
+      if (naranges != NULL)
+	*naranges = dbg->aranges->naranges;
+      return 0;
+    }
+
+  if (dbg->sectiondata[IDX_debug_aranges] == NULL)
+    {
+      /* No such section.  */
+      *aranges = NULL;
+      if (naranges != NULL)
+	*naranges = 0;
+      return 0;
+    }
+
+  if (dbg->sectiondata[IDX_debug_aranges]->d_buf == NULL)
+    return -1;
+
+  struct arangelist *arangelist = NULL;
+  unsigned int narangelist = 0;
+
+  const unsigned char *readp = dbg->sectiondata[IDX_debug_aranges]->d_buf;
+  const unsigned char *readendp
+    = readp + dbg->sectiondata[IDX_debug_aranges]->d_size;
+
+  while (readp < readendp)
+    {
+      const unsigned char *hdrstart = readp;
+
+      /* Each entry starts with a header:
+
+	 1. A 4-byte or 12-byte length containing the length of the
+	 set of entries for this compilation unit, not including the
+	 length field itself. [...]
+
+	 2. A 2-byte version identifier containing the value 2 for
+	 DWARF Version 2.1.
+
+	 3. A 4-byte or 8-byte offset into the .debug_info section. [...]
+
+	 4. A 1-byte unsigned integer containing the size in bytes of
+	 an address (or the offset portion of an address for segmented
+	 addressing) on the target system.
+
+	 5. A 1-byte unsigned integer containing the size in bytes of
+	 a segment descriptor on the target system.  */
+      if (unlikely (readp + 4 > readendp))
+	goto invalid;
+
+      Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
+      unsigned int length_bytes = 4;
+      if (length == DWARF3_LENGTH_64_BIT)
+	{
+	  if (unlikely (readp + 8 > readendp))
+	    goto invalid;
+
+	  length = read_8ubyte_unaligned_inc (dbg, readp);
+	  length_bytes = 8;
+	}
+      else if (unlikely (length >= DWARF3_LENGTH_MIN_ESCAPE_CODE
+			 && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE))
+	goto invalid;
+
+      if (unlikely (readp + 2 > readendp))
+	goto invalid;
+
+      unsigned int version = read_2ubyte_unaligned_inc (dbg, readp);
+      if (version != 2)
+	{
+	invalid:
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	fail:
+	  while (arangelist != NULL)
+	    {
+	      struct arangelist *next = arangelist->next;
+	      free (arangelist);
+	      arangelist = next;
+	    }
+	  return -1;
+	}
+
+      Dwarf_Word offset = 0;
+      if (__libdw_read_offset_inc (dbg,
+				   IDX_debug_aranges, &readp,
+				   length_bytes, &offset, IDX_debug_info, 4))
+	goto fail;
+
+      unsigned int address_size = *readp++;
+      if (unlikely (address_size != 4 && address_size != 8))
+	goto invalid;
+
+      /* We don't actually support segment selectors.  */
+      unsigned int segment_size = *readp++;
+      if (segment_size != 0)
+	goto invalid;
+
+      /* Round the address to the next multiple of 2*address_size.  */
+      readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
+		% (2 * address_size));
+
+      while (1)
+	{
+	  Dwarf_Word range_address;
+	  Dwarf_Word range_length;
+
+	  if (__libdw_read_address_inc (dbg, IDX_debug_aranges, &readp,
+					address_size, &range_address))
+	    goto fail;
+
+	  if (readp + address_size > readendp)
+	    goto invalid;
+
+	  if (address_size == 4)
+	    range_length = read_4ubyte_unaligned_inc (dbg, readp);
+	  else
+	    range_length = read_8ubyte_unaligned_inc (dbg, readp);
+
+	  /* Two zero values mark the end.  */
+	  if (range_address == 0 && range_length == 0)
+	    break;
+
+	  /* We don't use alloca for these temporary structures because
+	     the total number of them can be quite large.  */
+	  struct arangelist *new_arange = malloc (sizeof *new_arange);
+	  if (unlikely (new_arange == NULL))
+	    {
+	      __libdw_seterrno (DWARF_E_NOMEM);
+	      goto fail;
+	    }
+
+	  new_arange->arange.addr = range_address;
+	  new_arange->arange.length = range_length;
+
+	  /* We store the actual CU DIE offset, not the CU header offset.  */
+	  const char *cu_header = (dbg->sectiondata[IDX_debug_info]->d_buf
+				   + offset);
+	  unsigned int offset_size;
+	  if (read_4ubyte_unaligned_noncvt (cu_header) == DWARF3_LENGTH_64_BIT)
+	    offset_size = 8;
+	  else
+	    offset_size = 4;
+	  new_arange->arange.offset = DIE_OFFSET_FROM_CU_OFFSET (offset,
+								 offset_size,
+								 false);
+
+	  new_arange->next = arangelist;
+	  arangelist = new_arange;
+	  ++narangelist;
+
+	  /* Sanity-check the data.  */
+	  if (unlikely (new_arange->arange.offset
+			>= dbg->sectiondata[IDX_debug_info]->d_size))
+	    goto invalid;
+	}
+    }
+
+  if (narangelist == 0)
+    {
+      assert (arangelist == NULL);
+      if (naranges != NULL)
+	*naranges = 0;
+      *aranges = NULL;
+      return 0;
+    }
+
+  /* Allocate the array for the result.  */
+  void *buf = libdw_alloc (dbg, Dwarf_Aranges,
+			   sizeof (Dwarf_Aranges)
+			   + narangelist * sizeof (Dwarf_Arange), 1);
+
+  /* First use the buffer for the pointers, and sort the entries.
+     We'll write the pointers in the end of the buffer, and then
+     copy into the buffer from the beginning so the overlap works.  */
+  assert (sizeof (Dwarf_Arange) >= sizeof (Dwarf_Arange *));
+  struct arangelist **sortaranges
+    = (buf + sizeof (Dwarf_Aranges)
+       + ((sizeof (Dwarf_Arange) - sizeof sortaranges[0]) * narangelist));
+
+  /* The list is in LIFO order and usually they come in clumps with
+     ascending addresses.  So fill from the back to probably start with
+     runs already in order before we sort.  */
+  unsigned int i = narangelist;
+  while (i-- > 0)
+    {
+      sortaranges[i] = arangelist;
+      arangelist = arangelist->next;
+    }
+  assert (arangelist == NULL);
+
+  /* Sort by ascending address.  */
+  qsort (sortaranges, narangelist, sizeof sortaranges[0], &compare_aranges);
+
+  /* Now that they are sorted, put them in the final array.
+     The buffers overlap, so we've clobbered the early elements
+     of SORTARANGES by the time we're reading the later ones.  */
+  *aranges = buf;
+  (*aranges)->dbg = dbg;
+  (*aranges)->naranges = narangelist;
+  dbg->aranges = *aranges;
+  if (naranges != NULL)
+    *naranges = narangelist;
+  for (i = 0; i < narangelist; ++i)
+    {
+      struct arangelist *elt = sortaranges[i];
+      (*aranges)->info[i] = elt->arange;
+      free (elt);
+    }
+
+  return 0;
+}
+INTDEF(dwarf_getaranges)
diff --git a/third_party/elfutils/libdw/dwarf_getattrcnt.c b/third_party/elfutils/libdw/dwarf_getattrcnt.c
new file mode 100644
index 0000000..a05976d
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getattrcnt.c
@@ -0,0 +1,61 @@
+/* Get number of attributes of abbreviation.
+   Copyright (C) 2003, 2004, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_getattrcnt (Dwarf_Abbrev *abbrev, size_t *attrcntp)
+{
+  if (abbrev == NULL)
+    return -1;
+
+  const unsigned char *abbrevp = abbrev->attrp;
+
+  /* Skip over all the attributes and count them while doing so.  */
+  int attrcnt = 0;
+  unsigned int attrname;
+  unsigned int attrform;
+  do
+    {
+      /* We can use unchecked since they were checked when the Dwrf_Abbrev
+	 was created.  */
+      get_uleb128_unchecked (attrname, abbrevp);
+      get_uleb128_unchecked (attrform, abbrevp);
+    }
+  while (attrname != 0 && attrform != 0 && ++attrcnt);
+
+  *attrcntp = attrcnt;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getattrs.c b/third_party/elfutils/libdw/dwarf_getattrs.c
new file mode 100644
index 0000000..7f55faf
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getattrs.c
@@ -0,0 +1,110 @@
+/* Get attributes of the DIE.
+   Copyright (C) 2004, 2005, 2008, 2009, 2014, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+ptrdiff_t
+dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
+		void *arg, ptrdiff_t offset)
+{
+  if (die == NULL)
+    return -1l;
+
+  if (unlikely (offset == 1))
+    return 1;
+
+  const unsigned char *die_addr;
+
+  /* Find the abbreviation entry.  */
+  Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &die_addr);
+
+  if (unlikely (abbrevp == DWARF_END_ABBREV))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return -1l;
+    }
+
+  /* This is where the attributes start.  */
+  const unsigned char *attrp = abbrevp->attrp;
+  const unsigned char *const offset_attrp = abbrevp->attrp + offset;
+
+  /* Go over the list of attributes.  */
+  while (1)
+    {
+      /* Get attribute name and form.  Dwarf_Abbrev was checked when
+	 created, so we can read unchecked.  */
+      Dwarf_Attribute attr;
+      const unsigned char *remembered_attrp = attrp;
+
+      get_uleb128_unchecked (attr.code, attrp);
+      get_uleb128_unchecked (attr.form, attrp);
+
+      /* We can stop if we found the attribute with value zero.  */
+      if (attr.code == 0 && attr.form == 0)
+	/* Do not return 0 here - there would be no way to
+	   distinguish this value from the attribute at offset 0.
+	   Instead we return +1 which would never be a valid
+	   offset of an attribute.  */
+        return 1l;
+
+      /* If we are not to OFFSET_ATTRP yet, we just have to skip
+	 the values of the intervening attributes.  */
+      if (remembered_attrp >= offset_attrp)
+	{
+	  /* Fill in the rest.  */
+	  attr.valp = (unsigned char *) die_addr;
+	  attr.cu = die->cu;
+
+	  /* Now call the callback function.  */
+	  if (callback (&attr, arg) != DWARF_CB_OK)
+	    /* Return the offset of the start of the attribute, so that
+	       dwarf_getattrs() can be restarted from this point if the
+	       caller so desires.  */
+	    return remembered_attrp - abbrevp->attrp;
+	}
+
+      /* Skip over the rest of this attribute (if there is any).  */
+      if (attr.form != 0)
+	{
+	  size_t len = __libdw_form_val_len (die->cu, attr.form, die_addr);
+	  if (unlikely (len == (size_t) -1l))
+	    /* Something wrong with the file.  */
+	    return -1l;
+
+	  // __libdw_form_val_len will have done a bounds check.
+	  die_addr += len;
+	}
+    }
+  /* NOTREACHED */
+}
diff --git a/third_party/elfutils/libdw/dwarf_getcfi.c b/third_party/elfutils/libdw/dwarf_getcfi.c
new file mode 100644
index 0000000..9aed403
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getcfi.c
@@ -0,0 +1,72 @@
+/* Get CFI from DWARF file.
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include "cfi.h"
+#include <dwarf.h>
+
+Dwarf_CFI *
+dwarf_getcfi (Dwarf *dbg)
+{
+  if (dbg == NULL)
+    return NULL;
+
+  if (dbg->cfi == NULL && dbg->sectiondata[IDX_debug_frame] != NULL)
+    {
+      Dwarf_CFI *cfi = libdw_typed_alloc (dbg, Dwarf_CFI);
+
+      cfi->dbg = dbg;
+      cfi->data = (Elf_Data_Scn *) dbg->sectiondata[IDX_debug_frame];
+
+      cfi->search_table = NULL;
+      cfi->search_table_vaddr = 0;
+      cfi->search_table_entries = 0;
+      cfi->search_table_encoding = DW_EH_PE_omit;
+
+      cfi->frame_vaddr = 0;
+      cfi->textrel = 0;
+      cfi->datarel = 0;
+
+      cfi->e_ident = (unsigned char *) elf_getident (dbg->elf, NULL);
+      cfi->other_byte_order = dbg->other_byte_order;
+
+      cfi->next_offset = 0;
+      cfi->cie_tree = cfi->fde_tree = cfi->expr_tree = NULL;
+
+      cfi->ebl = NULL;
+
+      dbg->cfi = cfi;
+    }
+
+  return dbg->cfi;
+}
+INTDEF (dwarf_getcfi)
diff --git a/third_party/elfutils/libdw/dwarf_getcfi_elf.c b/third_party/elfutils/libdw/dwarf_getcfi_elf.c
new file mode 100644
index 0000000..315cc02
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getcfi_elf.c
@@ -0,0 +1,336 @@
+/* Get CFI from ELF file's exception-handling info.
+   Copyright (C) 2009-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "libdwP.h"
+#include "cfi.h"
+#include "encoded-value.h"
+#include <dwarf.h>
+
+
+static Dwarf_CFI *
+allocate_cfi (Elf *elf, GElf_Addr vaddr)
+{
+  Dwarf_CFI *cfi = calloc (1, sizeof *cfi);
+  if (cfi == NULL)
+    {
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return NULL;
+    }
+
+  cfi->e_ident = (unsigned char *) elf_getident (elf, NULL);
+  if (cfi->e_ident == NULL)
+    {
+      free (cfi);
+      __libdw_seterrno (DWARF_E_GETEHDR_ERROR);
+      return NULL;
+    }
+
+  if ((BYTE_ORDER == LITTLE_ENDIAN && cfi->e_ident[EI_DATA] == ELFDATA2MSB)
+      || (BYTE_ORDER == BIG_ENDIAN && cfi->e_ident[EI_DATA] == ELFDATA2LSB))
+    cfi->other_byte_order = true;
+
+  cfi->frame_vaddr = vaddr;
+  cfi->textrel = 0;		/* XXX ? */
+  cfi->datarel = 0;		/* XXX ? */
+
+  return cfi;
+}
+
+static const uint8_t *
+parse_eh_frame_hdr (const uint8_t *hdr, size_t hdr_size, GElf_Addr hdr_vaddr,
+		    const GElf_Ehdr *ehdr, GElf_Addr *eh_frame_vaddr,
+		    size_t *table_entries, uint8_t *table_encoding)
+{
+  const uint8_t *h = hdr;
+
+  if (hdr_size < 4 || *h++ != 1)		/* version */
+    return (void *) -1l;
+
+  uint8_t eh_frame_ptr_encoding = *h++;
+  uint8_t fde_count_encoding = *h++;
+  uint8_t fde_table_encoding = *h++;
+
+  if (eh_frame_ptr_encoding == DW_EH_PE_omit)
+    return (void *) -1l;
+
+  /* Dummy used by read_encoded_value.  */
+  Elf_Data_Scn dummy_cfi_hdr_data =
+    {
+      .d = { .d_buf = (void *) hdr, .d_size = hdr_size }
+    };
+  Dwarf_CFI dummy_cfi =
+    {
+      .e_ident = ehdr->e_ident,
+      .datarel = hdr_vaddr,
+      .frame_vaddr = hdr_vaddr,
+      .data = &dummy_cfi_hdr_data,
+    };
+
+  if (unlikely (read_encoded_value (&dummy_cfi, eh_frame_ptr_encoding, &h,
+				    eh_frame_vaddr)))
+    return (void *) -1l;
+
+  if (fde_count_encoding != DW_EH_PE_omit)
+    {
+      Dwarf_Word fde_count;
+      if (unlikely (read_encoded_value (&dummy_cfi, fde_count_encoding, &h,
+					&fde_count)))
+	return (void *) -1l;
+      if (fde_count != 0 && (size_t) fde_count == fde_count
+	  && fde_table_encoding != DW_EH_PE_omit
+	  && (fde_table_encoding &~ DW_EH_PE_signed) != DW_EH_PE_uleb128)
+	{
+	  *table_entries = fde_count;
+	  *table_encoding = fde_table_encoding;
+	  return h;
+	}
+    }
+
+  return NULL;
+}
+
+static Dwarf_CFI *
+getcfi_gnu_eh_frame (Elf *elf, const GElf_Ehdr *ehdr, const GElf_Phdr *phdr)
+{
+  Elf_Data *data = elf_getdata_rawchunk (elf, phdr->p_offset, phdr->p_filesz,
+					 ELF_T_BYTE);
+  if (data == NULL || data->d_buf == NULL)
+    {
+    invalid_hdr:
+      /* XXX might be read error or corrupt phdr */
+      __libdw_seterrno (DWARF_E_INVALID_CFI);
+      return NULL;
+    }
+
+  size_t vsize, dmax;
+  Dwarf_Addr eh_frame_ptr;
+  size_t search_table_entries = 0;
+  uint8_t search_table_encoding = 0;
+  const uint8_t *search_table = parse_eh_frame_hdr (data->d_buf, phdr->p_filesz,
+						    phdr->p_vaddr, ehdr,
+						    &eh_frame_ptr,
+						    &search_table_entries,
+						    &search_table_encoding);
+
+  /* Make sure there is enough room for the entries in the table,
+     each entry consists of 2 encoded values.  */
+  vsize = encoded_value_size (data, ehdr->e_ident, search_table_encoding,
+			      NULL);
+  dmax = phdr->p_filesz - (search_table - (const uint8_t *) data->d_buf);
+  if (unlikely (search_table == (void *) -1l
+		|| vsize == 0
+		|| search_table_entries > (dmax / vsize) / 2))
+    goto invalid_hdr;
+
+  Dwarf_Off eh_frame_offset = eh_frame_ptr - phdr->p_vaddr + phdr->p_offset;
+  Dwarf_Word eh_frame_size = 0;
+
+  /* XXX we have no way without section headers to know the size
+     of the .eh_frame data.  Calculate the largest it might possibly be.
+     This won't be wasteful if the file is already mmap'd, but if it isn't
+     it might be quite excessive.  */
+  size_t filesize;
+  if (elf_rawfile (elf, &filesize) != NULL)
+    eh_frame_size = filesize - eh_frame_offset;
+
+  data = elf_getdata_rawchunk (elf, eh_frame_offset, eh_frame_size, ELF_T_BYTE);
+  if (data == NULL)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_ELF); /* XXX might be read error */
+      return NULL;
+    }
+  Dwarf_CFI *cfi = allocate_cfi (elf, eh_frame_ptr);
+  if (cfi != NULL)
+    {
+      cfi->data = (Elf_Data_Scn *) data;
+
+      if (search_table != NULL)
+	{
+	  cfi->search_table = search_table;
+	  cfi->search_table_len = phdr->p_filesz;
+	  cfi->search_table_vaddr = phdr->p_vaddr;
+	  cfi->search_table_encoding = search_table_encoding;
+	  cfi->search_table_entries = search_table_entries;
+	}
+    }
+  return cfi;
+}
+
+/* Search the phdrs for PT_GNU_EH_FRAME.  */
+static Dwarf_CFI *
+getcfi_phdr (Elf *elf, const GElf_Ehdr *ehdr)
+{
+  size_t phnum;
+  if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
+    return NULL;
+
+  for (size_t i = 0; i < phnum; ++i)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
+      if (unlikely (phdr == NULL))
+	return NULL;
+      if (phdr->p_type == PT_GNU_EH_FRAME)
+	return getcfi_gnu_eh_frame (elf, ehdr, phdr);
+    }
+
+  __libdw_seterrno (DWARF_E_NO_DWARF);
+  return NULL;
+}
+
+static Dwarf_CFI *
+getcfi_scn_eh_frame (Elf *elf, const GElf_Ehdr *ehdr,
+		     Elf_Scn *scn, GElf_Shdr *shdr,
+		     Elf_Scn *hdr_scn, GElf_Addr hdr_vaddr)
+{
+  Elf_Data *data = elf_rawdata (scn, NULL);
+  if (data == NULL || data->d_buf == NULL)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_ELF);
+      return NULL;
+    }
+  Dwarf_CFI *cfi = allocate_cfi (elf, shdr->sh_addr);
+  if (cfi != NULL)
+    {
+      cfi->data = (Elf_Data_Scn *) data;
+      if (hdr_scn != NULL)
+	{
+	  Elf_Data *hdr_data = elf_rawdata (hdr_scn, NULL);
+	  if (hdr_data != NULL && hdr_data->d_buf != NULL)
+	    {
+	      size_t vsize, dmax;
+	      GElf_Addr eh_frame_vaddr;
+	      cfi->search_table_vaddr = hdr_vaddr;
+	      cfi->search_table
+		= parse_eh_frame_hdr (hdr_data->d_buf, hdr_data->d_size,
+				      hdr_vaddr, ehdr, &eh_frame_vaddr,
+				      &cfi->search_table_entries,
+				      &cfi->search_table_encoding);
+	      cfi->search_table_len = hdr_data->d_size;
+
+	      /* Make sure there is enough room for the entries in the table,
+		 each entry consists of 2 encoded values.  */
+	      vsize = encoded_value_size (hdr_data, ehdr->e_ident,
+					  cfi->search_table_encoding, NULL);
+	      dmax = hdr_data->d_size - (cfi->search_table
+					 - (const uint8_t *) hdr_data->d_buf);
+	      if (unlikely (cfi->search_table == (void *) -1l
+			    || vsize == 0
+			    || cfi->search_table_entries > (dmax / vsize) / 2))
+		{
+		  free (cfi);
+		  /* XXX might be read error or corrupt phdr */
+		  __libdw_seterrno (DWARF_E_INVALID_CFI);
+		  return NULL;
+		}
+
+	      /* Sanity check.  */
+	      if (unlikely (eh_frame_vaddr != shdr->sh_addr))
+		cfi->search_table = NULL;
+	    }
+	}
+    }
+  return cfi;
+}
+
+/* Search for the sections named ".eh_frame" and ".eh_frame_hdr".  */
+static Dwarf_CFI *
+getcfi_shdr (Elf *elf, const GElf_Ehdr *ehdr)
+{
+  size_t shstrndx;
+  if (elf_getshdrstrndx (elf, &shstrndx) != 0)
+    {
+      __libdw_seterrno (DWARF_E_GETEHDR_ERROR);
+      return NULL;
+    }
+
+  if (shstrndx != 0)
+    {
+      Elf_Scn *hdr_scn = NULL;
+      GElf_Addr hdr_vaddr = 0;
+      Elf_Scn *scn = NULL;
+      while ((scn = elf_nextscn (elf, scn)) != NULL)
+	{
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (shdr == NULL)
+	    continue;
+	  const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
+	  if (name == NULL)
+	    continue;
+	  if (!strcmp (name, ".eh_frame_hdr"))
+	    {
+	      hdr_scn = scn;
+	      hdr_vaddr = shdr->sh_addr;
+	    }
+	  else if (!strcmp (name, ".eh_frame"))
+	    {
+	      if (shdr->sh_type == SHT_PROGBITS)
+		return getcfi_scn_eh_frame (elf, ehdr, scn, shdr,
+					    hdr_scn, hdr_vaddr);
+	      else
+		return NULL;
+	    }
+	}
+    }
+
+  return (void *) -1l;
+}
+
+Dwarf_CFI *
+dwarf_getcfi_elf (Elf *elf)
+{
+  if (elf_kind (elf) != ELF_K_ELF)
+    {
+      __libdw_seterrno (DWARF_E_NOELF);
+      return NULL;
+    }
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (unlikely (ehdr == NULL))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_ELF);
+      return NULL;
+    }
+
+  Dwarf_CFI *result = getcfi_shdr (elf, ehdr);
+  if (result == (void *) -1l)
+    result = getcfi_phdr (elf, ehdr);
+
+  return result;
+}
+INTDEF (dwarf_getcfi_elf)
diff --git a/third_party/elfutils/libdw/dwarf_getelf.c b/third_party/elfutils/libdw/dwarf_getelf.c
new file mode 100644
index 0000000..2d6268e
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getelf.c
@@ -0,0 +1,47 @@
+/* Retrieve ELF descriptor used for DWARF access.
+   Copyright (C) 2002, 2004, 2007 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+
+#include "libdwP.h"
+
+
+Elf *
+dwarf_getelf (Dwarf *dwarf)
+{
+  if (dwarf == NULL)
+    /* Some error occurred before.  */
+    return NULL;
+
+  return dwarf->elf;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getfuncs.c b/third_party/elfutils/libdw/dwarf_getfuncs.c
new file mode 100644
index 0000000..b95f06f
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getfuncs.c
@@ -0,0 +1,118 @@
+/* Get function information.
+   Copyright (C) 2005, 2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+struct visitor_info
+{
+  /* The user callback of dwarf_getfuncs.  */
+  int (*callback) (Dwarf_Die *, void *);
+
+  /* The user arg value to dwarf_getfuncs.  */
+  void *arg;
+
+  /* Addr of the DIE offset where to (re)start the search.  Zero for all.  */
+  void *start_addr;
+
+  /* Last subprogram DIE addr seen.  */
+  void *last_addr;
+
+  /* The CU only contains C functions.  Allows pruning of most subtrees.  */
+  bool c_cu;
+};
+
+static int
+tree_visitor (unsigned int depth __attribute__ ((unused)),
+	      struct Dwarf_Die_Chain *chain, void *arg)
+{
+  struct visitor_info *const v = arg;
+  Dwarf_Die *die = &chain->die;
+  void *start_addr = v->start_addr;
+  void *die_addr = die->addr;
+
+  /* Pure C CUs can only contain defining subprogram DIEs as direct
+     children of the CU DIE or as nested function inside a normal C
+     code constructs.  */
+  int tag = INTUSE(dwarf_tag) (die);
+  if (v->c_cu
+      && tag != DW_TAG_subprogram
+      && tag != DW_TAG_lexical_block
+      && tag != DW_TAG_inlined_subroutine)
+    {
+      chain->prune = true;
+      return DWARF_CB_OK;
+    }
+
+  /* Skip all DIEs till we found the (re)start addr.  */
+  if (start_addr != NULL)
+    {
+      if (die_addr == start_addr)
+	v->start_addr = NULL;
+      return DWARF_CB_OK;
+    }
+
+  /* If this isn't a (defining) subprogram entity, skip DIE.  */
+  if (tag != DW_TAG_subprogram
+      || INTUSE(dwarf_hasattr) (die, DW_AT_declaration))
+    return DWARF_CB_OK;
+
+  v->last_addr = die_addr;
+  return (*v->callback) (die, v->arg);
+}
+
+ptrdiff_t
+dwarf_getfuncs (Dwarf_Die *cudie, int (*callback) (Dwarf_Die *, void *),
+		void *arg, ptrdiff_t offset)
+{
+  if (unlikely (cudie == NULL
+		|| INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit))
+    return -1;
+
+  int lang = INTUSE(dwarf_srclang) (cudie);
+  bool c_cu = (lang == DW_LANG_C89
+	       || lang == DW_LANG_C
+	       || lang == DW_LANG_C99
+	       || lang == DW_LANG_C11);
+
+  struct visitor_info v = { callback, arg, (void *) offset, NULL, c_cu };
+  struct Dwarf_Die_Chain chain = { .die = CUDIE (cudie->cu),
+				   .parent = NULL };
+  int res = __libdw_visit_scopes (0, &chain, NULL, &tree_visitor, NULL, &v);
+
+  if (res == DWARF_CB_ABORT)
+    return (ptrdiff_t) v.last_addr;
+  else
+    return res;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getlocation.c b/third_party/elfutils/libdw/dwarf_getlocation.c
new file mode 100644
index 0000000..86a9ae7
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getlocation.c
@@ -0,0 +1,890 @@
+/* Return location expression list.
+   Copyright (C) 2000-2010, 2013-2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <search.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include <libdwP.h>
+
+
+static bool
+attr_ok (Dwarf_Attribute *attr)
+{
+  if (attr == NULL)
+    return false;
+
+  /* If it is an exprloc, it is obviously OK.  */
+  if (dwarf_whatform (attr) == DW_FORM_exprloc)
+    return true;
+
+  /* Otherwise must be one of the attributes listed below.  Older
+     DWARF versions might have encoded the exprloc as block, and we
+     cannot easily distinquish attributes in the loclist class because
+     the same forms are used for different classes.  */
+  switch (attr->code)
+    {
+    case DW_AT_location:
+    case DW_AT_byte_size:
+    case DW_AT_bit_offset:
+    case DW_AT_bit_size:
+    case DW_AT_lower_bound:
+    case DW_AT_bit_stride:
+    case DW_AT_upper_bound:
+    case DW_AT_count:
+    case DW_AT_allocated:
+    case DW_AT_associated:
+    case DW_AT_data_location:
+    case DW_AT_byte_stride:
+    case DW_AT_rank:
+    case DW_AT_call_value:
+    case DW_AT_call_target:
+    case DW_AT_call_target_clobbered:
+    case DW_AT_call_data_location:
+    case DW_AT_call_data_value:
+    case DW_AT_data_member_location:
+    case DW_AT_vtable_elem_location:
+    case DW_AT_string_length:
+    case DW_AT_use_location:
+    case DW_AT_frame_base:
+    case DW_AT_return_addr:
+    case DW_AT_static_link:
+    case DW_AT_segment:
+    case DW_AT_GNU_call_site_value:
+    case DW_AT_GNU_call_site_data_value:
+    case DW_AT_GNU_call_site_target:
+    case DW_AT_GNU_call_site_target_clobbered:
+      break;
+
+    default:
+      __libdw_seterrno (DWARF_E_NO_LOCLIST);
+      return false;
+    }
+
+  return true;
+}
+
+
+struct loclist
+{
+  uint8_t atom;
+  Dwarf_Word number;
+  Dwarf_Word number2;
+  Dwarf_Word offset;
+  struct loclist *next;
+};
+
+
+static int
+loc_compare (const void *p1, const void *p2)
+{
+  const struct loc_s *l1 = (const struct loc_s *) p1;
+  const struct loc_s *l2 = (const struct loc_s *) p2;
+
+  if ((uintptr_t) l1->addr < (uintptr_t) l2->addr)
+    return -1;
+  if ((uintptr_t) l1->addr > (uintptr_t) l2->addr)
+    return 1;
+
+  return 0;
+}
+
+/* For each DW_OP_implicit_value, we store a special entry in the cache.
+   This points us directly to the block data for later fetching.  */
+static void
+store_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op)
+{
+  struct loc_block_s *block = libdw_alloc (dbg, struct loc_block_s,
+					   sizeof (struct loc_block_s), 1);
+  const unsigned char *data = (const unsigned char *) (uintptr_t) op->number2;
+  // Ignored, equal to op->number.  And data length already checked.
+  (void) __libdw_get_uleb128 (&data, data + len_leb128 (Dwarf_Word));
+  block->addr = op;
+  block->data = (unsigned char *) data;
+  block->length = op->number;
+  (void) tsearch (block, cache, loc_compare);
+}
+
+int
+dwarf_getlocation_implicit_value (Dwarf_Attribute *attr, const Dwarf_Op *op,
+				  Dwarf_Block *return_block)
+{
+  if (attr == NULL)
+    return -1;
+
+  struct loc_block_s fake = { .addr = (void *) op };
+  struct loc_block_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
+  if (unlikely (found == NULL))
+    {
+      __libdw_seterrno (DWARF_E_NO_BLOCK);
+      return -1;
+    }
+
+  return_block->length = (*found)->length;
+  return_block->data = (*found)->data;
+  return 0;
+}
+
+/* DW_AT_data_member_location can be a constant as well as a loclistptr.
+   Only data[48] indicate a loclistptr.  */
+static int
+check_constant_offset (Dwarf_Attribute *attr,
+		       Dwarf_Op **llbuf, size_t *listlen)
+{
+  if (attr->code != DW_AT_data_member_location)
+    return 1;
+
+  switch (attr->form)
+    {
+      /* Punt for any non-constant form.  */
+    default:
+      return 1;
+
+    case DW_FORM_data1:
+    case DW_FORM_data2:
+    case DW_FORM_data4:
+    case DW_FORM_data8:
+    case DW_FORM_sdata:
+    case DW_FORM_udata:
+      break;
+    }
+
+  /* Check whether we already cached this location.  */
+  struct loc_s fake = { .addr = attr->valp };
+  struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare);
+
+  if (found == NULL)
+    {
+      Dwarf_Word offset;
+      if (INTUSE(dwarf_formudata) (attr, &offset) != 0)
+	return -1;
+
+      Dwarf_Op *result = libdw_alloc (attr->cu->dbg,
+				      Dwarf_Op, sizeof (Dwarf_Op), 1);
+
+      result->atom = DW_OP_plus_uconst;
+      result->number = offset;
+      result->number2 = 0;
+      result->offset = 0;
+
+      /* Insert a record in the search tree so we can find it again later.  */
+      struct loc_s *newp = libdw_alloc (attr->cu->dbg,
+					struct loc_s, sizeof (struct loc_s),
+					1);
+      newp->addr = attr->valp;
+      newp->loc = result;
+      newp->nloc = 1;
+
+      found = tsearch (newp, &attr->cu->locs, loc_compare);
+    }
+
+  assert ((*found)->nloc == 1);
+
+  if (llbuf != NULL)
+    {
+      *llbuf = (*found)->loc;
+      *listlen = 1;
+    }
+
+  return 0;
+}
+
+int
+internal_function
+__libdw_intern_expression (Dwarf *dbg, bool other_byte_order,
+			   unsigned int address_size, unsigned int ref_size,
+			   void **cache, const Dwarf_Block *block,
+			   bool cfap, bool valuep,
+			   Dwarf_Op **llbuf, size_t *listlen, int sec_index)
+{
+  /* Empty location expressions don't have any ops to intern.  */
+  if (block->length == 0)
+    {
+      *listlen = 0;
+      return 0;
+    }
+
+  /* Check whether we already looked at this list.  */
+  struct loc_s fake = { .addr = block->data };
+  struct loc_s **found = tfind (&fake, cache, loc_compare);
+  if (found != NULL)
+    {
+      /* We already saw it.  */
+      *llbuf = (*found)->loc;
+      *listlen = (*found)->nloc;
+
+      if (valuep)
+	{
+	  assert (*listlen > 1);
+	  assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value);
+	}
+
+      return 0;
+    }
+
+  const unsigned char *data = block->data;
+  const unsigned char *const end_data = data + block->length;
+
+  const struct { bool other_byte_order; } bo = { other_byte_order };
+
+  struct loclist *loclist = NULL;
+  unsigned int n = 0;
+
+  /* Stack allocate at most this many locs.  */
+#define MAX_STACK_LOCS 256
+  struct loclist stack_locs[MAX_STACK_LOCS];
+#define NEW_LOC() ({ struct loclist *ll;			\
+		     ll = (likely (n < MAX_STACK_LOCS)		\
+			   ? &stack_locs[n]			\
+			   : malloc (sizeof (struct loclist)));	\
+		     if (unlikely (ll == NULL))			\
+		       goto nomem;				\
+		     n++;					\
+		     ll->next = loclist;			\
+		     loclist = ll;				\
+		     ll; })
+
+  if (cfap)
+    {
+      /* Synthesize the operation to push the CFA before the expression.  */
+      struct loclist *newloc = NEW_LOC ();
+      newloc->atom = DW_OP_call_frame_cfa;
+      newloc->number = 0;
+      newloc->number2 = 0;
+      newloc->offset = -1;
+    }
+
+  /* Decode the opcodes.  It is possible in some situations to have a
+     block of size zero.  */
+  while (data < end_data)
+    {
+      struct loclist *newloc;
+      newloc = NEW_LOC ();
+      newloc->number = 0;
+      newloc->number2 = 0;
+      newloc->offset = data - block->data;
+
+      switch ((newloc->atom = *data++))
+	{
+	case DW_OP_addr:
+	  /* Address, depends on address size of CU.  */
+	  if (dbg == NULL)
+	    {
+	      // XXX relocation?
+	      if (address_size == 4)
+		{
+		  if (unlikely (data + 4 > end_data))
+		    goto invalid;
+		  else
+		    newloc->number = read_4ubyte_unaligned_inc (&bo, data);
+		}
+	      else
+		{
+		  if (unlikely (data + 8 > end_data))
+		    goto invalid;
+		  else
+		    newloc->number = read_8ubyte_unaligned_inc (&bo, data);
+		}
+	    }
+	  else if (__libdw_read_address_inc (dbg, sec_index, &data,
+					     address_size, &newloc->number))
+	    goto invalid;
+	  break;
+
+	case DW_OP_call_ref:
+	case DW_OP_GNU_variable_value:
+	  /* DW_FORM_ref_addr, depends on offset size of CU.  */
+	  if (dbg == NULL || __libdw_read_offset_inc (dbg, sec_index, &data,
+						      ref_size,
+						      &newloc->number,
+						      IDX_debug_info, 0))
+	    goto invalid;
+	  break;
+
+	case DW_OP_deref:
+	case DW_OP_dup:
+	case DW_OP_drop:
+	case DW_OP_over:
+	case DW_OP_swap:
+	case DW_OP_rot:
+	case DW_OP_xderef:
+	case DW_OP_abs:
+	case DW_OP_and:
+	case DW_OP_div:
+	case DW_OP_minus:
+	case DW_OP_mod:
+	case DW_OP_mul:
+	case DW_OP_neg:
+	case DW_OP_not:
+	case DW_OP_or:
+	case DW_OP_plus:
+	case DW_OP_shl:
+	case DW_OP_shr:
+	case DW_OP_shra:
+	case DW_OP_xor:
+	case DW_OP_eq:
+	case DW_OP_ge:
+	case DW_OP_gt:
+	case DW_OP_le:
+	case DW_OP_lt:
+	case DW_OP_ne:
+	case DW_OP_lit0 ... DW_OP_lit31:
+	case DW_OP_reg0 ... DW_OP_reg31:
+	case DW_OP_nop:
+	case DW_OP_push_object_address:
+	case DW_OP_call_frame_cfa:
+	case DW_OP_form_tls_address:
+	case DW_OP_GNU_push_tls_address:
+	case DW_OP_stack_value:
+	  /* No operand.  */
+	  break;
+
+	case DW_OP_const1u:
+	case DW_OP_pick:
+	case DW_OP_deref_size:
+	case DW_OP_xderef_size:
+	  if (unlikely (data >= end_data))
+	    {
+	    invalid:
+	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	    returnmem:
+	      /* Free any dynamicly allocated loclists, if any.  */
+	      while (n > MAX_STACK_LOCS)
+		{
+		  struct loclist *loc = loclist;
+		  loclist = loc->next;
+		  free (loc);
+		  n--;
+		}
+	      return -1;
+	    }
+
+	  newloc->number = *data++;
+	  break;
+
+	case DW_OP_const1s:
+	  if (unlikely (data >= end_data))
+	    goto invalid;
+
+	  newloc->number = *((int8_t *) data);
+	  ++data;
+	  break;
+
+	case DW_OP_const2u:
+	  if (unlikely (data + 2 > end_data))
+	    goto invalid;
+
+	  newloc->number = read_2ubyte_unaligned_inc (&bo, data);
+	  break;
+
+	case DW_OP_const2s:
+	case DW_OP_skip:
+	case DW_OP_bra:
+	case DW_OP_call2:
+	  if (unlikely (data + 2 > end_data))
+	    goto invalid;
+
+	  newloc->number = read_2sbyte_unaligned_inc (&bo, data);
+	  break;
+
+	case DW_OP_const4u:
+	  if (unlikely (data + 4 > end_data))
+	    goto invalid;
+
+	  newloc->number = read_4ubyte_unaligned_inc (&bo, data);
+	  break;
+
+	case DW_OP_const4s:
+	case DW_OP_call4:
+	case DW_OP_GNU_parameter_ref:
+	  if (unlikely (data + 4 > end_data))
+	    goto invalid;
+
+	  newloc->number = read_4sbyte_unaligned_inc (&bo, data);
+	  break;
+
+	case DW_OP_const8u:
+	  if (unlikely (data + 8 > end_data))
+	    goto invalid;
+
+	  newloc->number = read_8ubyte_unaligned_inc (&bo, data);
+	  break;
+
+	case DW_OP_const8s:
+	  if (unlikely (data + 8 > end_data))
+	    goto invalid;
+
+	  newloc->number = read_8sbyte_unaligned_inc (&bo, data);
+	  break;
+
+	case DW_OP_constu:
+	case DW_OP_plus_uconst:
+	case DW_OP_regx:
+	case DW_OP_piece:
+	case DW_OP_GNU_convert:
+	case DW_OP_GNU_reinterpret:
+	  get_uleb128 (newloc->number, data, end_data);
+	  break;
+
+	case DW_OP_consts:
+	case DW_OP_breg0 ... DW_OP_breg31:
+	case DW_OP_fbreg:
+	  get_sleb128 (newloc->number, data, end_data);
+	  break;
+
+	case DW_OP_bregx:
+	  get_uleb128 (newloc->number, data, end_data);
+	  if (unlikely (data >= end_data))
+	    goto invalid;
+	  get_sleb128 (newloc->number2, data, end_data);
+	  break;
+
+	case DW_OP_bit_piece:
+	case DW_OP_GNU_regval_type:
+	  get_uleb128 (newloc->number, data, end_data);
+	  if (unlikely (data >= end_data))
+	    goto invalid;
+	  get_uleb128 (newloc->number2, data, end_data);
+	  break;
+
+	case DW_OP_implicit_value:
+	case DW_OP_GNU_entry_value:
+	  /* This cannot be used in a CFI expression.  */
+	  if (unlikely (dbg == NULL))
+	    goto invalid;
+
+	  /* start of block inc. len.  */
+	  newloc->number2 = (Dwarf_Word) (uintptr_t) data;
+	  get_uleb128 (newloc->number, data, end_data); /* Block length.  */
+	  if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number))
+	    goto invalid;
+	  data += newloc->number;		/* Skip the block.  */
+	  break;
+
+	case DW_OP_GNU_implicit_pointer:
+	  /* DW_FORM_ref_addr, depends on offset size of CU.  */
+	  if (dbg == NULL || __libdw_read_offset_inc (dbg, sec_index, &data,
+						      ref_size,
+						      &newloc->number,
+						      IDX_debug_info, 0))
+	    goto invalid;
+	  if (unlikely (data >= end_data))
+	    goto invalid;
+	  get_uleb128 (newloc->number2, data, end_data); /* Byte offset.  */
+	  break;
+
+	case DW_OP_GNU_deref_type:
+	  if (unlikely (data + 1 >= end_data))
+	    goto invalid;
+	  newloc->number = *data++;
+	  get_uleb128 (newloc->number2, data, end_data);
+	  break;
+
+	case DW_OP_GNU_const_type:
+	  {
+	    size_t size;
+	    get_uleb128 (newloc->number, data, end_data);
+	    if (unlikely (data >= end_data))
+	      goto invalid;
+
+	    /* start of block inc. len.  */
+	    newloc->number2 = (Dwarf_Word) (uintptr_t) data;
+	    size = *data++;
+	    if (unlikely ((Dwarf_Word) (end_data - data) < size))
+	      goto invalid;
+	    data += size;		/* Skip the block.  */
+	  }
+	  break;
+
+	default:
+	  goto invalid;
+	}
+    }
+
+  if (unlikely (n == 0))
+    {
+      /* This is not allowed.
+	 It would mean an empty location expression, which we handled
+	 already as a special case above.  */
+      goto invalid;
+    }
+
+  if (valuep)
+    {
+      struct loclist *newloc = NEW_LOC ();
+      newloc->atom = DW_OP_stack_value;
+      newloc->number = 0;
+      newloc->number2 = 0;
+      newloc->offset = data - block->data;
+    }
+
+  /* Allocate the array.  */
+  Dwarf_Op *result;
+  if (dbg != NULL)
+    result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n);
+  else
+    {
+      result = malloc (sizeof *result * n);
+      if (result == NULL)
+	{
+	nomem:
+	  __libdw_seterrno (DWARF_E_NOMEM);
+	  goto returnmem;
+	}
+    }
+
+  /* Store the result.  */
+  *llbuf = result;
+  *listlen = n;
+
+  do
+    {
+      /* We populate the array from the back since the list is backwards.  */
+      --n;
+      result[n].atom = loclist->atom;
+      result[n].number = loclist->number;
+      result[n].number2 = loclist->number2;
+      result[n].offset = loclist->offset;
+
+      if (result[n].atom == DW_OP_implicit_value)
+	store_implicit_value (dbg, cache, &result[n]);
+
+      struct loclist *loc = loclist;
+      loclist = loclist->next;
+      if (unlikely (n + 1 > MAX_STACK_LOCS))
+	free (loc);
+    }
+  while (n > 0);
+
+  /* Insert a record in the search tree so that we can find it again later.  */
+  struct loc_s *newp;
+  if (dbg != NULL)
+    newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1);
+  else
+    {
+      newp = malloc (sizeof *newp);
+      if (newp == NULL)
+	{
+	  free (result);
+	  goto nomem;
+	}
+    }
+
+  newp->addr = block->data;
+  newp->loc = result;
+  newp->nloc = *listlen;
+  (void) tsearch (newp, cache, loc_compare);
+
+  /* We did it.  */
+  return 0;
+}
+
+static int
+getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block,
+	     Dwarf_Op **llbuf, size_t *listlen, int sec_index)
+{
+  /* Empty location expressions don't have any ops to intern.
+     Note that synthetic empty_cu doesn't have an associated DWARF dbg.  */
+  if (block->length == 0)
+    {
+      *listlen = 0;
+      return 0;
+    }
+
+  return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order,
+				    cu->address_size, (cu->version == 2
+						       ? cu->address_size
+						       : cu->offset_size),
+				    &cu->locs, block,
+				    false, false,
+				    llbuf, listlen, sec_index);
+}
+
+int
+dwarf_getlocation (Dwarf_Attribute *attr, Dwarf_Op **llbuf, size_t *listlen)
+{
+  if (! attr_ok (attr))
+    return -1;
+
+  int result = check_constant_offset (attr, llbuf, listlen);
+  if (result != 1)
+    return result;
+
+  /* If it has a block form, it's a single location expression.  */
+  Dwarf_Block block;
+  if (INTUSE(dwarf_formblock) (attr, &block) != 0)
+    return -1;
+
+  return getlocation (attr->cu, &block, llbuf, listlen, cu_sec_idx (attr->cu));
+}
+
+static int
+attr_base_address (Dwarf_Attribute *attr, Dwarf_Addr *basep)
+{
+  /* Fetch the CU's base address.  */
+  Dwarf_Die cudie = CUDIE (attr->cu);
+
+  /* Find the base address of the compilation unit.  It will
+     normally be specified by DW_AT_low_pc.  In DWARF-3 draft 4,
+     the base address could be overridden by DW_AT_entry_pc.  It's
+     been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
+     for compilation units with discontinuous ranges.  */
+  Dwarf_Attribute attr_mem;
+  if (unlikely (INTUSE(dwarf_lowpc) (&cudie, basep) != 0)
+      && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
+						     DW_AT_entry_pc,
+						     &attr_mem),
+				 basep) != 0)
+    {
+      if (INTUSE(dwarf_errno) () != 0)
+	return -1;
+
+      /* The compiler provided no base address when it should
+	 have.  Buggy GCC does this when it used absolute
+	 addresses in the location list and no DW_AT_ranges.  */
+      *basep = 0;
+    }
+  return 0;
+}
+
+static int
+initial_offset_base (Dwarf_Attribute *attr, ptrdiff_t *offset,
+		     Dwarf_Addr *basep)
+{
+  if (attr_base_address (attr, basep) != 0)
+    return -1;
+
+  Dwarf_Word start_offset;
+  if (__libdw_formptr (attr, IDX_debug_loc,
+		       DWARF_E_NO_LOCLIST,
+		       NULL, &start_offset) == NULL)
+    return -1;
+
+  *offset = start_offset;
+  return 0;
+}
+
+static ptrdiff_t
+getlocations_addr (Dwarf_Attribute *attr, ptrdiff_t offset,
+		   Dwarf_Addr *basep, Dwarf_Addr *startp, Dwarf_Addr *endp,
+		   Dwarf_Addr address, const Elf_Data *locs, Dwarf_Op **expr,
+		   size_t *exprlen)
+{
+  unsigned char *readp = locs->d_buf + offset;
+  unsigned char *readendp = locs->d_buf + locs->d_size;
+
+ next:
+  if (readendp - readp < attr->cu->address_size * 2)
+    {
+    invalid:
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return -1;
+    }
+
+  Dwarf_Addr begin;
+  Dwarf_Addr end;
+
+  switch (__libdw_read_begin_end_pair_inc (attr->cu->dbg, IDX_debug_loc,
+					   &readp, attr->cu->address_size,
+					   &begin, &end, basep))
+    {
+    case 0: /* got location range. */
+      break;
+    case 1: /* base address setup. */
+      goto next;
+    case 2: /* end of loclist */
+      return 0;
+    default: /* error */
+      return -1;
+    }
+
+  if (readendp - readp < 2)
+    goto invalid;
+
+  /* We have a location expression.  */
+  Dwarf_Block block;
+  block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp);
+  block.data = readp;
+  if (readendp - readp < (ptrdiff_t) block.length)
+    goto invalid;
+  readp += block.length;
+
+  *startp = *basep + begin;
+  *endp = *basep + end;
+
+  /* If address is minus one we want them all, otherwise only matching.  */
+  if (address != (Dwarf_Word) -1 && (address < *startp || address >= *endp))
+    goto next;
+
+  if (getlocation (attr->cu, &block, expr, exprlen, IDX_debug_loc) != 0)
+    return -1;
+
+  return readp - (unsigned char *) locs->d_buf;
+}
+
+int
+dwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address,
+			Dwarf_Op **llbufs, size_t *listlens, size_t maxlocs)
+{
+  if (! attr_ok (attr))
+    return -1;
+
+  if (llbufs == NULL)
+    maxlocs = SIZE_MAX;
+
+  /* If it has a block form, it's a single location expression.  */
+  Dwarf_Block block;
+  if (INTUSE(dwarf_formblock) (attr, &block) == 0)
+    {
+      if (maxlocs == 0)
+	return 0;
+      if (llbufs != NULL &&
+	  getlocation (attr->cu, &block, &llbufs[0], &listlens[0],
+		       cu_sec_idx (attr->cu)) != 0)
+	return -1;
+      return listlens[0] == 0 ? 0 : 1;
+    }
+
+  int error = INTUSE(dwarf_errno) ();
+  if (unlikely (error != DWARF_E_NO_BLOCK))
+    {
+      __libdw_seterrno (error);
+      return -1;
+    }
+
+  int result = check_constant_offset (attr, &llbufs[0], &listlens[0]);
+  if (result != 1)
+    return result ?: 1;
+
+  Dwarf_Addr base, start, end;
+  Dwarf_Op *expr;
+  size_t expr_len;
+  ptrdiff_t off = 0;
+  size_t got = 0;
+
+  /* This is a true loclistptr, fetch the initial base address and offset.  */
+  if (initial_offset_base (attr, &off, &base) != 0)
+    return -1;
+
+  const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
+  if (d == NULL)
+    {
+      __libdw_seterrno (DWARF_E_NO_LOCLIST);
+      return -1;
+    }
+
+  while (got < maxlocs
+         && (off = getlocations_addr (attr, off, &base, &start, &end,
+				   address, d, &expr, &expr_len)) > 0)
+    {
+      /* This one matches the address.  */
+      if (llbufs != NULL)
+	{
+	  llbufs[got] = expr;
+	  listlens[got] = expr_len;
+	}
+      ++got;
+    }
+
+  /* We might stop early, so off can be zero or positive on success.  */
+  if (off < 0)
+    return -1;
+
+  return got;
+}
+
+ptrdiff_t
+dwarf_getlocations (Dwarf_Attribute *attr, ptrdiff_t offset, Dwarf_Addr *basep,
+		    Dwarf_Addr *startp, Dwarf_Addr *endp, Dwarf_Op **expr,
+		    size_t *exprlen)
+{
+  if (! attr_ok (attr))
+    return -1;
+
+  /* 1 is an invalid offset, meaning no more locations. */
+  if (offset == 1)
+    return 0;
+
+  if (offset == 0)
+    {
+      /* If it has a block form, it's a single location expression.  */
+      Dwarf_Block block;
+      if (INTUSE(dwarf_formblock) (attr, &block) == 0)
+	{
+	  if (getlocation (attr->cu, &block, expr, exprlen,
+			   cu_sec_idx (attr->cu)) != 0)
+	    return -1;
+
+	  /* This is the one and only location covering everything. */
+	  *startp = 0;
+	  *endp = -1;
+	  return 1;
+	}
+
+      int error = INTUSE(dwarf_errno) ();
+      if (unlikely (error != DWARF_E_NO_BLOCK))
+	{
+	  __libdw_seterrno (error);
+	  return -1;
+	}
+
+      int result = check_constant_offset (attr, expr, exprlen);
+      if (result != 1)
+	{
+	  if (result == 0)
+	    {
+	      /* This is the one and only location covering everything. */
+	      *startp = 0;
+	      *endp = -1;
+	      return 1;
+	    }
+	  return result;
+	}
+
+      /* We must be looking at a true loclistptr, fetch the initial
+	 base address and offset.  */
+      if (initial_offset_base (attr, &offset, basep) != 0)
+	return -1;
+    }
+
+  const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc];
+  if (d == NULL)
+    {
+      __libdw_seterrno (DWARF_E_NO_LOCLIST);
+      return -1;
+    }
+
+  return getlocations_addr (attr, offset, basep, startp, endp,
+			    (Dwarf_Word) -1, d, expr, exprlen);
+}
diff --git a/third_party/elfutils/libdw/dwarf_getlocation_attr.c b/third_party/elfutils/libdw/dwarf_getlocation_attr.c
new file mode 100644
index 0000000..e4dd708
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getlocation_attr.c
@@ -0,0 +1,120 @@
+/* Return DWARF attribute associated with a location expression op.
+   Copyright (C) 2013, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <libdwP.h>
+
+static Dwarf_CU *
+attr_form_cu (Dwarf_Attribute *attr)
+{
+  /* If the attribute has block/expr form the data comes from the
+     .debug_info from the same cu as the attr.  Otherwise it comes from
+     the .debug_loc data section.  */
+  switch (attr->form)
+    {
+    case DW_FORM_block1:
+    case DW_FORM_block2:
+    case DW_FORM_block4:
+    case DW_FORM_block:
+    case DW_FORM_exprloc:
+      return attr->cu;
+    default:
+      return attr->cu->dbg->fake_loc_cu;
+    }
+}
+
+int
+dwarf_getlocation_attr (Dwarf_Attribute *attr, const Dwarf_Op *op, Dwarf_Attribute *result)
+{
+  if (attr == NULL)
+    return -1;
+
+  switch (op->atom)
+    {
+      case DW_OP_implicit_value:
+	result->code = DW_AT_const_value;
+	result->form = DW_FORM_block;
+	result->valp = (unsigned char *) (uintptr_t) op->number2;
+	result->cu = attr_form_cu (attr);
+	break;
+
+      case DW_OP_GNU_entry_value:
+	result->code = DW_AT_location;
+	result->form = DW_FORM_exprloc;
+	result->valp = (unsigned char *) (uintptr_t) op->number2;
+	result->cu = attr_form_cu (attr);
+	break;
+
+      case DW_OP_GNU_const_type:
+	result->code = DW_AT_const_value;
+	result->form = DW_FORM_block1;
+	result->valp = (unsigned char *) (uintptr_t) op->number2;
+	result->cu = attr_form_cu (attr);
+	break;
+
+      case DW_OP_call2:
+      case DW_OP_call4:
+      case DW_OP_call_ref:
+	{
+	  Dwarf_Die die;
+	  if (INTUSE(dwarf_getlocation_die) (attr, op, &die) != 0)
+	    return -1;
+	  if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL)
+	    {
+	      __libdw_empty_loc_attr (result);
+	      return 0;
+	    }
+	}
+	break;
+
+      case DW_OP_GNU_implicit_pointer:
+      case DW_OP_GNU_variable_value:
+	{
+	  Dwarf_Die die;
+	  if (INTUSE(dwarf_getlocation_die) (attr, op, &die) != 0)
+	    return -1;
+	  if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL
+	      && INTUSE(dwarf_attr) (&die, DW_AT_const_value, result) == NULL)
+	    {
+	      __libdw_empty_loc_attr (result);
+	      return 0;
+	    }
+	}
+	break;
+
+      default:
+	__libdw_seterrno (DWARF_E_INVALID_ACCESS);
+	return -1;
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getlocation_die.c b/third_party/elfutils/libdw/dwarf_getlocation_die.c
new file mode 100644
index 0000000..21b4365
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getlocation_die.c
@@ -0,0 +1,77 @@
+/* Return DIE associated with a location expression op.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <libdwP.h>
+
+int
+dwarf_getlocation_die (Dwarf_Attribute *attr, const Dwarf_Op *op,
+		       Dwarf_Die *result)
+{
+  if (attr == NULL)
+    return -1;
+
+  Dwarf_Off dieoff;
+  switch (op->atom)
+    {
+    case DW_OP_GNU_implicit_pointer:
+    case DW_OP_call_ref:
+    case DW_OP_GNU_variable_value:
+      dieoff = op->number;
+      break;
+
+    case DW_OP_GNU_parameter_ref:
+    case DW_OP_GNU_convert:
+    case DW_OP_GNU_reinterpret:
+    case DW_OP_GNU_const_type:
+    case DW_OP_call2:
+    case DW_OP_call4:
+      dieoff = attr->cu->start + op->number;
+      break;
+
+    case DW_OP_GNU_regval_type:
+    case DW_OP_GNU_deref_type:
+      dieoff = attr->cu->start + op->number2;
+      break;
+
+    default:
+      __libdw_seterrno (DWARF_E_INVALID_ACCESS);
+      return -1;
+    }
+
+  if (__libdw_offdie (attr->cu->dbg, dieoff, result,
+                     attr->cu->type_offset != 0) == NULL)
+    return -1;
+
+  return 0;
+}
+INTDEF(dwarf_getlocation_die);
diff --git a/third_party/elfutils/libdw/dwarf_getlocation_implicit_pointer.c b/third_party/elfutils/libdw/dwarf_getlocation_implicit_pointer.c
new file mode 100644
index 0000000..9505382
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getlocation_implicit_pointer.c
@@ -0,0 +1,77 @@
+/* Return associated attribute for DW_OP_GNU_implicit_pointer.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+static unsigned char empty_exprloc = 0;
+static Dwarf_CU empty_cu = { .startp = &empty_exprloc,
+			     .endp = &empty_exprloc + 1 };
+
+void
+internal_function
+__libdw_empty_loc_attr (Dwarf_Attribute *attr)
+{
+  attr->code = DW_AT_location;
+  attr->form = DW_FORM_exprloc;
+  attr->valp = &empty_exprloc;
+  attr->cu = &empty_cu;
+}
+
+int
+dwarf_getlocation_implicit_pointer (Dwarf_Attribute *attr, const Dwarf_Op *op,
+				    Dwarf_Attribute *result)
+{
+  if (attr == NULL)
+    return -1;
+
+  if (unlikely (op->atom != DW_OP_GNU_implicit_pointer))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_ACCESS);
+      return -1;
+    }
+
+  Dwarf_Die die;
+  if (__libdw_offdie (attr->cu->dbg, op->number, &die,
+		      attr->cu->type_offset != 0) == NULL)
+    return -1;
+
+  if (INTUSE(dwarf_attr) (&die, DW_AT_location, result) == NULL
+      && INTUSE(dwarf_attr) (&die, DW_AT_const_value, result) == NULL)
+    {
+      __libdw_empty_loc_attr (result);
+      return 0;
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getmacros.c b/third_party/elfutils/libdw/dwarf_getmacros.c
new file mode 100644
index 0000000..c456051
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getmacros.c
@@ -0,0 +1,573 @@
+/* Get macro information.
+   Copyright (C) 2002-2009, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include <search.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libdwP.h>
+
+static int
+get_offset_from (Dwarf_Die *die, int name, Dwarf_Word *retp)
+{
+  /* Get the appropriate attribute.  */
+  Dwarf_Attribute attr;
+  if (INTUSE(dwarf_attr) (die, name, &attr) == NULL)
+    return -1;
+
+  /* Offset into the corresponding section.  */
+  return INTUSE(dwarf_formudata) (&attr, retp);
+}
+
+static int
+macro_op_compare (const void *p1, const void *p2)
+{
+  const Dwarf_Macro_Op_Table *t1 = (const Dwarf_Macro_Op_Table *) p1;
+  const Dwarf_Macro_Op_Table *t2 = (const Dwarf_Macro_Op_Table *) p2;
+
+  if (t1->offset < t2->offset)
+    return -1;
+  if (t1->offset > t2->offset)
+    return 1;
+
+  if (t1->sec_index < t2->sec_index)
+    return -1;
+  if (t1->sec_index > t2->sec_index)
+    return 1;
+
+  return 0;
+}
+
+static void
+build_table (Dwarf_Macro_Op_Table *table,
+	     Dwarf_Macro_Op_Proto op_protos[static 255])
+{
+  unsigned ct = 0;
+  for (unsigned i = 1; i < 256; ++i)
+    if (op_protos[i - 1].forms != NULL)
+      table->table[table->opcodes[i - 1] = ct++] = op_protos[i - 1];
+    else
+      table->opcodes[i - 1] = 0xff;
+}
+
+#define MACRO_PROTO(NAME, ...)					\
+  Dwarf_Macro_Op_Proto NAME = ({				\
+      static const uint8_t proto[] = {__VA_ARGS__};		\
+      (Dwarf_Macro_Op_Proto) {sizeof proto, proto};		\
+    })
+
+enum { macinfo_data_size = offsetof (Dwarf_Macro_Op_Table, table[5]) };
+static unsigned char macinfo_data[macinfo_data_size]
+	__attribute__ ((aligned (__alignof (Dwarf_Macro_Op_Table))));
+
+static __attribute__ ((constructor)) void
+init_macinfo_table (void)
+{
+  MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string);
+  MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata);
+  MACRO_PROTO (p_none);
+
+  Dwarf_Macro_Op_Proto op_protos[255] =
+    {
+      [DW_MACINFO_define - 1] = p_udata_str,
+      [DW_MACINFO_undef - 1] = p_udata_str,
+      [DW_MACINFO_vendor_ext - 1] = p_udata_str,
+      [DW_MACINFO_start_file - 1] = p_udata_udata,
+      [DW_MACINFO_end_file - 1] = p_none,
+      /* If you are adding more elements to this array, increase
+	 MACINFO_DATA_SIZE above.  */
+    };
+
+  Dwarf_Macro_Op_Table *macinfo_table = (void *) macinfo_data;
+  memset (macinfo_table, 0, sizeof macinfo_data);
+  build_table (macinfo_table, op_protos);
+  macinfo_table->sec_index = IDX_debug_macinfo;
+}
+
+static Dwarf_Macro_Op_Table *
+get_macinfo_table (Dwarf *dbg, Dwarf_Word macoff, Dwarf_Die *cudie)
+{
+  assert (cudie != NULL);
+
+  Dwarf_Attribute attr_mem, *attr
+    = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem);
+  Dwarf_Off line_offset = (Dwarf_Off) -1;
+  if (attr != NULL)
+    if (unlikely (INTUSE(dwarf_formudata) (attr, &line_offset) != 0))
+      return NULL;
+
+  Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table,
+					     macinfo_data_size, 1);
+  memcpy (table, macinfo_data, macinfo_data_size);
+
+  table->offset = macoff;
+  table->sec_index = IDX_debug_macinfo;
+  table->line_offset = line_offset;
+  table->is_64bit = cudie->cu->address_size == 8;
+  table->comp_dir = __libdw_getcompdir (cudie);
+
+  return table;
+}
+
+static Dwarf_Macro_Op_Table *
+get_table_for_offset (Dwarf *dbg, Dwarf_Word macoff,
+		      const unsigned char *readp,
+		      const unsigned char *const endp,
+		      Dwarf_Die *cudie)
+{
+  const unsigned char *startp = readp;
+
+  /* Request at least 3 bytes for header.  */
+  if (readp + 3 > endp)
+    {
+    invalid_dwarf:
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
+  if (version != 4 && version != 5)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_VERSION);
+      return NULL;
+    }
+
+  uint8_t flags = *readp++;
+  bool is_64bit = (flags & 0x1) != 0;
+
+  Dwarf_Off line_offset = (Dwarf_Off) -1;
+  if ((flags & 0x2) != 0)
+    {
+      line_offset = read_addr_unaligned_inc (is_64bit ? 8 : 4, dbg, readp);
+      if (readp > endp)
+	goto invalid_dwarf;
+    }
+  else if (cudie != NULL)
+    {
+      Dwarf_Attribute attr_mem, *attr
+	= INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &attr_mem);
+      if (attr != NULL)
+	if (unlikely (INTUSE(dwarf_formudata) (attr, &line_offset) != 0))
+	  return NULL;
+    }
+
+  /* """The macinfo entry types defined in this standard may, but
+     might not, be described in the table""".
+
+     I.e. these may be present.  It's tempting to simply skip them,
+     but it's probably more correct to tolerate that a producer tweaks
+     the way certain opcodes are encoded, for whatever reasons.  */
+
+  MACRO_PROTO (p_udata_str, DW_FORM_udata, DW_FORM_string);
+  MACRO_PROTO (p_udata_strp, DW_FORM_udata, DW_FORM_strp);
+  MACRO_PROTO (p_udata_udata, DW_FORM_udata, DW_FORM_udata);
+  MACRO_PROTO (p_secoffset, DW_FORM_sec_offset);
+  MACRO_PROTO (p_none);
+
+  Dwarf_Macro_Op_Proto op_protos[255] =
+    {
+      [DW_MACRO_define - 1] = p_udata_str,
+      [DW_MACRO_undef - 1] = p_udata_str,
+      [DW_MACRO_define_strp - 1] = p_udata_strp,
+      [DW_MACRO_undef_strp - 1] = p_udata_strp,
+      [DW_MACRO_start_file - 1] = p_udata_udata,
+      [DW_MACRO_end_file - 1] = p_none,
+      [DW_MACRO_import - 1] = p_secoffset,
+      /* When adding support for DWARF5 supplementary object files and
+	 indirect string tables also add support for DW_MACRO_define_sup,
+	 DW_MACRO_undef_sup, DW_MACRO_import_sup, DW_MACRO_define_strx
+	 and DW_MACRO_undef_strx.  */
+    };
+
+  if ((flags & 0x4) != 0)
+    {
+      unsigned count = *readp++;
+      for (unsigned i = 0; i < count; ++i)
+	{
+	  unsigned opcode = *readp++;
+
+	  Dwarf_Macro_Op_Proto e;
+	  if (readp >= endp)
+	    goto invalid;
+	  get_uleb128 (e.nforms, readp, endp);
+	  e.forms = readp;
+	  op_protos[opcode - 1] = e;
+
+	  readp += e.nforms;
+	  if (readp > endp)
+	    {
+	    invalid:
+	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	      return NULL;
+	    }
+	}
+    }
+
+  size_t ct = 0;
+  for (unsigned i = 1; i < 256; ++i)
+    if (op_protos[i - 1].forms != NULL)
+      ++ct;
+
+  /* We support at most 0xfe opcodes defined in the table, as 0xff is
+     a value that means that given opcode is not stored at all.  But
+     that should be fine, as opcode 0 is not allocated.  */
+  assert (ct < 0xff);
+
+  size_t macop_table_size = offsetof (Dwarf_Macro_Op_Table, table[ct]);
+
+  Dwarf_Macro_Op_Table *table = libdw_alloc (dbg, Dwarf_Macro_Op_Table,
+					     macop_table_size, 1);
+
+  *table = (Dwarf_Macro_Op_Table) {
+    .offset = macoff,
+    .sec_index = IDX_debug_macro,
+    .line_offset = line_offset,
+    .header_len = readp - startp,
+    .version = version,
+    .is_64bit = is_64bit,
+
+    /* NULL if CUDIE is NULL or DW_AT_comp_dir is absent.  */
+    .comp_dir = __libdw_getcompdir (cudie),
+  };
+  build_table (table, op_protos);
+
+  return table;
+}
+
+static Dwarf_Macro_Op_Table *
+cache_op_table (Dwarf *dbg, int sec_index, Dwarf_Off macoff,
+		const unsigned char *startp,
+		const unsigned char *const endp,
+		Dwarf_Die *cudie)
+{
+  Dwarf_Macro_Op_Table fake = { .offset = macoff, .sec_index = sec_index };
+  Dwarf_Macro_Op_Table **found = tfind (&fake, &dbg->macro_ops,
+					macro_op_compare);
+  if (found != NULL)
+    return *found;
+
+  Dwarf_Macro_Op_Table *table = sec_index == IDX_debug_macro
+    ? get_table_for_offset (dbg, macoff, startp, endp, cudie)
+    : get_macinfo_table (dbg, macoff, cudie);
+
+  if (table == NULL)
+    return NULL;
+
+  Dwarf_Macro_Op_Table **ret = tsearch (table, &dbg->macro_ops,
+					macro_op_compare);
+  if (unlikely (ret == NULL))
+    {
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return NULL;
+    }
+
+  return *ret;
+}
+
+static ptrdiff_t
+read_macros (Dwarf *dbg, int sec_index,
+	     Dwarf_Off macoff, int (*callback) (Dwarf_Macro *, void *),
+	     void *arg, ptrdiff_t offset, bool accept_0xff,
+	     Dwarf_Die *cudie)
+{
+  Elf_Data *d = dbg->sectiondata[sec_index];
+  if (unlikely (d == NULL || d->d_buf == NULL))
+    {
+      __libdw_seterrno (DWARF_E_NO_ENTRY);
+      return -1;
+    }
+
+  if (unlikely (macoff >= d->d_size))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return -1;
+    }
+
+  const unsigned char *const startp = d->d_buf + macoff;
+  const unsigned char *const endp = d->d_buf + d->d_size;
+
+  Dwarf_Macro_Op_Table *table = cache_op_table (dbg, sec_index, macoff,
+						startp, endp, cudie);
+  if (table == NULL)
+    return -1;
+
+  if (offset == 0)
+    offset = table->header_len;
+
+  assert (offset >= 0);
+  assert (offset < endp - startp);
+  const unsigned char *readp = startp + offset;
+
+  while (readp < endp)
+    {
+      unsigned int opcode = *readp++;
+      if (opcode == 0)
+	/* Nothing more to do.  */
+	return 0;
+
+      if (unlikely (opcode == 0xff && ! accept_0xff))
+	{
+	  /* See comment below at dwarf_getmacros for explanation of
+	     why we are doing this.  */
+	  __libdw_seterrno (DWARF_E_INVALID_OPCODE);
+	  return -1;
+	}
+
+      unsigned int idx = table->opcodes[opcode - 1];
+      if (idx == 0xff)
+	{
+	  __libdw_seterrno (DWARF_E_INVALID_OPCODE);
+	  return -1;
+	}
+
+      Dwarf_Macro_Op_Proto *proto = &table->table[idx];
+
+      /* A fake CU with bare minimum data to fool dwarf_formX into
+	 doing the right thing with the attributes that we put out.
+	 We pretend it is the same version as the actual table.
+	 Version 4 for the old GNU extension, version 5 for DWARF5.  */
+      Dwarf_CU fake_cu = {
+	.dbg = dbg,
+	.sec_idx = sec_index,
+	.version = table->version,
+	.offset_size = table->is_64bit ? 8 : 4,
+	.startp = (void *) startp + offset,
+	.endp = (void *) endp,
+      };
+
+      Dwarf_Attribute *attributes;
+      Dwarf_Attribute *attributesp = NULL;
+      Dwarf_Attribute nattributes[8];
+      if (unlikely (proto->nforms > 8))
+	{
+	  attributesp = malloc (sizeof (Dwarf_Attribute) * proto->nforms);
+	  if (attributesp == NULL)
+	    {
+	      __libdw_seterrno (DWARF_E_NOMEM);
+	      return -1;
+	    }
+	  attributes = attributesp;
+	}
+      else
+	attributes = &nattributes[0];
+
+      for (Dwarf_Word i = 0; i < proto->nforms; ++i)
+	{
+	  /* We pretend this is a DW_AT_GNU_macros attribute so that
+	     DW_FORM_sec_offset forms get correctly interpreted as
+	     offset into .debug_macro.  */
+	  attributes[i].code = DW_AT_GNU_macros;
+	  attributes[i].form = proto->forms[i];
+	  attributes[i].valp = (void *) readp;
+	  attributes[i].cu = &fake_cu;
+
+	  size_t len = __libdw_form_val_len (&fake_cu, proto->forms[i], readp);
+	  if (unlikely (len == (size_t) -1))
+	    {
+	      free (attributesp);
+	      return -1;
+	    }
+
+	  readp += len;
+	}
+
+      Dwarf_Macro macro = {
+	.table = table,
+	.opcode = opcode,
+	.attributes = attributes,
+      };
+
+      int res = callback (&macro, arg);
+      if (unlikely (attributesp != NULL))
+	free (attributesp);
+
+      if (res != DWARF_CB_OK)
+	return readp - startp;
+    }
+
+  return 0;
+}
+
+/* Token layout:
+
+   - The highest bit is used for distinguishing between callers that
+     know that opcode 0xff may have one of two incompatible meanings.
+     The mask that we use for selecting this bit is
+     DWARF_GETMACROS_START.
+
+   - The rest of the token (31 or 63 bits) encodes address inside the
+     macro unit.
+
+   Besides, token value of 0 signals end of iteration and -1 is
+   reserved for signaling errors.  That means it's impossible to
+   represent maximum offset of a .debug_macro unit to new-style
+   callers (which in practice decreases the permissible macro unit
+   size by another 1 byte).  */
+
+static ptrdiff_t
+token_from_offset (ptrdiff_t offset, bool accept_0xff)
+{
+  if (offset == -1 || offset == 0)
+    return offset;
+
+  /* Make sure the offset didn't overflow into the flag bit.  */
+  if ((offset & DWARF_GETMACROS_START) != 0)
+    {
+      __libdw_seterrno (DWARF_E_TOO_BIG);
+      return -1;
+    }
+
+  if (accept_0xff)
+    offset |= DWARF_GETMACROS_START;
+
+  return offset;
+}
+
+static ptrdiff_t
+offset_from_token (ptrdiff_t token, bool *accept_0xffp)
+{
+  *accept_0xffp = (token & DWARF_GETMACROS_START) != 0;
+  token &= ~DWARF_GETMACROS_START;
+
+  return token;
+}
+
+static ptrdiff_t
+gnu_macros_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
+			  int (*callback) (Dwarf_Macro *, void *),
+			  void *arg, ptrdiff_t offset, bool accept_0xff,
+			  Dwarf_Die *cudie)
+{
+  assert (offset >= 0);
+
+  if (macoff >= dbg->sectiondata[IDX_debug_macro]->d_size)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+      return -1;
+    }
+
+  return read_macros (dbg, IDX_debug_macro, macoff,
+		      callback, arg, offset, accept_0xff, cudie);
+}
+
+static ptrdiff_t
+macro_info_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
+			  int (*callback) (Dwarf_Macro *, void *),
+			  void *arg, ptrdiff_t offset, Dwarf_Die *cudie)
+{
+  assert (offset >= 0);
+
+  return read_macros (dbg, IDX_debug_macinfo, macoff,
+		      callback, arg, offset, true, cudie);
+}
+
+ptrdiff_t
+dwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
+		     int (*callback) (Dwarf_Macro *, void *),
+		     void *arg, ptrdiff_t token)
+{
+  if (dbg == NULL)
+    {
+      __libdw_seterrno (DWARF_E_NO_DWARF);
+      return -1;
+    }
+
+  bool accept_0xff;
+  ptrdiff_t offset = offset_from_token (token, &accept_0xff);
+  assert (accept_0xff);
+
+  offset = gnu_macros_getmacros_off (dbg, macoff, callback, arg, offset,
+				     accept_0xff, NULL);
+
+  return token_from_offset (offset, accept_0xff);
+}
+
+ptrdiff_t
+dwarf_getmacros (Dwarf_Die *cudie, int (*callback) (Dwarf_Macro *, void *),
+		 void *arg, ptrdiff_t token)
+{
+  if (cudie == NULL)
+    {
+      __libdw_seterrno (DWARF_E_NO_DWARF);
+      return -1;
+    }
+
+  /* This function might be called from a code that expects to see
+     DW_MACINFO_* opcodes, not DW_MACRO_{GNU_,}* ones.  It is fine to
+     serve most DW_MACRO_{GNU_,}* opcodes to such code, because those
+     whose values are the same as DW_MACINFO_* ones also have the same
+     behavior.  It is not very likely that a .debug_macro section
+     would only use the part of opcode space that it shares with
+     .debug_macinfo, but it is possible.  Serving the opcodes that are
+     only valid in DW_MACRO_{GNU_,}* domain is OK as well, because
+     clients in general need to be ready that newer standards define
+     more opcodes, and have coping mechanisms for unfamiliar opcodes.
+
+     The one exception to the above rule is opcode 0xff, which has
+     concrete semantics in .debug_macinfo, but falls into vendor block
+     in .debug_macro, and can be assigned to do whatever.  There is
+     some small probability that the two opcodes would look
+     superficially similar enough that a client would be confused and
+     misbehave as a result.  For this reason, we refuse to serve
+     through this interface 0xff's originating from .debug_macro
+     unless the TOKEN that we obtained indicates the call originates
+     from a new-style caller.  See above for details on what
+     information is encoded into tokens.  */
+
+  bool accept_0xff;
+  ptrdiff_t offset = offset_from_token (token, &accept_0xff);
+
+  /* DW_AT_macro_info */
+  if (dwarf_hasattr (cudie, DW_AT_macro_info))
+    {
+      Dwarf_Word macoff;
+      if (get_offset_from (cudie, DW_AT_macro_info, &macoff) != 0)
+	return -1;
+      offset = macro_info_getmacros_off (cudie->cu->dbg, macoff,
+					 callback, arg, offset, cudie);
+    }
+  else
+    {
+      /* DW_AT_GNU_macros, DW_AT_macros */
+      Dwarf_Word macoff;
+      if (get_offset_from (cudie, DW_AT_GNU_macros, &macoff) != 0)
+	return -1;
+      offset = gnu_macros_getmacros_off (cudie->cu->dbg, macoff,
+					 callback, arg, offset, accept_0xff,
+					 cudie);
+    }
+
+  return token_from_offset (offset, accept_0xff);
+}
diff --git a/third_party/elfutils/libdw/dwarf_getpubnames.c b/third_party/elfutils/libdw/dwarf_getpubnames.c
new file mode 100644
index 0000000..25600f3
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getpubnames.c
@@ -0,0 +1,244 @@
+/* Get public symbol information.
+   Copyright (C) 2002, 2003, 2004, 2005, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libdwP.h>
+#include <dwarf.h>
+#include <system.h>
+
+
+static int
+get_offsets (Dwarf *dbg)
+{
+  size_t allocated = 0;
+  size_t cnt = 0;
+  struct pubnames_s *mem = NULL;
+  const size_t entsize = sizeof (struct pubnames_s);
+  unsigned char *const startp = dbg->sectiondata[IDX_debug_pubnames]->d_buf;
+  unsigned char *readp = startp;
+  unsigned char *endp = readp + dbg->sectiondata[IDX_debug_pubnames]->d_size;
+
+  while (readp + 14 < endp)
+    {
+      /* If necessary, allocate more entries.  */
+      if (cnt >= allocated)
+	{
+	  allocated = MAX (10, 2 * allocated);
+	  struct pubnames_s *newmem
+	    = (struct pubnames_s *) realloc (mem, allocated * entsize);
+	  if (newmem == NULL)
+	    {
+	      __libdw_seterrno (DWARF_E_NOMEM);
+	    err_return:
+	      free (mem);
+	      return -1;
+	    }
+
+	  mem = newmem;
+	}
+
+      /* Read the set header.  */
+      int len_bytes = 4;
+      Dwarf_Off len = read_4ubyte_unaligned_inc (dbg, readp);
+      if (len == DWARF3_LENGTH_64_BIT)
+	{
+	  len = read_8ubyte_unaligned_inc (dbg, readp);
+	  len_bytes = 8;
+	}
+      else if (unlikely (len >= DWARF3_LENGTH_MIN_ESCAPE_CODE
+			 && len <= DWARF3_LENGTH_MAX_ESCAPE_CODE))
+	{
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  goto err_return;
+	}
+
+      /* Now we know the offset of the first offset/name pair.  */
+      mem[cnt].set_start = readp + 2 + 2 * len_bytes - startp;
+      mem[cnt].address_len = len_bytes;
+      size_t max_size = dbg->sectiondata[IDX_debug_pubnames]->d_size;
+      if (mem[cnt].set_start >= max_size
+	  || len - (2 + 2 * len_bytes) > max_size - mem[cnt].set_start)
+	/* Something wrong, the first entry is beyond the end of
+	   the section.  Or the length of the whole unit is too big.  */
+	break;
+
+      /* Read the version.  It better be two for now.  */
+      uint16_t version = read_2ubyte_unaligned (dbg, readp);
+      if (unlikely (version != 2))
+	{
+	  __libdw_seterrno (DWARF_E_INVALID_VERSION);
+	  goto err_return;
+	}
+
+      /* Get the CU offset.  */
+      if (__libdw_read_offset (dbg, dbg, IDX_debug_pubnames,
+			       readp + 2, len_bytes,
+			       &mem[cnt].cu_offset, IDX_debug_info, 3))
+	/* Error has been already set in reader.  */
+	goto err_return;
+
+      /* Determine the size of the CU header.  */
+      unsigned char *infop
+	= ((unsigned char *) dbg->sectiondata[IDX_debug_info]->d_buf
+	   + mem[cnt].cu_offset);
+      if (read_4ubyte_unaligned_noncvt (infop) == DWARF3_LENGTH_64_BIT)
+	mem[cnt].cu_header_size = 23;
+      else
+	mem[cnt].cu_header_size = 11;
+
+      ++cnt;
+
+      /* Advance to the next set.  */
+      readp += len;
+    }
+
+  if (mem == NULL || cnt == 0)
+    {
+      free (mem);
+      __libdw_seterrno (DWARF_E_NO_ENTRY);
+      return -1;
+    }
+
+  dbg->pubnames_sets = (struct pubnames_s *) realloc (mem, cnt * entsize);
+  dbg->pubnames_nsets = cnt;
+
+  return 0;
+}
+
+
+ptrdiff_t
+dwarf_getpubnames (Dwarf *dbg,
+		   int (*callback) (Dwarf *, Dwarf_Global *, void *),
+		   void *arg, ptrdiff_t offset)
+{
+  if (dbg == NULL)
+    return -1l;
+
+  if (unlikely (offset < 0))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+      return -1l;
+    }
+
+  /* Make sure it is a valid offset.  */
+  if (unlikely (dbg->sectiondata[IDX_debug_pubnames] == NULL
+		|| ((size_t) offset
+		    >= dbg->sectiondata[IDX_debug_pubnames]->d_size)))
+    /* No (more) entry.  */
+    return 0;
+
+  /* If necessary read the set information.  */
+  if (dbg->pubnames_nsets == 0 && unlikely (get_offsets (dbg) != 0))
+    return -1l;
+
+  /* Find the place where to start.  */
+  size_t cnt;
+  if (offset == 0)
+    {
+      cnt = 0;
+      offset = dbg->pubnames_sets[0].set_start;
+    }
+  else
+    {
+      for (cnt = 0; cnt + 1 < dbg->pubnames_nsets; ++cnt)
+	if ((Dwarf_Off) offset >= dbg->pubnames_sets[cnt].set_start)
+	  {
+	    assert ((Dwarf_Off) offset
+		    < dbg->pubnames_sets[cnt + 1].set_start);
+	    break;
+	  }
+      assert (cnt + 1 < dbg->pubnames_nsets);
+    }
+
+  unsigned char *startp
+    = (unsigned char *) dbg->sectiondata[IDX_debug_pubnames]->d_buf;
+  unsigned char *endp
+    = startp + dbg->sectiondata[IDX_debug_pubnames]->d_size;
+  unsigned char *readp = startp + offset;
+  while (1)
+    {
+      Dwarf_Global gl;
+
+      gl.cu_offset = (dbg->pubnames_sets[cnt].cu_offset
+		      + dbg->pubnames_sets[cnt].cu_header_size);
+
+      while (1)
+	{
+	  /* READP points to the next offset/name pair.  */
+	  if (readp + dbg->pubnames_sets[cnt].address_len > endp)
+	    goto invalid_dwarf;
+	  if (dbg->pubnames_sets[cnt].address_len == 4)
+	    gl.die_offset = read_4ubyte_unaligned_inc (dbg, readp);
+	  else
+	    gl.die_offset = read_8ubyte_unaligned_inc (dbg, readp);
+
+	  /* If the offset is zero we reached the end of the set.  */
+	  if (gl.die_offset == 0)
+	    break;
+
+	  /* Add the CU offset.  */
+	  gl.die_offset += dbg->pubnames_sets[cnt].cu_offset;
+
+	  gl.name = (char *) readp;
+	  readp = (unsigned char *) memchr (gl.name, '\0', endp - readp);
+	  if (unlikely (readp == NULL))
+	    {
+	    invalid_dwarf:
+	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	      return -1l;
+	    }
+	  readp++;
+
+	  /* We found name and DIE offset.  Report it.  */
+	  if (callback (dbg, &gl, arg) != DWARF_CB_OK)
+	    {
+	      /* The user wants us to stop.  Return the offset of the
+		 next entry.  */
+	      return readp - startp;
+	    }
+	}
+
+      if (++cnt == dbg->pubnames_nsets)
+	/* This was the last set.  */
+	break;
+
+      startp = (unsigned char *) dbg->sectiondata[IDX_debug_pubnames]->d_buf;
+      readp = startp + dbg->pubnames_sets[cnt].set_start;
+    }
+
+  /* We are done.  No more entries.  */
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getscopes.c b/third_party/elfutils/libdw/dwarf_getscopes.c
new file mode 100644
index 0000000..df480d3
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getscopes.c
@@ -0,0 +1,201 @@
+/* Return scope DIEs containing PC address.
+   Copyright (C) 2005, 2007, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+struct args
+{
+  Dwarf_Addr pc;
+  Dwarf_Die *scopes;
+  unsigned int inlined, nscopes;
+  Dwarf_Die inlined_origin;
+};
+
+/* Preorder visitor: prune the traversal if this DIE does not contain PC.  */
+static int
+pc_match (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg)
+{
+  struct args *a = arg;
+
+  if (a->scopes != NULL)
+    die->prune = true;
+  else
+    {
+      /* dwarf_haspc returns an error if there are no appropriate attributes.
+	 But we use it indiscriminantly instead of presuming which tags can
+	 have PC attributes.  So when it fails for that reason, treat it just
+	 as a nonmatching return.  */
+      int result = INTUSE(dwarf_haspc) (&die->die, a->pc);
+      if (result < 0)
+	{
+	  int error = INTUSE(dwarf_errno) ();
+	  if (error != DWARF_E_NOERROR && error != DWARF_E_NO_DEBUG_RANGES)
+	    {
+	      __libdw_seterrno (error);
+	      return -1;
+	    }
+	  result = 0;
+	}
+      if (result == 0)
+    	die->prune = true;
+
+      if (!die->prune
+	  && INTUSE (dwarf_tag) (&die->die) == DW_TAG_inlined_subroutine)
+	a->inlined = depth;
+    }
+
+  return 0;
+}
+
+/* Preorder visitor for second partial traversal after finding a
+   concrete inlined instance.  */
+static int
+origin_match (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg)
+{
+  struct args *a = arg;
+
+  if (die->die.addr != a->inlined_origin.addr)
+    return 0;
+
+  /* We have a winner!  This is the abstract definition of the inline
+     function of which A->scopes[A->nscopes - 1] is a concrete instance.
+  */
+
+  unsigned int nscopes = a->nscopes + depth;
+  Dwarf_Die *scopes = realloc (a->scopes, nscopes * sizeof scopes[0]);
+  if (scopes == NULL)
+    {
+      free (a->scopes);
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return -1;
+    }
+
+  a->scopes = scopes;
+  do
+    {
+      die = die->parent;
+      scopes[a->nscopes++] = die->die;
+    }
+  while (a->nscopes < nscopes);
+  assert (die->parent == NULL);
+  return a->nscopes;
+}
+
+/* Postorder visitor: first (innermost) call wins.  */
+static int
+pc_record (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg)
+{
+  struct args *a = arg;
+
+  if (die->prune)
+    return 0;
+
+  if (a->scopes == NULL)
+    {
+      /* We have hit the innermost DIE that contains the target PC.  */
+
+      a->nscopes = depth + 1 - a->inlined;
+      a->scopes = malloc (a->nscopes * sizeof a->scopes[0]);
+      if (a->scopes == NULL)
+	{
+	  __libdw_seterrno (DWARF_E_NOMEM);
+	  return -1;
+	}
+
+      for (unsigned int i = 0; i < a->nscopes; ++i)
+	{
+	  a->scopes[i] = die->die;
+	  die = die->parent;
+	}
+
+      if (a->inlined == 0)
+	{
+	  assert (die == NULL);
+	  return a->nscopes;
+	}
+
+      /* This is the concrete inlined instance itself.
+	 Record its abstract_origin pointer.  */
+      Dwarf_Die *const inlinedie = &a->scopes[depth - a->inlined];
+
+      assert (INTUSE (dwarf_tag) (inlinedie) == DW_TAG_inlined_subroutine);
+      Dwarf_Attribute attr_mem;
+      Dwarf_Attribute *attr = INTUSE (dwarf_attr) (inlinedie,
+						   DW_AT_abstract_origin,
+						   &attr_mem);
+      if (INTUSE (dwarf_formref_die) (attr, &a->inlined_origin) == NULL)
+	return -1;
+      return 0;
+    }
+
+
+  /* We've recorded the scopes back to one that is a concrete inlined
+     instance.  Now return out of the traversal back to the scope
+     containing that instance.  */
+
+  assert (a->inlined);
+  if (depth >= a->inlined)
+    /* Not there yet.  */
+    return 0;
+
+  /* Now we are in a scope that contains the concrete inlined instance.
+     Search it for the inline function's abstract definition.
+     If we don't find it, return to search the containing scope.
+     If we do find it, the nonzero return value will bail us out
+     of the postorder traversal.  */
+  return __libdw_visit_scopes (depth, die, NULL, &origin_match, NULL, a);
+}
+
+
+int
+dwarf_getscopes (Dwarf_Die *cudie, Dwarf_Addr pc, Dwarf_Die **scopes)
+{
+  if (cudie == NULL)
+    return -1;
+
+  struct Dwarf_Die_Chain cu = { .parent = NULL, .die = *cudie };
+  struct args a = { .pc = pc };
+
+  int result = __libdw_visit_scopes (0, &cu, NULL, &pc_match, &pc_record, &a);
+
+  if (result == 0 && a.scopes != NULL)
+    result = __libdw_visit_scopes (0, &cu, NULL, &origin_match, NULL, &a);
+
+  if (result > 0)
+    *scopes = a.scopes;
+
+  return result;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getscopes_die.c b/third_party/elfutils/libdw/dwarf_getscopes_die.c
new file mode 100644
index 0000000..8e2e41d
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getscopes_die.c
@@ -0,0 +1,74 @@
+/* Return scope DIEs containing given DIE.
+   Copyright (C) 2005, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "libdwP.h"
+#include <assert.h>
+#include <stdlib.h>
+
+static int
+scope_visitor (unsigned int depth, struct Dwarf_Die_Chain *die, void *arg)
+{
+  if (die->die.addr != *(void **) arg)
+    return 0;
+
+  Dwarf_Die *scopes = malloc (depth * sizeof scopes[0]);
+  if (scopes == NULL)
+    {
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return -1;
+    }
+
+  unsigned int i = 0;
+  do
+    {
+      scopes[i++] = die->die;
+      die = die->parent;
+    }
+  while (die != NULL);
+  assert (i == depth);
+
+  *(void **) arg = scopes;
+  return depth;
+}
+
+int
+dwarf_getscopes_die (Dwarf_Die *die, Dwarf_Die **scopes)
+{
+  if (die == NULL)
+    return -1;
+
+  struct Dwarf_Die_Chain cu = { .die = CUDIE (die->cu), .parent = NULL };
+  void *info = die->addr;
+  int result = __libdw_visit_scopes (1, &cu, NULL, &scope_visitor, NULL, &info);
+  if (result > 0)
+    *scopes = info;
+  return result;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getscopevar.c b/third_party/elfutils/libdw/dwarf_getscopevar.c
new file mode 100644
index 0000000..7b1416f
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getscopevar.c
@@ -0,0 +1,159 @@
+/* Find a named variable or parameter within given scopes.
+   Copyright (C) 2005-2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdbool.h>
+#include <string.h>
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+/* Find the containing CU's files.  */
+static int
+getfiles (Dwarf_Die *die, Dwarf_Files **files)
+{
+  return INTUSE(dwarf_getsrcfiles) (&CUDIE (die->cu), files, NULL);
+}
+
+/* Fetch an attribute that should have a constant integer form.  */
+static int
+getattr (Dwarf_Die *die, int search_name, Dwarf_Word *value)
+{
+  Dwarf_Attribute attr_mem;
+  return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr) (die, search_name,
+						      &attr_mem), value);
+}
+
+static inline int
+file_matches (const char *lastfile,
+              size_t match_file_len, const char *match_file,
+              Dwarf_Files *files, size_t idx,
+              bool *lastfile_matches)
+{
+  if (idx >= files->nfiles)
+    return false;
+  const char *file = files->info[idx].name;
+  if (file != lastfile)
+    {
+      size_t len = strlen (file);
+      *lastfile_matches = (len >= match_file_len
+                          && !memcmp (match_file, file, match_file_len)
+                          && (len == match_file_len
+                              || file[len - match_file_len - 1] == '/'));
+    }
+  return *lastfile_matches;
+}
+
+/* Search SCOPES[0..NSCOPES-1] for a variable called NAME.
+   Ignore the first SKIP_SHADOWS scopes that match the name.
+   If MATCH_FILE is not null, accept only declaration in that source file;
+   if MATCH_LINENO or MATCH_LINECOL are also nonzero, accept only declaration
+   at that line and column.
+
+   If successful, fill in *RESULT with the DIE of the variable found,
+   and return N where SCOPES[N] is the scope defining the variable.
+   Return -1 for errors or -2 for no matching variable found.  */
+
+int
+dwarf_getscopevar (Dwarf_Die *scopes, int nscopes,
+		   const char *name, int skip_shadows,
+		   const char *match_file, int match_lineno, int match_linecol,
+		   Dwarf_Die *result)
+{
+  /* Match against the given file name.  */
+  size_t match_file_len = match_file == NULL ? 0 : strlen (match_file);
+  bool lastfile_matches = false;
+  const char *lastfile = NULL;
+
+  /* Start with the innermost scope and move out.  */
+  for (int out = 0; out < nscopes; ++out)
+    if (INTUSE(dwarf_haschildren) (&scopes[out]))
+      {
+	if (INTUSE(dwarf_child) (&scopes[out], result) != 0)
+	  return -1;
+	do
+	  {
+	    switch (INTUSE(dwarf_tag) (result))
+	      {
+	      case DW_TAG_variable:
+	      case DW_TAG_formal_parameter:
+		break;
+
+	      default:
+		continue;
+	      }
+
+	    /* Only get here for a variable or parameter.  Check the name.  */
+	    const char *diename = INTUSE(dwarf_diename) (result);
+	    if (diename != NULL && !strcmp (name, diename))
+	      {
+		/* We have a matching name.  */
+
+		if (skip_shadows > 0)
+		  {
+		    /* Punt this scope for the one it shadows.  */
+		    --skip_shadows;
+		    break;
+		  }
+
+		if (match_file != NULL)
+		  {
+		    /* Check its decl_file.  */
+
+		    Dwarf_Word i;
+		    Dwarf_Files *files;
+		    if (getattr (result, DW_AT_decl_file, &i) != 0
+			|| getfiles (&scopes[out], &files) != 0)
+		      break;
+
+		    if (!file_matches (lastfile, match_file_len, match_file,
+		                       files, i, &lastfile_matches))
+		      break;
+
+		    if (match_lineno > 0
+			&& (getattr (result, DW_AT_decl_line, &i) != 0
+			    || (int) i != match_lineno))
+		      break;
+		    if (match_linecol > 0
+			&& (getattr (result, DW_AT_decl_column, &i) != 0
+			    || (int) i != match_linecol))
+		      break;
+		  }
+
+		/* We have a winner!  */
+		return out;
+	      }
+	  }
+	while (INTUSE(dwarf_siblingof) (result, result) == 0);
+      }
+
+  return -2;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getsrc_die.c b/third_party/elfutils/libdw/dwarf_getsrc_die.c
new file mode 100644
index 0000000..a95179f
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getsrc_die.c
@@ -0,0 +1,74 @@
+/* Find line information for address.
+   Copyright (C) 2004, 2005, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <assert.h>
+
+
+Dwarf_Line *
+dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr)
+{
+  Dwarf_Lines *lines;
+  size_t nlines;
+
+  if (INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines) != 0)
+    return NULL;
+
+  /* The lines are sorted by address, so we can use binary search.  */
+  if (nlines > 0)
+    {
+      size_t l = 0, u = nlines - 1;
+      while (l < u)
+	{
+	  size_t idx = u - (u - l) / 2;
+	  Dwarf_Line *line = &lines->info[idx];
+	  if (addr < line->addr)
+	    u = idx - 1;
+	  else
+	    l = idx;
+	}
+
+      /* This is guaranteed for us by libdw read_srclines.  */
+      assert (lines->info[nlines - 1].end_sequence);
+
+      /* The last line which is less than or equal to addr is what we
+	 want, unless it is the end_sequence which is after the
+	 current line sequence.  */
+      Dwarf_Line *line = &lines->info[l];
+      if (! line->end_sequence && line->addr <= addr)
+	return &lines->info[l];
+    }
+
+  __libdw_seterrno (DWARF_E_ADDR_OUTOFRANGE);
+  return NULL;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getsrc_file.c b/third_party/elfutils/libdw/dwarf_getsrc_file.c
new file mode 100644
index 0000000..5289c7d
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getsrc_file.c
@@ -0,0 +1,178 @@
+/* Find line information for given file/line/column triple.
+   Copyright (C) 2005-2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libdwP.h"
+
+
+int
+dwarf_getsrc_file (Dwarf *dbg, const char *fname, int lineno, int column,
+		   Dwarf_Line ***srcsp, size_t *nsrcs)
+{
+  if (dbg == NULL)
+    return -1;
+
+  bool is_basename = strchr (fname, '/') == NULL;
+
+  size_t max_match = *nsrcs ?: ~0u;
+  size_t act_match = *nsrcs;
+  size_t cur_match = 0;
+  Dwarf_Line **match = *nsrcs == 0 ? NULL : *srcsp;
+
+  size_t cuhl;
+  Dwarf_Off noff;
+  for (Dwarf_Off off = 0;
+       INTUSE(dwarf_nextcu) (dbg, off, &noff, &cuhl, NULL, NULL, NULL) == 0;
+       off = noff)
+    {
+      Dwarf_Die cudie_mem;
+      Dwarf_Die *cudie = INTUSE(dwarf_offdie) (dbg, off + cuhl, &cudie_mem);
+      if (cudie == NULL)
+	continue;
+
+      /* Get the line number information for this file.  */
+      Dwarf_Lines *lines;
+      size_t nlines;
+      if (INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines) != 0)
+	{
+	  /* Ignore a CU that just has no DW_AT_stmt_list at all.  */
+	  int error = INTUSE(dwarf_errno) ();
+	  if (error == 0)
+	    continue;
+	  __libdw_seterrno (error);
+	  return -1;
+	}
+
+      /* Search through all the line number records for a matching
+	 file and line/column number.  If any of the numbers is zero,
+	 no match is performed.  */
+      unsigned int lastfile = UINT_MAX;
+      bool lastmatch = false;
+      for (size_t cnt = 0; cnt < nlines; ++cnt)
+	{
+	  Dwarf_Line *line = &lines->info[cnt];
+
+	  if (lastfile != line->file)
+	    {
+	      lastfile = line->file;
+	      if (lastfile >= line->files->nfiles)
+		{
+		  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+		  return -1;
+		}
+
+	      /* Match the name with the name the user provided.  */
+	      const char *fname2 = line->files->info[lastfile].name;
+	      if (is_basename)
+		lastmatch = strcmp (basename (fname2), fname) == 0;
+	      else
+		lastmatch = strcmp (fname2, fname) == 0;
+	    }
+	  if (!lastmatch)
+	    continue;
+
+	  /* See whether line and possibly column match.  */
+	  if (lineno != 0
+	      && (lineno > line->line
+		  || (column != 0 && column > line->column)))
+	    /* Cannot match.  */
+	    continue;
+
+	  /* Determine whether this is the best match so far.  */
+	  size_t inner;
+	  for (inner = 0; inner < cur_match; ++inner)
+	    if (match[inner]->files == line->files
+		&& match[inner]->file == line->file)
+	      break;
+	  if (inner < cur_match
+	      && (match[inner]->line != line->line
+		  || match[inner]->line != lineno
+		  || (column != 0
+		      && (match[inner]->column != line->column
+			  || match[inner]->column != column))))
+	    {
+	      /* We know about this file already.  If this is a better
+		 match for the line number, use it.  */
+	      if (match[inner]->line >= line->line
+		  && (match[inner]->line != line->line
+		      || match[inner]->column >= line->column))
+		/*  Use the new line.  Otherwise the old one.  */
+		match[inner] = line;
+	      continue;
+	    }
+
+	  if (cur_match < max_match)
+	    {
+	      if (cur_match == act_match)
+		{
+		  /* Enlarge the array for the results.  */
+		  act_match += 10;
+		  Dwarf_Line **newp = realloc (match,
+					       act_match
+					       * sizeof (Dwarf_Line *));
+		  if (newp == NULL)
+		    {
+		      free (match);
+		      __libdw_seterrno (DWARF_E_NOMEM);
+		      return -1;
+		    }
+		  match = newp;
+		}
+
+	      match[cur_match++] = line;
+	    }
+	}
+
+      /* If we managed to find as many matches as the user requested
+	 already, there is no need to go on to the next CU.  */
+      if (cur_match == max_match)
+	break;
+    }
+
+  if (cur_match > 0)
+    {
+      assert (*nsrcs == 0 || *srcsp == match);
+
+      *nsrcs = cur_match;
+      *srcsp = match;
+
+      return 0;
+    }
+
+  __libdw_seterrno (DWARF_E_NO_MATCH);
+  return -1;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getsrcdirs.c b/third_party/elfutils/libdw/dwarf_getsrcdirs.c
new file mode 100644
index 0000000..8160ed3
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getsrcdirs.c
@@ -0,0 +1,45 @@
+/* Find include directories in source file information.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_getsrcdirs (Dwarf_Files *files, const char *const **result, size_t *ndirs)
+{
+  if (files == NULL)
+    return -1;
+
+  *result = (void *) &files->info[files->nfiles];
+  *ndirs = files->ndirs;
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_getsrcfiles.c b/third_party/elfutils/libdw/dwarf_getsrcfiles.c
new file mode 100644
index 0000000..5af6f68
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getsrcfiles.c
@@ -0,0 +1,79 @@
+/* Return source file information of CU.
+   Copyright (C) 2004, 2005, 2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
+{
+  if (cudie == NULL)
+    return -1;
+  if (! is_cudie (cudie))
+    {
+      __libdw_seterrno (DWARF_E_NOT_CUDIE);
+      return -1;
+    }
+
+  int res = -1;
+
+  /* Get the information if it is not already known.  */
+  struct Dwarf_CU *const cu = cudie->cu;
+  if (cu->lines == NULL)
+    {
+      Dwarf_Lines *lines;
+      size_t nlines;
+
+      /* Let the more generic function do the work.  It'll create more
+	 data but that will be needed in an real program anyway.  */
+      res = INTUSE(dwarf_getsrclines) (cudie, &lines, &nlines);
+    }
+  else if (cu->files != (void *) -1l)
+    /* We already have the information.  */
+    res = 0;
+
+  if (likely (res == 0))
+    {
+      assert (cu->files != NULL && cu->files != (void *) -1l);
+      *files = cu->files;
+      if (nfiles != NULL)
+	*nfiles = cu->files->nfiles;
+    }
+
+  // XXX Eventually: unlocking here.
+
+  return res;
+}
+INTDEF (dwarf_getsrcfiles)
diff --git a/third_party/elfutils/libdw/dwarf_getsrclines.c b/third_party/elfutils/libdw/dwarf_getsrclines.c
new file mode 100644
index 0000000..d02c38d
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getsrclines.c
@@ -0,0 +1,952 @@
+/* Return line number information of CU.
+   Copyright (C) 2004-2010, 2013, 2014, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <search.h>
+
+#include "dwarf.h"
+#include "libdwP.h"
+
+
+struct filelist
+{
+  Dwarf_Fileinfo info;
+  struct filelist *next;
+};
+
+struct linelist
+{
+  Dwarf_Line line;
+  struct linelist *next;
+  size_t sequence;
+};
+
+
+/* Compare by Dwarf_Line.addr, given pointers into an array of pointers.  */
+static int
+compare_lines (const void *a, const void *b)
+{
+  struct linelist *const *p1 = a;
+  struct linelist *const *p2 = b;
+  struct linelist *list1 = *p1;
+  struct linelist *list2 = *p2;
+  Dwarf_Line *line1 = &list1->line;
+  Dwarf_Line *line2 = &list2->line;
+
+  if (line1->addr != line2->addr)
+    return (line1->addr < line2->addr) ? -1 : 1;
+
+  /* An end_sequence marker precedes a normal record at the same address.  */
+  if (line1->end_sequence != line2->end_sequence)
+    return line2->end_sequence - line1->end_sequence;
+
+  /* Otherwise, the linelist sequence maintains a stable sort.  */
+  return (list1->sequence < list2->sequence) ? -1
+    : (list1->sequence > list2->sequence) ? 1
+    : 0;
+}
+
+struct line_state
+{
+  Dwarf_Word addr;
+  unsigned int op_index;
+  unsigned int file;
+  int64_t line;
+  unsigned int column;
+  uint_fast8_t is_stmt;
+  bool basic_block;
+  bool prologue_end;
+  bool epilogue_begin;
+  unsigned int isa;
+  unsigned int discriminator;
+  struct linelist *linelist;
+  size_t nlinelist;
+  unsigned int end_sequence;
+};
+
+static inline void
+run_advance_pc (struct line_state *state, unsigned int op_advance,
+                uint_fast8_t minimum_instr_len, uint_fast8_t max_ops_per_instr)
+{
+  state->addr += minimum_instr_len * ((state->op_index + op_advance)
+				      / max_ops_per_instr);
+  state->op_index = (state->op_index + op_advance) % max_ops_per_instr;
+}
+
+static inline bool
+add_new_line (struct line_state *state, struct linelist *new_line)
+{
+  /* Set the line information.  For some fields we use bitfields,
+     so we would lose information if the encoded values are too large.
+     Check just for paranoia, and call the data "invalid" if it
+     violates our assumptions on reasonable limits for the values.  */
+  new_line->next = state->linelist;
+  new_line->sequence = state->nlinelist;
+  state->linelist = new_line;
+  ++(state->nlinelist);
+
+  /* Set the line information.  For some fields we use bitfields,
+     so we would lose information if the encoded values are too large.
+     Check just for paranoia, and call the data "invalid" if it
+     violates our assumptions on reasonable limits for the values.  */
+#define SET(field)						      \
+  do {								      \
+     new_line->line.field = state->field;			      \
+     if (unlikely (new_line->line.field != state->field))	      \
+       return true;						      \
+   } while (0)
+
+  SET (addr);
+  SET (op_index);
+  SET (file);
+  SET (line);
+  SET (column);
+  SET (is_stmt);
+  SET (basic_block);
+  SET (end_sequence);
+  SET (prologue_end);
+  SET (epilogue_begin);
+  SET (isa);
+  SET (discriminator);
+
+#undef SET
+
+  return false;
+}
+
+static int
+read_srclines (Dwarf *dbg,
+	       const unsigned char *linep, const unsigned char *lineendp,
+	       const char *comp_dir, unsigned address_size,
+	       Dwarf_Lines **linesp, Dwarf_Files **filesp)
+{
+  int res = -1;
+
+  size_t nfilelist = 0;
+  unsigned int ndirlist = 0;
+
+  struct filelist null_file =
+    {
+      .info =
+      {
+	.name = "???",
+	.mtime = 0,
+	.length = 0
+      },
+      .next = NULL
+    };
+  struct filelist *filelist = &null_file;
+
+  /* If there are a large number of lines, files or dirs don't blow up
+     the stack.  Stack allocate some entries, only dynamically malloc
+     when more than MAX.  */
+#define MAX_STACK_ALLOC 4096
+#define MAX_STACK_LINES MAX_STACK_ALLOC
+#define MAX_STACK_FILES (MAX_STACK_ALLOC / 4)
+#define MAX_STACK_DIRS  (MAX_STACK_ALLOC / 16)
+
+  struct dirlist
+  {
+    const char *dir;
+    size_t len;
+  };
+  struct dirlist dirstack[MAX_STACK_DIRS];
+  struct dirlist *dirarray = dirstack;
+
+  /* We are about to process the statement program.  Initialize the
+     state machine registers (see 6.2.2 in the v2.1 specification).  */
+  struct line_state state =
+    {
+      .linelist = NULL,
+      .nlinelist = 0,
+      .addr = 0,
+      .op_index = 0,
+      .file = 1,
+      /* We only store int but want to check for overflow (see SET above).  */
+      .line = 1,
+      .column = 0,
+      .basic_block = false,
+      .prologue_end = false,
+      .epilogue_begin = false,
+      .isa = 0,
+      .discriminator = 0
+    };
+
+  if (unlikely (linep + 4 > lineendp))
+    {
+    invalid_data:
+      __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE);
+      goto out;
+    }
+
+  Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
+  unsigned int length = 4;
+  if (unlikely (unit_length == DWARF3_LENGTH_64_BIT))
+    {
+      if (unlikely (linep + 8 > lineendp))
+	goto invalid_data;
+      unit_length = read_8ubyte_unaligned_inc (dbg, linep);
+      length = 8;
+    }
+
+  /* Check whether we have enough room in the section.  */
+  if (unlikely (unit_length > (size_t) (lineendp - linep)
+      || unit_length < 2 + length + 5 * 1))
+    goto invalid_data;
+  lineendp = linep + unit_length;
+
+  /* The next element of the header is the version identifier.  */
+  uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
+  if (unlikely (version < 2) || unlikely (version > 4))
+    {
+      __libdw_seterrno (DWARF_E_VERSION);
+      goto out;
+    }
+
+  /* Next comes the header length.  */
+  Dwarf_Word header_length;
+  if (length == 4)
+    header_length = read_4ubyte_unaligned_inc (dbg, linep);
+  else
+    header_length = read_8ubyte_unaligned_inc (dbg, linep);
+  const unsigned char *header_start = linep;
+
+  /* Next the minimum instruction length.  */
+  uint_fast8_t minimum_instr_len = *linep++;
+
+  /* Next the maximum operations per instruction, in version 4 format.  */
+  uint_fast8_t max_ops_per_instr = 1;
+  if (version >= 4)
+    {
+      if (unlikely (lineendp - linep < 5))
+	goto invalid_data;
+      max_ops_per_instr = *linep++;
+      if (unlikely (max_ops_per_instr == 0))
+	goto invalid_data;
+    }
+
+  /* Then the flag determining the default value of the is_stmt
+     register.  */
+  uint_fast8_t default_is_stmt = *linep++;
+
+  /* Now the line base.  */
+  int_fast8_t line_base = (int8_t) *linep++;
+
+  /* And the line range.  */
+  uint_fast8_t line_range = *linep++;
+
+  /* The opcode base.  */
+  uint_fast8_t opcode_base = *linep++;
+
+  /* Remember array with the standard opcode length (-1 to account for
+     the opcode with value zero not being mentioned).  */
+  const uint8_t *standard_opcode_lengths = linep - 1;
+  if (unlikely (lineendp - linep < opcode_base - 1))
+    goto invalid_data;
+  linep += opcode_base - 1;
+
+  /* First comes the list of directories.  Add the compilation
+     directory first since the index zero is used for it.  */
+  struct dirlist comp_dir_elem =
+    {
+      .dir = comp_dir,
+      .len = comp_dir ? strlen (comp_dir) : 0,
+    };
+  ndirlist = 1;
+
+  /* First count the entries.  */
+  const unsigned char *dirp = linep;
+  unsigned int ndirs = 0;
+  while (*dirp != 0)
+    {
+      uint8_t *endp = memchr (dirp, '\0', lineendp - dirp);
+      if (endp == NULL)
+	goto invalid_data;
+      ++ndirs;
+      dirp = endp + 1;
+    }
+  ndirlist += ndirs;
+
+  /* Arrange the list in array form.  */
+  if (ndirlist >= MAX_STACK_DIRS)
+    {
+      dirarray = (struct dirlist *) malloc (ndirlist * sizeof (*dirarray));
+      if (unlikely (dirarray == NULL))
+	{
+	no_mem:
+	  __libdw_seterrno (DWARF_E_NOMEM);
+	  goto out;
+	}
+    }
+  dirarray[0] = comp_dir_elem;
+  for (unsigned int n = 1; n < ndirlist; n++)
+    {
+      dirarray[n].dir = (char *) linep;
+      uint8_t *endp = memchr (linep, '\0', lineendp - linep);
+      assert (endp != NULL);
+      dirarray[n].len = endp - linep;
+      linep = endp + 1;
+    }
+  /* Skip the final NUL byte.  */
+  ++linep;
+
+  /* Allocate memory for a new file.  For the first MAX_STACK_FILES
+     entries just return a slot in the preallocated stack array.  */
+  struct filelist flstack[MAX_STACK_FILES];
+#define NEW_FILE() ({							\
+  struct filelist *fl = (nfilelist < MAX_STACK_FILES			\
+			   ? &flstack[nfilelist]			\
+			   : malloc (sizeof (struct filelist)));	\
+  if (unlikely (fl == NULL))						\
+    goto no_mem;							\
+  ++nfilelist;								\
+  fl->next = filelist;							\
+  filelist = fl;							\
+  fl; })
+
+  /* Now read the files.  */
+  nfilelist = 1;
+
+  if (unlikely (linep >= lineendp))
+    goto invalid_data;
+  while (*linep != 0)
+    {
+      struct filelist *new_file = NEW_FILE ();
+
+      /* First comes the file name.  */
+      char *fname = (char *) linep;
+      uint8_t *endp = memchr (fname, '\0', lineendp - linep);
+      if (endp == NULL)
+	goto invalid_data;
+      size_t fnamelen = endp - (uint8_t *) fname;
+      linep = endp + 1;
+
+      /* Then the index.  */
+      Dwarf_Word diridx;
+      if (unlikely (linep >= lineendp))
+	goto invalid_data;
+      get_uleb128 (diridx, linep, lineendp);
+      if (unlikely (diridx >= ndirlist))
+	{
+	  __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
+	  goto out;
+	}
+
+      if (*fname == '/')
+	/* It's an absolute path.  */
+	new_file->info.name = fname;
+      else
+	{
+	  new_file->info.name = libdw_alloc (dbg, char, 1,
+					     dirarray[diridx].len + 1
+					     + fnamelen + 1);
+	  char *cp = new_file->info.name;
+
+	  if (dirarray[diridx].dir != NULL)
+	    {
+	      /* This value could be NULL in case the DW_AT_comp_dir
+		 was not present.  We cannot do much in this case.
+		 The easiest thing is to convert the path in an
+		 absolute path.  */
+	      cp = stpcpy (cp, dirarray[diridx].dir);
+	    }
+	  *cp++ = '/';
+	  strcpy (cp, fname);
+	  assert (strlen (new_file->info.name)
+		  < dirarray[diridx].len + 1 + fnamelen + 1);
+	}
+
+      /* Next comes the modification time.  */
+      if (unlikely (linep >= lineendp))
+	goto invalid_data;
+      get_uleb128 (new_file->info.mtime, linep, lineendp);
+
+      /* Finally the length of the file.  */
+      if (unlikely (linep >= lineendp))
+	goto invalid_data;
+      get_uleb128 (new_file->info.length, linep, lineendp);
+    }
+  /* Skip the final NUL byte.  */
+  ++linep;
+
+  /* Consistency check.  */
+  if (unlikely (linep != header_start + header_length))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      goto out;
+    }
+
+  state.is_stmt = default_is_stmt;
+
+  /* Apply the "operation advance" from a special opcode or
+     DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
+#define advance_pc(op_advance) \
+  run_advance_pc (&state, op_advance, minimum_instr_len, max_ops_per_instr)
+
+  /* Process the instructions.  */
+
+  /* Adds a new line to the matrix.  For the first MAX_STACK_LINES
+     entries just return a slot in the preallocated stack array.  */
+  struct linelist llstack[MAX_STACK_LINES];
+#define NEW_LINE(end_seq)						\
+  do {								\
+    struct linelist *ll = (state.nlinelist < MAX_STACK_LINES	\
+			   ? &llstack[state.nlinelist]		\
+			   : malloc (sizeof (struct linelist)));	\
+    if (unlikely (ll == NULL))					\
+      goto no_mem;						\
+    state.end_sequence = end_seq;				\
+    if (unlikely (add_new_line (&state, ll)))			\
+      goto invalid_data;						\
+  } while (0)
+
+  while (linep < lineendp)
+    {
+      unsigned int opcode;
+      unsigned int u128;
+      int s128;
+
+      /* Read the opcode.  */
+      opcode = *linep++;
+
+      /* Is this a special opcode?  */
+      if (likely (opcode >= opcode_base))
+	{
+	  if (unlikely (line_range == 0))
+	    goto invalid_data;
+
+	  /* Yes.  Handling this is quite easy since the opcode value
+	     is computed with
+
+	     opcode = (desired line increment - line_base)
+		       + (line_range * address advance) + opcode_base
+	  */
+	  int line_increment = (line_base
+				+ (opcode - opcode_base) % line_range);
+
+	  /* Perform the increments.  */
+	  state.line += line_increment;
+	  advance_pc ((opcode - opcode_base) / line_range);
+
+	  /* Add a new line with the current state machine values.  */
+	  NEW_LINE (0);
+
+	  /* Reset the flags.  */
+	  state.basic_block = false;
+	  state.prologue_end = false;
+	  state.epilogue_begin = false;
+	  state.discriminator = 0;
+	}
+      else if (opcode == 0)
+	{
+	  /* This an extended opcode.  */
+	  if (unlikely (lineendp - linep < 2))
+	    goto invalid_data;
+
+	  /* The length.  */
+	  uint_fast8_t len = *linep++;
+
+	  if (unlikely ((size_t) (lineendp - linep) < len))
+	    goto invalid_data;
+
+	  /* The sub-opcode.  */
+	  opcode = *linep++;
+
+	  switch (opcode)
+	    {
+	    case DW_LNE_end_sequence:
+	      /* Add a new line with the current state machine values.
+		 The is the end of the sequence.  */
+	      NEW_LINE (1);
+
+	      /* Reset the registers.  */
+	      state.addr = 0;
+	      state.op_index = 0;
+	      state.file = 1;
+	      state.line = 1;
+	      state.column = 0;
+	      state.is_stmt = default_is_stmt;
+	      state.basic_block = false;
+	      state.prologue_end = false;
+	      state.epilogue_begin = false;
+	      state.isa = 0;
+	      state.discriminator = 0;
+	      break;
+
+	    case DW_LNE_set_address:
+	      /* The value is an address.  The size is defined as
+		 apporiate for the target machine.  We use the
+		 address size field from the CU header.  */
+	      state.op_index = 0;
+	      if (unlikely (lineendp - linep < (uint8_t) address_size))
+		goto invalid_data;
+	      if (__libdw_read_address_inc (dbg, IDX_debug_line, &linep,
+					    address_size, &state.addr))
+		goto out;
+	      break;
+
+	    case DW_LNE_define_file:
+	      {
+		char *fname = (char *) linep;
+		uint8_t *endp = memchr (linep, '\0', lineendp - linep);
+		if (endp == NULL)
+		  goto invalid_data;
+		size_t fnamelen = endp - linep;
+		linep = endp + 1;
+
+		unsigned int diridx;
+		if (unlikely (linep >= lineendp))
+		  goto invalid_data;
+		get_uleb128 (diridx, linep, lineendp);
+		if (unlikely (diridx >= ndirlist))
+		  {
+		    __libdw_seterrno (DWARF_E_INVALID_DIR_IDX);
+		    goto invalid_data;
+		  }
+		Dwarf_Word mtime;
+		if (unlikely (linep >= lineendp))
+		  goto invalid_data;
+		get_uleb128 (mtime, linep, lineendp);
+		Dwarf_Word filelength;
+		if (unlikely (linep >= lineendp))
+		  goto invalid_data;
+		get_uleb128 (filelength, linep, lineendp);
+
+		struct filelist *new_file = NEW_FILE ();
+		if (fname[0] == '/')
+		  new_file->info.name = fname;
+		else
+		  {
+		    new_file->info.name =
+		      libdw_alloc (dbg, char, 1, (dirarray[diridx].len + 1
+						  + fnamelen + 1));
+		    char *cp = new_file->info.name;
+
+		    if (dirarray[diridx].dir != NULL)
+		      /* This value could be NULL in case the
+			 DW_AT_comp_dir was not present.  We
+			 cannot do much in this case.  The easiest
+			 thing is to convert the path in an
+			 absolute path.  */
+		      cp = stpcpy (cp, dirarray[diridx].dir);
+		    *cp++ = '/';
+		    strcpy (cp, fname);
+		  }
+
+		new_file->info.mtime = mtime;
+		new_file->info.length = filelength;
+	      }
+	      break;
+
+	    case DW_LNE_set_discriminator:
+	      /* Takes one ULEB128 parameter, the discriminator.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 1))
+		goto invalid_data;
+
+	      if (unlikely (linep >= lineendp))
+		goto invalid_data;
+	      get_uleb128 (state.discriminator, linep, lineendp);
+	      break;
+
+	    default:
+	      /* Unknown, ignore it.  */
+	      if (unlikely ((size_t) (lineendp - (linep - 1)) < len))
+		goto invalid_data;
+	      linep += len - 1;
+	      break;
+	    }
+	}
+      else if (opcode <= DW_LNS_set_isa)
+	{
+	  /* This is a known standard opcode.  */
+	  switch (opcode)
+	    {
+	    case DW_LNS_copy:
+	      /* Takes no argument.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 0))
+		goto invalid_data;
+
+	      /* Add a new line with the current state machine values.  */
+	      NEW_LINE (0);
+
+	      /* Reset the flags.  */
+	      state.basic_block = false;
+	      state.prologue_end = false;
+	      state.epilogue_begin = false;
+	      state.discriminator = 0;
+	      break;
+
+	    case DW_LNS_advance_pc:
+	      /* Takes one uleb128 parameter which is added to the
+		 address.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 1))
+		goto invalid_data;
+
+	      if (unlikely (linep >= lineendp))
+		goto invalid_data;
+	      get_uleb128 (u128, linep, lineendp);
+	      advance_pc (u128);
+	      break;
+
+	    case DW_LNS_advance_line:
+	      /* Takes one sleb128 parameter which is added to the
+		 line.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 1))
+		goto invalid_data;
+
+	      if (unlikely (linep >= lineendp))
+		goto invalid_data;
+	      get_sleb128 (s128, linep, lineendp);
+	      state.line += s128;
+	      break;
+
+	    case DW_LNS_set_file:
+	      /* Takes one uleb128 parameter which is stored in file.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 1))
+		goto invalid_data;
+
+	      if (unlikely (linep >= lineendp))
+		goto invalid_data;
+	      get_uleb128 (u128, linep, lineendp);
+	      state.file = u128;
+	      break;
+
+	    case DW_LNS_set_column:
+	      /* Takes one uleb128 parameter which is stored in column.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 1))
+		goto invalid_data;
+
+	      if (unlikely (linep >= lineendp))
+		goto invalid_data;
+	      get_uleb128 (u128, linep, lineendp);
+	      state.column = u128;
+	      break;
+
+	    case DW_LNS_negate_stmt:
+	      /* Takes no argument.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 0))
+		goto invalid_data;
+
+	      state.is_stmt = 1 - state.is_stmt;
+	      break;
+
+	    case DW_LNS_set_basic_block:
+	      /* Takes no argument.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 0))
+		goto invalid_data;
+
+	      state.basic_block = true;
+	      break;
+
+	    case DW_LNS_const_add_pc:
+	      /* Takes no argument.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 0))
+		goto invalid_data;
+
+	      if (unlikely (line_range == 0))
+		goto invalid_data;
+
+	      advance_pc ((255 - opcode_base) / line_range);
+	      break;
+
+	    case DW_LNS_fixed_advance_pc:
+	      /* Takes one 16 bit parameter which is added to the
+		 address.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 1)
+		  || unlikely (lineendp - linep < 2))
+		goto invalid_data;
+
+	      state.addr += read_2ubyte_unaligned_inc (dbg, linep);
+	      state.op_index = 0;
+	      break;
+
+	    case DW_LNS_set_prologue_end:
+	      /* Takes no argument.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 0))
+		goto invalid_data;
+
+	      state.prologue_end = true;
+	      break;
+
+	    case DW_LNS_set_epilogue_begin:
+	      /* Takes no argument.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 0))
+		goto invalid_data;
+
+	      state.epilogue_begin = true;
+	      break;
+
+	    case DW_LNS_set_isa:
+	      /* Takes one uleb128 parameter which is stored in isa.  */
+	      if (unlikely (standard_opcode_lengths[opcode] != 1))
+		goto invalid_data;
+
+	      if (unlikely (linep >= lineendp))
+		goto invalid_data;
+	      get_uleb128 (state.isa, linep, lineendp);
+	      break;
+	    }
+	}
+      else
+	{
+	  /* This is a new opcode the generator but not we know about.
+	     Read the parameters associated with it but then discard
+	     everything.  Read all the parameters for this opcode.  */
+	  for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
+	    {
+	      if (unlikely (linep >= lineendp))
+		goto invalid_data;
+	      get_uleb128 (u128, linep, lineendp);
+	    }
+
+	  /* Next round, ignore this opcode.  */
+	  continue;
+	}
+    }
+
+  /* Put all the files in an array.  */
+  Dwarf_Files *files = libdw_alloc (dbg, Dwarf_Files,
+				    sizeof (Dwarf_Files)
+				    + nfilelist * sizeof (Dwarf_Fileinfo)
+				    + (ndirlist + 1) * sizeof (char *),
+				    1);
+  const char **dirs = (void *) &files->info[nfilelist];
+
+  struct filelist *fileslist = filelist;
+  files->nfiles = nfilelist;
+  for (size_t n = nfilelist; n > 0; n--)
+    {
+      files->info[n - 1] = fileslist->info;
+      fileslist = fileslist->next;
+    }
+  assert (fileslist == NULL);
+
+  /* Put all the directory strings in an array.  */
+  files->ndirs = ndirlist;
+  for (unsigned int i = 0; i < ndirlist; ++i)
+    dirs[i] = dirarray[i].dir;
+  dirs[ndirlist] = NULL;
+
+  /* Pass the file data structure to the caller.  */
+  if (filesp != NULL)
+    *filesp = files;
+
+  size_t buf_size = (sizeof (Dwarf_Lines)
+		     + (sizeof (Dwarf_Line) * state.nlinelist));
+  void *buf = libdw_alloc (dbg, Dwarf_Lines, buf_size, 1);
+
+  /* First use the buffer for the pointers, and sort the entries.
+     We'll write the pointers in the end of the buffer, and then
+     copy into the buffer from the beginning so the overlap works.  */
+  assert (sizeof (Dwarf_Line) >= sizeof (struct linelist *));
+  struct linelist **sortlines = (buf + buf_size
+				 - sizeof (struct linelist **) * state.nlinelist);
+
+  /* The list is in LIFO order and usually they come in clumps with
+     ascending addresses.  So fill from the back to probably start with
+     runs already in order before we sort.  */
+  struct linelist *lineslist = state.linelist;
+  for (size_t i = state.nlinelist; i-- > 0; )
+    {
+      sortlines[i] = lineslist;
+      lineslist = lineslist->next;
+    }
+  assert (lineslist == NULL);
+
+  /* Sort by ascending address.  */
+  qsort (sortlines, state.nlinelist, sizeof sortlines[0], &compare_lines);
+
+  /* Now that they are sorted, put them in the final array.
+     The buffers overlap, so we've clobbered the early elements
+     of SORTLINES by the time we're reading the later ones.  */
+  Dwarf_Lines *lines = buf;
+  lines->nlines = state.nlinelist;
+  for (size_t i = 0; i < state.nlinelist; ++i)
+    {
+      lines->info[i] = sortlines[i]->line;
+      lines->info[i].files = files;
+    }
+
+  /* Make sure the highest address for the CU is marked as end_sequence.
+     This is required by the DWARF spec, but some compilers forget and
+     dwfl_module_getsrc depends on it.  */
+  if (state.nlinelist > 0)
+    lines->info[state.nlinelist - 1].end_sequence = 1;
+
+  /* Pass the line structure back to the caller.  */
+  if (linesp != NULL)
+    *linesp = lines;
+
+  /* Success.  */
+  res = 0;
+
+ out:
+  /* Free malloced line records, if any.  */
+  for (size_t i = MAX_STACK_LINES; i < state.nlinelist; i++)
+    {
+      struct linelist *ll = state.linelist->next;
+      free (state.linelist);
+      state.linelist = ll;
+    }
+  if (ndirlist >= MAX_STACK_DIRS)
+    free (dirarray);
+  for (size_t i = MAX_STACK_FILES; i < nfilelist; i++)
+    {
+      struct filelist *fl = filelist->next;
+      free (filelist);
+      filelist = fl;
+    }
+
+  return res;
+}
+
+static int
+files_lines_compare (const void *p1, const void *p2)
+{
+  const struct files_lines_s *t1 = p1;
+  const struct files_lines_s *t2 = p2;
+
+  if (t1->debug_line_offset < t2->debug_line_offset)
+    return -1;
+  if (t1->debug_line_offset > t2->debug_line_offset)
+    return 1;
+
+  return 0;
+}
+
+int
+internal_function
+__libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
+		     const char *comp_dir, unsigned address_size,
+		     Dwarf_Lines **linesp, Dwarf_Files **filesp)
+{
+  struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
+  struct files_lines_s **found = tfind (&fake, &dbg->files_lines,
+					files_lines_compare);
+  if (found == NULL)
+    {
+      Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
+      if (data == NULL
+	  || __libdw_offset_in_section (dbg, IDX_debug_line,
+					debug_line_offset, 1) != 0)
+	return -1;
+
+      const unsigned char *linep = data->d_buf + debug_line_offset;
+      const unsigned char *lineendp = data->d_buf + data->d_size;
+
+      struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s,
+						sizeof *node, 1);
+
+      if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
+			 &node->lines, &node->files) != 0)
+	return -1;
+
+      node->debug_line_offset = debug_line_offset;
+
+      found = tsearch (node, &dbg->files_lines, files_lines_compare);
+      if (found == NULL)
+	{
+	  __libdw_seterrno (DWARF_E_NOMEM);
+	  return -1;
+	}
+    }
+
+  if (linesp != NULL)
+    *linesp = (*found)->lines;
+
+  if (filesp != NULL)
+    *filesp = (*found)->files;
+
+  return 0;
+}
+
+/* Get the compilation directory, if any is set.  */
+const char *
+__libdw_getcompdir (Dwarf_Die *cudie)
+{
+  Dwarf_Attribute compdir_attr_mem;
+  Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie,
+						      DW_AT_comp_dir,
+						      &compdir_attr_mem);
+  return INTUSE(dwarf_formstring) (compdir_attr);
+}
+
+int
+dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
+{
+  if (cudie == NULL)
+    return -1;
+  if (! is_cudie (cudie))
+    {
+      __libdw_seterrno (DWARF_E_NOT_CUDIE);
+      return -1;
+    }
+
+  /* Get the information if it is not already known.  */
+  struct Dwarf_CU *const cu = cudie->cu;
+  if (cu->lines == NULL)
+    {
+      /* Failsafe mode: no data found.  */
+      cu->lines = (void *) -1l;
+      cu->files = (void *) -1l;
+
+      /* The die must have a statement list associated.  */
+      Dwarf_Attribute stmt_list_mem;
+      Dwarf_Attribute *stmt_list = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list,
+						       &stmt_list_mem);
+
+      /* Get the offset into the .debug_line section.  NB: this call
+	 also checks whether the previous dwarf_attr call failed.  */
+      Dwarf_Off debug_line_offset;
+      if (__libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE,
+			   NULL, &debug_line_offset) == NULL)
+	return -1;
+
+      if (__libdw_getsrclines (cu->dbg, debug_line_offset,
+			       __libdw_getcompdir (cudie),
+			       cu->address_size, &cu->lines, &cu->files) < 0)
+	return -1;
+    }
+  else if (cu->lines == (void *) -1l)
+    return -1;
+
+  *lines = cu->lines;
+  *nlines = cu->lines->nlines;
+
+  // XXX Eventually: unlocking here.
+
+  return 0;
+}
+INTDEF(dwarf_getsrclines)
diff --git a/third_party/elfutils/libdw/dwarf_getstring.c b/third_party/elfutils/libdw/dwarf_getstring.c
new file mode 100644
index 0000000..5620cb0
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_getstring.c
@@ -0,0 +1,63 @@
+/* Get string.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libdwP.h"
+
+
+const char *
+dwarf_getstring (Dwarf *dbg, Dwarf_Off offset, size_t *lenp)
+{
+  if (dbg == NULL)
+    return NULL;
+
+  if (dbg->sectiondata[IDX_debug_str] == NULL
+      || offset >= dbg->sectiondata[IDX_debug_str]->d_size)
+    {
+    no_string:
+      __libdw_seterrno (DWARF_E_NO_STRING);
+      return NULL;
+    }
+
+  const char *result = ((const char *) dbg->sectiondata[IDX_debug_str]->d_buf
+			+ offset);
+  const char *endp = memchr (result, '\0',
+			     dbg->sectiondata[IDX_debug_str]->d_size - offset);
+  if (endp == NULL)
+    goto no_string;
+
+  if (lenp != NULL)
+    *lenp = endp - result;
+
+  return result;
+}
diff --git a/third_party/elfutils/libdw/dwarf_hasattr.c b/third_party/elfutils/libdw/dwarf_hasattr.c
new file mode 100644
index 0000000..90b333e
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_hasattr.c
@@ -0,0 +1,71 @@
+/* Check whether given DIE has specific attribute.
+   Copyright (C) 2003, 2005, 2014, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_hasattr (Dwarf_Die *die, unsigned int search_name)
+{
+  if (die == NULL)
+    return 0;
+
+  /* Find the abbreviation entry.  */
+  Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL);
+  if (unlikely (abbrevp == DWARF_END_ABBREV))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return 0;
+    }
+
+  /* Search the name attribute.  Dwarf_Abbrev was checked when created,
+     so we can read unchecked here.  */
+  const unsigned char *attrp = abbrevp->attrp;
+  while (1)
+    {
+      /* Get attribute name and form.  */
+      unsigned int attr_name;
+      get_uleb128_unchecked (attr_name, attrp);
+      unsigned int attr_form;
+      get_uleb128_unchecked (attr_form, attrp);
+
+      /* We can stop if we found the attribute with value zero.  */
+      if (attr_name == 0 || attr_form == 0)
+	return 0;
+
+      if (attr_name == search_name)
+	return 1;
+    }
+}
+INTDEF (dwarf_hasattr)
diff --git a/third_party/elfutils/libdw/dwarf_hasattr_integrate.c b/third_party/elfutils/libdw/dwarf_hasattr_integrate.c
new file mode 100644
index 0000000..2d5348c
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_hasattr_integrate.c
@@ -0,0 +1,59 @@
+/* Check whether DIE has specific attribute, integrating DW_AT_abstract_origin.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+int
+dwarf_hasattr_integrate (Dwarf_Die *die, unsigned int search_name)
+{
+  Dwarf_Die die_mem;
+
+  do
+    {
+      if (INTUSE(dwarf_hasattr) (die, search_name))
+	return 1;
+
+      Dwarf_Attribute attr_mem;
+      Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_abstract_origin,
+						  &attr_mem);
+      if (attr == NULL)
+	attr = INTUSE(dwarf_attr) (die, DW_AT_specification, &attr_mem);
+      if (attr == NULL)
+	break;
+
+      die = INTUSE(dwarf_formref_die) (attr, &die_mem);
+    }
+  while (die != NULL);
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_haschildren.c b/third_party/elfutils/libdw/dwarf_haschildren.c
new file mode 100644
index 0000000..03a8173
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_haschildren.c
@@ -0,0 +1,51 @@
+/* Return string associated with given attribute.
+   Copyright (C) 2003, 2005, 2008, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <string.h>
+
+
+int
+dwarf_haschildren (Dwarf_Die *die)
+{
+  /* Find the abbreviation entry.  */
+  Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL);
+  if (unlikely (abbrevp == DWARF_END_ABBREV))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return -1;
+    }
+
+  return abbrevp->has_children;
+}
+INTDEF (dwarf_haschildren)
diff --git a/third_party/elfutils/libdw/dwarf_hasform.c b/third_party/elfutils/libdw/dwarf_hasform.c
new file mode 100644
index 0000000..a0c3229
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_hasform.c
@@ -0,0 +1,45 @@
+/* Check whether given attribute has specific form.
+   Copyright (C) 2003 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_hasform (Dwarf_Attribute *attr, unsigned int search_form)
+{
+  if (attr == NULL)
+    return 0;
+
+  return attr->form == search_form;
+}
diff --git a/third_party/elfutils/libdw/dwarf_haspc.c b/third_party/elfutils/libdw/dwarf_haspc.c
new file mode 100644
index 0000000..47e2b05
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_haspc.c
@@ -0,0 +1,54 @@
+/* Determine whether a DIE covers a PC address.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+int
+dwarf_haspc (Dwarf_Die *die, Dwarf_Addr pc)
+{
+  if (die == NULL)
+    return -1;
+
+  Dwarf_Addr base;
+  Dwarf_Addr begin;
+  Dwarf_Addr end;
+  ptrdiff_t offset = 0;
+  while ((offset = INTUSE(dwarf_ranges) (die, offset, &base,
+					 &begin, &end)) > 0)
+    if (pc >= begin && pc < end)
+      return 1;
+
+  return offset;
+}
+INTDEF (dwarf_haspc)
diff --git a/third_party/elfutils/libdw/dwarf_highpc.c b/third_party/elfutils/libdw/dwarf_highpc.c
new file mode 100644
index 0000000..2070254
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_highpc.c
@@ -0,0 +1,66 @@
+/* Return high PC attribute of DIE.
+   Copyright (C) 2003, 2005, 2012 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_highpc (Dwarf_Die *die, Dwarf_Addr *return_addr)
+{
+  Dwarf_Attribute attr_high_mem;
+  Dwarf_Attribute *attr_high = INTUSE(dwarf_attr) (die, DW_AT_high_pc,
+						   &attr_high_mem);
+  if (attr_high == NULL)
+    return -1;
+
+  if (attr_high->form == DW_FORM_addr)
+    return INTUSE(dwarf_formaddr) (attr_high, return_addr);
+
+  /* DWARF 4 allows high_pc to be a constant offset from low_pc. */
+  Dwarf_Attribute attr_low_mem;
+  if (INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (die, DW_AT_low_pc,
+						  &attr_low_mem),
+			      return_addr) == 0)
+    {
+      Dwarf_Word uval;
+      if (INTUSE(dwarf_formudata) (attr_high, &uval) == 0)
+	{
+	  *return_addr += uval;
+	  return 0;
+	}
+      __libdw_seterrno (DWARF_E_NO_ADDR);
+    }
+  return -1;
+}
+INTDEF(dwarf_highpc)
diff --git a/third_party/elfutils/libdw/dwarf_line_file.c b/third_party/elfutils/libdw/dwarf_line_file.c
new file mode 100644
index 0000000..e2df642
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_line_file.c
@@ -0,0 +1,52 @@
+/* Find line information for address.
+   Copyright (C) 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_line_file (Dwarf_Line *line, Dwarf_Files **files, size_t *idx)
+{
+  if (line == NULL)
+    return -1;
+
+  if (line->file >= line->files->nfiles)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return -1;
+    }
+
+  *files = line->files;
+  *idx = line->file;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_lineaddr.c b/third_party/elfutils/libdw/dwarf_lineaddr.c
new file mode 100644
index 0000000..4e1952d
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_lineaddr.c
@@ -0,0 +1,46 @@
+/* Return line address.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp)
+{
+  if (line == NULL)
+    return -1;
+
+  *addrp =  line->addr;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_linebeginstatement.c b/third_party/elfutils/libdw/dwarf_linebeginstatement.c
new file mode 100644
index 0000000..4854c56
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_linebeginstatement.c
@@ -0,0 +1,46 @@
+/* Return true if record is for beginning of a statement.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_linebeginstatement (Dwarf_Line *line, bool *flagp)
+{
+  if (line == NULL)
+    return -1;
+
+  *flagp =  line->is_stmt;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_lineblock.c b/third_party/elfutils/libdw/dwarf_lineblock.c
new file mode 100644
index 0000000..e3c7f41
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_lineblock.c
@@ -0,0 +1,46 @@
+/* Return true if record is for beginning of a basic block.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_lineblock (Dwarf_Line *line, bool *flagp)
+{
+  if (line == NULL)
+    return -1;
+
+  *flagp =  line->basic_block;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_linecol.c b/third_party/elfutils/libdw/dwarf_linecol.c
new file mode 100644
index 0000000..c667b1b
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_linecol.c
@@ -0,0 +1,46 @@
+/* Return column in line.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_linecol (Dwarf_Line *line, int *colp)
+{
+  if (line == NULL)
+    return -1;
+
+  *colp =  line->column;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_linediscriminator.c b/third_party/elfutils/libdw/dwarf_linediscriminator.c
new file mode 100644
index 0000000..552205a
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_linediscriminator.c
@@ -0,0 +1,45 @@
+/* Return code path discriminator in line record.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_linediscriminator (Dwarf_Line *line, unsigned int *discp)
+{
+  if (line == NULL)
+    return -1;
+
+  *discp = line->discriminator;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_lineendsequence.c b/third_party/elfutils/libdw/dwarf_lineendsequence.c
new file mode 100644
index 0000000..61bde93
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_lineendsequence.c
@@ -0,0 +1,46 @@
+/* Return true if record is for end of sequence.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_lineendsequence (Dwarf_Line *line, bool *flagp)
+{
+  if (line == NULL)
+    return -1;
+
+  *flagp =  line->end_sequence;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_lineepiloguebegin.c b/third_party/elfutils/libdw/dwarf_lineepiloguebegin.c
new file mode 100644
index 0000000..b914787
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_lineepiloguebegin.c
@@ -0,0 +1,46 @@
+/* Return true if record is for beginning of epilogue.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_lineepiloguebegin (Dwarf_Line *line, bool *flagp)
+{
+  if (line == NULL)
+    return -1;
+
+  *flagp =  line->epilogue_begin;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_lineisa.c b/third_party/elfutils/libdw/dwarf_lineisa.c
new file mode 100644
index 0000000..30181fc
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_lineisa.c
@@ -0,0 +1,45 @@
+/* Return ISA in line.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_lineisa (Dwarf_Line *line, unsigned int *isap)
+{
+  if (line == NULL)
+    return -1;
+
+  *isap = line->isa;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_lineno.c b/third_party/elfutils/libdw/dwarf_lineno.c
new file mode 100644
index 0000000..009999c
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_lineno.c
@@ -0,0 +1,46 @@
+/* Return line number.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_lineno (Dwarf_Line *line, int *linep)
+{
+  if (line == NULL)
+    return -1;
+
+  *linep =  line->line;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_lineop_index.c b/third_party/elfutils/libdw/dwarf_lineop_index.c
new file mode 100644
index 0000000..9ea4ef4
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_lineop_index.c
@@ -0,0 +1,45 @@
+/* Return line VLIW operation index.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_lineop_index (Dwarf_Line *line, unsigned int *idxp)
+{
+  if (line == NULL)
+    return -1;
+
+  *idxp = line->op_index;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_lineprologueend.c b/third_party/elfutils/libdw/dwarf_lineprologueend.c
new file mode 100644
index 0000000..6ba8be2
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_lineprologueend.c
@@ -0,0 +1,46 @@
+/* Return true if record is for end of prologue.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_lineprologueend (Dwarf_Line *line, bool *flagp)
+{
+  if (line == NULL)
+    return -1;
+
+  *flagp =  line->prologue_end;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_linesrc.c b/third_party/elfutils/libdw/dwarf_linesrc.c
new file mode 100644
index 0000000..27b5990
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_linesrc.c
@@ -0,0 +1,56 @@
+/* Find line information for address.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+const char *
+dwarf_linesrc (Dwarf_Line *line, Dwarf_Word *mtime, Dwarf_Word *length)
+{
+  if (line == NULL)
+    return NULL;
+
+  if (line->file >= line->files->nfiles)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  if (mtime != NULL)
+    *mtime = line->files->info[line->file].mtime;
+
+  if (length != NULL)
+    *length = line->files->info[line->file].length;
+
+  return line->files->info[line->file].name;
+}
diff --git a/third_party/elfutils/libdw/dwarf_lowpc.c b/third_party/elfutils/libdw/dwarf_lowpc.c
new file mode 100644
index 0000000..b3be2b0
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_lowpc.c
@@ -0,0 +1,47 @@
+/* Return low PC attribute of DIE.
+   Copyright (C) 2003, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_lowpc (Dwarf_Die *die, Dwarf_Addr *return_addr)
+{
+  Dwarf_Attribute attr_mem;
+
+  return INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (die, DW_AT_low_pc,
+						     &attr_mem),
+				 return_addr);
+}
+INTDEF(dwarf_lowpc)
diff --git a/third_party/elfutils/libdw/dwarf_macro_getparamcnt.c b/third_party/elfutils/libdw/dwarf_macro_getparamcnt.c
new file mode 100644
index 0000000..e218eb1
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_macro_getparamcnt.c
@@ -0,0 +1,43 @@
+/* Return number of parameters of a macro.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+int
+dwarf_macro_getparamcnt (Dwarf_Macro *macro, size_t *paramcntp)
+{
+  if (macro == NULL)
+    return -1;
+
+  *paramcntp = libdw_macro_nforms (macro);
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_macro_getsrcfiles.c b/third_party/elfutils/libdw/dwarf_macro_getsrcfiles.c
new file mode 100644
index 0000000..3b1794b
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_macro_getsrcfiles.c
@@ -0,0 +1,86 @@
+/* Find line information for a given macro.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+int
+dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
+			 Dwarf_Files **files, size_t *nfiles)
+{
+  /* macro is declared NN */
+  Dwarf_Macro_Op_Table *const table = macro->table;
+  if (table->files == NULL)
+    {
+      Dwarf_Off line_offset = table->line_offset;
+      if (line_offset == (Dwarf_Off) -1)
+	{
+	  *files = NULL;
+	  *nfiles = 0;
+	  return 0;
+	}
+
+      /* If TABLE->comp_dir is NULL that could mean any of the
+	 following:
+
+	 - The macro unit is not bound to a CU.  It's an auxiliary
+           unit used purely for import from other units.  In that case
+           there's actually no COMP_DIR value that we could use.
+
+	 - The macro unit is bound to a CU, but there's no
+           DW_AT_comp_dir attribute at the CU DIE.
+
+	 - The macro unit is bound to a CU, but we don't know that,
+           likely because its iteration was requested through
+           dwarf_getmacros_off interface.  This might be legitimate if
+           one macro unit imports another CU's macro unit, but that is
+           unlikely to happen in practice.  Most probably this is not
+           legitimate use of the interfaces.
+
+	 So when the interfaces are used correctly, COMP_DIR value is
+	 always right.  That means that we can cache the parsed
+	 .debug_line unit without fear that later on someone requests
+	 the same unit through dwarf_getsrcfiles, and the file names
+	 will be broken.  */
+
+      if (__libdw_getsrclines (dbg, line_offset, table->comp_dir,
+			       table->is_64bit ? 8 : 4,
+			       NULL, &table->files) < 0)
+	table->files = (void *) -1;
+    }
+
+  if (table->files == (void *) -1)
+    return -1;
+
+  *files = table->files;
+  *nfiles = table->files->nfiles;
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_macro_opcode.c b/third_party/elfutils/libdw/dwarf_macro_opcode.c
new file mode 100644
index 0000000..8607777
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_macro_opcode.c
@@ -0,0 +1,46 @@
+/* Return macro opcode.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_macro_opcode (Dwarf_Macro *macro, unsigned int *opcodep)
+{
+  if (macro == NULL)
+    return -1;
+
+  *opcodep = macro->opcode;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_macro_param.c b/third_party/elfutils/libdw/dwarf_macro_param.c
new file mode 100644
index 0000000..bd846a7
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_macro_param.c
@@ -0,0 +1,46 @@
+/* Return a given parameter of a macro.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+int
+dwarf_macro_param (Dwarf_Macro *macro, size_t idx, Dwarf_Attribute *ret)
+{
+  if (macro == NULL)
+    return -1;
+
+  if (idx >= libdw_macro_nforms (macro))
+    return -1;
+
+  *ret = macro->attributes[idx];
+  return 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_macro_param1.c b/third_party/elfutils/libdw/dwarf_macro_param1.c
new file mode 100644
index 0000000..87ce003
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_macro_param1.c
@@ -0,0 +1,48 @@
+/* Return first macro parameter.
+   Copyright (C) 2005, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_macro_param1 (Dwarf_Macro *macro, Dwarf_Word *paramp)
+{
+  if (macro == NULL)
+    return -1;
+
+  Dwarf_Attribute param;
+  if (dwarf_macro_param (macro, 0, &param) != 0)
+    return -1;
+
+  return dwarf_formudata (&param, paramp);
+}
diff --git a/third_party/elfutils/libdw/dwarf_macro_param2.c b/third_party/elfutils/libdw/dwarf_macro_param2.c
new file mode 100644
index 0000000..cc902c9
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_macro_param2.c
@@ -0,0 +1,55 @@
+/* Return second macro parameter.
+   Copyright (C) 2005, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_macro_param2 (Dwarf_Macro *macro, Dwarf_Word *paramp, const char **strp)
+{
+  if (macro == NULL)
+    return -1;
+
+  Dwarf_Attribute param;
+  if (dwarf_macro_param (macro, 1, &param) != 0)
+    return -1;
+
+  if (param.form == DW_FORM_string
+      || param.form == DW_FORM_strp)
+    {
+      *strp = dwarf_formstring (&param);
+      return 0;
+    }
+  else
+    return dwarf_formudata (&param, paramp);
+}
diff --git a/third_party/elfutils/libdw/dwarf_next_cfi.c b/third_party/elfutils/libdw/dwarf_next_cfi.c
new file mode 100644
index 0000000..53fc369
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_next_cfi.c
@@ -0,0 +1,245 @@
+/* Advance to next CFI entry.
+   Copyright (C) 2009-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include "encoded-value.h"
+
+#include <string.h>
+
+
+int
+dwarf_next_cfi (const unsigned char e_ident[],
+		Elf_Data *data,
+		bool eh_frame_p,
+		Dwarf_Off off,
+		Dwarf_Off *next_off,
+		Dwarf_CFI_Entry *entry)
+{
+  /* Dummy struct for memory-access.h macros.  */
+  BYTE_ORDER_DUMMY (dw, e_ident);
+
+  /* If we reached the end before don't do anything.  */
+  if (off == (Dwarf_Off) -1l
+      /* Make sure there is enough space in the .debug_frame section
+	 for at least the initial word.  We cannot test the rest since
+	 we don't know yet whether this is a 64-bit object or not.  */
+      || unlikely (off + 4 >= data->d_size))
+    {
+      *next_off = (Dwarf_Off) -1l;
+      return 1;
+    }
+
+  /* This points into the .debug_frame section at the start of the entry.  */
+  const uint8_t *bytes = data->d_buf + off;
+  const uint8_t *limit = data->d_buf + data->d_size;
+
+  /* The format of a CFI entry is described in DWARF3 6.4.1:
+   */
+
+  uint64_t length = read_4ubyte_unaligned_inc (&dw, bytes);
+  size_t offset_size = 4;
+  if (length == DWARF3_LENGTH_64_BIT)
+    {
+      /* This is the 64-bit DWARF format.  */
+      offset_size = 8;
+      if (unlikely (limit - bytes < 8))
+	{
+	invalid:
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  return -1;
+	}
+      length = read_8ubyte_unaligned_inc (&dw, bytes);
+    }
+  if (unlikely ((uint64_t) (limit - bytes) < length)
+      || unlikely (length < offset_size + 1))
+    goto invalid;
+
+  /* Now we know how large the entry is.  Note the trick in the
+     computation.  If the offset_size is 4 the '- 4' term undoes the
+     '2 *'.  If offset_size is 8 this term computes the size of the
+     escape value plus the 8 byte offset.  */
+  *next_off = off + (2 * offset_size - 4) + length;
+
+  limit = bytes + length;
+
+  const uint8_t *const cie_pointer_start = bytes;
+  if (offset_size == 8)
+    entry->cie.CIE_id = read_8ubyte_unaligned_inc (&dw, bytes);
+  else
+    {
+      entry->cie.CIE_id = read_4ubyte_unaligned_inc (&dw, bytes);
+      /* Canonicalize the 32-bit CIE_ID value to 64 bits.  */
+      if (!eh_frame_p && entry->cie.CIE_id == DW_CIE_ID_32)
+	entry->cie.CIE_id = DW_CIE_ID_64;
+    }
+  if (eh_frame_p)
+    {
+      /* Canonicalize the .eh_frame CIE pointer to .debug_frame format.  */
+      if (entry->cie.CIE_id == 0)
+	entry->cie.CIE_id = DW_CIE_ID_64;
+      else
+	{
+	  /* In .eh_frame format, a CIE pointer is the distance from where
+	     it appears back to the beginning of the CIE.  */
+	  ptrdiff_t pos = cie_pointer_start - (const uint8_t *) data->d_buf;
+	  if (unlikely (entry->cie.CIE_id > (Dwarf_Off) pos)
+	      || unlikely (pos <= (ptrdiff_t) offset_size))
+	    goto invalid;
+	  entry->cie.CIE_id = pos - entry->cie.CIE_id;
+	}
+    }
+
+  if (entry->cie.CIE_id == DW_CIE_ID_64)
+    {
+      /* Read the version stamp.  Always an 8-bit value.  */
+      uint8_t version = *bytes++;
+
+      if (version != 1 && (unlikely (version < 3) || unlikely (version > 4)))
+	goto invalid;
+
+      entry->cie.augmentation = (const char *) bytes;
+
+      bytes = memchr (bytes, '\0', limit - bytes);
+      if (unlikely (bytes == NULL))
+	goto invalid;
+      ++bytes;
+
+      /* The address size for CFI is implicit in the ELF class.  */
+      uint_fast8_t address_size = e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+      uint_fast8_t segment_size = 0;
+      if (version >= 4)
+	{
+	  if (unlikely (limit - bytes < 5))
+	    goto invalid;
+	  /* XXX We don't actually support address_size not matching the class.
+	     To do so, we'd have to return it here so that intern_new_cie
+	     could use it choose a specific fde_encoding.  */
+	  if (unlikely (*bytes != address_size))
+	    {
+	      __libdw_seterrno (DWARF_E_VERSION);
+	      return -1;
+	    }
+	  address_size = *bytes++;
+	  segment_size = *bytes++;
+	  /* We don't actually support segment selectors.  We'd have to
+	     roll this into the fde_encoding bits or something.  */
+	  if (unlikely (segment_size != 0))
+	    {
+	      __libdw_seterrno (DWARF_E_VERSION);
+	      return -1;
+	    }
+	}
+
+      const char *ap = entry->cie.augmentation;
+
+      /* g++ v2 "eh" has pointer immediately following augmentation string,
+	 so it must be handled first.  */
+      if (unlikely (ap[0] == 'e' && ap[1] == 'h'))
+	{
+	  ap += 2;
+	  bytes += address_size;
+	}
+
+      if (bytes >= limit)
+	goto invalid;
+      get_uleb128 (entry->cie.code_alignment_factor, bytes, limit);
+
+      if (bytes >= limit)
+	goto invalid;
+      get_sleb128 (entry->cie.data_alignment_factor, bytes, limit);
+
+      if (bytes >= limit)
+	goto invalid;
+
+      if (version >= 3)		/* DWARF 3+ */
+	get_uleb128 (entry->cie.return_address_register, bytes, limit);
+      else			/* DWARF 2 */
+	entry->cie.return_address_register = *bytes++;
+
+      /* If we have sized augmentation data,
+	 we don't need to grok it all.  */
+      entry->cie.fde_augmentation_data_size = 0;
+      bool sized_augmentation = *ap == 'z';
+      if (sized_augmentation)
+	{
+	  if (bytes >= limit)
+	    goto invalid;
+	  get_uleb128 (entry->cie.augmentation_data_size, bytes, limit);
+	  if ((Dwarf_Word) (limit - bytes) < entry->cie.augmentation_data_size)
+	    goto invalid;
+	  entry->cie.augmentation_data = bytes;
+	  bytes += entry->cie.augmentation_data_size;
+	}
+      else
+	{
+	  entry->cie.augmentation_data = bytes;
+
+	  for (; *ap != '\0'; ++ap)
+	    {
+	      uint8_t encoding;
+	      switch (*ap)
+		{
+		case 'L':		/* Skip LSDA pointer encoding byte.  */
+		case 'R':		/* Skip FDE address encoding byte.  */
+		  encoding = *bytes++;
+		  entry->cie.fde_augmentation_data_size
+		    += encoded_value_size (data, e_ident, encoding, NULL);
+		  continue;
+		case 'P':   /* Skip encoded personality routine pointer. */
+		  encoding = *bytes++;
+		  bytes += encoded_value_size (data, e_ident, encoding, bytes);
+		  continue;
+		case 'S':		/* Skip signal-frame flag.  */
+		  continue;
+		default:
+		  /* Unknown augmentation string.  initial_instructions might
+		     actually start with some augmentation data.  */
+		  break;
+		}
+	      break;
+	    }
+	  entry->cie.augmentation_data_size
+	    = bytes - entry->cie.augmentation_data;
+	}
+
+      entry->cie.initial_instructions = bytes;
+      entry->cie.initial_instructions_end = limit;
+    }
+  else
+    {
+      entry->fde.start = bytes;
+      entry->fde.end = limit;
+    }
+
+  return 0;
+}
+INTDEF (dwarf_next_cfi)
diff --git a/third_party/elfutils/libdw/dwarf_nextcu.c b/third_party/elfutils/libdw/dwarf_nextcu.c
new file mode 100644
index 0000000..fa9b0af
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_nextcu.c
@@ -0,0 +1,186 @@
+/* Advance to next CU header.
+   Copyright (C) 2002-2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwP.h>
+#include <dwarf.h>
+
+
+int
+dwarf_next_unit (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
+		 size_t *header_sizep, Dwarf_Half *versionp,
+		 Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep,
+		 uint8_t *offset_sizep, uint64_t *type_signaturep,
+		 Dwarf_Off *type_offsetp)
+{
+  const bool debug_types = type_signaturep != NULL;
+  const size_t sec_idx = debug_types ? IDX_debug_types : IDX_debug_info;
+
+  /* Maybe there has been an error before.  */
+  if (dwarf == NULL)
+    return -1;
+
+  /* If we reached the end before don't do anything.  */
+  if (off == (Dwarf_Off) -1l
+      || unlikely (dwarf->sectiondata[sec_idx] == NULL)
+      /* Make sure there is enough space in the .debug_info section
+	 for at least the initial word.  We cannot test the rest since
+	 we don't know yet whether this is a 64-bit object or not.  */
+      || unlikely (off + 4 >= dwarf->sectiondata[sec_idx]->d_size))
+    {
+      *next_off = (Dwarf_Off) -1l;
+      return 1;
+    }
+
+  /* This points into the .debug_info section to the beginning of the
+     CU entry.  */
+  const unsigned char *data = dwarf->sectiondata[sec_idx]->d_buf;
+  const unsigned char *bytes = data + off;
+
+  /* The format of the CU header is described in dwarf2p1 7.5.1:
+
+     1.  A 4-byte or 12-byte unsigned integer representing the length
+	 of the .debug_info contribution for that compilation unit, not
+	 including the length field itself. In the 32-bit DWARF format,
+	 this is a 4-byte unsigned integer (which must be less than
+	 0xfffffff0); in the 64-bit DWARF format, this consists of the
+	 4-byte value 0xffffffff followed by an 8-byte unsigned integer
+	 that gives the actual length (see Section 7.2.2).
+
+      2. A 2-byte unsigned integer representing the version of the
+	 DWARF information for that compilation unit. For DWARF Version
+	 2.1, the value in this field is 2.
+
+      3. A 4-byte or 8-byte unsigned offset into the .debug_abbrev
+	 section. This offset associates the compilation unit with a
+	 particular set of debugging information entry abbreviations. In
+	 the 32-bit DWARF format, this is a 4-byte unsigned length; in
+	 the 64-bit DWARF format, this is an 8-byte unsigned length (see
+	 Section 7.4).
+
+      4. A 1-byte unsigned integer representing the size in bytes of
+	 an address on the target architecture. If the system uses
+	 segmented addressing, this value represents the size of the
+	 offset portion of an address.  */
+  uint64_t length = read_4ubyte_unaligned_inc (dwarf, bytes);
+  size_t offset_size = 4;
+  /* Lengths of 0xfffffff0 - 0xffffffff are escape codes.  Oxffffffff is
+     used to indicate that 64-bit dwarf information is being used, the
+     other values are currently reserved.  */
+  if (length == DWARF3_LENGTH_64_BIT)
+    offset_size = 8;
+  else if (unlikely (length >= DWARF3_LENGTH_MIN_ESCAPE_CODE
+		     && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE))
+    {
+    invalid:
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return -1;
+    }
+
+  /* Now we know how large the header is.  */
+  if (unlikely (DIE_OFFSET_FROM_CU_OFFSET (off, offset_size, debug_types)
+		>= dwarf->sectiondata[sec_idx]->d_size))
+    {
+      *next_off = -1;
+      return 1;
+    }
+
+  if (length == DWARF3_LENGTH_64_BIT)
+    /* This is a 64-bit DWARF format.  */
+    length = read_8ubyte_unaligned_inc (dwarf, bytes);
+
+  /* Read the version stamp.  Always a 16-bit value.  */
+  uint_fast16_t version = read_2ubyte_unaligned_inc (dwarf, bytes);
+
+  /* Get offset in .debug_abbrev.  Note that the size of the entry
+     depends on whether this is a 32-bit or 64-bit DWARF definition.  */
+  uint64_t abbrev_offset;
+  if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size,
+			       &abbrev_offset, IDX_debug_abbrev, 0))
+    return -1;
+
+  /* The address size.  Always an 8-bit value.  */
+  uint8_t address_size = *bytes++;
+
+  if (debug_types)
+    {
+      uint64_t type_sig8 = read_8ubyte_unaligned_inc (dwarf, bytes);
+
+      Dwarf_Off type_offset;
+      if (__libdw_read_offset_inc (dwarf, sec_idx, &bytes, offset_size,
+				   &type_offset, sec_idx, 0))
+	return -1;
+
+      /* Validate that the TYPE_OFFSET points past the header.  */
+      if (unlikely (type_offset < (size_t) (bytes - (data + off))))
+	goto invalid;
+
+      *type_signaturep = type_sig8;
+      if (type_offsetp != NULL)
+	*type_offsetp = type_offset;
+    }
+
+  /* Store the header length.  */
+  if (header_sizep != NULL)
+    *header_sizep = bytes - (data + off);
+
+  if (versionp != NULL)
+    *versionp = version;
+
+  if (abbrev_offsetp != NULL)
+    *abbrev_offsetp = abbrev_offset;
+
+  if (address_sizep != NULL)
+    *address_sizep = address_size;
+
+  /* Store the offset size.  */
+  if (offset_sizep != NULL)
+    *offset_sizep = offset_size;
+
+  /* See definition of DIE_OFFSET_FROM_CU_OFFSET macro
+     for an explanation of the trick in this expression.  */
+  *next_off = off + 2 * offset_size - 4 + length;
+
+  return 0;
+}
+INTDEF(dwarf_next_unit)
+
+int
+dwarf_nextcu (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
+	      size_t *header_sizep, Dwarf_Off *abbrev_offsetp,
+	      uint8_t *address_sizep, uint8_t *offset_sizep)
+{
+  return INTUSE(dwarf_next_unit) (dwarf, off, next_off, header_sizep, NULL,
+				  abbrev_offsetp, address_sizep, offset_sizep,
+				  NULL, NULL);
+}
+INTDEF(dwarf_nextcu)
diff --git a/third_party/elfutils/libdw/dwarf_offabbrev.c b/third_party/elfutils/libdw/dwarf_offabbrev.c
new file mode 100644
index 0000000..27cdad6
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_offabbrev.c
@@ -0,0 +1,51 @@
+/* Get abbreviation at given offset.
+   Copyright (C) 2004, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+int
+dwarf_offabbrev (Dwarf *dbg, Dwarf_Off offset, size_t *lengthp,
+		 Dwarf_Abbrev *abbrevp)
+{
+  if (dbg == NULL)
+    return -1;
+
+  Dwarf_Abbrev *abbrev = __libdw_getabbrev (dbg, NULL, offset, lengthp,
+					    abbrevp);
+
+  if (abbrev == NULL)
+    return -1;
+
+  return abbrev == DWARF_END_ABBREV ? 1 : 0;
+}
diff --git a/third_party/elfutils/libdw/dwarf_offdie.c b/third_party/elfutils/libdw/dwarf_offdie.c
new file mode 100644
index 0000000..883720d
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_offdie.c
@@ -0,0 +1,84 @@
+/* Return DIE at given offset.
+   Copyright (C) 2002-2010, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libdwP.h"
+
+
+Dwarf_Die *
+internal_function
+__libdw_offdie (Dwarf *dbg, Dwarf_Off offset, Dwarf_Die *result,
+		bool debug_types)
+{
+  if (dbg == NULL)
+    return NULL;
+
+  Elf_Data *const data = dbg->sectiondata[debug_types ? IDX_debug_types
+					  : IDX_debug_info];
+  if (data == NULL || offset >= data->d_size)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  /* Clear the entire DIE structure.  This signals we have not yet
+     determined any of the information.  */
+  memset (result, '\0', sizeof (Dwarf_Die));
+
+  result->addr = (char *) data->d_buf + offset;
+
+  /* Get the CU.  */
+  result->cu = __libdw_findcu (dbg, offset, debug_types);
+  if (result->cu == NULL)
+    {
+      /* This should never happen.  The input file is malformed.  */
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      result = NULL;
+    }
+
+  return result;
+}
+
+
+Dwarf_Die *
+dwarf_offdie (Dwarf *dbg, Dwarf_Off offset, Dwarf_Die *result)
+{
+  return __libdw_offdie (dbg, offset, result, false);
+}
+INTDEF(dwarf_offdie)
+
+Dwarf_Die *
+dwarf_offdie_types (Dwarf *dbg, Dwarf_Off offset, Dwarf_Die *result)
+{
+  return __libdw_offdie (dbg, offset, result, true);
+}
diff --git a/third_party/elfutils/libdw/dwarf_onearange.c b/third_party/elfutils/libdw/dwarf_onearange.c
new file mode 100644
index 0000000..de49f6c
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_onearange.c
@@ -0,0 +1,50 @@
+/* Return one of the address range entries.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+Dwarf_Arange *
+dwarf_onearange (Dwarf_Aranges *aranges, size_t idx)
+{
+  if (aranges == NULL)
+    return NULL;
+
+  if (idx >= aranges->naranges)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_ARANGE_IDX);
+      return NULL;
+    }
+
+  return &aranges->info[idx];
+}
diff --git a/third_party/elfutils/libdw/dwarf_onesrcline.c b/third_party/elfutils/libdw/dwarf_onesrcline.c
new file mode 100644
index 0000000..5d3c3de
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_onesrcline.c
@@ -0,0 +1,50 @@
+/* Return one of the sources lines of a CU.
+   Copyright (C) 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+Dwarf_Line *
+dwarf_onesrcline (Dwarf_Lines *lines, size_t idx)
+{
+  if (lines == NULL)
+    return NULL;
+
+  if (idx >= lines->nlines)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_LINE_IDX);
+      return NULL;
+    }
+
+  return &lines->info[idx];
+}
diff --git a/third_party/elfutils/libdw/dwarf_peel_type.c b/third_party/elfutils/libdw/dwarf_peel_type.c
new file mode 100644
index 0000000..6bbfd42
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_peel_type.c
@@ -0,0 +1,75 @@
+/* Peel type aliases and qualifier tags from a type DIE.
+   Copyright (C) 2014, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+#include <string.h>
+
+
+int
+dwarf_peel_type (Dwarf_Die *die, Dwarf_Die *result)
+{
+  int tag;
+
+  /* Ignore previous errors.  */
+  if (die == NULL)
+    return -1;
+
+  *result = *die;
+  tag = INTUSE (dwarf_tag) (result);
+  while (tag == DW_TAG_typedef
+	 || tag == DW_TAG_const_type
+	 || tag == DW_TAG_volatile_type
+	 || tag == DW_TAG_restrict_type
+	 || tag == DW_TAG_atomic_type
+	 || tag == DW_TAG_immutable_type
+	 || tag == DW_TAG_packed_type
+	 || tag == DW_TAG_shared_type)
+    {
+      Dwarf_Attribute attr_mem;
+      Dwarf_Attribute *attr = INTUSE (dwarf_attr_integrate) (result, DW_AT_type,
+							     &attr_mem);
+      if (attr == NULL)
+	return 1;
+
+      if (INTUSE (dwarf_formref_die) (attr, result) == NULL)
+	return -1;
+
+      tag = INTUSE (dwarf_tag) (result);
+    }
+
+  if (tag == DW_TAG_invalid)
+    return -1;
+
+  return 0;
+}
+INTDEF(dwarf_peel_type)
diff --git a/third_party/elfutils/libdw/dwarf_ranges.c b/third_party/elfutils/libdw/dwarf_ranges.c
new file mode 100644
index 0000000..4b6853d
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_ranges.c
@@ -0,0 +1,193 @@
+/* Enumerate the PC ranges covered by a DIE.
+   Copyright (C) 2005, 2007, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+#include <assert.h>
+
+/* Read up begin/end pair and increment read pointer.
+    - If it's normal range record, set up `*beginp' and `*endp' and return 0.
+    - If it's base address selection record, set up `*basep' and return 1.
+    - If it's end of rangelist, don't set anything and return 2
+    - If an error occurs, don't set anything and return -1.  */
+internal_function int
+__libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
+				 unsigned char **addrp, int width,
+				 Dwarf_Addr *beginp, Dwarf_Addr *endp,
+				 Dwarf_Addr *basep)
+{
+  Dwarf_Addr escape = (width == 8 ? (Elf64_Addr) -1
+		       : (Elf64_Addr) (Elf32_Addr) -1);
+  Dwarf_Addr begin;
+  Dwarf_Addr end;
+
+  unsigned char *addr = *addrp;
+  bool begin_relocated = READ_AND_RELOCATE (__libdw_relocate_address, begin);
+  bool end_relocated = READ_AND_RELOCATE (__libdw_relocate_address, end);
+  *addrp = addr;
+
+  /* Unrelocated escape for begin means base address selection.  */
+  if (begin == escape && !begin_relocated)
+    {
+      if (unlikely (end == escape))
+	{
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  return -1;
+	}
+
+      if (basep != NULL)
+	*basep = end;
+      return 1;
+    }
+
+  /* Unrelocated pair of zeroes means end of range list.  */
+  if (begin == 0 && end == 0 && !begin_relocated && !end_relocated)
+    return 2;
+
+  /* Don't check for begin_relocated == end_relocated.  Serve the data
+     to the client even though it may be buggy.  */
+  *beginp = begin;
+  *endp = end;
+
+  return 0;
+}
+
+ptrdiff_t
+dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep,
+	      Dwarf_Addr *startp, Dwarf_Addr *endp)
+{
+  if (die == NULL)
+    return -1;
+
+  if (offset == 0
+      /* Usually there is a single contiguous range.  */
+      && INTUSE(dwarf_highpc) (die, endp) == 0
+      && INTUSE(dwarf_lowpc) (die, startp) == 0)
+    /* A offset into .debug_ranges will never be 1, it must be at least a
+       multiple of 4.  So we can return 1 as a special case value to mark
+       there are no ranges to look for on the next call.  */
+    return 1;
+
+  if (offset == 1)
+    return 0;
+
+  /* We have to look for a noncontiguous range.  */
+
+  const Elf_Data *d = die->cu->dbg->sectiondata[IDX_debug_ranges];
+  if (d == NULL && offset != 0)
+    {
+      __libdw_seterrno (DWARF_E_NO_DEBUG_RANGES);
+      return -1;
+    }
+
+  unsigned char *readp;
+  unsigned char *readendp;
+  if (offset == 0)
+    {
+      Dwarf_Attribute attr_mem;
+      Dwarf_Attribute *attr = INTUSE(dwarf_attr) (die, DW_AT_ranges,
+						  &attr_mem);
+      if (attr == NULL)
+	/* No PC attributes in this DIE at all, so an empty range list.  */
+	return 0;
+
+      Dwarf_Word start_offset;
+      if ((readp = __libdw_formptr (attr, IDX_debug_ranges,
+				    DWARF_E_NO_DEBUG_RANGES,
+				    &readendp, &start_offset)) == NULL)
+	return -1;
+
+      offset = start_offset;
+      assert ((Dwarf_Word) offset == start_offset);
+
+      /* Fetch the CU's base address.  */
+      Dwarf_Die cudie = CUDIE (attr->cu);
+
+      /* Find the base address of the compilation unit.  It will
+	 normally be specified by DW_AT_low_pc.  In DWARF-3 draft 4,
+	 the base address could be overridden by DW_AT_entry_pc.  It's
+	 been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc
+	 for compilation units with discontinuous ranges.  */
+      if (unlikely (INTUSE(dwarf_lowpc) (&cudie, basep) != 0)
+	  && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie,
+							 DW_AT_entry_pc,
+							 &attr_mem),
+				     basep) != 0)
+	*basep = (Dwarf_Addr) -1;
+    }
+  else
+    {
+      if (__libdw_offset_in_section (die->cu->dbg,
+				     IDX_debug_ranges, offset, 1))
+	return -1l;
+
+      readp = d->d_buf + offset;
+      readendp = d->d_buf + d->d_size;
+    }
+
+ next:
+  if (readendp - readp < die->cu->address_size * 2)
+    goto invalid;
+
+  Dwarf_Addr begin;
+  Dwarf_Addr end;
+
+  switch (__libdw_read_begin_end_pair_inc (die->cu->dbg, IDX_debug_ranges,
+					   &readp, die->cu->address_size,
+					   &begin, &end, basep))
+    {
+    case 0:
+      break;
+    case 1:
+      goto next;
+    case 2:
+      return 0;
+    default:
+      return -1l;
+    }
+
+  /* We have an address range entry.  Check that we have a base.  */
+  if (*basep == (Dwarf_Addr) -1)
+    {
+      if (INTUSE(dwarf_errno) () == 0)
+	{
+	invalid:
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	}
+      return -1;
+    }
+
+  *startp = *basep + begin;
+  *endp = *basep + end;
+  return readp - (unsigned char *) d->d_buf;
+}
+INTDEF (dwarf_ranges)
diff --git a/third_party/elfutils/libdw/dwarf_setalt.c b/third_party/elfutils/libdw/dwarf_setalt.c
new file mode 100644
index 0000000..9051b8e
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_setalt.c
@@ -0,0 +1,49 @@
+/* Provides the data referenced by the .gnu_debugaltlink section.
+   Copyright (C) 2014, 2018 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+#include <unistd.h>
+
+void
+dwarf_setalt (Dwarf *main, Dwarf *alt)
+{
+  if (main->alt_fd != -1)
+    {
+      INTUSE(dwarf_end) (main->alt_dwarf);
+      close (main->alt_fd);
+      main->alt_fd = -1;
+    }
+
+  main->alt_dwarf = alt;
+}
+INTDEF (dwarf_setalt)
diff --git a/third_party/elfutils/libdw/dwarf_siblingof.c b/third_party/elfutils/libdw/dwarf_siblingof.c
new file mode 100644
index 0000000..df39c1c
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_siblingof.c
@@ -0,0 +1,143 @@
+/* Return sibling of given DIE.
+   Copyright (C) 2003-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+#include <string.h>
+
+
+int
+dwarf_siblingof (Dwarf_Die *die, Dwarf_Die *result)
+{
+  /* Ignore previous errors.  */
+  if (die == NULL)
+    return -1;
+
+  /* result is declared NN */
+
+  if (result != die)
+    result->addr = NULL;
+
+  unsigned int level = 0;
+
+  /* Copy of the current DIE.  */
+  Dwarf_Die this_die = *die;
+  /* Temporary attributes we create.  */
+  Dwarf_Attribute sibattr;
+  /* Copy of the CU in the request.  */
+  sibattr.cu = this_die.cu;
+  /* That's the address we start looking.  */
+  unsigned char *addr = this_die.addr;
+  /* End of the buffer.  */
+  unsigned char *endp = sibattr.cu->endp;
+
+  /* Search for the beginning of the next die on this level.  We
+     must not return the dies for children of the given die.  */
+  do
+    {
+      /* Find the end of the DIE or the sibling attribute.  */
+      addr = __libdw_find_attr (&this_die, DW_AT_sibling, &sibattr.code,
+				&sibattr.form);
+      if (addr != NULL && sibattr.code == DW_AT_sibling)
+	{
+	  Dwarf_Off offset;
+	  sibattr.valp = addr;
+	  if (unlikely (__libdw_formref (&sibattr, &offset) != 0))
+	    /* Something went wrong.  */
+	    return -1;
+
+	  /* The sibling attribute should point after this DIE in the CU.
+	     But not after the end of the CU.  */
+	  size_t size = sibattr.cu->endp - sibattr.cu->startp;
+	  size_t die_off = this_die.addr - this_die.cu->startp;
+	  if (unlikely (offset >= size || offset <= die_off))
+	    {
+	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	      return -1;
+	    }
+
+	  /* Compute the next address.  */
+	  addr = sibattr.cu->startp + offset;
+	}
+      else if (unlikely (addr == NULL)
+	       || unlikely (this_die.abbrev == DWARF_END_ABBREV))
+	return -1;
+      else if (this_die.abbrev->has_children)
+	/* This abbreviation has children.  */
+	++level;
+
+
+      while (1)
+	{
+	  /* Make sure we are still in range.  Some producers might skip
+	     the trailing NUL bytes.  */
+	  if (addr >= endp)
+	    return 1;
+
+	  if (*addr != '\0')
+	    break;
+
+	  if (level-- == 0)
+	    {
+	      if (result != die)
+		result->addr = addr;
+	      /* No more sibling at all.  */
+	      return 1;
+	    }
+
+	  ++addr;
+	}
+
+      /* Initialize the 'current DIE'.  */
+      this_die.addr = addr;
+      this_die.abbrev = NULL;
+    }
+  while (level > 0);
+
+  /* Maybe we reached the end of the CU.  */
+  if (addr >= endp)
+    return 1;
+
+  /* Clear the entire DIE structure.  This signals we have not yet
+     determined any of the information.  */
+  memset (result, '\0', sizeof (Dwarf_Die));
+
+  /* We have the address.  */
+  result->addr = addr;
+
+  /* Same CU as the parent.  */
+  result->cu = sibattr.cu;
+
+  return 0;
+}
+INTDEF(dwarf_siblingof)
diff --git a/third_party/elfutils/libdw/dwarf_sig8_hash.c b/third_party/elfutils/libdw/dwarf_sig8_hash.c
new file mode 100644
index 0000000..043cac7
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_sig8_hash.c
@@ -0,0 +1,41 @@
+/* Implementation of hash table for DWARF .debug_types section content.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define NO_UNDEF
+#include "dwarf_sig8_hash.h"
+#undef NO_UNDEF
+
+/* This is defined in dwarf_abbrev_hash.c, we can just use it here.  */
+#define next_prime __libdwarf_next_prime
+extern size_t next_prime (size_t) attribute_hidden;
+
+#include <dynamicsizehash.c>
diff --git a/third_party/elfutils/libdw/dwarf_sig8_hash.h b/third_party/elfutils/libdw/dwarf_sig8_hash.h
new file mode 100644
index 0000000..705ffbc
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_sig8_hash.h
@@ -0,0 +1,38 @@
+/* Hash table for DWARF .debug_types section content.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _DWARF_SIG8_HASH_H
+#define _DWARF_SIG8_HASH_H	1
+
+#define NAME Dwarf_Sig8_Hash
+#define TYPE struct Dwarf_CU *
+#define COMPARE(a, b) (0)
+
+#include <dynamicsizehash.h>
+
+#endif	/* dwarf_sig8_hash.h */
diff --git a/third_party/elfutils/libdw/dwarf_srclang.c b/third_party/elfutils/libdw/dwarf_srclang.c
new file mode 100644
index 0000000..f10e764
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_srclang.c
@@ -0,0 +1,50 @@
+/* Return source language attribute of DIE.
+   Copyright (C) 2003-2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+int
+dwarf_srclang (Dwarf_Die *die)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Word value;
+
+  return INTUSE(dwarf_formudata) (INTUSE(dwarf_attr_integrate)
+				  (die, DW_AT_language, &attr_mem),
+				  &value) == 0 ? (int) value : -1;
+}
+INTDEF (dwarf_srclang)
+OLD_VERSION (dwarf_srclang, ELFUTILS_0.122)
+NEW_VERSION (dwarf_srclang, ELFUTILS_0.143)
diff --git a/third_party/elfutils/libdw/dwarf_tag.c b/third_party/elfutils/libdw/dwarf_tag.c
new file mode 100644
index 0000000..331eaa0
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_tag.c
@@ -0,0 +1,94 @@
+/* Return tag of given DIE.
+   Copyright (C) 2003-2011, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+
+
+Dwarf_Abbrev *
+internal_function
+__libdw_findabbrev (struct Dwarf_CU *cu, unsigned int code)
+{
+  Dwarf_Abbrev *abb;
+
+  /* Abbreviation code can never have a value of 0.  */
+  if (unlikely (code == 0))
+    return DWARF_END_ABBREV;
+
+  /* See whether the entry is already in the hash table.  */
+  abb = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code, NULL);
+  if (abb == NULL)
+    while (cu->last_abbrev_offset != (size_t) -1l)
+      {
+	size_t length;
+
+	/* Find the next entry.  It gets automatically added to the
+	   hash table.  */
+	abb = __libdw_getabbrev (cu->dbg, cu, cu->last_abbrev_offset, &length,
+				 NULL);
+	if (abb == NULL || abb == DWARF_END_ABBREV)
+	  {
+	    /* Make sure we do not try to search for it again.  */
+	    cu->last_abbrev_offset = (size_t) -1l;
+	    return DWARF_END_ABBREV;
+	  }
+
+	cu->last_abbrev_offset += length;
+
+	/* Is this the code we are looking for?  */
+	if (abb->code == code)
+	  break;
+      }
+
+  /* This is our second (or third, etc.) call to __libdw_findabbrev
+     and the code is invalid.  */
+  if (unlikely (abb == NULL))
+    abb = DWARF_END_ABBREV;
+
+  return abb;
+}
+
+
+int
+dwarf_tag (Dwarf_Die *die)
+{
+  /* Find the abbreviation entry.  */
+  Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL);
+  if (unlikely (abbrevp == DWARF_END_ABBREV))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return DW_TAG_invalid;
+    }
+
+  return abbrevp->tag;
+}
+INTDEF(dwarf_tag)
diff --git a/third_party/elfutils/libdw/dwarf_whatattr.c b/third_party/elfutils/libdw/dwarf_whatattr.c
new file mode 100644
index 0000000..d664b02
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_whatattr.c
@@ -0,0 +1,42 @@
+/* Return attribute code of given attribute.
+   Copyright (C) 2003 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+unsigned int
+dwarf_whatattr (Dwarf_Attribute *attr)
+{
+  return attr == NULL ? 0 : attr->code;
+}
diff --git a/third_party/elfutils/libdw/dwarf_whatform.c b/third_party/elfutils/libdw/dwarf_whatform.c
new file mode 100644
index 0000000..dee29a9
--- /dev/null
+++ b/third_party/elfutils/libdw/dwarf_whatform.c
@@ -0,0 +1,42 @@
+/* Return form code of given attribute.
+   Copyright (C) 2003 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include "libdwP.h"
+
+
+unsigned int
+dwarf_whatform (Dwarf_Attribute *attr)
+{
+  return attr == NULL ? 0 : attr->form;
+}
diff --git a/third_party/elfutils/libdw/encoded-value.h b/third_party/elfutils/libdw/encoded-value.h
new file mode 100644
index 0000000..f0df4ce
--- /dev/null
+++ b/third_party/elfutils/libdw/encoded-value.h
@@ -0,0 +1,232 @@
+/* DW_EH_PE_* support for libdw unwinder.
+   Copyright (C) 2009-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ENCODED_VALUE_H
+#define _ENCODED_VALUE_H 1
+
+#include <dwarf.h>
+#include <stdlib.h>
+#include "libdwP.h"
+#include "../libelf/common.h"
+
+
+/* Returns zero if the value is omitted, the encoding is unknown or
+   the (leb128) size cannot be determined.  */
+static size_t __attribute__ ((unused))
+encoded_value_size (const Elf_Data *data, const unsigned char e_ident[],
+		    uint8_t encoding, const uint8_t *p)
+{
+  if (encoding == DW_EH_PE_omit)
+    return 0;
+
+  switch (encoding & 0x07)
+    {
+    case DW_EH_PE_udata2:
+      return 2;
+    case DW_EH_PE_udata4:
+      return 4;
+    case DW_EH_PE_udata8:
+      return 8;
+
+    case DW_EH_PE_absptr:
+      return e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+
+    case DW_EH_PE_uleb128:
+      if (p != NULL)
+	{
+	  const uint8_t *end = p;
+	  while (end < (uint8_t *) data->d_buf + data->d_size)
+	    if (*end++ & 0x80u)
+	      return end - p;
+	}
+      return 0;
+
+    default:
+      return 0;
+    }
+}
+
+/* Returns zero when value was read successfully, minus one otherwise.  */
+static inline int __attribute__ ((unused))
+__libdw_cfi_read_address_inc (const Dwarf_CFI *cache,
+			      const unsigned char **addrp,
+			      int width, Dwarf_Addr *ret)
+{
+  width = width ?: cache->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+
+  if (cache->dbg != NULL)
+    return __libdw_read_address_inc (cache->dbg, IDX_debug_frame,
+				     addrp, width, ret);
+
+  /* Only .debug_frame might have relocation to consider.
+     Read plain values from .eh_frame data.  */
+
+  const unsigned char *endp = cache->data->d.d_buf + cache->data->d.d_size;
+  Dwarf eh_dbg = { .other_byte_order = MY_ELFDATA != cache->e_ident[EI_DATA] };
+
+  if (width == 4)
+    {
+      if (unlikely (*addrp + 4 > endp))
+	{
+	invalid_data:
+	  __libdw_seterrno (DWARF_E_INVALID_CFI);
+	  return -1;
+	}
+      *ret = read_4ubyte_unaligned_inc (&eh_dbg, *addrp);
+    }
+  else
+    {
+      if (unlikely (*addrp + 8 > endp))
+	goto invalid_data;
+      *ret = read_8ubyte_unaligned_inc (&eh_dbg, *addrp);
+    }
+  return 0;
+}
+
+/* Returns true on error, false otherwise. */
+static bool __attribute__ ((unused))
+read_encoded_value (const Dwarf_CFI *cache, uint8_t encoding,
+		    const uint8_t **p, Dwarf_Addr *result)
+{
+  *result = 0;
+  switch (encoding & 0x70)
+    {
+    case DW_EH_PE_absptr:
+      break;
+    case DW_EH_PE_pcrel:
+      *result = (cache->frame_vaddr
+		 + (*p - (const uint8_t *) cache->data->d.d_buf));
+      break;
+    case DW_EH_PE_textrel:
+      // ia64: segrel
+      *result = cache->textrel;
+      break;
+    case DW_EH_PE_datarel:
+      // i386: GOTOFF
+      // ia64: gprel
+      *result = cache->datarel;
+      break;
+    case DW_EH_PE_funcrel:	/* XXX */
+      break;
+    case DW_EH_PE_aligned:
+      {
+	const size_t size = encoded_value_size (&cache->data->d,
+						cache->e_ident,
+						encoding, *p);
+	if (unlikely (size == 0))
+	  return true;
+	size_t align = ((cache->frame_vaddr
+			 + (*p - (const uint8_t *) cache->data->d.d_buf))
+			& (size - 1));
+	if (align != 0)
+	  *p += size - align;
+	break;
+      }
+
+    default:
+      __libdw_seterrno (DWARF_E_INVALID_CFI);
+      return true;
+    }
+
+  Dwarf_Addr value = 0;
+  const unsigned char *endp = cache->data->d.d_buf + cache->data->d.d_size;
+  switch (encoding & 0x0f)
+    {
+    case DW_EH_PE_udata2:
+      if (unlikely (*p + 2 > endp))
+	{
+	invalid_data:
+	  __libdw_seterrno (DWARF_E_INVALID_CFI);
+	  return true;
+	}
+      value = read_2ubyte_unaligned_inc (cache, *p);
+      break;
+
+    case DW_EH_PE_sdata2:
+      if (unlikely (*p + 2 > endp))
+	goto invalid_data;
+      value = read_2sbyte_unaligned_inc (cache, *p);
+      break;
+
+    case DW_EH_PE_udata4:
+      if (unlikely (__libdw_cfi_read_address_inc (cache, p, 4, &value) != 0))
+	return true;
+      break;
+
+    case DW_EH_PE_sdata4:
+      if (unlikely (__libdw_cfi_read_address_inc (cache, p, 4, &value) != 0))
+	return true;
+      value = (Dwarf_Sword) (Elf32_Sword) value; /* Sign-extend.  */
+      break;
+
+    case DW_EH_PE_udata8:
+    case DW_EH_PE_sdata8:
+      if (unlikely (__libdw_cfi_read_address_inc (cache, p, 8, &value) != 0))
+	return true;
+      break;
+
+    case DW_EH_PE_absptr:
+      if (unlikely (__libdw_cfi_read_address_inc (cache, p, 0, &value) != 0))
+	return true;
+      break;
+
+    case DW_EH_PE_uleb128:
+      get_uleb128 (value, *p, endp);
+      break;
+
+    case DW_EH_PE_sleb128:
+      get_sleb128 (value, *p, endp);
+      break;
+
+    default:
+      __libdw_seterrno (DWARF_E_INVALID_CFI);
+      return true;
+    }
+
+  *result += value;
+
+  if (encoding & DW_EH_PE_indirect)
+    {
+      if (unlikely (*result < cache->frame_vaddr))
+	return true;
+      *result -= cache->frame_vaddr;
+      size_t ptrsize = encoded_value_size (NULL, cache->e_ident,
+					   DW_EH_PE_absptr, NULL);
+      if (unlikely (cache->data->d.d_size < ptrsize
+		    || *result > (cache->data->d.d_size - ptrsize)))
+	return true;
+      const uint8_t *ptr = cache->data->d.d_buf + *result;
+      if (unlikely (__libdw_cfi_read_address_inc (cache, &ptr, 0, result)
+		    != 0))
+	return true;
+    }
+
+  return false;
+}
+
+#endif	/* encoded-value.h */
diff --git a/third_party/elfutils/libdw/fde.c b/third_party/elfutils/libdw/fde.c
new file mode 100644
index 0000000..f5f6fbe
--- /dev/null
+++ b/third_party/elfutils/libdw/fde.c
@@ -0,0 +1,324 @@
+/* FDE reading.
+   Copyright (C) 2009-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include <search.h>
+#include <stdlib.h>
+
+#include "encoded-value.h"
+
+static int
+compare_fde (const void *a, const void *b)
+{
+  const struct dwarf_fde *fde1 = a;
+  const struct dwarf_fde *fde2 = b;
+
+  /* Find out which of the two arguments is the search value.
+     It has end offset 0.  */
+  if (fde1->end == 0)
+    {
+      if (fde1->start < fde2->start)
+	return -1;
+      if (fde1->start >= fde2->end)
+	return 1;
+    }
+  else
+    {
+      if (fde2->start < fde1->start)
+	return 1;
+      if (fde2->start >= fde1->end)
+	return -1;
+    }
+
+  return 0;
+}
+
+static struct dwarf_fde *
+intern_fde (Dwarf_CFI *cache, const Dwarf_FDE *entry)
+{
+  /* Look up the new entry's CIE.  */
+  struct dwarf_cie *cie = __libdw_find_cie (cache, entry->CIE_pointer);
+  if (cie == NULL)
+    return (void *) -1l;
+
+  struct dwarf_fde *fde = malloc (sizeof (struct dwarf_fde));
+  if (fde == NULL)
+    {
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return NULL;
+    }
+
+  fde->instructions = entry->start;
+  fde->instructions_end = entry->end;
+  if (unlikely (read_encoded_value (cache, cie->fde_encoding,
+				    &fde->instructions, &fde->start))
+      || unlikely (read_encoded_value (cache, cie->fde_encoding & 0x0f,
+				       &fde->instructions, &fde->end)))
+    {
+      free (fde);
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+  fde->end += fde->start;
+
+  /* Make sure the fde actually covers a real code range.  */
+  if (fde->start >= fde->end)
+    {
+      free (fde);
+      return (void *) -1;
+    }
+
+  fde->cie = cie;
+
+  if (cie->sized_augmentation_data)
+    {
+      /* The CIE augmentation says the FDE has a DW_FORM_block
+	 before its actual instruction stream.  */
+      Dwarf_Word len;
+      get_uleb128 (len, fde->instructions, fde->instructions_end);
+      if ((Dwarf_Word) (fde->instructions_end - fde->instructions) < len)
+	{
+	  free (fde);
+	  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	  return NULL;
+	}
+      fde->instructions += len;
+    }
+  else
+    /* We had to understand all of the CIE augmentation string.
+       We've recorded the number of data bytes in FDEs.  */
+    fde->instructions += cie->fde_augmentation_data_size;
+
+  /* Add the new entry to the search tree.  */
+  struct dwarf_fde **tres = tsearch (fde, &cache->fde_tree, &compare_fde);
+  if (tres == NULL)
+    {
+      free (fde);
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return NULL;
+    }
+  else if (*tres != fde)
+    {
+      /* There is already an FDE in the cache that covers the same
+	 address range.  That is odd.  Ignore this FDE.  And just use
+	 the one in the cache for consistency.  */
+      free (fde);
+      return *tres;
+    }
+
+  return fde;
+}
+
+struct dwarf_fde *
+internal_function
+__libdw_fde_by_offset (Dwarf_CFI *cache, Dwarf_Off offset)
+{
+  Dwarf_CFI_Entry entry;
+  Dwarf_Off next_offset;
+  int result = INTUSE(dwarf_next_cfi) (cache->e_ident,
+				       &cache->data->d, CFI_IS_EH (cache),
+				       offset, &next_offset, &entry);
+  if (result != 0)
+    {
+      if (result > 0)
+      invalid:
+	__libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  if (unlikely (dwarf_cfi_cie_p (&entry)))
+    goto invalid;
+
+  /* We have a new FDE to consider.  */
+  struct dwarf_fde *fde = intern_fde (cache, &entry.fde);
+  if (fde == (void *) -1l || fde == NULL)
+    return NULL;
+
+  /* If this happened to be what we would have read next, notice it.  */
+  if (cache->next_offset == offset)
+    cache->next_offset = next_offset;
+
+  return fde;
+}
+
+/* Use a binary search table in .eh_frame_hdr format, yield an FDE offset.  */
+static Dwarf_Off
+binary_search_fde (Dwarf_CFI *cache, Dwarf_Addr address)
+{
+  const size_t size = 2 * encoded_value_size (&cache->data->d, cache->e_ident,
+					      cache->search_table_encoding,
+					      NULL);
+  if (unlikely (size == 0))
+    return (Dwarf_Off) -1l;
+
+  /* Dummy used by read_encoded_value.  */
+  Elf_Data_Scn dummy_cfi_hdr_data =
+    {
+      .d = { .d_buf = (void *) cache->search_table,
+	     .d_size = cache->search_table_len }
+    };
+
+  Dwarf_CFI dummy_cfi =
+    {
+      .e_ident = cache->e_ident,
+      .datarel = cache->search_table_vaddr,
+      .frame_vaddr = cache->search_table_vaddr,
+      .data = &dummy_cfi_hdr_data
+    };
+
+  size_t l = 0, u = cache->search_table_entries;
+  while (l < u)
+    {
+      size_t idx = (l + u) / 2;
+
+      /* Max idx * size is checked against search_table len when
+	 loading eh_frame_hdr.  */
+      const uint8_t *p = &cache->search_table[idx * size];
+      Dwarf_Addr start;
+      if (unlikely (read_encoded_value (&dummy_cfi,
+					cache->search_table_encoding, &p,
+					&start)))
+	break;
+      if (address < start)
+	u = idx;
+      else
+	{
+	  l = idx + 1;
+
+	  Dwarf_Addr fde;
+	  if (unlikely (read_encoded_value (&dummy_cfi,
+					    cache->search_table_encoding, &p,
+					    &fde)))
+	    break;
+
+	  /* If this is the last entry, its upper bound is assumed to be
+	     the end of the module.
+	     XXX really should be end of containing PT_LOAD segment */
+	  if (l < cache->search_table_entries)
+	    {
+	      /* Look at the start address in the following entry.  */
+	      Dwarf_Addr end;
+	      if (unlikely (read_encoded_value
+			    (&dummy_cfi, cache->search_table_encoding, &p,
+			     &end)))
+		break;
+	      if (address >= end)
+		continue;
+	    }
+
+	  return fde - cache->frame_vaddr;
+	}
+    }
+
+  return (Dwarf_Off) -1l;
+}
+
+struct dwarf_fde *
+internal_function
+__libdw_find_fde (Dwarf_CFI *cache, Dwarf_Addr address)
+{
+  /* Look for a cached FDE covering this address.  */
+
+  const struct dwarf_fde fde_key = { .start = address, .end = 0 };
+  struct dwarf_fde **found = tfind (&fde_key, &cache->fde_tree, &compare_fde);
+  if (found != NULL)
+    return *found;
+
+  /* Use .eh_frame_hdr binary search table if possible.  */
+  if (cache->search_table != NULL)
+    {
+      Dwarf_Off offset = binary_search_fde (cache, address);
+      if (offset == (Dwarf_Off) -1l)
+	goto no_match;
+      struct dwarf_fde *fde = __libdw_fde_by_offset (cache, offset);
+      if (likely (fde != NULL))
+	{
+	  /* Sanity check the address range.  */
+	  if (unlikely (address < fde->start))
+	    {
+	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	      return NULL;
+	    }
+	  /* .eh_frame_hdr does not indicate length covered by FDE.  */
+	  if (unlikely (address >= fde->end))
+	    goto no_match;
+	}
+      return fde;
+    }
+
+  /* It's not there.  Read more CFI entries until we find it.  */
+  while (1)
+    {
+      Dwarf_Off last_offset = cache->next_offset;
+      Dwarf_CFI_Entry entry;
+      int result = INTUSE(dwarf_next_cfi) (cache->e_ident,
+					   &cache->data->d, CFI_IS_EH (cache),
+					   last_offset, &cache->next_offset,
+					   &entry);
+      if (result > 0)
+	break;
+      if (result < 0)
+	{
+	  if (cache->next_offset == last_offset)
+	    /* We couldn't progress past the bogus FDE.  */
+	    break;
+	  /* Skip the loser and look at the next entry.  */
+	  continue;
+	}
+
+      if (dwarf_cfi_cie_p (&entry))
+	{
+	  /* This is a CIE, not an FDE.  We eagerly intern these
+	     because the next FDE will usually refer to this CIE.  */
+	  __libdw_intern_cie (cache, last_offset, &entry.cie);
+	  continue;
+	}
+
+      /* We have a new FDE to consider.  */
+      struct dwarf_fde *fde = intern_fde (cache, &entry.fde);
+
+      if (fde == (void *) -1l)	/* Bad FDE, but we can keep looking.  */
+	continue;
+
+      if (fde == NULL)		/* Bad data.  */
+	return NULL;
+
+      /* Is this the one we're looking for?  */
+      if (fde->start <= address && fde->end > address)
+	return fde;
+    }
+
+ no_match:
+  /* We found no FDE covering this address.  */
+  __libdw_seterrno (DWARF_E_NO_MATCH);
+  return NULL;
+}
diff --git a/third_party/elfutils/libdw/frame-cache.c b/third_party/elfutils/libdw/frame-cache.c
new file mode 100644
index 0000000..5b6afb5
--- /dev/null
+++ b/third_party/elfutils/libdw/frame-cache.c
@@ -0,0 +1,70 @@
+/* Frame cache handling.
+   Copyright (C) 2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "../libebl/libebl.h"
+#include "cfi.h"
+#include <search.h>
+#include <stdlib.h>
+
+
+static void
+free_cie (void *arg)
+{
+  struct dwarf_cie *cie = arg;
+
+  free ((Dwarf_Frame *) cie->initial_state);
+  free (cie);
+}
+
+#define free_fde	free
+
+static void
+free_expr (void *arg)
+{
+  struct loc_s *loc = arg;
+
+  free (loc->loc);
+  free (loc);
+}
+
+void
+internal_function
+__libdw_destroy_frame_cache (Dwarf_CFI *cache)
+{
+  /* Most of the data is in our two search trees.  */
+  tdestroy (cache->fde_tree, free_fde);
+  tdestroy (cache->cie_tree, free_cie);
+  tdestroy (cache->expr_tree, free_expr);
+
+  if (cache->ebl != NULL && cache->ebl != (void *) -1l)
+    ebl_closebackend (cache->ebl);
+}
diff --git a/third_party/elfutils/libdw/libdw.h b/third_party/elfutils/libdw/libdw.h
new file mode 100644
index 0000000..1dcc815
--- /dev/null
+++ b/third_party/elfutils/libdw/libdw.h
@@ -0,0 +1,1031 @@
+/* Interfaces for libdw.
+   Copyright (C) 2002-2010, 2013, 2014, 2016, 2018 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBDW_H
+#define _LIBDW_H	1
+
+#include <gelf.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+/* Mode for the session.  */
+typedef enum
+  {
+    DWARF_C_READ,		/* Read .. */
+    DWARF_C_RDWR,		/* Read and write .. */
+    DWARF_C_WRITE,		/* Write .. */
+  }
+Dwarf_Cmd;
+
+
+/* Callback results.  */
+enum
+{
+  DWARF_CB_OK = 0,
+  DWARF_CB_ABORT
+};
+
+
+/* Error values.  */
+enum
+  {
+    DW_TAG_invalid = 0
+#define DW_TAG_invalid	DW_TAG_invalid
+  };
+
+
+/* Type for offset in DWARF file.  */
+typedef GElf_Off Dwarf_Off;
+
+/* Type for address in DWARF file.  */
+typedef GElf_Addr Dwarf_Addr;
+
+/* Integer types.  Big enough to hold any numeric value.  */
+typedef GElf_Xword Dwarf_Word;
+typedef GElf_Sxword Dwarf_Sword;
+/* For the times we know we do not need that much.  */
+typedef GElf_Half Dwarf_Half;
+
+
+/* DWARF abbreviation record.  */
+typedef struct Dwarf_Abbrev Dwarf_Abbrev;
+
+/* Returned to show the last DIE has be returned.  */
+#define DWARF_END_ABBREV ((Dwarf_Abbrev *) -1l)
+
+/* Source code line information for CU.  */
+typedef struct Dwarf_Lines_s Dwarf_Lines;
+
+/* One source code line information.  */
+typedef struct Dwarf_Line_s Dwarf_Line;
+
+/* Source file information.  */
+typedef struct Dwarf_Files_s Dwarf_Files;
+
+/* One address range record.  */
+typedef struct Dwarf_Arange_s Dwarf_Arange;
+
+/* Address ranges of a file.  */
+typedef struct Dwarf_Aranges_s Dwarf_Aranges;
+
+/* CU representation.  */
+struct Dwarf_CU;
+typedef struct Dwarf_CU Dwarf_CU;
+
+/* Macro information.  */
+typedef struct Dwarf_Macro_s Dwarf_Macro;
+
+/* Attribute representation.  */
+typedef struct
+{
+  unsigned int code;
+  unsigned int form;
+  unsigned char *valp;
+  struct Dwarf_CU *cu;
+} Dwarf_Attribute;
+
+
+/* Data block representation.  */
+typedef struct
+{
+  Dwarf_Word length;
+  unsigned char *data;
+} Dwarf_Block;
+
+
+/* DIE information.  */
+typedef struct
+{
+  /* The offset can be computed from the address.  */
+  void *addr;
+  struct Dwarf_CU *cu;
+  Dwarf_Abbrev *abbrev;
+  // XXX We'll see what other information will be needed.
+  long int padding__;
+} Dwarf_Die;
+
+/* Returned to show the last DIE has be returned.  */
+#define DWARF_END_DIE ((Dwarf_Die *) -1l)
+
+
+/* Global symbol information.  */
+typedef struct
+{
+  Dwarf_Off cu_offset;
+  Dwarf_Off die_offset;
+  const char *name;
+} Dwarf_Global;
+
+
+/* One operation in a DWARF location expression.
+   A location expression is an array of these.  */
+typedef struct
+{
+  uint8_t atom;			/* Operation */
+  Dwarf_Word number;		/* Operand */
+  Dwarf_Word number2;		/* Possible second operand */
+  Dwarf_Word offset;		/* Offset in location expression */
+} Dwarf_Op;
+
+
+/* This describes one Common Information Entry read from a CFI section.
+   Pointers here point into the DATA->d_buf block passed to dwarf_next_cfi.  */
+typedef struct
+{
+  Dwarf_Off CIE_id;	 /* Always DW_CIE_ID_64 in Dwarf_CIE structures.  */
+
+  /* Instruction stream describing initial state used by FDEs.  If
+     we did not understand the whole augmentation string and it did
+     not use 'z', then there might be more augmentation data here
+     (and in FDEs) before the actual instructions.  */
+  const uint8_t *initial_instructions;
+  const uint8_t *initial_instructions_end;
+
+  Dwarf_Word code_alignment_factor;
+  Dwarf_Sword data_alignment_factor;
+  Dwarf_Word return_address_register;
+
+  const char *augmentation;	/* Augmentation string.  */
+
+  /* Augmentation data, might be NULL.  The size is correct only if
+     we understood the augmentation string sufficiently.  */
+  const uint8_t *augmentation_data;
+  size_t augmentation_data_size;
+  size_t fde_augmentation_data_size;
+} Dwarf_CIE;
+
+/* This describes one Frame Description Entry read from a CFI section.
+   Pointers here point into the DATA->d_buf block passed to dwarf_next_cfi.  */
+typedef struct
+{
+  /* Section offset of CIE this FDE refers to.  This will never be
+     DW_CIE_ID_64 in an FDE.  If this value is DW_CIE_ID_64, this is
+     actually a Dwarf_CIE structure.  */
+  Dwarf_Off CIE_pointer;
+
+  /* We can't really decode anything further without looking up the CIE
+     and checking its augmentation string.  Here follows the encoded
+     initial_location and address_range, then any augmentation data,
+     then the instruction stream.  This FDE describes PC locations in
+     the byte range [initial_location, initial_location+address_range).
+     When the CIE augmentation string uses 'z', the augmentation data is
+     a DW_FORM_block (self-sized).  Otherwise, when we understand the
+     augmentation string completely, fde_augmentation_data_size gives
+     the number of bytes of augmentation data before the instructions.  */
+  const uint8_t *start;
+  const uint8_t *end;
+} Dwarf_FDE;
+
+/* Each entry in a CFI section is either a CIE described by Dwarf_CIE or
+   an FDE described by Dward_FDE.  Check CIE_id to see which you have.  */
+typedef union
+{
+  Dwarf_Off CIE_id;	 /* Always DW_CIE_ID_64 in Dwarf_CIE structures.  */
+  Dwarf_CIE cie;
+  Dwarf_FDE fde;
+} Dwarf_CFI_Entry;
+
+/* Same as DW_CIE_ID_64 from dwarf.h to keep libdw.h independent.  */
+#define LIBDW_CIE_ID 0xffffffffffffffffULL
+#define dwarf_cfi_cie_p(entry)	((entry)->cie.CIE_id == LIBDW_CIE_ID)
+
+/* Opaque type representing a frame state described by CFI.  */
+typedef struct Dwarf_Frame_s Dwarf_Frame;
+
+/* Opaque type representing a CFI section found in a DWARF or ELF file.  */
+typedef struct Dwarf_CFI_s Dwarf_CFI;
+
+
+/* Handle for debug sessions.  */
+typedef struct Dwarf Dwarf;
+
+
+/* Out-Of-Memory handler.  */
+typedef void (*__noreturn_attribute__ Dwarf_OOM) (void);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Create a handle for a new debug session.  */
+extern Dwarf *dwarf_begin (int fildes, Dwarf_Cmd cmd);
+
+/* Create a handle for a new debug session for an ELF file.  */
+extern Dwarf *dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp);
+
+/* Retrieve ELF descriptor used for DWARF access.  */
+extern Elf *dwarf_getelf (Dwarf *dwarf);
+
+/* Retieve DWARF descriptor used for a Dwarf_Die or Dwarf_Attribute.
+   A Dwarf_Die or a Dwarf_Attribute is associated with a particular
+   Dwarf_CU handle.  This function returns the DWARF descriptor for
+   that Dwarf_CU.  */
+extern Dwarf *dwarf_cu_getdwarf (Dwarf_CU *cu);
+
+/* Retrieves the DWARF descriptor for debugaltlink data.  Returns NULL
+   if no alternate debug data has been supplied yet.  libdw will try
+   to set the alt file on first use of an alt FORM if not yet explicitly
+   provided by dwarf_setalt.  */
+extern Dwarf *dwarf_getalt (Dwarf *main);
+
+/* Provides the data referenced by the .gnu_debugaltlink section.  The
+   caller should check that MAIN and ALT match (i.e., they have the
+   same build ID).  It is the responsibility of the caller to ensure
+   that the data referenced by ALT stays valid while it is used by
+   MAIN, until dwarf_setalt is called on MAIN with a different
+   descriptor, or dwarf_end.  Must be called before inspecting DIEs
+   that might have alt FORMs.  Otherwise libdw will try to set the
+   alt file itself on first use.  */
+extern void dwarf_setalt (Dwarf *main, Dwarf *alt);
+
+/* Release debugging handling context.  */
+extern int dwarf_end (Dwarf *dwarf);
+
+
+/* Get the data block for the .debug_info section.  */
+extern Elf_Data *dwarf_getscn_info (Dwarf *dwarf);
+
+/* Read the header for the DWARF CU.  */
+extern int dwarf_nextcu (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
+			 size_t *header_sizep, Dwarf_Off *abbrev_offsetp,
+			 uint8_t *address_sizep, uint8_t *offset_sizep)
+     __nonnull_attribute__ (3);
+
+/* Read the header of a DWARF CU or type unit.  If TYPE_SIGNATUREP is not
+   null, this reads a type unit from the .debug_types section; otherwise
+   this reads a CU from the .debug_info section.  */
+extern int dwarf_next_unit (Dwarf *dwarf, Dwarf_Off off, Dwarf_Off *next_off,
+			    size_t *header_sizep, Dwarf_Half *versionp,
+			    Dwarf_Off *abbrev_offsetp,
+			    uint8_t *address_sizep, uint8_t *offset_sizep,
+			    uint64_t *type_signaturep, Dwarf_Off *type_offsetp)
+     __nonnull_attribute__ (3);
+
+
+/* Decode one DWARF CFI entry (CIE or FDE) from the raw section data.
+   The E_IDENT from the originating ELF file indicates the address
+   size and byte order used in the CFI section contained in DATA;
+   EH_FRAME_P should be true for .eh_frame format and false for
+   .debug_frame format.  OFFSET is the byte position in the section
+   to start at; on return *NEXT_OFFSET is filled in with the byte
+   position immediately after this entry.
+
+   On success, returns 0 and fills in *ENTRY; use dwarf_cfi_cie_p to
+   see whether ENTRY->cie or ENTRY->fde is valid.
+
+   On errors, returns -1.  Some format errors will permit safely
+   skipping to the next CFI entry though the current one is unusable.
+   In that case, *NEXT_OFF will be updated before a -1 return.
+
+   If there are no more CFI entries left in the section,
+   returns 1 and sets *NEXT_OFFSET to (Dwarf_Off) -1.  */
+extern int dwarf_next_cfi (const unsigned char e_ident[],
+			   Elf_Data *data, bool eh_frame_p,
+			   Dwarf_Off offset, Dwarf_Off *next_offset,
+			   Dwarf_CFI_Entry *entry)
+  __nonnull_attribute__ (1, 2, 5, 6);
+
+/* Use the CFI in the DWARF .debug_frame section.
+   Returns NULL if there is no such section (not an error).
+   The pointer returned can be used until dwarf_end is called on DWARF,
+   and must not be passed to dwarf_cfi_end.
+   Calling this more than once returns the same pointer.  */
+extern Dwarf_CFI *dwarf_getcfi (Dwarf *dwarf);
+
+/* Use the CFI in the ELF file's exception-handling data.
+   Returns NULL if there is no such data.
+   The pointer returned can be used until elf_end is called on ELF,
+   and must be passed to dwarf_cfi_end before then.
+   Calling this more than once allocates independent data structures.  */
+extern Dwarf_CFI *dwarf_getcfi_elf (Elf *elf);
+
+/* Release resources allocated by dwarf_getcfi_elf.  */
+extern int dwarf_cfi_end (Dwarf_CFI *cache);
+
+
+/* Return DIE at given offset in .debug_info section.  */
+extern Dwarf_Die *dwarf_offdie (Dwarf *dbg, Dwarf_Off offset,
+				Dwarf_Die *result) __nonnull_attribute__ (3);
+
+/* Return DIE at given offset in .debug_types section.  */
+extern Dwarf_Die *dwarf_offdie_types (Dwarf *dbg, Dwarf_Off offset,
+				      Dwarf_Die *result)
+     __nonnull_attribute__ (3);
+
+/* Return offset of DIE.  */
+extern Dwarf_Off dwarf_dieoffset (Dwarf_Die *die);
+
+/* Return offset of DIE in CU.  */
+extern Dwarf_Off dwarf_cuoffset (Dwarf_Die *die);
+
+/* Return CU DIE containing given DIE.  */
+extern Dwarf_Die *dwarf_diecu (Dwarf_Die *die, Dwarf_Die *result,
+			       uint8_t *address_sizep, uint8_t *offset_sizep)
+     __nonnull_attribute__ (2);
+
+/* Return the CU DIE and the header info associated with a Dwarf_Die
+   or Dwarf_Attribute.  A Dwarf_Die or a Dwarf_Attribute is associated
+   with a particular Dwarf_CU handle.  This function returns the CU or
+   type unit DIE and header information for that Dwarf_CU.  The
+   returned DIE is either a compile_unit, partial_unit or type_unit.
+   If it is a type_unit, then the type signature and type offset are
+   also provided, otherwise type_offset will be set to zero.  See also
+   dwarf_diecu and dwarf_next_unit.  */
+extern Dwarf_Die *dwarf_cu_die (Dwarf_CU *cu, Dwarf_Die *result,
+				Dwarf_Half *versionp,
+				Dwarf_Off *abbrev_offsetp,
+				uint8_t *address_sizep,
+				uint8_t *offset_sizep,
+				uint64_t *type_signaturep,
+				Dwarf_Off *type_offsetp)
+     __nonnull_attribute__ (2);
+
+/* Return CU DIE containing given address.  */
+extern Dwarf_Die *dwarf_addrdie (Dwarf *dbg, Dwarf_Addr addr,
+				 Dwarf_Die *result) __nonnull_attribute__ (3);
+
+/* Return child of current DIE.  */
+extern int dwarf_child (Dwarf_Die *die, Dwarf_Die *result)
+     __nonnull_attribute__ (2);
+
+/* Locates the first sibling of DIE and places it in RESULT.
+   Returns 0 if a sibling was found, -1 if something went wrong.
+   Returns 1 if no sibling could be found and, if RESULT is not
+   the same as DIE, it sets RESULT->addr to the address of the
+   (non-sibling) DIE that follows this one, or NULL if this DIE
+   was the last one in the compilation unit.  */
+extern int dwarf_siblingof (Dwarf_Die *die, Dwarf_Die *result)
+     __nonnull_attribute__ (2);
+
+/* For type aliases and qualifier type DIEs, which don't modify or
+   change the structural layout of the underlying type, follow the
+   DW_AT_type attribute (recursively) and return the underlying type
+   Dwarf_Die.
+
+   Returns 0 when RESULT contains a Dwarf_Die (possibly equal to the
+   given DIE) that isn't a type alias or qualifier type.  Returns 1
+   when RESULT contains a type alias or qualifier Dwarf_Die that
+   couldn't be peeled further (it doesn't have a DW_TAG_type
+   attribute).  Returns -1 when an error occured.
+
+   The current DWARF specification defines one type alias tag
+   (DW_TAG_typedef) and seven modifier/qualifier type tags
+   (DW_TAG_const_type, DW_TAG_volatile_type, DW_TAG_restrict_type,
+   DW_TAG_atomic_type, DW_TAG_immutable_type, DW_TAG_packed_type and
+   DW_TAG_shared_type).  This function won't peel modifier type
+   tags that change the way the underlying type is accessed such
+   as the pointer or reference type tags (DW_TAG_pointer_type,
+   DW_TAG_reference_type or DW_TAG_rvalue_reference_type).
+
+   A future version of this function might peel other alias or
+   qualifier type tags if a future DWARF version or GNU extension
+   defines other type aliases or qualifier type tags that don't modify,
+   change the structural layout or the way to access the underlying type.  */
+extern int dwarf_peel_type (Dwarf_Die *die, Dwarf_Die *result)
+    __nonnull_attribute__ (2);
+
+/* Check whether the DIE has children.  */
+extern int dwarf_haschildren (Dwarf_Die *die) __nonnull_attribute__ (1);
+
+/* Walks the attributes of DIE, starting at the one OFFSET bytes in,
+   calling the CALLBACK function for each one.  Stops if the callback
+   function ever returns a value other than DWARF_CB_OK and returns the
+   offset of the offending attribute.  If the end of the attributes
+   is reached 1 is returned.  If something goes wrong -1 is returned and
+   the dwarf error number is set.  */
+extern ptrdiff_t dwarf_getattrs (Dwarf_Die *die,
+				 int (*callback) (Dwarf_Attribute *, void *),
+				 void *arg, ptrdiff_t offset)
+     __nonnull_attribute__ (2);
+
+/* Return tag of given DIE.  */
+extern int dwarf_tag (Dwarf_Die *die) __nonnull_attribute__ (1);
+
+
+/* Return specific attribute of DIE.  */
+extern Dwarf_Attribute *dwarf_attr (Dwarf_Die *die, unsigned int search_name,
+				    Dwarf_Attribute *result)
+     __nonnull_attribute__ (3);
+
+/* Check whether given DIE has specific attribute.  */
+extern int dwarf_hasattr (Dwarf_Die *die, unsigned int search_name);
+
+/* These are the same as dwarf_attr and dwarf_hasattr, respectively,
+   but they resolve an indirect attribute through DW_AT_abstract_origin.  */
+extern Dwarf_Attribute *dwarf_attr_integrate (Dwarf_Die *die,
+					      unsigned int search_name,
+					      Dwarf_Attribute *result)
+     __nonnull_attribute__ (3);
+extern int dwarf_hasattr_integrate (Dwarf_Die *die, unsigned int search_name);
+
+
+
+
+/* Check whether given attribute has specific form.  */
+extern int dwarf_hasform (Dwarf_Attribute *attr, unsigned int search_form);
+
+/* Return attribute code of given attribute.  */
+extern unsigned int dwarf_whatattr (Dwarf_Attribute *attr);
+
+/* Return form code of given attribute.  */
+extern unsigned int dwarf_whatform (Dwarf_Attribute *attr);
+
+
+/* Return string associated with given attribute.  */
+extern const char *dwarf_formstring (Dwarf_Attribute *attrp);
+
+/* Return unsigned constant represented by attribute.  */
+extern int dwarf_formudata (Dwarf_Attribute *attr, Dwarf_Word *return_uval)
+     __nonnull_attribute__ (2);
+
+/* Return signed constant represented by attribute.  */
+extern int dwarf_formsdata (Dwarf_Attribute *attr, Dwarf_Sword *return_uval)
+     __nonnull_attribute__ (2);
+
+/* Return address represented by attribute.  */
+extern int dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr)
+     __nonnull_attribute__ (2);
+
+/* This function is deprecated.  Always use dwarf_formref_die instead.
+   Return reference offset represented by attribute.  */
+extern int dwarf_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
+     __nonnull_attribute__ (2) __deprecated_attribute__;
+
+/* Look up the DIE in a reference-form attribute.  */
+extern Dwarf_Die *dwarf_formref_die (Dwarf_Attribute *attr, Dwarf_Die *die_mem)
+     __nonnull_attribute__ (2);
+
+/* Return block represented by attribute.  */
+extern int dwarf_formblock (Dwarf_Attribute *attr, Dwarf_Block *return_block)
+     __nonnull_attribute__ (2);
+
+/* Return flag represented by attribute.  */
+extern int dwarf_formflag (Dwarf_Attribute *attr, bool *return_bool)
+     __nonnull_attribute__ (2);
+
+
+/* Simplified attribute value access functions.  */
+
+/* Return string in name attribute of DIE.  */
+extern const char *dwarf_diename (Dwarf_Die *die);
+
+/* Return high PC attribute of DIE.  */
+extern int dwarf_highpc (Dwarf_Die *die, Dwarf_Addr *return_addr)
+     __nonnull_attribute__ (2);
+
+/* Return low PC attribute of DIE.  */
+extern int dwarf_lowpc (Dwarf_Die *die, Dwarf_Addr *return_addr)
+     __nonnull_attribute__ (2);
+
+/* Return entry_pc or low_pc attribute of DIE.  */
+extern int dwarf_entrypc (Dwarf_Die *die, Dwarf_Addr *return_addr)
+     __nonnull_attribute__ (2);
+
+/* Return 1 if DIE's lowpc/highpc or ranges attributes match the PC address,
+   0 if not, or -1 for errors.  */
+extern int dwarf_haspc (Dwarf_Die *die, Dwarf_Addr pc);
+
+/* Enumerate the PC address ranges covered by this DIE, covering all
+   addresses where dwarf_haspc returns true.  In the first call OFFSET
+   should be zero and *BASEP need not be initialized.  Returns -1 for
+   errors, zero when there are no more address ranges to report, or a
+   nonzero OFFSET value to pass to the next call.  Each subsequent call
+   must preserve *BASEP from the prior call.  Successful calls fill in
+   *STARTP and *ENDP with a contiguous address range.  */
+extern ptrdiff_t dwarf_ranges (Dwarf_Die *die,
+			       ptrdiff_t offset, Dwarf_Addr *basep,
+			       Dwarf_Addr *startp, Dwarf_Addr *endp);
+
+
+/* Return byte size attribute of DIE.  */
+extern int dwarf_bytesize (Dwarf_Die *die);
+
+/* Return bit size attribute of DIE.  */
+extern int dwarf_bitsize (Dwarf_Die *die);
+
+/* Return bit offset attribute of DIE.  */
+extern int dwarf_bitoffset (Dwarf_Die *die);
+
+/* Return array order attribute of DIE.  */
+extern int dwarf_arrayorder (Dwarf_Die *die);
+
+/* Return source language attribute of DIE.  */
+extern int dwarf_srclang (Dwarf_Die *die);
+
+
+/* Get abbreviation at given offset for given DIE.  */
+extern Dwarf_Abbrev *dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset,
+				      size_t *lengthp);
+
+/* Get abbreviation at given offset in .debug_abbrev section.  */
+extern int dwarf_offabbrev (Dwarf *dbg, Dwarf_Off offset, size_t *lengthp,
+			    Dwarf_Abbrev *abbrevp)
+     __nonnull_attribute__ (4);
+
+/* Get abbreviation code.  */
+extern unsigned int dwarf_getabbrevcode (Dwarf_Abbrev *abbrev);
+
+/* Get abbreviation tag.  */
+extern unsigned int dwarf_getabbrevtag (Dwarf_Abbrev *abbrev);
+
+/* Return true if abbreviation is children flag set.  */
+extern int dwarf_abbrevhaschildren (Dwarf_Abbrev *abbrev);
+
+/* Get number of attributes of abbreviation.  */
+extern int dwarf_getattrcnt (Dwarf_Abbrev *abbrev, size_t *attrcntp)
+     __nonnull_attribute__ (2);
+
+/* Get specific attribute of abbreviation.  */
+extern int dwarf_getabbrevattr (Dwarf_Abbrev *abbrev, size_t idx,
+				unsigned int *namep, unsigned int *formp,
+				Dwarf_Off *offset);
+
+
+/* Get string from-debug_str section.  */
+extern const char *dwarf_getstring (Dwarf *dbg, Dwarf_Off offset,
+				    size_t *lenp);
+
+
+/* Get public symbol information.  */
+extern ptrdiff_t dwarf_getpubnames (Dwarf *dbg,
+				    int (*callback) (Dwarf *, Dwarf_Global *,
+						     void *),
+				    void *arg, ptrdiff_t offset)
+     __nonnull_attribute__ (2);
+
+
+/* Get source file information for CU.  */
+extern int dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines,
+			      size_t *nlines) __nonnull_attribute__ (2, 3);
+
+/* Return one of the source lines of the CU.  */
+extern Dwarf_Line *dwarf_onesrcline (Dwarf_Lines *lines, size_t idx);
+
+/* Get the file source files used in the CU.  */
+extern int dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files,
+			      size_t *nfiles)
+     __nonnull_attribute__ (2);
+
+
+/* Get source for address in CU.  */
+extern Dwarf_Line *dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr);
+
+/* Get source for file and line number.  */
+extern int dwarf_getsrc_file (Dwarf *dbg, const char *fname, int line, int col,
+			      Dwarf_Line ***srcsp, size_t *nsrcs)
+     __nonnull_attribute__ (2, 5, 6);
+
+
+/* Return line address.  */
+extern int dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp);
+
+/* Return line VLIW operation index.  */
+extern int dwarf_lineop_index (Dwarf_Line *line, unsigned int *op_indexp);
+
+/* Return line number.  */
+extern int dwarf_lineno (Dwarf_Line *line, int *linep)
+     __nonnull_attribute__ (2);
+
+/* Return column in line.  */
+extern int dwarf_linecol (Dwarf_Line *line, int *colp)
+     __nonnull_attribute__ (2);
+
+/* Return true if record is for beginning of a statement.  */
+extern int dwarf_linebeginstatement (Dwarf_Line *line, bool *flagp)
+     __nonnull_attribute__ (2);
+
+/* Return true if record is for end of sequence.  */
+extern int dwarf_lineendsequence (Dwarf_Line *line, bool *flagp)
+     __nonnull_attribute__ (2);
+
+/* Return true if record is for beginning of a basic block.  */
+extern int dwarf_lineblock (Dwarf_Line *line, bool *flagp)
+     __nonnull_attribute__ (2);
+
+/* Return true if record is for end of prologue.  */
+extern int dwarf_lineprologueend (Dwarf_Line *line, bool *flagp)
+     __nonnull_attribute__ (2);
+
+/* Return true if record is for beginning of epilogue.  */
+extern int dwarf_lineepiloguebegin (Dwarf_Line *line, bool *flagp)
+     __nonnull_attribute__ (2);
+
+/* Return instruction-set architecture in this record.  */
+extern int dwarf_lineisa (Dwarf_Line *line, unsigned int *isap)
+     __nonnull_attribute__ (2);
+
+/* Return code path discriminator in this record.  */
+extern int dwarf_linediscriminator (Dwarf_Line *line, unsigned int *discp)
+     __nonnull_attribute__ (2);
+
+
+/* Find line information for address.  */
+extern const char *dwarf_linesrc (Dwarf_Line *line,
+				  Dwarf_Word *mtime, Dwarf_Word *length);
+
+/* Return file information.  */
+extern const char *dwarf_filesrc (Dwarf_Files *file, size_t idx,
+				  Dwarf_Word *mtime, Dwarf_Word *length);
+
+/* Return the Dwarf_Files and index associated with the given Dwarf_Line.  */
+extern int dwarf_line_file (Dwarf_Line *line,
+			    Dwarf_Files **files, size_t *idx)
+    __nonnull_attribute__ (2, 3);
+
+/* Return the directory list used in the file information extracted.
+   (*RESULT)[0] is the CU's DW_AT_comp_dir value, and may be null.
+   (*RESULT)[0..*NDIRS-1] are the compile-time include directory path
+   encoded by the compiler.  */
+extern int dwarf_getsrcdirs (Dwarf_Files *files,
+			     const char *const **result, size_t *ndirs)
+  __nonnull_attribute__ (2, 3);
+
+
+/* Return location expression, decoded as a list of operations.  */
+extern int dwarf_getlocation (Dwarf_Attribute *attr, Dwarf_Op **expr,
+			      size_t *exprlen) __nonnull_attribute__ (2, 3);
+
+/* Return location expressions.  If the attribute uses a location list,
+   ADDRESS selects the relevant location expressions from the list.
+   There can be multiple matches, resulting in multiple expressions to
+   return.  EXPRS and EXPRLENS are parallel arrays of NLOCS slots to
+   fill in.  Returns the number of locations filled in, or -1 for
+   errors.  If EXPRS is a null pointer, stores nothing and returns the
+   total number of locations.  A return value of zero means that the
+   location list indicated no value is accessible.  */
+extern int dwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address,
+				   Dwarf_Op **exprs, size_t *exprlens,
+				   size_t nlocs);
+
+/* Enumerate the locations ranges and descriptions covered by the
+   given attribute.  In the first call OFFSET should be zero and
+   *BASEP need not be initialized.  Returns -1 for errors, zero when
+   there are no more locations to report, or a nonzero OFFSET
+   value to pass to the next call.  Each subsequent call must preserve
+   *BASEP from the prior call.  Successful calls fill in *STARTP and
+   *ENDP with a contiguous address range and *EXPR with a pointer to
+   an array of operations with length *EXPRLEN.  If the attribute
+   describes a single location description and not a location list the
+   first call (with OFFSET zero) will return the location description
+   in *EXPR with *STARTP set to zero and *ENDP set to minus one.  */
+extern ptrdiff_t dwarf_getlocations (Dwarf_Attribute *attr,
+				     ptrdiff_t offset, Dwarf_Addr *basep,
+				     Dwarf_Addr *startp, Dwarf_Addr *endp,
+				     Dwarf_Op **expr, size_t *exprlen);
+
+/* Return the block associated with a DW_OP_implicit_value operation.
+   The OP pointer must point into an expression that dwarf_getlocation
+   or dwarf_getlocation_addr has returned given the same ATTR.  */
+extern int dwarf_getlocation_implicit_value (Dwarf_Attribute *attr,
+					     const Dwarf_Op *op,
+					     Dwarf_Block *return_block)
+  __nonnull_attribute__ (2, 3);
+
+/* Return the attribute indicated by a DW_OP_GNU_implicit_pointer operation.
+   The OP pointer must point into an expression that dwarf_getlocation
+   or dwarf_getlocation_addr has returned given the same ATTR.
+   The result is the DW_AT_location or DW_AT_const_value attribute
+   of the OP->number DIE.  */
+extern int dwarf_getlocation_implicit_pointer (Dwarf_Attribute *attr,
+					       const Dwarf_Op *op,
+					       Dwarf_Attribute *result)
+  __nonnull_attribute__ (2, 3);
+
+/* Return the DIE associated with an operation such as
+   DW_OP_GNU_implicit_pointer, DW_OP_GNU_parameter_ref, DW_OP_GNU_convert,
+   DW_OP_GNU_reinterpret, DW_OP_GNU_const_type, DW_OP_GNU_regval_type or
+   DW_OP_GNU_deref_type.  The OP pointer must point into an expression that
+   dwarf_getlocation or dwarf_getlocation_addr has returned given the same
+   ATTR.  The RESULT is a DIE that expresses a type or value needed by the
+   given OP.  */
+extern int dwarf_getlocation_die (Dwarf_Attribute *attr,
+				  const Dwarf_Op *op,
+				  Dwarf_Die *result)
+  __nonnull_attribute__ (2, 3);
+
+/* Return the attribute expressing a value associated with an operation such
+   as DW_OP_implicit_value, DW_OP_GNU_entry_value or DW_OP_GNU_const_type.
+   The OP pointer must point into an expression that dwarf_getlocation
+   or dwarf_getlocation_addr has returned given the same ATTR.
+   The RESULT is a value expressed by an attribute such as DW_AT_location
+   or DW_AT_const_value.  */
+extern int dwarf_getlocation_attr (Dwarf_Attribute *attr,
+				   const Dwarf_Op *op,
+				   Dwarf_Attribute *result)
+  __nonnull_attribute__ (2, 3);
+
+
+/* Compute the byte-size of a type DIE according to DWARF rules.
+   For most types, this is just DW_AT_byte_size.
+   For DW_TAG_array_type it can apply much more complex rules.  */
+extern int dwarf_aggregate_size (Dwarf_Die *die, Dwarf_Word *size);
+
+/* Given a language code, as returned by dwarf_srclan, get the default
+   lower bound for a subrange type without a lower bound attribute.
+   Returns zero on success or -1 on failure when the given language
+   wasn't recognized.  */
+extern int dwarf_default_lower_bound (int lang, Dwarf_Sword *result)
+  __nonnull_attribute__ (2);
+
+/* Return scope DIEs containing PC address.
+   Sets *SCOPES to a malloc'd array of Dwarf_Die structures,
+   and returns the number of elements in the array.
+   (*SCOPES)[0] is the DIE for the innermost scope containing PC,
+   (*SCOPES)[1] is the DIE for the scope containing that scope, and so on.
+   Returns -1 for errors or 0 if no scopes match PC.  */
+extern int dwarf_getscopes (Dwarf_Die *cudie, Dwarf_Addr pc,
+			    Dwarf_Die **scopes);
+
+/* Return scope DIEs containing the given DIE.
+   Sets *SCOPES to a malloc'd array of Dwarf_Die structures,
+   and returns the number of elements in the array.
+   (*SCOPES)[0] is a copy of DIE.
+   (*SCOPES)[1] is the DIE for the scope containing that scope, and so on.
+   Returns -1 for errors or 0 if DIE is not found in any scope entry.  */
+extern int dwarf_getscopes_die (Dwarf_Die *die, Dwarf_Die **scopes);
+
+
+/* Search SCOPES[0..NSCOPES-1] for a variable called NAME.
+   Ignore the first SKIP_SHADOWS scopes that match the name.
+   If MATCH_FILE is not null, accept only declaration in that source file;
+   if MATCH_LINENO or MATCH_LINECOL are also nonzero, accept only declaration
+   at that line and column.
+
+   If successful, fill in *RESULT with the DIE of the variable found,
+   and return N where SCOPES[N] is the scope defining the variable.
+   Return -1 for errors or -2 for no matching variable found.  */
+extern int dwarf_getscopevar (Dwarf_Die *scopes, int nscopes,
+			      const char *name, int skip_shadows,
+			      const char *match_file,
+			      int match_lineno, int match_linecol,
+			      Dwarf_Die *result);
+
+
+
+/* Return list address ranges.  */
+extern int dwarf_getaranges (Dwarf *dbg, Dwarf_Aranges **aranges,
+			     size_t *naranges)
+     __nonnull_attribute__ (2);
+
+/* Return one of the address range entries.  */
+extern Dwarf_Arange *dwarf_onearange (Dwarf_Aranges *aranges, size_t idx);
+
+/* Return information in address range record.  */
+extern int dwarf_getarangeinfo (Dwarf_Arange *arange, Dwarf_Addr *addrp,
+				Dwarf_Word *lengthp, Dwarf_Off *offsetp);
+
+/* Get address range which includes given address.  */
+extern Dwarf_Arange *dwarf_getarange_addr (Dwarf_Aranges *aranges,
+					   Dwarf_Addr addr);
+
+
+
+/* Get functions in CUDIE.  The given callback will be called for all
+   defining DW_TAG_subprograms in the CU DIE tree.  If the callback
+   returns DWARF_CB_ABORT the return value can be used as offset argument
+   to resume the function to find all remaining functions (this is not
+   really recommended, since it needs to rewalk the CU DIE tree first till
+   that offset is found again).  If the callback returns DWARF_CB_OK
+   dwarf_getfuncs will not return but keep calling the callback for each
+   function DIE it finds.  Pass zero for offset on the first call to walk
+   the full CU DIE tree.  If no more functions can be found and the callback
+   returned DWARF_CB_OK then the function returns zero.  */
+extern ptrdiff_t dwarf_getfuncs (Dwarf_Die *cudie,
+				 int (*callback) (Dwarf_Die *, void *),
+				 void *arg, ptrdiff_t offset);
+
+
+/* Return file name containing definition of the given declaration.  */
+extern const char *dwarf_decl_file (Dwarf_Die *decl);
+
+/* Get line number of beginning of given declaration.  */
+extern int dwarf_decl_line (Dwarf_Die *decl, int *linep)
+     __nonnull_attribute__ (2);
+
+/* Get column number of beginning of given declaration.  */
+extern int dwarf_decl_column (Dwarf_Die *decl, int *colp)
+     __nonnull_attribute__ (2);
+
+
+/* Return nonzero if given function is an abstract inline definition.  */
+extern int dwarf_func_inline (Dwarf_Die *func);
+
+/* Find each concrete inlined instance of the abstract inline definition.  */
+extern int dwarf_func_inline_instances (Dwarf_Die *func,
+					int (*callback) (Dwarf_Die *, void *),
+					void *arg);
+
+
+/* Find the appropriate PC location or locations for function entry
+   breakpoints for the given DW_TAG_subprogram DIE.  Returns -1 for errors.
+   On success, returns the number of breakpoint locations (never zero)
+   and sets *BKPTS to a malloc'd vector of addresses.  */
+extern int dwarf_entry_breakpoints (Dwarf_Die *die, Dwarf_Addr **bkpts);
+
+
+/* Iterate through the macro unit referenced by CUDIE and call
+   CALLBACK for each macro information entry.  To start the iteration,
+   one would pass DWARF_GETMACROS_START for TOKEN.
+
+   The iteration continues while CALLBACK returns DWARF_CB_OK.  If the
+   callback returns DWARF_CB_ABORT, the iteration stops and a
+   continuation token is returned, which can be used to restart the
+   iteration at the point where it ended.  Returns -1 for errors or 0
+   if there are no more macro entries.
+
+   Note that the Dwarf_Macro pointer passed to the callback is only
+   valid for the duration of the callback invocation.
+
+   For backward compatibility, a token of 0 is accepted for starting
+   the iteration as well, but in that case this interface will refuse
+   to serve opcode 0xff from .debug_macro sections.  Such opcode would
+   be considered invalid and would cause dwarf_getmacros to return
+   with error.  */
+#define DWARF_GETMACROS_START PTRDIFF_MIN
+extern ptrdiff_t dwarf_getmacros (Dwarf_Die *cudie,
+				  int (*callback) (Dwarf_Macro *, void *),
+				  void *arg, ptrdiff_t token)
+     __nonnull_attribute__ (2);
+
+/* This is similar in operation to dwarf_getmacros, but selects the
+   unit to iterate through by offset instead of by CU, and always
+   iterates .debug_macro.  This can be used for handling
+   DW_MACRO_GNU_transparent_include's or similar opcodes.
+
+   TOKEN value of DWARF_GETMACROS_START can be used to start the
+   iteration.
+
+   It is not appropriate to obtain macro unit offset by hand from a CU
+   DIE and then request iteration through this interface.  The reason
+   for this is that if a dwarf_macro_getsrcfiles is later called,
+   there would be no way to figure out what DW_AT_comp_dir was present
+   on the CU DIE, and file names referenced in either the macro unit
+   itself, or the .debug_line unit that it references, might be wrong.
+   Use dwarf_getmacros.  */
+extern ptrdiff_t dwarf_getmacros_off (Dwarf *dbg, Dwarf_Off macoff,
+				      int (*callback) (Dwarf_Macro *, void *),
+				      void *arg, ptrdiff_t token)
+  __nonnull_attribute__ (3);
+
+/* Get the source files used by the macro entry.  You shouldn't assume
+   that Dwarf_Files references will remain valid after MACRO becomes
+   invalid.  (Which is to say it's only valid within the
+   dwarf_getmacros* callback.)  Returns 0 for success or a negative
+   value in case of an error.  */
+extern int dwarf_macro_getsrcfiles (Dwarf *dbg, Dwarf_Macro *macro,
+				    Dwarf_Files **files, size_t *nfiles)
+  __nonnull_attribute__ (2, 3, 4);
+
+/* Return macro opcode.  That's a constant that can be either from
+   DW_MACINFO_* domain or DW_MACRO_GNU_* domain.  The two domains have
+   compatible values, so it's OK to use either of them for
+   comparisons.  The only differences is 0xff, which could be either
+   DW_MACINFO_vendor_ext or a vendor-defined DW_MACRO_* constant.  One
+   would need to look if the CU DIE which the iteration was requested
+   for has attribute DW_AT_macro_info, or either of DW_AT_GNU_macros
+   or DW_AT_macros to differentiate the two interpretations.  */
+extern int dwarf_macro_opcode (Dwarf_Macro *macro, unsigned int *opcodep)
+     __nonnull_attribute__ (2);
+
+/* Get number of parameters of MACRO and store it to *PARAMCNTP.  */
+extern int dwarf_macro_getparamcnt (Dwarf_Macro *macro, size_t *paramcntp);
+
+/* Get IDX-th parameter of MACRO (numbered from zero), and stores it
+   to *ATTRIBUTE.  Returns 0 on success or -1 for errors.
+
+   After a successful call, you can query ATTRIBUTE by dwarf_whatform
+   to determine which of the dwarf_formX calls to make to get actual
+   value out of ATTRIBUTE.  Note that calling dwarf_whatattr is not
+   meaningful for pseudo-attributes formed this way.  */
+extern int dwarf_macro_param (Dwarf_Macro *macro, size_t idx,
+			      Dwarf_Attribute *attribute);
+
+/* Return macro parameter with index 0.  This will return -1 if the
+   parameter is not an integral value.  Use dwarf_macro_param for more
+   general access.  */
+extern int dwarf_macro_param1 (Dwarf_Macro *macro, Dwarf_Word *paramp)
+     __nonnull_attribute__ (2);
+
+/* Return macro parameter with index 1.  This will return -1 if the
+   parameter is not an integral or string value.  Use
+   dwarf_macro_param for more general access.  */
+extern int dwarf_macro_param2 (Dwarf_Macro *macro, Dwarf_Word *paramp,
+			       const char **strp);
+
+/* Compute what's known about a call frame when the PC is at ADDRESS.
+   Returns 0 for success or -1 for errors.
+   On success, *FRAME is a malloc'd pointer.  */
+extern int dwarf_cfi_addrframe (Dwarf_CFI *cache,
+				Dwarf_Addr address, Dwarf_Frame **frame)
+  __nonnull_attribute__ (3);
+
+/* Return the DWARF register number used in FRAME to denote
+   the return address in FRAME's caller frame.  The remaining
+   arguments can be non-null to fill in more information.
+
+   Fill [*START, *END) with the PC range to which FRAME's information applies.
+   Fill in *SIGNALP to indicate whether this is a signal-handling frame.
+   If true, this is the implicit call frame that calls a signal handler.
+   This frame's "caller" is actually the interrupted state, not a call;
+   its return address is an exact PC, not a PC after a call instruction.  */
+extern int dwarf_frame_info (Dwarf_Frame *frame,
+			     Dwarf_Addr *start, Dwarf_Addr *end, bool *signalp);
+
+/* Return a DWARF expression that yields the Canonical Frame Address at
+   this frame state.  Returns -1 for errors, or zero for success, with
+   *NOPS set to the number of operations stored at *OPS.  That pointer
+   can be used only as long as FRAME is alive and unchanged.  *NOPS is
+   zero if the CFA cannot be determined here.  Note that if nonempty,
+   *OPS is a DWARF expression, not a location description--append
+   DW_OP_stack_value to a get a location description for the CFA.  */
+extern int dwarf_frame_cfa (Dwarf_Frame *frame, Dwarf_Op **ops, size_t *nops)
+  __nonnull_attribute__ (2);
+
+/* Deliver a DWARF location description that yields the location or
+   value of DWARF register number REGNO in the state described by FRAME.
+
+   Returns -1 for errors or zero for success, setting *NOPS to the
+   number of operations in the array stored at *OPS.  Note the last
+   operation is DW_OP_stack_value if there is no mutable location but
+   only a computable value.
+
+   *NOPS zero with *OPS set to OPS_MEM means CFI says the caller's
+   REGNO is "undefined", i.e. it's call-clobbered and cannot be recovered.
+
+   *NOPS zero with *OPS set to a null pointer means CFI says the
+   caller's REGNO is "same_value", i.e. this frame did not change it;
+   ask the caller frame where to find it.
+
+   For common simple expressions *OPS is OPS_MEM.  For arbitrary DWARF
+   expressions in the CFI, *OPS is an internal pointer that can be used as
+   long as the Dwarf_CFI used to create FRAME remains alive.  */
+extern int dwarf_frame_register (Dwarf_Frame *frame, int regno,
+				 Dwarf_Op ops_mem[3],
+				 Dwarf_Op **ops, size_t *nops)
+  __nonnull_attribute__ (3, 4, 5);
+
+
+/* Return error code of last failing function call.  This value is kept
+   separately for each thread.  */
+extern int dwarf_errno (void);
+
+/* Return error string for ERROR.  If ERROR is zero, return error string
+   for most recent error or NULL is none occurred.  If ERROR is -1 the
+   behaviour is similar to the last case except that not NULL but a legal
+   string is returned.  */
+extern const char *dwarf_errmsg (int err);
+
+
+/* Register new Out-Of-Memory handler.  The old handler is returned.  */
+extern Dwarf_OOM dwarf_new_oom_handler (Dwarf *dbg, Dwarf_OOM handler);
+
+
+/* Inline optimizations.  */
+#ifdef __OPTIMIZE__
+/* Return attribute code of given attribute.  */
+__libdw_extern_inline unsigned int
+dwarf_whatattr (Dwarf_Attribute *attr)
+{
+  return attr == NULL ? 0 : attr->code;
+}
+
+/* Return attribute code of given attribute.  */
+__libdw_extern_inline unsigned int
+dwarf_whatform (Dwarf_Attribute *attr)
+{
+  return attr == NULL ? 0 : attr->form;
+}
+#endif	/* Optimize.  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* libdw.h */
diff --git a/third_party/elfutils/libdw/libdw.map b/third_party/elfutils/libdw/libdw.map
new file mode 100644
index 0000000..1430705
--- /dev/null
+++ b/third_party/elfutils/libdw/libdw.map
@@ -0,0 +1,346 @@
+ELFUTILS_0 { };
+ELFUTILS_0.122 {
+  global:
+    dwarf_abbrevhaschildren;
+    dwarf_addrdie;
+    dwarf_arrayorder;
+    dwarf_attr;
+    dwarf_attr_integrate;
+    dwarf_begin;
+    dwarf_begin_elf;
+    dwarf_bitoffset;
+    dwarf_bitsize;
+    dwarf_bytesize;
+    dwarf_child;
+    dwarf_cuoffset;
+    dwarf_decl_column;
+    dwarf_decl_file;
+    dwarf_decl_line;
+    dwarf_diecu;
+    dwarf_diename;
+    dwarf_dieoffset;
+    dwarf_end;
+    dwarf_entry_breakpoints;
+    dwarf_entrypc;
+    dwarf_errmsg;
+    dwarf_errno;
+    dwarf_filesrc;
+    dwarf_formaddr;
+    dwarf_formblock;
+    dwarf_formflag;
+    dwarf_formref;
+    dwarf_formref_die;
+    dwarf_formsdata;
+    dwarf_formstring;
+    dwarf_formudata;
+    dwarf_func_inline;
+    dwarf_func_inline_instances;
+    dwarf_getabbrev;
+    dwarf_getabbrevattr;
+    dwarf_getabbrevcode;
+    dwarf_getabbrevtag;
+    dwarf_getarange_addr;
+    dwarf_getarangeinfo;
+    dwarf_getaranges;
+    dwarf_getattrcnt;
+    dwarf_getattrs;
+    dwarf_getfuncs;
+    dwarf_getlocation;
+    dwarf_getlocation_addr;
+    dwarf_getmacros;
+    dwarf_getpubnames;
+    dwarf_getscn_info;
+    dwarf_getscopes;
+    dwarf_getscopes_die;
+    dwarf_getscopevar;
+    dwarf_getsrc_die;
+    dwarf_getsrc_file;
+    dwarf_getsrcfiles;
+    dwarf_getsrclines;
+    dwarf_getstring;
+    dwarf_hasattr;
+    dwarf_hasattr_integrate;
+    dwarf_haschildren;
+    dwarf_hasform;
+    dwarf_haspc;
+    dwarf_highpc;
+    dwarf_lineaddr;
+    dwarf_linebeginstatement;
+    dwarf_lineblock;
+    dwarf_linecol;
+    dwarf_lineendsequence;
+    dwarf_lineepiloguebegin;
+    dwarf_lineno;
+    dwarf_lineprologueend;
+    dwarf_linesrc;
+    dwarf_lowpc;
+    dwarf_macro_opcode;
+    dwarf_macro_param1;
+    dwarf_macro_param2;
+    dwarf_new_oom_handler;
+    dwarf_nextcu;
+    dwarf_offabbrev;
+    dwarf_offdie;
+    dwarf_onearange;
+    dwarf_onesrcline;
+    dwarf_ranges;
+    dwarf_siblingof;
+    dwarf_srclang;
+    dwarf_tag;
+    dwarf_whatattr;
+    dwarf_whatform;
+
+    # libdwfl_pic.a contributes these symbols.
+    dwfl_addrdie;
+    dwfl_addrdwarf;
+    dwfl_addrmodule;
+    dwfl_begin;
+    dwfl_cumodule;
+    dwfl_end;
+    dwfl_errmsg;
+    dwfl_errno;
+    dwfl_getdwarf;
+    dwfl_getmodules;
+    dwfl_getsrc;
+    dwfl_getsrclines;
+    dwfl_line_comp_dir;
+    dwfl_linecu;
+    dwfl_lineinfo;
+    dwfl_linemodule;
+    dwfl_linux_kernel_find_elf;
+    dwfl_linux_kernel_module_section_address;
+    dwfl_linux_kernel_report_kernel;
+    dwfl_linux_kernel_report_modules;
+    dwfl_linux_kernel_report_offline;
+    dwfl_linux_proc_find_elf;
+    dwfl_linux_proc_maps_report;
+    dwfl_linux_proc_report;
+    dwfl_module_addrdie;
+    dwfl_module_addrname;
+    dwfl_module_getdwarf;
+    dwfl_module_getelf;
+    dwfl_module_getsrc;
+    dwfl_module_getsrc_file;
+    dwfl_module_getsym;
+    dwfl_module_getsymtab;
+    dwfl_module_info;
+    dwfl_module_nextcu;
+    dwfl_module_register_names;
+    dwfl_module_relocate_address;
+    dwfl_module_relocation_info;
+    dwfl_module_relocations;
+    dwfl_module_return_value_location;
+    dwfl_nextcu;
+    dwfl_offline_section_address;
+    dwfl_onesrcline;
+    dwfl_report_begin;
+    dwfl_report_elf;
+    dwfl_report_end;
+    dwfl_report_module;
+    dwfl_report_offline;
+    dwfl_standard_argp;
+    dwfl_standard_find_debuginfo;
+    dwfl_version;
+
+  local:
+    *;
+} ELFUTILS_0;
+
+ELFUTILS_0.126 {
+  global:
+    dwarf_getelf;
+
+  local:
+    *;
+} ELFUTILS_0.122;
+
+ELFUTILS_0.127 {
+  global:
+    dwarf_getsrcdirs;
+
+    dwfl_module_addrsym;
+    dwfl_report_begin_add;
+    dwfl_module_address_section;
+
+  local:
+    *;
+} ELFUTILS_0.126;
+
+ELFUTILS_0.130 {
+  global:
+    dwfl_build_id_find_elf;
+    dwfl_build_id_find_debuginfo;
+    dwfl_module_build_id;
+    dwfl_module_report_build_id;
+
+  local:
+    *;
+} ELFUTILS_0.127;
+
+ELFUTILS_0.136 {
+  global:
+    dwfl_addrsegment;
+    dwfl_report_segment;
+
+  local:
+    *;
+} ELFUTILS_0.130;
+
+ELFUTILS_0.138 {
+  global:
+    # Replaced ELFUTILS_0.130 version, which has bug-compatibility wrapper.
+    dwfl_module_build_id;
+
+  local:
+    *;
+} ELFUTILS_0.136;
+
+ELFUTILS_0.142 {
+  global:
+    dwarf_next_cfi;
+    dwarf_getcfi;
+    dwarf_getcfi_elf;
+    dwarf_cfi_addrframe;
+    dwarf_cfi_end;
+    dwarf_frame_cfa;
+    dwarf_frame_register;
+    dwarf_frame_info;
+
+    dwfl_module_dwarf_cfi;
+    dwfl_module_eh_cfi;
+} ELFUTILS_0.138;
+
+ELFUTILS_0.143 {
+  global:
+    dwarf_getlocation_implicit_value;
+
+    # Replaced ELFUTILS_0.122 versions.  Both versions point to the
+    # same implementation, but users of the new symbol version can
+    # presume that they use dwarf_attr_integrate properly.
+    dwarf_arrayorder;
+    dwarf_bitoffset;
+    dwarf_bitsize;
+    dwarf_bytesize;
+    dwarf_decl_column;
+    dwarf_decl_file;
+    dwarf_decl_line;
+    dwarf_srclang;
+
+} ELFUTILS_0.142;
+
+ELFUTILS_0.144 {
+  global:
+    dwarf_aggregate_size;
+} ELFUTILS_0.143;
+
+ELFUTILS_0.146 {
+  global:
+    dwfl_core_file_report;
+} ELFUTILS_0.144;
+
+ELFUTILS_0.148 {
+  global:
+    dwarf_lineisa;
+    dwarf_linediscriminator;
+    dwarf_lineop_index;
+
+    dwarf_next_unit;
+    dwarf_offdie_types;
+} ELFUTILS_0.146;
+
+ELFUTILS_0.149 {
+  global:
+    dwarf_getlocation_implicit_pointer;
+
+    dwfl_dwarf_line;
+} ELFUTILS_0.148;
+
+ELFUTILS_0.156 {
+  global:
+    # Replaced ELFUTILS_0.122 version, which has a wrapper without add_p_vaddr.
+    dwfl_report_elf;
+} ELFUTILS_0.149;
+
+ELFUTILS_0.157 {
+  global:
+    dwarf_getlocations;
+    dwarf_getlocation_die;
+    dwarf_getlocation_attr;
+} ELFUTILS_0.156;
+
+ELFUTILS_0.158 {
+  global:
+    # Replaced ELFUTILS_0.146 version, which has a wrapper without executable.
+    dwfl_core_file_report;
+
+    dwfl_attach_state;
+    dwfl_pid;
+    dwfl_thread_dwfl;
+    dwfl_thread_tid;
+    dwfl_frame_thread;
+    dwfl_thread_state_registers;
+    dwfl_thread_state_register_pc;
+    dwfl_getthread_frames;
+    dwfl_getthreads;
+    dwfl_thread_getframes;
+    dwfl_frame_pc;
+
+    dwfl_module_getsymtab_first_global;
+    dwfl_module_addrinfo;
+    dwfl_module_getsym_info;
+
+    dwfl_core_file_attach;
+    dwfl_linux_proc_attach;
+} ELFUTILS_0.157;
+
+ELFUTILS_0.159 {
+  global:
+    dwarf_getalt;
+    dwarf_setalt;
+    dwelf_dwarf_gnu_debugaltlink;
+    dwelf_elf_gnu_debuglink;
+    dwelf_elf_gnu_build_id;
+} ELFUTILS_0.158;
+
+ELFUTILS_0.160 {
+  global:
+    dwarf_cu_getdwarf;
+    dwarf_cu_die;
+} ELFUTILS_0.159;
+
+ELFUTILS_0.161 {
+  global:
+    dwarf_peel_type;
+
+    # Replaced ELFUTILS_0.144 version.  Both versions point to the
+    # same implementation, but users of the new symbol version can
+    # presume that it uses dwarf_peel_type.
+    dwarf_aggregate_size;
+
+    dwarf_getmacros_off;
+    dwarf_macro_getsrcfiles;
+    dwarf_macro_getparamcnt;
+    dwarf_macro_param;
+} ELFUTILS_0.160;
+
+ELFUTILS_0.165 {
+  global:
+    dwelf_scn_gnu_compressed_size;
+} ELFUTILS_0.161;
+
+ELFUTILS_0.167 {
+  global:
+    dwelf_strtab_init;
+    dwelf_strtab_add;
+    dwelf_strtab_add_len;
+    dwelf_strtab_finalize;
+    dwelf_strent_off;
+    dwelf_strent_str;
+    dwelf_strtab_free;
+} ELFUTILS_0.165;
+
+ELFUTILS_0.170 {
+  global:
+    dwarf_default_lower_bound;
+    dwarf_line_file;
+} ELFUTILS_0.167;
diff --git a/third_party/elfutils/libdw/libdwP.h b/third_party/elfutils/libdw/libdwP.h
new file mode 100644
index 0000000..0681aa1
--- /dev/null
+++ b/third_party/elfutils/libdw/libdwP.h
@@ -0,0 +1,825 @@
+/* Internal definitions for libdwarf.
+   Copyright (C) 2002-2011, 2013-2018 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBDWP_H
+#define _LIBDWP_H 1
+
+#include <libintl.h>
+#include <stdbool.h>
+
+#include <libdw.h>
+#include <dwarf.h>
+
+
+/* gettext helper macros.  */
+#define _(Str) dgettext ("elfutils", Str)
+
+
+/* Known location expressions already decoded.  */
+struct loc_s
+{
+  void *addr;
+  Dwarf_Op *loc;
+  size_t nloc;
+};
+
+/* Known DW_OP_implicit_value blocks already decoded.
+   This overlaps struct loc_s exactly, but only the
+   first member really has to match.  */
+struct loc_block_s
+{
+  void *addr;
+  unsigned char *data;
+  size_t length;
+};
+
+/* Already decoded .debug_line units.  */
+struct files_lines_s
+{
+  Dwarf_Off debug_line_offset;
+  Dwarf_Files *files;
+  Dwarf_Lines *lines;
+};
+
+/* Valid indeces for the section data.  */
+enum
+  {
+    IDX_debug_info = 0,
+    IDX_debug_types,
+    IDX_debug_abbrev,
+    IDX_debug_aranges,
+    IDX_debug_line,
+    IDX_debug_frame,
+    IDX_debug_loc,
+    IDX_debug_pubnames,
+    IDX_debug_str,
+    IDX_debug_macinfo,
+    IDX_debug_macro,
+    IDX_debug_ranges,
+    IDX_gnu_debugaltlink,
+    IDX_last
+  };
+
+
+/* Error values.  */
+enum
+{
+  DWARF_E_NOERROR = 0,
+  DWARF_E_UNKNOWN_ERROR,
+  DWARF_E_INVALID_ACCESS,
+  DWARF_E_NO_REGFILE,
+  DWARF_E_IO_ERROR,
+  DWARF_E_INVALID_ELF,
+  DWARF_E_NO_DWARF,
+  DWARF_E_COMPRESSED_ERROR,
+  DWARF_E_NOELF,
+  DWARF_E_GETEHDR_ERROR,
+  DWARF_E_NOMEM,
+  DWARF_E_UNIMPL,
+  DWARF_E_INVALID_CMD,
+  DWARF_E_INVALID_VERSION,
+  DWARF_E_INVALID_FILE,
+  DWARF_E_NO_ENTRY,
+  DWARF_E_INVALID_DWARF,
+  DWARF_E_NO_STRING,
+  DWARF_E_NO_ADDR,
+  DWARF_E_NO_CONSTANT,
+  DWARF_E_NO_REFERENCE,
+  DWARF_E_INVALID_REFERENCE,
+  DWARF_E_NO_DEBUG_LINE,
+  DWARF_E_INVALID_DEBUG_LINE,
+  DWARF_E_TOO_BIG,
+  DWARF_E_VERSION,
+  DWARF_E_INVALID_DIR_IDX,
+  DWARF_E_ADDR_OUTOFRANGE,
+  DWARF_E_NO_LOCLIST,
+  DWARF_E_NO_BLOCK,
+  DWARF_E_INVALID_LINE_IDX,
+  DWARF_E_INVALID_ARANGE_IDX,
+  DWARF_E_NO_MATCH,
+  DWARF_E_NO_FLAG,
+  DWARF_E_INVALID_OFFSET,
+  DWARF_E_NO_DEBUG_RANGES,
+  DWARF_E_INVALID_CFI,
+  DWARF_E_NO_ALT_DEBUGLINK,
+  DWARF_E_INVALID_OPCODE,
+  DWARF_E_NOT_CUDIE,
+  DWARF_E_UNKNOWN_LANGUAGE,
+};
+
+
+#include "dwarf_sig8_hash.h"
+
+/* This is the structure representing the debugging state.  */
+struct Dwarf
+{
+  /* The underlying ELF file.  */
+  Elf *elf;
+
+  /* dwz alternate DWARF file.  */
+  Dwarf *alt_dwarf;
+
+  /* The section data.  */
+  Elf_Data *sectiondata[IDX_last];
+
+  /* True if the file has a byte order different from the host.  */
+  bool other_byte_order;
+
+  /* If true, we allocated the ELF descriptor ourselves.  */
+  bool free_elf;
+
+  /* If >= 0, we allocated the alt_dwarf ourselves and must end it and
+     close this file descriptor.  */
+  int alt_fd;
+
+  /* Information for traversing the .debug_pubnames section.  This is
+     an array and separately allocated with malloc.  */
+  struct pubnames_s
+  {
+    Dwarf_Off cu_offset;
+    Dwarf_Off set_start;
+    unsigned int cu_header_size;
+    int address_len;
+  } *pubnames_sets;
+  size_t pubnames_nsets;
+
+  /* Search tree for the CUs.  */
+  void *cu_tree;
+  Dwarf_Off next_cu_offset;
+
+  /* Search tree and sig8 hash table for .debug_types type units.  */
+  void *tu_tree;
+  Dwarf_Off next_tu_offset;
+  Dwarf_Sig8_Hash sig8_hash;
+
+  /* Search tree for .debug_macro operator tables.  */
+  void *macro_ops;
+
+  /* Search tree for decoded .debug_line units.  */
+  void *files_lines;
+
+  /* Address ranges.  */
+  Dwarf_Aranges *aranges;
+
+  /* Cached info from the CFI section.  */
+  struct Dwarf_CFI_s *cfi;
+
+  /* Fake loc CU.  Used when synthesizing attributes for Dwarf_Ops that
+     came from a location list entry in dwarf_getlocation_attr.  */
+  struct Dwarf_CU *fake_loc_cu;
+
+  /* Internal memory handling.  This is basically a simplified
+     reimplementation of obstacks.  Unfortunately the standard obstack
+     implementation is not usable in libraries.  */
+  struct libdw_memblock
+  {
+    size_t size;
+    size_t remaining;
+    struct libdw_memblock *prev;
+    char mem[0];
+  } *mem_tail;
+
+  /* Default size of allocated memory blocks.  */
+  size_t mem_default_size;
+
+  /* Registered OOM handler.  */
+  Dwarf_OOM oom_handler;
+};
+
+
+/* Abbreviation representation.  */
+struct Dwarf_Abbrev
+{
+  Dwarf_Off offset;	  /* Offset to start of abbrev into .debug_abbrev.  */
+  unsigned char *attrp;   /* Pointer to start of attribute name/form pairs. */
+  bool has_children : 1;  /* Whether or not the DIE has children. */
+  unsigned int code : 31; /* The (unique) abbrev code.  */
+  unsigned int tag;	  /* The tag of the DIE. */
+} attribute_packed;
+
+#include "dwarf_abbrev_hash.h"
+
+
+/* Files in line information records.  */
+struct Dwarf_Files_s
+  {
+    unsigned int ndirs;
+    unsigned int nfiles;
+    struct Dwarf_Fileinfo_s
+    {
+      char *name;
+      Dwarf_Word mtime;
+      Dwarf_Word length;
+    } info[0];
+    /* nfiles of those, followed by char *[ndirs].  */
+  };
+typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
+
+
+/* Representation of a row in the line table.  */
+
+struct Dwarf_Line_s
+{
+  Dwarf_Files *files;
+
+  Dwarf_Addr addr;
+  unsigned int file;
+  int line;
+  unsigned short int column;
+  unsigned int is_stmt:1;
+  unsigned int basic_block:1;
+  unsigned int end_sequence:1;
+  unsigned int prologue_end:1;
+  unsigned int epilogue_begin:1;
+  /* The remaining bit fields are not flags, but hold values presumed to be
+     small.  All the flags and other bit fields should add up to 48 bits
+     to give the whole struct a nice round size.  */
+  unsigned int op_index:8;
+  unsigned int isa:8;
+  unsigned int discriminator:24;
+};
+
+struct Dwarf_Lines_s
+{
+  size_t nlines;
+  struct Dwarf_Line_s info[0];
+};
+
+/* Representation of address ranges.  */
+struct Dwarf_Aranges_s
+{
+  Dwarf *dbg;
+  size_t naranges;
+
+  struct Dwarf_Arange_s
+  {
+    Dwarf_Addr addr;
+    Dwarf_Word length;
+    Dwarf_Off offset;
+  } info[0];
+};
+
+
+/* CU representation.  */
+struct Dwarf_CU
+{
+  Dwarf *dbg;
+  Dwarf_Off start;
+  Dwarf_Off end;
+  uint8_t address_size;
+  uint8_t offset_size;
+  uint16_t version;
+
+  size_t sec_idx; /* Normally .debug_info, could be .debug_type or "fake". */
+
+  /* Zero if this is a normal CU.  Nonzero if it is a type unit.  */
+  size_t type_offset;
+  uint64_t type_sig8;
+
+  /* Hash table for the abbreviations.  */
+  Dwarf_Abbrev_Hash abbrev_hash;
+  /* Offset of the first abbreviation.  */
+  size_t orig_abbrev_offset;
+  /* Offset past last read abbreviation.  */
+  size_t last_abbrev_offset;
+
+  /* The srcline information.  */
+  Dwarf_Lines *lines;
+
+  /* The source file information.  */
+  Dwarf_Files *files;
+
+  /* Known location lists.  */
+  void *locs;
+
+  /* Memory boundaries of this CU.  */
+  void *startp;
+  void *endp;
+};
+
+/* Compute the offset of a CU's first DIE from its offset.  This
+   is either:
+        LEN       VER     OFFSET    ADDR
+      4-bytes + 2-bytes + 4-bytes + 1-byte  for 32-bit dwarf
+     12-bytes + 2-bytes + 8-bytes + 1-byte  for 64-bit dwarf
+   or in .debug_types, 			     SIGNATURE TYPE-OFFSET
+      4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes  for 32-bit
+     12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes  for 64-bit
+
+   Note the trick in the computation.  If the offset_size is 4
+   the '- 4' term changes the '3 *' into a '2 *'.  If the
+   offset_size is 8 it accounts for the 4-byte escape value
+   used at the start of the length.  */
+#define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size, type_unit)	\
+  ((type_unit) ? ((cu_offset) + 4 * (offset_size) - 4 + 3 + 8)		\
+   : ((cu_offset) + 3 * (offset_size) - 4 + 3))
+
+#define CUDIE(fromcu)							      \
+  ((Dwarf_Die)								      \
+   {									      \
+     .cu = (fromcu),							      \
+     .addr = ((char *) fromcu->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf   \
+	      + DIE_OFFSET_FROM_CU_OFFSET ((fromcu)->start,		      \
+					   (fromcu)->offset_size,	      \
+					   (fromcu)->type_offset != 0))	      \
+   })									      \
+
+
+/* Prototype of a single .debug_macro operator.  */
+typedef struct
+{
+  Dwarf_Word nforms;
+  unsigned char const *forms;
+} Dwarf_Macro_Op_Proto;
+
+/* Prototype table.  */
+typedef struct
+{
+  /* Offset of .debug_macro section.  */
+  Dwarf_Off offset;
+
+  /* Offset of associated .debug_line section.  */
+  Dwarf_Off line_offset;
+
+  /* The source file information.  */
+  Dwarf_Files *files;
+
+  /* If this macro unit was opened through dwarf_getmacros or
+     dwarf_getmacros_die, this caches value of DW_AT_comp_dir, if
+     present.  */
+  const char *comp_dir;
+
+  /* Header length.  */
+  Dwarf_Half header_len;
+
+  uint16_t version;
+  bool is_64bit;
+  uint8_t sec_index;	/* IDX_debug_macro or IDX_debug_macinfo.  */
+
+  /* Shows where in TABLE each opcode is defined.  Since opcode 0 is
+     never used, it stores index of opcode X in X-1'th element.  The
+     value of 0xff means not stored at all.  */
+  unsigned char opcodes[255];
+
+  /* Individual opcode prototypes.  */
+  Dwarf_Macro_Op_Proto table[];
+} Dwarf_Macro_Op_Table;
+
+struct Dwarf_Macro_s
+{
+  Dwarf_Macro_Op_Table *table;
+  Dwarf_Attribute *attributes;
+  uint8_t opcode;
+};
+
+static inline Dwarf_Word
+libdw_macro_nforms (Dwarf_Macro *macro)
+{
+  return macro->table->table[macro->table->opcodes[macro->opcode - 1]].nforms;
+}
+
+/* We have to include the file at this point because the inline
+   functions access internals of the Dwarf structure.  */
+#include "memory-access.h"
+
+
+/* Set error value.  */
+extern void __libdw_seterrno (int value) internal_function;
+
+
+/* Memory handling, the easy parts.  This macro does not do any locking.  */
+#define libdw_alloc(dbg, type, tsize, cnt) \
+  ({ struct libdw_memblock *_tail = (dbg)->mem_tail;			      \
+     size_t _required = (tsize) * (cnt);				      \
+     type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
+     size_t _padding = ((__alignof (type)				      \
+			 - ((uintptr_t) _result & (__alignof (type) - 1)))    \
+			& (__alignof (type) - 1));			      \
+     if (unlikely (_tail->remaining < _required + _padding))		      \
+       _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\
+     else								      \
+       {								      \
+	 _required += _padding;						      \
+	 _result = (type *) ((char *) _result + _padding);		      \
+	 _tail->remaining -= _required;					      \
+       }								      \
+     _result; })
+
+#define libdw_typed_alloc(dbg, type) \
+  libdw_alloc (dbg, type, sizeof (type), 1)
+
+/* Callback to allocate more.  */
+extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
+     __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
+
+/* Default OOM handler.  */
+extern void __libdw_oom (void) __attribute ((noreturn)) attribute_hidden;
+
+/* Allocate the internal data for a unit not seen before.  */
+extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
+     __nonnull_attribute__ (1) internal_function;
+
+/* Find CU for given offset.  */
+extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu)
+     __nonnull_attribute__ (1) internal_function;
+
+/* Get abbreviation with given code.  */
+extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
+					 unsigned int code)
+     __nonnull_attribute__ (1) internal_function;
+
+/* Get abbreviation at given offset.  */
+extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
+					Dwarf_Off offset, size_t *lengthp,
+					Dwarf_Abbrev *result)
+     __nonnull_attribute__ (1) internal_function;
+
+/* Get abbreviation of given DIE, and optionally set *READP to the DIE memory
+   just past the abbreviation code.  */
+static inline Dwarf_Abbrev *
+__nonnull_attribute__ (1)
+__libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
+{
+  /* Do we need to get the abbreviation, or need to read after the code?  */
+  if (die->abbrev == NULL || readp != NULL)
+    {
+      /* Get the abbreviation code.  */
+      unsigned int code;
+      const unsigned char *addr = die->addr;
+      get_uleb128 (code, addr, die->cu->endp);
+      if (readp != NULL)
+	*readp = addr;
+
+      /* Find the abbreviation.  */
+      if (die->abbrev == NULL)
+	die->abbrev = __libdw_findabbrev (die->cu, code);
+    }
+  return die->abbrev;
+}
+
+/* Helper functions for form handling.  */
+extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu,
+					    unsigned int form,
+					    const unsigned char *valp)
+     __nonnull_attribute__ (1, 3) internal_function;
+
+/* Find the length of a form attribute.  */
+static inline size_t
+__nonnull_attribute__ (1, 3)
+__libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form,
+		      const unsigned char *valp)
+{
+  /* Small lookup table of forms with fixed lengths.  Absent indexes are
+     initialized 0, so any truly desired 0 is set to 0x80 and masked.  */
+  static const uint8_t form_lengths[] =
+    {
+      [DW_FORM_flag_present] = 0x80,
+      [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1, [DW_FORM_flag] = 1,
+      [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2,
+      [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4,
+      [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sig8] = 8,
+    };
+
+  /* Return immediately for forms with fixed lengths.  */
+  if (form < sizeof form_lengths / sizeof form_lengths[0])
+    {
+      uint8_t len = form_lengths[form];
+      if (len != 0)
+	{
+	  const unsigned char *endp = cu->endp;
+	  len &= 0x7f; /* Mask to allow 0x80 -> 0.  */
+	  if (unlikely (len > (size_t) (endp - valp)))
+	    {
+	      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+	      return -1;
+	    }
+	  return len;
+	}
+    }
+
+  /* Other forms require some computation.  */
+  return __libdw_form_val_compute_len (cu, form, valp);
+}
+
+/* Helper function for DW_FORM_ref* handling.  */
+extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
+     __nonnull_attribute__ (1, 2) internal_function;
+
+
+/* Helper function to locate attribute.  */
+extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
+					 unsigned int search_name,
+					 unsigned int *codep,
+					 unsigned int *formp)
+     __nonnull_attribute__ (1) internal_function;
+
+/* Helper function to access integer attribute.  */
+extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
+     __nonnull_attribute__ (1, 2) internal_function;
+
+/* Helper function to walk scopes.  */
+struct Dwarf_Die_Chain
+{
+  Dwarf_Die die;
+  struct Dwarf_Die_Chain *parent;
+  bool prune;			/* The PREVISIT function can set this.  */
+};
+extern int __libdw_visit_scopes (unsigned int depth,
+				 struct Dwarf_Die_Chain *root,
+				 struct Dwarf_Die_Chain *imports,
+				 int (*previsit) (unsigned int depth,
+						  struct Dwarf_Die_Chain *,
+						  void *arg),
+				 int (*postvisit) (unsigned int depth,
+						   struct Dwarf_Die_Chain *,
+						   void *arg),
+				 void *arg)
+  __nonnull_attribute__ (2, 4) internal_function;
+
+/* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
+   and cache the result (via tsearch).  */
+extern int __libdw_intern_expression (Dwarf *dbg,
+				      bool other_byte_order,
+				      unsigned int address_size,
+				      unsigned int ref_size,
+				      void **cache, const Dwarf_Block *block,
+				      bool cfap, bool valuep,
+				      Dwarf_Op **llbuf, size_t *listlen,
+				      int sec_index)
+  __nonnull_attribute__ (5, 6, 9, 10) internal_function;
+
+extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
+				  Dwarf_Die *result, bool debug_types)
+  internal_function;
+
+
+/* Return error code of last failing function call.  This value is kept
+   separately for each thread.  */
+extern int __dwarf_errno_internal (void);
+
+
+/* Reader hooks.  */
+
+/* Relocation hooks return -1 on error (in that case the error code
+   must already have been set), 0 if there is no relocation and 1 if a
+   relocation was present.*/
+
+static inline int
+__libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
+			  int sec_index __attribute__ ((unused)),
+			  const void *addr __attribute__ ((unused)),
+			  int width __attribute__ ((unused)),
+			  Dwarf_Addr *val __attribute__ ((unused)))
+{
+  return 0;
+}
+
+static inline int
+__libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
+			 int sec_index __attribute__ ((unused)),
+			 const void *addr __attribute__ ((unused)),
+			 int width __attribute__ ((unused)),
+			 Dwarf_Off *val __attribute__ ((unused)))
+{
+  return 0;
+}
+
+static inline Elf_Data *
+__libdw_checked_get_data (Dwarf *dbg, int sec_index)
+{
+  Elf_Data *data = dbg->sectiondata[sec_index];
+  if (unlikely (data == NULL)
+      || unlikely (data->d_buf == NULL))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+  return data;
+}
+
+static inline int
+__libdw_offset_in_section (Dwarf *dbg, int sec_index,
+			   Dwarf_Off offset, size_t size)
+{
+  Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
+  if (data == NULL)
+    return -1;
+  if (unlikely (offset > data->d_size)
+      || unlikely (data->d_size < size)
+      || unlikely (offset > data->d_size - size))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+      return -1;
+    }
+
+  return 0;
+}
+
+static inline bool
+__libdw_in_section (Dwarf *dbg, int sec_index,
+		    const void *addr, size_t size)
+{
+  Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
+  if (data == NULL)
+    return false;
+  if (unlikely (addr < data->d_buf)
+      || unlikely (data->d_size < size)
+      || unlikely ((size_t)(addr - data->d_buf) > data->d_size - size))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_OFFSET);
+      return false;
+    }
+
+  return true;
+}
+
+#define READ_AND_RELOCATE(RELOC_HOOK, VAL)				\
+  ({									\
+    if (!__libdw_in_section (dbg, sec_index, addr, width))		\
+      return -1;							\
+									\
+    const unsigned char *orig_addr = addr;				\
+    if (width == 4)							\
+      VAL = read_4ubyte_unaligned_inc (dbg, addr);			\
+    else								\
+      VAL = read_8ubyte_unaligned_inc (dbg, addr);			\
+									\
+    int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL);	\
+    if (status < 0)							\
+      return status;							\
+    status > 0;								\
+   })
+
+static inline int
+__libdw_read_address_inc (Dwarf *dbg,
+			  int sec_index, const unsigned char **addrp,
+			  int width, Dwarf_Addr *ret)
+{
+  const unsigned char *addr = *addrp;
+  READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
+  *addrp = addr;
+  return 0;
+}
+
+static inline int
+__libdw_read_address (Dwarf *dbg,
+		      int sec_index, const unsigned char *addr,
+		      int width, Dwarf_Addr *ret)
+{
+  READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
+  return 0;
+}
+
+static inline int
+__libdw_read_offset_inc (Dwarf *dbg,
+			 int sec_index, const unsigned char **addrp,
+			 int width, Dwarf_Off *ret, int sec_ret,
+			 size_t size)
+{
+  const unsigned char *addr = *addrp;
+  READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
+  *addrp = addr;
+  return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
+}
+
+static inline int
+__libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret,
+		     int sec_index, const unsigned char *addr,
+		     int width, Dwarf_Off *ret, int sec_ret,
+		     size_t size)
+{
+  READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
+  return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size);
+}
+
+static inline size_t
+cu_sec_idx (struct Dwarf_CU *cu)
+{
+  return cu->sec_idx;
+}
+
+static inline bool
+is_cudie (Dwarf_Die *cudie)
+{
+  return CUDIE (cudie->cu).addr == cudie->addr;
+}
+
+/* Read up begin/end pair and increment read pointer.
+    - If it's normal range record, set up *BEGINP and *ENDP and return 0.
+    - If it's base address selection record, set up *BASEP and return 1.
+    - If it's end of rangelist, don't set anything and return 2
+    - If an error occurs, don't set anything and return <0.  */
+int __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
+				     unsigned char **addr, int width,
+				     Dwarf_Addr *beginp, Dwarf_Addr *endp,
+				     Dwarf_Addr *basep)
+  internal_function;
+
+unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
+				 int err_nodata, unsigned char **endpp,
+				 Dwarf_Off *offsetp)
+  internal_function;
+
+/* Fills in the given attribute to point at an empty location expression.  */
+void __libdw_empty_loc_attr (Dwarf_Attribute *attr)
+  internal_function;
+
+/* Load .debug_line unit at DEBUG_LINE_OFFSET.  COMP_DIR is a value of
+   DW_AT_comp_dir or NULL if that attribute is not available.  Caches
+   the loaded unit and optionally set *LINESP and/or *FILESP (if not
+   NULL) with loaded information.  Returns 0 for success or a negative
+   value for failure.  */
+int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
+			 const char *comp_dir, unsigned address_size,
+			 Dwarf_Lines **linesp, Dwarf_Files **filesp)
+  internal_function
+  __nonnull_attribute__ (1);
+
+/* Load and return value of DW_AT_comp_dir from CUDIE.  */
+const char *__libdw_getcompdir (Dwarf_Die *cudie);
+
+/* Given a file descriptor, dir and file returns a full path.  If the
+   file is absolute (starts with a /) a copy of file is returned.  If
+   the file isn't absolute, but dir is absolute, then a path that is
+   the concatenation of dir and file is returned.  If neither file,
+   nor dir is absolute, the path will be constructed using dir (if not
+   NULL) and file relative to the path of the given file descriptor
+   (if valid).
+
+   The file descriptor may be -1 and the dir may be NULL (in which
+   case they aren't used). If file is NULL, or no full path can be
+   constructed NULL is returned.
+
+   The caller is responsible for freeing the result if not NULL.  */
+char * filepath (int fd, const char *dir, const char *file)
+  internal_function;
+
+
+/* Aliases to avoid PLTs.  */
+INTDECL (dwarf_aggregate_size)
+INTDECL (dwarf_attr)
+INTDECL (dwarf_attr_integrate)
+INTDECL (dwarf_begin)
+INTDECL (dwarf_begin_elf)
+INTDECL (dwarf_child)
+INTDECL (dwarf_default_lower_bound)
+INTDECL (dwarf_dieoffset)
+INTDECL (dwarf_diename)
+INTDECL (dwarf_end)
+INTDECL (dwarf_entrypc)
+INTDECL (dwarf_errmsg)
+INTDECL (dwarf_formaddr)
+INTDECL (dwarf_formblock)
+INTDECL (dwarf_formref_die)
+INTDECL (dwarf_formsdata)
+INTDECL (dwarf_formstring)
+INTDECL (dwarf_formudata)
+INTDECL (dwarf_getalt)
+INTDECL (dwarf_getarange_addr)
+INTDECL (dwarf_getarangeinfo)
+INTDECL (dwarf_getaranges)
+INTDECL (dwarf_getlocation_die)
+INTDECL (dwarf_getsrcfiles)
+INTDECL (dwarf_getsrclines)
+INTDECL (dwarf_hasattr)
+INTDECL (dwarf_haschildren)
+INTDECL (dwarf_haspc)
+INTDECL (dwarf_highpc)
+INTDECL (dwarf_lowpc)
+INTDECL (dwarf_nextcu)
+INTDECL (dwarf_next_unit)
+INTDECL (dwarf_offdie)
+INTDECL (dwarf_peel_type)
+INTDECL (dwarf_ranges)
+INTDECL (dwarf_setalt)
+INTDECL (dwarf_siblingof)
+INTDECL (dwarf_srclang)
+INTDECL (dwarf_tag)
+
+#endif	/* libdwP.h */
diff --git a/third_party/elfutils/libdw/libdw_alloc.c b/third_party/elfutils/libdw/libdw_alloc.c
new file mode 100644
index 0000000..d6af23a
--- /dev/null
+++ b/third_party/elfutils/libdw/libdw_alloc.c
@@ -0,0 +1,78 @@
+/* Memory handling for libdw.
+   Copyright (C) 2003, 2004, 2006 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <error.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "libdwP.h"
+#include "system.h"
+
+
+void *
+__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
+{
+  size_t size = MAX (dbg->mem_default_size,
+		     (align - 1 +
+		      2 * minsize + offsetof (struct libdw_memblock, mem)));
+  struct libdw_memblock *newp = malloc (size);
+  if (newp == NULL)
+    dbg->oom_handler ();
+
+  uintptr_t result = ((uintptr_t) newp->mem + align - 1) & ~(align - 1);
+
+  newp->size = size - offsetof (struct libdw_memblock, mem);
+  newp->remaining = (uintptr_t) newp + size - (result + minsize);
+
+  newp->prev = dbg->mem_tail;
+  dbg->mem_tail = newp;
+
+  return (void *) result;
+}
+
+
+Dwarf_OOM
+dwarf_new_oom_handler (Dwarf *dbg, Dwarf_OOM handler)
+{
+  Dwarf_OOM old = dbg->oom_handler;
+  dbg->oom_handler = handler;
+  return old;
+}
+
+
+void
+__attribute ((noreturn)) attribute_hidden
+__libdw_oom (void)
+{
+  while (1)
+    error (EXIT_FAILURE, ENOMEM, "libdw");
+}
diff --git a/third_party/elfutils/libdw/libdw_findcu.c b/third_party/elfutils/libdw/libdw_findcu.c
new file mode 100644
index 0000000..4e025e2
--- /dev/null
+++ b/third_party/elfutils/libdw/libdw_findcu.c
@@ -0,0 +1,169 @@
+/* Find CU for given offset.
+   Copyright (C) 2003-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <search.h>
+#include "libdwP.h"
+
+static int
+findcu_cb (const void *arg1, const void *arg2)
+{
+  struct Dwarf_CU *cu1 = (struct Dwarf_CU *) arg1;
+  struct Dwarf_CU *cu2 = (struct Dwarf_CU *) arg2;
+
+  /* Find out which of the two arguments is the search value.  It has
+     end offset 0.  */
+  if (cu1->end == 0)
+    {
+      if (cu1->start < cu2->start)
+	return -1;
+      if (cu1->start >= cu2->end)
+	return 1;
+    }
+  else
+    {
+      if (cu2->start < cu1->start)
+	return 1;
+      if (cu2->start >= cu1->end)
+	return -1;
+    }
+
+  return 0;
+}
+
+struct Dwarf_CU *
+internal_function
+__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
+{
+  Dwarf_Off *const offsetp
+    = debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset;
+  void **tree = debug_types ? &dbg->tu_tree : &dbg->cu_tree;
+
+  Dwarf_Off oldoff = *offsetp;
+  uint16_t version;
+  uint8_t address_size;
+  uint8_t offset_size;
+  Dwarf_Off abbrev_offset;
+  uint64_t type_sig8 = 0;
+  Dwarf_Off type_offset = 0;
+
+  if (INTUSE(dwarf_next_unit) (dbg, oldoff, offsetp, NULL,
+			       &version, &abbrev_offset,
+			       &address_size, &offset_size,
+			       debug_types ? &type_sig8 : NULL,
+			       debug_types ? &type_offset : NULL) != 0)
+    /* No more entries.  */
+    return NULL;
+
+  /* We only know how to handle the DWARF version 2 through 4 formats.  */
+  if (unlikely (version < 2) || unlikely (version > 4))
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  /* Invalid or truncated debug section data?  */
+  size_t sec_idx = debug_types ? IDX_debug_types : IDX_debug_info;
+  Elf_Data *data = dbg->sectiondata[sec_idx];
+  if (unlikely (*offsetp > data->d_size))
+    *offsetp = data->d_size;
+
+  /* Create an entry for this CU.  */
+  struct Dwarf_CU *newp = libdw_typed_alloc (dbg, struct Dwarf_CU);
+
+  newp->dbg = dbg;
+  newp->sec_idx = sec_idx;
+  newp->start = oldoff;
+  newp->end = *offsetp;
+  newp->address_size = address_size;
+  newp->offset_size = offset_size;
+  newp->version = version;
+  newp->type_sig8 = type_sig8;
+  newp->type_offset = type_offset;
+  Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41);
+  newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset;
+  newp->lines = NULL;
+  newp->locs = NULL;
+
+  if (debug_types)
+    Dwarf_Sig8_Hash_insert (&dbg->sig8_hash, type_sig8, newp);
+
+  newp->startp = data->d_buf + newp->start;
+  newp->endp = data->d_buf + newp->end;
+
+  /* Add the new entry to the search tree.  */
+  if (tsearch (newp, tree, findcu_cb) == NULL)
+    {
+      /* Something went wrong.  Undo the operation.  */
+      *offsetp = oldoff;
+      __libdw_seterrno (DWARF_E_NOMEM);
+      return NULL;
+    }
+
+  return newp;
+}
+
+struct Dwarf_CU *
+internal_function
+__libdw_findcu (Dwarf *dbg, Dwarf_Off start, bool debug_types)
+{
+  void **tree = debug_types ? &dbg->tu_tree : &dbg->cu_tree;
+  Dwarf_Off *next_offset
+    = debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset;
+
+  /* Maybe we already know that CU.  */
+  struct Dwarf_CU fake = { .start = start, .end = 0 };
+  struct Dwarf_CU **found = tfind (&fake, tree, findcu_cb);
+  if (found != NULL)
+    return *found;
+
+  if (start < *next_offset)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      return NULL;
+    }
+
+  /* No.  Then read more CUs.  */
+  while (1)
+    {
+      struct Dwarf_CU *newp = __libdw_intern_next_unit (dbg, debug_types);
+      if (newp == NULL)
+	return NULL;
+
+      /* Is this the one we are looking for?  */
+      if (start < *next_offset)
+	// XXX Match exact offset.
+	return newp;
+    }
+  /* NOTREACHED */
+}
diff --git a/third_party/elfutils/libdw/libdw_form.c b/third_party/elfutils/libdw/libdw_form.c
new file mode 100644
index 0000000..72e2390
--- /dev/null
+++ b/third_party/elfutils/libdw/libdw_form.c
@@ -0,0 +1,132 @@
+/* Helper functions for form handling.
+   Copyright (C) 2003-2009, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <string.h>
+
+#include "libdwP.h"
+
+
+size_t
+internal_function
+__libdw_form_val_compute_len (struct Dwarf_CU *cu, unsigned int form,
+			      const unsigned char *valp)
+{
+  const unsigned char *startp = valp;
+  const unsigned char *endp = cu->endp;
+  Dwarf_Word u128;
+  size_t result;
+
+  /* NB: This doesn't cover constant form lengths, which are
+     already handled by the inlined __libdw_form_val_len.  */
+  switch (form)
+    {
+    case DW_FORM_addr:
+      result = cu->address_size;
+      break;
+
+    case DW_FORM_ref_addr:
+      result = cu->version == 2 ? cu->address_size : cu->offset_size;
+      break;
+
+    case DW_FORM_strp:
+    case DW_FORM_sec_offset:
+    case DW_FORM_GNU_ref_alt:
+    case DW_FORM_GNU_strp_alt:
+      result = cu->offset_size;
+      break;
+
+    case DW_FORM_block1:
+      if (unlikely ((size_t) (endp - startp) < 1))
+	goto invalid;
+      result = *valp + 1;
+      break;
+
+    case DW_FORM_block2:
+      if (unlikely ((size_t) (endp - startp) < 2))
+	goto invalid;
+      result = read_2ubyte_unaligned (cu->dbg, valp) + 2;
+      break;
+
+    case DW_FORM_block4:
+      if (unlikely ((size_t) (endp - startp) < 4))
+	goto invalid;
+      result = read_4ubyte_unaligned (cu->dbg, valp) + 4;
+      break;
+
+    case DW_FORM_block:
+    case DW_FORM_exprloc:
+      get_uleb128 (u128, valp, endp);
+      result = u128 + (valp - startp);
+      break;
+
+    case DW_FORM_string:
+      {
+	const unsigned char *endstrp = memchr (valp, '\0',
+					       (size_t) (endp - startp));
+	if (unlikely (endstrp == NULL))
+	  goto invalid;
+	result = (size_t) (endstrp - startp) + 1;
+	break;
+      }
+
+    case DW_FORM_sdata:
+    case DW_FORM_udata:
+    case DW_FORM_ref_udata:
+      get_uleb128 (u128, valp, endp);
+      result = valp - startp;
+      break;
+
+    case DW_FORM_indirect:
+      get_uleb128 (u128, valp, endp);
+      // XXX Is this really correct?
+      result = __libdw_form_val_len (cu, u128, valp);
+      if (result != (size_t) -1)
+	result += valp - startp;
+      else
+        return (size_t) -1;
+      break;
+
+    default:
+      goto invalid;
+    }
+
+  if (unlikely (result > (size_t) (endp - startp)))
+    {
+    invalid:
+      __libdw_seterrno (DWARF_E_INVALID_DWARF);
+      result = (size_t) -1;
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/libdw/libdw_visit_scopes.c b/third_party/elfutils/libdw/libdw_visit_scopes.c
new file mode 100644
index 0000000..eb892e1
--- /dev/null
+++ b/third_party/elfutils/libdw/libdw_visit_scopes.c
@@ -0,0 +1,188 @@
+/* Helper functions to descend DWARF scope trees.
+   Copyright (C) 2005,2006,2007,2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+
+static bool
+may_have_scopes (Dwarf_Die *die)
+{
+  switch (INTUSE(dwarf_tag) (die))
+    {
+      /* DIEs with addresses we can try to match.  */
+    case DW_TAG_compile_unit:
+    case DW_TAG_module:
+    case DW_TAG_lexical_block:
+    case DW_TAG_with_stmt:
+    case DW_TAG_catch_block:
+    case DW_TAG_try_block:
+    case DW_TAG_entry_point:
+    case DW_TAG_inlined_subroutine:
+    case DW_TAG_subprogram:
+      return true;
+
+      /* DIEs without addresses that can own DIEs with addresses.  */
+    case DW_TAG_namespace:
+    case DW_TAG_class_type:
+    case DW_TAG_structure_type:
+      return true;
+
+      /* Other DIEs we have no reason to descend.  */
+    default:
+      break;
+    }
+  return false;
+}
+
+struct walk_children_state
+{
+  /* Parameters of __libdw_visit_scopes. */
+  unsigned int depth;
+  struct Dwarf_Die_Chain *imports;
+  int (*previsit) (unsigned int depth, struct Dwarf_Die_Chain *, void *);
+  int (*postvisit) (unsigned int depth, struct Dwarf_Die_Chain *, void *);
+  void *arg;
+  /* Extra local variables for the walker. */
+  struct Dwarf_Die_Chain child;
+};
+
+static inline int
+walk_children (struct walk_children_state *state);
+
+int
+internal_function
+__libdw_visit_scopes (unsigned int depth, struct Dwarf_Die_Chain *root,
+		      struct Dwarf_Die_Chain *imports,
+		      int (*previsit) (unsigned int,
+				       struct Dwarf_Die_Chain *,
+				       void *),
+		      int (*postvisit) (unsigned int,
+					struct Dwarf_Die_Chain *,
+					void *),
+		      void *arg)
+{
+  struct walk_children_state state =
+    {
+      .depth = depth,
+      .imports = imports,
+      .previsit = previsit,
+      .postvisit = postvisit,
+      .arg = arg
+    };
+
+  state.child.parent = root;
+  int ret;
+  if ((ret = INTUSE(dwarf_child) (&root->die, &state.child.die)) != 0)
+    return ret < 0 ? -1 : 0; // Having zero children is legal.
+
+  return walk_children (&state);
+}
+
+static inline int
+walk_children (struct walk_children_state *state)
+{
+  int ret;
+  do
+    {
+      /* For an imported unit, it is logically as if the children of
+	 that unit are siblings of the other children.  So don't do
+	 a full recursion into the imported unit, but just walk the
+	 children in place before moving to the next real child.  */
+      while (INTUSE(dwarf_tag) (&state->child.die) == DW_TAG_imported_unit)
+	{
+	  Dwarf_Die orig_child_die = state->child.die;
+	  Dwarf_Attribute attr_mem;
+	  Dwarf_Attribute *attr = INTUSE(dwarf_attr) (&state->child.die,
+						      DW_AT_import,
+						      &attr_mem);
+	  if (INTUSE(dwarf_formref_die) (attr, &state->child.die) != NULL
+	      && INTUSE(dwarf_child) (&state->child.die, &state->child.die) == 0)
+	    {
+	      /* Checks the given DIE hasn't been imported yet
+	         to prevent cycles.  */
+	      bool imported = false;
+	      for (struct Dwarf_Die_Chain *import = state->imports; import != NULL;
+	        import = import->parent)
+	        if (import->die.addr == orig_child_die.addr)
+	          {
+	            imported = true;
+	            break;
+	          }
+	      if (imported)
+		{
+		  __libdw_seterrno (DWARF_E_INVALID_DWARF);
+		  return -1;
+		}
+	      struct Dwarf_Die_Chain *orig_imports = state->imports;
+	      struct Dwarf_Die_Chain import = { .die = orig_child_die,
+					        .parent = orig_imports };
+	      state->imports = &import;
+	      int result = walk_children (state);
+	      state->imports = orig_imports;
+	      if (result != DWARF_CB_OK)
+		return result;
+	    }
+
+	  /* Any "real" children left?  */
+	  if ((ret = INTUSE(dwarf_siblingof) (&orig_child_die,
+					      &state->child.die)) != 0)
+	    return ret < 0 ? -1 : 0;
+	};
+
+	state->child.prune = false;
+
+	/* previsit is declared NN */
+	int result = (*state->previsit) (state->depth + 1, &state->child, state->arg);
+	if (result != DWARF_CB_OK)
+	  return result;
+
+	if (!state->child.prune && may_have_scopes (&state->child.die)
+	    && INTUSE(dwarf_haschildren) (&state->child.die))
+	  {
+	    result = __libdw_visit_scopes (state->depth + 1, &state->child, state->imports,
+				           state->previsit, state->postvisit, state->arg);
+	    if (result != DWARF_CB_OK)
+	      return result;
+	  }
+
+	if (state->postvisit != NULL)
+	  {
+	    result = (*state->postvisit) (state->depth + 1, &state->child, state->arg);
+	    if (result != DWARF_CB_OK)
+	      return result;
+	  }
+    }
+  while ((ret = INTUSE(dwarf_siblingof) (&state->child.die, &state->child.die)) == 0);
+
+  return ret < 0 ? -1 : 0;
+}
diff --git a/third_party/elfutils/libdw/memory-access.h b/third_party/elfutils/libdw/memory-access.h
new file mode 100644
index 0000000..ed68bdb
--- /dev/null
+++ b/third_party/elfutils/libdw/memory-access.h
@@ -0,0 +1,305 @@
+/* Unaligned memory access functionality.
+   Copyright (C) 2000-2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _MEMORY_ACCESS_H
+#define _MEMORY_ACCESS_H 1
+
+#include <byteswap.h>
+#include <limits.h>
+#include <stdint.h>
+
+
+/* Number decoding macros.  See 7.6 Variable Length Data.  */
+
+#define len_leb128(var) ((8 * sizeof (var) + 6) / 7)
+
+static inline size_t
+__libdw_max_len_leb128 (const size_t type_len,
+			const unsigned char *addr, const unsigned char *end)
+{
+  const size_t pointer_len = likely (addr < end) ? end - addr : 0;
+  return likely (type_len <= pointer_len) ? type_len : pointer_len;
+}
+
+static inline size_t
+__libdw_max_len_uleb128 (const unsigned char *addr, const unsigned char *end)
+{
+  const size_t type_len = len_leb128 (uint64_t);
+  return __libdw_max_len_leb128 (type_len, addr, end);
+}
+
+static inline size_t
+__libdw_max_len_sleb128 (const unsigned char *addr, const unsigned char *end)
+{
+  /* Subtract one step, so we don't shift into sign bit.  */
+  const size_t type_len = len_leb128 (int64_t) - 1;
+  return __libdw_max_len_leb128 (type_len, addr, end);
+}
+
+#define get_uleb128_step(var, addr, nth)				      \
+  do {									      \
+    unsigned char __b = *(addr)++;					      \
+    (var) |= (typeof (var)) (__b & 0x7f) << ((nth) * 7);		      \
+    if (likely ((__b & 0x80) == 0))					      \
+      return (var);							      \
+  } while (0)
+
+static inline uint64_t
+__libdw_get_uleb128 (const unsigned char **addrp, const unsigned char *end)
+{
+  uint64_t acc = 0;
+
+  /* Unroll the first step to help the compiler optimize
+     for the common single-byte case.  */
+  get_uleb128_step (acc, *addrp, 0);
+
+  const size_t max = __libdw_max_len_uleb128 (*addrp - 1, end);
+  for (size_t i = 1; i < max; ++i)
+    get_uleb128_step (acc, *addrp, i);
+  /* Other implementations set VALUE to UINT_MAX in this
+     case.  So we better do this as well.  */
+  return UINT64_MAX;
+}
+
+static inline uint64_t
+__libdw_get_uleb128_unchecked (const unsigned char **addrp)
+{
+  uint64_t acc = 0;
+
+  /* Unroll the first step to help the compiler optimize
+     for the common single-byte case.  */
+  get_uleb128_step (acc, *addrp, 0);
+
+  const size_t max = len_leb128 (uint64_t);
+  for (size_t i = 1; i < max; ++i)
+    get_uleb128_step (acc, *addrp, i);
+  /* Other implementations set VALUE to UINT_MAX in this
+     case.  So we better do this as well.  */
+  return UINT64_MAX;
+}
+
+/* Note, addr needs to me smaller than end. */
+#define get_uleb128(var, addr, end) ((var) = __libdw_get_uleb128 (&(addr), end))
+#define get_uleb128_unchecked(var, addr) ((var) = __libdw_get_uleb128_unchecked (&(addr)))
+
+/* The signed case is similar, but we sign-extend the result.  */
+
+#define get_sleb128_step(var, addr, nth)				      \
+  do {									      \
+    unsigned char __b = *(addr)++;					      \
+    if (likely ((__b & 0x80) == 0))					      \
+      {									      \
+	struct { signed int i:7; } __s = { .i = __b };			      \
+	(var) |= (typeof (var)) __s.i * ((typeof (var)) 1 << ((nth) * 7));    \
+	return (var);							      \
+      }									      \
+    (var) |= (typeof (var)) (__b & 0x7f) << ((nth) * 7);		      \
+  } while (0)
+
+static inline int64_t
+__libdw_get_sleb128 (const unsigned char **addrp, const unsigned char *end)
+{
+  int64_t acc = 0;
+
+  /* Unroll the first step to help the compiler optimize
+     for the common single-byte case.  */
+  get_sleb128_step (acc, *addrp, 0);
+
+  const size_t max = __libdw_max_len_sleb128 (*addrp - 1, end);
+  for (size_t i = 1; i < max; ++i)
+    get_sleb128_step (acc, *addrp, i);
+  /* Other implementations set VALUE to INT_MAX in this
+     case.  So we better do this as well.  */
+  return INT64_MAX;
+}
+
+#define get_sleb128(var, addr, end) ((var) = __libdw_get_sleb128 (&(addr), end))
+
+
+/* We use simple memory access functions in case the hardware allows it.
+   The caller has to make sure we don't have alias problems.  */
+#if ALLOW_UNALIGNED
+
+# define read_2ubyte_unaligned(Dbg, Addr) \
+  (unlikely ((Dbg)->other_byte_order)					      \
+   ? bswap_16 (*((const uint16_t *) (Addr)))				      \
+   : *((const uint16_t *) (Addr)))
+# define read_2sbyte_unaligned(Dbg, Addr) \
+  (unlikely ((Dbg)->other_byte_order)					      \
+   ? (int16_t) bswap_16 (*((const int16_t *) (Addr)))			      \
+   : *((const int16_t *) (Addr)))
+
+# define read_4ubyte_unaligned_noncvt(Addr) \
+   *((const uint32_t *) (Addr))
+# define read_4ubyte_unaligned(Dbg, Addr) \
+  (unlikely ((Dbg)->other_byte_order)					      \
+   ? bswap_32 (*((const uint32_t *) (Addr)))				      \
+   : *((const uint32_t *) (Addr)))
+# define read_4sbyte_unaligned(Dbg, Addr) \
+  (unlikely ((Dbg)->other_byte_order)					      \
+   ? (int32_t) bswap_32 (*((const int32_t *) (Addr)))			      \
+   : *((const int32_t *) (Addr)))
+
+# define read_8ubyte_unaligned_noncvt(Addr) \
+   *((const uint64_t *) (Addr))
+# define read_8ubyte_unaligned(Dbg, Addr) \
+  (unlikely ((Dbg)->other_byte_order)					      \
+   ? bswap_64 (*((const uint64_t *) (Addr)))				      \
+   : *((const uint64_t *) (Addr)))
+# define read_8sbyte_unaligned(Dbg, Addr) \
+  (unlikely ((Dbg)->other_byte_order)					      \
+   ? (int64_t) bswap_64 (*((const int64_t *) (Addr)))			      \
+   : *((const int64_t *) (Addr)))
+
+#else
+
+union unaligned
+  {
+    void *p;
+    uint16_t u2;
+    uint32_t u4;
+    uint64_t u8;
+    int16_t s2;
+    int32_t s4;
+    int64_t s8;
+  } attribute_packed;
+
+# define read_2ubyte_unaligned(Dbg, Addr) \
+  read_2ubyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
+# define read_2sbyte_unaligned(Dbg, Addr) \
+  read_2sbyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
+# define read_4ubyte_unaligned(Dbg, Addr) \
+  read_4ubyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
+# define read_4sbyte_unaligned(Dbg, Addr) \
+  read_4sbyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
+# define read_8ubyte_unaligned(Dbg, Addr) \
+  read_8ubyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
+# define read_8sbyte_unaligned(Dbg, Addr) \
+  read_8sbyte_unaligned_1 ((Dbg)->other_byte_order, (Addr))
+
+static inline uint16_t
+read_2ubyte_unaligned_1 (bool other_byte_order, const void *p)
+{
+  const union unaligned *up = p;
+  if (unlikely (other_byte_order))
+    return bswap_16 (up->u2);
+  return up->u2;
+}
+static inline int16_t
+read_2sbyte_unaligned_1 (bool other_byte_order, const void *p)
+{
+  const union unaligned *up = p;
+  if (unlikely (other_byte_order))
+    return (int16_t) bswap_16 (up->u2);
+  return up->s2;
+}
+
+static inline uint32_t
+read_4ubyte_unaligned_noncvt (const void *p)
+{
+  const union unaligned *up = p;
+  return up->u4;
+}
+static inline uint32_t
+read_4ubyte_unaligned_1 (bool other_byte_order, const void *p)
+{
+  const union unaligned *up = p;
+  if (unlikely (other_byte_order))
+    return bswap_32 (up->u4);
+  return up->u4;
+}
+static inline int32_t
+read_4sbyte_unaligned_1 (bool other_byte_order, const void *p)
+{
+  const union unaligned *up = p;
+  if (unlikely (other_byte_order))
+    return (int32_t) bswap_32 (up->u4);
+  return up->s4;
+}
+
+static inline uint64_t
+read_8ubyte_unaligned_noncvt (const void *p)
+{
+  const union unaligned *up = p;
+  return up->u8;
+}
+static inline uint64_t
+read_8ubyte_unaligned_1 (bool other_byte_order, const void *p)
+{
+  const union unaligned *up = p;
+  if (unlikely (other_byte_order))
+    return bswap_64 (up->u8);
+  return up->u8;
+}
+static inline int64_t
+read_8sbyte_unaligned_1 (bool other_byte_order, const void *p)
+{
+  const union unaligned *up = p;
+  if (unlikely (other_byte_order))
+    return (int64_t) bswap_64 (up->u8);
+  return up->s8;
+}
+
+#endif	/* allow unaligned */
+
+
+#define read_2ubyte_unaligned_inc(Dbg, Addr) \
+  ({ uint16_t t_ = read_2ubyte_unaligned (Dbg, Addr);			      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2);		      \
+     t_; })
+#define read_2sbyte_unaligned_inc(Dbg, Addr) \
+  ({ int16_t t_ = read_2sbyte_unaligned (Dbg, Addr);			      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 2);		      \
+     t_; })
+
+#define read_4ubyte_unaligned_inc(Dbg, Addr) \
+  ({ uint32_t t_ = read_4ubyte_unaligned (Dbg, Addr);			      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4);		      \
+     t_; })
+#define read_4sbyte_unaligned_inc(Dbg, Addr) \
+  ({ int32_t t_ = read_4sbyte_unaligned (Dbg, Addr);			      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 4);		      \
+     t_; })
+
+#define read_8ubyte_unaligned_inc(Dbg, Addr) \
+  ({ uint64_t t_ = read_8ubyte_unaligned (Dbg, Addr);			      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8);		      \
+     t_; })
+#define read_8sbyte_unaligned_inc(Dbg, Addr) \
+  ({ int64_t t_ = read_8sbyte_unaligned (Dbg, Addr);			      \
+     Addr = (__typeof (Addr)) (((uintptr_t) (Addr)) + 8);		      \
+     t_; })
+
+
+#define read_addr_unaligned_inc(Nbytes, Dbg, Addr)			\
+  (assert ((Nbytes) == 4 || (Nbytes) == 8),				\
+    ((Nbytes) == 4 ? read_4ubyte_unaligned_inc (Dbg, Addr)		\
+     : read_8ubyte_unaligned_inc (Dbg, Addr)))
+
+#endif	/* memory-access.h */
diff --git a/third_party/elfutils/libdwelf/ChangeLog b/third_party/elfutils/libdwelf/ChangeLog
new file mode 100644
index 0000000..a332655
--- /dev/null
+++ b/third_party/elfutils/libdwelf/ChangeLog
@@ -0,0 +1,59 @@
+2015-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* dwelf_strtab.c: Remove sys/param.h include.
+	(MIN): Remove definition.
+
+2016-07-08  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libdwelf_a_SOURCES): Add dwelf_strtab.c.
+	* dwelf_strtab.c: New file.
+	* libdwelf.h (Dwelf_Strtab): New typedef.
+	(Dwelf_Strent): Likewise.
+	(dwelf_strtab_init): New function.
+	(dwelf_strtab_add): Likewise.
+	(dwelf_strtab_add_len): Likewise.
+	(dwelf_strtab_finalize): Likewise.
+	(dwelf_strent_off): Likewise.
+	(dwelf_strent_str): Likewise.
+	(dwelf_strtab_free): Likewise.
+
+2015-10-28  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libdwelf_a_SOURCES): Add
+	dwelf_scn_gnu_compressed_size.c.
+	* dwelf_scn_gnu_compressed_size.c: Likewise.
+	* libdwelf.h (dwelf_scn_gnu_compressed_size): New declaration.
+
+2015-10-14  Chih-Hung Hsieh  <chh@google.com>
+
+	* dwelf_elf_gnu_build_id.c (find_elf_build_id): Move nested function
+	'check_notes' to file scope.
+
+2014-11-14  Mark Wielaard  <mjw@redhat.com>
+
+	* dwelf_elf_gnu_debuglink.c (dwelf_elf_gnu_debuglink): Check d_buf
+	is not NULL.
+
+2014-04-30  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (AM_CPPFLAGS): Add libdwfl and libebl include dirs.
+	(libdwelf_a_SOURCES): Add dwelf_elf_gnu_build_id.c
+	* dwelf_elf_gnu_build_id.c: New file. Moved libdwfl function
+	__libdwfl_find_elf_build_id here.
+	* libdwelf.h (dwelf_elf_gnu_build_id): Declare new function.
+	* libdwelfP.h (dwelf_elf_gnu_build_id): Add internal declaration.
+
+2014-04-24  Florian Weimer  <fweimer@redhat.com>
+
+	* dwelf_dwarf_gnu_debugaltlink.c: New file.
+	* Makefile.am (libdwelf_a_SOURCES): Add it.
+	* libdwelf.h (dwelf_dwarf_gnu_debugaltlink): Declare new function.
+	* libdwelfP.h (dwelf_dwarf_gnu_debugaltlink): Add internal
+	declaration.
+
+2014-04-11  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: New file.
+	* libdwelf.h: Likewise.
+	* libdwelfP.h: Likewise.
+	* dwelf_elf_gnu_debuglink.c: Likewise.
diff --git a/third_party/elfutils/libdwelf/Makefile.am b/third_party/elfutils/libdwelf/Makefile.am
new file mode 100644
index 0000000..7ca767a
--- /dev/null
+++ b/third_party/elfutils/libdwelf/Makefile.am
@@ -0,0 +1,56 @@
+## Makefile.am for libdwelf library subdirectory in elfutils.
+##
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 2014, 2015 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * 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
+##
+## or both in parallel, as here.
+##
+## elfutils 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.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libdw \
+	       -I$(srcdir)/../libdwfl -I$(srcdir)/../libebl
+VERSION = 1
+
+noinst_LIBRARIES = libdwelf.a libdwelf_pic.a
+
+pkginclude_HEADERS = libdwelf.h
+noinst_HEADERS = libdwelfP.h
+
+libdwelf_a_SOURCES = dwelf_elf_gnu_debuglink.c dwelf_dwarf_gnu_debugaltlink.c \
+		     dwelf_elf_gnu_build_id.c dwelf_scn_gnu_compressed_size.c \
+		     dwelf_strtab.c
+
+libdwelf = $(libdw)
+
+libdw = ../libdw/libdw.so
+libelf = ../libelf/libelf.so
+libebl = ../libebl/libebl.a
+libeu = ../lib/libeu.a
+
+libdwelf_pic_a_SOURCES =
+am_libdwelf_pic_a_OBJECTS = $(libdwelf_a_SOURCES:.c=.os)
+
+CLEANFILES += $(am_libdwelf_pic_a_OBJECTS)
diff --git a/third_party/elfutils/libdwelf/dwelf_dwarf_gnu_debugaltlink.c b/third_party/elfutils/libdwelf/dwelf_dwarf_gnu_debugaltlink.c
new file mode 100644
index 0000000..b8285d0
--- /dev/null
+++ b/third_party/elfutils/libdwelf/dwelf_dwarf_gnu_debugaltlink.c
@@ -0,0 +1,62 @@
+/* Returns the file name and build ID stored in the .gnu_altdebuglink if found.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwelfP.h"
+
+ssize_t
+dwelf_dwarf_gnu_debugaltlink (Dwarf *dwarf,
+			      const char **name_p,
+			      const void **build_idp)
+{
+  Elf_Data *data = dwarf->sectiondata[IDX_gnu_debugaltlink];
+  if (data == NULL)
+    {
+      return 0;
+    }
+
+  const void *ptr = memchr (data->d_buf, '\0', data->d_size);
+  if (ptr == NULL)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_ELF);
+      return -1;
+    }
+  size_t build_id_len = data->d_size - (ptr - data->d_buf + 1);
+  if (build_id_len == 0 || (size_t) (ssize_t) build_id_len != build_id_len)
+    {
+      __libdw_seterrno (DWARF_E_INVALID_ELF);
+      return -1;
+    }
+  *name_p = data->d_buf;
+  *build_idp = ptr + 1;
+  return build_id_len;
+}
+INTDEF(dwelf_dwarf_gnu_debugaltlink)
diff --git a/third_party/elfutils/libdwelf/dwelf_elf_gnu_build_id.c b/third_party/elfutils/libdwelf/dwelf_elf_gnu_build_id.c
new file mode 100644
index 0000000..8c78c70
--- /dev/null
+++ b/third_party/elfutils/libdwelf/dwelf_elf_gnu_build_id.c
@@ -0,0 +1,156 @@
+/* Returns the build id if found in a NT_GNU_BUILD_ID note.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwelfP.h"
+#include "libdwflP.h"
+
+#define NO_VADDR	((GElf_Addr) -1l)
+
+static int
+check_notes (Elf_Data *data, GElf_Addr data_elfaddr,
+             const void **build_id_bits, GElf_Addr *build_id_elfaddr,
+             int *build_id_len)
+{
+  size_t pos = 0;
+  GElf_Nhdr nhdr;
+  size_t name_pos;
+  size_t desc_pos;
+  while ((pos = gelf_getnote (data, pos, &nhdr, &name_pos, &desc_pos)) > 0)
+    if (nhdr.n_type == NT_GNU_BUILD_ID
+	&& nhdr.n_namesz == sizeof "GNU"
+	&& !memcmp (data->d_buf + name_pos, "GNU", sizeof "GNU"))
+	{
+	  *build_id_bits = data->d_buf + desc_pos;
+	  *build_id_elfaddr = (data_elfaddr == NO_VADDR
+	                      ? 0 : data_elfaddr + desc_pos);
+	  *build_id_len = nhdr.n_descsz;
+	  return 1;
+	}
+  return 0;
+}
+
+/* Defined here for reuse. The dwelf interface doesn't care about the
+   address of the note, but libdwfl does.  */
+static int
+find_elf_build_id (Dwfl_Module *mod, int e_type, Elf *elf,
+		   const void **build_id_bits, GElf_Addr *build_id_elfaddr,
+		   int *build_id_len)
+{
+  size_t shstrndx = SHN_UNDEF;
+  int result = 0;
+
+  Elf_Scn *scn = elf_nextscn (elf, NULL);
+
+  if (scn == NULL)
+    {
+      /* No sections, have to look for phdrs.  */
+      size_t phnum;
+      if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
+	{
+	  if (mod != NULL)
+	    __libdwfl_seterrno (DWFL_E_LIBELF);
+	  return -1;
+	}
+      for (size_t i = 0; result == 0 && i < phnum; ++i)
+	{
+	  GElf_Phdr phdr_mem;
+	  GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
+	  if (likely (phdr != NULL) && phdr->p_type == PT_NOTE)
+	    result = check_notes (elf_getdata_rawchunk (elf,
+							phdr->p_offset,
+							phdr->p_filesz,
+							ELF_T_NHDR),
+				  phdr->p_vaddr,
+				  build_id_bits,
+				  build_id_elfaddr,
+				  build_id_len);
+	}
+    }
+  else
+    do
+      {
+	GElf_Shdr shdr_mem;
+	GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	if (likely (shdr != NULL) && shdr->sh_type == SHT_NOTE)
+	  {
+	    /* Determine the right sh_addr in this module.  */
+	    GElf_Addr vaddr = 0;
+	    if (!(shdr->sh_flags & SHF_ALLOC))
+	      vaddr = NO_VADDR;
+	    else if (mod == NULL || e_type != ET_REL)
+	      vaddr = shdr->sh_addr;
+	    else if (__libdwfl_relocate_value (mod, elf, &shstrndx,
+					       elf_ndxscn (scn), &vaddr))
+	      vaddr = NO_VADDR;
+	    result = check_notes (elf_getdata (scn, NULL), vaddr,
+	                          build_id_bits,
+	                          build_id_elfaddr,
+	                          build_id_len);
+	  }
+      }
+    while (result == 0 && (scn = elf_nextscn (elf, scn)) != NULL);
+
+  return result;
+}
+
+int
+internal_function
+__libdwfl_find_elf_build_id (Dwfl_Module *mod, Elf *elf,
+			     const void **build_id_bits,
+			     GElf_Addr *build_id_elfaddr, int *build_id_len)
+{
+  GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (unlikely (ehdr == NULL))
+    {
+      __libdwfl_seterrno (DWFL_E_LIBELF);
+      return -1;
+    }
+  // MOD->E_TYPE is zero here.
+  assert (ehdr->e_type != ET_REL || mod != NULL);
+
+  return find_elf_build_id (mod, ehdr->e_type, elf,
+			    build_id_bits, build_id_elfaddr, build_id_len);
+}
+
+ssize_t
+dwelf_elf_gnu_build_id (Elf *elf, const void **build_idp)
+{
+  GElf_Addr build_id_elfaddr;
+  int build_id_len;
+  int result = find_elf_build_id (NULL, ET_NONE, elf, build_idp,
+				  &build_id_elfaddr, &build_id_len);
+  if (result > 0)
+    return build_id_len;
+
+  return result;
+}
+INTDEF(dwelf_elf_gnu_build_id)
diff --git a/third_party/elfutils/libdwelf/dwelf_elf_gnu_debuglink.c b/third_party/elfutils/libdwelf/dwelf_elf_gnu_debuglink.c
new file mode 100644
index 0000000..6e22cf6
--- /dev/null
+++ b/third_party/elfutils/libdwelf/dwelf_elf_gnu_debuglink.c
@@ -0,0 +1,99 @@
+/* Returns the file name and crc stored in the .gnu_debuglink if found.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwelfP.h"
+
+const char *
+dwelf_elf_gnu_debuglink (Elf *elf, GElf_Word *crc)
+{
+  size_t shstrndx;
+  if (elf_getshdrstrndx (elf, &shstrndx) < 0)
+    return NULL;
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+        return NULL;
+
+      const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
+      if (name == NULL)
+        return NULL;
+
+      if (!strcmp (name, ".gnu_debuglink"))
+        break;
+    }
+
+  if (scn == NULL)
+    return NULL;
+
+  /* Found the .gnu_debuglink section.  Extract its contents.  */
+  Elf_Data *rawdata = elf_rawdata (scn, NULL);
+  if (rawdata == NULL || rawdata->d_buf == NULL)
+    return NULL;
+
+  /* The CRC comes after the zero-terminated file name,
+     (aligned up to 4 bytes) at the end of the section data.  */
+  if (rawdata->d_size <= sizeof *crc
+      || memchr (rawdata->d_buf, '\0', rawdata->d_size - sizeof *crc) == NULL)
+    return NULL;
+
+  Elf_Data crcdata =
+    {
+      .d_type = ELF_T_WORD,
+      .d_buf = crc,
+      .d_size = sizeof *crc,
+      .d_version = EV_CURRENT,
+    };
+  Elf_Data conv =
+    {
+      .d_type = ELF_T_WORD,
+      .d_buf = rawdata->d_buf + rawdata->d_size - sizeof *crc,
+      .d_size = sizeof *crc,
+      .d_version = EV_CURRENT,
+    };
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    return NULL;
+
+  Elf_Data *d = gelf_xlatetom (elf, &crcdata, &conv, ehdr->e_ident[EI_DATA]);
+  if (d == NULL)
+    return NULL;
+  assert (d == &crcdata);
+
+  return rawdata->d_buf;
+}
+INTDEF(dwelf_elf_gnu_debuglink)
diff --git a/third_party/elfutils/libdwelf/dwelf_scn_gnu_compressed_size.c b/third_party/elfutils/libdwelf/dwelf_scn_gnu_compressed_size.c
new file mode 100644
index 0000000..d39b702
--- /dev/null
+++ b/third_party/elfutils/libdwelf/dwelf_scn_gnu_compressed_size.c
@@ -0,0 +1,77 @@
+/* Return size of GNU compressed section.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwelfP.h"
+#include "libelfP.h"
+
+ssize_t
+dwelf_scn_gnu_compressed_size (Elf_Scn *scn)
+{
+  if (scn == NULL)
+    return -1;
+
+  GElf_Shdr shdr;
+  if (gelf_getshdr (scn, &shdr) == NULL)
+    return -1;
+
+  /* Allocated or no bits sections can never be compressed.  */
+  if ((shdr.sh_flags & SHF_ALLOC) != 0
+      || shdr.sh_type == SHT_NULL
+      || shdr.sh_type == SHT_NOBITS)
+    return -1;
+
+  Elf_Data *d = elf_rawdata (scn, NULL);
+  if (d == NULL)
+    return -1;
+
+  if (d->d_size >= 4 + 8
+      && memcmp (d->d_buf, "ZLIB", 4) == 0)
+    {
+      /* There is a 12-byte header of "ZLIB" followed by
+	 an 8-byte big-endian size.  There is only one type and
+	 alignment isn't preserved separately.  */
+      uint64_t size;
+      memcpy (&size, d->d_buf + 4, sizeof size);
+      size = be64toh (size);
+
+      /* One more sanity check, size should be bigger than original
+	 data size plus some overhead (4 chars ZLIB + 8 bytes size + 6
+	 bytes zlib stream overhead + 5 bytes overhead max for one 16K
+	 block) and should fit into a size_t.  */
+      if (size + 4 + 8 + 6 + 5 < d->d_size || size > SIZE_MAX)
+	return -1;
+
+      return size;
+    }
+
+  return -1;
+}
diff --git a/third_party/elfutils/libdwelf/dwelf_strtab.c b/third_party/elfutils/libdwelf/dwelf_strtab.c
new file mode 100644
index 0000000..01e091c
--- /dev/null
+++ b/third_party/elfutils/libdwelf/dwelf_strtab.c
@@ -0,0 +1,360 @@
+/* ELF/DWARF string table handling.
+   Copyright (C) 2000, 2001, 2002, 2005, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libdwelfP.h"
+#include <system.h>
+
+
+struct Dwelf_Strent
+{
+  const char *string;
+  size_t len;
+  struct Dwelf_Strent *next;
+  struct Dwelf_Strent *left;
+  struct Dwelf_Strent *right;
+  size_t offset;
+  char reverse[0];
+};
+
+
+struct memoryblock
+{
+  struct memoryblock *next;
+  char memory[0];
+};
+
+
+struct Dwelf_Strtab
+{
+  struct Dwelf_Strent *root;
+  struct memoryblock *memory;
+  char *backp;
+  size_t left;
+  size_t total;
+  bool nullstr;
+
+  struct Dwelf_Strent null;
+};
+
+
+/* Cache for the pagesize.  */
+static size_t ps;
+/* We correct this value a bit so that `malloc' is not allocating more
+   than a page. */
+#define MALLOC_OVERHEAD (2 * sizeof (void *))
+
+
+Dwelf_Strtab *
+dwelf_strtab_init (bool nullstr)
+{
+  if (ps == 0)
+    {
+      ps = sysconf (_SC_PAGESIZE);
+      assert (sizeof (struct memoryblock) < ps - MALLOC_OVERHEAD);
+    }
+
+  Dwelf_Strtab *ret
+    = (Dwelf_Strtab *) calloc (1, sizeof (struct Dwelf_Strtab));
+  if (ret != NULL)
+    {
+      ret->nullstr = nullstr;
+
+      if (nullstr)
+	{
+	  ret->null.len = 1;
+	  ret->null.string = "";
+	}
+    }
+
+  return ret;
+}
+
+
+static int
+morememory (Dwelf_Strtab *st, size_t len)
+{
+  size_t overhead = offsetof (struct memoryblock, memory);
+  len += overhead + MALLOC_OVERHEAD;
+
+  /* Allocate nearest multiple of pagesize >= len.  */
+  len = ((len / ps) + (len % ps != 0)) * ps - MALLOC_OVERHEAD;
+
+  struct memoryblock *newmem = (struct memoryblock *) malloc (len);
+  if (newmem == NULL)
+    return 1;
+
+  newmem->next = st->memory;
+  st->memory = newmem;
+  st->backp = newmem->memory;
+  st->left = len - overhead;
+
+  return 0;
+}
+
+
+void
+dwelf_strtab_free (Dwelf_Strtab *st)
+{
+  struct memoryblock *mb = st->memory;
+
+  while (mb != NULL)
+    {
+      void *old = mb;
+      mb = mb->next;
+      free (old);
+    }
+
+  free (st);
+}
+
+
+static Dwelf_Strent *
+newstring (Dwelf_Strtab *st, const char *str, size_t len)
+{
+  /* Compute the amount of padding needed to make the structure aligned.  */
+  size_t align = ((__alignof__ (struct Dwelf_Strent)
+		   - (((uintptr_t) st->backp)
+		      & (__alignof__ (struct Dwelf_Strent) - 1)))
+		  & (__alignof__ (struct Dwelf_Strent) - 1));
+
+  /* Make sure there is enough room in the memory block.  */
+  if (st->left < align + sizeof (struct Dwelf_Strent) + len)
+    {
+      if (morememory (st, sizeof (struct Dwelf_Strent) + len))
+	return NULL;
+
+      align = 0;
+    }
+
+  /* Create the reserved string.  */
+  Dwelf_Strent *newstr = (Dwelf_Strent *) (st->backp + align);
+  newstr->string = str;
+  newstr->len = len;
+  newstr->next = NULL;
+  newstr->left = NULL;
+  newstr->right = NULL;
+  newstr->offset = 0;
+  for (int i = len - 2; i >= 0; --i)
+    newstr->reverse[i] = str[len - 2 - i];
+  newstr->reverse[len - 1] = '\0';
+  st->backp += align + sizeof (struct Dwelf_Strent) + len;
+  st->left -= align + sizeof (struct Dwelf_Strent) + len;
+
+  return newstr;
+}
+
+
+/* XXX This function should definitely be rewritten to use a balancing
+   tree algorith (AVL, red-black trees).  For now a simple, correct
+   implementation is enough.  */
+static Dwelf_Strent **
+searchstring (Dwelf_Strent **sep, Dwelf_Strent *newstr)
+{
+  /* More strings?  */
+  if (*sep == NULL)
+    {
+      *sep = newstr;
+      return sep;
+    }
+
+  /* Compare the strings.  */
+  int cmpres = memcmp ((*sep)->reverse, newstr->reverse,
+		       MIN ((*sep)->len, newstr->len) - 1);
+  if (cmpres == 0)
+    /* We found a matching string.  */
+    return sep;
+  else if (cmpres > 0)
+    return searchstring (&(*sep)->left, newstr);
+  else
+    return searchstring (&(*sep)->right, newstr);
+}
+
+
+/* Add new string.  The actual string is assumed to be permanent.  */
+static Dwelf_Strent *
+strtab_add (Dwelf_Strtab *st, const char *str, size_t len)
+{
+  /* Make sure all "" strings get offset 0 but only if the table was
+     created with a special null entry in mind.  */
+  if (len == 1 && st->null.string != NULL)
+    return &st->null;
+
+  /* Allocate memory for the new string and its associated information.  */
+  Dwelf_Strent *newstr = newstring (st, str, len);
+  if (newstr == NULL)
+    return NULL;
+
+  /* Search in the array for the place to insert the string.  If there
+     is no string with matching prefix and no string with matching
+     leading substring, create a new entry.  */
+  Dwelf_Strent **sep = searchstring (&st->root, newstr);
+  if (*sep != newstr)
+    {
+      /* This is not the same entry.  This means we have a prefix match.  */
+      if ((*sep)->len > newstr->len)
+	{
+	  /* Check whether we already know this string.  */
+	  for (Dwelf_Strent *subs = (*sep)->next; subs != NULL;
+	       subs = subs->next)
+	    if (subs->len == newstr->len)
+	      {
+		/* We have an exact match with a substring.  Free the memory
+		   we allocated.  */
+		st->left += st->backp - (char *) newstr;
+		st->backp = (char *) newstr;
+
+		return subs;
+	      }
+
+	  /* We have a new substring.  This means we don't need the reverse
+	     string of this entry anymore.  */
+	  st->backp -= newstr->len;
+	  st->left += newstr->len;
+
+	  newstr->next = (*sep)->next;
+	  (*sep)->next = newstr;
+	}
+      else if ((*sep)->len != newstr->len)
+	{
+	  /* When we get here it means that the string we are about to
+	     add has a common prefix with a string we already have but
+	     it is longer.  In this case we have to put it first.  */
+	  st->total += newstr->len - (*sep)->len;
+	  newstr->next = *sep;
+	  newstr->left = (*sep)->left;
+	  newstr->right = (*sep)->right;
+	  *sep = newstr;
+	}
+      else
+	{
+	  /* We have an exact match.  Free the memory we allocated.  */
+	  st->left += st->backp - (char *) newstr;
+	  st->backp = (char *) newstr;
+
+	  newstr = *sep;
+	}
+    }
+  else
+    st->total += newstr->len;
+
+  return newstr;
+}
+
+Dwelf_Strent *
+dwelf_strtab_add (Dwelf_Strtab *st, const char *str)
+{
+  return strtab_add (st, str, strlen (str) + 1);
+}
+
+Dwelf_Strent *
+dwelf_strtab_add_len (Dwelf_Strtab *st, const char *str, size_t len)
+{
+  return strtab_add (st, str, len);
+}
+
+static void
+copystrings (Dwelf_Strent *nodep, char **freep, size_t *offsetp)
+{
+  if (nodep->left != NULL)
+    copystrings (nodep->left, freep, offsetp);
+
+  /* Process the current node.  */
+  nodep->offset = *offsetp;
+  *freep = (char *) mempcpy (*freep, nodep->string, nodep->len);
+  *offsetp += nodep->len;
+
+  for (Dwelf_Strent *subs = nodep->next; subs != NULL; subs = subs->next)
+    {
+      assert (subs->len < nodep->len);
+      subs->offset = nodep->offset + nodep->len - subs->len;
+      assert (subs->offset != 0 || subs->string[0] == '\0');
+    }
+
+  if (nodep->right != NULL)
+    copystrings (nodep->right, freep, offsetp);
+}
+
+
+Elf_Data *
+dwelf_strtab_finalize (Dwelf_Strtab *st, Elf_Data *data)
+{
+  size_t nulllen = st->nullstr ? 1 : 0;
+
+  /* Fill in the information.  */
+  data->d_buf = malloc (st->total + nulllen);
+  if (data->d_buf == NULL)
+    return NULL;
+
+  /* The first byte must always be zero if we created the table with a
+     null string.  */
+  if (st->nullstr)
+    *((char *) data->d_buf) = '\0';
+
+  data->d_type = ELF_T_BYTE;
+  data->d_size = st->total + nulllen;
+  data->d_off = 0;
+  data->d_align = 1;
+  data->d_version = EV_CURRENT;
+
+  /* Now run through the tree and add all the string while also updating
+     the offset members of the elfstrent records.  */
+  char *endp = (char *) data->d_buf + nulllen;
+  size_t copylen = nulllen;
+  if (st->root)
+    copystrings (st->root, &endp, &copylen);
+  assert (copylen == st->total + nulllen);
+
+  return data;
+}
+
+
+size_t
+dwelf_strent_off (Dwelf_Strent *se)
+{
+  return se->offset;
+}
+
+
+const char *
+dwelf_strent_str (Dwelf_Strent *se)
+{
+  return se->string;
+}
diff --git a/third_party/elfutils/libdwelf/libdwelf.h b/third_party/elfutils/libdwelf/libdwelf.h
new file mode 100644
index 0000000..72089db
--- /dev/null
+++ b/third_party/elfutils/libdwelf/libdwelf.h
@@ -0,0 +1,132 @@
+/* Interfaces for libdwelf. DWARF ELF Low-level Functions.
+   Copyright (C) 2014, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBDWELF_H
+#define _LIBDWELF_H	1
+
+#include "libdw.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* DWARF ELF Low-level Functions (dwelf).
+   Functions starting with dwelf_elf will take a (libelf) Elf object as
+   first argument and might set elf_errno on error.  Functions starting
+   with dwelf_dwarf will take a (libdw) Dwarf object as first argument
+   and might set dwarf_errno on error.  */
+
+/* Returns the name and the CRC32 of the separate debug file from the
+   .gnu_debuglink section if found in the ELF.  Return NULL if the ELF
+   file didn't have a .gnu_debuglink section, had malformed data in the
+   section or some other error occured.  */
+extern const char *dwelf_elf_gnu_debuglink (Elf *elf, GElf_Word *crc);
+
+/* Returns the name and build ID from the .gnu_debugaltlink section if
+   found in the ELF.  On success, pointers to the name and build ID
+   are written to *NAMEP and *BUILDID_P, and the positive length of
+   the build ID is returned.  Returns 0 if the ELF lacks a
+   .gnu_debugaltlink section.  Returns -1 in case of malformed data or
+   other errors.  */
+extern ssize_t dwelf_dwarf_gnu_debugaltlink (Dwarf *dwarf,
+					     const char **namep,
+					     const void **build_idp);
+
+/* Returns the build ID as found in a NT_GNU_BUILD_ID note from either
+   a SHT_NOTE section or from a PT_NOTE segment if the ELF file
+   doesn't contain any section headers.  On success a pointer to the
+   build ID is written to *BUILDID_P, and the positive length of the
+   build ID is returned.  Returns 0 if the ELF lacks a NT_GNU_BUILD_ID
+   note.  Returns -1 in case of malformed data or other errors.  */
+extern ssize_t dwelf_elf_gnu_build_id (Elf *elf, const void **build_idp);
+
+/* Returns the size of the uncompressed data of a GNU compressed
+   section.  The section name should start with .zdebug (but this
+   isn't checked by this function).  If the section isn't compressed
+   (the section data doesn't start with ZLIB) -1 is returned. If an
+   error occured -1 is returned and elf_errno is set.  */
+extern ssize_t dwelf_scn_gnu_compressed_size (Elf_Scn *scn);
+
+/* ELF/DWARF string table handling.  */
+typedef struct Dwelf_Strtab Dwelf_Strtab;
+typedef struct Dwelf_Strent Dwelf_Strent;
+
+/* Create a new ELF/DWARF string table object in memory.  ELF string
+   tables have a required zero length null string at offset zero.
+   DWARF string tables don't require such a null entry (unless they
+   are shared with an ELF string table).  If NULLSTR is true then a
+   null entry is always created (even if the string table is empty
+   otherwise).  */
+extern Dwelf_Strtab *dwelf_strtab_init (bool nullstr);
+
+/* Add string STR to string table ST.  Returns NULL if no memory could
+   be allocated.  The given STR is owned by the called and must be
+   valid till dwelf_strtab_free is called.  dwelf_strtab_finalize
+   might copy the string into the final table and dwelf_strent_str
+   might return it, or a reference to an identical copy/substring
+   added to the string table.  */
+extern Dwelf_Strent *dwelf_strtab_add (Dwelf_Strtab *st, const char *str)
+  __nonnull_attribute__ (1, 2);
+
+/* This is an optimized version of dwelf_strtab_add if the length of
+   the string is already known.  LEN is the length of STR including
+   zero terminator.  Calling dwelf_strtab_add (st, str) is similar to
+   calling dwelf_strtab_len (st, str, strlen (str) + 1).  */
+extern Dwelf_Strent *dwelf_strtab_add_len (Dwelf_Strtab *st,
+					   const char *str, size_t len)
+  __nonnull_attribute__ (1, 2);
+
+/* Finalize string table ST and store size and memory location
+   information in DATA d_size and d_buf.  DATA d_type will be set to
+   ELF_T_BYTE, d_off will be zero, d_align will be 1 and d_version
+   will be set to EV_CURRENT.  If no memory could be allocated NULL is
+   returned and DATA->d_buf will be set to NULL.  Otherwise DATA will
+   be returned.  */
+extern Elf_Data *dwelf_strtab_finalize (Dwelf_Strtab *st,
+					Elf_Data *data)
+  __nonnull_attribute__ (1, 2);
+
+/* Get offset in string table for string associated with entry.  Only
+   valid after dwelf_strtab_finalize has been called.  */
+extern size_t dwelf_strent_off (Dwelf_Strent *se)
+  __nonnull_attribute__ (1);
+
+/* Return the string associated with the entry.  */
+extern const char *dwelf_strent_str (Dwelf_Strent *se)
+  __nonnull_attribute__ (1);
+
+/* Free resources allocated for the string table.  This invalidates
+   any Dwelf_Strent references returned earlier. */
+extern void dwelf_strtab_free (Dwelf_Strtab *st)
+  __nonnull_attribute__ (1);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* libdwelf.h */
diff --git a/third_party/elfutils/libdwelf/libdwelfP.h b/third_party/elfutils/libdwelf/libdwelfP.h
new file mode 100644
index 0000000..d83c759
--- /dev/null
+++ b/third_party/elfutils/libdwelf/libdwelfP.h
@@ -0,0 +1,42 @@
+/* Internal definitions for libdwelf. DWARF ELF Low-level Functions.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBDWELFP_H
+#define _LIBDWELFP_H	1
+
+#include <libdwelf.h>
+#include "../libdw/libdwP.h"	/* We need its INTDECLs.  */
+#include <assert.h>
+#include <string.h>
+
+/* Avoid PLT entries.  */
+INTDECL (dwelf_elf_gnu_debuglink)
+INTDECL (dwelf_dwarf_gnu_debugaltlink)
+INTDECL (dwelf_elf_gnu_build_id)
+
+#endif	/* libdwelfP.h */
diff --git a/third_party/elfutils/libdwfl/ChangeLog b/third_party/elfutils/libdwfl/ChangeLog
new file mode 100644
index 0000000..453f1d3
--- /dev/null
+++ b/third_party/elfutils/libdwfl/ChangeLog
@@ -0,0 +1,2903 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* dwfl_report_elf.c (__libdwfl_elf_address_range): Use FALLTHROUGH
+	macro instead of comment.
+	* frame_unwind.c (expr_eval): Likewise.
+
+2017-11-20  Mark Wielaard  <mark@klomp.org>
+
+	* link_map.c (do_check64): Take a char * and calculate type and val
+	offsets before reading, possibly unaligned, values.
+	(do_check32): Likewise.
+	(check64): Remove define.
+	(check32): Likewise.
+	(auxv_format_probe): Call do_check32 and do_check64 directly with
+	a, possibly unaligned, auxv entry pointer.
+	(dwfl_link_map_report): Redefine AUXV_SCAN to not dereference a
+	possibly unaligned auxv entry pointer.
+
+2017-10-16  Mark Wielaard  <mark@klomp.org>
+
+	* argp-std.c (parse_opt): For -k call argp_failure not failure to
+	keep dwfl around.
+
+2017-07-26  Yunlian Jiang  <yunlian@google.com>
+
+	* argp-std.c (failure): Move to file scope.
+	(fail): Likewise.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+	    Mark Wielaard  <mark@klomp.org>
+
+	* derelocate.c (compare_secrefs): Compare by end address and then by
+	section number if addresses are equal.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+	    Mark Wielaard  <mark@klomp.org>
+
+	* linux-kernel-modules.c: Always return NULL from kernel_release() on
+	non-linux systems and set errno to ENOTSUP.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* libdwflP.h: Don't include config.h.
+	* argp-std.c: Include config.h.
+	* cu.c: Likewise.
+	* derelocate.c: Likewise.
+	* dwfl_addrdie.c: Likewise.
+	* dwfl_addrdwarf.c: Likewise.
+	* dwfl_addrmodule.c: Likewise.
+	* dwfl_begin.c: Likewise.
+	* dwfl_build_id_find_debuginfo.c: Likewise.
+	* dwfl_build_id_find_elf.c: Likewise.
+	* dwfl_cumodule.c: Likewise.
+	* dwfl_dwarf_line.c: Likewise.
+	* dwfl_end.c: Likewise.
+	* dwfl_frame.c: Likewise.
+	* dwfl_frame_regs.c: Likewise.
+	* dwfl_getdwarf.c: Likewise.
+	* dwfl_getmodules.c: Likewise.
+	* dwfl_getsrc.c: Likewise.
+	* dwfl_getsrclines.c: Likewise.
+	* dwfl_line_comp_dir.c: Likewise.
+	* dwfl_linecu.c: Likewise.
+	* dwfl_lineinfo.c: Likewise.
+	* dwfl_linemodule.c: Likewise.
+	* dwfl_module.c: Likewise.
+	* dwfl_module_addrdie.c: Likewise.
+	* dwfl_module_addrname.c: Likewise.
+	* dwfl_module_addrsym.c: Likewise.
+	* dwfl_module_build_id.c: Likewise.
+	* dwfl_module_dwarf_cfi.c: Likewise.
+	* dwfl_module_eh_cfi.c: Likewise.
+	* dwfl_module_getdarf.c: Likewise.
+	* dwfl_module_getelf.c: Likewise.
+	* dwfl_module_getsrc.c: Likewise.
+	* dwfl_module_getsrc_file.c: Likewise.
+	* dwfl_module_getsym.c: Likewise.
+	* dwfl_module_info.c: Likewise.
+	* dwfl_module_nextcu.c: Likewise.
+	* dwfl_module_register_names.c: Likewise.
+	* dwfl_module_report_build_id.c: Likewise.
+	* dwfl_module_return_value_location.c: Likewise.
+	* dwfl_nextcu.c: Likewise.
+	* dwfl_onesrcline.c: Likewise.
+	* dwfl_report_elf.c: Likewise.
+	* dwfl_validate_address.c: Likewise.
+	* dwfl_version.c: Likewise.
+	* find-debuginfo.c: Likewise.
+	* gzip.c: Likewise.
+	* image-header.c: Likewise.
+	* lines.c: Likewise.
+	* linux-core-attach.c: Likewise.
+	* linux-pid-attach.c: Likewise.
+	* offline.c: Likewise.
+	* open.c: Likewise.
+	* relocate.c: Likewise.
+	* segment.c: Likewise.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* libdwfl.h: Use __const_attribute__.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* elf-from-memory.c: Explicitly cast phnum to size_t.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* dwfl_module_getdwarf.c: Check shnum for 0 before subtracting from
+	it.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* dwfl_frame.c: Drop unused sys/ptrace.h include.
+	* frame_unwind.c: Likewise.
+	* linux-pid-attach.c: Include sys/ptrace.h and sys/syscall.h only on
+	linux.
+
+2017-04-20  Ulf Hermann <ulf.hermann@qt.io>
+
+	* linux-kernel-modules.c: Include sys/types.h before fts.h
+
+2017-03-24  Mark Wielaard  <mark@klomp.org>
+
+	* linux-core-attach.c (core_next_thread): If n_namesz == 0 then
+	the note name data is the empty string.
+	(dwfl_core_file_attach): Likewise.
+
+2017-02-15  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* linux-kernel-modules.c: Include system.h.
+
+2017-02-15  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* linux-kernel-modules.c: Use sysconf(_SC_PAGESIZE) to get page size.
+	* linux-proc-maps.c: Likewise.
+
+2016-12-29  Luiz Angelo Daros de Luca  <luizluca@gmail.com>
+
+	* dwfl_build_id_find_elf.c: Include system.h.
+	* dwfl_module_getdwarf.c: Likewise.
+	* libdwfl_crc32_file.c: Don't define LIB_SYSTEM_H.
+
+2016-11-23  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-kernel-modules.c: Only include fts.h early if BAD_FTS is
+	defined.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* core-file.c: Remove sys/param.h.
+	* dwfl_segment_report_module.c: Likewise. Add system.h include.
+	(MAX): Remove definition.
+	* frame_unwind.c: Add system.h include.
+	(MAX): Remove definition.
+	* linux-core-attach.c (MIN): Remove definition.
+	* linux-pid-attach.c (MAX): Likewise.
+
+2016-08-12  Mark Wielaard  <mjw@redhat.com>
+
+	* link_map.c (dwfl_link_map_report): Fix assert, set in.d_size.
+
+2016-04-14  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getsrc_file.c (dwfl_module_getsrc_file): Free match
+	on invalid DWARF if we allocated it.
+
+2016-04-14  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-proc-maps.c (proc_maps_report): Free last_file on bad file
+	mapping.
+
+2016-03-01  Steven Chamberlain  <steven@pyro.eu.org>
+
+	* linux-pid-attach.c: Removed unused pid_thread_callbacks,
+	pid_thread_detach, pid_detach, pid_set_initial_registers,
+	pid_memory_read, pid_getthread, pid_next_thread in #ifndef
+	__linux__ code.
+
+2016-02-22  Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* find-debuginfo.c (find_debuginfo_in_path): Remember whether
+	debuglink_file is NULL. Try file basename (without .debug) ofr
+	absolute and relative path if debug_file was NULL.
+	* linux-kernel-modules.c (try_kernel_name): If try_debug is true call
+	dwfl_standard_find_debuginfo with NULL debuglink_file, otherwise with
+	basename of fname.
+
+2016-02-13  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-proc-maps.c (proc_maps_report): Free last_file when ENOEXEC.
+
+2016-02-13  Mark Wielaard  <mjw@redhat.com>
+
+	* frame_unwind.c (new_unwound): Check and return unwound.
+	(handle_cfi): Check new_unwound was able to allocate new memory
+	before use. Return DWFL_E_NOMEM otherwise.
+
+2016-02-11  Mark Wielaard  <mjw@redhat.com>
+
+	* relocate.c (relocate_section): Check result of all gelf_get* calls.
+	(__libdwfl_relocate): Likewise.
+	(__libdwfl_relocate_section): Likewise.
+
+2016-02-11  Mark Wielaard  <mjw@redhat.com>
+
+	* relocate.c (relocate_section): Check result of gelf_update_* calls.
+
+2016-01-08  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwfl_a_SOURCES: Unconditionally add gzip.c.
+	* linux-kernel-modules.c (vmlinux_suffixes): We always have at least
+	.gz support.
+	(try_kernel_name): Likewise.
+	(check_suffix): Likewise.
+	* open.c (decompress): Likewise.
+
+2015-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_symtab): Uncompress symstr, xndx, sym
+	sections and aux_str, aux_xndx and aux_sym sections if necessary.
+	* relocate.c (relocate_getsym): Uncompress symtab and symtab_shndx
+	if necessary.
+	(resolve_symbol): Uncompress strtab section if necessary.
+	(relocate_section): Uncompress the section the relocations apply to
+	if necessary.
+
+2015-11-18  Chih-Hung Hsieh <chh@google.com>
+
+	* linux-proc-maps.c (proc_maps_report): Move nested function
+	'report' to file scope.
+
+2015-11-18  Chih-Hung Hsieh <chh@google.com>
+
+	* core-file.c (elf_begin_rand): Move nested function 'fail' to file
+	scope.
+	* core-file.c (dwfl_elf_phdr_memory_callback): Move nested functions
+	'update_end' and 'more' to file scope.
+
+2015-11-17  Chih-Hung Hsieh <chh@google.com>
+
+	* link_map.c (auxv_format_probe): Move nested functions
+	check64 and check32 to file scope.
+
+2015-12-08  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* dwfl_frame.c (state_fetch_pc): Add a backend-defined offset to
+	the value of the return address register as defined by the CFI
+	abi.
+	* frame_unwind.c (handle_cfi): Likewise.
+
+2015-12-01  Mark Wielaard  <mjw@redhat.com>
+
+	* link_map.c (dwfl_link_map_report): Track whether in.d_buf comes
+	from exec or memory_callback, free as appropriate.
+
+2015-12-01  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwflP.h (struct Dwfl_User_Core): New.
+	(struct DWfl): Replace executable_for_core with user_core.
+	* argp-std.c (parse_opt): Store core and fd in Dwfl user_core.
+	* core-file.c (dwfl_core_file_report): Check and store
+	executable_for_core in Dwfl user_core.
+	* dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Check and use
+	executable_for_core in Dwfl user_core.
+	* dwfl_end.c (dwfl_end): Release resources held in Dwfl user_core.
+	* link-map.c (report_r_debug): Check executable_for_core in Dwfl
+	user_core.
+	(dwfl_link_map_report): Likewise.
+
+2015-11-16  Chih-Hung Hsieh <chh@google.com>
+
+	* dwfl_module_getdwarf.c (find_prelink_address_sync): Move nested
+	function 'consider_shdr' to file scope.
+	* dwfl_module_getdwarf.c (find_dynsym): Move nested function
+	'translate_offs' to file scope.
+
+2015-11-16  Chih-Hung Hsieh <chh@google.com>
+
+	* dwfl_module_addrsym.c (__libdwfl_addrsym): Move nested functions
+	'same_section', 'binding_value', 'try_sym_value', and 'search_table'
+	to file scope.
+
+2015-11-19  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module.c (__libdwfl_module_free): Remove Dwfl_Module Ebl from
+	eh_cfi and dwarf_cfi cache if necessary before calling dwarf_end and
+	dwarf_cfi_end.
+
+2015-11-13  Chih-Hung Hsieh <chh@google.com>
+
+	* gzip.c (unzip): Move nested functions to file scope.
+
+2015-10-21  Chih-Hung Hsieh <chh@google.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getsrc_file.c (dwfl_module_getsrc_file): Move nested
+	functions 'dwarf_line_file', 'dwfl_line', and 'dwfl_line_file' to
+	file scope. Rename dwarf_line_file to dwfl_dwarf_line_file. Don't
+	use INTUSE.
+
+2015-10-21  Chih-Hung Hsieh <chh@google.com>
+
+	* frame_unwind.c (expr_eval): Move nested function 'push' and 'pop'
+	to file scope. Pass used local variables in struct eval_stack.
+
+2015-10-21  Chih-Hung Hsieh <chh@google.com>
+
+	* dwfl_module.c (dwfl_report_module): Move nested function 'use' to
+	file scope.
+
+2015-10-09  Josh Stone  <jistone@redhat.com>
+
+	* core-file.c (elf_begin_rand): Replace loff_t with off_t.
+	* open.c (decompress): Replace off64_t with off_t.
+	* gzip.c (unzip): Likewise.
+	* image-header.c (__libdw_image_header): Likewise.
+	* libdwflP.h: Likewise in function declarations.
+	* argp-std.c (parse_opt): Replace open64 with open.
+	* dwfl_build_id_find_elf.c (__libdwfl_open_mod_by_build_id,
+	dwfl_build_id_find_elf): Likewise.
+	* dwfl_module_getdwarf.c (open_elf_file): Likewise.
+	* dwfl_report_elf.c (dwfl_report_elf): Likewise.
+	* dwfl_segment_report_module.c (dwfl_segment_report_module): Likewise.
+	* link_map.c (report_r_debug): Likewise.
+	* offline.c (dwfl_report_offline): Likewise.
+	* linux-proc-maps.c (grovel_auxv, get_pid_class,
+	dwfl_linux_proc_find_elf): Likewise.
+	(read_proc_memory): Replace off64_t with off_t.
+	* find-debuginfo.c (find_debuginfo_in_path): Replace stat64 and
+	fstat64 with stat and fstat.
+	(try_open): Likewise, and replace open64 with open.
+	* linux-kernel-modules.c: Manually define open and fopen to open64 and
+	fopen64 when needed, since the early fts.h include breaks that.
+	(try_kernel_name): Replace open64 with open.
+	(check_notes): Likewise.
+
+2015-10-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* linux-proc-maps.c (read_proc_memory): Use seek+read instead of
+	pread, as the later doesn't accept negative offsets.
+
+2015-10-07  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (MAX): Removed.
+	(find_prelink_address_sync): Allocate exact amount of bytes for
+	phdrs and shdrs.
+	* dwfl_segment_report_module.c (dwfl_segment_report_module):
+	Likewise for phdrs.
+	* elf-from-memory.c (MAX): Removed.
+	(elf_from_remote_memory): Allocate exact amount of bytes for phdrs.
+
+2015-10-05  Chih-Hung Hsieh <chh@google.com>
+
+	* dwfl_module_getdwarf.c (find_prelink_address_sync): Do not use
+	union of variable length arrays.
+	* dwfl_segment_report_module.c (dwfl_segment_report_module): Likewise.
+	* elf-from-memory.c (elf_from_remote_memory): Likewise.
+	* link_map.c (auxv_format_probe): Likewise.
+	* link_map.c (report_r_debug): Likewise.
+	* link_map.c (dwfl_link_map_report): Likewise.
+
+2015-09-18  Chih-Hung Hsieh  <chh@google.com>
+
+	* relocate.c (relocate_section): Move nested function "relocate"
+	to file scope, pass all used local variables as constants.
+	Move nested "check_badreltype" to file scope, pass addresses of
+	updated used local variables.
+	* linux-kernel-modules.c (intuit_kernel_bounds): Move nested function
+	"read_address" to file scope, pass all updated local variables in
+	a state structure.
+	* linux-kernel-modules.c (dwfl_linux_kernel_find_elf): Move nested
+	function "subst_name" to file scope, pass all used local variables
+	as constants.
+	* linux-kernel-modules.c (dwfl_linux_kernel_report_kernel): Replace
+	simple nested function "report" with a macro. Work around gcc static
+	analysis error -Werror=maybe-uninitialized.
+
+2015-09-22  Mark Wielaard  <mjw@redhat.com>
+
+	* core-file.c: Remove old-style function definitions.
+	* dwfl_error.c: Likewise.
+	* dwfl_module_dwarf_cfi.c: Likewise.
+	* dwfl_module_eh_cfi.c: Likewise.
+	* dwfl_module_register_names.c: Likewise.
+	* dwfl_module_return_value_location.c: Likewise.
+	* dwfl_version.c: Likewise.
+
+2015-09-09  Chih-Hung Hsieh  <chh@google.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_frame.c (dwfl_attach_state): Remove redundant NULL tests
+	on parameters declared with __nonnull_attribute__.
+	* libdwfl.h (dwfl_module_getelf): Don't mark first argument as
+	nonnull.
+
+2015-09-08  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwflP.h (struct __libdwfl_pid_arg): Add elf and elf_fd.
+	* linux-pid-attach.c (pid_detach): Call elf_end and close.
+	(dwfl_linux_proc_attach): Open and save /proc/PID/exe.
+
+2015-09-04  Chih-Hung Hsieh  <chh@google.com
+
+	* frame_unwind.c (expr_eval): Use llabs instead of abs.
+
+2015-08-14  Dodji Seketeli  <dodji@seketeli.org>
+
+	* find-debuginfo.c (find_debuginfo_in_path): Try to locate the
+	debug info file named debuglink_file under
+	mod->dwfl->callbacks->debuginfo_path, by looking at
+	the set of sub-trees under mod->dwfl->callbacks->debuginfo_path
+	which is common to the set of non-absolute parent trees of
+	file_name.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* find-debuginfo.c (try_open): Free fname on all failure paths.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_symtab): Check shdr is not NULL and
+	sh_entsize is not zero.
+
+2015-06-06  Mark Wielaard  <mjw@redhat.com>
+
+	* find-debuginfo.c (find_debuginfo_in_path): Always free localpath,
+	localname and file_dirname.
+
+2015-06-06  Mark Wielaard  <mjw@redhat.com>
+
+	* derelocate.c (cache_sections): Free sortrefs.
+
+2015-06-05  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_segment_report_module.c (dwfl_segment_report_module):
+	If the note_file exists, but the build_id doesn't match discard
+	the file and continue reporting.
+
+2015-06-01  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Copy path
+	pointer before passing to strsep.
+
+2015-05-30  Mark Wielaard  <mjw@redhat.com>
+
+	* link_map.c (check32): Use read_4ubyte_unaligned_noncvt to read
+	type and value.
+	(read_addrs): Use read_(4|8)ubyte_unaligned_noncvt or to read
+	adresses.
+
+2015-05-30  Mark Wielaard  <mjw@redhat.com>
+
+	* find-debuginfo.c (dwfl_standard_find_debuginfo): Check file_name is
+	not NULL before calling canonicalize_file_name.
+
+2015-05-24  Mark Wielaard  <mjw@redhat.com>
+
+	* derelocate.c (check_module): Check mod is not NULL.
+
+2015-05-22  Mark Wielaard  <mjw@redhat.com>
+
+	* link_map.c (dwfl_link_map_report): Allocate phdrs and dyn with
+	malloc instead of stack allocating. Call free when done with data.
+
+2015-05-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_segment_report_module.c (dwfl_segment_report_module):
+	Allocate phdrs with malloc, not on stack. free in finish.
+	Allocate dyn with malloc, not on stack, free after use.
+
+2015-05-22  Mark Wielaard  <mjw@redhat.com>
+
+	* find-debuginfo.c (find_debuginfo_in_path): malloc or strdup,
+	instead of alloca or strdupa, local strings of unknown size.
+	Call free before return.
+
+2015-05-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Return
+	error when id_len too small or too large. strdup, not strdupa,
+	and free path when done.
+
+2015-05-19  Mark Wielaard  <mjw@redhat.com>
+
+	* elf-from-memory.c (elf_from_remote_memory): Don't allocate all
+	phdrs on the stack. Allocate with malloc and free when done.
+
+2015-05-19  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_find_elf): malloc and
+	free alternate_name.
+
+2015-05-19  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Don't
+	stack allocate name. Only change chars up to suffix.
+
+2015-05-18  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_prelink_address_sync): Allocate
+	phdrs and shdrs unions with malloc, not alloca. Free after use.
+
+2015-05-18  Mark Wielaard  <mjw@redhat.com>
+
+	* derelocate.c (cache_sections): Allocate temporary newrefs and
+	sortrefs with malloc, not alloca. Always free them on return.
+
+2015-05-07  Mark Wielaard  <mjw@redhat.com>
+
+	* cu.c (intern_cu): Check for EOF and check cuoff points to a real
+	Dwarf_Die before interning. Explicitly check EOF is expected.
+
+2015-05-05  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_lineinfo.c (dwfl_lineinfo): Check info->file is valid.
+
+2015-05-06  Roland McGrath  <roland@hack.frob.com>
+
+	* dwfl_error.c (struct msgtable): Break type definition out of
+	the 'msgtable' initializer.
+	(msgtable): Make it a union of struct msgtable and a char array.
+	(msgstr): Use the full-table char array rather than the msg_0 entry.
+
+2015-04-23  Max Filippov  <jcmvbkbc@gmail.com>
+
+	* core-file.c (_compat_without_executable_dwfl_core_file_report):
+	Guard with SYMBOL_VERSIONING.
+	* dwfl_module_build_id.c (_compat_vaddr_at_end_dwfl_module_build_id):
+	Likewise.
+	* dwfl_report_elf.c (_compat_without_add_p_vaddr_dwfl_report_elf):
+	Likewise.
+
+2015-04-02  Mark Wielaard  <mjw@redhat.com>
+
+	* segment.c (insert): Check correct number of lookup_elts.
+
+2015-03-31  Mark Wielaard  <mjw@redhat.com>
+
+	* core-file.c (core_file_read_eagerly): Special case small images.
+
+2015-01-26  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_symtab): Explicitly clear symdata,
+	syments and first_global on elferr before calling find_dynsym.
+
+2014-12-27  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getsrc.c (dwfl_module_getsrc): Never match a line that
+	has end_sequence set.
+
+2015-01-04  Mark Wielaard  <mjw@redhat.com>
+
+	* cu.c (intern_cu): Store result and return directly when finding
+	EOF marker.
+	(__libdwfl_nextcu): Check *nextp as returned by intern_cu isn't -1.
+
+2014-12-19  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_symtab): Always try find_dynsym last.
+
+2014-12-19  Mark Wielaard  <mjw@redhat.com>
+
+	* elf-from-memory.c (handle_segment): Remove palign sanity check.
+
+2014-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* relocate.c (resolve_symbol): Make sure symstrdata->d_buf != NULL.
+
+2014-12-13  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_dynsym): elf_getdata_rawchunk takes
+	a size_t, make sure it doesn't overflow.
+
+2014-12-13  Mark Wielaard  <mjw@redhat.com>
+
+	* cu.c (cudie_offset): Make sure Dwarf_Off difference doesn't
+	wrap around before returning as int.
+
+2014-12-11  Josh Stone  <jistone@redhat.com>
+
+	* dwfl_module_getsrc.c (dwfl_module_getsrc): Return the *last* line
+	record <= addr, rather than returning immediately on matches.
+
+2014-12-09  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_segment_report_module.c (handle_file_note): Check count doesn't
+	overflow.
+
+2014-12-07  Mark Wielaard  <mjw@redhat.com>
+
+	* relocate.c (relocate_section): Sanity check section overlap against
+	actually used ehsize, shentsize and phentsize.
+
+2014-12-07  Mark Wielaard  <mjw@redhat.com>
+
+	* offline.c (dwfl_offline_section_address): Assert shndx is not zero.
+	* relocate.c (__libdwfl_relocate_value): Don't relocate against
+	section zero.
+
+2014-11-29  Mark Wielaard  <mjw@redhat.com>
+
+	* relocate.c (relocate_section): Check relocation section and target
+	section data don't overlap any of the ELF headers.
+	(relocate): Check for offset + size overflow.
+
+2014-11-22  Mark Wielaard  <mjw@redhat.com>
+
+	* link_map.c (consider_executable): Use elf_getphdrnum.
+	(dwfl_link_map_report): Likewise.
+
+2014-11-18  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_symtab): Sanity check the data buffer,
+	number of symbols and first_global before use.
+
+2014-11-14  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (load_symtab): Don't use tables which have
+	a zero sh_entsize.
+
+2014-11-10  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_dynsym): New inner function
+	translate_offs that takes an adjust argument. Try finding
+	the symbol table with and without adjusting to main_bias.
+
+2014-09-26  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Support NT_FILE for locating files.
+	* core-file.c (dwfl_core_file_report): New variables note_file and
+	note_file_size, set them and pass them to dwfl_segment_report_module.
+	* dwfl_segment_report_module.c: Include common.h and fcntl.h.
+	(buf_has_data, buf_read_ulong, handle_file_note): New functions.
+	(invalid_elf): New function from code of dwfl_segment_report_module.
+	(dwfl_segment_report_module): Add parameters note_file and
+	note_file_size.  New variables elf and fd, clean them up in finish.
+	Move some code to invalid_elf.  Call handle_file_note, if it found
+	a name verify the file by invalid_elf.  Protect elf and fd against
+	cleanup by finish if we found the file for new Dwfl_Module.
+	* libdwflP.h (dwfl_segment_report_module): Add parameters note_file and
+	note_file_size.
+
+2014-09-23  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_segment_report_module.c (dwfl_segment_report_module):
+	Extract ei_class, ei_data and e_type early and use the result.
+
+2014-09-18  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Use IS_EXECUTABLE.
+	* dwfl_segment_report_module.c (dwfl_segment_report_module): Set
+	IS_EXECUTABLE.
+	* libdwflP.h (struct Dwfl_Module): New field is_executable.
+
+2014-08-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_offsets): Add parameter main_bias, use
+	it.
+	(find_dynsym): Pass the new parameter main_bias.
+
+2014-08-14  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-kernel-modules.c (check-suffix): Also TRY .ko.xz.
+
+2014-07-24  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Fix report_r_debug for prelinked libraries.
+	* link_map.c (report_r_debug): Comment out variable l_addr.
+	Use instead new variable base recalculated from l_ld.
+
+2014-06-24  Kurt Roeckx  <kurt@roeckx.be>
+
+	* linux-pid-attach.c: Make it build on non linux hosts.
+
+2014-06-17  Mark Wielaard  <mjw@redhat.com>
+
+	* frame_unwind.c (handle_cfi): Use ebl_func_addr_mask.
+	* dwfl_module_getsym.c (__libdwfl_getsym): Likewise.
+
+2014-06-15  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-core-attach.c (core_memory_read): Use libdw/memory-access.h
+	macros read_4ubyte_unaligned_noncvt and read_8ubyte_unaligned_noncvt
+	to read possibly unaligned data.
+	(core_next_thread): Likewise.
+	(core_set_initial_registers): Likewise.
+	(dwfl_core_file_attach): Likewise.
+
+2014-06-11  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_frame.c (__libdwfl_process_free): Reset dwfl->attacherr.
+	(dwfl_attach_state): Set dwfl->attacherr.
+	(dwfl_pid): Check and return dwfl->attacherr if set.
+	(dwfl_getthreads): Likewise.
+	(getthread): Likewise.
+	* libdwflP.h: Add DWFL_E_NO_CORE_FILE.
+	(struct Dwfl): Add attacherr field.
+	* linux-core-attach.c (dwfl_core_file_attach): Set dwfl->attacherr.
+	Don't assert if ELF file is not ET_CORE, just return error.
+	* linux-pid-attach.c (dwfl_linux_proc_attach): Set dwfl->attacherr.
+
+2014-06-10  Mark Wielaard  <mjw@redhat.com>
+
+	* argp-std.c (parse_opt): Ignore errors from dwfl_core_file_attach
+	or dwfl_linux_proc_attach.
+
+2014-05-15  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-proc-maps.c (grovel_auxv): Close fd on error.
+
+2014-05-02  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf: Remove ENABLE_DWZ ifdefs so find_debug_altlink
+	is always called.
+
+2014-05-01  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwflP.h (struct Dwfl_Module): Add alt, alt_fd and alt_elf fields.
+	(__libdwfl_open_mod_by_build_id): Renamed __libdwfl_open_by_build_id.
+	(__libdwfl_open_by_build_id): New declaration that takes an explicit
+	build-id.
+	* dwfl_build_id_find_debuginfo.c (dwfl_build_id_find_debuginfo): If
+	we already have the Dwarf then look for the alt dwz multi file by
+	build-id.
+	* dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Add the
+	build-id we are looking for as argument.
+	(__libdwfl_open_mod_by_build_id): New function, calls
+	__libdwfl_open_by_build_id.
+	(dwfl_build_id_find_elf): Call __libdwfl_open_mod_by_build_id.
+	* dwfl_module.c (__libdwfl_module_free): Release alt, alt_elf and
+	close alt_fd if necessary.
+	* dwfl_module_getdwarf.c (__check_build_id): Removed.
+	(try_debugaltlink): Removed.
+	(open_debugaltlink): Removed.
+	(open_elf_file): First half of open_elf that just opens the elf
+	file but doesn't setup the load address.
+	(open_elf): Call open_elf_file.
+	(find_debug_altlink): New function.
+	(load_dw): Remove loading of dwz multifile.
+	(find_dw): Call find_debug_altlink.
+	* find-debuginfo.c (validate): Handle alt debug case using
+	dwelf_dwarf_gnu_debugaltlink and mod->alt_elf.
+	(find_debuginfo_in_path): Handle alt debug files possibly in .dwz
+	subdirs.
+	* linux-kernel-modules.c (try_kernel_name): Use fakemod.debug.name
+	to store name to find by dwfl_standard_find_debuginfo instead of
+	allocating an extra variable on stack.
+
+2014-04-30  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_build_id.c (__libdwfl_find_elf_build_id): Moved to
+	dwelf_elf_gnu_build_id.c.
+	(__libdwfl_find_build_id): Add assert to make sure mod is never NULL.
+	* dwfl_segment_report_module.c (dwfl_segment_report_module): Call
+	dwelf_elf_gnu_build_id directly instead of __libdwfl_find_build_id.
+	* dwfl_module_getdwarf.c (__check_build_id): Implement using
+	dwelf_elf_gnu_build_id.
+
+2014-04-15  Florian Weimer  <fweimer@redhat.com>
+
+	* dwfl_module_getdwarf.c (__check_build_id): Moved from libdw.
+	(try_debugaltlink): Likewise.
+	(open_debugaltlink): Likewise.
+	(load_dw): Locate alternate debug information using
+	dwelf_dwarf_gnu_debugaltlink and call open_debugaltlink.
+
+2014-04-11  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (AM_CPPFLAGS): Add libdwelf.
+	* libdwflP.h: Include libdwelfP.h.
+	* dwfl_module_getdwarf.c (find_debuglink): Moved to libdwelf.
+	(find_debuginfo): Use dwelf_elf_gnu_debuglink.
+
+2014-04-22  Mark Wielaard  <mjw@redhat.com>
+
+	* frame_unwind.c (__libdwfl_frame_reg_get): Use uint64_t when
+	checking bits.
+	(__libdwfl_frame_reg_set): Likewise.
+
+2014-04-22  Kurt Roeckx  <kurt@roeckx.be>
+
+	* linux-pid-attach.c: Make linux only.
+
+2014-03-14  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Remove !MUDFLAP and MUDFLAP conditions.
+	Remove libelf and libdw definitions when MUDFLAP is defined.
+	* argp-std.c (__libdwfl_argp_mudflap_options): Removed.
+
+2014-03-03  Mark Wielaard  <mjw@redhat.com>
+
+	* elf-from-memory.c (elf_from_remote_memory): Keep track of
+	segments_end_mem. Pass memsz to first handle_segment pass. Only
+	extend contents_size and use shdrs if only file bits are in
+	segment.
+
+2014-03-11  Josh Stone  <jistone@redhat.com>
+
+	* dwfl_module_getdwarf.c (open_elf): Only explicitly set
+	mod->e_type when processing the main ELF file.
+
+2014-03-04  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwflP.h (struct __libdwfl_pid_arg): Moved here and renamed from
+	linux-pid-attach.c (struct pid_arg).
+	(__libdwfl_get_pid_arg): New internal function declaration.
+	(__libdwfl_ptrace_attach): Likewise.
+	(__libdwfl_ptrace_detach): Likewise.
+	* dwfl_frame.c (dwfl_attach_state): Add "(deleted)" files to the
+	special exception modules that cannot be checked at this point.
+	* linux-pid-attach.c (struct pid_arg): Moved to libdwflP.h
+	(ptrace_attach): Renamed to...
+	(__libdwfl_ptrace_attach): New internal function.
+	(__libdwfl_ptrace_detach): Likewise. Extracted from ...
+	(pid_thread_detach): Call __libdwfl_ptrace_detach now.
+	(__libdwfl_get_pid_arg): New internal function.
+	* linux-proc-maps.c (dwfl_linux_proc_find_elf): Check if special
+	module name contains "(deleted)" and dwfl_pid gives an attached
+	pid. If pid is set and try to (re)use ptrace attach state of
+	process before reading memory.
+
+2014-03-03  Mark Wielaard  <mjw@redhat.com>
+
+	* elf-from-memory.c (elf_from_remote_memory): Take pagesize as
+	argument. Free buffer when detecting bad elf. Check PT_LOAD
+	alignment requirements on first handle_segment pass. Calculate
+	loadbase, start and end of segment using pagesize, not p_align.
+	* linux-proc-maps.c (dwfl_linux_proc_find_elf): Provide pagesize
+	to elf_from_remote_memory.
+
+2014-02-26  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-proc-maps.c (proc_maps_report): Don't assert on bad input.
+
+2014-02-26  Mark Wielaard  <mjw@redhat.com>
+
+	* elf-from-memory.c (elf_from_remote_memory): Check against p64
+	p_type in case ELFCLASS64, not against p32 p_type.
+
+2014-01-17  Petr Machata  <pmachata@redhat.com>
+
+	* relocate.c (relocate_section): Use gelf_fsize instead of relying
+	on shdr->sh_entsize.
+
+2014-01-05  Mark Wielaard  <mjw@redhat.com>
+
+	* frame_unwind.c (handle_cfi): Only skip resetting return register
+	if the regno is not the actual CIE return address register.
+
+2014-01-02  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-pid-attach.c (dwfl_linux_proc_attach): Use strtol, not atoi.
+
+2013-12-30  Mark Wielaard  <mjw@redhat.com>
+
+	* argp-std.c (parse_opt): Call dwfl_linux_proc_attach and
+	dwfl_core_file_attach explicitly.
+	* core-file.c (dwfl_core_file_report): Don't call
+	__libdwfl_attach_state_for_core implicitly.
+	* dwfl_begin.c (dwfl_begin): Remove setting of process_attach_error.
+	* dwfl_frame.c (dwfl_pid): Set errno to DWFL_E_NO_ATTACH_STATE, not
+	process_attach_error.
+	(dwfl_getthreads): Likewise.
+	(getthread): Likewise.
+	* libdwfl.h (dwfl_core_file_report): Update documentation.
+	(dwfl_linux_proc_report): Likewise.
+	(dwfl_core_file_attach): New function declaration.
+	(dwfl_linux_proc_attach): Likewise.
+	* libdwflP.h (struct Dwfl): Remove process_attach_error.
+	(__libdwfl_attach_state_for_pid): Removed declaration.
+	(__libdwfl_attach_state_for_core): Likewise.
+	(dwfl_core_file_attach): New internal declaration.
+	(dwfl_linux_proc_attach): Likewise.
+	(attach_state_for_core): Renamed to...
+	(dwfl_core_file_attach): ...this. Change return type.
+	(__libdwfl_attach_state_for_core): Removed.
+	* linux-pid-attach.c (struct pid_arg): Add assume_ptrace_stopped.
+	(pid_set_initial_registers): Check assume_ptrace_stopped before
+	calling ptrace.
+	(pid_thread_detach): Likewise.
+	(__libdwfl_attach_state_for_pid): Renamed to...
+	(dwfl_linux_proc_attach): ...this. Adjust return type.
+	* linux-proc-maps.c (dwfl_linux_proc_report): Don't call
+	__libdwfl_attach_state_for_pid implicitly.
+
+2013-12-28  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-proc-maps.c (dwfl_linux_proc_find_elf): Don't return special
+	character device files, only regular files.
+
+2013-12-24  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-core-attach.c (core_next_thread): Check whether thread_argp
+	is NULL. Reset core_arg->thread_note_offset and malloc a thread_arg
+	in that case. Free thread_arg if there are no more threads.
+
+2013-12-23  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_segment_report_module.c (dwfl_segment_report_module): Free
+	build_id before returning early.
+
+2013-12-23  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-pid-attach.c (__libdwfl_attach_state_for_pid): Report actual
+	pid (thread group leader) to dwfl_attach_state.
+
+2013-12-21  Mark Wielaard  <mjw@redhat.com>
+
+	* frame_unwind.c (handle_cfi): Track whether the return register
+	has been set and only allow it to be set once.
+
+2013-12-20  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_frame.c (one_arg): New struct.
+	(get_one_thread_cb): New function.
+	(dwfl_getthread): Likewise.
+	(one_thread): New struct.
+	(get_one_thread_frames_cb): New function.
+	(dwfl_getthread_frames): Likewise.
+	* libdwfl.h (Dwfl_Thread_Callbacks): Add get_thread function.
+	(dwfl_getthread_frames): Likewise.
+	* libdwflP.h (dwfl_getthread_frames): New internal function declaration.
+	* linux-core-attach.c (core_thread_callbacks): Initialize get_thread
+	to NULL.
+	* linux-pid-attach.c (pid_getthread): New function.
+	(pid_thread_callbacks): Initialize get_thread to pid_getthread.
+
+2013-12-20  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-kernel-modules.c (report_kernel_archive): Correct nested
+	asprintf result check for debug.a.
+
+2013-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* derelocate.c (__libdwfl_find_section_ndx): New internal function.
+	* dwfl_module_addrname.c (dwfl_module_addrname): Use
+	dwfl_module_addrinfo.
+	* dwfl_module_addrsym.c (dwfl_module_addrsym_elf): Replace with...
+	(__libdwfl_addrsym): ...this. Use __libdwfl_getsym, use value
+	for comparisons, not st_value. Fill in off. Search for both value
+	and the (adjusted) sym.st_value when different.
+	(dwfl_module_addrsym): Implement using __libdwfl_addrsym.
+	(dwfl_module_addrinfo): New function.
+	* dwfl_module_getsym.c (dwfl_module_getsym_elf): Replace with...
+	(__libdwfl_getsym): ...this. Use ebl_resolve_sym_value if requested
+	and possible. Adjust sym->st_value only when requested. Fill in addr
+	if available.
+	(dwfl_module_getsym_info): New function.
+	(dwfl_module_getsym): Use __libdwfl_getsym.
+	* libdwfl.h (dwfl_module_getsym_elf): Removed.
+	(dwfl_module_getsym_info): New function declaration.
+	(dwfl_module_addrinfo): Likewise.
+	(dwfl_module_addrsym): Add documentation describing differences
+	with addrinfo variants.
+	(dwfl_module_addrsym_elf): Removed.
+	* libdwflP.h (__libdwfl_getsym): New internal function declaration.
+	(__libdwfl_addrsym): Likewise.
+	(__libdwfl_find_section_ndx): Likewise.
+	(dwfl_module_addrinfo): New internal declaration.
+	(dwfl_module_getsym_info): Likewise.
+	(dwfl_module_addrsym_elf): Removed.
+	(dwfl_module_getsym_elf): Likewise.
+
+2013-12-18  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* argp-std.c (offline_find_elf): Remove.
+	(offline_callbacks): Use dwfl_build_id_find_elf instead.
+	* dwfl_build_id_find_elf.c (dwfl_build_id_find_elf): Move here the code
+	removed above.
+
+2013-12-18  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	unwinder: s390 and s390x
+	* dwfl_frame_pc.c (dwfl_frame_pc): Call ebl_normalize_pc.
+	* frame_unwind.c (new_unwound): New function from ...
+	(handle_cfi): ... here.  Call it.
+	(setfunc, getfunc, readfunc): New functions.
+	(__libdwfl_frame_unwind): Call ebl_unwind with those functions.
+	* linux-core-attach.c (core_set_initial_registers): Always iterate
+	through the Ebl_Register_Location loop.  Call
+	dwfl_thread_state_register_pc there.
+
+2013-12-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* frame_unwind.c (handle_cfi): Call ebl_dwarf_to_regno for RA.
+
+2013-12-17  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-pid-attach.c (pid_next_thread): Call rewinddir on first
+	traversal.
+
+2013-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwfl.h (dwfl_module_getsymtab_first_global): New function
+	definition.
+	* dwfl_module_getdwarf.c (dwfl_module_getsymtab_first_global): New
+	function.
+	* libdwflP.h (dwfl_module_getsymtab_first_global): New internal
+	function definition.
+	* dwfl_module_addrsym.c (dwfl_module_addrsym_elf): Use new function.
+
+2013-12-14  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module.c (__libdwfl_module_free): Free mod->reloc_info if
+	allocated. Call dwarf_cfi_end on mod->eh_cfi if necessary.
+	* frame_unwind.c (handle_cfi): Free frame result from
+	dwarf_cfi_addrframe when done.
+
+2013-12-15  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	unwinder: ppc and ppc64
+	* frame_unwind.c (__libdwfl_frame_reg_get, __libdwfl_frame_reg_set):
+	Call ebl_dwarf_to_regno.
+	* linux-core-attach.c (core_set_initial_registers): Implement
+	pc_register support.
+	* linux-pid-attach.c (pid_thread_state_registers_cb): Implement
+	FIRSTREG -1.
+
+2013-11-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Introduce process_attach_error.
+	* dwfl_begin.c (dwfl_begin): Initialize process_attach_error.
+	* dwfl_frame.c (dwfl_pid, dwfl_getthreads): Use PROCESS_ATTACH_ERROR if
+	PROCESS is NULL.
+	* libdwflP.h (struct Dwfl): New field process_attach_error.
+	* linux-core-attach.c (__libdwfl_attach_state_for_core): Rename to ...
+	(attach_state_for_core): ... here, make it static, change return type,
+	no longer use __libdwfl_seterrno.
+	(__libdwfl_attach_state_for_core): New wrapper for it.
+
+2013-11-27  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_addrsym.c (dwfl_module_addrsym): Rename to and call...
+	(dwfl_module_addrsym_elf): this. Add elfp and biasp arguments,
+	keep track of symelf, addr_symelf, closest_elf and sizeless_elf
+	instead of tracking dwfl_files.
+	* dwfl_module_getsym.c (__libdwfl_module_getsym): Renamed to...
+	(dwfl_module_getsym_elf): ...this. Remove dwfl_file argument, add
+	new elfp and biasp arguments. Track elf instead of file.
+	(dwfl_module_getsym): Call dwfl_module_getsym_elf.
+	dwfl_module_info.c (dwfl_module_info): Pass elf to
+	dwfl_adjusted_st_value.
+	* libdwfl.h (dwfl_module_getsym): Document limitations of shndx.
+	(dwfl_module_getsym_elf): New function declaration.
+	(dwfl_module_addrsym_elf): Likewise.
+	* libdwflP.h (dwfl_module_addrsym_elf): INTDECL.
+	(dwfl_module_getsym_elf): Likewise.
+	(dwfl_adjusted_st_value): Take and check elf not dwfl_file.
+	(dwfl_deadjust_st_value): Likewise.
+	(__libdwfl_module_getsym): Removed.
+	* relocate.c (resolve_symbol): Pass elf to dwfl_adjusted_st_value.
+
+2013-11-21  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Fix non-build-id core files on build-id system.
+	* link_map.c (report_r_debug): Remove valid clearing if build-id cannot
+	be read from memory.
+
+2013-11-21  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwfl_segment_report_module.c (dwfl_segment_report_module): New
+	variable close_elf.  Call __libdwfl_find_elf_build_id and compare the
+	content, if possible.
+
+2013-11-21  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	link_map: Use proper bias, not l_addr.
+	* core-file.c (dynamic_vaddr_get): Rename to ...
+	(__libdwfl_dynamic_vaddr_get): ... here, make it global,
+	internal_function.
+	(dwfl_core_file_report): Update name in the caller.
+	* libdwflP.h (__libdwfl_dynamic_vaddr_get): New declaration.
+	* link_map.c (report_r_debug): New variable elf_dynamic_vaddr.  Call
+	__libdwfl_dynamic_vaddr_get for it.  Remove L_ADDR FIXME comment.
+	Use ELF_DYNAMIC_VADDR instead of L_ADDR.
+
+2013-11-19  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Compatibility with older kernels such as RHEL-6.
+	* linux-pid-attach.c (struct pid_arg): New field tid_was_stopped.
+	(ptrace_attach): New parameter tid_was_stoppedp.  Set it.
+	(pid_set_initial_registers): Pass tid_was_stopped.
+	(pid_thread_detach): Use tid_was_stopped.
+
+2013-11-18  Josh Stone  <jistone@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_aux_address_sync): New function.
+	(find_aux_sym): Use it.
+
+2013-11-14  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Code cleanup: Remove const in prototype
+	* dwfl_frame_regs.c (dwfl_thread_state_registers): Remove const from
+	firstreg.
+	* libdwfl.h (dwfl_thread_state_registers): Likewise.
+	* linux-pid-attach.c (pid_thread_state_registers_cb): Likewise.
+
+2013-11-14  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Fix dwfl_attach_state machine->elf.
+	* dwfl_frame.c (dwfl_attach_state): Change parameter machine to elf.
+	Call ebl_openbackend instead of ebl_openbackend_machine.
+	* libdwfl.h (dwfl_attach_state): Change parameter machine to elf.
+	Update the function description.
+	* linux-core-attach.c (__libdwfl_attach_state_for_core): Pass CORE to
+	dwfl_attach_state.
+	* linux-pid-attach.c (__libdwfl_attach_state_for_pid): Pass NULL to
+	dwfl_attach_state.
+
+2013-11-06  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Provide __libdwfl_module_getsym to get dwfl_file *.
+	* dwfl_module_addrsym.c (dwfl_module_addrsym) (i_to_symfile): Remove.
+	(dwfl_module_addrsym) (search_table): New variable file.  Use
+	__libdwfl_module_getsym.  Use file.
+	* dwfl_module_getsym.c (dwfl_module_getsym): Rename to ...
+	(__libdwfl_module_getsym): ... here.  Add parameter filep.  Set it.
+	(dwfl_module_getsym): New wrapper.
+	* libdwflP.h (__libdwfl_module_getsym): New declaration.
+
+2013-11-13  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Fix dwfl_module_addrsym for minidebuginfo.
+	* dwfl_module_addrsym.c (dwfl_module_addrsym): New variable
+	addr_symfile.
+	(dwfl_module_addrsym) (same_section): Use it.
+	(dwfl_module_addrsym) (i_to_symfile): New function.
+	(dwfl_module_addrsym) (search_table): Use it.
+
+2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libdwfl_a_SOURCES): Add dwfl_frame.c, frame_unwind.c,
+	dwfl_frame_pc.c, linux-pid-attach.c, linux-core-attach.c and
+	dwfl_frame_regs.c.
+	* core-file.c (dwfl_core_file_report): Call
+	__libdwfl_attach_state_for_core.
+	* dwfl_end.c (dwfl_end): Call __libdwfl_process_free.
+	* dwfl_frame.c: New file.
+	* frame_unwind.c: New file.
+	* dwfl_frame_pc.c: New file.
+	* linux-pid-attach.c: New file.
+	* linux-core-attach.c: New file.
+	* dwfl_frame_regs.c: New file.
+	* libdwfl.h (Dwfl_Thread, Dwfl_Frame): New typedefs.
+	(dwfl_core_file_report, dwfl_linux_proc_report): Extend comments.
+	(Dwfl_Thread_Callbacks): New definition.
+	(struct ebl, dwfl_attach_state, dwfl_pid, dwfl_thread_dwfl)
+	(dwfl_thread_tid, dwfl_frame_thread, dwfl_thread_state_registers)
+	(dwfl_thread_state_register_pc, dwfl_getthreads, dwfl_thread_getframes)
+	(dwfl_frame_pc): New declarations.
+	* libdwflP.h (Dwfl_Process): New typedef.
+	(LIBEBL_BAD, CORE_MISSING, INVALID_REGISTER, PROCESS_MEMORY_READ)
+	(PROCESS_NO_ARCH, PARSE_PROC, INVALID_DWARF, UNSUPPORTED_DWARF)
+	(NEXT_THREAD_FAIL, ATTACH_STATE_CONFLICT, NO_ATTACH_STATE, NO_UNWIND)
+	(INVALID_ARGUMENT): New DWFL_ERROR entries.
+	(struct Dwfl): New entry process.
+	(struct Dwfl_Process, struct Dwfl_Thread, struct Dwfl_Frame)
+	(__libdwfl_frame_reg_get, __libdwfl_frame_reg_set)
+	(__libdwfl_process_free, __libdwfl_frame_unwind)
+	(__libdwfl_attach_state_for_pid, __libdwfl_attach_state_for_core)
+	(__libdwfl_segment_start, __libdwfl_segment_end): New declarations.
+	(dwfl_attach_state, dwfl_pid, dwfl_thread_dwfl, dwfl_thread_tid)
+	(dwfl_frame_thread, dwfl_thread_state_registers)
+	(dwfl_thread_state_register_pc, dwfl_getthreads, dwfl_thread_getframes)
+	(dwfl_frame_pc): New INTDECL entries.
+	* linux-proc-maps.c (dwfl_linux_proc_report): Call
+	__libdwfl_attach_state_for_pid.
+	* segment.c (segment_start): Rename to ...
+	(__libdwfl_segment_start): ... here and make it internal_function.
+	(segment_end): Rename to ...
+	(__libdwfl_segment_end): ... here and make it internal_function.
+	(reify_segments, dwfl_report_segment): Rename them at the callers.
+
+2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* core-file.c (dwfl_core_file_report): Remove the use of MAX.
+
+2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* core-file.c (dwfl_core_file_report): Replaced variable sniffed by
+	retval.  Fix one forgotten LISTED increase.
+
+2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Fix core files for re-prelink-ed files.
+	* core-file.c (dynamic_vaddr_get): New function.
+	(dwfl_core_file_report): New variable file_dynamic_vaddr.  Call
+	dynamic_vaddr_get instead of using L_ADDR.
+	* libdwflP.h (struct r_debug_info_module): Remove field l_addr.
+	* link_map.c (report_r_debug): Do not initialize l_addr.
+
+2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Code cleanup.
+	* core-file.c (dwfl_core_file_report): Reindent block of code by
+	continue keyword.
+
+2013-10-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* argp-std.c (parse_opt): Use executable parameter of
+	dwfl_core_file_report.
+	* core-file.c (dwfl_core_file_report): Add parameter executable.  Set
+	it to DWFL.  Add NEW_VERSION for it.
+	(_compat_without_executable_dwfl_core_file_report): New.  Twice.
+	* libdwfl.h (dwfl_core_file_report): Add parameter executable, update
+	the function comment.
+
+2013-10-15  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-proc-maps.c (proc_maps_report): Ignore non-absolute file
+	mappings.
+	(dwfl_linux_proc_find_elf): Don't abort, just return failure.
+
+2013-09-12  Mark Wielaard  <mjw@redhat.com>
+
+	* cu.c (intern_cu): If dwarf_offdie fails free cu.
+
+2013-09-12  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-proc-maps.c (proc_maps_report): Don't fclose FILE in
+	bad_report.
+
+2013-09-12  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_symtab): Call elf_getdata with
+	aux_xndxscn, not xndxscn, for aux_symxndxdata.
+
+2013-08-25  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-kernel-modules.c (report_kernel): Pass add_p_vaddr as true
+	to dwfl_report_elf.
+
+2013-07-25  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwfl_segment_report_module.c (dwfl_segment_report_module): Check for
+	conflicts all the modules, not just the first one.  Compare L_LD if it
+	is equal, not if it is in a module address range.
+
+2013-07-23  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* libdwflP.h (__libdwfl_elf_address_range): Add internal_function.
+
+2013-07-23  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* core-file.c (clear_r_debug_info): Close also ELF and FD.
+	(dwfl_core_file_report): Call __libdwfl_report_elf for
+	R_DEBUG_INFO.MODULE.
+	* dwfl_report_elf.c (__libdwfl_elf_address_range): New function from
+	code of ...
+	(__libdwfl_report_elf): ... this function.  Call it.
+	* dwfl_segment_report_module.c: Include unistd.h.
+	(dwfl_segment_report_module): Use basename for MODULE->NAME.
+	Clear MODULE if it has no build-id and we have segment with build-id.
+	Ignore this segment only if MODULE still contains valid ELF.
+	* libdwflP.h (__libdwfl_elf_address_range): New declaration.
+	(struct r_debug_info_module): New fields fd, elf, l_addr, start, end
+	and disk_file_has_build_id.
+	(dwfl_link_map_report): Extend the comment.
+	* link_map.c (report_r_debug): Extend the comment.  Always fill in new
+	r_debug_info_module.  Initialize also the new r_debug_info_module
+	fields.  Remove one FIXME comment.  Call __libdwfl_elf_address_range
+	instead of __libdwfl_report_elf when R_DEBUG_INFO is not NULL.
+
+2013-07-19  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* libdwflP.h (__libdwfl_find_elf_build_id): Add internal_function.
+
+2013-07-02  Mark Wielaard  <mjw@redhat.com>
+
+	* relocate.c (__libdwfl_relocate_value): Remove mod->e_type assert.
+
+2013-06-05  Mark Wielaard  <mjw@redhat.com>
+
+	* link_map.c (report_r_debug): Always call release_buffer after
+	memory_callback succeeded reading build_id.
+
+2013-05-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* argp-std.c (parse_opt) <ARGP_KEY_SUCCESS> <opt->core> <opt->e>: Set
+	executable_for_core before calling dwfl_core_file_report.
+	* core-file.c (clear_r_debug_info): New function.
+	(dwfl_core_file_report): Move raw segments reporting lower.  New
+	variable r_debug_info, pass it to dwfl_segment_report_module.  Call
+	clear_r_debug_info in the end.  Return sum of LISTED and SNIFFED.
+	* dwfl_module_build_id.c (check_notes): Move into
+	__libdwfl_find_elf_build_id.
+	(__libdwfl_find_build_id): Rename to ...
+	(__libdwfl_find_elf_build_id): ... here.  Add parameters build_id_bits,
+	build_id_elfaddr and build_id_len.  Verify MOD vs. ELF.
+	(__libdwfl_find_elf_build_id) (check_notes): Remove parameters mod and
+	set, rename data_vaddr to data_elfaddr.  Do not call found_build_id.
+	(__libdwfl_find_elf_build_id): Update the check_notes caller, do not
+	adjust its data_elfaddr parameter.
+	(__libdwfl_find_build_id): New wrapper of __libdwfl_find_elf_build_id.
+	* dwfl_segment_report_module.c (dwfl_segment_report_module): New
+	parameter r_debug_info.  New variable name_is_final.  Adjust addresses
+	according to R_DEBUG_INFO->MODULE.  Check conflicts against DWFL.
+	Do not overwrite NAME by SONAME if NAME_IS_FINAL.
+	* libdwflP.h (__libdwfl_find_elf_build_id): New declaration.
+	(struct r_debug_info_module, struct r_debug_info): New definitions.
+	(dwfl_segment_report_module, dwfl_link_map_report): Add parameter
+	r_debug_info.
+	* link_map.c: Include fcntl.h.
+	(report_r_debug): Add parameter r_debug_info, describe it in the
+	function comment.  Delete dwfl_addrmodule call and its dependent code.
+	Verify build-id before calling dwfl_report_elf, also supply
+	executable_for_core to it.  Store r_debug_info->module info when
+	appropriate.
+	(dwfl_link_map_report): Add parameter r_debug_info.  New variable
+	in_ok.  Try to read IN from EXECUTABLE_FOR_CORE.  Update report_r_debug
+	caller parameters.
+
+2013-04-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Add parameter add_p_vaddr.
+	Set it to true for ET_EXEC and ET_CORE.  Provide alternative
+	setup of START and BIAS if !ADD_P_VADDR.  Set END from BIAS, not BASE.
+	(dwfl_report_elf): Add parameter add_p_vaddr.  Pass it down.  Add
+	NEW_VERSION.
+	(_compat_without_add_p_vaddr_dwfl_report_elf) <SHARED>: New, with
+	COMPAT_VERSION.
+	* libdwfl.h (dwfl_report_elf): Add parameter add_p_vaddr.  Describe it.
+	* libdwflP.h (__libdwfl_report_elf): Add parameter add_p_vaddr.
+	* link_map.c (report_r_debug): Use true add_p_vaddr for dwfl_report_elf.
+	* linux-kernel-modules.c (report_kernel): Use false add_p_vaddr for
+	dwfl_report_elf.
+	* offline.c (process_elf): Use true add_p_vaddr for dwfl_report_elf.
+
+2013-04-27  Mark Wielaard  <mjw@redhat.com>
+
+	* link_map.c: #include system.h.
+
+2013-04-26  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* link_map.c (BE32, BE64, LE32, LE64): Delete the definitions, move
+	them to lib/system.h.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+
+2013-03-20  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Remove BASE aligning.
+
+2013-03-12  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_getsrclines.c (dwfl_getsrclines): Return 0 on success.
+
+2013-02-22  Mark Wielaard  <mjw@redhat.com>
+
+	* open.c (__libdw_gunzip,__libdw_bunzip2,__libdw_unlzma): Define
+	as DWFL_E_BADELF when not used.
+
+2013-02-10  Mark Wielaard  <mjw@redhat.com>
+
+	* argp-std.c (parse_opt): Use opt->core and opt->e explicitly in
+	failure messages When handling ARGP_KEY_SUCCESS because arg will
+	not have been set.
+
+2013-01-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* linux-proc-maps.c: Include system.h.
+	(PROCEXEFMT, get_pid_class): New.
+	(grovel_auxv): Detect 32-bit vs. 64-bit auxv, possibly call
+	get_pid_class.
+
+2013-01-23  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_aux_sym): Don't substract one
+	from aux_syments by default.
+	(find_symtab): Also succeed when only aux_symdata is found.
+	When no symtab is found always try to load auxiliary table.
+	(dwfl_module_getsymtab): Substract one from result when both
+	tables have symbols.
+	* dwfl_module_getsym.c (dwfl_module_getsym): Only skip auxiliary
+	zero entry when both tables have symbols.
+	* dwfl_module_addrsym.c (dwfl_module_addrsym): Only substract
+	one from first_global when both tables have symbols.
+
+2013-01-16  Mark Wielaard  <mjw@redhat.com>
+
+	* libdwflP.h (struct Dwfl_Module): Add aux_sym, aux_symdata,
+	aux_syments, aux_symstrdata, aux_symxndxdata and aux_first_global.
+	(dwfl_adjusted_aux_sym_addr): New function.
+	(dwfl_deadjust_aux_sym_addr): Likewise.
+	(dwfl_adjusted_st_value): Take and check symfile argument.
+	(dwfl_deadjust_st_value): Likewise.
+	* dwfl_module_getdwarf.c (find_prelink_address_sync): Take and
+	use dwfl_file as argument to set address_sync.
+	(find_debuginfo): Call find_prelink_address_sync with debug file.
+	(find_aux_sym): New function.
+	(find_symtab): Use find_aux_sym if all we have is the dynsym table
+	and fill in aux DwflModule fields.
+	(dwfl_module_getsymtab): Return syments plus aux_syments.
+	(load_symtab): Always set first_global.
+	* dwfl_module_addrsym.c (dwfl_module_addrsym): Check symfile
+	when using same_section. Calculate first_global based on both
+	mod->first_global and mod->aux_first_global.
+	* dwfl_module.c (__libdwfl_module_free): Free aux_sym.
+	* dwfl_module_getsym.c (dwfl_module_getsym): Use auxsym table
+	to retrieve symbol and name if necessary, making sure all locals
+	from any table come before any globals.
+	* dwfl_module_info.c (dwfl_module_info): Call dwfl_adjusted_st_value
+	with symfile.
+	* relocate.c (resolve_symbol): Likewise.
+
+2013-01-07  Roland McGrath  <roland@hack.frob.com>
+
+	* link_map.c (auxv_format_probe): Handle unaligned 64-bit data, but
+	still assume the data is at least 32-bit aligned anyway.
+	(dwfl_link_map_report): Handle unaligned auxv data.
+
+2012-12-11  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-kernel-modules.c (report_kernel): Only free fname if
+	find_kernel_elf succeeds and allocates it.
+	(report_kernel_archive): Fix brackets around unlikely expression.
+
+2012-11-29  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* argp-std.c: Update Copyright year.
+	(offline_find_elf): New function.
+	(offline_callbacks): Use it for find_elf.
+	(struct parse_opt): New.
+	(parse_opt): New key ARGP_KEY_INIT.  In other make hook struct
+	parse_opt pointer from former Dwfl pointer.  Delay 'e and OPT_COREFILE
+	processing till ARGP_KEY_SUCCESS.  Initialize state->input already from
+	ARGP_KEY_SUCCESS.  Modify the cleanup in ARGP_KEY_ERROR.  Make the
+	final state->input initialization optional.
+	* dwfl_end.c: Update Copyright year.
+	(dwfl_end): Free executable_for_core.
+	* libdwflP.h: Update Copyright year.
+	(struct Dwfl): New field executable_for_core.
+
+2012-11-20  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Simplify START and BIAS
+	calculation.
+
+2012-10-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwfl_module_getdwarf.c (mod_verify_build_id): New function with code
+	from ...
+	(__libdwfl_getelf): ... here.  Call it.
+
+2012-10-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* libdwfl.h (dwfl_module_getelf): Add __nonnull_attribute__.
+
+2012-10-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwfl_segment_report_module.c (dwfl_segment_report_module):
+	Initialize mod->MAIN_BIAS.
+
+2012-10-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwfl_module_addrsym.c (dwfl_module_addrsym): New function
+	binding_value.  Use it for both zero and non-zero size symbols
+	comparisons.
+
+2012-10-01  Mark Wielaard  <mjw@redhat.com>
+
+	* cu.c (cudie_offset): Don't use type_sig8, it might not be
+	initialized and these are always real CUs, never TUs.
+
+2012-10-01  Mark Wielaard  <mjw@redhat.com>
+
+	* derelocate.c (find_section): Check next section exists before
+	accessing it.
+
+2012-08-01  Petr Machata  <pmachata@redhat.com>
+
+	* offline.c (process_archive_member): Ignore entry "/SYM64/".
+
+2012-03-28  Roland McGrath  <roland@hack.frob.com>
+
+	* dwfl_segment_report_module.c
+	(dwfl_segment_report_module: read_portion): Don't use existing buffer
+	when FILESZ is zero (string mode) and available portion doesn't hold
+	a terminated string.
+
+2011-12-02  Roland McGrath  <roland@hack.frob.com>
+
+	* elf-from-memory.c (elf_from_remote_memory): Fix ELFCLASS64 case
+	to use elf64_xlatetom and PHDRS.p64.
+	Reported by Serge Pavlov <serge.pavlov.at.gnu@gmail.com>.
+
+2011-11-31  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_addrsym.c (dwfl_module_addrsym): First search all
+	global symbols. Then only when that doesn't provide a match search
+	all local symbols too.
+	* dwfl_module_getdwarf.c (load_symtab): Take first_global int arg
+	and fill it in.
+	(find_symtab): Initialize mod->first_global and pass it to load_symtab.
+	* libdwfl/libdwflP.h (Dwfl_Module): Add first_global field.
+
+2011-11-31  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_addrsym.c (dwfl_module_addrsym): Only update
+	sizeless_sym if needed and closer to desired addr.
+
+2011-10-20  Mark Wielaard  <mjw@redhat.com>
+
+	* derelocate.c (cache_sections): Intern mod->reloc_info check.
+	(dwfl_module_relocations): Don't check mod->reloc_info.
+	(dwfl_module_relocation_info): Likewise.
+	(find_section): Likewise.
+
+2011-07-09  Roland McGrath  <roland@hack.frob.com>
+
+	* image-header.c (LE32): Macro removed (now in lib/system.h).
+
+2011-04-11  Mark Wielaard  <mjw@redhat.com>
+
+	* linux-kernel-modules.c (vmlinux_suffixes): Guard definition
+	by check for zlib, bzlib or lzma defines to check it isn't empty.
+	(try_kernel_name): Use same guard for use of vmlinux_suffixes.
+
+2011-03-08  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (open_elf): Clear errno before CBFAIL.
+	Reported by Kurt Roeckx <kurt@roeckx.be>.
+
+2011-02-11  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (try_kernel_name): Try .gz, .bz2, .xz
+	suffixes if corresponding decompression support is enabled.
+
+2011-02-01  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_prelink_address_sync): Use the
+	section-end address as the synchronization point, rather than sh_addr.
+
+	* dwfl_module_getdwarf.c (find_prelink_address_sync): Discover
+	PT_INTERP p_vaddr separately from main phdrs and undo phdrs.
+
+	* dwfl_module_getdwarf.c (find_prelink_address_sync): Fix pasto in
+	last change, so we recognize PT_INTERP in ELFCLASS64 correctly.
+
+2011-01-11  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (open_elf): Remove section-based
+	address_sync fixup from here.
+	(find_prelink_address_sync): New function.
+	(find_debuginfo): Call it.
+	* libdwflP.h (DWFL_ERRORS): Add BAD_PRELINK error.
+
+2011-01-04  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (open_elf): Enhance address_sync calculation
+	logic to consider section addresses, the better to survive all the
+	possible prelink machinations.
+	* libdwflP.h (struct dwfl_file): Comment change.
+
+2010-11-30  Roland McGrath  <roland@redhat.com>
+
+	* derelocate.c (dwfl_module_relocations): Remove over-eager assert.
+
+2010-11-12  Roland McGrath  <roland@redhat.com>
+
+	* libdwflP.h (struct Dwfl_Module): New member main_bias.
+	(dwfl_adjusted_address, dwfl_deadjust_address): Use it.
+	* dwfl_module_getdwarf.c (__libdwfl_getelf): Initialize it.
+
+	* libdwflP.h (dwfl_deadjust_address): New function.
+	(dwfl_deadjust_dwarf_addr, dwfl_deadjust_st_value): New functions.
+	* cu.c (addrarange): Use dwfl_deadjust_dwarf_addr.
+	* dwfl_module_addrsym.c: Use dwfl_deadjust_st_value.
+
+2010-11-11  Roland McGrath  <roland@redhat.com>
+
+	* libdwflP.h (struct dwfl_file): Remove bias member.
+	Add vaddr and address_sync members instead.
+	(dwfl_adjusted_address): Calculate using vaddr.
+	(dwfl_adjusted_dwarf_addr): Calculate using address_sync and call that.
+	(dwfl_adjusted_st_value): Use one of those calls.
+	* dwfl_module_getdwarf.c (open_elf): Initialize vaddr and address_sync.
+	* dwfl_segment_report_module.c (dwfl_segment_report_module): Likewise.
+	* derelocate.c (dwfl_module_relocations): Update ET_EXEC assertions.
+	* link_map.c (consider_executable): Adjust only MOD->low_addr for
+	detected PIE bias change.
+
+	* libdwflP.h (dwfl_adjusted_dwarf_addr): New function.
+	* dwfl_module_info.c: Use it.
+	* cu.c (addrarange): Likewise.
+	* dwfl_dwarf_line.c: Likewise.
+	* dwfl_module_dwarf_cfi.c: Likewise.
+	* dwfl_lineinfo.c: Likewise.
+	* dwfl_nextcu.c: Likewise.
+	* dwfl_module_getdwarf.c (dwfl_module_getdwarf): Likewise.
+
+	* libdwflP.h (dwfl_adjusted_st_value): New function.
+	* relocate.c (resolve_symbol): Use it.
+	* dwfl_module_getsym.c: Likewise.
+	* dwfl_module_addrsym.c: Likewise.
+	* dwfl_module_info.c: Likewise.
+
+	* libdwflP.h (dwfl_adjusted_address): New function.
+	* dwfl_module_build_id.c (__libdwfl_find_build_id): Use it.
+	* relocate.c (__libdwfl_relocate_value): Likewise.
+	* derelocate.c (cache_sections): Likewise.
+	(dwfl_module_address_section): Likewise.
+	* dwfl_module_getelf.c: Likewise.
+	* dwfl_module_eh_cfi.c: Likewise.
+	* link_map.c (consider_executable): Likewise.
+
+2010-08-24  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_dwarf_line.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+
+2010-08-18  Roland McGrath  <roland@redhat.com>
+
+	* link_map.c (report_r_debug): Use found name if we have no name,
+	even if we already have an Elf handle.
+
+2010-06-30  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_find_elf): Don't be
+	confused by -1 return from dwfl_build_id_find_elf after it opened
+	the Elf handle.
+	* find-debuginfo.c (dwfl_standard_find_debuginfo): Likewise for
+	dwfl_build_id_find_debuginfo.
+
+2010-06-16  Roland McGrath  <roland@redhat.com>
+
+	* cu.c (cudie_offset): Use DIE_OFFSET_FROM_CU_OFFSET macro.
+
+2010-06-14  Roland McGrath  <roland@redhat.com>
+
+	* find-debuginfo.c (try_open): Take new arg MAIN_STAT.  Compare
+	candidate file to that st_dev/st_ino and pretend it didn't exist
+	if they match.
+	(find_debuginfo_in_path): Update caller, pass main file's info.
+
+2010-05-20  Roland McGrath  <roland@redhat.com>
+
+	* linux-proc-maps.c (find_sysinfo_ehdr): Renamed to ...
+	(grovel_auxv): ... this.  Take DWFL argument.
+	(dwfl_linux_proc_report): Update caller.
+
+	* dwfl_module_getdwarf.c (open_elf): Calculate alignment for bias
+	based on dwfl->segment_align or manifest alignment of MOD->low_addr.
+
+2010-05-19  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (intuit_kernel_bounds): Rewritten.
+
+2010-05-06  Roland McGrath  <roland@redhat.com>
+
+	* segment.c (insert): Clear inserted elements of DWFL->lookup_module.
+
+	* libdwflP.h (DWFL_ERRORS): Add WRONG_ID_ELF.
+	* dwfl_build_id_find_elf.c: Set MOD->main.valid when there is a build
+	ID but we didn't find a file.
+	* dwfl_module_getdwarf.c (__libdwfl_getelf): When that's set, check
+	and refuse any fallback file-by-name if it lacks the matching ID.
+
+	* dwfl_error.c (dwfl_errno): Add INTDEF.
+	* libdwflP.h: Add INTDECL.
+
+	* dwfl_module_getdwarf.c (open_elf): Do elf_end and clear FILE->elf in
+	failure cases.
+
+2010-05-04  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_segment_report_module.c: Use "[pie]" rather than "[dso]" for an
+	ET_DYN that has a DT_DEBUG.
+
+	* dwfl_segment_report_module.c: Fix jump-start of NDX-finding loop.
+
+	* segment.c (insert): Fix moving of values following insertion.
+	(reify_segments): Fix up MOD->segment backpointer indices after
+	later insertions in the main loop invalidate them.
+
+	* link_map.c (dwfl_link_map_report): Detect bias of embedded phdrs and
+	apply it to PT_DYNAMIC p_vaddr so we handle a PIE correctly.
+
+	* core-file.c (dwfl_core_file_report): Return any nonzero count of
+	modules reported, even if link_map grovelling failed and only sniffing
+	found anything.
+
+2010-04-26  Roland McGrath  <roland@redhat.com>
+
+	* relocate.c (relocate_section): Treat R_*_NONE reloc as no reloc.
+	Works around probably-wrong ld -r behavior for case of a DWARF address
+	constant that refers to a discarded SHF_ALLOC section.
+
+2010-04-14  Roland McGrath  <roland@redhat.com>
+
+	* link_map.c (report_r_debug): Limit iterations on the l_next chain to
+	an upper bound on sane possible number of elements.
+
+2010-03-11  Roland McGrath  <roland@redhat.com>
+
+	* link_map.c (auxv_format_probe): Fix scanning loop, so we really scan
+	the second half for 32-bit matches.
+
+2010-03-10  Roland McGrath  <roland@redhat.com>
+
+	* core-file.c (dwfl_core_file_report): Punt EHDR argument.
+	* argp-std.c (parse_opt): Update caller.
+	* libdwfl.h: Declare dwfl_core_file_report.
+	* libdwflP.h: Don't.
+
+2010-02-17  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_segment_report_module.c (addr_segndx): Take new flag argument.
+	If set, find the first index not below ADDR.
+	(dwfl_segment_report_module): Update callers.
+	Pass true when calculating return value.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Use config/eu.am for common stuff.
+
+	* find-debuginfo.c (find_debuginfo_in_path): Fix uninitialized
+	variable in failure path.
+
+2010-02-02  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_dwarf_cfi.c (dwfl_module_dwarf_cfi): Always set bias.
+	* dwfl_module_eh_cfi.c (dwfl_module_eh_cfi): Likewise
+
+2010-01-07  Roland McGrath  <roland@redhat.com>
+
+	* core-file.c (dwfl_core_file_report): Use elf_getphdrnum.
+	* dwfl_module_build_id.c (__libdwfl_find_build_id): Likewise.
+	* dwfl_module_getdwarf.c (open_elf, find_dynsym): Likewise.
+	* dwfl_report_elf.c (__libdwfl_report_elf): Likewise.
+
+2010-01-06  Roland McGrath  <roland@redhat.com>
+
+	* relocate.c (relocate_getsym): For SHN_COMMON, zero st_value.
+	(relocate_section): Let unresolved SHN_COMMON symbol stay 0.
+
+2009-11-16  Roland McGrath  <roland@redhat.com>
+
+	* relocate.c (relocate_section): Skip SHT_NOBITS or empty target scn.
+
+2009-11-12  Petr Machata  <pmachata@redhat.com>
+
+	* core-file.c (dwfl_elf_phdr_memory_callback): Only load ahead if
+	the chunk is both offset-contiguous and vaddr-contiguous.
+
+2009-11-05  Roland McGrath  <roland@redhat.com>
+
+	* link_map.c (report_r_debug): Skip entries with l_ld==0.
+	Use dwfl_addrmodule for l_ld lookup, don't bail on lookup failure.
+
+2009-09-04  Roland McGrath  <roland@redhat.com>
+
+	* image-header.c (__libdw_image_header): Fix tranposed comparison.
+
+2009-08-27  Roland McGrath  <roland@redhat.com>
+
+	* image-header.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwflP.h: Declare __libdw_image_header.
+	* open.c (decompress): Don't consume ELF on failure.
+	(what_kind): New function, broken out of ...
+	(__libdw_open_file): ... here.  Call it.
+	If it fails, try __libdw_image_header and then try what_kind again.
+
+	* gzip.c (unzip): Reuse *WHOLE as first INPUT_BUFFER,
+	leave it behind for next decompressor.
+	* open.c (decompress): Free BUFFER on failure.
+
+2009-08-26  Roland McGrath  <roland@redhat.com>
+
+	* gzip.c (find_zImage_payload): New function, broken out of ...
+	(mapped_zImage): ... here.  Call it.
+	(find_zImage_payload) [LZMA]: Match LZMA-compressed kernels with
+	stupid method of just trying the decoder.
+
+	* open.c [USE_LZMA]: Try __libdw_unlzma.
+	* libdwflP.h: Declare it.
+	(DWFL_ERRORS): Add DWFL_E_LZMA.
+	* gzip.c [LZMA]: Implement liblzma version for XZ file format.
+	* lzma.c: New file.
+	* Makefile.am [LZMA] (libdwfl_a_SOURCES): Add it.
+
+	* gzip.c (mapped_zImage): Limit scan to 32kb.
+	Make this unconditional, support bzip2 kernel images too.
+	(unzip): Use direct inflate method for non-mmap case too.
+	Only zlib uses the stream method.
+
+2009-08-09  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_build_id.c: Use new macros for versioned definitions.
+
+2009-07-08  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_dwarf_cfi.c: New file.
+	* dwfl_module_eh_cfi.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add them.
+	* libdwflP.h (struct Dwfl_Module): New members `dwarf_cfi', `eh_cfi.
+	Add INTDECL for dwfl_module_eh_cfi, dwfl_module_dwarf_cfi.
+
+2009-07-08  Roland McGrath  <roland@redhat.com>
+
+	* libdwflP.h (struct Dwfl_Module): Reorder members to pack better.
+
+2009-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Return NULL on overlap.
+
+2009-06-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* derelocate.c: Don't use deprecated libelf functions.
+	* dwfl_module_getdwarf.c: Likewise.
+	* relocate.c: Likewise.
+
+2009-04-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwfl_module_build_id.c: Define versioned symbols only if SHARED is
+	defined.  Otherwise just define the latest version.
+
+2009-04-22  Roland McGrath  <roland@redhat.com>
+
+	* relocate.c (resolve_symbol): Apply correct bias to st_value found in
+	a non-ET_REL module.
+
+	* dwfl_module_build_id.c (__libdwfl_find_build_id): Fix last change to
+	adjust properly for non-ET_REL.
+
+2009-04-21  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getsym.c: Apply non-ET_REL bias only if SHF_ALLOC.
+
+	* relocate.c (__libdwfl_relocate_value): Assert that MOD is ET_REL.
+	* derelocate.c (cache_sections): Call __libdwfl_relocate_value only
+	for ET_REL.
+	* dwfl_module_build_id.c (__libdwfl_find_build_id): Likewise.
+
+2009-04-20  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (__libdwfl_getelf): Add internal_function.
+
+2009-04-19  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_file): Renamed to ...
+	(__libdwfl_getelf): ... this.  Make it global.
+	(find_symtab, find_dw): Update callers.
+	(dwfl_module_getelf): Functions moved ...
+	* dwfl_module_getelf.c: ... here, new file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwflP.h: Declare __libdwfl_getelf.
+
+2009-04-14  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_segment_report_module.c: Handle DT_STRTAB value being either
+	absolute (already adjusted in place) or needing load bias adjustment.
+
+	* core-file.c (dwfl_elf_phdr_memory_callback): Fix return value for
+	gelf_getphdr failure.  Fix file size limit checks.
+
+	* dwfl_segment_report_module.c: Fix underflow in DYNSTRSZ check.
+
+2009-04-08  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getsym.c: Don't adjust for bias again after
+	__libdwfl_relocate_value.
+
+	* relocate.c (__libdwfl_relocate_value): Don't adjust a value from
+	a non-SHF_ALLOC section.
+	(relocate_getsym): Test st_shndx for SHN_* values, not *SHNDX.
+	* dwfl_module_getsym.c (dwfl_module_getsym): Likewise.
+
+2009-03-09  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_build_id.c (__libdwfl_find_build_id): Move SHSTRNDX
+	variable to outer scope, so we cache it for the loop.
+
+	* relocate.c (__libdwfl_relocate_value): Add MOD->main.bias to sh_addr.
+
+2009-02-12  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_build_id.c (__libdwfl_find_build_id): Use
+	__libdwfl_relocate_value to find correct sh_addr value.
+
+2009-02-10  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Take new arg SANITY.
+	If false, don't fail for NO_PHDR.
+	(dwfl_report_elf): Update caller.
+	* libdwflP.h: Update decl.
+	* offline.c (process_elf): Call it with false, so we don't refuse
+	dubiously-formed objects here.
+
+	* link_map.c (consider_executable): Don't assert dwfl_addrsegment
+	finds our module.  We shouldn't crash when we confuse some guesses.
+
+2009-02-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* open.c (decompress): Avoid crash with empty input file.
+
+2009-01-27  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Ignore trailing PT_LOAD
+	with zero vaddr and memsz.
+
+2009-01-22  Roland McGrath  <roland@redhat.com>
+
+	* open.c (decompress): Move BUFFER, SIZE decls outside #if.
+
+	* dwfl_segment_report_module.c (addr_segndx): Remove bogus adjustments
+	after address-matching loop.
+
+	* segment.c (lookup): Fix fencepost in checking for HINT match.
+
+2009-01-14  Roland McGrath  <roland@redhat.com>
+
+	* gzip.c [!BZLIB] (mapped_zImage): New function.
+	(unzip) [!BZLIB]: Grok Linux kernel zImage format.
+
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwfl_error.c: Always use __thread.  Remove all !USE_TLS code.
+
+2009-01-08  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_report_offline):
+	Skip subdirectory named "source".
+	(dwfl_linux_kernel_find_elf): Likewise.
+
+2009-01-06  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (check_suffix): New function.
+	Match ".ko", ".ko.gz", and ".ko.bz2" suffixes.
+	(dwfl_linux_kernel_report_offline): Use it.
+	(dwfl_linux_kernel_find_elf): Likewise.
+
+2009-01-05  Roland McGrath  <roland@redhat.com>
+
+	* argp-std.c (parse_opt): Use __libdw_open_file for core file.
+	* dwfl_build_id_find_debuginfo.c: Use it to open the file.
+	* dwfl_build_id_find_elf.c: Likewise.
+	* dwfl_module_getdwarf.c (open_elf): Likewise.
+	* dwfl_report_elf.c: Likewise.
+	* find-debuginfo.c (validate): Likewise.
+	* offline.c (__libdwfl_report_offline): Likewise.
+
+	* libdwflP.h: Declare __libdw_open_file.
+	* open.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+
+	* gzip.c: New file.
+	* Makefile.am [ZLIB] (libdwfl_a_SOURCES): Add it.
+	* bzip2.c: New file.
+	* Makefile.am [BZLIB] (libdwfl_a_SOURCES): Add it.
+	* libdwflP.h: Declare __libdw_gunzip, __libdw_bunzip2.
+
+2008-12-16  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_build_id.c (dwfl_module_build_id): Define with alias and
+	symver magic to bind to ELFUTILS_0.138.
+	(_BUG_COMPAT_dwfl_module_build_id): New function, bug compatible
+	wrapper for ELFUTILS_0.130 version set.
+
+2008-12-18  Roland McGrath  <roland@redhat.com>
+
+	* derelocate.c (dwfl_module_relocate_address): Fix last fix: ET_DYN
+	addresses are taken as relative to MOD->low_addr.
+
+2008-12-15  Roland McGrath  <roland@redhat.com>
+
+	* derelocate.c (dwfl_module_relocate_address): Apply main.bias, not
+	debug.bias.
+
+2008-12-11  Roland McGrath  <roland@redhat.com>
+
+	* offline.c (process_archive): Don't call elf_end and close if
+	returning NULL.  Check first elf_begin call and set error code
+	specially for empty archive.
+	Fixes RHBZ#465878.
+
+2008-12-02  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_getmodules.c (dwfl_getmodules): Typo fix in last change.
+
+2008-11-26  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_getmodules.c (dwfl_getmodules): Encode iteration style in
+	return value, and interpret encoded OFFSET argument.
+
+2008-10-07  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_build_id.c (check_notes): Fix typo in vaddr calculation.
+
+2008-09-29  Roland McGrath  <roland@redhat.com>
+
+	* segment.c (insert): Must realloc DWFL->lookup_module here too.
+	(dwfl_report_segment): Clear DWFL->lookup_module before insert calls.
+
+2008-08-28  Roland McGrath  <roland@redhat.com>
+
+	* segment.c (reify_segments): Fix last change.
+
+2008-08-27  Roland McGrath  <roland@redhat.com>
+
+	* linux-proc-maps.c (read_proc_memory): Return 0 for EINVAL or EPERM
+	failure from pread64.
+
+2008-08-26  Roland McGrath  <roland@redhat.com>
+
+	* segment.c (reify_segments): Insert a trailing segment for a module
+	end that is above the highest current segment.
+
+2008-08-25  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (open_elf): Extract elf_errno () for
+	coded return value, not plain DWFL_E_LIBELF.  Return DWFL_E_BADELF
+	if FILE->elf is not ELF_K_ELF.
+
+	* dwfl_segment_report_module.c: Add a cast.
+
+2008-08-21  Denys Vlasenko  <dvlasenk@redhat.com>
+
+	* dwfl_module_addrsym.c (dwfl_module_addrsym): Improve logic
+	which decides which symbol is "closest" to a given address.
+
+2008-08-15  Roland McGrath  <roland@redhat.com>
+
+	* argp-std.c (offline_callbacks): Use dwfl_build_id_find_elf.
+	(options, parse_opt): Handle --core.
+
+	* core-file.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwflP.h (dwfl_core_file_report): Declare it.
+
+	* link_map.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwflP.h (dwfl_link_map_report): Declare it.
+
+	* libdwflP.h (MIN, MAX): New macros.
+	(Dwfl_Memory_Callback): New typedef.
+	(Dwfl_Module_Callback): New typedef.
+	(dwfl_segment_report_module): Declare it.
+	* dwfl_segment_report_module.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+
+	* derelocate.c (dwfl_module_address_section): Add INTDEF.
+	* libdwflP.h: Add INTDECL.
+
+	* segment.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwfl.h: Declare dwfl_addrsegment, dwfl_report_segment.
+	* libdwflP.h (struct Dwfl): New members lookup_elts, lookup_alloc,
+	lookup_addr, lookup_module, lookup_segndx, replace removed members
+	modules, nmodules.
+	(struct Dwfl_Module): New member segment.
+	* dwfl_end.c (dwfl_end): Free the new ones.  Iterate via modulelist
+	to each free module.
+	* dwfl_module.c (dwfl_report_begin_add): Do nothing.
+	(dwfl_report_begin): Don't call it.  Truncate the segment table instead.
+	(dwfl_report_module): Don't touch DWFL->nmodules.
+	(dwfl_report_end): Don't touch DWFL->modules and DWFL->nmodules.
+	(compare_modules): Function removed.
+	* dwfl_getmodules.c: Rewritten.
+	Add INTDEF.
+	* libdwflP.h: Add INTDECLs.
+	* dwfl_getdwarf.c: Rewritten to call dwfl_getmodules.
+	* dwfl_addrmodule.c: Rewritten to just call dwfl_addrsegment.
+
+2008-08-03  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c: Include <fts.h> before <config.h>.
+
+2008-07-17  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Set errno to
+	zero if the failure was only ENOENT.
+
+2008-06-03  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_addrsym.c (dwfl_module_addrsym): Exclude undefined
+	symbols.
+
+2008-05-22  Petr Machata  <pmachata@redhat.com>
+
+	* dwfl_module_getdwarf.c (open_elf): Bias of ET_EXEC files is always 0.
+
+2008-05-06  Roland McGrath  <roland@frob.com>
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Use
+	FTS_LOGICAL here too.
+	(dwfl_linux_kernel_find_elf): Likewise.
+
+2008-04-29  Roland McGrath  <roland@redhat.com>
+
+	* find-debuginfo.c (dwfl_standard_find_debuginfo): Try path search
+	based on canonicalize_file_name if it differs from the supplied name.
+
+	* linux-kernel-modules.c (check_module_notes): Use FTS_LOGICAL so
+	we accept symlinks.
+
+2008-04-27  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (report_kernel): Fix crash when
+	dwfl_report_elf fails.
+
+2008-04-05  Roland McGrath  <roland@redhat.com>
+
+	* linux-proc-maps.c (proc_maps_report): Don't leak LAST_FILE.
+
+	* dwfl_module_getdwarf.c (find_file): Always free build_id_bits.
+	Clear it after freeing.
+	* dwfl_module_report_build_id.c (dwfl_module_report_build_id): Likewise.
+
+2008-03-26  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (load_symtab): Don't return success for
+	SHT_DYNSYM, just set *SYMSCN like the comment says.
+
+	* dwfl_end.c (dwfl_end): Iterate on modulelist chain, not modules array.
+
+	* argp-std.c (parse_opt): On failure, call dwfl_end before argp_failure.
+
+2008-03-19  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getsrc.c: Adjust address for module bias before search.
+
+2008-03-01  Roland McGrath  <roland@redhat.com>
+
+	* libdwflP.h (__libdwfl_seterrno): Remove parameter name from
+	prototype to avoid older compiler's complaint about reuse of the name.
+	(__libdwfl_canon_error): Likewise.
+
+2008-02-19  Roland McGrath  <roland@redhat.com>
+
+	* relocate.c (relocate_section): Check for an unhandled relocation
+	type before resolving a reloc's symbol.  Lift DWFL_E_BADRELTYPE ->
+	DWFL_E_UNKNOWN_MACHINE check out of loops.
+
+	* dwfl_module_getdwarf.c (load_dw): Skip relocation if
+	DEBUGFILE->relocated is already set.
+
+2008-01-26  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (open_elf): Open FILE->name if it's non-null.
+
+	* dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Don't clear
+	incoming *FILE_NAME at the start.
+
+2008-01-08  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (euinclude): Variable removed.
+	(pkginclude_HEADERS): Set this instead of euinclude_HEADERS.
+
+2007-10-23  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (report_kernel_archive): Reorder the kernel
+	module to appear first.
+
+2007-10-20  Roland McGrath  <roland@redhat.com>
+
+	* offline.c (process_archive_member): Take FD argument, pass it down
+	to process_file.  Return Elf_Cmd, not bool.
+	Call elf_next here, always before elf_end.
+	(process_archive): Update caller.  Don't close FD here unless there
+	are no member refs.
+
+	* dwfl_module.c (free_file): Close fd only when elf_end returns zero.
+
+	* libdwflP.h (struct dwfl_file): New bool member `relocated'.
+	* dwfl_module_getdwarf.c (dwfl_module_getelf): For ET_REL, apply
+	partial relocation to one or both files.
+	(dwfl_module_getdwarf): For ET_REL, make sure extra sections'
+	relocations have been applied to the debug file if dwfl_module_getelf
+	has been used before.
+
+	* relocate.c (resolve_symbol): New function.
+	(relocate_section): Call it.
+
+	* relocate.c (relocate_getsym): Handle null MOD->symfile.
+	(relocate_section): Take new bool arg, PARTIAL.  If true,
+	no error for BADRELTYPE/RELUNDEF, instead just skip them
+	and leave only those skipped relocs behind the reloc section.
+	(__libdwfl_relocate_section): Take new arg, pass it down.
+	(__libdwfl_relocate): Take new bool arg, DEBUG.  If false,
+	do partial relocation on all sections.
+	* dwfl_module_getdwarf.c (load_dw): Update caller.
+	* libdwflP.h: Update decls.
+	* derelocate.c (dwfl_module_address_section): Pass new argument
+	to __libdwfl_relocate_section, true.
+
+	* derelocate.c (cache_sections): Don't cache reloc sections when
+	section_address callback is null.
+
+2007-10-19  Roland McGrath  <roland@redhat.com>
+
+	* relocate.c (relocate_section): Fix fencepost error in r_offset check.
+
+	* derelocate.c (struct dwfl_relocation): Add member `relocs'.
+	(struct secref): Likewise.
+	(cache_sections): Cache the relocation section referring to each
+	section we cache, if any.
+	(dwfl_module_address_section): Use __libdwfl_relocate_section as
+	necessary.
+
+	* relocate.c (struct reloc_symtab_cache): New type.
+	(relocate_getsym): Use it instead of four arguments.
+	(__libdwfl_relocate): Update caller.
+	(relocate_section): New function, broken out of ...
+	(__libdwfl_relocate): ... here.
+	(__libdwfl_relocate_section): New function.
+	* libdwflP.h: Declare it.
+
+2007-10-17  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getsym.c (dwfl_module_getsym): Apply MOD->symfile->bias
+	to relocated st_value.
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Align initial BASE for
+	ET_REL to 0x100.
+
+2007-10-16  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Readjust BASE when a later
+	section has larger alignment requirements not met by the original BASE,
+	rather than padding more between sections.
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Fix bias calculation.
+
+	* dwfl_module_build_id.c (__libdwfl_find_build_id): Apply module bias
+	to sh_addr value.
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Don't be confused by BASE
+	at zero in ET_REL case.  Adjust BASE to necessary alignment.
+
+	* dwfl_module_build_id.c (check_notes): Take -1, not 0, as stub value
+	for DATA_VADDR.
+	(__libdwfl_find_build_id): Update caller.
+
+	* relocate.c (__libdwfl_relocate_value): Don't use sh_offset.
+	* dwfl_report_elf.c (__libdwfl_report_elf): Likewise.
+	* offline.c (dwfl_offline_section_address): Bail early if there is
+	separate debug file.
+
+	* relocate.c (__libdwfl_relocate): Don't return DWFL_E_NO_DWARF.
+
+2007-10-09  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): Clear SHDR->sh_offset when
+	caching SHDR->sh_addr = 0.
+	* offline.c (dwfl_offline_section_address): Never called for sh_addr
+	really at 0, don't check for it.  Use MOD->debug directly, not symfile.
+
+	* dwfl_module_getdwarf.c (load_symtab): Return success properly when
+	we've found SHT_SYMTAB.
+
+	* relocate.c (relocate_getsym): New function.
+	(__libdwfl_relocate): Use it.
+	(__libdwfl_relocate_value): Take new Elf * argument.  Make SYMSHSTRNDX
+	be a pointer instead of value; cache getshstrndx result there.
+	* libdwflP.h: Update decl.
+	* derelocate.c (cache_sections): Update caller.
+	Always work on the main file, not the symfile.
+	(dwfl_module_address_section): Likewise.
+	* dwfl_module_getsym.c (dwfl_module_getsym): Update caller.
+
+2007-10-07  Roland McGrath  <roland@redhat.com>
+
+	* offline.c (process_archive): Initialize MOD.
+
+	* linux-kernel-modules.c (get_release): New function, broken out of ...
+	(report_kernel): ... here.  Call it.
+	(try_kernel_name): Take new arg TRY_DEBUG, only try ".debug" if set.
+	(find_kernel_elf): Update caller.
+	(report_kernel_archive): New function.
+	(dwfl_linux_kernel_report_offline): Call it.
+
+	* offline.c (process_file): Take new arg PREDICATE, pass it down.
+	(process_archive): Likewise.
+	(process_archive_member): Likewise.  When nonnull, let the predicate
+	decide whether to use this member.
+	(__libdwfl_report_offline): New function, broken out of ...
+	(dwfl_report_offline): ... here.  Call it.
+	* libdwflP.h: Declare it.
+
+	* offline.c (process_archive, process_archive_member): New functions.
+	(process_elf, process_file): New functions, broken out of ...
+	(dwfl_report_offline): ... here.  Call process_file, which recurses on
+	ELF_K_AR files.
+
+	* dwfl_report_elf.c (__libdwfl_report_elf): New, broken out of ...
+	(dwfl_report_elf): ... here.  Call it.
+	* libdwflP.h: Declare it.
+
+2007-10-06  Roland McGrath  <roland@redhat.com>
+
+	* derelocate.c (dwfl_module_relocations): Don't call
+	dwfl_module_getdwarf.
+
+	* derelocate.c (find_section): Use __libdwfl_seterrno, not
+	__libdw_seterrno.
+
+	* relocate.c (__libdwfl_relocate_value): Abuse sh_offset, not
+	SHF_ALLOC, to cache sh_addr resolved to 0.
+
+	* dwfl_report_elf.c (dwfl_report_elf): When an ET_REL file has sh_addr
+	values nonzero already, just use its existing layout.
+
+	* relocate.c (__libdwfl_relocate): Clear size of reloc section in its
+	in-core shdr after applying it.
+
+2007-10-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_report_kernel): Fake
+	initialization of notes variable.
+
+2007-10-04  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (intuit_kernel_bounds): Take new arg NOTES,
+	fill in with vaddr of "__start_notes" symbol if found.
+	(check_notes): New function.
+	(check_kernel_notes): New function.
+	(dwfl_linux_kernel_report_kernel): Call it.
+	(check_module_notes): New function.
+	(dwfl_linux_kernel_report_modules): Call it.
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_find_elf):
+	Try dwfl_build_id_find_elf first.
+
+	* linux-kernel-modules.c (report_kernel): Don't leak FD if !REPORT.
+	Set kernel module e_type to ET_DYN.
+
+2007-10-03  Roland McGrath  <roland@redhat.com>
+
+	* find-debuginfo.c (validate): New function, broken out of ...
+	(find_debuginfo_in_path): ... here.  New function, broken out of ...
+	(dwfl_standard_find_debuginfo): ... here.  Call it, after trying
+	dwfl_build_id_find_debuginfo first.
+
+	* dwfl_build_id_find_elf.c: New file.
+	* dwfl_build_id_find_debuginfo.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add them.
+	* libdwfl.h: Declare them.
+	* libdwflP.h: Add INTDECLs.
+
+	* dwfl_module_build_id.c: New file.
+	* dwfl_module_report_build_id.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add them.
+	* libdwfl.h: Declare them.
+	* libdwflP.h (struct Dwfl_Module): New members build_id_bits,
+	build_id_len, build_id_vaddr.  Declare __libdwfl_find_build_id.
+	* dwfl_module.c (__libdwfl_module_free): Free MOD->build_id_bits.
+
+	* dwfl_module_getdwarf.c (find_offsets): New function.
+	(find_dynsym): New function, calls that.
+	(find_symtab): Call it.
+
+2007-09-11  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_addrsym.c: Prefer a later global symbol at the same
+	address if its st_size is smaller.
+
+2007-08-13  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_addrsym.c: Add dead initializer for stupid compiler.
+
+2007-08-12  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Don't use
+	FTS_LOGICAL.
+
+	* elf-from-memory.c (elf_from_remote_memory): Don't reset LOADBASE on
+	a second phdr if it happens to match EHDR_VMA exactly.
+
+2007-08-08  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_addrsym.c: Don't use STT_SECTION, STT_FILE symbols and
+	those with no names.  Rewrite best symbol algorithm not to assume a
+	sorted table and to be smarter handling sizeless symbols.
+
+2007-07-16  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module.c (dwfl_report_module): Increment DWFL->nmodules when
+	reviving an existing module.
+
+2007-06-08  Roland McGrath  <roland@redhat.com>
+
+	* libdwflP.h: Fix #ifndef for config.h to use PACKAGE_NAME.
+
+2007-05-17  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_report_offline): Look at
+	whole /lib/modules/VERSION tree, not just /lib/modules/VERSION/kernel.
+	(dwfl_linux_kernel_find_elf): Likewise.
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_report_modules): Use
+	getline and sscanf instead of fscanf.
+
+2007-05-08  Roland McGrath  <roland@redhat.com>
+
+	* offline.c (dwfl_offline_section_address): Don't assume section
+	numbers match between stripped and debuginfo files.  Instead, assume
+	only that the ordering among SHF_ALLOC sections matches.
+
+	* linux-kernel-modules.c (report_kernel): Change RELEASE argument to
+	pointer to string.
+	(dwfl_linux_kernel_report_offline): Update caller.
+	(dwfl_linux_kernel_report_kernel): Likewise.
+
+2007-04-23  Roland McGrath  <roland@redhat.com>
+
+	* argp-std.c (options): Fix group title string.
+
+	* argp-std.c (parse_opt): Handle ARGP_KEY_ERROR, free the Dwfl.
+	Update via STATE->input every time we set STATE->hook, not only at
+	ARGP_KEY_SUCCESS.
+
+	* dwfl_module.c (free_file): Free FILE->name.
+
+2007-04-16  Roland McGrath  <roland@redhat.com>
+
+	* derelocate.c (cache_sections): Apply bias to sh_addr.
+	(compare_secrefs): Fix address comparison to avoid signed overflow.
+	(find_section): New function, broken out of ...
+	(dwfl_module_relocate_address): ... here, call it.
+	(check_module): New function, broken out of ...
+	(dwfl_module_relocate_address): ... here, call it.
+	(dwfl_module_address_section): New function.
+	* libdwfl.h: Declare it.
+
+2007-03-26  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module.c (__libdwfl_module_free): Free MOD itself.
+
+2007-03-18  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (find_debuglink): New function, broken out of
+	(find_debuginfo): ... here.  Call it.
+	Don't return error for libelf errors finding .gnu_debuglink section.
+
+2007-03-12  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module.c (dwfl_report_begin_add): New function broken out of ...
+	(dwfl_report_begin): ... here.  Call it.
+	* libdwfl.h: Declare it.
+	* libdwflP.h: Add INTDECL.
+
+	* elf-from-memory.c (elf_from_remote_memory): Fix 32/64 typo.
+
+	* offline.c: Comment typo fix.
+
+2007-03-04  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (KERNEL_MODNAME): New macro for "kernel".
+	(find_kernel_elf): New function, broken out of ...
+	(report_kernel): ... here.  Call it.
+	(dwfl_linux_kernel_find_elf): Use it for module named KERNEL_MODNAME.
+	(intuit_kernel_bounds): New function, grovel /proc/kallsyms to guess
+	virtual address bounds of kernel from symbols rounded to page size.
+	(dwfl_linux_kernel_report_kernel): Use that if it works, before
+	resorting to report_kernel.
+
+	* dwfl_module_getdwarf.c (open_elf): Set MOD->e_type to ET_DYN for an
+	ET_EXEC file with nonzero bias.
+
+	* dwfl_module_addrname.c (dwfl_module_addrname): Just call
+	dwfl_module_addrsym.  Guts moved to ...
+	* dwfl_module_addrsym.c: ... here; new file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwfl.h: Declare dwfl_module_addrsym.
+	* libdwflP.h: Add INTDECL.
+
+2007-03-03  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module.c (free_file): New function, broken out of ...
+	(__libdwfl_module_free): ... here.  In it, close fd after elf_end.
+
+	* dwfl_module_getdwarf.c (open_elf): Close fd and reset to -1
+	on libelf failure.
+
+2007-03-02  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c: Fix bogus error test for asprintf call.
+
+2007-02-02  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_addrmodule.c (dwfl_addrmodule): Match a module's high boundary
+	address exactly if it's no other module's low boundary.
+
+	* dwfl_module_addrname.c (dwfl_module_addrname): If no symbol's value
+	and size cover the address, select the closest symbol with st_size==0
+	that lies in the same section.
+
+2007-01-29  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_version.c (dwfl_version): Return PACKAGE_VERSION,
+	not PACKAGE_STRING.
+
+2007-01-20  Roland McGrath  <roland@redhat.com>
+
+	* relocate.c (__libdwfl_relocate_value): Treat section_address of -1
+	as omitted, not 0.
+	* libdwfl.h (Dwfl_Callbacks): Update comment.
+	* derelocate.c (cache_sections): Don't ignore sh_addr == 0 sections.
+	* linux-kernel-modules.c (dwfl_linux_kernel_module_section_address):
+	For ignored missing section, use -1 instead of 0.
+	* offline.c (dwfl_offline_section_address): Expect a call for 0.
+
+2007-01-19  Roland McGrath  <roland@redhat.com>
+
+	* argp-std.c (parse_opt): For -e, reset DWFL->offline_next_address to
+	zero so a lone -e foo.so is shown without address bias.
+
+2007-01-10  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (report_kernel): Check asprintf return value
+	directly instead of via side effect, to silence warn_unused_result.
+	(dwfl_linux_kernel_report_offline): Likewise.
+	(dwfl_linux_kernel_find_elf): Likewise.
+	(dwfl_linux_kernel_module_section_address): Likewise.
+	* find-debuginfo.c (try_open): Likewise.
+	* linux-proc-maps.c (find_sysinfo_ehdr): Likewise.
+	(dwfl_linux_proc_report): Likewise.
+
+	* libdwfl.h (dwfl_begin): Require nonnull argument.
+
+2006-12-27  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module.c (compare_modules): Fix address comparison to avoid
+	signed overflow.  Patch by Frank Ch. Eigler <fche@redhat.com>.
+
+2006-10-30  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module.c (dwfl_report_module): Comment typo fix.
+
+2006-09-05  Roland McGrath  <roland@redhat.com>
+
+	* derelocate.c (cache_sections): Use alloca instead of variable-sized
+	auto array, in function already using alloca.
+
+2006-08-14  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (try_kernel_name): If the call to
+	dwfl_standard_find_debuginfo produces no results, try it again
+	with NULL as DEBUGLINK_FILE to try *FNAME with .debug suffix.
+
+	* find-debuginfo.c (DEFAULT_DEBUGINFO_PATH): Macro moved ...
+	* libdwflP.h: ... to here.
+	* linux-kernel-modules.c (try_kernel_name): Skip manual open if it
+	repeats the first thing dwfl_standard_find_debuginfo will try.
+
+	* linux-kernel-modules.c (MODULE_SECT_NAME_LEN): New macro.
+	(dwfl_linux_kernel_module_section_address): If a /sys file is missing
+	and the section name is >= MODULE_SECT_NAME_LEN, try truncating the
+	section name.
+
+2006-07-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* cu.c: Adjust for internal_function_def removal.
+	* dwfl_error.c: Likewise.
+	* dwfl_module.c: Likewise.
+	* dwfl_module_getdwarf.c: Likewise.
+	* lines.c: Likewise.
+	* relocate.c: Likewise.
+
+2006-07-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwfl_module.c (compare_modules): Don't return GElf_Sxword value,
+	it can overflow the return value type.
+	Patch by Tim Moore <timoore@redhat.com>.
+
+2006-06-28  Roland McGrath  <roland@redhat.com>
+
+	* libdwfl.h: Cosmetic changes.
+
+	* dwfl_line_comp_dir.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwfl.h: Declare dwfl_line_comp_dir.
+
+	* dwfl_lineinfo.c (dwfl_lineinfo): Remove stray extern in defn.
+
+	* dwfl_linecu.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwfl.h: Declare dwfl_linecu.
+
+	* libdwflP.h (dwfl_linecu_inline): Function renamed from dwfl_linecu.
+	(dwfl_linecu): Define as macro.
+
+	* relocate.c (__libdwfl_relocate): Use dwfl_module_getsym.
+
+	* dwfl_module_getdwarf.c (dwfl_module_getsymtab): New function.
+	(dwfl_module_addrname): Function moved ...
+	* dwfl_module_addrname.c: ... here, new file.
+	* dwfl_module_getsym.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add them.
+	* libdwfl.h: Declare dwfl_module_getsymtab, dwfl_module_getsym.
+	* libdwflP.h: Add INTDECLs.
+
+2006-06-27  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module.c (dwfl_report_end): Whitespace fix.
+
+2006-06-13  Roland McGrath  <roland@redhat.com>
+
+	* elf-from-memory.c (elf_from_remote_memory): Fix 32/64 typo.
+	Use __libdwfl_seterrno for elf_memory failure.
+
+2006-05-22  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_return_value_location.c
+	(dwfl_module_return_value_location): Use __libdwfl_module_getebl.
+
+2006-05-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* libdwfl.h: Add extern "C".
+
+2006-05-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* cu.c (addrarange): Handle files without aranges information.
+
+2006-05-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* dwfl_addrmodule.c (dwfl_addrmodule): Also return NULL of
+	->modules is NULL.
+
+2006-02-26  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_version.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwfl.h: Declare dwfl_version.
+
+	* offline.c (dwfl_report_offline): Account for dwfl_report_elf having
+	aligned up from DWFL->offline_next_address when checking for overlap.
+
+2005-12-22  Roland McGrath  <roland@redhat.com>
+
+	* argp-std.c (parse_opt): Call dwfl_end in failure cases.
+
+	* linux-proc-maps.c (proc_maps_report): New function, broken out of ...
+	(dwfl_linux_proc_report): ... here.  Call it.
+	(dwfl_linux_proc_maps_report): New function.
+	* libdwfl.h: Declare it.
+	* libdwflP.h: Add INTDECL.
+	* argp-std.c (options, parse_opt): Grok -M/--linux-process-map.
+
+	* dwfl_nextcu.c (dwfl_nextcu): Don't fail when dwfl_module_getdwarf
+	failed with DWFL_E_NO_DWARF.
+
+2005-11-26  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_end.c (dwfl_end): Free the DWFL itself.
+
+2005-11-25  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getdwarf.c (__libdwfl_module_getebl): New function.
+	(load_dw): Use it.
+	* dwfl_module_register_names.c (dwfl_module_register_names): Likewise.
+	* libdwflP.h: Declare it.
+
+	* dwfl_module_register_names.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwfl.h: Declare dwfl_module_register_names.
+
+2005-11-21  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_module_section_address):
+	Don't leak malloc'd file name.
+	If a /sys/.../sections file is missing and starts with ".init",
+	try the variant with "_init" too; catches PPC64 kernel braindamage.
+
+2005-11-15  Roland McGrath  <roland@redhat.com>
+
+	* libdwfl.h: Comment fixes.
+
+	* dwfl_module_return_value_location.c: Add unlikely for error case.
+
+2005-11-13  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_return_value_location.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwfl.h: Declare dwfl_module_return_value_location.
+	* libdwflP.h (DWFL_ERRORS): Add DWFL_E_WEIRD_TYPE.
+
+2005-10-20  Roland McGrath  <roland@redhat.com>
+
+	* libdwflP.h (DWFL_ERRORS): New error UNKNOWN_MACHINE.
+	* relocate.c (__libdwfl_relocate): Return DWFL_E_UNKNOWN_MACHINE
+	instead of DWFL_E_BADRELTYPE if ebl_get_elfmachine yields EM_NONE.
+
+2005-10-01  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (report_kernel): Return ENOENT if we fail
+	with errno 0.
+
+2005-09-19  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_report_modules): Use
+	PRIx64 instead of PRIi64, lest addresses with high bits set overflow
+	the signed integer reading; they will just have to be in hexadecimal.
+	(dwfl_linux_kernel_module_section_address): Likewise.
+
+2005-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (%.os): Use COMPILE.os.
+	(COMPILE.os): Filter out gconv options.
+
+2005-08-25  Roland McGrath  <roland@redhat.com>
+
+	* cu.c (__libdwfl_nextcu): Return success when dwarf_nextcu hits end.
+	* dwfl_nextcu.c (dwfl_nextcu): Skip modules with no dwarf info.
+
+2005-08-24  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_lineinfo.c (dwfl_lineinfo): Add bias, don't subtract it.
+
+	* argp-std.c [_MUDFLAP] (__libdwfl_argp_mudflap_options): New function,
+	magic initializer to set -heur-stack-bound option.
+
+2005-08-22  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_validate_address.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwfl.h: Declare dwfl_validate_address.
+
+	* derelocate.c (dwfl_module_relocate_address): Add INTDEF.
+	* libdwflP.h: Add INTDECL.
+
+	* dwfl_module_getdwarf.c (find_symtab): Use elf_getdata instead of
+	elf_rawdata for symbol-related sections.
+
+	* offline.c (dwfl_report_offline): Move offline_next_address outside
+	module's range, in case it's an ET_EXEC using fixed segment locations.
+	* libdwfl.h: Update comment.
+
+	* dwfl_report_elf.c (dwfl_report_elf): Align BASE to first segment's
+	required alignment.
+
+2005-08-20  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (report_kernel): Take new argument PREDICATE,
+	function to choose whether to report.
+	(dwfl_linux_kernel_report_offline): Likewise.
+	* libdwfl.h: Update decl.
+	* argp-std.c (parse_opt): Update caller.
+
+	* dwfl_getsrclines.c: New file.
+	* dwfl_onesrcline.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add them.
+	* libdwfl.h: Declare dwfl_getsrclines, dwfl_onesrcline.
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_find_elf): Don't leak
+	MODULESDIR[0].  Call fts_close on failure.
+
+	* dwfl_module_getdwarf.c (load_dw): Take dwfl_file * instead of Elf *.
+	Close ET_REL file descriptors after relocation.
+	(find_dw): Update caller.
+	* offline.c (dwfl_report_offline): Get the file into memory and close
+	the file descriptor.
+
+	* dwfl_module_getdwarf.c (find_debuginfo): Do nothing when
+	MOD->debug.elf is already set.
+
+	* find-debuginfo.c (try_open): Use TEMP_FAILURE_RETRY.
+	(dwfl_standard_find_debuginfo): Fail on errors not ENOENT or ENOTDIR.
+
+	* argp-std.c (options, parse_opt): Grok -K/--offline-kernel, use
+	dwfl_linux_kernel_report_offline with offline_callbacks.
+
+	* linux-kernel-modules.c (report_kernel): New function, broken out of
+	...
+	(dwfl_linux_kernel_report_kernel): ... here.  Use it.
+	(dwfl_linux_kernel_report_offline): New function.
+	* libdwfl.h: Declare it.
+	* libdwflP.h: Add INTDECL.
+
+2005-08-19  Roland McGrath  <roland@redhat.com>
+
+	Use standard debuginfo search path to look for vmlinux.
+	* find-debuginfo.c (dwfl_standard_find_debuginfo): Don't check CRC if
+	passed zero.
+	* linux-kernel-modules.c (try_kernel_name): New function, broken out
+	of ...
+	(dwfl_linux_kernel_report_kernel): ... here.  Use it.
+
+	* argp-std.c (offline_callbacks): New variable.
+	(parse_opt): Use it for -e.  Allow multiple -e options.
+
+	* offline.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+	* libdwfl.h: Declare dwfl_offline_section_address, dwfl_report_offline.
+	* libdwflP.h: Add INTDECLs.
+	(OFFLINE_REDZONE): New macro.
+	(struct Dwfl): New member `offline_next_address'.
+	* dwfl_begin.c (dwfl_begin): Initialize it.
+	* dwfl_module.c (dwfl_report_begin): Likewise.
+
+	* dwfl_report_elf.c (dwfl_report_elf): Accept all types.  When ET_REL,
+	do a nominal absolute section layout starting at BASE.
+	* libdwfl.h: Update comment.
+
+2005-08-18  Roland McGrath  <roland@redhat.com>
+
+	* dwfl_module_getsrc_file.c (dwfl_module_getsrc_file): Do
+	dwfl_module_getdwarf if necessary.
+
+	* dwfl_report_elf.c (dwfl_report_elf): Permit ET_REL with BASE==0.
+	* libdwfl.h: Update comment.
+
+	* derelocate.c: New file.
+	* Makefile.am (libdwfl_a_SOURCES): Add it.
+
+	* libdwflP.h (struct Dwfl_Module): isrel -> e_type.
+	* dwfl_report_elf.c (dwfl_report_elf): Initialize it.
+	* dwfl_module_getdwarf.c (open_elf): Update initialization.
+	(load_dw, dwfl_module_addrname): Update uses.
+	* relocate.c (__libdwfl_relocate): Likewise.
+
+2005-08-04  Roland McGrath  <roland@redhat.com>
+
+	* libdwfl.h (Dwfl_Callbacks.section_address): Take additional
+	arguments SHNDX, SHDR.
+	(dwfl_linux_kernel_module_section_address): Update prototype.
+	* relocate.c (__libdwfl_relocate_value): Update caller.
+	* linux-kernel-modules.c (dwfl_linux_kernel_module_section_address):
+	Take the new arguments.
+
+2005-08-10  Roland McGrath  <roland@redhat.com>
+
+	* relocate.c (__libdwfl_relocate): Take argument DEBUGFILE,
+	use it instead of MOD->debug.file.
+	* libdwflP.h: Update decl.
+	* dwfl_module_getdwarf.c (load_dw): Update caller.
+	Fixes bug #165598.
+
+2005-08-09  Roland McGrath  <roland@redhat.com>
+
+	* libdwflP.h: Include ../libdw/libdwP.h for its INTDECLs.
+	* cu.c: Use INTUSE on dwarf_* calls.
+	* dwfl_error.c: Likewise.
+	* dwfl_module.c: Likewise.
+	* dwfl_module_getdwarf.c: Likewise.
+	* dwfl_module_getsrc_file.c: Likewise.
+	* lines.c: Likewise.
+
+2005-08-07  Roland McGrath  <roland@redhat.com>
+
+	* linux-kernel-modules.c (dwfl_linux_kernel_find_elf): When module
+	names contain '_' or '-', look for files named either "foo-bar.ko"
+	or "foo_bar.ko".
+
+2005-07-29  Roland McGrath  <roland@redhat.com>
+
+	* loc2c.c: File removed.
+	* loc2c.h: File removed.
+	* loc2c-runtime.h: File removed.
+	* test2.c: File removed.
+	* Makefile.am (EXTRA_DIST): Variable removed.
+	(noinst_HEADERS): Remove loc2c.h from here.
+
+2005-07-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* libdwfl.h: Add a few missing extern for function prototypes.
+
+	* libdwfl_crc32.c: New file.
+	* libdwfl_crc32_file.c: New file.
+	* libdwflP.h: Declare the new functions.
+	* Makefile.am (libdwfl_a_SOURCES): Add libdwfl_crc32.c and
+	libdwfl_crc32_file.c.
+	* libdwfl/find-debuginfo.c (check_crc): Use __libdwfl_crc32_file
+	instead of crc32_file.
+
+2005-07-28  Roland McGrath  <roland@redhat.com>
+
+	* ptest.c: Moved to ../tests/dwflmodtest.c.
+
+	* Makefile.am (noinst_PROGRAMS): Variable removed.
+	(libdwfl_so_SOURCES, libdwfl_LIBS, libdwfl_so_LDADD): Likewise.
+	(EXTRA_DIST, ptest_LDADD, test2_LDADD): Likewise.
+	(libdwfl): Don't use libdwfl.so any more.
+	(libdwfl.so, install, uninstall): Targets removed.
+	(test2_SOURCES): Define EXTRA_DIST instead of this.
+	* libdwfl.map: File removed.
+
+	* libdwfl.h: Use "" for libdw.h #include.
+
+2005-07-27  Roland McGrath  <roland@redhat.com>
+
+	* libdwfl.map: Add dwfl_getmodules.
+
+2005-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Fix rules to allow building with mudflap.
+
+2005-07-21  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (noinst_HEADERS): Add loc2c.c.
+
+	* test2.c (main): Check sscanf result to quiet warning.
+
+2005-07-20  Roland McGrath  <roland@redhat.com>
+
+	* libdwfl-branch merged, creating this direcotry.
diff --git a/third_party/elfutils/libdwfl/Makefile.am b/third_party/elfutils/libdwfl/Makefile.am
new file mode 100644
index 0000000..89ca92e
--- /dev/null
+++ b/third_party/elfutils/libdwfl/Makefile.am
@@ -0,0 +1,92 @@
+## Makefile.am for libdwfl library subdirectory in elfutils.
+##
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 2005-2010, 2013 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * 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
+##
+## or both in parallel, as here.
+##
+## elfutils 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.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+AM_CPPFLAGS += -I$(srcdir) -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+	   -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf
+VERSION = 1
+
+noinst_LIBRARIES = libdwfl.a
+noinst_LIBRARIES += libdwfl_pic.a
+
+pkginclude_HEADERS = libdwfl.h
+
+libdwfl_a_SOURCES = dwfl_begin.c dwfl_end.c dwfl_error.c dwfl_version.c \
+		    dwfl_module.c dwfl_report_elf.c relocate.c \
+		    dwfl_module_build_id.c dwfl_module_report_build_id.c \
+		    derelocate.c offline.c segment.c \
+		    dwfl_module_info.c dwfl_getmodules.c dwfl_getdwarf.c \
+		    dwfl_module_getdwarf.c dwfl_module_getelf.c \
+		    dwfl_validate_address.c \
+		    argp-std.c find-debuginfo.c \
+		    dwfl_build_id_find_elf.c \
+		    dwfl_build_id_find_debuginfo.c \
+		    linux-kernel-modules.c linux-proc-maps.c \
+		    dwfl_addrmodule.c dwfl_addrdwarf.c \
+		    cu.c dwfl_module_nextcu.c dwfl_nextcu.c dwfl_cumodule.c \
+		    dwfl_module_addrdie.c dwfl_addrdie.c \
+		    lines.c dwfl_lineinfo.c dwfl_line_comp_dir.c \
+		    dwfl_linemodule.c dwfl_linecu.c dwfl_dwarf_line.c \
+		    dwfl_getsrclines.c dwfl_onesrcline.c \
+		    dwfl_module_getsrc.c dwfl_getsrc.c \
+		    dwfl_module_getsrc_file.c \
+		    libdwfl_crc32.c libdwfl_crc32_file.c \
+		    elf-from-memory.c \
+		    dwfl_module_dwarf_cfi.c dwfl_module_eh_cfi.c \
+		    dwfl_module_getsym.c \
+		    dwfl_module_addrname.c dwfl_module_addrsym.c \
+		    dwfl_module_return_value_location.c \
+		    dwfl_module_register_names.c \
+		    dwfl_segment_report_module.c \
+		    link_map.c core-file.c open.c image-header.c \
+		    dwfl_frame.c frame_unwind.c dwfl_frame_pc.c \
+		    linux-pid-attach.c linux-core-attach.c dwfl_frame_regs.c \
+		    gzip.c
+
+if BZLIB
+libdwfl_a_SOURCES += bzip2.c
+endif
+if LZMA
+libdwfl_a_SOURCES += lzma.c
+endif
+
+libdwfl = $(libdw)
+libdw = ../libdw/libdw.so
+libelf = ../libelf/libelf.so
+libebl = ../libebl/libebl.a
+libeu = ../lib/libeu.a
+
+libdwfl_pic_a_SOURCES =
+am_libdwfl_pic_a_OBJECTS = $(libdwfl_a_SOURCES:.c=.os)
+
+noinst_HEADERS = libdwflP.h
+
+CLEANFILES += $(am_libdwfl_pic_a_OBJECTS)
diff --git a/third_party/elfutils/libdwfl/argp-std.c b/third_party/elfutils/libdwfl/argp-std.c
new file mode 100644
index 0000000..8ee9158
--- /dev/null
+++ b/third_party/elfutils/libdwfl/argp-std.c
@@ -0,0 +1,383 @@
+/* Standard argp argument parsers for tools using libdwfl.
+   Copyright (C) 2005-2010, 2012, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <argp.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <libintl.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/* gettext helper macros.  */
+#define _(Str) dgettext ("elfutils", Str)
+
+
+#define OPT_DEBUGINFO	0x100
+#define OPT_COREFILE	0x101
+
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("Input selection options:"), 0 },
+  { "executable", 'e', "FILE", 0, N_("Find addresses in FILE"), 0 },
+  { "core", OPT_COREFILE, "COREFILE", 0,
+    N_("Find addresses from signatures found in COREFILE"), 0 },
+  { "pid", 'p', "PID", 0,
+    N_("Find addresses in files mapped into process PID"), 0 },
+  { "linux-process-map", 'M', "FILE", 0,
+    N_("Find addresses in files mapped as read from FILE"
+       " in Linux /proc/PID/maps format"), 0 },
+  { "kernel", 'k', NULL, 0, N_("Find addresses in the running kernel"), 0 },
+  { "offline-kernel", 'K', "RELEASE", OPTION_ARG_OPTIONAL,
+    N_("Kernel with all modules"), 0 },
+  { "debuginfo-path", OPT_DEBUGINFO, "PATH", 0,
+    N_("Search path for separate debuginfo files"), 0 },
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+static char *debuginfo_path;
+
+static const Dwfl_Callbacks offline_callbacks =
+  {
+    .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
+    .debuginfo_path = &debuginfo_path,
+
+    .section_address = INTUSE(dwfl_offline_section_address),
+
+    /* We use this table for core files too.  */
+    .find_elf = INTUSE(dwfl_build_id_find_elf),
+  };
+
+static const Dwfl_Callbacks proc_callbacks =
+  {
+    .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
+    .debuginfo_path = &debuginfo_path,
+
+    .find_elf = INTUSE(dwfl_linux_proc_find_elf),
+  };
+
+static const Dwfl_Callbacks kernel_callbacks =
+  {
+    .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
+    .debuginfo_path = &debuginfo_path,
+
+    .find_elf = INTUSE(dwfl_linux_kernel_find_elf),
+    .section_address = INTUSE(dwfl_linux_kernel_module_section_address),
+  };
+
+/* Structure held at state->HOOK.  */
+struct parse_opt
+{
+  Dwfl *dwfl;
+  /* The -e|--executable parameter.  */
+  const char *e;
+  /* The --core parameter.  */
+  const char *core;
+};
+
+static inline void
+failure (Dwfl *dwfl, int errnum, const char *msg, struct argp_state *state)
+{
+  if (dwfl != NULL)
+    dwfl_end (dwfl);
+  if (errnum == -1)
+    argp_failure (state, EXIT_FAILURE, 0, "%s: %s",
+                  msg, INTUSE(dwfl_errmsg) (-1));
+  else
+    argp_failure (state, EXIT_FAILURE, errnum, "%s", msg);
+}
+
+static inline error_t
+fail (Dwfl *dwfl, int errnum, const char *msg, struct argp_state *state)
+{
+  failure (dwfl, errnum, msg, state);
+  return errnum == -1 ? EIO : errnum;
+}
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+  switch (key)
+    {
+    case ARGP_KEY_INIT:
+      {
+	assert (state->hook == NULL);
+	struct parse_opt *opt = calloc (1, sizeof (*opt));
+	if (opt == NULL)
+	  failure (NULL, DWFL_E_ERRNO, "calloc", state);
+	state->hook = opt;
+      }
+      break;
+
+    case OPT_DEBUGINFO:
+      debuginfo_path = arg;
+      break;
+
+    case 'e':
+      {
+	struct parse_opt *opt = state->hook;
+	Dwfl *dwfl = opt->dwfl;
+	if (dwfl == NULL)
+	  {
+	    dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+	    if (dwfl == NULL)
+	      return fail (dwfl, -1, arg, state);
+	    opt->dwfl = dwfl;
+
+	    /* Start at zero so if there is just one -e foo.so,
+	       the DSO is shown without address bias.  */
+	    dwfl->offline_next_address = 0;
+	  }
+	if (dwfl->callbacks != &offline_callbacks)
+	  {
+	  toomany:
+	    argp_error (state, "%s",
+			_("only one of -e, -p, -k, -K, or --core allowed"));
+	    return EINVAL;
+	  }
+	opt->e = arg;
+      }
+      break;
+
+    case 'p':
+      {
+	struct parse_opt *opt = state->hook;
+	if (opt->dwfl == NULL)
+	  {
+	    Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
+	    int result = INTUSE(dwfl_linux_proc_report) (dwfl, atoi (arg));
+	    if (result != 0)
+	      return fail (dwfl, result, arg, state);
+
+	    /* Non-fatal to not be able to attach to process, ignore error.  */
+	    INTUSE(dwfl_linux_proc_attach) (dwfl, atoi (arg), false);
+
+	    opt->dwfl = dwfl;
+	  }
+	else
+	  goto toomany;
+      }
+      break;
+
+    case 'M':
+      {
+	struct parse_opt *opt = state->hook;
+	if (opt->dwfl == NULL)
+	  {
+	    FILE *f = fopen (arg, "r");
+	    if (f == NULL)
+	      {
+		int code = errno;
+		argp_failure (state, EXIT_FAILURE, code,
+			      "cannot open '%s'", arg);
+		return code;
+	      }
+	    Dwfl *dwfl = INTUSE(dwfl_begin) (&proc_callbacks);
+	    int result = INTUSE(dwfl_linux_proc_maps_report) (dwfl, f);
+	    fclose (f);
+	    if (result != 0)
+	      return fail (dwfl, result, arg, state);
+	    opt->dwfl = dwfl;
+	  }
+	else
+	  goto toomany;
+      }
+      break;
+
+    case OPT_COREFILE:
+      {
+	struct parse_opt *opt = state->hook;
+	Dwfl *dwfl = opt->dwfl;
+	if (dwfl == NULL)
+	  opt->dwfl = dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+	/* Permit -e and --core together.  */
+	else if (dwfl->callbacks != &offline_callbacks)
+	  goto toomany;
+	opt->core = arg;
+      }
+      break;
+
+    case 'k':
+      {
+	struct parse_opt *opt = state->hook;
+	if (opt->dwfl == NULL)
+	  {
+	    Dwfl *dwfl = INTUSE(dwfl_begin) (&kernel_callbacks);
+	    int result = INTUSE(dwfl_linux_kernel_report_kernel) (dwfl);
+	    if (result != 0)
+	      return fail (dwfl, result, _("cannot load kernel symbols"), state);
+	    result = INTUSE(dwfl_linux_kernel_report_modules) (dwfl);
+	    if (result != 0)
+	      /* Non-fatal to have no modules since we do have the kernel.  */
+	      argp_failure (state, 0, result, _("cannot find kernel modules"));
+	    opt->dwfl = dwfl;
+	  }
+	else
+	  goto toomany;
+      }
+      break;
+
+    case 'K':
+      {
+	struct parse_opt *opt = state->hook;
+	if (opt->dwfl == NULL)
+	  {
+	    Dwfl *dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+	    int result = INTUSE(dwfl_linux_kernel_report_offline) (dwfl, arg,
+								   NULL);
+	    if (result != 0)
+	      return fail (dwfl, result, _("cannot find kernel or modules"), state);
+	    opt->dwfl = dwfl;
+	  }
+	else
+	  goto toomany;
+      }
+      break;
+
+    case ARGP_KEY_SUCCESS:
+      {
+	struct parse_opt *opt = state->hook;
+	Dwfl *dwfl = opt->dwfl;
+
+	if (dwfl == NULL)
+	  {
+	    /* Default if no -e, -p, or -k, is "-e a.out".  */
+	    arg = "a.out";
+	    dwfl = INTUSE(dwfl_begin) (&offline_callbacks);
+	    if (INTUSE(dwfl_report_offline) (dwfl, "", arg, -1) == NULL)
+	      return fail (dwfl, -1, arg, state);
+	    opt->dwfl = dwfl;
+	  }
+
+	if (opt->core)
+	  {
+	    int fd = open (opt->core, O_RDONLY);
+	    if (fd < 0)
+	      {
+		int code = errno;
+		argp_failure (state, EXIT_FAILURE, code,
+			      "cannot open '%s'", opt->core);
+		return code;
+	      }
+
+	    Elf *core;
+	    Dwfl_Error error = __libdw_open_file (&fd, &core, true, false);
+	    if (error != DWFL_E_NOERROR)
+	      {
+		argp_failure (state, EXIT_FAILURE, 0,
+			      _("cannot read ELF core file: %s"),
+			      INTUSE(dwfl_errmsg) (error));
+		return error == DWFL_E_ERRNO ? errno : EIO;
+	      }
+
+	    int result = INTUSE(dwfl_core_file_report) (dwfl, core, opt->e);
+	    if (result < 0)
+	      {
+		elf_end (core);
+		close (fd);
+		return fail (dwfl, result, opt->core, state);
+	      }
+
+	    /* Non-fatal to not be able to attach to core, ignore error.  */
+	    INTUSE(dwfl_core_file_attach) (dwfl, core);
+
+	    /* Store core Elf and fd in Dwfl to expose with dwfl_end.  */
+	    if (dwfl->user_core == NULL)
+	      {
+		dwfl->user_core = calloc (1, sizeof (struct Dwfl_User_Core));
+		if (dwfl->user_core == NULL)
+		  {
+		    argp_failure (state, EXIT_FAILURE, 0,
+				  _("Not enough memory"));
+		    return ENOMEM;
+		  }
+	      }
+	    dwfl->user_core->core = core;
+	    dwfl->user_core->fd = fd;
+
+	    if (result == 0)
+	      {
+		argp_failure (state, EXIT_FAILURE, 0,
+			      _("No modules recognized in core file"));
+		return ENOENT;
+	      }
+	  }
+	else if (opt->e)
+	  {
+	    if (INTUSE(dwfl_report_offline) (dwfl, "", opt->e, -1) == NULL)
+	      return fail (dwfl, -1, opt->e, state);
+	  }
+
+	/* One of the three flavors has done dwfl_begin and some reporting
+	   if we got here.  Tie up the Dwfl and return it to the caller of
+	   argp_parse.  */
+
+	int result = INTUSE(dwfl_report_end) (dwfl, NULL, NULL);
+	assert (result == 0);
+
+	/* Update the input all along, so a parent parser can see it.
+	   As we free OPT the update below will be no longer active.  */
+	*(Dwfl **) state->input = dwfl;
+	free (opt);
+	state->hook = NULL;
+      }
+      break;
+
+    case ARGP_KEY_ERROR:
+      {
+	struct parse_opt *opt = state->hook;
+	dwfl_end (opt->dwfl);
+	free (opt);
+	state->hook = NULL;
+      }
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+
+  /* Update the input all along, so a parent parser can see it.  */
+  struct parse_opt *opt = state->hook;
+  if (opt)
+    *(Dwfl **) state->input = opt->dwfl;
+
+  return 0;
+}
+
+static const struct argp libdwfl_argp =
+  { .options = options, .parser = parse_opt };
+
+const struct argp *
+dwfl_standard_argp (void)
+{
+  return &libdwfl_argp;
+}
diff --git a/third_party/elfutils/libdwfl/bzip2.c b/third_party/elfutils/libdwfl/bzip2.c
new file mode 100644
index 0000000..8ad4ee5
--- /dev/null
+++ b/third_party/elfutils/libdwfl/bzip2.c
@@ -0,0 +1,4 @@
+/* bzlib is almost just like zlib.  */
+
+#define BZLIB
+#include "gzip.c"
diff --git a/third_party/elfutils/libdwfl/core-file.c b/third_party/elfutils/libdwfl/core-file.c
new file mode 100644
index 0000000..84cb89a
--- /dev/null
+++ b/third_party/elfutils/libdwfl/core-file.c
@@ -0,0 +1,624 @@
+/* Core file handling.
+   Copyright (C) 2008-2010, 2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include "../libelf/libelfP.h"	/* For NOTE_ALIGN.  */
+#undef	_
+#include "libdwflP.h"
+#include <gelf.h>
+
+#include <unistd.h>
+#include <endian.h>
+#include <byteswap.h>
+#include "system.h"
+
+
+/* On failure return, we update *NEXT to point back at OFFSET.  */
+static inline Elf *
+do_fail (int error, off_t *next, off_t offset)
+{
+    if (next != NULL)
+      *next = offset;
+    //__libelf_seterrno (error);
+    __libdwfl_seterrno (DWFL_E (LIBELF, error));
+    return NULL;
+}
+
+#define fail(error) do_fail (error, next, offset)
+
+/* This is a prototype of what a new libelf interface might be.
+   This implementation is pessimal for non-mmap cases and should
+   be replaced by more diddling inside libelf internals.  */
+static Elf *
+elf_begin_rand (Elf *parent, off_t offset, off_t size, off_t *next)
+{
+  if (parent == NULL)
+    return NULL;
+
+  off_t min = (parent->kind == ELF_K_ELF ?
+		(parent->class == ELFCLASS32
+		 ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr))
+		: parent->kind == ELF_K_AR ? SARMAG
+		: 0);
+
+  if (unlikely (offset < min)
+      || unlikely (offset >= (off_t) parent->maximum_size))
+    return fail (ELF_E_RANGE);
+
+  /* For an archive, fetch just the size field
+     from the archive header to override SIZE.  */
+  if (parent->kind == ELF_K_AR)
+    {
+      struct ar_hdr h = { .ar_size = "" };
+
+      if (unlikely (parent->maximum_size - offset < sizeof h))
+	return fail (ELF_E_RANGE);
+
+      if (parent->map_address != NULL)
+	memcpy (h.ar_size, parent->map_address + parent->start_offset + offset,
+		sizeof h.ar_size);
+      else if (unlikely (pread_retry (parent->fildes,
+				      h.ar_size, sizeof (h.ar_size),
+				      parent->start_offset + offset
+				      + offsetof (struct ar_hdr, ar_size))
+			 != sizeof (h.ar_size)))
+	return fail (ELF_E_READ_ERROR);
+
+      offset += sizeof h;
+
+      char *endp;
+      size = strtoll (h.ar_size, &endp, 10);
+      if (unlikely (endp == h.ar_size)
+	  || unlikely ((off_t) parent->maximum_size - offset < size))
+	return fail (ELF_E_INVALID_ARCHIVE);
+    }
+
+  if (unlikely ((off_t) parent->maximum_size - offset < size))
+    return fail (ELF_E_RANGE);
+
+  /* Even if we fail at this point, update *NEXT to point past the file.  */
+  if (next != NULL)
+    *next = offset + size;
+
+  if (unlikely (offset == 0)
+      && unlikely (size == (off_t) parent->maximum_size))
+    return elf_clone (parent, parent->cmd);
+
+  /* Note the image is guaranteed live only as long as PARENT
+     lives.  Using elf_memory is quite suboptimal if the whole
+     file is not mmap'd.  We really should have something like
+     a generalization of the archive support.  */
+  Elf_Data *data = elf_getdata_rawchunk (parent, offset, size, ELF_T_BYTE);
+  if (data == NULL)
+    return NULL;
+  assert ((off_t) data->d_size == size);
+  return elf_memory (data->d_buf, size);
+}
+
+
+int
+dwfl_report_core_segments (Dwfl *dwfl, Elf *elf, size_t phnum, GElf_Phdr *notes)
+{
+  if (unlikely (dwfl == NULL))
+    return -1;
+
+  int result = 0;
+
+  if (notes != NULL)
+    notes->p_type = PT_NULL;
+
+  for (size_t ndx = 0; result >= 0 && ndx < phnum; ++ndx)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (elf, ndx, &phdr_mem);
+      if (unlikely (phdr == NULL))
+	{
+	  __libdwfl_seterrno (DWFL_E_LIBELF);
+	  return -1;
+	}
+      switch (phdr->p_type)
+	{
+	case PT_LOAD:
+	  result = dwfl_report_segment (dwfl, ndx, phdr, 0, NULL);
+	  break;
+
+	case PT_NOTE:
+	  if (notes != NULL)
+	    {
+	      *notes = *phdr;
+	      notes = NULL;
+	    }
+	  break;
+	}
+    }
+
+  return result;
+}
+
+/* Never read more than this much without mmap.  */
+#define MAX_EAGER_COST	8192
+
+/* Dwfl_Module_Callback passed to and called by dwfl_segment_report_module
+   to read in a segment as ELF image directly if possible or indicate an
+   attempt must be made to read in the while segment right now.  */
+static bool
+core_file_read_eagerly (Dwfl_Module *mod,
+			void **userdata __attribute__ ((unused)),
+			const char *name __attribute__ ((unused)),
+			Dwarf_Addr start __attribute__ ((unused)),
+			void **buffer, size_t *buffer_available,
+			GElf_Off cost, GElf_Off worthwhile,
+			GElf_Off whole,
+			GElf_Off contiguous __attribute__ ((unused)),
+			void *arg, Elf **elfp)
+{
+  Elf *core = arg;
+
+  /* The available buffer is often the whole segment when the core file
+     was mmap'd if used together with the dwfl_elf_phdr_memory_callback.
+     Which means that if it is complete we can just construct the whole
+     ELF image right now without having to read in anything more.  */
+  if (whole <= *buffer_available)
+    {
+      /* All there ever was, we already have on hand.  */
+
+      if (core->map_address == NULL)
+	{
+	  /* We already malloc'd the buffer.  */
+	  *elfp = elf_memory (*buffer, whole);
+	  if (unlikely (*elfp == NULL))
+	    return false;
+
+	  (*elfp)->flags |= ELF_F_MALLOCED;
+	  *buffer = NULL;
+	  *buffer_available = 0;
+	  return true;
+	}
+
+      /* We can use the image inside the core file directly.  */
+      *elfp = elf_begin_rand (core, *buffer - core->map_address, whole, NULL);
+      *buffer = NULL;
+      *buffer_available = 0;
+      return *elfp != NULL;
+    }
+
+  /* We don't have the whole file.  Which either means the core file
+     wasn't mmap'd, but needs to still be read in, or that the segment
+     is truncated.  Figure out if this is better than nothing.  */
+
+  if (worthwhile == 0)
+    /* Caller doesn't think so.  */
+    return false;
+
+  /*
+    XXX would like to fall back to partial file via memory
+    when build id find_elf fails
+    also, link_map name may give file name from disk better than partial here
+    requires find_elf hook re-doing the magic to fall back if no file found
+  */
+
+  if (whole > MAX_EAGER_COST && mod->build_id_len > 0)
+    /* We can't cheaply read the whole file here, so we'd
+       be using a partial file.  But there is a build ID that could
+       help us find the whole file, which might be more useful than
+       what we have.  We'll just rely on that.  */
+    return false;
+
+  /* The file is either small (most likely the vdso) or big and incomplete,
+     but we don't have a build-id.  */
+
+  if (core->map_address != NULL)
+    /* It's cheap to get, so get it.  */
+    return true;
+
+  /* Only use it if there isn't too much to be read.  */
+  return cost <= MAX_EAGER_COST;
+}
+
+static inline void
+update_end (GElf_Phdr *pphdr, const GElf_Off align,
+            GElf_Off *pend, GElf_Addr *pend_vaddr)
+{
+  *pend = (pphdr->p_offset + pphdr->p_filesz + align - 1) & -align;
+  *pend_vaddr = (pphdr->p_vaddr + pphdr->p_memsz + align - 1) & -align;
+}
+
+/* Use following contiguous segments to get towards SIZE.  */
+static inline bool
+do_more (size_t size, GElf_Phdr *pphdr, const GElf_Off align,
+         Elf *elf, GElf_Off start, int *pndx,
+         GElf_Off *pend, GElf_Addr *pend_vaddr)
+{
+  while (*pend <= start || *pend - start < size)
+    {
+      if (pphdr->p_filesz < pphdr->p_memsz)
+	/* This segment is truncated, so no following one helps us.  */
+	return false;
+
+      if (unlikely (gelf_getphdr (elf, (*pndx)++, pphdr) == NULL))
+	return false;
+
+      if (pphdr->p_type == PT_LOAD)
+	{
+	  if (pphdr->p_offset > *pend
+	      || pphdr->p_vaddr > *pend_vaddr)
+	    /* It's discontiguous!  */
+	    return false;
+
+	  update_end (pphdr, align, pend, pend_vaddr);
+	}
+    }
+  return true;
+}
+
+#define more(size) do_more (size, &phdr, align, elf, start, &ndx, &end, &end_vaddr)
+
+bool
+dwfl_elf_phdr_memory_callback (Dwfl *dwfl, int ndx,
+			       void **buffer, size_t *buffer_available,
+			       GElf_Addr vaddr,
+			       size_t minread,
+			       void *arg)
+{
+  Elf *elf = arg;
+
+  if (ndx == -1)
+    {
+      /* Called for cleanup.  */
+      if (elf->map_address == NULL)
+	free (*buffer);
+      *buffer = NULL;
+      *buffer_available = 0;
+      return false;
+    }
+
+  const GElf_Off align = dwfl->segment_align ?: 1;
+  GElf_Phdr phdr;
+
+  do
+    if (unlikely (gelf_getphdr (elf, ndx++, &phdr) == NULL))
+      return false;
+  while (phdr.p_type != PT_LOAD
+	 || ((phdr.p_vaddr + phdr.p_memsz + align - 1) & -align) <= vaddr);
+
+  GElf_Off start = vaddr - phdr.p_vaddr + phdr.p_offset;
+  GElf_Off end;
+  GElf_Addr end_vaddr;
+
+  update_end (&phdr, align, &end, &end_vaddr);
+
+  /* We need at least this much.  */
+  if (! more (minread))
+    return false;
+
+  /* See how much more we can get of what the caller wants.  */
+  (void) more (*buffer_available);
+
+  /* If it's already on hand anyway, use as much as there is.  */
+  if (elf->map_address != NULL)
+    (void) more (elf->maximum_size - start);
+
+  /* Make sure we don't look past the end of the actual file,
+     even if the headers tell us to.  */
+  if (unlikely (end > elf->maximum_size))
+    end = elf->maximum_size;
+
+  /* If the file is too small, there is nothing at all to get.  */
+  if (unlikely (start >= end))
+    return false;
+
+  if (elf->map_address != NULL)
+    {
+      void *contents = elf->map_address + elf->start_offset + start;
+      size_t size = end - start;
+
+      if (minread == 0)		/* String mode.  */
+	{
+	  const void *eos = memchr (contents, '\0', size);
+	  if (unlikely (eos == NULL) || unlikely (eos == contents))
+	    return false;
+	  size = eos + 1 - contents;
+	}
+
+      if (*buffer == NULL)
+	{
+	  *buffer = contents;
+	  *buffer_available = size;
+	}
+      else
+	{
+	  *buffer_available = MIN (size, *buffer_available);
+	  memcpy (*buffer, contents, *buffer_available);
+	}
+    }
+  else
+    {
+      void *into = *buffer;
+      if (*buffer == NULL)
+	{
+	  *buffer_available = MIN (minread ?: 512,
+				   MAX (4096, MIN (end - start,
+						   *buffer_available)));
+	  into = malloc (*buffer_available);
+	  if (unlikely (into == NULL))
+	    {
+	      __libdwfl_seterrno (DWFL_E_NOMEM);
+	      return false;
+	    }
+	}
+
+      ssize_t nread = pread_retry (elf->fildes, into, *buffer_available, start);
+      if (nread < (ssize_t) minread)
+	{
+	  if (into != *buffer)
+	    free (into);
+	  if (nread < 0)
+	    __libdwfl_seterrno (DWFL_E_ERRNO);
+	  return false;
+	}
+
+      if (minread == 0)		/* String mode.  */
+	{
+	  const void *eos = memchr (into, '\0', nread);
+	  if (unlikely (eos == NULL) || unlikely (eos == into))
+	    {
+	      if (*buffer == NULL)
+		free (into);
+	      return false;
+	    }
+	  nread = eos + 1 - into;
+	}
+
+      if (*buffer == NULL)
+	*buffer = into;
+      *buffer_available = nread;
+    }
+
+  return true;
+}
+
+/* Free the contents of R_DEBUG_INFO without the R_DEBUG_INFO memory itself.  */
+
+static void
+clear_r_debug_info (struct r_debug_info *r_debug_info)
+{
+  while (r_debug_info->module != NULL)
+    {
+      struct r_debug_info_module *module = r_debug_info->module;
+      r_debug_info->module = module->next;
+      elf_end (module->elf);
+      if (module->fd != -1)
+	close (module->fd);
+      free (module);
+    }
+}
+
+bool
+internal_function
+__libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
+{
+  size_t phnum;
+  if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
+    return false;
+  for (size_t i = 0; i < phnum; ++i)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
+      if (unlikely (phdr == NULL))
+	return false;
+      if (phdr->p_type == PT_DYNAMIC)
+	{
+	  *vaddrp = phdr->p_vaddr;
+	  return true;
+	}
+    }
+  return false;
+}
+
+int
+dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable)
+{
+  size_t phnum;
+  if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
+    {
+      __libdwfl_seterrno (DWFL_E_LIBELF);
+      return -1;
+    }
+
+  if (dwfl->user_core != NULL)
+    free (dwfl->user_core->executable_for_core);
+  if (executable == NULL)
+    {
+      if (dwfl->user_core != NULL)
+	dwfl->user_core->executable_for_core = NULL;
+    }
+  else
+    {
+      if (dwfl->user_core == NULL)
+	{
+	  dwfl->user_core = calloc (1, sizeof (struct Dwfl_User_Core));
+	  if (dwfl->user_core == NULL)
+	    {
+	      __libdwfl_seterrno (DWFL_E_NOMEM);
+	      return -1;
+	    }
+	  dwfl->user_core->fd = -1;
+	}
+      dwfl->user_core->executable_for_core = strdup (executable);
+      if (dwfl->user_core->executable_for_core == NULL)
+	{
+	  __libdwfl_seterrno (DWFL_E_NOMEM);
+	  return -1;
+	}
+    }
+
+  /* First report each PT_LOAD segment.  */
+  GElf_Phdr notes_phdr;
+  int ndx = dwfl_report_core_segments (dwfl, elf, phnum, &notes_phdr);
+  if (unlikely (ndx <= 0))
+    return ndx;
+
+  /* Next, we should follow the chain from DT_DEBUG.  */
+
+  const void *auxv = NULL;
+  const void *note_file = NULL;
+  size_t auxv_size = 0;
+  size_t note_file_size = 0;
+  if (likely (notes_phdr.p_type == PT_NOTE))
+    {
+      /* PT_NOTE -> NT_AUXV -> AT_PHDR -> PT_DYNAMIC -> DT_DEBUG */
+
+      Elf_Data *notes = elf_getdata_rawchunk (elf,
+					      notes_phdr.p_offset,
+					      notes_phdr.p_filesz,
+					      ELF_T_NHDR);
+      if (likely (notes != NULL))
+	{
+	  size_t pos = 0;
+	  GElf_Nhdr nhdr;
+	  size_t name_pos;
+	  size_t desc_pos;
+	  while ((pos = gelf_getnote (notes, pos, &nhdr,
+				      &name_pos, &desc_pos)) > 0)
+	    if (nhdr.n_namesz == sizeof "CORE"
+		&& !memcmp (notes->d_buf + name_pos, "CORE", sizeof "CORE"))
+	      {
+		if (nhdr.n_type == NT_AUXV)
+		  {
+		    auxv = notes->d_buf + desc_pos;
+		    auxv_size = nhdr.n_descsz;
+		  }
+		if (nhdr.n_type == NT_FILE)
+		  {
+		    note_file = notes->d_buf + desc_pos;
+		    note_file_size = nhdr.n_descsz;
+		  }
+	      }
+	}
+    }
+
+  /* Now we have NT_AUXV contents.  From here on this processing could be
+     used for a live process with auxv read from /proc.  */
+
+  struct r_debug_info r_debug_info;
+  memset (&r_debug_info, 0, sizeof r_debug_info);
+  int retval = dwfl_link_map_report (dwfl, auxv, auxv_size,
+				     dwfl_elf_phdr_memory_callback, elf,
+				     &r_debug_info);
+  int listed = retval > 0 ? retval : 0;
+
+  /* Now sniff segment contents for modules hinted by information gathered
+     from DT_DEBUG.  */
+
+  ndx = 0;
+  do
+    {
+      int seg = dwfl_segment_report_module (dwfl, ndx, NULL,
+					    &dwfl_elf_phdr_memory_callback, elf,
+					    core_file_read_eagerly, elf,
+					    note_file, note_file_size,
+					    &r_debug_info);
+      if (unlikely (seg < 0))
+	{
+	  clear_r_debug_info (&r_debug_info);
+	  return seg;
+	}
+      if (seg > ndx)
+	{
+	  ndx = seg;
+	  ++listed;
+	}
+      else
+	++ndx;
+    }
+  while (ndx < (int) phnum);
+
+  /* Now report the modules from dwfl_link_map_report which were not filtered
+     out by dwfl_segment_report_module.  */
+
+  Dwfl_Module **lastmodp = &dwfl->modulelist;
+  while (*lastmodp != NULL)
+    lastmodp = &(*lastmodp)->next;
+  for (struct r_debug_info_module *module = r_debug_info.module;
+       module != NULL; module = module->next)
+    {
+      if (module->elf == NULL)
+	continue;
+      GElf_Addr file_dynamic_vaddr;
+      if (! __libdwfl_dynamic_vaddr_get (module->elf, &file_dynamic_vaddr))
+	continue;
+      Dwfl_Module *mod;
+      mod = __libdwfl_report_elf (dwfl, basename (module->name), module->name,
+				  module->fd, module->elf,
+				  module->l_ld - file_dynamic_vaddr,
+				  true, true);
+      if (mod == NULL)
+	continue;
+      ++listed;
+      module->elf = NULL;
+      module->fd = -1;
+      /* Move this module to the end of the list, so that we end
+	 up with a list in the same order as the link_map chain.  */
+      if (mod->next != NULL)
+	{
+	  if (*lastmodp != mod)
+	    {
+	      lastmodp = &dwfl->modulelist;
+	      while (*lastmodp != mod)
+		lastmodp = &(*lastmodp)->next;
+	    }
+	  *lastmodp = mod->next;
+	  mod->next = NULL;
+	  while (*lastmodp != NULL)
+	    lastmodp = &(*lastmodp)->next;
+	  *lastmodp = mod;
+	}
+      lastmodp = &mod->next;
+    }
+
+  clear_r_debug_info (&r_debug_info);
+
+  /* We return the number of modules we found if we found any.
+     If we found none, we return -1 instead of 0 if there was an
+     error rather than just nothing found.  */
+  return listed > 0 ? listed : retval;
+}
+INTDEF (dwfl_core_file_report)
+NEW_VERSION (dwfl_core_file_report, ELFUTILS_0.158)
+
+#ifdef SYMBOL_VERSIONING
+int _compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf);
+COMPAT_VERSION_NEWPROTO (dwfl_core_file_report, ELFUTILS_0.146,
+			 without_executable)
+
+int
+_compat_without_executable_dwfl_core_file_report (Dwfl *dwfl, Elf *elf)
+{
+  return dwfl_core_file_report (dwfl, elf, NULL);
+}
+#endif
diff --git a/third_party/elfutils/libdwfl/cu.c b/third_party/elfutils/libdwfl/cu.c
new file mode 100644
index 0000000..7aa23b5
--- /dev/null
+++ b/third_party/elfutils/libdwfl/cu.c
@@ -0,0 +1,322 @@
+/* Keeping track of DWARF compilation units in libdwfl.
+   Copyright (C) 2005-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+#include "../libdw/memory-access.h"
+#include <search.h>
+
+
+static inline Dwarf_Arange *
+dwar (Dwfl_Module *mod, unsigned int idx)
+{
+  return &mod->dw->aranges->info[mod->aranges[idx].arange];
+}
+
+
+static Dwfl_Error
+addrarange (Dwfl_Module *mod, Dwarf_Addr addr, struct dwfl_arange **arange)
+{
+  if (mod->aranges == NULL)
+    {
+      struct dwfl_arange *aranges = NULL;
+      Dwarf_Aranges *dwaranges = NULL;
+      size_t naranges;
+      if (INTUSE(dwarf_getaranges) (mod->dw, &dwaranges, &naranges) != 0)
+	return DWFL_E_LIBDW;
+
+      /* If the module has no aranges (when no code is included) we
+	 allocate nothing.  */
+      if (naranges != 0)
+	{
+	  aranges = malloc (naranges * sizeof *aranges);
+	  if (unlikely (aranges == NULL))
+	    return DWFL_E_NOMEM;
+
+	  /* libdw has sorted its list by address, which is how we want it.
+	     But the sorted list is full of not-quite-contiguous runs pointing
+	     to the same CU.  We don't care about the little gaps inside the
+	     module, we'll consider them part of the surrounding CU anyway.
+	     Collect our own array with just one record for each run of ranges
+	     pointing to one CU.  */
+
+	  naranges = 0;
+	  Dwarf_Off lastcu = 0;
+	  for (size_t i = 0; i < dwaranges->naranges; ++i)
+	    if (i == 0 || dwaranges->info[i].offset != lastcu)
+	      {
+		aranges[naranges].arange = i;
+		aranges[naranges].cu = NULL;
+		++naranges;
+		lastcu = dwaranges->info[i].offset;
+	      }
+	}
+
+      /* Store the final array, which is probably much smaller than before.  */
+      mod->naranges = naranges;
+      mod->aranges = (realloc (aranges, naranges * sizeof aranges[0])
+		      ?: aranges);
+      mod->lazycu += naranges;
+    }
+
+  /* The address must be inside the module to begin with.  */
+  addr = dwfl_deadjust_dwarf_addr (mod, addr);
+
+  /* The ranges are sorted by address, so we can use binary search.  */
+  size_t l = 0, u = mod->naranges;
+  while (l < u)
+    {
+      size_t idx = (l + u) / 2;
+      Dwarf_Addr start = dwar (mod, idx)->addr;
+      if (addr < start)
+	{
+	  u = idx;
+	  continue;
+	}
+      else if (addr > start)
+	{
+	  if (idx + 1 < mod->naranges)
+	    {
+	      if (addr >= dwar (mod, idx + 1)->addr)
+		{
+		  l = idx + 1;
+		  continue;
+		}
+	    }
+	  else
+	    {
+	      /* It might be in the last range.  */
+	      const Dwarf_Arange *last
+		= &mod->dw->aranges->info[mod->dw->aranges->naranges - 1];
+	      if (addr > last->addr + last->length)
+		break;
+	    }
+	}
+
+      *arange = &mod->aranges[idx];
+      return DWFL_E_NOERROR;
+    }
+
+  return DWFL_E_ADDR_OUTOFRANGE;
+}
+
+
+static void
+nofree (void *arg)
+{
+  struct dwfl_cu *cu = arg;
+  if (cu == (void *) -1l)
+    return;
+
+  assert (cu->mod->lazycu == 0);
+}
+
+/* One reason fewer to keep the lazy lookup table for CUs.  */
+static inline void
+less_lazy (Dwfl_Module *mod)
+{
+  if (--mod->lazycu > 0)
+    return;
+
+  /* We know about all the CUs now, we don't need this table.  */
+  tdestroy (mod->lazy_cu_root, nofree);
+  mod->lazy_cu_root = NULL;
+}
+
+static inline Dwarf_Off
+cudie_offset (const struct dwfl_cu *cu)
+{
+  /* These are real CUs, so there never is a type_sig8.  Note
+     initialization of dwkey.start and offset_size in intern_cu ()
+     to see why this calculates the same value for both key and
+     die.cu search items.  */
+  return DIE_OFFSET_FROM_CU_OFFSET (cu->die.cu->start, cu->die.cu->offset_size,
+				    0);
+}
+
+static int
+compare_cukey (const void *a, const void *b)
+{
+  Dwarf_Off a_off = cudie_offset (a);
+  Dwarf_Off b_off = cudie_offset (b);
+  return (a_off < b_off) ? -1 : ((a_off > b_off) ? 1 : 0);
+}
+
+/* Intern the CU if necessary.  */
+static Dwfl_Error
+intern_cu (Dwfl_Module *mod, Dwarf_Off cuoff, struct dwfl_cu **result)
+{
+  if (unlikely (cuoff + 4 >= mod->dw->sectiondata[IDX_debug_info]->d_size))
+    {
+      if (likely (mod->lazycu == 1))
+	{
+	  /* This is the EOF marker.  Now we have interned all the CUs.
+	     One increment in MOD->lazycu counts not having hit EOF yet.  */
+	  *result = (void *) -1;
+	  less_lazy (mod);
+	  return DWFL_E_NOERROR;
+	}
+      else
+	{
+	  /* Unexpected EOF, most likely a bogus aranges.  */
+	  return (DWFL_E (LIBDW, DWARF_E_INVALID_DWARF));
+	}
+    }
+
+  /* Make sure the cuoff points to a real DIE.  */
+  Dwarf_Die cudie;
+  Dwarf_Die *die = INTUSE(dwarf_offdie) (mod->dw, cuoff, &cudie);
+  if (die == NULL)
+    return DWFL_E_LIBDW;
+
+  struct Dwarf_CU dwkey;
+  struct dwfl_cu key;
+  key.die.cu = &dwkey;
+  dwkey.offset_size = 0;
+  dwkey.start = cuoff - (3 * 0 - 4 + 3);
+  struct dwfl_cu **found = tsearch (&key, &mod->lazy_cu_root, &compare_cukey);
+  if (unlikely (found == NULL))
+    return DWFL_E_NOMEM;
+
+  if (*found == &key || *found == NULL)
+    {
+      /* This is a new entry, meaning we haven't looked at this CU.  */
+
+      *found = NULL;
+
+      struct dwfl_cu *cu = malloc (sizeof *cu);
+      if (unlikely (cu == NULL))
+	return DWFL_E_NOMEM;
+
+      cu->mod = mod;
+      cu->next = NULL;
+      cu->lines = NULL;
+      cu->die = cudie;
+
+      struct dwfl_cu **newvec = realloc (mod->cu, ((mod->ncu + 1)
+						   * sizeof (mod->cu[0])));
+      if (newvec == NULL)
+	{
+	  free (cu);
+	  return DWFL_E_NOMEM;
+	}
+      mod->cu = newvec;
+
+      mod->cu[mod->ncu++] = cu;
+      if (cu->die.cu->start == 0)
+	mod->first_cu = cu;
+
+      *found = cu;
+    }
+
+  *result = *found;
+  return DWFL_E_NOERROR;
+}
+
+
+/* Traverse all the CUs in the module.  */
+
+Dwfl_Error
+internal_function
+__libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu,
+		  struct dwfl_cu **cu)
+{
+  Dwarf_Off cuoff;
+  struct dwfl_cu **nextp;
+
+  if (lastcu == NULL)
+    {
+      /* Start the traversal.  */
+      cuoff = 0;
+      nextp = &mod->first_cu;
+    }
+  else
+    {
+      /* Continue following LASTCU.  */
+      cuoff = lastcu->die.cu->end;
+      nextp = &lastcu->next;
+    }
+
+  if (*nextp == NULL)
+    {
+      size_t cuhdrsz;
+      Dwarf_Off nextoff;
+      int end = INTUSE(dwarf_nextcu) (mod->dw, cuoff, &nextoff, &cuhdrsz,
+				      NULL, NULL, NULL);
+      if (end < 0)
+	return DWFL_E_LIBDW;
+      if (end > 0)
+	{
+	  *cu = NULL;
+	  return DWFL_E_NOERROR;
+	}
+
+      Dwfl_Error result = intern_cu (mod, cuoff + cuhdrsz, nextp);
+      if (result != DWFL_E_NOERROR)
+	return result;
+
+      if (*nextp != (void *) -1
+	  && (*nextp)->next == NULL && nextoff == (Dwarf_Off) -1l)
+	(*nextp)->next = (void *) -1l;
+    }
+
+  *cu = *nextp == (void *) -1l ? NULL : *nextp;
+  return DWFL_E_NOERROR;
+}
+
+
+/* Intern the CU arange points to, if necessary.  */
+
+static Dwfl_Error
+arangecu (Dwfl_Module *mod, struct dwfl_arange *arange, struct dwfl_cu **cu)
+{
+  if (arange->cu == NULL)
+    {
+      const Dwarf_Arange *dwarange = &mod->dw->aranges->info[arange->arange];
+      Dwfl_Error result = intern_cu (mod, dwarange->offset, &arange->cu);
+      if (result != DWFL_E_NOERROR)
+	return result;
+      assert (arange->cu != NULL && arange->cu != (void *) -1l);
+      less_lazy (mod);		/* Each arange with null ->cu counts once.  */
+    }
+
+  *cu = arange->cu;
+  return DWFL_E_NOERROR;
+}
+
+Dwfl_Error
+internal_function
+__libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr, struct dwfl_cu **cu)
+{
+  struct dwfl_arange *arange;
+  return addrarange (mod, addr, &arange) ?: arangecu (mod, arange, cu);
+}
diff --git a/third_party/elfutils/libdwfl/derelocate.c b/third_party/elfutils/libdwfl/derelocate.c
new file mode 100644
index 0000000..2f80b20
--- /dev/null
+++ b/third_party/elfutils/libdwfl/derelocate.c
@@ -0,0 +1,434 @@
+/* Recover relocatibility for addresses computed from debug information.
+   Copyright (C) 2005-2010, 2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+struct dwfl_relocation
+{
+  size_t count;
+  struct
+  {
+    Elf_Scn *scn;
+    Elf_Scn *relocs;
+    const char *name;
+    GElf_Addr start, end;
+  } refs[0];
+};
+
+
+struct secref
+{
+  struct secref *next;
+  Elf_Scn *scn;
+  Elf_Scn *relocs;
+  const char *name;
+  GElf_Addr start, end;
+};
+
+static int
+compare_secrefs (const void *a, const void *b)
+{
+  struct secref *const *p1 = a;
+  struct secref *const *p2 = b;
+
+  /* No signed difference calculation is correct here, since the
+     terms are unsigned and could be more than INT64_MAX apart.  */
+  if ((*p1)->start < (*p2)->start)
+    return -1;
+  if ((*p1)->start > (*p2)->start)
+    return 1;
+
+  if ((*p1)->end < (*p2)->end)
+    return -1;
+  if ((*p1)->end > (*p2)->end)
+    return 1;
+
+  /* Same start/end, then just compare which section came first.  */
+  return elf_ndxscn ((*p1)->scn) - elf_ndxscn ((*p2)->scn);
+}
+
+static int
+cache_sections (Dwfl_Module *mod)
+{
+  if (likely (mod->reloc_info != NULL))
+    return mod->reloc_info->count;
+
+  struct secref *refs = NULL;
+  size_t nrefs = 0;
+
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (mod->main.elf, &shstrndx) < 0))
+    {
+    elf_error:
+      __libdwfl_seterrno (DWFL_E_LIBELF);
+      nrefs = -1;
+      goto free_refs;
+    }
+
+  bool check_reloc_sections = false;
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	goto elf_error;
+
+      if ((shdr->sh_flags & SHF_ALLOC) && shdr->sh_addr == 0
+	  && mod->e_type == ET_REL)
+	{
+	  /* This section might not yet have been looked at.  */
+	  if (__libdwfl_relocate_value (mod, mod->main.elf, &shstrndx,
+					elf_ndxscn (scn),
+					&shdr->sh_addr) != DWFL_E_NOERROR)
+	    continue;
+	  shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (unlikely (shdr == NULL))
+	    goto elf_error;
+	}
+
+      if (shdr->sh_flags & SHF_ALLOC)
+	{
+	  const char *name = elf_strptr (mod->main.elf, shstrndx,
+					 shdr->sh_name);
+	  if (unlikely (name == NULL))
+	    goto elf_error;
+
+	  struct secref *newref = malloc (sizeof *newref);
+	  if (unlikely (newref == NULL))
+	    {
+	    nomem:
+	      __libdwfl_seterrno (DWFL_E_NOMEM);
+	      nrefs = -1;
+	      goto free_refs;
+	    }
+
+	  newref->scn = scn;
+	  newref->relocs = NULL;
+	  newref->name = name;
+	  newref->start = dwfl_adjusted_address (mod, shdr->sh_addr);
+	  newref->end = newref->start + shdr->sh_size;
+	  newref->next = refs;
+	  refs = newref;
+	  ++nrefs;
+	}
+
+      if (mod->e_type == ET_REL
+	  && shdr->sh_size != 0
+	  && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+	  && mod->dwfl->callbacks->section_address != NULL)
+	{
+	  if (shdr->sh_info < elf_ndxscn (scn))
+	    {
+	      /* We've already looked at the section these relocs apply to.  */
+	      Elf_Scn *tscn = elf_getscn (mod->main.elf, shdr->sh_info);
+	      if (likely (tscn != NULL))
+		for (struct secref *sec = refs; sec != NULL; sec = sec->next)
+		  if (sec->scn == tscn)
+		    {
+		      sec->relocs = scn;
+		      break;
+		    }
+	    }
+	  else
+	    /* We'll have to do a second pass.  */
+	    check_reloc_sections = true;
+	}
+    }
+
+  mod->reloc_info = malloc (offsetof (struct dwfl_relocation, refs[nrefs]));
+  if (unlikely (mod->reloc_info == NULL))
+    goto nomem;
+
+  struct secref **sortrefs = malloc (nrefs * sizeof sortrefs[0]);
+  if (unlikely (sortrefs == NULL))
+    goto nomem;
+
+  for (size_t i = nrefs; i-- > 0; refs = refs->next)
+    sortrefs[i] = refs;
+  assert (refs == NULL);
+
+  qsort (sortrefs, nrefs, sizeof sortrefs[0], &compare_secrefs);
+
+  mod->reloc_info->count = nrefs;
+  for (size_t i = 0; i < nrefs; ++i)
+    {
+      mod->reloc_info->refs[i].name = sortrefs[i]->name;
+      mod->reloc_info->refs[i].scn = sortrefs[i]->scn;
+      mod->reloc_info->refs[i].relocs = sortrefs[i]->relocs;
+      mod->reloc_info->refs[i].start = sortrefs[i]->start;
+      mod->reloc_info->refs[i].end = sortrefs[i]->end;
+      free (sortrefs[i]);
+    }
+
+  free (sortrefs);
+
+  if (unlikely (check_reloc_sections))
+    {
+      /* There was a reloc section that preceded its target section.
+	 So we have to scan again now that we have cached all the
+	 possible target sections we care about.  */
+
+      scn = NULL;
+      while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
+	{
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (shdr == NULL)
+	    goto elf_error;
+
+      	  if (shdr->sh_size != 0
+	      && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA))
+	    {
+	      Elf_Scn *tscn = elf_getscn (mod->main.elf, shdr->sh_info);
+	      if (likely (tscn != NULL))
+		for (size_t i = 0; i < nrefs; ++i)
+		  if (mod->reloc_info->refs[i].scn == tscn)
+		    {
+		      mod->reloc_info->refs[i].relocs = scn;
+		      break;
+		    }
+	    }
+	}
+    }
+
+free_refs:
+  while (refs != NULL)
+    {
+      struct secref *ref = refs;
+      refs = ref->next;
+      free (ref);
+    }
+
+  return nrefs;
+}
+
+
+int
+dwfl_module_relocations (Dwfl_Module *mod)
+{
+  if (mod == NULL)
+    return -1;
+
+  switch (mod->e_type)
+    {
+    case ET_REL:
+      return cache_sections (mod);
+
+    case ET_DYN:
+      return 1;
+
+    case ET_EXEC:
+      assert (mod->main.vaddr == mod->low_addr);
+      break;
+    }
+
+  return 0;
+}
+
+const char *
+dwfl_module_relocation_info (Dwfl_Module *mod, unsigned int idx,
+			     Elf32_Word *shndxp)
+{
+  if (mod == NULL)
+    return NULL;
+
+  switch (mod->e_type)
+    {
+    case ET_REL:
+      break;
+
+    case ET_DYN:
+      if (idx != 0)
+	return NULL;
+      if (shndxp)
+	*shndxp = SHN_ABS;
+      return "";
+
+    default:
+      return NULL;
+    }
+
+  if (cache_sections (mod) < 0)
+    return NULL;
+
+  struct dwfl_relocation *sections = mod->reloc_info;
+
+  if (idx >= sections->count)
+    return NULL;
+
+  if (shndxp)
+    *shndxp = elf_ndxscn (sections->refs[idx].scn);
+
+  return sections->refs[idx].name;
+}
+
+/* Check that MOD is valid and make sure its relocation has been done.  */
+static bool
+check_module (Dwfl_Module *mod)
+{
+  if (mod == NULL)
+    return true;
+
+  if (INTUSE(dwfl_module_getsymtab) (mod) < 0)
+    {
+      Dwfl_Error error = dwfl_errno ();
+      if (error != DWFL_E_NO_SYMTAB)
+	{
+	  __libdwfl_seterrno (error);
+	  return true;
+	}
+    }
+
+  if (mod->dw == NULL)
+    {
+      Dwarf_Addr bias;
+      if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL)
+	{
+	  Dwfl_Error error = dwfl_errno ();
+	  if (error != DWFL_E_NO_DWARF)
+	    {
+	      __libdwfl_seterrno (error);
+	      return true;
+	    }
+	}
+    }
+
+  return false;
+}
+
+/* Find the index in MOD->reloc_info.refs containing *ADDR.  */
+static int
+find_section (Dwfl_Module *mod, Dwarf_Addr *addr)
+{
+  if (cache_sections (mod) < 0)
+    return -1;
+
+  struct dwfl_relocation *sections = mod->reloc_info;
+
+  /* The sections are sorted by address, so we can use binary search.  */
+  size_t l = 0, u = sections->count;
+  while (l < u)
+    {
+      size_t idx = (l + u) / 2;
+      if (*addr < sections->refs[idx].start)
+	u = idx;
+      else if (*addr > sections->refs[idx].end)
+	l = idx + 1;
+      else
+	{
+	  /* Consider the limit of a section to be inside it, unless it's
+	     inside the next one.  A section limit address can appear in
+	     line records.  */
+	  if (*addr == sections->refs[idx].end
+	      && idx + 1 < sections->count
+	      && *addr == sections->refs[idx + 1].start)
+	    ++idx;
+
+	  *addr -= sections->refs[idx].start;
+	  return idx;
+	}
+    }
+
+  __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_NO_MATCH));
+  return -1;
+}
+
+size_t
+internal_function
+__libdwfl_find_section_ndx (Dwfl_Module *mod, Dwarf_Addr *addr)
+{
+  int idx = find_section (mod, addr);
+  if (unlikely (idx == -1))
+    return SHN_UNDEF;
+
+  return elf_ndxscn (mod->reloc_info->refs[idx].scn);
+}
+
+int
+dwfl_module_relocate_address (Dwfl_Module *mod, Dwarf_Addr *addr)
+{
+  if (unlikely (check_module (mod)))
+    return -1;
+
+  switch (mod->e_type)
+    {
+    case ET_REL:
+      return find_section (mod, addr);
+
+    case ET_DYN:
+      /* All relative to first and only relocation base: module start.  */
+      *addr -= mod->low_addr;
+      break;
+
+    default:
+      /* Already absolute, dwfl_module_relocations returned zero.  We
+	 shouldn't really have been called, but it's a harmless no-op.  */
+      break;
+    }
+
+  return 0;
+}
+INTDEF (dwfl_module_relocate_address)
+
+Elf_Scn *
+dwfl_module_address_section (Dwfl_Module *mod, Dwarf_Addr *address,
+			     Dwarf_Addr *bias)
+{
+  if (check_module (mod))
+    return NULL;
+
+  int idx = find_section (mod, address);
+  if (idx < 0)
+    return NULL;
+
+  if (mod->reloc_info->refs[idx].relocs != NULL)
+    {
+      assert (mod->e_type == ET_REL);
+
+      Elf_Scn *tscn = mod->reloc_info->refs[idx].scn;
+      Elf_Scn *relocscn = mod->reloc_info->refs[idx].relocs;
+      Dwfl_Error result = __libdwfl_relocate_section (mod, mod->main.elf,
+						      relocscn, tscn, true);
+      if (likely (result == DWFL_E_NOERROR))
+	mod->reloc_info->refs[idx].relocs = NULL;
+      else
+	{
+	  __libdwfl_seterrno (result);
+	  return NULL;
+	}
+    }
+
+  *bias = dwfl_adjusted_address (mod, 0);
+  return mod->reloc_info->refs[idx].scn;
+}
+INTDEF (dwfl_module_address_section)
diff --git a/third_party/elfutils/libdwfl/dwfl_addrdie.c b/third_party/elfutils/libdwfl/dwfl_addrdie.c
new file mode 100644
index 0000000..c5b1d68
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_addrdie.c
@@ -0,0 +1,40 @@
+/* Fetch CU DIE from address.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwarf_Die *
+dwfl_addrdie (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias)
+{
+  return INTUSE(dwfl_module_addrdie) (INTUSE(dwfl_addrmodule) (dwfl, addr),
+				      addr, bias);
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_addrdwarf.c b/third_party/elfutils/libdwfl/dwfl_addrdwarf.c
new file mode 100644
index 0000000..4f9efab
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_addrdwarf.c
@@ -0,0 +1,41 @@
+/* Fetch libdw handle from address.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwarf *
+dwfl_addrdwarf (Dwfl *dwfl, Dwarf_Addr address, Dwarf_Addr *bias)
+{
+  return INTUSE(dwfl_module_getdwarf) (INTUSE(dwfl_addrmodule) (dwfl, address),
+				       bias);
+}
+INTDEF (dwfl_addrdwarf)
diff --git a/third_party/elfutils/libdwfl/dwfl_addrmodule.c b/third_party/elfutils/libdwfl/dwfl_addrmodule.c
new file mode 100644
index 0000000..abf1ff4
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_addrmodule.c
@@ -0,0 +1,42 @@
+/* Find module containing address.
+   Copyright (C) 2005, 2006, 2007, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwfl_Module *
+dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address)
+{
+  Dwfl_Module *mod;
+  (void) INTUSE(dwfl_addrsegment) (dwfl, address, &mod);
+  return mod;
+}
+INTDEF (dwfl_addrmodule)
diff --git a/third_party/elfutils/libdwfl/dwfl_begin.c b/third_party/elfutils/libdwfl/dwfl_begin.c
new file mode 100644
index 0000000..b03f5cf
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_begin.c
@@ -0,0 +1,55 @@
+/* Set up a session using libdwfl.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwfl *
+dwfl_begin (const Dwfl_Callbacks *callbacks)
+{
+  if (elf_version (EV_CURRENT) == EV_NONE)
+    {
+      __libdwfl_seterrno (DWFL_E_LIBELF);
+      return NULL;
+    }
+
+  Dwfl *dwfl = calloc (1, sizeof *dwfl);
+  if (dwfl == NULL)
+    __libdwfl_seterrno (DWFL_E_NOMEM);
+  else
+    {
+      dwfl->callbacks = callbacks;
+      dwfl->offline_next_address = OFFLINE_REDZONE;
+    }
+
+  return dwfl;
+}
+INTDEF (dwfl_begin)
diff --git a/third_party/elfutils/libdwfl/dwfl_build_id_find_debuginfo.c b/third_party/elfutils/libdwfl/dwfl_build_id_find_debuginfo.c
new file mode 100644
index 0000000..273e5e5
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_build_id_find_debuginfo.c
@@ -0,0 +1,132 @@
+/* Find the debuginfo file for a module from its build ID.
+   Copyright (C) 2007, 2009, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <unistd.h>
+
+
+int
+dwfl_build_id_find_debuginfo (Dwfl_Module *mod,
+			      void **userdata __attribute__ ((unused)),
+			      const char *modname __attribute__ ((unused)),
+			      Dwarf_Addr base __attribute__ ((unused)),
+			      const char *file __attribute__ ((unused)),
+			      const char *debuglink __attribute__ ((unused)),
+			      GElf_Word crc __attribute__ ((unused)),
+			      char **debuginfo_file_name)
+{
+  int fd = -1;
+
+  /* Are we looking for a separate debug file for the main file or for
+     an alternate (dwz multi) debug file?  Alternatively we could check
+     whether the dwbias == -1.  */
+  if (mod->dw != NULL)
+    {
+      const void *build_id;
+      const char *altname;
+      ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw,
+								   &altname,
+								   &build_id);
+      if (build_id_len > 0)
+	fd = __libdwfl_open_by_build_id (mod, true, debuginfo_file_name,
+					 build_id_len, build_id);
+
+      if (fd >= 0)
+	{
+	  /* We need to open an Elf handle on the file so we can check its
+	     build ID note for validation.  Backdoor the handle into the
+	     module data structure since we had to open it early anyway.  */
+	  Dwfl_Error error = __libdw_open_file (&fd, &mod->alt_elf,
+						true, false);
+	  if (error != DWFL_E_NOERROR)
+	    __libdwfl_seterrno (error);
+	  else
+	    {
+	      const void *alt_build_id;
+	      ssize_t alt_len = INTUSE(dwelf_elf_gnu_build_id) (mod->alt_elf,
+								&alt_build_id);
+	      if (alt_len > 0 && alt_len == build_id_len
+		  && memcmp (build_id, alt_build_id, alt_len) == 0)
+		return fd;
+	      else
+		{
+		  /* A mismatch!  */
+		  elf_end (mod->alt_elf);
+		  mod->alt_elf = NULL;
+		  close (fd);
+		  fd = -1;
+		}
+	      free (*debuginfo_file_name);
+	      *debuginfo_file_name = NULL;
+	      errno = 0;
+	    }
+	}
+      return fd;
+    }
+
+  /* We don't even have the Dwarf yet and it isn't in the main file.
+     Try to find separate debug file now using the module build id.  */
+  const unsigned char *bits;
+  GElf_Addr vaddr;
+
+  if (INTUSE(dwfl_module_build_id) (mod, &bits, &vaddr) > 0)
+    fd = __libdwfl_open_mod_by_build_id (mod, true, debuginfo_file_name);
+  if (fd >= 0)
+    {
+      /* We need to open an Elf handle on the file so we can check its
+	 build ID note for validation.  Backdoor the handle into the
+	 module data structure since we had to open it early anyway.  */
+      Dwfl_Error error = __libdw_open_file (&fd, &mod->debug.elf, true, false);
+      if (error != DWFL_E_NOERROR)
+	__libdwfl_seterrno (error);
+      else if (likely (__libdwfl_find_build_id (mod, false,
+						mod->debug.elf) == 2))
+	{
+	  /* Also backdoor the gratuitous flag.  */
+	  mod->debug.valid = true;
+	  return fd;
+	}
+      else
+	{
+	  /* A mismatch!  */
+	  elf_end (mod->debug.elf);
+	  mod->debug.elf = NULL;
+	  close (fd);
+	  fd = -1;
+	}
+      free (*debuginfo_file_name);
+      *debuginfo_file_name = NULL;
+      errno = 0;
+    }
+  return fd;
+}
+INTDEF (dwfl_build_id_find_debuginfo)
diff --git a/third_party/elfutils/libdwfl/dwfl_build_id_find_elf.c b/third_party/elfutils/libdwfl/dwfl_build_id_find_elf.c
new file mode 100644
index 0000000..ee0c164
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_build_id_find_elf.c
@@ -0,0 +1,198 @@
+/* Find an ELF file for a module from its build ID.
+   Copyright (C) 2007-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <inttypes.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "system.h"
+
+
+int
+internal_function
+__libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug, char **file_name,
+			    const size_t id_len, const uint8_t *id)
+{
+  /* We don't handle very short or really large build-ids.  We need at
+     at least 3 and allow for up to 64 (normally ids are 20 long).  */
+#define MIN_BUILD_ID_BYTES 3
+#define MAX_BUILD_ID_BYTES 64
+  if (id_len < MIN_BUILD_ID_BYTES || id_len > MAX_BUILD_ID_BYTES)
+    {
+      __libdwfl_seterrno (DWFL_E_WRONG_ID_ELF);
+      return -1;
+    }
+
+  /* Search debuginfo_path directories' .build-id/ subdirectories.  */
+
+  char id_name[sizeof "/.build-id/" + 1 + MAX_BUILD_ID_BYTES * 2
+	       + sizeof ".debug" - 1];
+  strcpy (id_name, "/.build-id/");
+  int n = snprintf (&id_name[sizeof "/.build-id/" - 1],
+		    4, "%02" PRIx8 "/", (uint8_t) id[0]);
+  assert (n == 3);
+  for (size_t i = 1; i < id_len; ++i)
+    {
+      n = snprintf (&id_name[sizeof "/.build-id/" - 1 + 3 + (i - 1) * 2],
+		    3, "%02" PRIx8, (uint8_t) id[i]);
+      assert (n == 2);
+    }
+  if (debug)
+    strcpy (&id_name[sizeof "/.build-id/" - 1 + 3 + (id_len - 1) * 2],
+	    ".debug");
+
+  const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
+  char *path = strdup ((cb->debuginfo_path ? *cb->debuginfo_path : NULL)
+		       ?: DEFAULT_DEBUGINFO_PATH);
+  if (path == NULL)
+    return -1;
+
+  int fd = -1;
+  char *dir;
+  char *paths = path;
+  while (fd < 0 && (dir = strsep (&paths, ":")) != NULL)
+    {
+      if (dir[0] == '+' || dir[0] == '-')
+	++dir;
+
+      /* Only absolute directory names are useful to us.  */
+      if (dir[0] != '/')
+	continue;
+
+      size_t dirlen = strlen (dir);
+      char *name = malloc (dirlen + sizeof id_name);
+      if (unlikely (name == NULL))
+	break;
+      memcpy (mempcpy (name, dir, dirlen), id_name, sizeof id_name);
+
+      fd = TEMP_FAILURE_RETRY (open (name, O_RDONLY));
+      if (fd >= 0)
+	{
+	  if (*file_name != NULL)
+	    free (*file_name);
+	  *file_name = canonicalize_file_name (name);
+	  if (*file_name == NULL)
+	    {
+	      *file_name = name;
+	      name = NULL;
+	    }
+	}
+      free (name);
+    }
+
+  free (path);
+
+  /* If we simply found nothing, clear errno.  If we had some other error
+     with the file, report that.  Possibly this should treat other errors
+     like ENOENT too.  But ignoring all errors could mask some that should
+     be reported.  */
+  if (fd < 0 && errno == ENOENT)
+    errno = 0;
+
+  return fd;
+}
+
+int
+internal_function
+__libdwfl_open_mod_by_build_id (Dwfl_Module *mod, bool debug, char **file_name)
+{
+  /* If *FILE_NAME was primed into the module, leave it there
+     as the fallback when we have nothing to offer.  */
+  errno = 0;
+  if (mod->build_id_len <= 0)
+    return -1;
+
+  const size_t id_len = mod->build_id_len;
+  const uint8_t *id = mod->build_id_bits;
+
+  return __libdwfl_open_by_build_id (mod, debug, file_name, id_len, id);
+}
+
+int
+dwfl_build_id_find_elf (Dwfl_Module *mod,
+			void **userdata __attribute__ ((unused)),
+			const char *modname __attribute__ ((unused)),
+			Dwarf_Addr base __attribute__ ((unused)),
+			char **file_name, Elf **elfp)
+{
+  *elfp = NULL;
+  if (mod->is_executable
+      && mod->dwfl->user_core != NULL
+      && mod->dwfl->user_core->executable_for_core != NULL)
+    {
+      /* When dwfl_core_file_report was called with a non-NULL executable file
+	 name this callback will replace the Dwfl_Module main.name with the
+	 recorded executable file when MOD was identified as main executable
+	 (which then triggers opening and reporting of the executable).  */
+      const char *executable = mod->dwfl->user_core->executable_for_core;
+      int fd = open (executable, O_RDONLY);
+      if (fd >= 0)
+	{
+	  *file_name = strdup (executable);
+	  if (*file_name != NULL)
+	    return fd;
+	  else
+	    close (fd);
+	}
+    }
+  int fd = __libdwfl_open_mod_by_build_id (mod, false, file_name);
+  if (fd >= 0)
+    {
+      Dwfl_Error error = __libdw_open_file (&fd, elfp, true, false);
+      if (error != DWFL_E_NOERROR)
+	__libdwfl_seterrno (error);
+      else if (__libdwfl_find_build_id (mod, false, *elfp) == 2)
+	{
+	  /* This is a backdoor signal to short-circuit the ID refresh.  */
+	  mod->main.valid = true;
+	  return fd;
+	}
+      else
+	{
+	  /* This file does not contain the ID it should!  */
+	  elf_end (*elfp);
+	  *elfp = NULL;
+	  close (fd);
+	  fd = -1;
+	}
+      free (*file_name);
+      *file_name = NULL;
+    }
+  else if (errno == 0 && mod->build_id_len > 0)
+    /* Setting this with no file yet loaded is a marker that
+       the build ID is authoritative even if we also know a
+       putative *FILE_NAME.  */
+    mod->main.valid = true;
+
+  return fd;
+}
+INTDEF (dwfl_build_id_find_elf)
diff --git a/third_party/elfutils/libdwfl/dwfl_cumodule.c b/third_party/elfutils/libdwfl/dwfl_cumodule.c
new file mode 100644
index 0000000..2b593f2
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_cumodule.c
@@ -0,0 +1,40 @@
+/* Find the module for a CU DIE previously returned by libdwfl.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwfl_Module *
+dwfl_cumodule (Dwarf_Die *cudie)
+{
+  struct dwfl_cu *cu = (struct dwfl_cu *) cudie;
+  return cu->mod;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_dwarf_line.c b/third_party/elfutils/libdwfl/dwfl_dwarf_line.c
new file mode 100644
index 0000000..e22e984
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_dwarf_line.c
@@ -0,0 +1,47 @@
+/* Get information from a source line record returned by libdwfl.
+   Copyright (C) 2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+
+Dwarf_Line *
+dwfl_dwarf_line (Dwfl_Line *line, Dwarf_Addr *bias)
+{
+  if (line == NULL)
+    return NULL;
+
+  struct dwfl_cu *cu = dwfl_linecu (line);
+  const Dwarf_Line *info = &cu->die.cu->lines->info[line->idx];
+
+  *bias = dwfl_adjusted_dwarf_addr (cu->mod, 0);
+  return (Dwarf_Line *) info;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_end.c b/third_party/elfutils/libdwfl/dwfl_end.c
new file mode 100644
index 0000000..74ee9e0
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_end.c
@@ -0,0 +1,66 @@
+/* Finish a session using libdwfl.
+   Copyright (C) 2005, 2008, 2012-2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <unistd.h>
+
+void
+dwfl_end (Dwfl *dwfl)
+{
+  if (dwfl == NULL)
+    return;
+
+  if (dwfl->process)
+    __libdwfl_process_free (dwfl->process);
+
+  free (dwfl->lookup_addr);
+  free (dwfl->lookup_module);
+  free (dwfl->lookup_segndx);
+
+  Dwfl_Module *next = dwfl->modulelist;
+  while (next != NULL)
+    {
+      Dwfl_Module *dead = next;
+      next = dead->next;
+      __libdwfl_module_free (dead);
+    }
+
+  if (dwfl->user_core != NULL)
+    {
+      free (dwfl->user_core->executable_for_core);
+      elf_end (dwfl->user_core->core);
+      if (dwfl->user_core->fd != -1)
+	close (dwfl->user_core->fd);
+      free (dwfl->user_core);
+    }
+  free (dwfl);
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_error.c b/third_party/elfutils/libdwfl/dwfl_error.c
new file mode 100644
index 0000000..7bcf61c
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_error.c
@@ -0,0 +1,171 @@
+/* Error handling in libdwfl.
+   Copyright (C) 2005-2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "libdwflP.h"
+
+
+/* The error number.  */
+static __thread int global_error;
+
+
+int
+dwfl_errno (void)
+{
+  int result = global_error;
+  global_error = DWFL_E_NOERROR;
+  return result;
+}
+INTDEF (dwfl_errno)
+
+
+struct msgtable
+{
+#define DWFL_ERROR(name, text) char msg_##name[sizeof text];
+  DWFL_ERRORS
+#undef	DWFL_ERROR
+};
+
+static const union
+{
+  struct msgtable table;
+  char strings[
+#define DWFL_ERROR(name, text)	+ sizeof text
+	       DWFL_ERRORS
+#undef	DWFL_ERROR
+	       ];
+} msgtable =
+  {
+    .table =
+    {
+#define DWFL_ERROR(name, text) text,
+      DWFL_ERRORS
+#undef	DWFL_ERROR
+    }
+  };
+#define msgstr (msgtable.strings)
+
+static const uint_fast16_t msgidx[] =
+{
+#define DWFL_ERROR(name, text) \
+  [DWFL_E_##name] = offsetof (struct msgtable, msg_##name),
+  DWFL_ERRORS
+#undef	DWFL_ERROR
+};
+#define nmsgidx (sizeof msgidx / sizeof msgidx[0])
+
+
+static inline int
+canonicalize (Dwfl_Error error)
+{
+  unsigned int value;
+
+  switch (error)
+    {
+    default:
+      value = error;
+      if ((value &~ 0xffff) != 0)
+	break;
+      assert (value < nmsgidx);
+      break;
+    case DWFL_E_ERRNO:
+      value = DWFL_E (ERRNO, errno);
+      break;
+    case DWFL_E_LIBELF:
+      value = DWFL_E (LIBELF, elf_errno ());
+      break;
+    case DWFL_E_LIBDW:
+      value = DWFL_E (LIBDW, INTUSE(dwarf_errno) ());
+      break;
+#if 0
+    DWFL_E_LIBEBL:
+      value = DWFL_E (LIBEBL, ebl_errno ());
+      break;
+#endif
+    }
+
+  return value;
+}
+
+int
+internal_function
+__libdwfl_canon_error (Dwfl_Error error)
+{
+  return canonicalize (error);
+}
+
+void
+internal_function
+__libdwfl_seterrno (Dwfl_Error error)
+{
+  global_error = canonicalize (error);
+}
+
+
+const char *
+dwfl_errmsg (int error)
+{
+  if (error == 0 || error == -1)
+    {
+      int last_error = global_error;
+
+      if (error == 0 && last_error == 0)
+	return NULL;
+
+      error = last_error;
+      global_error = DWFL_E_NOERROR;
+    }
+
+  switch (error &~ 0xffff)
+    {
+    case OTHER_ERROR (ERRNO):
+      return strerror_r (error & 0xffff, "bad", 0);
+    case OTHER_ERROR (LIBELF):
+      return elf_errmsg (error & 0xffff);
+    case OTHER_ERROR (LIBDW):
+      return INTUSE(dwarf_errmsg) (error & 0xffff);
+#if 0
+    case OTHER_ERROR (LIBEBL):
+      return ebl_errmsg (error & 0xffff);
+#endif
+    }
+
+  return _(&msgstr[msgidx[(unsigned int) error < nmsgidx
+			  ? error : DWFL_E_UNKNOWN_ERROR]]);
+}
+INTDEF (dwfl_errmsg)
diff --git a/third_party/elfutils/libdwfl/dwfl_frame.c b/third_party/elfutils/libdwfl/dwfl_frame.c
new file mode 100644
index 0000000..881f735
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_frame.c
@@ -0,0 +1,478 @@
+/* Get Dwarf Frame state for target PID or core file.
+   Copyright (C) 2013, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <unistd.h>
+
+/* Set STATE->pc_set from STATE->regs according to the backend.  Return true on
+   success, false on error.  */
+static bool
+state_fetch_pc (Dwfl_Frame *state)
+{
+  switch (state->pc_state)
+    {
+    case DWFL_FRAME_STATE_PC_SET:
+      return true;
+    case DWFL_FRAME_STATE_PC_UNDEFINED:
+      abort ();
+    case DWFL_FRAME_STATE_ERROR:
+      {
+	Ebl *ebl = state->thread->process->ebl;
+	Dwarf_CIE abi_info;
+	if (ebl_abi_cfi (ebl, &abi_info) != 0)
+	  {
+	    __libdwfl_seterrno (DWFL_E_LIBEBL);
+	    return false;
+	  }
+	unsigned ra = abi_info.return_address_register;
+	/* dwarf_frame_state_reg_is_set is not applied here.  */
+	if (ra >= ebl_frame_nregs (ebl))
+	  {
+	    __libdwfl_seterrno (DWFL_E_LIBEBL_BAD);
+	    return false;
+	  }
+	state->pc = state->regs[ra] + ebl_ra_offset (ebl);
+	state->pc_state = DWFL_FRAME_STATE_PC_SET;
+      }
+      return true;
+    }
+  abort ();
+}
+
+/* Do not call it on your own, to be used by thread_* functions only.  */
+
+static void
+state_free (Dwfl_Frame *state)
+{
+  Dwfl_Thread *thread = state->thread;
+  assert (thread->unwound == state);
+  thread->unwound = state->unwound;
+  free (state);
+}
+
+static void
+thread_free_all_states (Dwfl_Thread *thread)
+{
+  while (thread->unwound)
+    state_free (thread->unwound);
+}
+
+static Dwfl_Frame *
+state_alloc (Dwfl_Thread *thread)
+{
+  assert (thread->unwound == NULL);
+  Ebl *ebl = thread->process->ebl;
+  size_t nregs = ebl_frame_nregs (ebl);
+  if (nregs == 0)
+    return NULL;
+  assert (nregs < sizeof (((Dwfl_Frame *) NULL)->regs_set) * 8);
+  Dwfl_Frame *state = malloc (sizeof (*state) + sizeof (*state->regs) * nregs);
+  if (state == NULL)
+    return NULL;
+  state->thread = thread;
+  state->signal_frame = false;
+  state->initial_frame = true;
+  state->pc_state = DWFL_FRAME_STATE_ERROR;
+  memset (state->regs_set, 0, sizeof (state->regs_set));
+  thread->unwound = state;
+  state->unwound = NULL;
+  return state;
+}
+
+void
+internal_function
+__libdwfl_process_free (Dwfl_Process *process)
+{
+  Dwfl *dwfl = process->dwfl;
+  if (process->callbacks->detach != NULL)
+    process->callbacks->detach (dwfl, process->callbacks_arg);
+  assert (dwfl->process == process);
+  dwfl->process = NULL;
+  if (process->ebl_close)
+    ebl_closebackend (process->ebl);
+  free (process);
+  dwfl->attacherr = DWFL_E_NOERROR;
+}
+
+/* Allocate new Dwfl_Process for DWFL.  */
+static void
+process_alloc (Dwfl *dwfl)
+{
+  Dwfl_Process *process = malloc (sizeof (*process));
+  if (process == NULL)
+    return;
+  process->dwfl = dwfl;
+  dwfl->process = process;
+}
+
+bool
+dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
+		   const Dwfl_Thread_Callbacks *thread_callbacks, void *arg)
+{
+  if (dwfl->process != NULL)
+    {
+      __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
+      return false;
+    }
+
+  /* Reset any previous error, we are just going to try again.  */
+  dwfl->attacherr = DWFL_E_NOERROR;
+  /* thread_callbacks is declared NN */
+  if (thread_callbacks->next_thread == NULL
+      || thread_callbacks->set_initial_registers == NULL)
+    {
+      dwfl->attacherr = DWFL_E_INVALID_ARGUMENT;
+    fail:
+      dwfl->attacherr = __libdwfl_canon_error (dwfl->attacherr);
+      __libdwfl_seterrno (dwfl->attacherr);
+      return false;
+    }
+
+  Ebl *ebl;
+  bool ebl_close;
+  if (elf != NULL)
+    {
+      ebl = ebl_openbackend (elf);
+      ebl_close = true;
+    }
+  else
+    {
+      ebl = NULL;
+      for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
+	{
+	  /* Reading of the vDSO or (deleted) modules may fail as
+	     /proc/PID/mem is unreadable without PTRACE_ATTACH and
+	     we may not be PTRACE_ATTACH-ed now.  MOD would not be
+	     re-read later to unwind it when we are already
+	     PTRACE_ATTACH-ed to PID.  This happens when this function
+	     is called from dwfl_linux_proc_attach with elf == NULL.
+	     __libdwfl_module_getebl will call __libdwfl_getelf which
+	     will call the find_elf callback.  */
+	  if (strncmp (mod->name, "[vdso: ", 7) == 0
+	      || strcmp (strrchr (mod->name, ' ') ?: "",
+			 " (deleted)") == 0)
+	    continue;
+	  Dwfl_Error error = __libdwfl_module_getebl (mod);
+	  if (error != DWFL_E_NOERROR)
+	    continue;
+	  ebl = mod->ebl;
+	  break;
+	}
+      ebl_close = false;
+    }
+  if (ebl == NULL)
+    {
+      /* Not identified EBL from any of the modules.  */
+      dwfl->attacherr = DWFL_E_PROCESS_NO_ARCH;
+      goto fail;
+    }
+  process_alloc (dwfl);
+  Dwfl_Process *process = dwfl->process;
+  if (process == NULL)
+    {
+      if (ebl_close)
+	ebl_closebackend (ebl);
+      dwfl->attacherr = DWFL_E_NOMEM;
+      goto fail;
+    }
+  process->ebl = ebl;
+  process->ebl_close = ebl_close;
+  process->pid = pid;
+  process->callbacks = thread_callbacks;
+  process->callbacks_arg = arg;
+  return true;
+}
+INTDEF(dwfl_attach_state)
+
+pid_t
+dwfl_pid (Dwfl *dwfl)
+{
+  if (dwfl->attacherr != DWFL_E_NOERROR)
+    {
+      __libdwfl_seterrno (dwfl->attacherr);
+      return -1;
+    }
+
+  if (dwfl->process == NULL)
+    {
+      __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
+      return -1;
+    }
+  return dwfl->process->pid;
+}
+INTDEF(dwfl_pid)
+
+Dwfl *
+dwfl_thread_dwfl (Dwfl_Thread *thread)
+{
+  return thread->process->dwfl;
+}
+INTDEF(dwfl_thread_dwfl)
+
+pid_t
+dwfl_thread_tid (Dwfl_Thread *thread)
+{
+  return thread->tid;
+}
+INTDEF(dwfl_thread_tid)
+
+Dwfl_Thread *
+dwfl_frame_thread (Dwfl_Frame *state)
+{
+  return state->thread;
+}
+INTDEF(dwfl_frame_thread)
+
+int
+dwfl_getthreads (Dwfl *dwfl, int (*callback) (Dwfl_Thread *thread, void *arg),
+		 void *arg)
+{
+  if (dwfl->attacherr != DWFL_E_NOERROR)
+    {
+      __libdwfl_seterrno (dwfl->attacherr);
+      return -1;
+    }
+
+  Dwfl_Process *process = dwfl->process;
+  if (process == NULL)
+    {
+      __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
+      return -1;
+    }
+
+  Dwfl_Thread thread;
+  thread.process = process;
+  thread.unwound = NULL;
+  thread.callbacks_arg = NULL;
+  for (;;)
+    {
+      thread.tid = process->callbacks->next_thread (dwfl,
+						    process->callbacks_arg,
+						    &thread.callbacks_arg);
+      if (thread.tid < 0)
+	{
+	  Dwfl_Error saved_errno = dwfl_errno ();
+	  thread_free_all_states (&thread);
+	  __libdwfl_seterrno (saved_errno);
+	  return -1;
+	}
+      if (thread.tid == 0)
+	{
+	  thread_free_all_states (&thread);
+	  __libdwfl_seterrno (DWFL_E_NOERROR);
+	  return 0;
+	}
+      int err = callback (&thread, arg);
+      if (err != DWARF_CB_OK)
+	{
+	  thread_free_all_states (&thread);
+	  return err;
+	}
+      assert (thread.unwound == NULL);
+    }
+  /* NOTREACHED */
+}
+INTDEF(dwfl_getthreads)
+
+struct one_arg
+{
+  pid_t tid;
+  bool seen;
+  int (*callback) (Dwfl_Thread *thread, void *arg);
+  void *arg;
+  int ret;
+};
+
+static int
+get_one_thread_cb (Dwfl_Thread *thread, void *arg)
+{
+  struct one_arg *oa = (struct one_arg *) arg;
+  if (! oa->seen && INTUSE(dwfl_thread_tid) (thread) == oa->tid)
+    {
+      oa->seen = true;
+      oa->ret = oa->callback (thread, oa->arg);
+      return DWARF_CB_ABORT;
+    }
+
+  return DWARF_CB_OK;
+}
+
+/* Note not currently exported, will be when there are more Dwfl_Thread
+   properties to query.  Use dwfl_getthread_frames for now directly.  */
+static int
+getthread (Dwfl *dwfl, pid_t tid,
+	   int (*callback) (Dwfl_Thread *thread, void *arg),
+	   void *arg)
+{
+  if (dwfl->attacherr != DWFL_E_NOERROR)
+    {
+      __libdwfl_seterrno (dwfl->attacherr);
+      return -1;
+    }
+
+  Dwfl_Process *process = dwfl->process;
+  if (process == NULL)
+    {
+      __libdwfl_seterrno (DWFL_E_NO_ATTACH_STATE);
+      return -1;
+    }
+
+  if (process->callbacks->get_thread != NULL)
+    {
+      Dwfl_Thread thread;
+      thread.process = process;
+      thread.unwound = NULL;
+      thread.callbacks_arg = NULL;
+
+      if (process->callbacks->get_thread (dwfl, tid, process->callbacks_arg,
+					  &thread.callbacks_arg))
+	{
+	  int err;
+	  thread.tid = tid;
+	  err = callback (&thread, arg);
+	  thread_free_all_states (&thread);
+	  return err;
+	}
+
+      return -1;
+    }
+
+   struct one_arg oa = { .tid = tid, .callback = callback,
+			 .arg = arg, .seen = false };
+   int err = INTUSE(dwfl_getthreads) (dwfl, get_one_thread_cb, &oa);
+
+   if (err == DWARF_CB_ABORT && oa.seen)
+     return oa.ret;
+
+   if (err == DWARF_CB_OK && ! oa.seen)
+     {
+	errno = ESRCH;
+	__libdwfl_seterrno (DWFL_E_ERRNO);
+	return -1;
+     }
+
+   return err;
+}
+
+struct one_thread
+{
+  int (*callback) (Dwfl_Frame *frame, void *arg);
+  void *arg;
+};
+
+static int
+get_one_thread_frames_cb (Dwfl_Thread *thread, void *arg)
+{
+  struct one_thread *ot = (struct one_thread *) arg;
+  return INTUSE(dwfl_thread_getframes) (thread, ot->callback, ot->arg);
+}
+
+int
+dwfl_getthread_frames (Dwfl *dwfl, pid_t tid,
+		       int (*callback) (Dwfl_Frame *frame, void *arg),
+		       void *arg)
+{
+  struct one_thread ot = { .callback = callback, .arg = arg };
+  return getthread (dwfl, tid, get_one_thread_frames_cb, &ot);
+}
+INTDEF(dwfl_getthread_frames)
+
+int
+dwfl_thread_getframes (Dwfl_Thread *thread,
+		       int (*callback) (Dwfl_Frame *state, void *arg),
+		       void *arg)
+{
+  if (thread->unwound != NULL)
+    {
+      /* We had to be called from inside CALLBACK.  */
+      __libdwfl_seterrno (DWFL_E_ATTACH_STATE_CONFLICT);
+      return -1;
+    }
+  Ebl *ebl = thread->process->ebl;
+  if (ebl_frame_nregs (ebl) == 0)
+    {
+      __libdwfl_seterrno (DWFL_E_NO_UNWIND);
+      return -1;
+    }
+  if (state_alloc (thread) == NULL)
+    {
+      __libdwfl_seterrno (DWFL_E_NOMEM);
+      return -1;
+    }
+  Dwfl_Process *process = thread->process;
+  if (! process->callbacks->set_initial_registers (thread,
+						   thread->callbacks_arg))
+    {
+      thread_free_all_states (thread);
+      return -1;
+    }
+  if (! state_fetch_pc (thread->unwound))
+    {
+      if (process->callbacks->thread_detach)
+	process->callbacks->thread_detach (thread, thread->callbacks_arg);
+      thread_free_all_states (thread);
+      return -1;
+    }
+
+  Dwfl_Frame *state;
+  do
+    {
+      state = thread->unwound;
+      int err = callback (state, arg);
+      if (err != DWARF_CB_OK)
+	{
+	  if (process->callbacks->thread_detach)
+	    process->callbacks->thread_detach (thread, thread->callbacks_arg);
+	  thread_free_all_states (thread);
+	  return err;
+	}
+      __libdwfl_frame_unwind (state);
+      /* The old frame is no longer needed.  */
+      state_free (thread->unwound);
+      state = thread->unwound;
+    }
+  while (state && state->pc_state == DWFL_FRAME_STATE_PC_SET);
+
+  Dwfl_Error err = dwfl_errno ();
+  if (process->callbacks->thread_detach)
+    process->callbacks->thread_detach (thread, thread->callbacks_arg);
+  if (state == NULL || state->pc_state == DWFL_FRAME_STATE_ERROR)
+    {
+      thread_free_all_states (thread);
+      __libdwfl_seterrno (err);
+      return -1;
+    }
+  assert (state->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
+  thread_free_all_states (thread);
+  return 0;
+}
+INTDEF(dwfl_thread_getframes)
diff --git a/third_party/elfutils/libdwfl/dwfl_frame_pc.c b/third_party/elfutils/libdwfl/dwfl_frame_pc.c
new file mode 100644
index 0000000..296c815
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_frame_pc.c
@@ -0,0 +1,64 @@
+/* Get return address register value for frame.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+bool
+dwfl_frame_pc (Dwfl_Frame *state, Dwarf_Addr *pc, bool *isactivation)
+{
+  assert (state->pc_state == DWFL_FRAME_STATE_PC_SET);
+  *pc = state->pc;
+  ebl_normalize_pc (state->thread->process->ebl, pc);
+  if (isactivation)
+    {
+      /* Bottom frame?  */
+      if (state->initial_frame)
+	*isactivation = true;
+      /* *ISACTIVATION is logical union of whether current or previous frame
+	 state is SIGNAL_FRAME.  */
+      else if (state->signal_frame)
+	*isactivation = true;
+      else
+	{
+	  /* If the previous frame has unwound unsuccessfully just silently do
+	     not consider it could be a SIGNAL_FRAME.  */
+	  __libdwfl_frame_unwind (state);
+	  if (state->unwound == NULL
+	      || state->unwound->pc_state != DWFL_FRAME_STATE_PC_SET)
+	    *isactivation = false;
+	  else
+	    *isactivation = state->unwound->signal_frame;
+	}
+    }
+  return true;
+}
+INTDEF (dwfl_frame_pc)
diff --git a/third_party/elfutils/libdwfl/dwfl_frame_regs.c b/third_party/elfutils/libdwfl/dwfl_frame_regs.c
new file mode 100644
index 0000000..83b1abe
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_frame_regs.c
@@ -0,0 +1,61 @@
+/* Get Dwarf Frame state from modules present in DWFL.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+bool
+dwfl_thread_state_registers (Dwfl_Thread *thread, int firstreg,
+			     unsigned nregs, const Dwarf_Word *regs)
+{
+  Dwfl_Frame *state = thread->unwound;
+  assert (state && state->unwound == NULL);
+  assert (state->initial_frame);
+  for (unsigned regno = firstreg; regno < firstreg + nregs; regno++)
+    if (! __libdwfl_frame_reg_set (state, regno, regs[regno - firstreg]))
+      {
+	__libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
+	return false;
+      }
+  return true;
+}
+INTDEF(dwfl_thread_state_registers)
+
+void
+dwfl_thread_state_register_pc (Dwfl_Thread *thread, Dwarf_Word pc)
+{
+  Dwfl_Frame *state = thread->unwound;
+  assert (state && state->unwound == NULL);
+  assert (state->initial_frame);
+  state->pc = pc;
+  state->pc_state = DWFL_FRAME_STATE_PC_SET;
+}
+INTDEF(dwfl_thread_state_register_pc)
diff --git a/third_party/elfutils/libdwfl/dwfl_getdwarf.c b/third_party/elfutils/libdwfl/dwfl_getdwarf.c
new file mode 100644
index 0000000..edd088e
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_getdwarf.c
@@ -0,0 +1,63 @@
+/* Iterate through modules to fetch Dwarf information.
+   Copyright (C) 2005, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+struct module_callback_info
+{
+  int (*callback) (Dwfl_Module *, void **,
+		   const char *, Dwarf_Addr,
+		   Dwarf *, Dwarf_Addr, void *);
+  void *arg;
+};
+
+static int
+module_callback (Dwfl_Module *mod, void **userdata,
+		 const char *name, Dwarf_Addr start, void *arg)
+{
+  const struct module_callback_info *info = arg;
+  Dwarf_Addr bias = 0;
+  Dwarf *dw = INTUSE(dwfl_module_getdwarf) (mod, &bias);
+  return (*info->callback) (mod, userdata, name, start, dw, bias, info->arg);
+}
+
+ptrdiff_t
+dwfl_getdwarf (Dwfl *dwfl,
+	       int (*callback) (Dwfl_Module *, void **,
+				const char *, Dwarf_Addr,
+				Dwarf *, Dwarf_Addr, void *),
+	       void *arg,
+	       ptrdiff_t offset)
+{
+  struct module_callback_info info = { callback, arg };
+  return INTUSE(dwfl_getmodules) (dwfl, &module_callback, &info, offset);
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_getmodules.c b/third_party/elfutils/libdwfl/dwfl_getmodules.c
new file mode 100644
index 0000000..243cb04
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_getmodules.c
@@ -0,0 +1,96 @@
+/* Iterate through modules.
+   Copyright (C) 2005, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+ptrdiff_t
+dwfl_getmodules (Dwfl *dwfl,
+		 int (*callback) (Dwfl_Module *, void **,
+				  const char *, Dwarf_Addr, void *),
+		 void *arg,
+		 ptrdiff_t offset)
+{
+  if (dwfl == NULL)
+    return -1;
+
+  /* We iterate through the linked list when it's all we have.
+     But continuing from an offset is slow that way.  So when
+     DWFL->lookup_module is populated, we can instead keep our
+     place by jumping directly into the array.  Since the actions
+     of a callback could cause it to get populated, we must
+     choose the style of place-holder when we return an offset,
+     and we encode the choice in the low bits of that value.  */
+
+  Dwfl_Module *m = dwfl->modulelist;
+
+  if ((offset & 3) == 1)
+    {
+      offset >>= 2;
+      for (ptrdiff_t pos = 0; pos < offset; ++pos)
+	if (m == NULL)
+	  return -1;
+	else
+	  m = m->next;
+    }
+  else if (((offset & 3) == 2) && likely (dwfl->lookup_module != NULL))
+    {
+      offset >>= 2;
+
+      if ((size_t) offset - 1 == dwfl->lookup_elts)
+	return 0;
+
+      if (unlikely ((size_t) offset - 1 > dwfl->lookup_elts))
+	return -1;
+
+      m = dwfl->lookup_module[offset - 1];
+      if (unlikely (m == NULL))
+	return -1;
+    }
+  else if (offset != 0)
+    {
+      __libdwfl_seterrno (DWFL_E_BADSTROFF);
+      return -1;
+    }
+
+  while (m != NULL)
+    {
+      int ok = (*callback) (MODCB_ARGS (m), arg);
+      ++offset;
+      m = m->next;
+      if (ok != DWARF_CB_OK)
+	return ((dwfl->lookup_module == NULL) ? ((offset << 2) | 1)
+		: (((m == NULL ? (ptrdiff_t) dwfl->lookup_elts + 1
+		     : m->segment + 1) << 2) | 2));
+    }
+  return 0;
+}
+INTDEF (dwfl_getmodules)
diff --git a/third_party/elfutils/libdwfl/dwfl_getsrc.c b/third_party/elfutils/libdwfl/dwfl_getsrc.c
new file mode 100644
index 0000000..d853aed
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_getsrc.c
@@ -0,0 +1,40 @@
+/* Find source location for PC address.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwfl_Line *
+dwfl_getsrc (Dwfl *dwfl, Dwarf_Addr addr)
+{
+  return INTUSE(dwfl_module_getsrc) (INTUSE(dwfl_addrmodule) (dwfl, addr),
+				     addr);
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_getsrclines.c b/third_party/elfutils/libdwfl/dwfl_getsrclines.c
new file mode 100644
index 0000000..1ce78fc
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_getsrclines.c
@@ -0,0 +1,52 @@
+/* Fetch source line information for CU.
+   Copyright (C) 2005, 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+int
+dwfl_getsrclines (Dwarf_Die *cudie, size_t *nlines)
+{
+  struct dwfl_cu *cu = (struct dwfl_cu *) cudie;
+
+  if (cu->lines == NULL)
+    {
+      Dwfl_Error error = __libdwfl_cu_getsrclines (cu);
+      if (error != DWFL_E_NOERROR)
+	{
+	  __libdwfl_seterrno (error);
+	  return -1;
+	}
+    }
+
+  *nlines = cu->die.cu->lines->nlines;
+  return 0;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_line_comp_dir.c b/third_party/elfutils/libdwfl/dwfl_line_comp_dir.c
new file mode 100644
index 0000000..77c3fdf
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_line_comp_dir.c
@@ -0,0 +1,47 @@
+/* Get information from a source line record returned by libdwfl.
+   Copyright (C) 2005, 2006 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <dwarf.h>
+
+const char *
+dwfl_line_comp_dir (Dwfl_Line *line)
+{
+  if (line == NULL)
+    return NULL;
+
+  struct dwfl_cu *cu = dwfl_linecu (line);
+  Dwarf_Attribute attr_mem;
+  return INTUSE(dwarf_formstring) (INTUSE(dwarf_attr) (&cu->die,
+						       DW_AT_comp_dir,
+						       &attr_mem));
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_linecu.c b/third_party/elfutils/libdwfl/dwfl_linecu.c
new file mode 100644
index 0000000..2043b17
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_linecu.c
@@ -0,0 +1,45 @@
+/* Fetch the module containing a source line record returned by libdwfl.
+   Copyright (C) 2006 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+#undef dwfl_linecu
+
+Dwarf_Die *
+dwfl_linecu (Dwfl_Line *line)
+{
+  if (line == NULL)
+    return NULL;
+
+  struct dwfl_cu *cu = dwfl_linecu_inline (line);
+  return &cu->die;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_lineinfo.c b/third_party/elfutils/libdwfl/dwfl_lineinfo.c
new file mode 100644
index 0000000..9618712
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_lineinfo.c
@@ -0,0 +1,65 @@
+/* Get information from a source line record returned by libdwfl.
+   Copyright (C) 2005-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+
+const char *
+dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr, int *linep, int *colp,
+	       Dwarf_Word *mtime, Dwarf_Word *length)
+{
+  if (line == NULL)
+    return NULL;
+
+  struct dwfl_cu *cu = dwfl_linecu (line);
+  const Dwarf_Line *info = &cu->die.cu->lines->info[line->idx];
+
+  if (addr != NULL)
+    *addr = dwfl_adjusted_dwarf_addr (cu->mod, info->addr);
+  if (linep != NULL)
+    *linep = info->line;
+  if (colp != NULL)
+    *colp = info->column;
+
+  if (unlikely (info->file >= info->files->nfiles))
+    {
+      __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_DWARF));
+      return NULL;
+    }
+
+  struct Dwarf_Fileinfo_s *file = &info->files->info[info->file];
+  if (mtime != NULL)
+    *mtime = file->mtime;
+  if (length != NULL)
+    *length = file->length;
+  return file->name;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_linemodule.c b/third_party/elfutils/libdwfl/dwfl_linemodule.c
new file mode 100644
index 0000000..d243f0d
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_linemodule.c
@@ -0,0 +1,42 @@
+/* Fetch the module containing a source line record returned by libdwfl.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwfl_Module *
+dwfl_linemodule (Dwfl_Line *line)
+{
+  if (line == NULL)
+    return NULL;
+
+  return dwfl_linecu (line)->mod;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_module.c b/third_party/elfutils/libdwfl/dwfl_module.c
new file mode 100644
index 0000000..510bd69
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module.c
@@ -0,0 +1,242 @@
+/* Maintenance of module list in libdwfl.
+   Copyright (C) 2005, 2006, 2007, 2008, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include "../libdw/cfi.h"
+#include <search.h>
+#include <unistd.h>
+
+static void
+free_cu (struct dwfl_cu *cu)
+{
+  if (cu->lines != NULL)
+    free (cu->lines);
+  free (cu);
+}
+
+static void
+nofree (void *arg __attribute__ ((unused)))
+{
+}
+
+static void
+free_file (struct dwfl_file *file)
+{
+  free (file->name);
+
+  /* Close the fd only on the last reference.  */
+  if (file->elf != NULL && elf_end (file->elf) == 0 && file->fd != -1)
+    close (file->fd);
+}
+
+void
+internal_function
+__libdwfl_module_free (Dwfl_Module *mod)
+{
+  if (mod->lazy_cu_root != NULL)
+    tdestroy (mod->lazy_cu_root, nofree);
+
+  if (mod->aranges != NULL)
+    free (mod->aranges);
+
+  if (mod->cu != NULL)
+    {
+      for (size_t i = 0; i < mod->ncu; ++i)
+	free_cu (mod->cu[i]);
+      free (mod->cu);
+    }
+
+  /* We might have primed the Dwarf_CFI ebl cache with our own ebl
+     in __libdwfl_set_cfi. Make sure we don't free it twice.  */
+  if (mod->eh_cfi != NULL)
+    {
+      if (mod->eh_cfi->ebl != NULL && mod->eh_cfi->ebl == mod->ebl)
+	mod->eh_cfi->ebl = NULL;
+      dwarf_cfi_end (mod->eh_cfi);
+    }
+
+  if (mod->dwarf_cfi != NULL)
+    {
+      if (mod->dwarf_cfi->ebl != NULL && mod->dwarf_cfi->ebl == mod->ebl)
+	mod->dwarf_cfi->ebl = NULL;
+      /* We don't need to explicitly destroy the dwarf_cfi.
+	 That will be done by dwarf_end.  */
+    }
+
+  if (mod->dw != NULL)
+    {
+      INTUSE(dwarf_end) (mod->dw);
+      if (mod->alt != NULL)
+	{
+	  INTUSE(dwarf_end) (mod->alt);
+	  if (mod->alt_elf != NULL)
+	    elf_end (mod->alt_elf);
+	  if (mod->alt_fd != -1)
+	    close (mod->alt_fd);
+	}
+    }
+
+  if (mod->ebl != NULL)
+    ebl_closebackend (mod->ebl);
+
+  if (mod->debug.elf != mod->main.elf)
+    free_file (&mod->debug);
+  free_file (&mod->main);
+  free_file (&mod->aux_sym);
+
+  if (mod->build_id_bits != NULL)
+    free (mod->build_id_bits);
+
+  if (mod->reloc_info != NULL)
+    free (mod->reloc_info);
+
+  free (mod->name);
+  free (mod);
+}
+
+void
+dwfl_report_begin_add (Dwfl *dwfl __attribute__ ((unused)))
+{
+  /* The lookup table will be cleared on demand, there is nothing we need
+     to do here.  */
+}
+INTDEF (dwfl_report_begin_add)
+
+void
+dwfl_report_begin (Dwfl *dwfl)
+{
+  /* Clear the segment lookup table.  */
+  dwfl->lookup_elts = 0;
+
+  for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next)
+    m->gc = true;
+
+  dwfl->offline_next_address = OFFLINE_REDZONE;
+}
+INTDEF (dwfl_report_begin)
+
+static inline Dwfl_Module *
+use (Dwfl_Module *mod, Dwfl_Module **tailp, Dwfl *dwfl)
+{
+  mod->next = *tailp;
+  *tailp = mod;
+
+  if (unlikely (dwfl->lookup_module != NULL))
+    {
+      free (dwfl->lookup_module);
+      dwfl->lookup_module = NULL;
+    }
+
+  return mod;
+}
+
+/* Report that a module called NAME spans addresses [START, END).
+   Returns the module handle, either existing or newly allocated,
+   or returns a null pointer for an allocation error.  */
+Dwfl_Module *
+dwfl_report_module (Dwfl *dwfl, const char *name,
+		    GElf_Addr start, GElf_Addr end)
+{
+  Dwfl_Module **tailp = &dwfl->modulelist, **prevp = tailp;
+
+  for (Dwfl_Module *m = *prevp; m != NULL; m = *(prevp = &m->next))
+    {
+      if (m->low_addr == start && m->high_addr == end
+	  && !strcmp (m->name, name))
+	{
+	  /* This module is still here.  Move it to the place in the list
+	     after the last module already reported.  */
+	  *prevp = m->next;
+	  m->gc = false;
+	  return use (m, tailp, dwfl);
+	}
+
+      if (! m->gc)
+	tailp = &m->next;
+    }
+
+  Dwfl_Module *mod = calloc (1, sizeof *mod);
+  if (mod == NULL)
+    goto nomem;
+
+  mod->name = strdup (name);
+  if (mod->name == NULL)
+    {
+      free (mod);
+    nomem:
+      __libdwfl_seterrno (DWFL_E_NOMEM);
+      return NULL;
+    }
+
+  mod->low_addr = start;
+  mod->high_addr = end;
+  mod->dwfl = dwfl;
+
+  return use (mod, tailp, dwfl);
+}
+INTDEF (dwfl_report_module)
+
+
+/* Finish reporting the current set of modules to the library.
+   If REMOVED is not null, it's called for each module that
+   existed before but was not included in the current report.
+   Returns a nonzero return value from the callback.
+   DWFL cannot be used until this function has returned zero.  */
+int
+dwfl_report_end (Dwfl *dwfl,
+		 int (*removed) (Dwfl_Module *, void *,
+				 const char *, Dwarf_Addr,
+				 void *arg),
+		 void *arg)
+{
+  Dwfl_Module **tailp = &dwfl->modulelist;
+  while (*tailp != NULL)
+    {
+      Dwfl_Module *m = *tailp;
+      if (m->gc && removed != NULL)
+	{
+	  int result = (*removed) (MODCB_ARGS (m), arg);
+	  if (result != 0)
+	    return result;
+	}
+      if (m->gc)
+	{
+	  *tailp = m->next;
+	  __libdwfl_module_free (m);
+	}
+      else
+	tailp = &m->next;
+    }
+
+  return 0;
+}
+INTDEF (dwfl_report_end)
diff --git a/third_party/elfutils/libdwfl/dwfl_module_addrdie.c b/third_party/elfutils/libdwfl/dwfl_module_addrdie.c
new file mode 100644
index 0000000..b44ec13
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_addrdie.c
@@ -0,0 +1,49 @@
+/* Fetch the CU DIE for a PC address in a given module.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwarf_Die *
+dwfl_module_addrdie (Dwfl_Module *mod, Dwarf_Addr addr, Dwarf_Addr *bias)
+{
+  if (INTUSE(dwfl_module_getdwarf) (mod, bias) == NULL)
+    return NULL;
+
+  struct dwfl_cu *cu;
+  Dwfl_Error error = __libdwfl_addrcu (mod, addr, &cu);
+  if (likely (error == DWFL_E_NOERROR))
+    return &cu->die;
+
+  __libdwfl_seterrno (error);
+  return NULL;
+}
+INTDEF (dwfl_module_addrdie)
diff --git a/third_party/elfutils/libdwfl/dwfl_module_addrname.c b/third_party/elfutils/libdwfl/dwfl_module_addrname.c
new file mode 100644
index 0000000..3142b3e
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_addrname.c
@@ -0,0 +1,42 @@
+/* Find debugging and symbol information for a module in libdwfl.
+   Copyright (C) 2005, 2006, 2007, 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+const char *
+dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr addr)
+{
+  GElf_Off off;
+  GElf_Sym sym;
+  return INTUSE(dwfl_module_addrinfo) (mod, addr, &off, &sym,
+				       NULL, NULL, NULL);
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_module_addrsym.c b/third_party/elfutils/libdwfl/dwfl_module_addrsym.c
new file mode 100644
index 0000000..db302e6
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_addrsym.c
@@ -0,0 +1,332 @@
+/* Find debugging and symbol information for a module in libdwfl.
+   Copyright (C) 2005-2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+struct search_state
+{
+  Dwfl_Module *mod;
+  GElf_Addr addr;
+
+  GElf_Sym *closest_sym;
+  bool adjust_st_value;
+  GElf_Word addr_shndx;
+  Elf *addr_symelf;
+
+  /* Keep track of the closest symbol we have seen so far.
+     Here we store only symbols with nonzero st_size.  */
+  const char *closest_name;
+  GElf_Addr closest_value;
+  GElf_Word closest_shndx;
+  Elf *closest_elf;
+
+  /* Keep track of an eligible symbol with st_size == 0 as a fallback.  */
+  const char *sizeless_name;
+  GElf_Sym sizeless_sym;
+  GElf_Addr sizeless_value;
+  GElf_Word sizeless_shndx;
+  Elf *sizeless_elf;
+
+  /* Keep track of the lowest address a relevant sizeless symbol could have.  */
+  GElf_Addr min_label;
+};
+
+/* Return true iff we consider ADDR to lie in the same section as SYM.  */
+static inline bool
+same_section (struct search_state *state,
+	      GElf_Addr value, Elf *symelf, GElf_Word shndx)
+{
+  /* For absolute symbols and the like, only match exactly.  */
+  if (shndx >= SHN_LORESERVE)
+    return value == state->addr;
+
+  /* If value might not be st_value, the shndx of the symbol might
+      not match the section of the value. Explicitly look both up.  */
+  if (! state->adjust_st_value)
+    {
+      Dwarf_Addr v;
+      if (state->addr_shndx == SHN_UNDEF)
+        {
+          v = state->addr;
+          state->addr_shndx = __libdwfl_find_section_ndx (state->mod, &v);
+        }
+
+      v = value;
+      return state->addr_shndx == __libdwfl_find_section_ndx (state->mod, &v);
+    }
+
+  /* Figure out what section ADDR lies in.  */
+  if (state->addr_shndx == SHN_UNDEF || state->addr_symelf != symelf)
+    {
+      GElf_Addr mod_addr = dwfl_deadjust_st_value (state->mod, symelf,
+						   state->addr);
+      Elf_Scn *scn = NULL;
+      state->addr_shndx = SHN_ABS;
+      state->addr_symelf = symelf;
+      while ((scn = elf_nextscn (symelf, scn)) != NULL)
+        {
+          GElf_Shdr shdr_mem;
+          GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+          if (likely (shdr != NULL)
+              && mod_addr >= shdr->sh_addr
+              && mod_addr < shdr->sh_addr + shdr->sh_size)
+            {
+              state->addr_shndx = elf_ndxscn (scn);
+              break;
+            }
+        }
+    }
+
+  return shndx == state->addr_shndx && state->addr_symelf == symelf;
+}
+
+/* Return GELF_ST_BIND as higher-is-better integer.  */
+static inline int
+binding_value (const GElf_Sym *symp)
+{
+  switch (GELF_ST_BIND (symp->st_info))
+    {
+    case STB_GLOBAL:
+      return 3;
+    case STB_WEAK:
+      return 2;
+    case STB_LOCAL:
+      return 1;
+    default:
+      return 0;
+    }
+}
+
+/* Try one symbol and associated value from the search table.  */
+static inline void
+try_sym_value (struct search_state *state,
+               GElf_Addr value, GElf_Sym *sym,
+               const char *name, GElf_Word shndx,
+               Elf *elf, bool resolved)
+{
+    /* Even if we don't choose this symbol, its existence excludes
+       any sizeless symbol (assembly label) that is below its upper
+       bound.  */
+    if (value + sym->st_size > state->min_label)
+      state->min_label = value + sym->st_size;
+
+    if (sym->st_size == 0 || state->addr - value < sym->st_size)
+      {
+	/* This symbol is a better candidate than the current one
+	   if it's closer to ADDR or is global when it was local.  */
+	if (state->closest_name == NULL
+	    || state->closest_value < value
+	    || binding_value (state->closest_sym) < binding_value (sym))
+	  {
+	    if (sym->st_size != 0)
+	      {
+		*state->closest_sym = *sym;
+		state->closest_value = value;
+		state->closest_shndx = shndx;
+		state->closest_elf = elf;
+		state->closest_name = name;
+	      }
+	    else if (state->closest_name == NULL
+		     && value >= state->min_label
+		     && same_section (state, value,
+				      resolved ? state->mod->main.elf : elf,
+				      shndx))
+	      {
+		/* Handwritten assembly symbols sometimes have no
+		   st_size.  If no symbol with proper size includes
+		   the address, we'll use the closest one that is in
+		   the same section as ADDR.  */
+		state->sizeless_sym = *sym;
+		state->sizeless_value = value;
+		state->sizeless_shndx = shndx;
+		state->sizeless_elf = elf;
+		state->sizeless_name = name;
+	      }
+	  }
+	/* When the beginning of its range is no closer,
+	   the end of its range might be.  Otherwise follow
+	   GELF_ST_BIND preference.  If all are equal prefer
+	   the first symbol found.  */
+	else if (sym->st_size != 0
+		 && state->closest_value == value
+		 && ((state->closest_sym->st_size > sym->st_size
+		      && (binding_value (state->closest_sym)
+			  <= binding_value (sym)))
+		     || (state->closest_sym->st_size >= sym->st_size
+			 && (binding_value (state->closest_sym)
+			     < binding_value (sym)))))
+	  {
+	    *state->closest_sym = *sym;
+	    state->closest_value = value;
+	    state->closest_shndx = shndx;
+	    state->closest_elf = elf;
+	    state->closest_name = name;
+	  }
+      }
+}
+
+/* Look through the symbol table for a matching symbol.  */
+static inline void
+search_table (struct search_state *state, int start, int end)
+{
+      for (int i = start; i < end; ++i)
+	{
+	  GElf_Sym sym;
+	  GElf_Addr value;
+	  GElf_Word shndx;
+	  Elf *elf;
+	  bool resolved;
+	  const char *name = __libdwfl_getsym (state->mod, i, &sym, &value,
+					       &shndx, &elf, NULL,
+					       &resolved,
+					       state->adjust_st_value);
+	  if (name != NULL && name[0] != '\0'
+	      && sym.st_shndx != SHN_UNDEF
+	      && value <= state->addr
+	      && GELF_ST_TYPE (sym.st_info) != STT_SECTION
+	      && GELF_ST_TYPE (sym.st_info) != STT_FILE
+	      && GELF_ST_TYPE (sym.st_info) != STT_TLS)
+	    {
+	      try_sym_value (state, value, &sym, name, shndx, elf, resolved);
+
+	      /* If this is an addrinfo variant and the value could be
+		 resolved then also try matching the (adjusted) st_value.  */
+	      if (resolved && state->mod->e_type != ET_REL)
+		{
+		  GElf_Addr adjusted_st_value;
+		  adjusted_st_value = dwfl_adjusted_st_value (state->mod, elf,
+							      sym.st_value);
+		  if (value != adjusted_st_value
+		      && adjusted_st_value <= state->addr)
+		    try_sym_value (state, adjusted_st_value, &sym, name, shndx,
+				   elf, false);
+		}
+	    }
+	}
+}
+
+/* Returns the name of the symbol "closest" to ADDR.
+   Never returns symbols at addresses above ADDR.  */
+const char *
+internal_function
+__libdwfl_addrsym (Dwfl_Module *_mod, GElf_Addr _addr, GElf_Off *off,
+		   GElf_Sym *_closest_sym, GElf_Word *shndxp,
+		   Elf **elfp, Dwarf_Addr *biasp, bool _adjust_st_value)
+{
+  int syments = INTUSE(dwfl_module_getsymtab) (_mod);
+  if (syments < 0)
+    return NULL;
+
+  struct search_state state =
+    {
+      .addr = _addr,
+      .mod = _mod,
+      .closest_sym = _closest_sym,
+      .adjust_st_value = _adjust_st_value,
+      .addr_shndx = SHN_UNDEF,
+      .addr_symelf = NULL,
+      .closest_name = NULL,
+      .closest_value = 0,
+      .closest_shndx = SHN_UNDEF,
+      .closest_elf = NULL,
+      .sizeless_name = NULL,
+      .sizeless_sym = { 0, 0, 0, 0, 0, SHN_UNDEF },
+      .sizeless_value = 0,
+      .sizeless_shndx = SHN_UNDEF,
+      .sizeless_elf = NULL,
+      .min_label = 0
+    };
+
+  /* First go through global symbols.  mod->first_global and
+     mod->aux_first_global are setup by dwfl_module_getsymtab to the
+     index of the first global symbol in those symbol tables.  Both
+     are non-zero when the table exist, except when there is only a
+     dynsym table loaded through phdrs, then first_global is zero and
+     there will be no auxiliary table.  All symbols with local binding
+     come first in the symbol table, then all globals.  The zeroth,
+     null entry, in the auxiliary table is skipped if there is a main
+     table.  */
+  int first_global = INTUSE (dwfl_module_getsymtab_first_global) (state.mod);
+  if (first_global < 0)
+    return NULL;
+  search_table (&state, first_global == 0 ? 1 : first_global, syments);
+
+  /* If we found nothing searching the global symbols, then try the locals.
+     Unless we have a global sizeless symbol that matches exactly.  */
+  if (state.closest_name == NULL && first_global > 1
+      && (state.sizeless_name == NULL || state.sizeless_value != state.addr))
+    search_table (&state, 1, first_global);
+
+  /* If we found no proper sized symbol to use, fall back to the best
+     candidate sizeless symbol we found, if any.  */
+  if (state.closest_name == NULL
+      && state.sizeless_name != NULL
+      && state.sizeless_value >= state.min_label)
+    {
+      *state.closest_sym = state.sizeless_sym;
+      state.closest_value = state.sizeless_value;
+      state.closest_shndx = state.sizeless_shndx;
+      state.closest_elf = state.sizeless_elf;
+      state.closest_name = state.sizeless_name;
+    }
+
+  *off = state.addr - state.closest_value;
+
+  if (shndxp != NULL)
+    *shndxp = state.closest_shndx;
+  if (elfp != NULL)
+    *elfp = state.closest_elf;
+  if (biasp != NULL)
+    *biasp = dwfl_adjusted_st_value (state.mod, state.closest_elf, 0);
+  return state.closest_name;
+}
+
+
+const char *
+dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
+		     GElf_Sym *closest_sym, GElf_Word *shndxp)
+{
+  GElf_Off off;
+  return __libdwfl_addrsym (mod, addr, &off, closest_sym, shndxp,
+			    NULL, NULL, true);
+}
+INTDEF (dwfl_module_addrsym)
+
+const char
+*dwfl_module_addrinfo (Dwfl_Module *mod, GElf_Addr address,
+		       GElf_Off *offset, GElf_Sym *sym,
+		       GElf_Word *shndxp, Elf **elfp, Dwarf_Addr *bias)
+{
+  return __libdwfl_addrsym (mod, address, offset, sym, shndxp, elfp, bias,
+			    false);
+}
+INTDEF (dwfl_module_addrinfo)
diff --git a/third_party/elfutils/libdwfl/dwfl_module_build_id.c b/third_party/elfutils/libdwfl/dwfl_module_build_id.c
new file mode 100644
index 0000000..6ca9376
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_build_id.c
@@ -0,0 +1,121 @@
+/* Return build ID information for a module.
+   Copyright (C) 2007-2010, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+static int
+found_build_id (Dwfl_Module *mod, bool set,
+		const void *bits, int len, GElf_Addr vaddr)
+{
+  if (!set)
+    /* When checking bits, we do not compare VADDR because the
+       address found in a debuginfo file may not match the main
+       file as modified by prelink.  */
+    return 1 + (mod->build_id_len == len
+		&& !memcmp (bits, mod->build_id_bits, len));
+
+  void *copy = malloc (len);
+  if (unlikely (copy == NULL))
+    {
+      __libdwfl_seterrno (DWFL_E_NOMEM);
+      return -1;
+    }
+
+  mod->build_id_bits = memcpy (copy, bits, len);
+  mod->build_id_vaddr = vaddr;
+  mod->build_id_len = len;
+  return len;
+}
+
+int
+internal_function
+__libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf)
+{
+  const void *build_id_bits;
+  GElf_Addr build_id_elfaddr;
+  int build_id_len;
+
+  /* For mod == NULL use dwelf_elf_gnu_build_id directly.  */
+  assert (mod != NULL);
+
+  int result = __libdwfl_find_elf_build_id (mod, elf, &build_id_bits,
+					    &build_id_elfaddr, &build_id_len);
+  if (result <= 0)
+    return result;
+
+  GElf_Addr build_id_vaddr = build_id_elfaddr + (build_id_elfaddr != 0
+						 ? mod->main_bias : 0);
+  return found_build_id (mod, set, build_id_bits, build_id_len, build_id_vaddr);
+}
+
+int
+dwfl_module_build_id (Dwfl_Module *mod,
+		      const unsigned char **bits, GElf_Addr *vaddr)
+{
+  if (mod == NULL)
+    return -1;
+
+  if (mod->build_id_len == 0 && mod->main.elf != NULL)
+    {
+      /* We have the file, but have not examined it yet.  */
+      int result = __libdwfl_find_build_id (mod, true, mod->main.elf);
+      if (result <= 0)
+	{
+	  mod->build_id_len = -1;	/* Cache negative result.  */
+	  return result;
+	}
+    }
+
+  if (mod->build_id_len <= 0)
+    return 0;
+
+  *bits = mod->build_id_bits;
+  *vaddr = mod->build_id_vaddr;
+  return mod->build_id_len;
+}
+INTDEF (dwfl_module_build_id)
+NEW_VERSION (dwfl_module_build_id, ELFUTILS_0.138)
+
+#ifdef SYMBOL_VERSIONING
+COMPAT_VERSION (dwfl_module_build_id, ELFUTILS_0.130, vaddr_at_end)
+
+int
+_compat_vaddr_at_end_dwfl_module_build_id (Dwfl_Module *mod,
+					   const unsigned char **bits,
+					   GElf_Addr *vaddr)
+{
+  int result = INTUSE(dwfl_module_build_id) (mod, bits, vaddr);
+  if (result > 0)
+    *vaddr += (result + 3) & -4;
+  return result;
+}
+#endif
diff --git a/third_party/elfutils/libdwfl/dwfl_module_dwarf_cfi.c b/third_party/elfutils/libdwfl/dwfl_module_dwarf_cfi.c
new file mode 100644
index 0000000..0e5b435
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_dwarf_cfi.c
@@ -0,0 +1,73 @@
+/* Find DWARF CFI for a module in libdwfl.
+   Copyright (C) 2009-2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include "../libdw/cfi.h"
+
+Dwarf_CFI *
+internal_function
+__libdwfl_set_cfi (Dwfl_Module *mod, Dwarf_CFI **slot, Dwarf_CFI *cfi)
+{
+  if (cfi != NULL && cfi->ebl == NULL)
+    {
+      Dwfl_Error error = __libdwfl_module_getebl (mod);
+      if (error == DWFL_E_NOERROR)
+	cfi->ebl = mod->ebl;
+      else
+	{
+	  if (slot == &mod->eh_cfi)
+	    INTUSE(dwarf_cfi_end) (cfi);
+	  __libdwfl_seterrno (error);
+	  return NULL;
+	}
+    }
+
+  return *slot = cfi;
+}
+
+Dwarf_CFI *
+dwfl_module_dwarf_cfi (Dwfl_Module *mod, Dwarf_Addr *bias)
+{
+  if (mod == NULL)
+    return NULL;
+
+  if (mod->dwarf_cfi != NULL)
+    {
+      *bias = dwfl_adjusted_dwarf_addr (mod, 0);
+      return mod->dwarf_cfi;
+    }
+
+  return __libdwfl_set_cfi (mod, &mod->dwarf_cfi,
+			    INTUSE(dwarf_getcfi)
+			    (INTUSE(dwfl_module_getdwarf) (mod, bias)));
+}
+INTDEF (dwfl_module_dwarf_cfi)
diff --git a/third_party/elfutils/libdwfl/dwfl_module_eh_cfi.c b/third_party/elfutils/libdwfl/dwfl_module_eh_cfi.c
new file mode 100644
index 0000000..c296e39
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_eh_cfi.c
@@ -0,0 +1,59 @@
+/* Find EH CFI for a module in libdwfl.
+   Copyright (C) 2009-2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include "../libdw/cfi.h"
+
+Dwarf_CFI *
+dwfl_module_eh_cfi (Dwfl_Module *mod, Dwarf_Addr *bias)
+{
+  if (mod == NULL)
+    return NULL;
+
+  if (mod->eh_cfi != NULL)
+    {
+      *bias = dwfl_adjusted_address (mod, 0);
+      return mod->eh_cfi;
+    }
+
+  __libdwfl_getelf (mod);
+  if (mod->elferr != DWFL_E_NOERROR)
+    {
+      __libdwfl_seterrno (mod->elferr);
+      return NULL;
+    }
+
+  *bias = dwfl_adjusted_address (mod, 0);
+  return __libdwfl_set_cfi (mod, &mod->eh_cfi,
+			    INTUSE(dwarf_getcfi_elf) (mod->main.elf));
+}
+INTDEF (dwfl_module_eh_cfi)
diff --git a/third_party/elfutils/libdwfl/dwfl_module_getdwarf.c b/third_party/elfutils/libdwfl/dwfl_module_getdwarf.c
new file mode 100644
index 0000000..9775ace
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_getdwarf.c
@@ -0,0 +1,1494 @@
+/* Find debugging and symbol information for a module in libdwfl.
+   Copyright (C) 2005-2012, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <inttypes.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include "../libdw/libdwP.h"	/* DWARF_E_* values are here.  */
+#include "../libelf/libelfP.h"
+#include "system.h"
+
+static inline Dwfl_Error
+open_elf_file (Elf **elf, int *fd, char **name)
+{
+  if (*elf == NULL)
+    {
+      /* CBFAIL uses errno if it's set, so clear it first in case we don't
+	 set it with an open failure below.  */
+      errno = 0;
+
+      /* If there was a pre-primed file name left that the callback left
+	 behind, try to open that file name.  */
+      if (*fd < 0 && *name != NULL)
+	*fd = TEMP_FAILURE_RETRY (open (*name, O_RDONLY));
+
+      if (*fd < 0)
+	return CBFAIL;
+
+      return __libdw_open_file (fd, elf, true, false);
+    }
+  else if (unlikely (elf_kind (*elf) != ELF_K_ELF))
+    {
+      elf_end (*elf);
+      *elf = NULL;
+      close (*fd);
+      *fd = -1;
+      return DWFL_E_BADELF;
+    }
+
+  /* Elf file already open and looks fine.  */
+  return DWFL_E_NOERROR;
+}
+
+/* Open libelf FILE->fd and compute the load base of ELF as loaded in MOD.
+   When we return success, FILE->elf and FILE->vaddr are set up.  */
+static inline Dwfl_Error
+open_elf (Dwfl_Module *mod, struct dwfl_file *file)
+{
+  Dwfl_Error error = open_elf_file (&file->elf, &file->fd, &file->name);
+  if (error != DWFL_E_NOERROR)
+    return error;
+
+  GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (file->elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+    elf_error:
+      elf_end (file->elf);
+      file->elf = NULL;
+      close (file->fd);
+      file->fd = -1;
+      return DWFL_E (LIBELF, elf_errno ());
+    }
+
+  if (ehdr->e_type != ET_REL)
+    {
+      /* In any non-ET_REL file, we compute the "synchronization address".
+
+	 We start with the address at the end of the first PT_LOAD
+	 segment.  When prelink converts REL to RELA in an ET_DYN
+	 file, it expands the space between the beginning of the
+	 segment and the actual code/data addresses.  Since that
+	 change wasn't made in the debug file, the distance from
+	 p_vaddr to an address of interest (in an st_value or DWARF
+	 data) now differs between the main and debug files.  The
+	 distance from address_sync to an address of interest remains
+	 consistent.
+
+	 If there are no section headers at all (full stripping), then
+	 the end of the first segment is a valid synchronization address.
+	 This cannot happen in a prelinked file, since prelink itself
+	 relies on section headers for prelinking and for undoing it.
+	 (If you do full stripping on a prelinked file, then you get what
+	 you deserve--you can neither undo the prelinking, nor expect to
+	 line it up with a debug file separated before prelinking.)
+
+	 However, when prelink processes an ET_EXEC file, it can do
+	 something different.  There it juggles the "special" sections
+	 (SHT_DYNSYM et al) to make space for the additional prelink
+	 special sections.  Sometimes it will do this by moving a special
+	 section like .dynstr after the real program sections in the first
+	 PT_LOAD segment--i.e. to the end.  That changes the end address of
+	 the segment, so it no longer lines up correctly and is not a valid
+	 synchronization address to use.  Because of this, we need to apply
+	 a different prelink-savvy means to discover the synchronization
+	 address when there is a separate debug file and a prelinked main
+	 file.  That is done in find_debuginfo, below.  */
+
+      size_t phnum;
+      if (unlikely (elf_getphdrnum (file->elf, &phnum) != 0))
+	goto elf_error;
+
+      file->vaddr = file->address_sync = 0;
+      for (size_t i = 0; i < phnum; ++i)
+	{
+	  GElf_Phdr ph_mem;
+	  GElf_Phdr *ph = gelf_getphdr (file->elf, i, &ph_mem);
+	  if (unlikely (ph == NULL))
+	    goto elf_error;
+	  if (ph->p_type == PT_LOAD)
+	    {
+	      file->vaddr = ph->p_vaddr & -ph->p_align;
+	      file->address_sync = ph->p_vaddr + ph->p_memsz;
+	      break;
+	    }
+	}
+    }
+
+  /* We only want to set the module e_type explictly once, derived from
+     the main ELF file.  (It might be changed for the kernel, because
+     that is special - see below.)  open_elf is always called first for
+     the main ELF file, because both find_dw and find_symtab call
+     __libdwfl_getelf first to open the main file.  So don't let debug
+     or aux files override the module e_type.  The kernel heuristic
+     below could otherwise trigger for non-kernel/non-main files, since
+     their phdrs might not match the actual load addresses.  */
+  if (file == &mod->main)
+    {
+      mod->e_type = ehdr->e_type;
+
+      /* Relocatable Linux kernels are ET_EXEC but act like ET_DYN.  */
+      if (mod->e_type == ET_EXEC && file->vaddr != mod->low_addr)
+	mod->e_type = ET_DYN;
+    }
+  else
+    assert (mod->main.elf != NULL);
+
+  return DWFL_E_NOERROR;
+}
+
+/* We have an authoritative build ID for this module MOD, so don't use
+   a file by name that doesn't match that ID.  */
+static void
+mod_verify_build_id (Dwfl_Module *mod)
+{
+  assert (mod->build_id_len > 0);
+
+  switch (__builtin_expect (__libdwfl_find_build_id (mod, false,
+						     mod->main.elf), 2))
+    {
+    case 2:
+      /* Build ID matches as it should. */
+      return;
+
+    case -1:			/* ELF error.  */
+      mod->elferr = INTUSE(dwfl_errno) ();
+      break;
+
+    case 0:			/* File has no build ID note.  */
+    case 1:			/* FIle has a build ID that does not match.  */
+      mod->elferr = DWFL_E_WRONG_ID_ELF;
+      break;
+
+    default:
+      abort ();
+    }
+
+  /* We get here when it was the right ELF file.  Clear it out.  */
+  elf_end (mod->main.elf);
+  mod->main.elf = NULL;
+  if (mod->main.fd >= 0)
+    {
+      close (mod->main.fd);
+      mod->main.fd = -1;
+    }
+}
+
+/* Find the main ELF file for this module and open libelf on it.
+   When we return success, MOD->main.elf and MOD->main.bias are set up.  */
+void
+internal_function
+__libdwfl_getelf (Dwfl_Module *mod)
+{
+  if (mod->main.elf != NULL	/* Already done.  */
+      || mod->elferr != DWFL_E_NOERROR)	/* Cached failure.  */
+    return;
+
+  mod->main.fd = (*mod->dwfl->callbacks->find_elf) (MODCB_ARGS (mod),
+						    &mod->main.name,
+						    &mod->main.elf);
+  const bool fallback = mod->main.elf == NULL && mod->main.fd < 0;
+  mod->elferr = open_elf (mod, &mod->main);
+  if (mod->elferr != DWFL_E_NOERROR)
+    return;
+
+  if (!mod->main.valid)
+    {
+      /* Clear any explicitly reported build ID, just in case it was wrong.
+	 We'll fetch it from the file when asked.  */
+      free (mod->build_id_bits);
+      mod->build_id_bits = NULL;
+      mod->build_id_len = 0;
+    }
+  else if (fallback)
+    mod_verify_build_id (mod);
+
+  mod->main_bias = mod->e_type == ET_REL ? 0 : mod->low_addr - mod->main.vaddr;
+}
+
+static inline void
+consider_shdr (GElf_Addr interp,
+               GElf_Word sh_type,
+               GElf_Xword sh_flags,
+               GElf_Addr sh_addr,
+               GElf_Xword sh_size,
+               GElf_Addr *phighest)
+{
+  if ((sh_flags & SHF_ALLOC)
+      && ((sh_type == SHT_PROGBITS && sh_addr != interp)
+          || sh_type == SHT_NOBITS))
+    {
+      const GElf_Addr sh_end = sh_addr + sh_size;
+      if (sh_end > *phighest)
+        *phighest = sh_end;
+    }
+}
+
+/* If the main file might have been prelinked, then we need to
+   discover the correct synchronization address between the main and
+   debug files.  Because of prelink's section juggling, we cannot rely
+   on the address_sync computed from PT_LOAD segments (see open_elf).
+
+   We will attempt to discover a synchronization address based on the
+   section headers instead.  But finding a section address that is
+   safe to use requires identifying which sections are SHT_PROGBITS.
+   We can do that in the main file, but in the debug file all the
+   allocated sections have been transformed into SHT_NOBITS so we have
+   lost the means to match them up correctly.
+
+   The only method left to us is to decode the .gnu.prelink_undo
+   section in the prelinked main file.  This shows what the sections
+   looked like before prelink juggled them--when they still had a
+   direct correspondence to the debug file.  */
+static Dwfl_Error
+find_prelink_address_sync (Dwfl_Module *mod, struct dwfl_file *file)
+{
+  /* The magic section is only identified by name.  */
+  size_t shstrndx;
+  if (elf_getshdrstrndx (mod->main.elf, &shstrndx) < 0)
+    return DWFL_E_LIBELF;
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (unlikely (shdr == NULL))
+	return DWFL_E_LIBELF;
+      if (shdr->sh_type == SHT_PROGBITS
+	  && !(shdr->sh_flags & SHF_ALLOC)
+	  && shdr->sh_name != 0)
+	{
+	  const char *secname = elf_strptr (mod->main.elf, shstrndx,
+					    shdr->sh_name);
+	  if (unlikely (secname == NULL))
+	    return DWFL_E_LIBELF;
+	  if (!strcmp (secname, ".gnu.prelink_undo"))
+	    break;
+	}
+    }
+
+  if (scn == NULL)
+    /* There was no .gnu.prelink_undo section.  */
+    return DWFL_E_NOERROR;
+
+  Elf_Data *undodata = elf_rawdata (scn, NULL);
+  if (unlikely (undodata == NULL))
+    return DWFL_E_LIBELF;
+
+  /* Decode the section.  It consists of the original ehdr, phdrs,
+     and shdrs (but omits section 0).  */
+
+  union
+  {
+    Elf32_Ehdr e32;
+    Elf64_Ehdr e64;
+  } ehdr;
+  Elf_Data dst =
+    {
+      .d_buf = &ehdr,
+      .d_size = sizeof ehdr,
+      .d_type = ELF_T_EHDR,
+      .d_version = EV_CURRENT
+    };
+  Elf_Data src = *undodata;
+  src.d_size = gelf_fsize (mod->main.elf, ELF_T_EHDR, 1, EV_CURRENT);
+  src.d_type = ELF_T_EHDR;
+  if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
+			       elf_getident (mod->main.elf, NULL)[EI_DATA])
+		== NULL))
+    return DWFL_E_LIBELF;
+
+  size_t shentsize = gelf_fsize (mod->main.elf, ELF_T_SHDR, 1, EV_CURRENT);
+  size_t phentsize = gelf_fsize (mod->main.elf, ELF_T_PHDR, 1, EV_CURRENT);
+
+  uint_fast16_t phnum;
+  uint_fast16_t shnum;
+  if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
+    {
+      if (ehdr.e32.e_shentsize != shentsize
+	  || ehdr.e32.e_phentsize != phentsize)
+	return DWFL_E_BAD_PRELINK;
+      phnum = ehdr.e32.e_phnum;
+      shnum = ehdr.e32.e_shnum;
+    }
+  else
+    {
+      if (ehdr.e64.e_shentsize != shentsize
+	  || ehdr.e64.e_phentsize != phentsize)
+	return DWFL_E_BAD_PRELINK;
+      phnum = ehdr.e64.e_phnum;
+      shnum = ehdr.e64.e_shnum;
+    }
+
+  /* Since prelink does not store the zeroth section header in the undo
+     section, it cannot support SHN_XINDEX encoding.  */
+  if (unlikely (shnum >= SHN_LORESERVE) || unlikely(shnum == 0)
+      || unlikely (undodata->d_size != (src.d_size
+					+ phnum * phentsize
+					+ (shnum - 1) * shentsize)))
+    return DWFL_E_BAD_PRELINK;
+
+  --shnum;
+
+  /* We look at the allocated SHT_PROGBITS (or SHT_NOBITS) sections.  (Most
+     every file will have some SHT_PROGBITS sections, but it's possible to
+     have one with nothing but .bss, i.e. SHT_NOBITS.)  The special sections
+     that can be moved around have different sh_type values--except for
+     .interp, the section that became the PT_INTERP segment.  So we exclude
+     the SHT_PROGBITS section whose address matches the PT_INTERP p_vaddr.
+     For this reason, we must examine the phdrs first to find PT_INTERP.  */
+
+  GElf_Addr main_interp = 0;
+  {
+    size_t main_phnum;
+    if (unlikely (elf_getphdrnum (mod->main.elf, &main_phnum)))
+      return DWFL_E_LIBELF;
+    for (size_t i = 0; i < main_phnum; ++i)
+      {
+	GElf_Phdr phdr;
+	if (unlikely (gelf_getphdr (mod->main.elf, i, &phdr) == NULL))
+	  return DWFL_E_LIBELF;
+	if (phdr.p_type == PT_INTERP)
+	  {
+	    main_interp = phdr.p_vaddr;
+	    break;
+	  }
+      }
+  }
+
+  src.d_buf += src.d_size;
+  src.d_type = ELF_T_PHDR;
+  src.d_size = phnum * phentsize;
+
+  GElf_Addr undo_interp = 0;
+  bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
+  {
+    size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
+    if (unlikely (phnum > SIZE_MAX / phdr_size))
+      return DWFL_E_NOMEM;
+    const size_t phdrs_bytes = phnum * phdr_size;
+    void *phdrs = malloc (phdrs_bytes);
+    if (unlikely (phdrs == NULL))
+      return DWFL_E_NOMEM;
+    dst.d_buf = phdrs;
+    dst.d_size = phdrs_bytes;
+    if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
+				 ehdr.e32.e_ident[EI_DATA]) == NULL))
+      {
+	free (phdrs);
+	return DWFL_E_LIBELF;
+      }
+    if (class32)
+      {
+	Elf32_Phdr (*p32)[phnum] = phdrs;
+	for (uint_fast16_t i = 0; i < phnum; ++i)
+	  if ((*p32)[i].p_type == PT_INTERP)
+	    {
+	      undo_interp = (*p32)[i].p_vaddr;
+	      break;
+	    }
+      }
+    else
+      {
+	Elf64_Phdr (*p64)[phnum] = phdrs;
+	for (uint_fast16_t i = 0; i < phnum; ++i)
+	  if ((*p64)[i].p_type == PT_INTERP)
+	    {
+	      undo_interp = (*p64)[i].p_vaddr;
+	      break;
+	    }
+      }
+    free (phdrs);
+  }
+
+  if (unlikely ((main_interp == 0) != (undo_interp == 0)))
+    return DWFL_E_BAD_PRELINK;
+
+  src.d_buf += src.d_size;
+  src.d_type = ELF_T_SHDR;
+  src.d_size = gelf_fsize (mod->main.elf, ELF_T_SHDR, shnum, EV_CURRENT);
+
+  size_t shdr_size = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
+  if (unlikely (shnum > SIZE_MAX / shdr_size))
+    return DWFL_E_NOMEM;
+  const size_t shdrs_bytes = shnum * shdr_size;
+  void *shdrs = malloc (shdrs_bytes);
+  if (unlikely (shdrs == NULL))
+    return DWFL_E_NOMEM;
+  dst.d_buf = shdrs;
+  dst.d_size = shdrs_bytes;
+  if (unlikely (gelf_xlatetom (mod->main.elf, &dst, &src,
+			       ehdr.e32.e_ident[EI_DATA]) == NULL))
+    {
+      free (shdrs);
+      return DWFL_E_LIBELF;
+    }
+
+  /* Now we can look at the original section headers of the main file
+     before it was prelinked.  First we'll apply our method to the main
+     file sections as they are after prelinking, to calculate the
+     synchronization address of the main file.  Then we'll apply that
+     same method to the saved section headers, to calculate the matching
+     synchronization address of the debug file.
+
+     The method is to consider SHF_ALLOC sections that are either
+     SHT_PROGBITS or SHT_NOBITS, excluding the section whose sh_addr
+     matches the PT_INTERP p_vaddr.  The special sections that can be
+     moved by prelink have other types, except for .interp (which
+     becomes PT_INTERP).  The "real" sections cannot move as such, but
+     .bss can be split into .dynbss and .bss, with the total memory
+     image remaining the same but being spread across the two sections.
+     So we consider the highest section end, which still matches up.  */
+
+  GElf_Addr highest;
+
+  highest = 0;
+  scn = NULL;
+  while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
+    {
+      GElf_Shdr sh_mem;
+      GElf_Shdr *sh = gelf_getshdr (scn, &sh_mem);
+      if (unlikely (sh == NULL))
+	{
+	  free (shdrs);
+	  return DWFL_E_LIBELF;
+	}
+      consider_shdr (main_interp, sh->sh_type, sh->sh_flags,
+		     sh->sh_addr, sh->sh_size, &highest);
+    }
+  if (highest > mod->main.vaddr)
+    {
+      mod->main.address_sync = highest;
+
+      highest = 0;
+      if (class32)
+	{
+	  Elf32_Shdr (*s32)[shnum] = shdrs;
+	  for (size_t i = 0; i < shnum; ++i)
+	    consider_shdr (undo_interp, (*s32)[i].sh_type,
+			   (*s32)[i].sh_flags, (*s32)[i].sh_addr,
+			   (*s32)[i].sh_size, &highest);
+	}
+      else
+	{
+	  Elf64_Shdr (*s64)[shnum] = shdrs;
+	  for (size_t i = 0; i < shnum; ++i)
+	    consider_shdr (undo_interp, (*s64)[i].sh_type,
+			   (*s64)[i].sh_flags, (*s64)[i].sh_addr,
+			   (*s64)[i].sh_size, &highest);
+	}
+
+      if (highest > file->vaddr)
+	file->address_sync = highest;
+      else
+	{
+	  free (shdrs);
+	  return DWFL_E_BAD_PRELINK;
+	}
+    }
+
+  free (shdrs);
+
+  return DWFL_E_NOERROR;
+}
+
+/* Find the separate debuginfo file for this module and open libelf on it.
+   When we return success, MOD->debug is set up.  */
+static Dwfl_Error
+find_debuginfo (Dwfl_Module *mod)
+{
+  if (mod->debug.elf != NULL)
+    return DWFL_E_NOERROR;
+
+  GElf_Word debuglink_crc = 0;
+  const char *debuglink_file;
+  debuglink_file = INTUSE(dwelf_elf_gnu_debuglink) (mod->main.elf,
+						    &debuglink_crc);
+
+  mod->debug.fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
+							   mod->main.name,
+							   debuglink_file,
+							   debuglink_crc,
+							   &mod->debug.name);
+  Dwfl_Error result = open_elf (mod, &mod->debug);
+  if (result == DWFL_E_NOERROR && mod->debug.address_sync != 0)
+    result = find_prelink_address_sync (mod, &mod->debug);
+  return result;
+}
+
+/* Try to find the alternative debug link for the given DWARF and set
+   it if found.  Only called when mod->dw is already setup but still
+   might need an alternative (dwz multi) debug file.  filename is either
+   the main or debug name from which the Dwarf was created. */
+static void
+find_debug_altlink (Dwfl_Module *mod, const char *filename)
+{
+  assert (mod->dw != NULL);
+
+  const char *altname;
+  const void *build_id;
+  ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw,
+							       &altname,
+							       &build_id);
+
+  if (build_id_len > 0)
+    {
+      /* We could store altfile in the module, but don't really need it.  */
+      char *altfile = NULL;
+      mod->alt_fd = (*mod->dwfl->callbacks->find_debuginfo) (MODCB_ARGS (mod),
+							     filename,
+							     altname,
+							     0,
+							     &altfile);
+
+      /* The (internal) callbacks might just set mod->alt_elf directly
+	 because they open the Elf anyway for sanity checking.
+	 Otherwise open either the given file name or use the fd
+	 returned.  */
+      Dwfl_Error error = open_elf_file (&mod->alt_elf, &mod->alt_fd,
+					&altfile);
+      if (error == DWFL_E_NOERROR)
+	{
+	  mod->alt = INTUSE(dwarf_begin_elf) (mod->alt_elf,
+					      DWARF_C_READ, NULL);
+	  if (mod->alt == NULL)
+	    {
+	      elf_end (mod->alt_elf);
+	      mod->alt_elf = NULL;
+	      close (mod->alt_fd);
+	      mod->alt_fd = -1;
+	    }
+	  else
+	    dwarf_setalt (mod->dw, mod->alt);
+	}
+
+      free (altfile); /* See above, we don't really need it.  */
+    }
+}
+
+/* Try to find a symbol table in FILE.
+   Returns DWFL_E_NOERROR if a proper one is found.
+   Returns DWFL_E_NO_SYMTAB if not, but still sets results for SHT_DYNSYM.  */
+static Dwfl_Error
+load_symtab (struct dwfl_file *file, struct dwfl_file **symfile,
+	     Elf_Scn **symscn, Elf_Scn **xndxscn,
+	     size_t *syments, int *first_global, GElf_Word *strshndx)
+{
+  bool symtab = false;
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (file->elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr != NULL)
+	switch (shdr->sh_type)
+	  {
+	  case SHT_SYMTAB:
+	    if (shdr->sh_entsize == 0)
+	      break;
+	    symtab = true;
+	    *symscn = scn;
+	    *symfile = file;
+	    *strshndx = shdr->sh_link;
+	    *syments = shdr->sh_size / shdr->sh_entsize;
+	    *first_global = shdr->sh_info;
+	    if (*xndxscn != NULL)
+	      return DWFL_E_NOERROR;
+	    break;
+
+	  case SHT_DYNSYM:
+	    if (symtab)
+	      break;
+	    /* Use this if need be, but keep looking for SHT_SYMTAB.  */
+	    if (shdr->sh_entsize == 0)
+	      break;
+	    *symscn = scn;
+	    *symfile = file;
+	    *strshndx = shdr->sh_link;
+	    *syments = shdr->sh_size / shdr->sh_entsize;
+	    *first_global = shdr->sh_info;
+	    break;
+
+	  case SHT_SYMTAB_SHNDX:
+	    *xndxscn = scn;
+	    if (symtab)
+	      return DWFL_E_NOERROR;
+	    break;
+
+	  default:
+	    break;
+	  }
+    }
+
+  if (symtab)
+    /* We found one, though no SHT_SYMTAB_SHNDX to go with it.  */
+    return DWFL_E_NOERROR;
+
+  /* We found no SHT_SYMTAB, so any SHT_SYMTAB_SHNDX was bogus.
+     We might have found an SHT_DYNSYM and set *SYMSCN et al though.  */
+  *xndxscn = NULL;
+  return DWFL_E_NO_SYMTAB;
+}
+
+
+/* Translate addresses into file offsets.
+   OFFS[*] start out zero and remain zero if unresolved.  */
+static void
+find_offsets (Elf *elf, GElf_Addr main_bias, size_t phnum, size_t n,
+	      GElf_Addr addrs[n], GElf_Off offs[n])
+{
+  size_t unsolved = n;
+  for (size_t i = 0; i < phnum; ++i)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
+      if (phdr != NULL && phdr->p_type == PT_LOAD && phdr->p_memsz > 0)
+	for (size_t j = 0; j < n; ++j)
+	  if (offs[j] == 0
+	      && addrs[j] >= phdr->p_vaddr + main_bias
+	      && addrs[j] - (phdr->p_vaddr + main_bias) < phdr->p_filesz)
+	    {
+	      offs[j] = addrs[j] - (phdr->p_vaddr + main_bias) + phdr->p_offset;
+	      if (--unsolved == 0)
+		break;
+	    }
+    }
+}
+
+/* Various addresses we might want to pull from the dynamic segment.  */
+enum
+{
+  i_symtab,
+  i_strtab,
+  i_hash,
+  i_gnu_hash,
+  i_max
+};
+
+/* Translate pointers into file offsets.  ADJUST is either zero
+   in case the dynamic segment wasn't adjusted or mod->main_bias.
+   Will set mod->symfile if the translated offsets can be used as
+   symbol table.  */
+static void
+translate_offs (GElf_Addr adjust,
+                Dwfl_Module *mod, size_t phnum,
+                GElf_Addr addrs[i_max], GElf_Xword strsz,
+                GElf_Ehdr *ehdr)
+{
+  GElf_Off offs[i_max] = { 0, };
+  find_offsets (mod->main.elf, adjust, phnum, i_max, addrs, offs);
+
+  /* Figure out the size of the symbol table.  */
+  if (offs[i_hash] != 0)
+    {
+      /* In the original format, .hash says the size of .dynsym.  */
+
+      size_t entsz = SH_ENTSIZE_HASH (ehdr);
+      Elf_Data *data = elf_getdata_rawchunk (mod->main.elf,
+					     offs[i_hash] + entsz, entsz,
+					     (entsz == 4
+					      ? ELF_T_WORD : ELF_T_XWORD));
+      if (data != NULL)
+	mod->syments = (entsz == 4
+			? *(const GElf_Word *) data->d_buf
+			: *(const GElf_Xword *) data->d_buf);
+    }
+  if (offs[i_gnu_hash] != 0 && mod->syments == 0)
+    {
+      /* In the new format, we can derive it with some work.  */
+
+      const struct
+      {
+        Elf32_Word nbuckets;
+        Elf32_Word symndx;
+        Elf32_Word maskwords;
+        Elf32_Word shift2;
+      } *header;
+
+      Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, offs[i_gnu_hash],
+					     sizeof *header, ELF_T_WORD);
+      if (data != NULL)
+        {
+          header = data->d_buf;
+          Elf32_Word nbuckets = header->nbuckets;
+          Elf32_Word symndx = header->symndx;
+          GElf_Off buckets_at = (offs[i_gnu_hash] + sizeof *header
+				 + (gelf_getclass (mod->main.elf)
+				    * sizeof (Elf32_Word)
+				    * header->maskwords));
+
+          // elf_getdata_rawchunk takes a size_t, make sure it
+          // doesn't overflow.
+#if SIZE_MAX <= UINT32_MAX
+          if (nbuckets > SIZE_MAX / sizeof (Elf32_Word))
+            data = NULL;
+          else
+#endif
+            data = elf_getdata_rawchunk (mod->main.elf, buckets_at,
+					   nbuckets * sizeof (Elf32_Word),
+					   ELF_T_WORD);
+	  if (data != NULL && symndx < nbuckets)
+	    {
+	      const Elf32_Word *const buckets = data->d_buf;
+	      Elf32_Word maxndx = symndx;
+	      for (Elf32_Word bucket = 0; bucket < nbuckets; ++bucket)
+		if (buckets[bucket] > maxndx)
+		  maxndx = buckets[bucket];
+
+	      GElf_Off hasharr_at = (buckets_at
+				     + nbuckets * sizeof (Elf32_Word));
+	      hasharr_at += (maxndx - symndx) * sizeof (Elf32_Word);
+	      do
+		{
+		  data = elf_getdata_rawchunk (mod->main.elf,
+					       hasharr_at,
+					       sizeof (Elf32_Word),
+					       ELF_T_WORD);
+		  if (data != NULL
+		      && (*(const Elf32_Word *) data->d_buf & 1u))
+		    {
+		      mod->syments = maxndx + 1;
+		      break;
+		    }
+		  ++maxndx;
+		  hasharr_at += sizeof (Elf32_Word);
+		}
+	      while (data != NULL);
+	    }
+	}
+    }
+  if (offs[i_strtab] > offs[i_symtab] && mod->syments == 0)
+    mod->syments = ((offs[i_strtab] - offs[i_symtab])
+		    / gelf_fsize (mod->main.elf,
+				  ELF_T_SYM, 1, EV_CURRENT));
+
+  if (mod->syments > 0)
+    {
+      mod->symdata = elf_getdata_rawchunk (mod->main.elf,
+					   offs[i_symtab],
+					   gelf_fsize (mod->main.elf,
+						       ELF_T_SYM,
+						       mod->syments,
+						       EV_CURRENT),
+						       ELF_T_SYM);
+      if (mod->symdata != NULL)
+	{
+	  mod->symstrdata = elf_getdata_rawchunk (mod->main.elf,
+						  offs[i_strtab],
+						  strsz,
+						  ELF_T_BYTE);
+	  if (mod->symstrdata == NULL)
+	    mod->symdata = NULL;
+	}
+      if (mod->symdata == NULL)
+	mod->symerr = DWFL_E (LIBELF, elf_errno ());
+      else
+	{
+	  mod->symfile = &mod->main;
+	  mod->symerr = DWFL_E_NOERROR;
+	}
+    }
+}
+
+/* Try to find a dynamic symbol table via phdrs.  */
+static void
+find_dynsym (Dwfl_Module *mod)
+{
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (mod->main.elf, &ehdr_mem);
+
+  size_t phnum;
+  if (unlikely (elf_getphdrnum (mod->main.elf, &phnum) != 0))
+    return;
+
+  for (size_t i = 0; i < phnum; ++i)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem);
+      if (phdr == NULL)
+	break;
+
+      if (phdr->p_type == PT_DYNAMIC)
+	{
+	  /* Examine the dynamic section for the pointers we need.  */
+
+	  Elf_Data *data = elf_getdata_rawchunk (mod->main.elf,
+						 phdr->p_offset, phdr->p_filesz,
+						 ELF_T_DYN);
+	  if (data == NULL)
+	    continue;
+
+	  GElf_Addr addrs[i_max] = { 0, };
+	  GElf_Xword strsz = 0;
+	  size_t n = data->d_size / gelf_fsize (mod->main.elf,
+						ELF_T_DYN, 1, EV_CURRENT);
+	  for (size_t j = 0; j < n; ++j)
+	    {
+	      GElf_Dyn dyn_mem;
+	      GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
+	      if (dyn != NULL)
+		switch (dyn->d_tag)
+		  {
+		  case DT_SYMTAB:
+		    addrs[i_symtab] = dyn->d_un.d_ptr;
+		    continue;
+
+		  case DT_HASH:
+		    addrs[i_hash] = dyn->d_un.d_ptr;
+		    continue;
+
+		  case DT_GNU_HASH:
+		    addrs[i_gnu_hash] = dyn->d_un.d_ptr;
+		    continue;
+
+		  case DT_STRTAB:
+		    addrs[i_strtab] = dyn->d_un.d_ptr;
+		    continue;
+
+		  case DT_STRSZ:
+		    strsz = dyn->d_un.d_val;
+		    continue;
+
+		  default:
+		    continue;
+
+		  case DT_NULL:
+		    break;
+		  }
+	      break;
+	    }
+
+	  /* First try unadjusted, like ELF files from disk, vdso.
+	     Then try for already adjusted dynamic section, like ELF
+	     from remote memory.  */
+	  translate_offs (0, mod, phnum, addrs, strsz, ehdr);
+	  if (mod->symfile == NULL)
+	    translate_offs (mod->main_bias, mod, phnum, addrs, strsz, ehdr);
+
+	  return;
+	}
+    }
+}
+
+
+#if USE_LZMA
+/* Try to find the offset between the main file and .gnu_debugdata.  */
+static bool
+find_aux_address_sync (Dwfl_Module *mod)
+{
+  /* Don't trust the phdrs in the minisymtab elf file to be setup correctly.
+     The address_sync is equal to the main file it is embedded in at first.  */
+  mod->aux_sym.address_sync = mod->main.address_sync;
+
+  /* Adjust address_sync for the difference in entry addresses, attempting to
+     account for ELF relocation changes after aux was split.  */
+  GElf_Ehdr ehdr_main, ehdr_aux;
+  if (unlikely (gelf_getehdr (mod->main.elf, &ehdr_main) == NULL)
+      || unlikely (gelf_getehdr (mod->aux_sym.elf, &ehdr_aux) == NULL))
+    return false;
+  mod->aux_sym.address_sync += ehdr_aux.e_entry - ehdr_main.e_entry;
+
+  /* The shdrs are setup OK to make find_prelink_address_sync () do the right
+     thing, which is possibly more reliable, but it needs .gnu.prelink_undo.  */
+  if (mod->aux_sym.address_sync != 0)
+    return find_prelink_address_sync (mod, &mod->aux_sym) == DWFL_E_NOERROR;
+
+  return true;
+}
+#endif
+
+/* Try to find the auxiliary symbol table embedded in the main elf file
+   section .gnu_debugdata.  Only matters if the symbol information comes
+   from the main file dynsym.  No harm done if not found.  */
+static void
+find_aux_sym (Dwfl_Module *mod __attribute__ ((unused)),
+	      Elf_Scn **aux_symscn __attribute__ ((unused)),
+	      Elf_Scn **aux_xndxscn __attribute__ ((unused)),
+	      GElf_Word *aux_strshndx __attribute__ ((unused)))
+{
+  /* Since a .gnu_debugdata section is compressed using lzma don't do
+     anything unless we have support for that.  */
+#if USE_LZMA
+  Elf *elf = mod->main.elf;
+
+  size_t shstrndx;
+  if (elf_getshdrstrndx (elf, &shstrndx) < 0)
+    return;
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	return;
+
+      const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
+      if (name == NULL)
+	return;
+
+      if (!strcmp (name, ".gnu_debugdata"))
+	break;
+    }
+
+  if (scn == NULL)
+    return;
+
+  /* Found the .gnu_debugdata section.  Uncompress the lzma image and
+     turn it into an ELF image.  */
+  Elf_Data *rawdata = elf_rawdata (scn, NULL);
+  if (rawdata == NULL)
+    return;
+
+  Dwfl_Error error;
+  void *buffer = NULL;
+  size_t size = 0;
+  error = __libdw_unlzma (-1, 0, rawdata->d_buf, rawdata->d_size,
+			  &buffer, &size);
+  if (error == DWFL_E_NOERROR)
+    {
+      if (unlikely (size == 0))
+	free (buffer);
+      else
+	{
+	  mod->aux_sym.elf = elf_memory (buffer, size);
+	  if (mod->aux_sym.elf == NULL)
+	    free (buffer);
+	  else
+	    {
+	      mod->aux_sym.fd = -1;
+	      mod->aux_sym.elf->flags |= ELF_F_MALLOCED;
+	      if (open_elf (mod, &mod->aux_sym) != DWFL_E_NOERROR)
+		return;
+	      if (! find_aux_address_sync (mod))
+		{
+		  elf_end (mod->aux_sym.elf);
+		  mod->aux_sym.elf = NULL;
+		  return;
+		}
+
+	      /* So far, so good. Get minisymtab table data and cache it. */
+	      bool minisymtab = false;
+	      scn = NULL;
+	      while ((scn = elf_nextscn (mod->aux_sym.elf, scn)) != NULL)
+		{
+		  GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
+		  if (shdr != NULL)
+		    switch (shdr->sh_type)
+		      {
+		      case SHT_SYMTAB:
+			minisymtab = true;
+			*aux_symscn = scn;
+			*aux_strshndx = shdr->sh_link;
+			mod->aux_syments = shdr->sh_size / shdr->sh_entsize;
+			mod->aux_first_global = shdr->sh_info;
+			if (*aux_xndxscn != NULL)
+			  return;
+			break;
+
+		      case SHT_SYMTAB_SHNDX:
+			*aux_xndxscn = scn;
+			if (minisymtab)
+			  return;
+			break;
+
+		      default:
+			break;
+		      }
+		}
+
+	      if (minisymtab)
+		/* We found one, though no SHT_SYMTAB_SHNDX to go with it.  */
+		return;
+
+	      /* We found no SHT_SYMTAB, so everything else is bogus.  */
+	      *aux_xndxscn = NULL;
+	      *aux_strshndx = 0;
+	      mod->aux_syments = 0;
+	      elf_end (mod->aux_sym.elf);
+	      mod->aux_sym.elf = NULL;
+	      return;
+	    }
+	}
+    }
+  else
+    free (buffer);
+#endif
+}
+
+/* Try to find a symbol table in either MOD->main.elf or MOD->debug.elf.  */
+static void
+find_symtab (Dwfl_Module *mod)
+{
+  if (mod->symdata != NULL || mod->aux_symdata != NULL	/* Already done.  */
+      || mod->symerr != DWFL_E_NOERROR) /* Cached previous failure.  */
+    return;
+
+  __libdwfl_getelf (mod);
+  mod->symerr = mod->elferr;
+  if (mod->symerr != DWFL_E_NOERROR)
+    return;
+
+  /* First see if the main ELF file has the debugging information.  */
+  Elf_Scn *symscn = NULL, *xndxscn = NULL;
+  Elf_Scn *aux_symscn = NULL, *aux_xndxscn = NULL;
+  GElf_Word strshndx, aux_strshndx = 0;
+  mod->symerr = load_symtab (&mod->main, &mod->symfile, &symscn,
+			     &xndxscn, &mod->syments, &mod->first_global,
+			     &strshndx);
+  switch (mod->symerr)
+    {
+    default:
+      return;
+
+    case DWFL_E_NOERROR:
+      break;
+
+    case DWFL_E_NO_SYMTAB:
+      /* Now we have to look for a separate debuginfo file.  */
+      mod->symerr = find_debuginfo (mod);
+      switch (mod->symerr)
+	{
+	default:
+	  return;
+
+	case DWFL_E_NOERROR:
+	  mod->symerr = load_symtab (&mod->debug, &mod->symfile, &symscn,
+				     &xndxscn, &mod->syments,
+				     &mod->first_global, &strshndx);
+	  break;
+
+	case DWFL_E_CB:		/* The find_debuginfo hook failed.  */
+	  mod->symerr = DWFL_E_NO_SYMTAB;
+	  break;
+	}
+
+      switch (mod->symerr)
+	{
+	default:
+	  return;
+
+	case DWFL_E_NOERROR:
+	  break;
+
+	case DWFL_E_NO_SYMTAB:
+	  /* There might be an auxiliary table.  */
+	  find_aux_sym (mod, &aux_symscn, &aux_xndxscn, &aux_strshndx);
+
+	  if (symscn != NULL)
+	    {
+	      /* We still have the dynamic symbol table.  */
+	      mod->symerr = DWFL_E_NOERROR;
+	      break;
+	    }
+
+	  if (aux_symscn != NULL)
+	    {
+	      /* We still have the auxiliary symbol table.  */
+	      mod->symerr = DWFL_E_NOERROR;
+	      goto aux_cache;
+	    }
+
+	  /* Last ditch, look for dynamic symbols without section headers.  */
+	  find_dynsym (mod);
+	  return;
+	}
+      break;
+    }
+
+  /* This does some sanity checks on the string table section.  */
+  if (elf_strptr (mod->symfile->elf, strshndx, 0) == NULL)
+    {
+    elferr:
+      mod->symdata = NULL;
+      mod->syments = 0;
+      mod->first_global = 0;
+      mod->symerr = DWFL_E (LIBELF, elf_errno ());
+      goto aux_cleanup; /* This cleans up some more and tries find_dynsym.  */
+    }
+
+  /* Cache the data; MOD->syments and MOD->first_global were set
+     above.  If any of the sections is compressed, uncompress it
+     first.  Only the string data setion could theoretically be
+     compressed GNU style (as .zdebug_str).  Everything else only ELF
+     gabi style (SHF_COMPRESSED).  */
+
+  Elf_Scn *symstrscn = elf_getscn (mod->symfile->elf, strshndx);
+  if (symstrscn == NULL)
+    goto elferr;
+
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (symstrscn, &shdr_mem);
+  if (shdr == NULL)
+    goto elferr;
+
+  size_t shstrndx;
+  if (elf_getshdrstrndx (mod->symfile->elf, &shstrndx) < 0)
+    goto elferr;
+
+  const char *sname = elf_strptr (mod->symfile->elf, shstrndx, shdr->sh_name);
+  if (sname == NULL)
+    goto elferr;
+
+  if (strncmp (sname, ".zdebug", strlen (".zdebug")) == 0)
+    /* Try to uncompress, but it might already have been, an error
+       might just indicate, already uncompressed.  */
+    elf_compress_gnu (symstrscn, 0, 0);
+
+  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+    if (elf_compress (symstrscn, 0, 0) < 0)
+      goto elferr;
+
+  mod->symstrdata = elf_getdata (symstrscn, NULL);
+  if (mod->symstrdata == NULL || mod->symstrdata->d_buf == NULL)
+    goto elferr;
+
+  if (xndxscn == NULL)
+    mod->symxndxdata = NULL;
+  else
+    {
+      shdr = gelf_getshdr (xndxscn, &shdr_mem);
+      if (shdr == NULL)
+	goto elferr;
+
+      if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	if (elf_compress (xndxscn, 0, 0) < 0)
+	  goto elferr;
+
+      mod->symxndxdata = elf_getdata (xndxscn, NULL);
+      if (mod->symxndxdata == NULL || mod->symxndxdata->d_buf == NULL)
+	goto elferr;
+    }
+
+  shdr = gelf_getshdr (symscn, &shdr_mem);
+  if (shdr == NULL)
+    goto elferr;
+
+  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+    if (elf_compress (symscn, 0, 0) < 0)
+      goto elferr;
+
+  mod->symdata = elf_getdata (symscn, NULL);
+  if (mod->symdata == NULL || mod->symdata->d_buf == NULL)
+    goto elferr;
+
+  // Sanity check number of symbols.
+  shdr = gelf_getshdr (symscn, &shdr_mem);
+  if (shdr == NULL || shdr->sh_entsize == 0
+      || mod->syments > mod->symdata->d_size / shdr->sh_entsize
+      || (size_t) mod->first_global > mod->syments)
+    goto elferr;
+
+  /* Cache any auxiliary symbol info, when it fails, just ignore aux_sym.  */
+  if (aux_symscn != NULL)
+    {
+  aux_cache:
+      /* This does some sanity checks on the string table section.  */
+      if (elf_strptr (mod->aux_sym.elf, aux_strshndx, 0) == NULL)
+	{
+	aux_cleanup:
+	  mod->aux_syments = 0;
+	  elf_end (mod->aux_sym.elf);
+	  mod->aux_sym.elf = NULL;
+	  /* We thought we had something through shdrs, but it failed...
+	     Last ditch, look for dynamic symbols without section headers.  */
+	  find_dynsym (mod);
+	  return;
+	}
+
+      Elf_Scn *aux_strscn = elf_getscn (mod->aux_sym.elf, aux_strshndx);
+      if (aux_strscn == NULL)
+	goto elferr;
+
+      shdr = gelf_getshdr (aux_strscn, &shdr_mem);
+      if (shdr == NULL)
+	goto elferr;
+
+      size_t aux_shstrndx;
+      if (elf_getshdrstrndx (mod->aux_sym.elf, &aux_shstrndx) < 0)
+	goto elferr;
+
+      sname = elf_strptr (mod->aux_sym.elf, aux_shstrndx,
+				      shdr->sh_name);
+      if (sname == NULL)
+	goto elferr;
+
+      if (strncmp (sname, ".zdebug", strlen (".zdebug")) == 0)
+	/* Try to uncompress, but it might already have been, an error
+	   might just indicate, already uncompressed.  */
+	elf_compress_gnu (aux_strscn, 0, 0);
+
+      if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	if (elf_compress (aux_strscn, 0, 0) < 0)
+	  goto elferr;
+
+      mod->aux_symstrdata = elf_getdata (aux_strscn, NULL);
+      if (mod->aux_symstrdata == NULL || mod->aux_symstrdata->d_buf == NULL)
+	goto aux_cleanup;
+
+      if (aux_xndxscn == NULL)
+	mod->aux_symxndxdata = NULL;
+      else
+	{
+	  shdr = gelf_getshdr (aux_xndxscn, &shdr_mem);
+	  if (shdr == NULL)
+	    goto elferr;
+
+	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	    if (elf_compress (aux_xndxscn, 0, 0) < 0)
+	      goto elferr;
+
+	  mod->aux_symxndxdata = elf_getdata (aux_xndxscn, NULL);
+	  if (mod->aux_symxndxdata == NULL
+	      || mod->aux_symxndxdata->d_buf == NULL)
+	    goto aux_cleanup;
+	}
+
+      shdr = gelf_getshdr (aux_symscn, &shdr_mem);
+      if (shdr == NULL)
+	goto elferr;
+
+      if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	if (elf_compress (aux_symscn, 0, 0) < 0)
+	  goto elferr;
+
+      mod->aux_symdata = elf_getdata (aux_symscn, NULL);
+      if (mod->aux_symdata == NULL || mod->aux_symdata->d_buf == NULL)
+	goto aux_cleanup;
+
+      // Sanity check number of aux symbols.
+      shdr = gelf_getshdr (aux_symscn, &shdr_mem);
+      if (mod->aux_syments > mod->aux_symdata->d_size / shdr->sh_entsize
+	  || (size_t) mod->aux_first_global > mod->aux_syments)
+	goto aux_cleanup;
+    }
+}
+
+
+/* Try to open a libebl backend for MOD.  */
+Dwfl_Error
+internal_function
+__libdwfl_module_getebl (Dwfl_Module *mod)
+{
+  if (mod->ebl == NULL)
+    {
+      __libdwfl_getelf (mod);
+      if (mod->elferr != DWFL_E_NOERROR)
+	return mod->elferr;
+
+      mod->ebl = ebl_openbackend (mod->main.elf);
+      if (mod->ebl == NULL)
+	return DWFL_E_LIBEBL;
+    }
+  return DWFL_E_NOERROR;
+}
+
+/* Try to start up libdw on DEBUGFILE.  */
+static Dwfl_Error
+load_dw (Dwfl_Module *mod, struct dwfl_file *debugfile)
+{
+  if (mod->e_type == ET_REL && !debugfile->relocated)
+    {
+      const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
+
+      /* The debugging sections have to be relocated.  */
+      if (cb->section_address == NULL)
+	return DWFL_E_NOREL;
+
+      Dwfl_Error error = __libdwfl_module_getebl (mod);
+      if (error != DWFL_E_NOERROR)
+	return error;
+
+      find_symtab (mod);
+      Dwfl_Error result = mod->symerr;
+      if (result == DWFL_E_NOERROR)
+	result = __libdwfl_relocate (mod, debugfile->elf, true);
+      if (result != DWFL_E_NOERROR)
+	return result;
+
+      /* Don't keep the file descriptors around.  */
+      if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0)
+	{
+	  close (mod->main.fd);
+	  mod->main.fd = -1;
+	}
+      if (debugfile->fd != -1 && elf_cntl (debugfile->elf, ELF_C_FDREAD) == 0)
+	{
+	  close (debugfile->fd);
+	  debugfile->fd = -1;
+	}
+    }
+
+  mod->dw = INTUSE(dwarf_begin_elf) (debugfile->elf, DWARF_C_READ, NULL);
+  if (mod->dw == NULL)
+    {
+      int err = INTUSE(dwarf_errno) ();
+      return err == DWARF_E_NO_DWARF ? DWFL_E_NO_DWARF : DWFL_E (LIBDW, err);
+    }
+
+  /* Until we have iterated through all CU's, we might do lazy lookups.  */
+  mod->lazycu = 1;
+
+  return DWFL_E_NOERROR;
+}
+
+/* Try to start up libdw on either the main file or the debuginfo file.  */
+static void
+find_dw (Dwfl_Module *mod)
+{
+  if (mod->dw != NULL		/* Already done.  */
+      || mod->dwerr != DWFL_E_NOERROR) /* Cached previous failure.  */
+    return;
+
+  __libdwfl_getelf (mod);
+  mod->dwerr = mod->elferr;
+  if (mod->dwerr != DWFL_E_NOERROR)
+    return;
+
+  /* First see if the main ELF file has the debugging information.  */
+  mod->dwerr = load_dw (mod, &mod->main);
+  switch (mod->dwerr)
+    {
+    case DWFL_E_NOERROR:
+      mod->debug.elf = mod->main.elf;
+      mod->debug.address_sync = mod->main.address_sync;
+
+      /* The Dwarf might need an alt debug file, find that now after
+	 everything about the debug file has been setup (the
+	 find_debuginfo callback might need it).  */
+      find_debug_altlink (mod, mod->main.name);
+      return;
+
+    case DWFL_E_NO_DWARF:
+      break;
+
+    default:
+      goto canonicalize;
+    }
+
+  /* Now we have to look for a separate debuginfo file.  */
+  mod->dwerr = find_debuginfo (mod);
+  switch (mod->dwerr)
+    {
+    case DWFL_E_NOERROR:
+      mod->dwerr = load_dw (mod, &mod->debug);
+      if (mod->dwerr == DWFL_E_NOERROR)
+	{
+	  /* The Dwarf might need an alt debug file, find that now after
+	     everything about the debug file has been setup (the
+	     find_debuginfo callback might need it).  */
+	  find_debug_altlink (mod, mod->debug.name);
+	  return;
+	}
+
+      break;
+
+    case DWFL_E_CB:		/* The find_debuginfo hook failed.  */
+      mod->dwerr = DWFL_E_NO_DWARF;
+      return;
+
+    default:
+      break;
+    }
+
+ canonicalize:
+  mod->dwerr = __libdwfl_canon_error (mod->dwerr);
+}
+
+Dwarf *
+dwfl_module_getdwarf (Dwfl_Module *mod, Dwarf_Addr *bias)
+{
+  if (mod == NULL)
+    return NULL;
+
+  find_dw (mod);
+  if (mod->dwerr == DWFL_E_NOERROR)
+    {
+      /* If dwfl_module_getelf was used previously, then partial apply
+	 relocation to miscellaneous sections in the debug file too.  */
+      if (mod->e_type == ET_REL
+	  && mod->main.relocated && ! mod->debug.relocated)
+	{
+	  mod->debug.relocated = true;
+	  if (mod->debug.elf != mod->main.elf)
+	    (void) __libdwfl_relocate (mod, mod->debug.elf, false);
+	}
+
+      *bias = dwfl_adjusted_dwarf_addr (mod, 0);
+      return mod->dw;
+    }
+
+  __libdwfl_seterrno (mod->dwerr);
+  return NULL;
+}
+INTDEF (dwfl_module_getdwarf)
+
+int
+dwfl_module_getsymtab (Dwfl_Module *mod)
+{
+  if (mod == NULL)
+    return -1;
+
+  find_symtab (mod);
+  if (mod->symerr == DWFL_E_NOERROR)
+    /* We will skip the auxiliary zero entry if there is another one.  */
+    return (mod->syments + mod->aux_syments
+	    - (mod->syments > 0 && mod->aux_syments > 0 ? 1 : 0));
+
+  __libdwfl_seterrno (mod->symerr);
+  return -1;
+}
+INTDEF (dwfl_module_getsymtab)
+
+int
+dwfl_module_getsymtab_first_global (Dwfl_Module *mod)
+{
+  if (mod == NULL)
+    return -1;
+
+  find_symtab (mod);
+  if (mod->symerr == DWFL_E_NOERROR)
+    {
+      /* All local symbols should come before all global symbols.  If
+	 we have an auxiliary table make sure all the main locals come
+	 first, then all aux locals, then all main globals and finally all
+	 aux globals.  And skip the auxiliary table zero undefined
+	 entry.  */
+      int skip_aux_zero = (mod->syments > 0 && mod->aux_syments > 0) ? 1 : 0;
+      return mod->first_global + mod->aux_first_global - skip_aux_zero;
+    }
+
+  __libdwfl_seterrno (mod->symerr);
+  return -1;
+}
+INTDEF (dwfl_module_getsymtab_first_global)
diff --git a/third_party/elfutils/libdwfl/dwfl_module_getelf.c b/third_party/elfutils/libdwfl/dwfl_module_getelf.c
new file mode 100644
index 0000000..6358de4
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_getelf.c
@@ -0,0 +1,71 @@
+/* Find debugging and symbol information for a module in libdwfl.
+   Copyright (C) 2009-2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Elf *
+dwfl_module_getelf (Dwfl_Module *mod, GElf_Addr *loadbase)
+{
+  if (mod == NULL)
+    return NULL;
+
+  __libdwfl_getelf (mod);
+  if (mod->elferr == DWFL_E_NOERROR)
+    {
+      if (mod->e_type == ET_REL && ! mod->main.relocated)
+	{
+	  /* Before letting them get at the Elf handle,
+	     apply all the relocations we know how to.  */
+
+	  mod->main.relocated = true;
+	  if (likely (__libdwfl_module_getebl (mod) == DWFL_E_NOERROR))
+	    {
+	      (void) __libdwfl_relocate (mod, mod->main.elf, false);
+
+	      if (mod->debug.elf == mod->main.elf)
+		mod->debug.relocated = true;
+	      else if (mod->debug.elf != NULL && ! mod->debug.relocated)
+		{
+		  mod->debug.relocated = true;
+		  (void) __libdwfl_relocate (mod, mod->debug.elf, false);
+		}
+	    }
+	}
+
+      *loadbase = dwfl_adjusted_address (mod, 0);
+      return mod->main.elf;
+    }
+
+  __libdwfl_seterrno (mod->elferr);
+  return NULL;
+}
+INTDEF (dwfl_module_getelf)
diff --git a/third_party/elfutils/libdwfl/dwfl_module_getsrc.c b/third_party/elfutils/libdwfl/dwfl_module_getsrc.c
new file mode 100644
index 0000000..fc99b16
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_getsrc.c
@@ -0,0 +1,85 @@
+/* Find source location for PC address in module.
+   Copyright (C) 2005, 2008, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+
+Dwfl_Line *
+dwfl_module_getsrc (Dwfl_Module *mod, Dwarf_Addr addr)
+{
+  Dwarf_Addr bias;
+  if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL)
+    return NULL;
+
+  struct dwfl_cu *cu;
+  Dwfl_Error error = __libdwfl_addrcu (mod, addr, &cu);
+  if (likely (error == DWFL_E_NOERROR))
+    error = __libdwfl_cu_getsrclines (cu);
+  if (likely (error == DWFL_E_NOERROR))
+    {
+      Dwarf_Lines *lines = cu->die.cu->lines;
+      size_t nlines = lines->nlines;
+      if (nlines > 0)
+	{
+	  /* This is guaranteed for us by libdw read_srclines.  */
+	  assert(lines->info[nlines - 1].end_sequence);
+
+	  /* Now we look at the module-relative address.  */
+	  addr -= bias;
+
+	  /* The lines are sorted by address, so we can use binary search.  */
+	  size_t l = 0, u = nlines - 1;
+	  while (l < u)
+	    {
+	      size_t idx = u - (u - l) / 2;
+	      Dwarf_Line *line = &lines->info[idx];
+	      if (addr < line->addr)
+		u = idx - 1;
+	      else
+		l = idx;
+	    }
+
+	  /* The last line which is less than or equal to addr is what
+	     we want, unless it is the end_sequence which is after the
+	     current line sequence.  */
+	  Dwarf_Line *line = &lines->info[l];
+	  if (! line->end_sequence && line->addr <= addr)
+	    return &cu->lines->idx[l];
+	}
+
+      error = DWFL_E_ADDR_OUTOFRANGE;
+    }
+
+  __libdwfl_seterrno (error);
+  return NULL;
+}
+INTDEF (dwfl_module_getsrc)
diff --git a/third_party/elfutils/libdwfl/dwfl_module_getsrc_file.c b/third_party/elfutils/libdwfl/dwfl_module_getsrc_file.c
new file mode 100644
index 0000000..cea2ba4
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_getsrc_file.c
@@ -0,0 +1,178 @@
+/* Find matching source locations in a module.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+
+
+static inline const char *
+dwfl_dwarf_line_file (const Dwarf_Line *line)
+{
+  return line->files->info[line->file].name;
+}
+
+static inline Dwarf_Line *
+dwfl_line (const Dwfl_Line *line)
+{
+  return &dwfl_linecu (line)->die.cu->lines->info[line->idx];
+}
+
+static inline const char *
+dwfl_line_file (const Dwfl_Line *line)
+{
+  return dwfl_dwarf_line_file (dwfl_line (line));
+}
+
+int
+dwfl_module_getsrc_file (Dwfl_Module *mod,
+			 const char *fname, int lineno, int column,
+			 Dwfl_Line ***srcsp, size_t *nsrcs)
+{
+  if (mod == NULL)
+    return -1;
+
+  if (mod->dw == NULL)
+    {
+      Dwarf_Addr bias;
+      if (INTUSE(dwfl_module_getdwarf) (mod, &bias) == NULL)
+	return -1;
+    }
+
+  bool is_basename = strchr (fname, '/') == NULL;
+
+  size_t max_match = *nsrcs ?: ~0u;
+  size_t act_match = *nsrcs;
+  size_t cur_match = 0;
+  Dwfl_Line **match = *nsrcs == 0 ? NULL : *srcsp;
+
+  struct dwfl_cu *cu = NULL;
+  Dwfl_Error error;
+  while ((error = __libdwfl_nextcu (mod, cu, &cu)) == DWFL_E_NOERROR
+	 && cu != NULL
+	 && (error = __libdwfl_cu_getsrclines (cu)) == DWFL_E_NOERROR)
+    {
+      /* Search through all the line number records for a matching
+	 file and line/column number.  If any of the numbers is zero,
+	 no match is performed.  */
+      const char *lastfile = NULL;
+      bool lastmatch = false;
+      for (size_t cnt = 0; cnt < cu->die.cu->lines->nlines; ++cnt)
+	{
+	  Dwarf_Line *line = &cu->die.cu->lines->info[cnt];
+
+	  if (unlikely (line->file >= line->files->nfiles))
+	    {
+	      if (*nsrcs == 0)
+		free (match);
+	      __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_DWARF));
+	      return -1;
+	    }
+	  else
+	    {
+	      const char *file = dwfl_dwarf_line_file (line);
+	      if (file != lastfile)
+		{
+		  /* Match the name with the name the user provided.  */
+		  lastfile = file;
+		  lastmatch = !strcmp (is_basename ? basename (file) : file,
+				       fname);
+		}
+	    }
+	  if (!lastmatch)
+	    continue;
+
+	  /* See whether line and possibly column match.  */
+	  if (lineno != 0
+	      && (lineno > line->line
+		  || (column != 0 && column > line->column)))
+	    /* Cannot match.  */
+	    continue;
+
+	  /* Determine whether this is the best match so far.  */
+	  size_t inner;
+	  for (inner = 0; inner < cur_match; ++inner)
+	    if (dwfl_line_file (match[inner])
+		== dwfl_dwarf_line_file (line))
+	      break;
+	  if (inner < cur_match
+	      && (dwfl_line (match[inner])->line != line->line
+		  || dwfl_line (match[inner])->line != lineno
+		  || (column != 0
+		      && (dwfl_line (match[inner])->column != line->column
+			  || dwfl_line (match[inner])->column != column))))
+	    {
+	      /* We know about this file already.  If this is a better
+		 match for the line number, use it.  */
+	      if (dwfl_line (match[inner])->line >= line->line
+		  && (dwfl_line (match[inner])->line != line->line
+		      || dwfl_line (match[inner])->column >= line->column))
+		/* Use the new line.  Otherwise the old one.  */
+		match[inner] = &cu->lines->idx[cnt];
+	      continue;
+	    }
+
+	  if (cur_match < max_match)
+	    {
+	      if (cur_match == act_match)
+		{
+		  /* Enlarge the array for the results.  */
+		  act_match += 10;
+		  Dwfl_Line **newp = realloc (match,
+					      act_match
+					      * sizeof (Dwfl_Line *));
+		  if (newp == NULL)
+		    {
+		      free (match);
+		      __libdwfl_seterrno (DWFL_E_NOMEM);
+		      return -1;
+		    }
+		  match = newp;
+		}
+
+	      match[cur_match++] = &cu->lines->idx[cnt];
+	    }
+	}
+    }
+
+  if (cur_match > 0)
+    {
+      assert (*nsrcs == 0 || *srcsp == match);
+
+      *nsrcs = cur_match;
+      *srcsp = match;
+
+      return 0;
+    }
+
+  __libdwfl_seterrno (DWFL_E_NO_MATCH);
+  return -1;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_module_getsym.c b/third_party/elfutils/libdwfl/dwfl_module_getsym.c
new file mode 100644
index 0000000..8de9a3e
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_getsym.c
@@ -0,0 +1,220 @@
+/* Find debugging and symbol information for a module in libdwfl.
+   Copyright (C) 2006-2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+const char *
+internal_function
+__libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym *sym, GElf_Addr *addr,
+		  GElf_Word *shndxp, Elf **elfp, Dwarf_Addr *biasp,
+		  bool *resolved, bool adjust_st_value)
+{
+  if (unlikely (mod == NULL))
+    return NULL;
+
+  if (unlikely (mod->symdata == NULL))
+    {
+      int result = INTUSE(dwfl_module_getsymtab) (mod);
+      if (result < 0)
+	return NULL;
+    }
+
+  /* All local symbols should come before all global symbols.  If we
+     have an auxiliary table make sure all the main locals come first,
+     then all aux locals, then all main globals and finally all aux globals.
+     And skip the auxiliary table zero undefined entry.  */
+  GElf_Word shndx;
+  int tndx = ndx;
+  int skip_aux_zero = (mod->syments > 0 && mod->aux_syments > 0) ? 1 : 0;
+  Elf *elf;
+  Elf_Data *symdata;
+  Elf_Data *symxndxdata;
+  Elf_Data *symstrdata;
+  if (mod->aux_symdata == NULL
+      || ndx < mod->first_global)
+    {
+      /* main symbol table (locals).  */
+      tndx = ndx;
+      elf = mod->symfile->elf;
+      symdata = mod->symdata;
+      symxndxdata = mod->symxndxdata;
+      symstrdata = mod->symstrdata;
+    }
+  else if (ndx < mod->first_global + mod->aux_first_global - skip_aux_zero)
+    {
+      /* aux symbol table (locals).  */
+      tndx = ndx - mod->first_global + skip_aux_zero;
+      elf = mod->aux_sym.elf;
+      symdata = mod->aux_symdata;
+      symxndxdata = mod->aux_symxndxdata;
+      symstrdata = mod->aux_symstrdata;
+    }
+  else if ((size_t) ndx < mod->syments + mod->aux_first_global - skip_aux_zero)
+    {
+      /* main symbol table (globals).  */
+      tndx = ndx - mod->aux_first_global + skip_aux_zero;
+      elf = mod->symfile->elf;
+      symdata = mod->symdata;
+      symxndxdata = mod->symxndxdata;
+      symstrdata = mod->symstrdata;
+    }
+  else
+    {
+      /* aux symbol table (globals).  */
+      tndx = ndx - mod->syments + skip_aux_zero;
+      elf = mod->aux_sym.elf;
+      symdata = mod->aux_symdata;
+      symxndxdata = mod->aux_symxndxdata;
+      symstrdata = mod->aux_symstrdata;
+    }
+  sym = gelf_getsymshndx (symdata, symxndxdata, tndx, sym, &shndx);
+
+  if (unlikely (sym == NULL))
+    {
+      __libdwfl_seterrno (DWFL_E_LIBELF);
+      return NULL;
+    }
+
+  if (sym->st_shndx != SHN_XINDEX)
+    shndx = sym->st_shndx;
+
+  /* Figure out whether this symbol points into an SHF_ALLOC section.  */
+  bool alloc = true;
+  if ((shndxp != NULL || mod->e_type != ET_REL)
+      && (sym->st_shndx == SHN_XINDEX
+	  || (sym->st_shndx < SHN_LORESERVE && sym->st_shndx != SHN_UNDEF)))
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, shndx), &shdr_mem);
+      alloc = unlikely (shdr == NULL) || (shdr->sh_flags & SHF_ALLOC);
+    }
+
+  /* In case of an value in an allocated section the main Elf Ebl
+     might know where the real value is (e.g. for function
+     descriptors).  */
+
+  char *ident;
+  GElf_Addr st_value = sym->st_value & ebl_func_addr_mask (mod->ebl);
+  *resolved = false;
+  if (! adjust_st_value && mod->e_type != ET_REL && alloc
+      && (GELF_ST_TYPE (sym->st_info) == STT_FUNC
+	  || (GELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+	      && (ident = elf_getident (elf, NULL)) != NULL
+	      && ident[EI_OSABI] == ELFOSABI_LINUX)))
+    {
+      if (likely (__libdwfl_module_getebl (mod) == DWFL_E_NOERROR))
+	{
+	  if (elf != mod->main.elf)
+	    {
+	      st_value = dwfl_adjusted_st_value (mod, elf, st_value);
+	      st_value = dwfl_deadjust_st_value (mod, mod->main.elf, st_value);
+	    }
+
+	  *resolved = ebl_resolve_sym_value (mod->ebl, &st_value);
+	  if (! *resolved)
+	    st_value = sym->st_value;
+	}
+    }
+
+  if (shndxp != NULL)
+    /* Yield -1 in case of a non-SHF_ALLOC section.  */
+    *shndxp = alloc ? shndx : (GElf_Word) -1;
+
+  switch (sym->st_shndx)
+    {
+    case SHN_ABS:		/* XXX sometimes should use bias?? */
+    case SHN_UNDEF:
+    case SHN_COMMON:
+      break;
+
+    default:
+      if (mod->e_type == ET_REL)
+	{
+	  /* In an ET_REL file, the symbol table values are relative
+	     to the section, not to the module's load base.  */
+	  size_t symshstrndx = SHN_UNDEF;
+	  Dwfl_Error result = __libdwfl_relocate_value (mod, elf,
+							&symshstrndx,
+							shndx, &st_value);
+	  if (unlikely (result != DWFL_E_NOERROR))
+	    {
+	      __libdwfl_seterrno (result);
+	      return NULL;
+	    }
+	}
+      else if (alloc)
+	/* Apply the bias to the symbol value.  */
+	st_value = dwfl_adjusted_st_value (mod,
+					   *resolved ? mod->main.elf : elf,
+					   st_value);
+      break;
+    }
+
+  if (adjust_st_value)
+    sym->st_value = st_value;
+
+  if (addr != NULL)
+    *addr = st_value;
+
+  if (unlikely (sym->st_name >= symstrdata->d_size))
+    {
+      __libdwfl_seterrno (DWFL_E_BADSTROFF);
+      return NULL;
+    }
+  if (elfp)
+    *elfp = elf;
+  if (biasp)
+    *biasp = dwfl_adjusted_st_value (mod, elf, 0);
+  return (const char *) symstrdata->d_buf + sym->st_name;
+}
+
+const char *
+dwfl_module_getsym_info (Dwfl_Module *mod, int ndx,
+			 GElf_Sym *sym, GElf_Addr *addr,
+			 GElf_Word *shndxp,
+			 Elf **elfp, Dwarf_Addr *bias)
+{
+  bool resolved;
+  return __libdwfl_getsym (mod, ndx, sym, addr, shndxp, elfp, bias,
+			   &resolved, false);
+}
+INTDEF (dwfl_module_getsym_info)
+
+const char *
+dwfl_module_getsym (Dwfl_Module *mod, int ndx,
+		    GElf_Sym *sym, GElf_Word *shndxp)
+{
+  bool resolved;
+  return __libdwfl_getsym (mod, ndx, sym, NULL, shndxp, NULL, NULL,
+			   &resolved, true);
+}
+INTDEF (dwfl_module_getsym)
diff --git a/third_party/elfutils/libdwfl/dwfl_module_info.c b/third_party/elfutils/libdwfl/dwfl_module_info.c
new file mode 100644
index 0000000..af1faab
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_info.c
@@ -0,0 +1,65 @@
+/* Return information about a module.
+   Copyright (C) 2005-2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+const char *
+dwfl_module_info (Dwfl_Module *mod, void ***userdata,
+		  Dwarf_Addr *start, Dwarf_Addr *end,
+		  Dwarf_Addr *dwbias, Dwarf_Addr *symbias,
+		  const char **mainfile, const char **debugfile)
+{
+  if (mod == NULL)
+    return NULL;
+
+  if (userdata)
+    *userdata = &mod->userdata;
+  if (start)
+    *start = mod->low_addr;
+  if (end)
+    *end = mod->high_addr;
+
+  if (dwbias)
+    *dwbias = (mod->debug.elf == NULL ? (Dwarf_Addr) -1
+	       : dwfl_adjusted_dwarf_addr (mod, 0));
+  if (symbias)
+    *symbias = (mod->symfile == NULL ? (Dwarf_Addr) -1
+		: dwfl_adjusted_st_value (mod, mod->symfile->elf, 0));
+
+  if (mainfile)
+    *mainfile = mod->main.name;
+
+  if (debugfile)
+    *debugfile = mod->debug.name;
+
+  return mod->name;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_module_nextcu.c b/third_party/elfutils/libdwfl/dwfl_module_nextcu.c
new file mode 100644
index 0000000..32ee6bc
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_nextcu.c
@@ -0,0 +1,48 @@
+/* Iterate through DWARF compilation units in a module.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwarf_Die *
+dwfl_module_nextcu (Dwfl_Module *mod, Dwarf_Die *lastcu, Dwarf_Addr *bias)
+{
+  if (INTUSE(dwfl_module_getdwarf) (mod, bias) == NULL)
+    return NULL;
+
+  struct dwfl_cu *cu;
+  Dwfl_Error error = __libdwfl_nextcu (mod, (struct dwfl_cu *) lastcu, &cu);
+  if (likely (error == DWFL_E_NOERROR))
+    return &cu->die;		/* Same as a cast, so ok for null too.  */
+
+  __libdwfl_seterrno (error);
+  return NULL;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_module_register_names.c b/third_party/elfutils/libdwfl/dwfl_module_register_names.c
new file mode 100644
index 0000000..9ea0937
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_register_names.c
@@ -0,0 +1,82 @@
+/* Enumerate DWARF register numbers and their names.
+   Copyright (C) 2005, 2006 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+
+int
+dwfl_module_register_names (Dwfl_Module *mod,
+			    int (*func) (void *, int, const char *,
+					 const char *, const char *,
+					 int, int),
+			    void *arg)
+{
+  if (unlikely (mod == NULL))
+    return -1;
+
+  if (unlikely (mod->ebl == NULL))
+    {
+      Dwfl_Error error = __libdwfl_module_getebl (mod);
+      if (error != DWFL_E_NOERROR)
+	{
+	  __libdwfl_seterrno (error);
+	  return -1;
+	}
+    }
+
+  int nregs = ebl_register_info (mod->ebl, -1, NULL, 0,
+				 NULL, NULL, NULL, NULL);
+  int result = 0;
+  for (int regno = 0; regno < nregs && likely (result == 0); ++regno)
+    {
+      char name[32];
+      const char *setname = NULL;
+      const char *prefix = NULL;
+      int bits = -1;
+      int type = -1;
+      ssize_t len = ebl_register_info (mod->ebl, regno, name, sizeof name,
+				       &prefix, &setname, &bits, &type);
+      if (unlikely (len < 0))
+	{
+	  __libdwfl_seterrno (DWFL_E_LIBEBL);
+	  result = -1;
+	  break;
+	}
+      if (likely (len > 0))
+	{
+	  assert (len > 1);	/* Backend should never yield "".  */
+	  result = (*func) (arg, regno, setname, prefix, name, bits, type);
+	}
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_module_report_build_id.c b/third_party/elfutils/libdwfl/dwfl_module_report_build_id.c
new file mode 100644
index 0000000..31e17c8
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_report_build_id.c
@@ -0,0 +1,84 @@
+/* Report build ID information for a module.
+   Copyright (C) 2007, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+// XXX vs report changed module: punting old file
+int
+dwfl_module_report_build_id (Dwfl_Module *mod,
+			     const unsigned char *bits, size_t len,
+			     GElf_Addr vaddr)
+{
+  if (mod == NULL)
+    return -1;
+
+  if (mod->main.elf != NULL)
+    {
+      /* Once we know about a file, we won't take any lies about
+	 its contents.  The only permissible call is a no-op.  */
+
+      if ((size_t) mod->build_id_len == len
+	  && (mod->build_id_vaddr == vaddr || vaddr == 0)
+	  && !memcmp (bits, mod->build_id_bits, len))
+	return 0;
+
+      __libdwfl_seterrno (DWFL_E_ALREADY_ELF);
+      return -1;
+    }
+
+  if (vaddr != 0 && (vaddr < mod->low_addr || vaddr + len > mod->high_addr))
+    {
+      __libdwfl_seterrno (DWFL_E_ADDR_OUTOFRANGE);
+      return -1;
+    }
+
+  void *copy = NULL;
+  if (len > 0)
+    {
+      copy = malloc (len);
+      if (unlikely (copy == NULL))
+	{
+	  __libdwfl_seterrno (DWFL_E_NOMEM);
+	  return -1;
+	}
+      memcpy (copy, bits, len);
+    }
+
+  free (mod->build_id_bits);
+
+  mod->build_id_bits = copy;
+  mod->build_id_len = len;
+  mod->build_id_vaddr = vaddr;
+
+  return 0;
+}
+INTDEF (dwfl_module_report_build_id)
diff --git a/third_party/elfutils/libdwfl/dwfl_module_return_value_location.c b/third_party/elfutils/libdwfl/dwfl_module_return_value_location.c
new file mode 100644
index 0000000..ff6f56f
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_module_return_value_location.c
@@ -0,0 +1,66 @@
+/* Return location expression to find return value given a function type DIE.
+   Copyright (C) 2005, 2006 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+
+int
+dwfl_module_return_value_location (Dwfl_Module *mod, Dwarf_Die *functypedie,
+				   const Dwarf_Op **locops)
+{
+  if (mod == NULL)
+    return -1;
+
+  if (mod->ebl == NULL)
+    {
+      Dwfl_Error error = __libdwfl_module_getebl (mod);
+      if (error != DWFL_E_NOERROR)
+	{
+	  __libdwfl_seterrno (error);
+	  return -1;
+	}
+    }
+
+  int nops = ebl_return_value_location (mod->ebl, functypedie, locops);
+  if (unlikely (nops < 0))
+    {
+      if (nops == -1)
+	__libdwfl_seterrno (DWFL_E_LIBDW);
+      else if (nops == -2)
+	__libdwfl_seterrno (DWFL_E_WEIRD_TYPE);
+      else
+	__libdwfl_seterrno (DWFL_E_LIBEBL);
+      nops = -1;
+    }
+
+  return nops;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_nextcu.c b/third_party/elfutils/libdwfl/dwfl_nextcu.c
new file mode 100644
index 0000000..64bd521
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_nextcu.c
@@ -0,0 +1,86 @@
+/* Iterate through DWARF compilation units across all modules.
+   Copyright (C) 2005-2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwarf_Die *
+dwfl_nextcu (Dwfl *dwfl, Dwarf_Die *lastcu, Dwarf_Addr *bias)
+{
+  if (dwfl == NULL)
+    return NULL;
+
+  struct dwfl_cu *cu = (struct dwfl_cu *) lastcu;
+  Dwfl_Module *mod;
+
+  if (cu == NULL)
+    {
+      mod = dwfl->modulelist;
+      goto nextmod;
+    }
+  else
+    mod = cu->mod;
+
+  Dwfl_Error error;
+  do
+    {
+      error = __libdwfl_nextcu (mod, cu, &cu);
+      if (error != DWFL_E_NOERROR)
+	break;
+
+      if (cu != NULL)
+	{
+	  *bias = dwfl_adjusted_dwarf_addr (mod, 0);
+	  return &cu->die;
+	}
+
+      do
+	{
+	  mod = mod->next;
+
+	nextmod:
+	  if (mod == NULL)
+	    return NULL;
+
+	  if (mod->dwerr == DWFL_E_NOERROR
+	      && (mod->dw != NULL
+		  || INTUSE(dwfl_module_getdwarf) (mod, bias) != NULL))
+	    break;
+	}
+      while (mod->dwerr == DWFL_E_NO_DWARF);
+      error = mod->dwerr;
+    }
+  while (error == DWFL_E_NOERROR);
+
+  __libdwfl_seterrno (error);
+  return NULL;
+}
+INTDEF (dwfl_nextcu)
diff --git a/third_party/elfutils/libdwfl/dwfl_onesrcline.c b/third_party/elfutils/libdwfl/dwfl_onesrcline.c
new file mode 100644
index 0000000..b1e7055
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_onesrcline.c
@@ -0,0 +1,60 @@
+/* Return one of the sources lines of a CU.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+Dwfl_Line *
+dwfl_onesrcline (Dwarf_Die *cudie, size_t idx)
+{
+  struct dwfl_cu *cu = (struct dwfl_cu *) cudie;
+
+  if (cudie == NULL)
+    return NULL;
+
+  if (cu->lines == NULL)
+    {
+      Dwfl_Error error = __libdwfl_cu_getsrclines (cu);
+      if (error != DWFL_E_NOERROR)
+	{
+	  __libdwfl_seterrno (error);
+	  return NULL;
+	}
+    }
+
+  if (idx >= cu->die.cu->lines->nlines)
+    {
+      __libdwfl_seterrno (DWFL_E (LIBDW, DWARF_E_INVALID_LINE_IDX));
+      return NULL;
+    }
+
+  return &cu->lines->idx[idx];
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_report_elf.c b/third_party/elfutils/libdwfl/dwfl_report_elf.c
new file mode 100644
index 0000000..3fc9384
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_report_elf.c
@@ -0,0 +1,342 @@
+/* Report a module to libdwfl based on ELF program headers.
+   Copyright (C) 2005-2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <fcntl.h>
+#include <unistd.h>
+
+
+/* We start every ET_REL module at a moderately aligned boundary.
+   This keeps the low addresses easy to read compared to a layout
+   starting at 0 (as when using -e).  It also makes it unlikely
+   that a middle section will have a larger alignment and require
+   rejiggering (see below).  */
+#define REL_MIN_ALIGN	((GElf_Xword) 0x100)
+
+bool
+internal_function
+__libdwfl_elf_address_range (Elf *elf, GElf_Addr base, bool add_p_vaddr,
+			     bool sanity, GElf_Addr *vaddrp,
+			     GElf_Addr *address_syncp, GElf_Addr *startp,
+			     GElf_Addr *endp, GElf_Addr *biasp,
+			     GElf_Half *e_typep)
+{
+  GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+    elf_error:
+      __libdwfl_seterrno (DWFL_E_LIBELF);
+      return false;
+    }
+
+  GElf_Addr vaddr = 0;
+  GElf_Addr address_sync = 0;
+  GElf_Addr start = 0, end = 0, bias = 0;
+  switch (ehdr->e_type)
+    {
+    case ET_REL:
+      /* For a relocatable object, we do an arbitrary section layout.
+	 By updating the section header in place, we leave the layout
+	 information to be found by relocation.  */
+
+      start = end = base = (base + REL_MIN_ALIGN - 1) & -REL_MIN_ALIGN;
+
+      bool first = true;
+      Elf_Scn *scn = NULL;
+      while ((scn = elf_nextscn (elf, scn)) != NULL)
+	{
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (unlikely (shdr == NULL))
+	    goto elf_error;
+
+	  if (shdr->sh_flags & SHF_ALLOC)
+	    {
+	      const GElf_Xword align = shdr->sh_addralign ?: 1;
+	      const GElf_Addr next = (end + align - 1) & -align;
+	      if (shdr->sh_addr == 0
+		  /* Once we've started doing layout we have to do it all,
+		     unless we just layed out the first section at 0 when
+		     it already was at 0.  */
+		  || (bias == 0 && end > start && end != next))
+		{
+		  shdr->sh_addr = next;
+		  if (end == base)
+		    /* This is the first section assigned a location.
+		       Use its aligned address as the module's base.  */
+		    start = base = shdr->sh_addr;
+		  else if (unlikely (base & (align - 1)))
+		    {
+		      /* If BASE has less than the maximum alignment of
+			 any section, we eat more than the optimal amount
+			 of padding and so make the module's apparent
+			 size come out larger than it would when placed
+			 at zero.  So reset the layout with a better base.  */
+
+		      start = end = base = (base + align - 1) & -align;
+		      Elf_Scn *prev_scn = NULL;
+		      do
+			{
+			  prev_scn = elf_nextscn (elf, prev_scn);
+			  GElf_Shdr prev_shdr_mem;
+			  GElf_Shdr *prev_shdr = gelf_getshdr (prev_scn,
+							       &prev_shdr_mem);
+			  if (unlikely (prev_shdr == NULL))
+			    goto elf_error;
+			  if (prev_shdr->sh_flags & SHF_ALLOC)
+			    {
+			      const GElf_Xword prev_align
+				= prev_shdr->sh_addralign ?: 1;
+
+			      prev_shdr->sh_addr
+				= (end + prev_align - 1) & -prev_align;
+			      end = prev_shdr->sh_addr + prev_shdr->sh_size;
+
+			      if (unlikely (! gelf_update_shdr (prev_scn,
+								prev_shdr)))
+				goto elf_error;
+			    }
+			}
+		      while (prev_scn != scn);
+		      continue;
+		    }
+
+		  end = shdr->sh_addr + shdr->sh_size;
+		  if (likely (shdr->sh_addr != 0)
+		      && unlikely (! gelf_update_shdr (scn, shdr)))
+		    goto elf_error;
+		}
+	      else
+		{
+		  /* The address is already assigned.  Just track it.  */
+		  if (first || end < shdr->sh_addr + shdr->sh_size)
+		    end = shdr->sh_addr + shdr->sh_size;
+		  if (first || bias > shdr->sh_addr)
+		    /* This is the lowest address in the module.  */
+		    bias = shdr->sh_addr;
+
+		  if ((shdr->sh_addr - bias + base) & (align - 1))
+		    /* This section winds up misaligned using BASE.
+		       Adjust BASE upwards to make it congruent to
+		       the lowest section address in the file modulo ALIGN.  */
+		    base = (((base + align - 1) & -align)
+			    + (bias & (align - 1)));
+		}
+
+	      first = false;
+	    }
+	}
+
+      if (bias != 0)
+	{
+	  /* The section headers had nonzero sh_addr values.  The layout
+	     was already done.  We've just collected the total span.
+	     Now just compute the bias from the requested base.  */
+	  start = base;
+	  end = end - bias + start;
+	  bias = start - bias;
+	}
+      break;
+
+      /* Everything else has to have program headers.  */
+
+    case ET_EXEC:
+    case ET_CORE:
+      /* An assigned base address is meaningless for these.  */
+      base = 0;
+      add_p_vaddr = true;
+      FALLTHROUGH;
+    case ET_DYN:
+    default:;
+      size_t phnum;
+      if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
+	goto elf_error;
+      for (size_t i = 0; i < phnum; ++i)
+	{
+	  GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem);
+	  if (unlikely (ph == NULL))
+	    goto elf_error;
+	  if (ph->p_type == PT_LOAD)
+	    {
+	      vaddr = ph->p_vaddr & -ph->p_align;
+	      address_sync = ph->p_vaddr + ph->p_memsz;
+	      break;
+	    }
+	}
+      if (add_p_vaddr)
+	{
+	  start = base + vaddr;
+	  bias = base;
+	}
+      else
+	{
+	  start = base;
+	  bias = base - vaddr;
+	}
+
+      for (size_t i = phnum; i-- > 0;)
+	{
+	  GElf_Phdr phdr_mem, *ph = gelf_getphdr (elf, i, &phdr_mem);
+	  if (unlikely (ph == NULL))
+	    goto elf_error;
+	  if (ph->p_type == PT_LOAD
+	      && ph->p_vaddr + ph->p_memsz > 0)
+	    {
+	      end = bias + (ph->p_vaddr + ph->p_memsz);
+	      break;
+	    }
+	}
+
+      if (end == 0 && sanity)
+	{
+	  __libdwfl_seterrno (DWFL_E_NO_PHDR);
+	  return false;
+	}
+      break;
+    }
+  if (vaddrp)
+    *vaddrp = vaddr;
+  if (address_syncp)
+    *address_syncp = address_sync;
+  if (startp)
+    *startp = start;
+  if (endp)
+    *endp = end;
+  if (biasp)
+    *biasp = bias;
+  if (e_typep)
+    *e_typep = ehdr->e_type;
+  return true;
+}
+
+Dwfl_Module *
+internal_function
+__libdwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name,
+		      int fd, Elf *elf, GElf_Addr base, bool add_p_vaddr,
+		      bool sanity)
+{
+  GElf_Addr vaddr, address_sync, start, end, bias;
+  GElf_Half e_type;
+  if (! __libdwfl_elf_address_range (elf, base, add_p_vaddr, sanity, &vaddr,
+				     &address_sync, &start, &end, &bias,
+				     &e_type))
+    return NULL;
+  Dwfl_Module *m = INTUSE(dwfl_report_module) (dwfl, name, start, end);
+  if (m != NULL)
+    {
+      if (m->main.name == NULL)
+	{
+	  m->main.name = strdup (file_name);
+	  m->main.fd = fd;
+	}
+      else if ((fd >= 0 && m->main.fd != fd)
+	       || strcmp (m->main.name, file_name))
+	{
+	overlap:
+	  m->gc = true;
+	  __libdwfl_seterrno (DWFL_E_OVERLAP);
+	  return NULL;
+	}
+
+      /* Preinstall the open ELF handle for the module.  */
+      if (m->main.elf == NULL)
+	{
+	  m->main.elf = elf;
+	  m->main.vaddr = vaddr;
+	  m->main.address_sync = address_sync;
+	  m->main_bias = bias;
+	  m->e_type = e_type;
+	}
+      else
+	{
+	  elf_end (elf);
+	  if (m->main_bias != bias
+	      || m->main.vaddr != vaddr || m->main.address_sync != address_sync)
+	    goto overlap;
+	}
+    }
+  return m;
+}
+
+Dwfl_Module *
+dwfl_report_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
+		 GElf_Addr base, bool add_p_vaddr)
+{
+  bool closefd = false;
+  if (fd < 0)
+    {
+      closefd = true;
+      fd = open (file_name, O_RDONLY);
+      if (fd < 0)
+	{
+	  __libdwfl_seterrno (DWFL_E_ERRNO);
+	  return NULL;
+	}
+    }
+
+  Elf *elf;
+  Dwfl_Error error = __libdw_open_file (&fd, &elf, closefd, false);
+  if (error != DWFL_E_NOERROR)
+    {
+      __libdwfl_seterrno (error);
+      return NULL;
+    }
+
+  Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name,
+					   fd, elf, base, add_p_vaddr, true);
+  if (mod == NULL)
+    {
+      elf_end (elf);
+      if (closefd)
+	close (fd);
+    }
+
+  return mod;
+}
+INTDEF (dwfl_report_elf)
+NEW_VERSION (dwfl_report_elf, ELFUTILS_0.156)
+
+#ifdef SYMBOL_VERSIONING
+Dwfl_Module *
+  _compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name,
+					       const char *file_name, int fd,
+					       GElf_Addr base);
+COMPAT_VERSION_NEWPROTO (dwfl_report_elf, ELFUTILS_0.122, without_add_p_vaddr)
+
+Dwfl_Module *
+_compat_without_add_p_vaddr_dwfl_report_elf (Dwfl *dwfl, const char *name,
+					     const char *file_name, int fd,
+					     GElf_Addr base)
+{
+  return dwfl_report_elf (dwfl, name, file_name, fd, base, true);
+}
+#endif
diff --git a/third_party/elfutils/libdwfl/dwfl_segment_report_module.c b/third_party/elfutils/libdwfl/dwfl_segment_report_module.c
new file mode 100644
index 0000000..207a257
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_segment_report_module.c
@@ -0,0 +1,939 @@
+/* Sniff out modules from ELF headers visible in memory segments.
+   Copyright (C) 2008-2012, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include "../libelf/libelfP.h"	/* For NOTE_ALIGN.  */
+#undef	_
+#include "libdwflP.h"
+#include "common.h"
+
+#include <elf.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <endian.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <system.h>
+
+
+/* A good size for the initial read from memory, if it's not too costly.
+   This more than covers the phdrs and note segment in the average 64-bit
+   binary.  */
+
+#define INITIAL_READ	1024
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define MY_ELFDATA	ELFDATA2LSB
+#else
+# define MY_ELFDATA	ELFDATA2MSB
+#endif
+
+
+/* Return user segment index closest to ADDR but not above it.
+   If NEXT, return the closest to ADDR but not below it.  */
+static int
+addr_segndx (Dwfl *dwfl, size_t segment, GElf_Addr addr, bool next)
+{
+  int ndx = -1;
+  do
+    {
+      if (dwfl->lookup_segndx[segment] >= 0)
+	ndx = dwfl->lookup_segndx[segment];
+      if (++segment >= dwfl->lookup_elts - 1)
+	return next ? ndx + 1 : ndx;
+    }
+  while (dwfl->lookup_addr[segment] < addr);
+
+  if (next)
+    {
+      while (dwfl->lookup_segndx[segment] < 0)
+	if (++segment >= dwfl->lookup_elts - 1)
+	  return ndx + 1;
+      ndx = dwfl->lookup_segndx[segment];
+    }
+
+  return ndx;
+}
+
+/* Return whether there is SZ bytes available at PTR till END.  */
+
+static bool
+buf_has_data (const void *ptr, const void *end, size_t sz)
+{
+  return ptr < end && (size_t) (end - ptr) >= sz;
+}
+
+/* Read SZ bytes into *RETP from *PTRP (limited by END) in format EI_DATA.
+   Function comes from src/readelf.c .  */
+
+static bool
+buf_read_ulong (unsigned char ei_data, size_t sz,
+		const void **ptrp, const void *end, uint64_t *retp)
+{
+  if (! buf_has_data (*ptrp, end, sz))
+    return false;
+
+  union
+  {
+    uint64_t u64;
+    uint32_t u32;
+  } u;
+
+  memcpy (&u, *ptrp, sz);
+  (*ptrp) += sz;
+
+  if (retp == NULL)
+    return true;
+
+  if (MY_ELFDATA != ei_data)
+    {
+      if (sz == 4)
+	CONVERT (u.u32);
+      else
+	CONVERT (u.u64);
+    }
+  if (sz == 4)
+    *retp = u.u32;
+  else
+    *retp = u.u64;
+  return true;
+}
+
+/* Try to find matching entry for module from address MODULE_START to
+   MODULE_END in NT_FILE note located at NOTE_FILE of NOTE_FILE_SIZE
+   bytes in format EI_CLASS and EI_DATA.  */
+
+static const char *
+handle_file_note (GElf_Addr module_start, GElf_Addr module_end,
+		  unsigned char ei_class, unsigned char ei_data,
+		  const void *note_file, size_t note_file_size)
+{
+  if (note_file == NULL)
+    return NULL;
+
+  size_t sz;
+  switch (ei_class)
+    {
+    case ELFCLASS32:
+      sz = 4;
+      break;
+    case ELFCLASS64:
+      sz = 8;
+      break;
+    default:
+      return NULL;
+    }
+
+  const void *ptr = note_file;
+  const void *end = note_file + note_file_size;
+  uint64_t count;
+  if (! buf_read_ulong (ei_data, sz, &ptr, end, &count))
+    return NULL;
+  if (! buf_read_ulong (ei_data, sz, &ptr, end, NULL)) // page_size
+    return NULL;
+
+  uint64_t maxcount = (size_t) (end - ptr) / (3 * sz);
+  if (count > maxcount)
+    return NULL;
+
+  /* Where file names are stored.  */
+  const char *fptr = ptr + 3 * count * sz;
+
+  ssize_t firstix = -1;
+  ssize_t lastix = -1;
+  for (size_t mix = 0; mix < count; mix++)
+    {
+      uint64_t mstart, mend, moffset;
+      if (! buf_read_ulong (ei_data, sz, &ptr, fptr, &mstart)
+	  || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &mend)
+	  || ! buf_read_ulong (ei_data, sz, &ptr, fptr, &moffset))
+	return NULL;
+      if (mstart == module_start && moffset == 0)
+	firstix = lastix = mix;
+      if (firstix != -1 && mstart < module_end)
+	lastix = mix;
+      if (mend >= module_end)
+	break;
+    }
+  if (firstix == -1)
+    return NULL;
+
+  const char *retval = NULL;
+  for (ssize_t mix = 0; mix <= lastix; mix++)
+    {
+      const char *fnext = memchr (fptr, 0, (const char *) end - fptr);
+      if (fnext == NULL)
+	return NULL;
+      if (mix == firstix)
+	retval = fptr;
+      if (firstix < mix && mix <= lastix && strcmp (fptr, retval) != 0)
+	return NULL;
+      fptr = fnext + 1;
+    }
+  return retval;
+}
+
+/* Return true iff we are certain ELF cannot match BUILD_ID of
+   BUILD_ID_LEN bytes.  Pass DISK_FILE_HAS_BUILD_ID as false if it is
+   certain ELF does not contain build-id (it is only a performance hit
+   to pass it always as true).  */
+
+static bool
+invalid_elf (Elf *elf, bool disk_file_has_build_id,
+	     const void *build_id, size_t build_id_len)
+{
+  if (! disk_file_has_build_id && build_id_len > 0)
+    {
+      /* Module found in segments with build-id is more reliable
+	 than a module found via DT_DEBUG on disk without any
+	 build-id.   */
+      return true;
+    }
+  if (disk_file_has_build_id && build_id_len > 0)
+    {
+      const void *elf_build_id;
+      ssize_t elf_build_id_len;
+
+      /* If there is a build id in the elf file, check it.  */
+      elf_build_id_len = INTUSE(dwelf_elf_gnu_build_id) (elf, &elf_build_id);
+      if (elf_build_id_len > 0)
+	{
+	  if (build_id_len != (size_t) elf_build_id_len
+	      || memcmp (build_id, elf_build_id, build_id_len) != 0)
+	    return true;
+	}
+    }
+  return false;
+}
+
+int
+dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
+			    Dwfl_Memory_Callback *memory_callback,
+			    void *memory_callback_arg,
+			    Dwfl_Module_Callback *read_eagerly,
+			    void *read_eagerly_arg,
+			    const void *note_file, size_t note_file_size,
+			    const struct r_debug_info *r_debug_info)
+{
+  size_t segment = ndx;
+
+  if (segment >= dwfl->lookup_elts)
+    segment = dwfl->lookup_elts - 1;
+
+  while (segment > 0
+	 && (dwfl->lookup_segndx[segment] > ndx
+	     || dwfl->lookup_segndx[segment] == -1))
+    --segment;
+
+  while (dwfl->lookup_segndx[segment] < ndx)
+    if (++segment == dwfl->lookup_elts)
+      return 0;
+
+  GElf_Addr start = dwfl->lookup_addr[segment];
+
+  inline bool segment_read (int segndx,
+			    void **buffer, size_t *buffer_available,
+			    GElf_Addr addr, size_t minread)
+  {
+    return ! (*memory_callback) (dwfl, segndx, buffer, buffer_available,
+				 addr, minread, memory_callback_arg);
+  }
+
+  inline void release_buffer (void **buffer, size_t *buffer_available)
+  {
+    if (*buffer != NULL)
+      (void) segment_read (-1, buffer, buffer_available, 0, 0);
+  }
+
+  /* First read in the file header and check its sanity.  */
+
+  void *buffer = NULL;
+  size_t buffer_available = INITIAL_READ;
+  Elf *elf = NULL;
+  int fd = -1;
+
+  /* We might have to reserve some memory for the phdrs.  Set to NULL
+     here so we can always safely free it.  */
+  void *phdrsp = NULL;
+
+  inline int finish (void)
+  {
+    free (phdrsp);
+    release_buffer (&buffer, &buffer_available);
+    if (elf != NULL)
+      elf_end (elf);
+    if (fd != -1)
+      close (fd);
+    return ndx;
+  }
+
+  if (segment_read (ndx, &buffer, &buffer_available,
+		    start, sizeof (Elf64_Ehdr))
+      || memcmp (buffer, ELFMAG, SELFMAG) != 0)
+    return finish ();
+
+  inline bool read_portion (void **data, size_t *data_size,
+			    GElf_Addr vaddr, size_t filesz)
+  {
+    if (vaddr - start + filesz > buffer_available
+	/* If we're in string mode, then don't consider the buffer we have
+	   sufficient unless it contains the terminator of the string.  */
+	|| (filesz == 0 && memchr (vaddr - start + buffer, '\0',
+				   buffer_available - (vaddr - start)) == NULL))
+      {
+	*data = NULL;
+	*data_size = filesz;
+	return segment_read (addr_segndx (dwfl, segment, vaddr, false),
+			     data, data_size, vaddr, filesz);
+      }
+
+    /* We already have this whole note segment from our initial read.  */
+    *data = vaddr - start + buffer;
+    *data_size = 0;
+    return false;
+  }
+
+  inline void finish_portion (void **data, size_t *data_size)
+  {
+    if (*data_size != 0)
+      release_buffer (data, data_size);
+  }
+
+  /* Extract the information we need from the file header.  */
+  const unsigned char *e_ident;
+  unsigned char ei_class;
+  unsigned char ei_data;
+  uint16_t e_type;
+  union
+  {
+    Elf32_Ehdr e32;
+    Elf64_Ehdr e64;
+  } ehdr;
+  GElf_Off phoff;
+  uint_fast16_t phnum;
+  uint_fast16_t phentsize;
+  GElf_Off shdrs_end;
+  Elf_Data xlatefrom =
+    {
+      .d_type = ELF_T_EHDR,
+      .d_buf = (void *) buffer,
+      .d_version = EV_CURRENT,
+    };
+  Elf_Data xlateto =
+    {
+      .d_type = ELF_T_EHDR,
+      .d_buf = &ehdr,
+      .d_size = sizeof ehdr,
+      .d_version = EV_CURRENT,
+    };
+  e_ident = ((const unsigned char *) buffer);
+  ei_class = e_ident[EI_CLASS];
+  ei_data = e_ident[EI_DATA];
+  switch (ei_class)
+    {
+    case ELFCLASS32:
+      xlatefrom.d_size = sizeof (Elf32_Ehdr);
+      if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
+	return finish ();
+      e_type = ehdr.e32.e_type;
+      phoff = ehdr.e32.e_phoff;
+      phnum = ehdr.e32.e_phnum;
+      phentsize = ehdr.e32.e_phentsize;
+      if (phentsize != sizeof (Elf32_Phdr))
+	return finish ();
+      shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
+      break;
+
+    case ELFCLASS64:
+      xlatefrom.d_size = sizeof (Elf64_Ehdr);
+      if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
+	return finish ();
+      e_type = ehdr.e64.e_type;
+      phoff = ehdr.e64.e_phoff;
+      phnum = ehdr.e64.e_phnum;
+      phentsize = ehdr.e64.e_phentsize;
+      if (phentsize != sizeof (Elf64_Phdr))
+	return finish ();
+      shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
+      break;
+
+    default:
+      return finish ();
+    }
+
+  /* The file header tells where to find the program headers.
+     These are what we need to find the boundaries of the module.
+     Without them, we don't have a module to report.  */
+
+  if (phnum == 0)
+    return finish ();
+
+  xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
+  xlatefrom.d_size = phnum * phentsize;
+
+  void *ph_buffer = NULL;
+  size_t ph_buffer_size = 0;
+  if (read_portion (&ph_buffer, &ph_buffer_size,
+		    start + phoff, xlatefrom.d_size))
+    return finish ();
+
+  xlatefrom.d_buf = ph_buffer;
+
+  bool class32 = ei_class == ELFCLASS32;
+  size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
+  if (unlikely (phnum > SIZE_MAX / phdr_size))
+    return finish ();
+  const size_t phdrsp_bytes = phnum * phdr_size;
+  phdrsp = malloc (phdrsp_bytes);
+  if (unlikely (phdrsp == NULL))
+    return finish ();
+
+  xlateto.d_buf = phdrsp;
+  xlateto.d_size = phdrsp_bytes;
+
+  /* Track the bounds of the file visible in memory.  */
+  GElf_Off file_trimmed_end = 0; /* Proper p_vaddr + p_filesz end.  */
+  GElf_Off file_end = 0;	 /* Rounded up to effective page size.  */
+  GElf_Off contiguous = 0;	 /* Visible as contiguous file from START.  */
+  GElf_Off total_filesz = 0;	 /* Total size of data to read.  */
+
+  /* Collect the bias between START and the containing PT_LOAD's p_vaddr.  */
+  GElf_Addr bias = 0;
+  bool found_bias = false;
+
+  /* Collect the unbiased bounds of the module here.  */
+  GElf_Addr module_start = -1l;
+  GElf_Addr module_end = 0;
+  GElf_Addr module_address_sync = 0;
+
+  /* If we see PT_DYNAMIC, record it here.  */
+  GElf_Addr dyn_vaddr = 0;
+  GElf_Xword dyn_filesz = 0;
+
+  /* Collect the build ID bits here.  */
+  void *build_id = NULL;
+  size_t build_id_len = 0;
+  GElf_Addr build_id_vaddr = 0;
+
+  /* Consider a PT_NOTE we've found in the image.  */
+  inline void consider_notes (GElf_Addr vaddr, GElf_Xword filesz)
+  {
+    /* If we have already seen a build ID, we don't care any more.  */
+    if (build_id != NULL || filesz == 0)
+      return;
+
+    void *data;
+    size_t data_size;
+    if (read_portion (&data, &data_size, vaddr, filesz))
+      return;
+
+    assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
+
+    void *notes;
+    if (ei_data == MY_ELFDATA)
+      notes = data;
+    else
+      {
+	notes = malloc (filesz);
+	if (unlikely (notes == NULL))
+	  return;
+	xlatefrom.d_type = xlateto.d_type = ELF_T_NHDR;
+	xlatefrom.d_buf = (void *) data;
+	xlatefrom.d_size = filesz;
+	xlateto.d_buf = notes;
+	xlateto.d_size = filesz;
+	if (elf32_xlatetom (&xlateto, &xlatefrom,
+			    ehdr.e32.e_ident[EI_DATA]) == NULL)
+	  goto done;
+      }
+
+    const GElf_Nhdr *nh = notes;
+    while ((const void *) nh < (const void *) notes + filesz)
+     {
+	const void *note_name = nh + 1;
+	const void *note_desc = note_name + NOTE_ALIGN (nh->n_namesz);
+	if (unlikely ((size_t) ((const void *) notes + filesz
+				- note_desc) < nh->n_descsz))
+	  break;
+
+	if (nh->n_type == NT_GNU_BUILD_ID
+	    && nh->n_descsz > 0
+	    && nh->n_namesz == sizeof "GNU"
+	    && !memcmp (note_name, "GNU", sizeof "GNU"))
+	  {
+	    build_id_vaddr = note_desc - (const void *) notes + vaddr;
+	    build_id_len = nh->n_descsz;
+	    build_id = malloc (nh->n_descsz);
+	    if (likely (build_id != NULL))
+	      memcpy (build_id, note_desc, build_id_len);
+	    break;
+	  }
+
+	nh = note_desc + NOTE_ALIGN (nh->n_descsz);
+      }
+
+  done:
+    if (notes != data)
+      free (notes);
+    finish_portion (&data, &data_size);
+  }
+
+  /* Consider each of the program headers we've read from the image.  */
+  inline void consider_phdr (GElf_Word type,
+			     GElf_Addr vaddr, GElf_Xword memsz,
+			     GElf_Off offset, GElf_Xword filesz,
+			     GElf_Xword align)
+  {
+    switch (type)
+      {
+      case PT_DYNAMIC:
+	dyn_vaddr = vaddr;
+	dyn_filesz = filesz;
+	break;
+
+      case PT_NOTE:
+	/* We calculate from the p_offset of the note segment,
+	   because we don't yet know the bias for its p_vaddr.  */
+	consider_notes (start + offset, filesz);
+	break;
+
+      case PT_LOAD:
+	align = dwfl->segment_align > 1 ? dwfl->segment_align : align ?: 1;
+
+	GElf_Addr vaddr_end = (vaddr + memsz + align - 1) & -align;
+	GElf_Addr filesz_vaddr = filesz < memsz ? vaddr + filesz : vaddr_end;
+	GElf_Off filesz_offset = filesz_vaddr - vaddr + offset;
+
+	if (file_trimmed_end < offset + filesz)
+	  {
+	    file_trimmed_end = offset + filesz;
+
+	    /* Trim the last segment so we don't bother with zeros
+	       in the last page that are off the end of the file.
+	       However, if the extra bit in that page includes the
+	       section headers, keep them.  */
+	    if (shdrs_end <= filesz_offset && shdrs_end > file_trimmed_end)
+	      {
+		filesz += shdrs_end - file_trimmed_end;
+		file_trimmed_end = shdrs_end;
+	      }
+	  }
+
+	total_filesz += filesz;
+
+	if (file_end < filesz_offset)
+	  {
+	    file_end = filesz_offset;
+	    if (filesz_vaddr - start == filesz_offset)
+	      contiguous = file_end;
+	  }
+
+	if (!found_bias && (offset & -align) == 0
+	    && likely (filesz_offset >= phoff + phnum * phentsize))
+	  {
+	    bias = start - vaddr;
+	    found_bias = true;
+	  }
+
+	if ((vaddr & -align) < module_start)
+	  {
+	    module_start = vaddr & -align;
+	    module_address_sync = vaddr + memsz;
+	  }
+
+	if (module_end < vaddr_end)
+	  module_end = vaddr_end;
+	break;
+      }
+  }
+
+  Elf32_Phdr (*p32)[phnum] = phdrsp;
+  Elf64_Phdr (*p64)[phnum] = phdrsp;
+  if (ei_class == ELFCLASS32)
+    {
+      if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
+	found_bias = false;	/* Trigger error check.  */
+      else
+	for (uint_fast16_t i = 0; i < phnum; ++i)
+	  consider_phdr ((*p32)[i].p_type,
+			 (*p32)[i].p_vaddr, (*p32)[i].p_memsz,
+			 (*p32)[i].p_offset, (*p32)[i].p_filesz,
+			 (*p32)[i].p_align);
+    }
+  else
+    {
+      if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) == NULL)
+	found_bias = false;	/* Trigger error check.  */
+      else
+	for (uint_fast16_t i = 0; i < phnum; ++i)
+	  consider_phdr ((*p64)[i].p_type,
+			 (*p64)[i].p_vaddr, (*p64)[i].p_memsz,
+			 (*p64)[i].p_offset, (*p64)[i].p_filesz,
+			 (*p64)[i].p_align);
+    }
+
+  finish_portion (&ph_buffer, &ph_buffer_size);
+
+  /* We must have seen the segment covering offset 0, or else the ELF
+     header we read at START was not produced by these program headers.  */
+  if (unlikely (!found_bias))
+    {
+      free (build_id);
+      return finish ();
+    }
+
+  /* Now we know enough to report a module for sure: its bounds.  */
+  module_start += bias;
+  module_end += bias;
+
+  dyn_vaddr += bias;
+
+  /* NAME found from link map has precedence over DT_SONAME possibly read
+     below.  */
+  bool name_is_final = false;
+
+  /* Try to match up DYN_VADDR against L_LD as found in link map.
+     Segments sniffing may guess invalid address as the first read-only memory
+     mapping may not be dumped to the core file (if ELF headers are not dumped)
+     and the ELF header is dumped first with the read/write mapping of the same
+     file at higher addresses.  */
+  if (r_debug_info != NULL)
+    for (const struct r_debug_info_module *module = r_debug_info->module;
+	 module != NULL; module = module->next)
+      if (module_start <= module->l_ld && module->l_ld < module_end)
+	{
+	  /* L_LD read from link map must be right while DYN_VADDR is unsafe.
+	     Therefore subtract DYN_VADDR and add L_LD to get a possibly
+	     corrective displacement for all addresses computed so far.  */
+	  GElf_Addr fixup = module->l_ld - dyn_vaddr;
+	  if ((fixup & (dwfl->segment_align - 1)) == 0
+	      && module_start + fixup <= module->l_ld
+	      && module->l_ld < module_end + fixup)
+	    {
+	      module_start += fixup;
+	      module_end += fixup;
+	      dyn_vaddr += fixup;
+	      bias += fixup;
+	      if (module->name[0] != '\0')
+		{
+		  name = basename (module->name);
+		  name_is_final = true;
+		}
+	      break;
+	    }
+	}
+
+  if (r_debug_info != NULL)
+    {
+      bool skip_this_module = false;
+      for (struct r_debug_info_module *module = r_debug_info->module;
+	   module != NULL; module = module->next)
+	if ((module_end > module->start && module_start < module->end)
+	    || dyn_vaddr == module->l_ld)
+	  {
+	    if (module->elf != NULL
+	        && invalid_elf (module->elf, module->disk_file_has_build_id,
+				build_id, build_id_len))
+	      {
+		elf_end (module->elf);
+		close (module->fd);
+		module->elf = NULL;
+		module->fd = -1;
+	      }
+	    if (module->elf != NULL)
+	      {
+		/* Ignore this found module if it would conflict in address
+		   space with any already existing module of DWFL.  */
+		skip_this_module = true;
+	      }
+	  }
+      if (skip_this_module)
+	{
+	  free (build_id);
+	  return finish ();
+	}
+    }
+
+  const char *file_note_name = handle_file_note (module_start, module_end,
+						 ei_class, ei_data,
+						 note_file, note_file_size);
+  if (file_note_name)
+    {
+      name = file_note_name;
+      name_is_final = true;
+      bool invalid = false;
+      fd = open (name, O_RDONLY);
+      if (fd >= 0)
+	{
+	  Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false);
+	  if (error == DWFL_E_NOERROR)
+	    invalid = invalid_elf (elf, true /* disk_file_has_build_id */,
+				   build_id, build_id_len);
+	}
+      if (invalid)
+	{
+	  /* The file was there, but the build_id didn't match.  We
+	     still want to report the module, but need to get the ELF
+	     some other way if possible.  */
+	  close (fd);
+	  fd = -1;
+	  elf_end (elf);
+	  elf = NULL;
+	}
+    }
+
+  /* Our return value now says to skip the segments contained
+     within the module.  */
+  ndx = addr_segndx (dwfl, segment, module_end, true);
+
+  /* Examine its .dynamic section to get more interesting details.
+     If it has DT_SONAME, we'll use that as the module name.
+     If it has a DT_DEBUG, then it's actually a PIE rather than a DSO.
+     We need its DT_STRTAB and DT_STRSZ to decipher DT_SONAME,
+     and they also tell us the essential portion of the file
+     for fetching symbols.  */
+  GElf_Addr soname_stroff = 0;
+  GElf_Addr dynstr_vaddr = 0;
+  GElf_Xword dynstrsz = 0;
+  bool execlike = false;
+  inline bool consider_dyn (GElf_Sxword tag, GElf_Xword val)
+  {
+    switch (tag)
+      {
+      default:
+	return false;
+
+      case DT_DEBUG:
+	execlike = true;
+	break;
+
+      case DT_SONAME:
+	soname_stroff = val;
+	break;
+
+      case DT_STRTAB:
+	dynstr_vaddr = val;
+	break;
+
+      case DT_STRSZ:
+	dynstrsz = val;
+	break;
+      }
+
+    return soname_stroff != 0 && dynstr_vaddr != 0 && dynstrsz != 0;
+  }
+
+  const size_t dyn_entsize = (ei_class == ELFCLASS32
+			      ? sizeof (Elf32_Dyn) : sizeof (Elf64_Dyn));
+  void *dyn_data = NULL;
+  size_t dyn_data_size = 0;
+  if (dyn_filesz != 0 && dyn_filesz % dyn_entsize == 0
+      && ! read_portion (&dyn_data, &dyn_data_size, dyn_vaddr, dyn_filesz))
+    {
+      void *dyns = malloc (dyn_filesz);
+      Elf32_Dyn (*d32)[dyn_filesz / sizeof (Elf32_Dyn)] = dyns;
+      Elf64_Dyn (*d64)[dyn_filesz / sizeof (Elf64_Dyn)] = dyns;
+      if (unlikely (dyns == NULL))
+	return finish ();
+
+      xlatefrom.d_type = xlateto.d_type = ELF_T_DYN;
+      xlatefrom.d_buf = (void *) dyn_data;
+      xlatefrom.d_size = dyn_filesz;
+      xlateto.d_buf = dyns;
+      xlateto.d_size = dyn_filesz;
+
+      if (ei_class == ELFCLASS32)
+	{
+	  if (elf32_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
+	    for (size_t i = 0; i < dyn_filesz / sizeof (Elf32_Dyn); ++i)
+	      if (consider_dyn ((*d32)[i].d_tag, (*d32)[i].d_un.d_val))
+		break;
+	}
+      else
+	{
+	  if (elf64_xlatetom (&xlateto, &xlatefrom, ei_data) != NULL)
+	    for (size_t i = 0; i < dyn_filesz / sizeof (Elf64_Dyn); ++i)
+	      if (consider_dyn ((*d64)[i].d_tag, (*d64)[i].d_un.d_val))
+		break;
+	}
+      free (dyns);
+    }
+  finish_portion (&dyn_data, &dyn_data_size);
+
+  /* We'll use the name passed in or a stupid default if not DT_SONAME.  */
+  if (name == NULL)
+    name = e_type == ET_EXEC ? "[exe]" : execlike ? "[pie]" : "[dso]";
+
+  void *soname = NULL;
+  size_t soname_size = 0;
+  if (! name_is_final && dynstrsz != 0 && dynstr_vaddr != 0)
+    {
+      /* We know the bounds of the .dynstr section.
+
+	 The DYNSTR_VADDR pointer comes from the .dynamic section
+	 (DT_STRTAB, detected above).  Ordinarily the dynamic linker
+	 will have adjusted this pointer in place so it's now an
+	 absolute address.  But sometimes .dynamic is read-only (in
+	 vDSOs and odd architectures), and sometimes the adjustment
+	 just hasn't happened yet in the memory image we looked at.
+	 So treat DYNSTR_VADDR as an absolute address if it falls
+	 within the module bounds, or try applying the phdr bias
+	 when that adjusts it to fall within the module bounds.  */
+
+      if ((dynstr_vaddr < module_start || dynstr_vaddr >= module_end)
+	  && dynstr_vaddr + bias >= module_start
+	  && dynstr_vaddr + bias < module_end)
+	dynstr_vaddr += bias;
+
+      if (unlikely (dynstr_vaddr + dynstrsz > module_end))
+	dynstrsz = 0;
+
+      /* Try to get the DT_SONAME string.  */
+      if (soname_stroff != 0 && soname_stroff + 1 < dynstrsz
+	  && ! read_portion (&soname, &soname_size,
+			     dynstr_vaddr + soname_stroff, 0))
+	name = soname;
+    }
+
+  /* Now that we have chosen the module's name and bounds, report it.
+     If we found a build ID, report that too.  */
+
+  Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, name,
+						 module_start, module_end);
+
+  // !execlike && ET_EXEC is PIE.
+  // execlike && !ET_EXEC is a static executable.
+  if (mod != NULL && (execlike || ehdr.e32.e_type == ET_EXEC))
+    mod->is_executable = true;
+
+  if (likely (mod != NULL) && build_id != NULL
+      && unlikely (INTUSE(dwfl_module_report_build_id) (mod,
+							build_id,
+							build_id_len,
+							build_id_vaddr)))
+    {
+      mod->gc = true;
+      mod = NULL;
+    }
+
+  /* At this point we do not need BUILD_ID or NAME any more.
+     They have been copied.  */
+  free (build_id);
+  finish_portion (&soname, &soname_size);
+
+  if (unlikely (mod == NULL))
+    {
+      ndx = -1;
+      return finish ();
+    }
+
+  /* We have reported the module.  Now let the caller decide whether we
+     should read the whole thing in right now.  */
+
+  const GElf_Off cost = (contiguous < file_trimmed_end ? total_filesz
+			 : buffer_available >= contiguous ? 0
+			 : contiguous - buffer_available);
+  const GElf_Off worthwhile = ((dynstr_vaddr == 0 || dynstrsz == 0) ? 0
+			       : dynstr_vaddr + dynstrsz - start);
+  const GElf_Off whole = MAX (file_trimmed_end, shdrs_end);
+
+  if (elf == NULL
+      && (*read_eagerly) (MODCB_ARGS (mod), &buffer, &buffer_available,
+			  cost, worthwhile, whole, contiguous,
+			  read_eagerly_arg, &elf)
+      && elf == NULL)
+    {
+      /* The caller wants to read the whole file in right now, but hasn't
+	 done it for us.  Fill in a local image of the virtual file.  */
+
+      void *contents = calloc (1, file_trimmed_end);
+      if (unlikely (contents == NULL))
+	return finish ();
+
+      inline void final_read (size_t offset, GElf_Addr vaddr, size_t size)
+      {
+	void *into = contents + offset;
+	size_t read_size = size;
+	(void) segment_read (addr_segndx (dwfl, segment, vaddr, false),
+			     &into, &read_size, vaddr, size);
+      }
+
+      if (contiguous < file_trimmed_end)
+	{
+	  /* We can't use the memory image verbatim as the file image.
+	     So we'll be reading into a local image of the virtual file.  */
+
+	  inline void read_phdr (GElf_Word type, GElf_Addr vaddr,
+				 GElf_Off offset, GElf_Xword filesz)
+	  {
+	    if (type == PT_LOAD)
+	      final_read (offset, vaddr + bias, filesz);
+	  }
+
+	  if (ei_class == ELFCLASS32)
+	    for (uint_fast16_t i = 0; i < phnum; ++i)
+	      read_phdr ((*p32)[i].p_type, (*p32)[i].p_vaddr,
+			 (*p32)[i].p_offset, (*p32)[i].p_filesz);
+	  else
+	    for (uint_fast16_t i = 0; i < phnum; ++i)
+	      read_phdr ((*p64)[i].p_type, (*p64)[i].p_vaddr,
+			 (*p64)[i].p_offset, (*p64)[i].p_filesz);
+	}
+      else
+	{
+	  /* The whole file sits contiguous in memory,
+	     but the caller didn't want to just do it.  */
+
+	  const size_t have = MIN (buffer_available, file_trimmed_end);
+	  memcpy (contents, buffer, have);
+
+	  if (have < file_trimmed_end)
+	    final_read (have, start + have, file_trimmed_end - have);
+	}
+
+      elf = elf_memory (contents, file_trimmed_end);
+      if (unlikely (elf == NULL))
+	free (contents);
+      else
+	elf->flags |= ELF_F_MALLOCED;
+    }
+
+  if (elf != NULL)
+    {
+      /* Install the file in the module.  */
+      mod->main.elf = elf;
+      elf = NULL;
+      fd = -1;
+      mod->main.vaddr = module_start - bias;
+      mod->main.address_sync = module_address_sync;
+      mod->main_bias = bias;
+    }
+
+  return finish ();
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_validate_address.c b/third_party/elfutils/libdwfl/dwfl_validate_address.c
new file mode 100644
index 0000000..15e2602
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_validate_address.c
@@ -0,0 +1,65 @@
+/* Validate an address and the relocatability of an offset from it.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+int
+dwfl_validate_address (Dwfl *dwfl, Dwarf_Addr address, Dwarf_Sword offset)
+{
+  Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (dwfl, address);
+  if (mod == NULL)
+    return -1;
+
+  Dwarf_Addr relative = address;
+  int idx = INTUSE(dwfl_module_relocate_address) (mod, &relative);
+  if (idx < 0)
+    return -1;
+
+  if (offset != 0)
+    {
+      int offset_idx = -1;
+      relative = address + offset;
+      if (relative >= mod->low_addr && relative <= mod->high_addr)
+	{
+	  offset_idx = INTUSE(dwfl_module_relocate_address) (mod, &relative);
+	  if (offset_idx < 0)
+	    return -1;
+	}
+      if (offset_idx != idx)
+	{
+	  __libdwfl_seterrno (DWFL_E_ADDR_OUTOFRANGE);
+	  return -1;
+	}
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/libdwfl/dwfl_version.c b/third_party/elfutils/libdwfl/dwfl_version.c
new file mode 100644
index 0000000..c27d4f6
--- /dev/null
+++ b/third_party/elfutils/libdwfl/dwfl_version.c
@@ -0,0 +1,39 @@
+/* Return implementation's version string suitable for printing.
+   Copyright (C) 2006, 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+const char *
+dwfl_version (Dwfl *dwfl __attribute__ ((unused)))
+{
+  return PACKAGE_VERSION;
+}
diff --git a/third_party/elfutils/libdwfl/elf-from-memory.c b/third_party/elfutils/libdwfl/elf-from-memory.c
new file mode 100644
index 0000000..12a0a1b
--- /dev/null
+++ b/third_party/elfutils/libdwfl/elf-from-memory.c
@@ -0,0 +1,394 @@
+/* Reconstruct an ELF file by reading the segments out of remote memory.
+   Copyright (C) 2005-2011, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include "../libelf/libelfP.h"
+#undef _
+
+#include "libdwflP.h"
+
+#include <gelf.h>
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Reconstruct an ELF file by reading the segments out of remote memory
+   based on the ELF file header at EHDR_VMA and the ELF program headers it
+   points to.  If not null, *LOADBASEP is filled in with the difference
+   between the addresses from which the segments were read, and the
+   addresses the file headers put them at.
+
+   The function READ_MEMORY is called to copy at least MINREAD and at most
+   MAXREAD bytes from the remote memory at target address ADDRESS into the
+   local buffer at DATA; it should return -1 for errors (with code in
+   `errno'), 0 if it failed to read at least MINREAD bytes due to EOF, or
+   the number of bytes read if >= MINREAD.  ARG is passed through.
+
+   PAGESIZE is the minimum page size and alignment used for the PT_LOAD
+   segments.  */
+
+Elf *
+elf_from_remote_memory (GElf_Addr ehdr_vma,
+			GElf_Xword pagesize,
+			GElf_Addr *loadbasep,
+			ssize_t (*read_memory) (void *arg, void *data,
+						GElf_Addr address,
+						size_t minread,
+						size_t maxread),
+			void *arg)
+{
+  /* We might have to reserve some memory for the phdrs.  Set to NULL
+     here so we can always safely free it.  */
+  void *phdrsp = NULL;
+
+  /* First read in the file header and check its sanity.  */
+
+  const size_t initial_bufsize = 256;
+  unsigned char *buffer = malloc (initial_bufsize);
+  if (unlikely (buffer == NULL))
+    {
+    no_memory:
+      __libdwfl_seterrno (DWFL_E_NOMEM);
+      return NULL;
+    }
+
+  ssize_t nread = (*read_memory) (arg, buffer, ehdr_vma,
+				  sizeof (Elf32_Ehdr), initial_bufsize);
+  if (nread <= 0)
+    {
+    read_error:
+      free (buffer);
+      free (phdrsp);
+      __libdwfl_seterrno (nread < 0 ? DWFL_E_ERRNO : DWFL_E_TRUNCATED);
+      return NULL;
+    }
+
+  if (memcmp (buffer, ELFMAG, SELFMAG) != 0)
+    {
+    bad_elf:
+      free (buffer);
+      free (phdrsp);
+      __libdwfl_seterrno (DWFL_E_BADELF);
+      return NULL;
+    }
+
+  /* Extract the information we need from the file header.  */
+
+  union
+  {
+    Elf32_Ehdr e32;
+    Elf64_Ehdr e64;
+  } ehdr;
+  Elf_Data xlatefrom =
+    {
+      .d_type = ELF_T_EHDR,
+      .d_buf = buffer,
+      .d_version = EV_CURRENT,
+    };
+  Elf_Data xlateto =
+    {
+      .d_type = ELF_T_EHDR,
+      .d_buf = &ehdr,
+      .d_size = sizeof ehdr,
+      .d_version = EV_CURRENT,
+    };
+
+  GElf_Off phoff;
+  uint_fast16_t phnum;
+  uint_fast16_t phentsize;
+  GElf_Off shdrs_end;
+
+  switch (buffer[EI_CLASS])
+    {
+    case ELFCLASS32:
+      xlatefrom.d_size = sizeof (Elf32_Ehdr);
+      if (elf32_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
+	{
+	libelf_error:
+	  __libdwfl_seterrno (DWFL_E_LIBELF);
+	  return NULL;
+	}
+      phoff = ehdr.e32.e_phoff;
+      phnum = ehdr.e32.e_phnum;
+      phentsize = ehdr.e32.e_phentsize;
+      if (phentsize != sizeof (Elf32_Phdr) || phnum == 0)
+	goto bad_elf;
+      shdrs_end = ehdr.e32.e_shoff + ehdr.e32.e_shnum * ehdr.e32.e_shentsize;
+      break;
+
+    case ELFCLASS64:
+      xlatefrom.d_size = sizeof (Elf64_Ehdr);
+      if (elf64_xlatetom (&xlateto, &xlatefrom, buffer[EI_DATA]) == NULL)
+	goto libelf_error;
+      phoff = ehdr.e64.e_phoff;
+      phnum = ehdr.e64.e_phnum;
+      phentsize = ehdr.e64.e_phentsize;
+      if (phentsize != sizeof (Elf64_Phdr) || phnum == 0)
+	goto bad_elf;
+      shdrs_end = ehdr.e64.e_shoff + ehdr.e64.e_shnum * ehdr.e64.e_shentsize;
+      break;
+
+    default:
+      goto bad_elf;
+    }
+
+
+  /* The file header tells where to find the program headers.
+     These are what we use to actually choose what to read.  */
+
+  xlatefrom.d_type = xlateto.d_type = ELF_T_PHDR;
+  xlatefrom.d_size = phnum * phentsize;
+
+  if ((size_t) nread >= phoff + phnum * phentsize)
+    /* We already have all the phdrs from the initial read.  */
+    xlatefrom.d_buf = buffer + phoff;
+  else
+    {
+      /* Read in the program headers.  */
+
+      if (initial_bufsize < (size_t)phnum * phentsize)
+	{
+	  unsigned char *newbuf = realloc (buffer, phnum * phentsize);
+	  if (newbuf == NULL)
+	    {
+	      free (buffer);
+	      free (phdrsp);
+	      goto no_memory;
+	    }
+	  buffer = newbuf;
+	}
+      nread = (*read_memory) (arg, buffer, ehdr_vma + phoff,
+			      phnum * phentsize, phnum * phentsize);
+      if (nread <= 0)
+	goto read_error;
+
+      xlatefrom.d_buf = buffer;
+    }
+
+  bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
+  size_t phdr_size = class32 ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr);
+  if (unlikely (phnum > SIZE_MAX / phdr_size))
+    {
+      free (buffer);
+      goto no_memory;
+    }
+  const size_t phdrsp_bytes = phnum * phdr_size;
+  phdrsp = malloc (phdrsp_bytes);
+  if (unlikely (phdrsp == NULL))
+    {
+      free (buffer);
+      goto no_memory;
+    }
+
+  xlateto.d_buf = phdrsp;
+  xlateto.d_size = phdrsp_bytes;
+
+  /* Scan for PT_LOAD segments to find the total size of the file image.  */
+  size_t contents_size = 0;
+  GElf_Off segments_end = 0;
+  GElf_Off segments_end_mem = 0;
+  GElf_Addr loadbase = ehdr_vma;
+  bool found_base = false;
+  Elf32_Phdr (*p32)[phnum] = phdrsp;
+  Elf64_Phdr (*p64)[phnum] = phdrsp;
+  switch (ehdr.e32.e_ident[EI_CLASS])
+    {
+      /* Sanity checks segments and calculates segment_end,
+	 segments_end, segments_end_mem and loadbase (if not
+	 found_base yet).  Returns true if sanity checking failed,
+	 false otherwise.  */
+      inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
+				  GElf_Xword filesz, GElf_Xword memsz)
+	{
+	  /* Sanity check the segment load aligns with the pagesize.  */
+	  if (((vaddr - offset) & (pagesize - 1)) != 0)
+	    return true;
+
+	  GElf_Off segment_end = ((offset + filesz + pagesize - 1)
+				  & -pagesize);
+
+	  if (segment_end > (GElf_Off) contents_size)
+	    contents_size = segment_end;
+
+	  if (!found_base && (offset & -pagesize) == 0)
+	    {
+	      loadbase = ehdr_vma - (vaddr & -pagesize);
+	      found_base = true;
+	    }
+
+	  segments_end = offset + filesz;
+	  segments_end_mem = offset + memsz;
+	  return false;
+	}
+
+    case ELFCLASS32:
+      if (elf32_xlatetom (&xlateto, &xlatefrom,
+			  ehdr.e32.e_ident[EI_DATA]) == NULL)
+	goto libelf_error;
+      for (uint_fast16_t i = 0; i < phnum; ++i)
+	if ((*p32)[i].p_type == PT_LOAD)
+	  if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
+			      (*p32)[i].p_filesz, (*p32)[i].p_memsz))
+	    goto bad_elf;
+      break;
+
+    case ELFCLASS64:
+      if (elf64_xlatetom (&xlateto, &xlatefrom,
+			  ehdr.e64.e_ident[EI_DATA]) == NULL)
+	goto libelf_error;
+      for (uint_fast16_t i = 0; i < phnum; ++i)
+	if ((*p64)[i].p_type == PT_LOAD)
+	  if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset,
+			      (*p64)[i].p_filesz, (*p64)[i].p_memsz))
+	    goto bad_elf;
+      break;
+
+    default:
+      abort ();
+      break;
+    }
+
+  /* Trim the last segment so we don't bother with zeros in the last page
+     that are off the end of the file.  However, if the extra bit in that
+     page includes the section headers and the memory isn't extended (which
+     might indicate it will have been reused otherwise), keep them.  */
+  if ((GElf_Off) contents_size > segments_end
+      && (GElf_Off) contents_size >= shdrs_end
+      && segments_end == segments_end_mem)
+    {
+      contents_size = segments_end;
+      if ((GElf_Off) contents_size < shdrs_end)
+	contents_size = shdrs_end;
+    }
+  else
+    contents_size = segments_end;
+
+  free (buffer);
+
+  /* Now we know the size of the whole image we want read in.  */
+  buffer = calloc (1, contents_size);
+  if (buffer == NULL)
+    {
+      free (phdrsp);
+      goto no_memory;
+    }
+
+  switch (ehdr.e32.e_ident[EI_CLASS])
+    {
+      /* Reads the given segment.  Returns true if reading fails,
+	 false otherwise.  */
+      inline bool handle_segment (GElf_Addr vaddr, GElf_Off offset,
+				  GElf_Xword filesz)
+	{
+	  GElf_Off start = offset & -pagesize;
+	  GElf_Off end = (offset + filesz + pagesize - 1) & -pagesize;
+	  if (end > (GElf_Off) contents_size)
+	    end = contents_size;
+	  nread = (*read_memory) (arg, buffer + start,
+				  (loadbase + vaddr) & -pagesize,
+				  end - start, end - start);
+	  return nread <= 0;
+	}
+
+    case ELFCLASS32:
+      for (uint_fast16_t i = 0; i < phnum; ++i)
+	if ((*p32)[i].p_type == PT_LOAD)
+	  if (handle_segment ((*p32)[i].p_vaddr, (*p32)[i].p_offset,
+			      (*p32)[i].p_filesz))
+	    goto read_error;
+
+      /* If the segments visible in memory didn't include the section
+	 headers, then clear them from the file header.  */
+      if (contents_size < shdrs_end)
+	{
+	  ehdr.e32.e_shoff = 0;
+	  ehdr.e32.e_shnum = 0;
+	  ehdr.e32.e_shstrndx = 0;
+	}
+
+      /* This will normally have been in the first PT_LOAD segment.  But it
+	 conceivably could be missing, and we might have just changed it.  */
+      xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
+      xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e32;
+      xlatefrom.d_buf = &ehdr.e32;
+      xlateto.d_buf = buffer;
+      if (elf32_xlatetof (&xlateto, &xlatefrom,
+			  ehdr.e32.e_ident[EI_DATA]) == NULL)
+	goto libelf_error;
+      break;
+
+    case ELFCLASS64:
+      for (uint_fast16_t i = 0; i < phnum; ++i)
+	if ((*p64)[i].p_type == PT_LOAD)
+	  if (handle_segment ((*p64)[i].p_vaddr, (*p64)[i].p_offset,
+			      (*p64)[i].p_filesz))
+	    goto read_error;
+
+      /* If the segments visible in memory didn't include the section
+	 headers, then clear them from the file header.  */
+      if (contents_size < shdrs_end)
+	{
+	  ehdr.e64.e_shoff = 0;
+	  ehdr.e64.e_shnum = 0;
+	  ehdr.e64.e_shstrndx = 0;
+	}
+
+      /* This will normally have been in the first PT_LOAD segment.  But it
+	 conceivably could be missing, and we might have just changed it.  */
+      xlatefrom.d_type = xlateto.d_type = ELF_T_EHDR;
+      xlatefrom.d_size = xlateto.d_size = sizeof ehdr.e64;
+      xlatefrom.d_buf = &ehdr.e64;
+      xlateto.d_buf = buffer;
+      if (elf64_xlatetof (&xlateto, &xlatefrom,
+			  ehdr.e64.e_ident[EI_DATA]) == NULL)
+	goto libelf_error;
+      break;
+
+    default:
+      abort ();
+      break;
+    }
+
+  free (phdrsp);
+  phdrsp = NULL;
+
+  /* Now we have the image.  Open libelf on it.  */
+
+  Elf *elf = elf_memory ((char *) buffer, contents_size);
+  if (elf == NULL)
+    {
+      free (buffer);
+      goto libelf_error;
+    }
+
+  elf->flags |= ELF_F_MALLOCED;
+  if (loadbasep != NULL)
+    *loadbasep = loadbase;
+  return elf;
+}
diff --git a/third_party/elfutils/libdwfl/find-debuginfo.c b/third_party/elfutils/libdwfl/find-debuginfo.c
new file mode 100644
index 0000000..6d5a42a
--- /dev/null
+++ b/third_party/elfutils/libdwfl/find-debuginfo.c
@@ -0,0 +1,402 @@
+/* Standard find_debuginfo callback for libdwfl.
+   Copyright (C) 2005-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include "system.h"
+
+
+/* Try to open [DIR/][SUBDIR/]DEBUGLINK, return file descriptor or -1.
+   On success, *DEBUGINFO_FILE_NAME has the malloc'd name of the open file.  */
+static int
+try_open (const struct stat *main_stat,
+	  const char *dir, const char *subdir, const char *debuglink,
+	  char **debuginfo_file_name)
+{
+  char *fname;
+  if (dir == NULL && subdir == NULL)
+    {
+      fname = strdup (debuglink);
+      if (unlikely (fname == NULL))
+	return -1;
+    }
+  else if ((subdir == NULL ? asprintf (&fname, "%s/%s", dir, debuglink)
+	    : dir == NULL ? asprintf (&fname, "%s/%s", subdir, debuglink)
+	    : asprintf (&fname, "%s/%s/%s", dir, subdir, debuglink)) < 0)
+    return -1;
+
+  struct stat st;
+  int fd = TEMP_FAILURE_RETRY (open (fname, O_RDONLY));
+  if (fd < 0)
+    free (fname);
+  else if (fstat (fd, &st) == 0
+	   && st.st_ino == main_stat->st_ino
+	   && st.st_dev == main_stat->st_dev)
+    {
+      /* This is the main file by another name.  Don't look at it again.  */
+      free (fname);
+      close (fd);
+      errno = ENOENT;
+      fd = -1;
+    }
+  else
+    *debuginfo_file_name = fname;
+
+  return fd;
+}
+
+/* Return true iff the FD's contents CRC matches DEBUGLINK_CRC.  */
+static inline bool
+check_crc (int fd, GElf_Word debuglink_crc)
+{
+  uint32_t file_crc;
+  return (__libdwfl_crc32_file (fd, &file_crc) == 0
+	  && file_crc == debuglink_crc);
+}
+
+static bool
+validate (Dwfl_Module *mod, int fd, bool check, GElf_Word debuglink_crc)
+{
+  /* For alt debug files always check the build-id from the Dwarf and alt.  */
+  if (mod->dw != NULL)
+    {
+      bool valid = false;
+      const void *build_id;
+      const char *altname;
+      ssize_t build_id_len = INTUSE(dwelf_dwarf_gnu_debugaltlink) (mod->dw,
+								   &altname,
+								   &build_id);
+      if (build_id_len > 0)
+	{
+	  /* We need to open an Elf handle on the file so we can check its
+	     build ID note for validation.  Backdoor the handle into the
+	     module data structure since we had to open it early anyway.  */
+	  Dwfl_Error error = __libdw_open_file (&fd, &mod->alt_elf,
+						false, false);
+	  if (error != DWFL_E_NOERROR)
+	    __libdwfl_seterrno (error);
+	  else
+	    {
+	      const void *alt_build_id;
+	      ssize_t alt_len = INTUSE(dwelf_elf_gnu_build_id) (mod->alt_elf,
+								&alt_build_id);
+	      if (alt_len > 0 && alt_len == build_id_len
+		  && memcmp (build_id, alt_build_id, alt_len) == 0)
+		valid = true;
+	      else
+		{
+		  /* A mismatch!  */
+		  elf_end (mod->alt_elf);
+		  mod->alt_elf = NULL;
+		  close (fd);
+		  fd = -1;
+		}
+	    }
+	}
+      return valid;
+    }
+
+  /* If we have a build ID, check only that.  */
+  if (mod->build_id_len > 0)
+    {
+      /* We need to open an Elf handle on the file so we can check its
+	 build ID note for validation.  Backdoor the handle into the
+	 module data structure since we had to open it early anyway.  */
+
+      mod->debug.valid = false;
+      Dwfl_Error error = __libdw_open_file (&fd, &mod->debug.elf, false, false);
+      if (error != DWFL_E_NOERROR)
+	__libdwfl_seterrno (error);
+      else if (likely (__libdwfl_find_build_id (mod, false,
+						mod->debug.elf) == 2))
+	/* Also backdoor the gratuitous flag.  */
+	mod->debug.valid = true;
+      else
+	{
+	  /* A mismatch!  */
+	  elf_end (mod->debug.elf);
+	  mod->debug.elf = NULL;
+	  close (fd);
+	  fd = -1;
+	}
+
+      return mod->debug.valid;
+    }
+
+  return !check || check_crc (fd, debuglink_crc);
+}
+
+static int
+find_debuginfo_in_path (Dwfl_Module *mod, const char *file_name,
+			const char *debuglink_file, GElf_Word debuglink_crc,
+			char **debuginfo_file_name)
+{
+  bool cancheck = debuglink_crc != (GElf_Word) 0;
+
+  const char *file_basename = file_name == NULL ? NULL : basename (file_name);
+  char *localname = NULL;
+
+  /* We invent a debuglink .debug name if NULL, but then want to try the
+     basename too.  */
+  bool debuglink_null = debuglink_file == NULL;
+  if (debuglink_null)
+    {
+      /* For a alt debug multi file we need a name, for a separate debug
+	 name we may be able to fall back on file_basename.debug.  */
+      if (file_basename == NULL || mod->dw != NULL)
+	{
+	  errno = 0;
+	  return -1;
+	}
+
+      size_t len = strlen (file_basename);
+      localname = malloc (len + sizeof ".debug");
+      if (unlikely (localname == NULL))
+	return -1;
+      memcpy (localname, file_basename, len);
+      memcpy (&localname[len], ".debug", sizeof ".debug");
+      debuglink_file = localname;
+      cancheck = false;
+    }
+
+  /* Look for a file named DEBUGLINK_FILE in the directories
+     indicated by the debug directory path setting.  */
+
+  const Dwfl_Callbacks *const cb = mod->dwfl->callbacks;
+  char *localpath = strdup ((cb->debuginfo_path ? *cb->debuginfo_path : NULL)
+			    ?: DEFAULT_DEBUGINFO_PATH);
+  if (unlikely (localpath == NULL))
+    {
+      free (localname);
+      return -1;
+    }
+
+  /* A leading - or + in the whole path sets whether to check file CRCs.  */
+  bool defcheck = true;
+  char *path = localpath;
+  if (path[0] == '-' || path[0] == '+')
+    {
+      defcheck = path[0] == '+';
+      ++path;
+    }
+
+  /* XXX dev/ino should be cached in struct dwfl_file.  */
+  struct stat main_stat;
+  if (unlikely ((mod->main.fd != -1 ? fstat (mod->main.fd, &main_stat)
+		 : file_name != NULL ? stat (file_name, &main_stat)
+		 : -1) < 0))
+    {
+      main_stat.st_dev = 0;
+      main_stat.st_ino = 0;
+    }
+
+  char *file_dirname = (file_basename == file_name ? NULL
+			: strndup (file_name, file_basename - 1 - file_name));
+  if (file_basename != file_name && file_dirname == NULL)
+    {
+      free (localpath);
+      free (localname);
+      return -1;
+    }
+  char *p;
+  while ((p = strsep (&path, ":")) != NULL)
+    {
+      /* A leading - or + says whether to check file CRCs for this element.  */
+      bool check = defcheck;
+      if (*p == '+' || *p == '-')
+	check = *p++ == '+';
+      check = check && cancheck;
+
+      /* Try the basename too, if we made up the debuglink name and this
+	 is not the main directory.  */
+      bool try_file_basename;
+
+      const char *dir, *subdir, *file;
+      switch (p[0])
+	{
+	case '\0':
+	  /* An empty entry says to try the main file's directory.  */
+	  dir = file_dirname;
+	  subdir = NULL;
+	  file = debuglink_file;
+	  try_file_basename = false;
+	  break;
+	case '/':
+	  /* An absolute path says to look there for a subdirectory
+	     named by the main file's absolute directory.  This cannot
+	     be applied to a relative file name.  For alt debug files
+	     it means to look for the basename file in that dir or the
+	     .dwz subdir (see below).  */
+	  if (mod->dw == NULL
+	      && (file_dirname == NULL || file_dirname[0] != '/'))
+	    continue;
+	  dir = p;
+	  if (mod->dw == NULL)
+	    {
+	      subdir = file_dirname;
+	      /* We want to explore all sub-subdirs.  Chop off one slash
+		 at a time.  */
+	    explore_dir:
+	      subdir = strchr (subdir, '/');
+	      if (subdir != NULL)
+		subdir = subdir + 1;
+	      if (subdir && *subdir == 0)
+		continue;
+	      file = debuglink_file;
+	    }
+	  else
+	    {
+	      subdir = NULL;
+	      file = basename (debuglink_file);
+	    }
+	  try_file_basename = debuglink_null;
+	  break;
+	default:
+	  /* A relative path says to try a subdirectory of that name
+	     in the main file's directory.  */
+	  dir = file_dirname;
+	  subdir = p;
+	  file = debuglink_file;
+	  try_file_basename = debuglink_null;
+	  break;
+	}
+
+      char *fname = NULL;
+      int fd = try_open (&main_stat, dir, subdir, file, &fname);
+      if (fd < 0 && try_file_basename)
+	fd = try_open (&main_stat, dir, subdir, file_basename, &fname);
+      if (fd < 0)
+	switch (errno)
+	  {
+	  case ENOENT:
+	  case ENOTDIR:
+	    /* If we are looking for the alt file also try the .dwz subdir.
+	       But only if this is the empty or absolute path.  */
+	    if (mod->dw != NULL && (p[0] == '\0' || p[0] == '/'))
+	      {
+		fd = try_open (&main_stat, dir, ".dwz",
+			       basename (file), &fname);
+		if (fd < 0)
+		  {
+		    if (errno != ENOENT && errno != ENOTDIR)
+		      goto fail_free;
+		    else
+		      continue;
+		  }
+		break;
+	      }
+	    /* If possible try again with a sub-subdir.  */
+	    if (mod->dw == NULL && subdir)
+	      goto explore_dir;
+	    continue;
+	  default:
+	    goto fail_free;
+	  }
+      if (validate (mod, fd, check, debuglink_crc))
+	{
+	  free (localpath);
+	  free (localname);
+	  free (file_dirname);
+	  *debuginfo_file_name = fname;
+	  return fd;
+	}
+      free (fname);
+      close (fd);
+    }
+
+  /* No dice.  */
+  errno = 0;
+fail_free:
+  free (localpath);
+  free (localname);
+  free (file_dirname);
+  return -1;
+}
+
+int
+dwfl_standard_find_debuginfo (Dwfl_Module *mod,
+			      void **userdata __attribute__ ((unused)),
+			      const char *modname __attribute__ ((unused)),
+			      GElf_Addr base __attribute__ ((unused)),
+			      const char *file_name,
+			      const char *debuglink_file,
+			      GElf_Word debuglink_crc,
+			      char **debuginfo_file_name)
+{
+  /* First try by build ID if we have one.  If that succeeds or fails
+     other than just by finding nothing, that's all we do.  */
+  const unsigned char *bits;
+  GElf_Addr vaddr;
+  if (INTUSE(dwfl_module_build_id) (mod, &bits, &vaddr) > 0)
+    {
+      /* Dropping most arguments means we cannot rely on them in
+	 dwfl_build_id_find_debuginfo.  But leave it that way since
+	 some user code out there also does this, so we'll have to
+	 handle it anyway.  */
+      int fd = INTUSE(dwfl_build_id_find_debuginfo) (mod,
+						     NULL, NULL, 0,
+						     NULL, NULL, 0,
+						     debuginfo_file_name);
+
+      /* Did the build_id callback find something or report an error?
+         Then we are done.  Otherwise fallback on path based search.  */
+      if (fd >= 0
+	  || (mod->dw == NULL && mod->debug.elf != NULL)
+	  || (mod->dw != NULL && mod->alt_elf != NULL)
+	  || errno != 0)
+	return fd;
+    }
+
+  /* Failing that, search the path by name.  */
+  int fd = find_debuginfo_in_path (mod, file_name,
+				   debuglink_file, debuglink_crc,
+				   debuginfo_file_name);
+
+  if (fd < 0 && errno == 0 && file_name != NULL)
+    {
+      /* If FILE_NAME is a symlink, the debug file might be associated
+	 with the symlink target name instead.  */
+
+      char *canon = canonicalize_file_name (file_name);
+      if (canon != NULL && strcmp (file_name, canon))
+	fd = find_debuginfo_in_path (mod, canon,
+				     debuglink_file, debuglink_crc,
+				     debuginfo_file_name);
+      free (canon);
+    }
+
+  return fd;
+}
+INTDEF (dwfl_standard_find_debuginfo)
diff --git a/third_party/elfutils/libdwfl/frame_unwind.c b/third_party/elfutils/libdwfl/frame_unwind.c
new file mode 100644
index 0000000..eaea495
--- /dev/null
+++ b/third_party/elfutils/libdwfl/frame_unwind.c
@@ -0,0 +1,758 @@
+/* Get previous frame state for an existing frame state.
+   Copyright (C) 2013, 2014, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "cfi.h"
+#include <stdlib.h>
+#include "libdwflP.h"
+#include "../libdw/dwarf.h"
+#include <system.h>
+
+/* Maximum number of DWARF expression stack slots before returning an error.  */
+#define DWARF_EXPR_STACK_MAX 0x100
+
+/* Maximum number of DWARF expression executed operations before returning an
+   error.  */
+#define DWARF_EXPR_STEPS_MAX 0x1000
+
+bool
+internal_function
+__libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
+{
+  Ebl *ebl = state->thread->process->ebl;
+  if (! ebl_dwarf_to_regno (ebl, &regno))
+    return false;
+  if (regno >= ebl_frame_nregs (ebl))
+    return false;
+  if ((state->regs_set[regno / sizeof (*state->regs_set) / 8]
+       & ((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)))) == 0)
+    return false;
+  if (val)
+    *val = state->regs[regno];
+  return true;
+}
+
+bool
+internal_function
+__libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno, Dwarf_Addr val)
+{
+  Ebl *ebl = state->thread->process->ebl;
+  if (! ebl_dwarf_to_regno (ebl, &regno))
+    return false;
+  if (regno >= ebl_frame_nregs (ebl))
+    return false;
+  /* For example i386 user_regs_struct has signed fields.  */
+  if (ebl_get_elfclass (ebl) == ELFCLASS32)
+    val &= 0xffffffff;
+  state->regs_set[regno / sizeof (*state->regs_set) / 8] |=
+		((uint64_t) 1U << (regno % (sizeof (*state->regs_set) * 8)));
+  state->regs[regno] = val;
+  return true;
+}
+
+static bool
+state_get_reg (Dwfl_Frame *state, unsigned regno, Dwarf_Addr *val)
+{
+  if (! __libdwfl_frame_reg_get (state, regno, val))
+    {
+      __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
+      return false;
+    }
+  return true;
+}
+
+static int
+bra_compar (const void *key_voidp, const void *elem_voidp)
+{
+  Dwarf_Word offset = (uintptr_t) key_voidp;
+  const Dwarf_Op *op = elem_voidp;
+  return (offset > op->offset) - (offset < op->offset);
+}
+
+struct eval_stack {
+  Dwarf_Addr *addrs;
+  size_t used;
+  size_t allocated;
+};
+
+static bool
+do_push (struct eval_stack *stack, Dwarf_Addr val)
+{
+  if (stack->used >= DWARF_EXPR_STACK_MAX)
+    {
+      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+      return false;
+    }
+  if (stack->used == stack->allocated)
+    {
+      stack->allocated = MAX (stack->allocated * 2, 32);
+      Dwarf_Addr *new_addrs;
+      new_addrs = realloc (stack->addrs,
+			   stack->allocated * sizeof (*stack->addrs));
+      if (new_addrs == NULL)
+        {
+          __libdwfl_seterrno (DWFL_E_NOMEM);
+          return false;
+        }
+      stack->addrs = new_addrs;
+    }
+  stack->addrs[stack->used++] = val;
+  return true;
+}
+
+static bool
+do_pop (struct eval_stack *stack, Dwarf_Addr *val)
+{
+  if (stack->used == 0)
+    {
+      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+      return false;
+    }
+  *val = stack->addrs[--stack->used];
+  return true;
+}
+
+/* If FRAME is NULL is are computing CFI frame base.  In such case another
+   DW_OP_call_frame_cfa is no longer permitted.  */
+
+static bool
+expr_eval (Dwfl_Frame *state, Dwarf_Frame *frame, const Dwarf_Op *ops,
+	   size_t nops, Dwarf_Addr *result, Dwarf_Addr bias)
+{
+  Dwfl_Process *process = state->thread->process;
+  if (nops == 0)
+    {
+      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+      return false;
+    }
+  struct eval_stack stack =
+    {
+      .addrs = NULL,
+      .used = 0,
+      .allocated = 0
+    };
+
+#define pop(x) do_pop(&stack, x)
+#define push(x) do_push(&stack, x)
+
+  Dwarf_Addr val1, val2;
+  bool is_location = false;
+  size_t steps_count = 0;
+  for (const Dwarf_Op *op = ops; op < ops + nops; op++)
+    {
+      if (++steps_count > DWARF_EXPR_STEPS_MAX)
+	{
+	  __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+	  return false;
+	}
+      switch (op->atom)
+      {
+	/* DW_OP_* order matches libgcc/unwind-dw2.c execute_stack_op:  */
+	case DW_OP_lit0 ... DW_OP_lit31:
+	  if (! push (op->atom - DW_OP_lit0))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_addr:
+	  if (! push (op->number + bias))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_GNU_encoded_addr:
+	  /* Missing support in the rest of elfutils.  */
+	  __libdwfl_seterrno (DWFL_E_UNSUPPORTED_DWARF);
+	  return false;
+	case DW_OP_const1u:
+	case DW_OP_const1s:
+	case DW_OP_const2u:
+	case DW_OP_const2s:
+	case DW_OP_const4u:
+	case DW_OP_const4s:
+	case DW_OP_const8u:
+	case DW_OP_const8s:
+	case DW_OP_constu:
+	case DW_OP_consts:
+	  if (! push (op->number))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_reg0 ... DW_OP_reg31:
+	  if (! state_get_reg (state, op->atom - DW_OP_reg0, &val1)
+	      || ! push (val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_regx:
+	  if (! state_get_reg (state, op->number, &val1) || ! push (val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_breg0 ... DW_OP_breg31:
+	  if (! state_get_reg (state, op->atom - DW_OP_breg0, &val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  val1 += op->number;
+	  if (! push (val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_bregx:
+	  if (! state_get_reg (state, op->number, &val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  val1 += op->number2;
+	  if (! push (val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_dup:
+	  if (! pop (&val1) || ! push (val1) || ! push (val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_drop:
+	  if (! pop (&val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_pick:
+	  if (stack.used <= op->number)
+	    {
+	      free (stack.addrs);
+	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+	      return false;
+	    }
+	  if (! push (stack.addrs[stack.used - 1 - op->number]))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_over:
+	  if (! pop (&val1) || ! pop (&val2)
+	      || ! push (val2) || ! push (val1) || ! push (val2))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_swap:
+	  if (! pop (&val1) || ! pop (&val2) || ! push (val1) || ! push (val2))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	case DW_OP_rot:
+	  {
+	    Dwarf_Addr val3;
+	    if (! pop (&val1) || ! pop (&val2) || ! pop (&val3)
+		|| ! push (val1) || ! push (val3) || ! push (val2))
+	      {
+		free (stack.addrs);
+		return false;
+	      }
+	  }
+	  break;
+	case DW_OP_deref:
+	case DW_OP_deref_size:
+	  if (process->callbacks->memory_read == NULL)
+	    {
+	      free (stack.addrs);
+	      __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
+	      return false;
+	    }
+	  if (! pop (&val1)
+	      || ! process->callbacks->memory_read (process->dwfl, val1, &val1,
+						    process->callbacks_arg))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  if (op->atom == DW_OP_deref_size)
+	    {
+	      const int elfclass = frame->cache->e_ident[EI_CLASS];
+	      const unsigned addr_bytes = elfclass == ELFCLASS32 ? 4 : 8;
+	      if (op->number > addr_bytes)
+		{
+		  free (stack.addrs);
+		  __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+		  return false;
+		}
+#if BYTE_ORDER == BIG_ENDIAN
+	      if (op->number == 0)
+		val1 = 0;
+	      else
+		val1 >>= (addr_bytes - op->number) * 8;
+#else
+	      if (op->number < 8)
+		val1 &= (1 << (op->number * 8)) - 1;
+#endif
+	    }
+	  if (! push (val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+#define UNOP(atom, expr)						\
+	case atom:							\
+	  if (! pop (&val1) || ! push (expr))				\
+	    {								\
+	      free (stack.addrs);					\
+	      return false;						\
+	    }								\
+	  break;
+	UNOP (DW_OP_abs, llabs ((int64_t) val1))
+	UNOP (DW_OP_neg, -(int64_t) val1)
+	UNOP (DW_OP_not, ~val1)
+#undef UNOP
+	case DW_OP_plus_uconst:
+	  if (! pop (&val1) || ! push (val1 + op->number))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+#define BINOP(atom, op)							\
+	case atom:							\
+	  if (! pop (&val2) || ! pop (&val1) || ! push (val1 op val2))	\
+	    {								\
+	      free (stack.addrs);					\
+	      return false;						\
+	    }								\
+	  break;
+#define BINOP_SIGNED(atom, op)						\
+	case atom:							\
+	  if (! pop (&val2) || ! pop (&val1)				\
+	      || ! push ((int64_t) val1 op (int64_t) val2))		\
+	    {								\
+	      free (stack.addrs);					\
+	      return false;						\
+	    }								\
+	  break;
+	BINOP (DW_OP_and, &)
+	case DW_OP_div:
+	  if (! pop (&val2) || ! pop (&val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  if (val2 == 0)
+	    {
+	      free (stack.addrs);
+	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+	      return false;
+	    }
+	  if (! push ((int64_t) val1 / (int64_t) val2))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	BINOP (DW_OP_minus, -)
+	case DW_OP_mod:
+	  if (! pop (&val2) || ! pop (&val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  if (val2 == 0)
+	    {
+	      free (stack.addrs);
+	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+	      return false;
+	    }
+	  if (! push (val1 % val2))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  break;
+	BINOP (DW_OP_mul, *)
+	BINOP (DW_OP_or, |)
+	BINOP (DW_OP_plus, +)
+	BINOP (DW_OP_shl, <<)
+	BINOP (DW_OP_shr, >>)
+	BINOP_SIGNED (DW_OP_shra, >>)
+	BINOP (DW_OP_xor, ^)
+	BINOP_SIGNED (DW_OP_le, <=)
+	BINOP_SIGNED (DW_OP_ge, >=)
+	BINOP_SIGNED (DW_OP_eq, ==)
+	BINOP_SIGNED (DW_OP_lt, <)
+	BINOP_SIGNED (DW_OP_gt, >)
+	BINOP_SIGNED (DW_OP_ne, !=)
+#undef BINOP
+#undef BINOP_SIGNED
+	case DW_OP_bra:
+	  if (! pop (&val1))
+	    {
+	      free (stack.addrs);
+	      return false;
+	    }
+	  if (val1 == 0)
+	    break;
+	  FALLTHROUGH;
+	case DW_OP_skip:;
+	  Dwarf_Word offset = op->offset + 1 + 2 + (int16_t) op->number;
+	  const Dwarf_Op *found = bsearch ((void *) (uintptr_t) offset, ops, nops,
+					   sizeof (*ops), bra_compar);
+	  if (found == NULL)
+	    {
+	      free (stack.addrs);
+	      /* PPC32 vDSO has such invalid operations.  */
+	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+	      return false;
+	    }
+	  /* Undo the 'for' statement increment.  */
+	  op = found - 1;
+	  break;
+	case DW_OP_nop:
+	  break;
+	/* DW_OP_* not listed in libgcc/unwind-dw2.c execute_stack_op:  */
+	case DW_OP_call_frame_cfa:;
+	  // Not used by CFI itself but it is synthetized by elfutils internation.
+	  Dwarf_Op *cfa_ops;
+	  size_t cfa_nops;
+	  Dwarf_Addr cfa;
+	  if (frame == NULL
+	      || dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0
+	      || ! expr_eval (state, NULL, cfa_ops, cfa_nops, &cfa, bias)
+	      || ! push (cfa))
+	    {
+	      __libdwfl_seterrno (DWFL_E_LIBDW);
+	      free (stack.addrs);
+	      return false;
+	    }
+	  is_location = true;
+	  break;
+	case DW_OP_stack_value:
+	  // Not used by CFI itself but it is synthetized by elfutils internation.
+	  is_location = false;
+	  break;
+	default:
+	  __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+	  return false;
+      }
+    }
+  if (! pop (result))
+    {
+      free (stack.addrs);
+      return false;
+    }
+  free (stack.addrs);
+  if (is_location)
+    {
+      if (process->callbacks->memory_read == NULL)
+	{
+	  __libdwfl_seterrno (DWFL_E_INVALID_ARGUMENT);
+	  return false;
+	}
+      if (! process->callbacks->memory_read (process->dwfl, *result, result,
+					     process->callbacks_arg))
+	return false;
+    }
+  return true;
+#undef push
+#undef pop
+}
+
+static Dwfl_Frame *
+new_unwound (Dwfl_Frame *state)
+{
+  assert (state->unwound == NULL);
+  Dwfl_Thread *thread = state->thread;
+  Dwfl_Process *process = thread->process;
+  Ebl *ebl = process->ebl;
+  size_t nregs = ebl_frame_nregs (ebl);
+  assert (nregs > 0);
+  Dwfl_Frame *unwound;
+  unwound = malloc (sizeof (*unwound) + sizeof (*unwound->regs) * nregs);
+  if (unlikely (unwound == NULL))
+    return NULL;
+  state->unwound = unwound;
+  unwound->thread = thread;
+  unwound->unwound = NULL;
+  unwound->signal_frame = false;
+  unwound->initial_frame = false;
+  unwound->pc_state = DWFL_FRAME_STATE_ERROR;
+  memset (unwound->regs_set, 0, sizeof (unwound->regs_set));
+  return unwound;
+}
+
+/* The logic is to call __libdwfl_seterrno for any CFI bytecode interpretation
+   error so one can easily catch the problem with a debugger.  Still there are
+   archs with invalid CFI for some registers where the registers are never used
+   later.  Therefore we continue unwinding leaving the registers undefined.  */
+
+static void
+handle_cfi (Dwfl_Frame *state, Dwarf_Addr pc, Dwarf_CFI *cfi, Dwarf_Addr bias)
+{
+  Dwarf_Frame *frame;
+  if (INTUSE(dwarf_cfi_addrframe) (cfi, pc, &frame) != 0)
+    {
+      __libdwfl_seterrno (DWFL_E_LIBDW);
+      return;
+    }
+
+  Dwfl_Frame *unwound = new_unwound (state);
+  if (unwound == NULL)
+    {
+      __libdwfl_seterrno (DWFL_E_NOMEM);
+      return;
+    }
+
+  unwound->signal_frame = frame->fde->cie->signal_frame;
+  Dwfl_Thread *thread = state->thread;
+  Dwfl_Process *process = thread->process;
+  Ebl *ebl = process->ebl;
+  size_t nregs = ebl_frame_nregs (ebl);
+  assert (nregs > 0);
+
+  /* The return register is special for setting the unwound->pc_state.  */
+  unsigned ra = frame->fde->cie->return_address_register;
+  bool ra_set = false;
+  ebl_dwarf_to_regno (ebl, &ra);
+
+  for (unsigned regno = 0; regno < nregs; regno++)
+    {
+      Dwarf_Op reg_ops_mem[3], *reg_ops;
+      size_t reg_nops;
+      if (dwarf_frame_register (frame, regno, reg_ops_mem, &reg_ops,
+				&reg_nops) != 0)
+	{
+	  __libdwfl_seterrno (DWFL_E_LIBDW);
+	  continue;
+	}
+      Dwarf_Addr regval;
+      if (reg_nops == 0)
+	{
+	  if (reg_ops == reg_ops_mem)
+	    {
+	      /* REGNO is undefined.  */
+	      if (regno == ra)
+		unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
+	      continue;
+	    }
+	  else if (reg_ops == NULL)
+	    {
+	      /* REGNO is same-value.  */
+	      if (! state_get_reg (state, regno, &regval))
+		continue;
+	    }
+	  else
+	    {
+	      __libdwfl_seterrno (DWFL_E_INVALID_DWARF);
+	      continue;
+	    }
+	}
+      else if (! expr_eval (state, frame, reg_ops, reg_nops, &regval, bias))
+	{
+	  /* PPC32 vDSO has various invalid operations, ignore them.  The
+	     register will look as unset causing an error later, if used.
+	     But PPC32 does not use such registers.  */
+	  continue;
+	}
+
+      /* Some architectures encode some extra info in the return address.  */
+      if (regno == frame->fde->cie->return_address_register)
+	regval &= ebl_func_addr_mask (ebl);
+
+      /* This is another strange PPC[64] case.  There are two
+	 registers numbers that can represent the same DWARF return
+	 register number.  We only want one to actually set the return
+	 register value.  But we always want to override the value if
+	 the register is the actual CIE return address register.  */
+      if (ra_set && regno != frame->fde->cie->return_address_register)
+	{
+	  unsigned r = regno;
+	  if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
+	    continue;
+	}
+
+      if (! __libdwfl_frame_reg_set (unwound, regno, regval))
+	{
+	  __libdwfl_seterrno (DWFL_E_INVALID_REGISTER);
+	  continue;
+	}
+      else if (! ra_set)
+	{
+	  unsigned r = regno;
+          if (ebl_dwarf_to_regno (ebl, &r) && r == ra)
+	    ra_set = true;
+	}
+    }
+  if (unwound->pc_state == DWFL_FRAME_STATE_ERROR
+      && __libdwfl_frame_reg_get (unwound,
+				  frame->fde->cie->return_address_register,
+				  &unwound->pc))
+    {
+      /* PPC32 __libc_start_main properly CFI-unwinds PC as zero.  Currently
+	 none of the archs supported for unwinding have zero as a valid PC.  */
+      if (unwound->pc == 0)
+	unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
+      else
+        {
+          unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
+          /* In SPARC the return address register actually contains
+             the address of the call instruction instead of the return
+             address.  Therefore we add here an offset defined by the
+             backend.  Most likely 0.  */
+          unwound->pc += ebl_ra_offset (ebl);
+        }
+    }
+  free (frame);
+}
+
+static bool
+setfunc (int firstreg, unsigned nregs, const Dwarf_Word *regs, void *arg)
+{
+  Dwfl_Frame *state = arg;
+  Dwfl_Frame *unwound = state->unwound;
+  if (firstreg < 0)
+    {
+      assert (firstreg == -1);
+      assert (nregs == 1);
+      assert (unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED);
+      unwound->pc = *regs;
+      unwound->pc_state = DWFL_FRAME_STATE_PC_SET;
+      return true;
+    }
+  while (nregs--)
+    if (! __libdwfl_frame_reg_set (unwound, firstreg++, *regs++))
+      return false;
+  return true;
+}
+
+static bool
+getfunc (int firstreg, unsigned nregs, Dwarf_Word *regs, void *arg)
+{
+  Dwfl_Frame *state = arg;
+  assert (firstreg >= 0);
+  while (nregs--)
+    if (! __libdwfl_frame_reg_get (state, firstreg++, regs++))
+      return false;
+  return true;
+}
+
+static bool
+readfunc (Dwarf_Addr addr, Dwarf_Word *datap, void *arg)
+{
+  Dwfl_Frame *state = arg;
+  Dwfl_Thread *thread = state->thread;
+  Dwfl_Process *process = thread->process;
+  return process->callbacks->memory_read (process->dwfl, addr, datap,
+					  process->callbacks_arg);
+}
+
+void
+internal_function
+__libdwfl_frame_unwind (Dwfl_Frame *state)
+{
+  if (state->unwound)
+    return;
+  /* Do not ask dwfl_frame_pc for ISACTIVATION, it would try to unwind STATE
+     which would deadlock us.  */
+  Dwarf_Addr pc;
+  bool ok = INTUSE(dwfl_frame_pc) (state, &pc, NULL);
+  assert (ok);
+  /* Check whether this is the initial frame or a signal frame.
+     Then we need to unwind from the original, unadjusted PC.  */
+  if (! state->initial_frame && ! state->signal_frame)
+    pc--;
+  Dwfl_Module *mod = INTUSE(dwfl_addrmodule) (state->thread->process->dwfl, pc);
+  if (mod == NULL)
+    __libdwfl_seterrno (DWFL_E_NO_DWARF);
+  else
+    {
+      Dwarf_Addr bias;
+      Dwarf_CFI *cfi_eh = INTUSE(dwfl_module_eh_cfi) (mod, &bias);
+      if (cfi_eh)
+	{
+	  handle_cfi (state, pc - bias, cfi_eh, bias);
+	  if (state->unwound)
+	    return;
+	}
+      Dwarf_CFI *cfi_dwarf = INTUSE(dwfl_module_dwarf_cfi) (mod, &bias);
+      if (cfi_dwarf)
+	{
+	  handle_cfi (state, pc - bias, cfi_dwarf, bias);
+	  if (state->unwound)
+	    return;
+	}
+    }
+  assert (state->unwound == NULL);
+  Dwfl_Thread *thread = state->thread;
+  Dwfl_Process *process = thread->process;
+  Ebl *ebl = process->ebl;
+  if (new_unwound (state) == NULL)
+    {
+      __libdwfl_seterrno (DWFL_E_NOMEM);
+      return;
+    }
+  state->unwound->pc_state = DWFL_FRAME_STATE_PC_UNDEFINED;
+  // &Dwfl_Frame.signal_frame cannot be passed as it is a bitfield.
+  bool signal_frame = false;
+  if (! ebl_unwind (ebl, pc, setfunc, getfunc, readfunc, state, &signal_frame))
+    {
+      // Discard the unwind attempt.  During next __libdwfl_frame_unwind call
+      // we may have for example the appropriate Dwfl_Module already mapped.
+      assert (state->unwound->unwound == NULL);
+      free (state->unwound);
+      state->unwound = NULL;
+      // __libdwfl_seterrno has been called above.
+      return;
+    }
+  assert (state->unwound->pc_state == DWFL_FRAME_STATE_PC_SET);
+  state->unwound->signal_frame = signal_frame;
+}
diff --git a/third_party/elfutils/libdwfl/gzip.c b/third_party/elfutils/libdwfl/gzip.c
new file mode 100644
index 0000000..c2c13ba
--- /dev/null
+++ b/third_party/elfutils/libdwfl/gzip.c
@@ -0,0 +1,328 @@
+/* Decompression support for libdwfl: zlib (gzip) and/or bzlib (bzip2).
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include "system.h"
+
+#include <unistd.h>
+
+#ifdef LZMA
+# define USE_INFLATE	1
+# include <lzma.h>
+# define unzip		__libdw_unlzma
+# define DWFL_E_ZLIB	DWFL_E_LZMA
+# define MAGIC		"\xFD" "7zXZ\0" /* XZ file format.  */
+# define MAGIC2		"\x5d\0"	/* Raw LZMA format.  */
+# define Z(what)	LZMA_##what
+# define LZMA_ERRNO	LZMA_PROG_ERROR
+# define z_stream	lzma_stream
+# define inflateInit(z)	lzma_auto_decoder (z, 1 << 30, 0)
+# define do_inflate(z)	lzma_code (z, LZMA_RUN)
+# define inflateEnd(z)	lzma_end (z)
+#elif defined BZLIB
+# define USE_INFLATE	1
+# include <bzlib.h>
+# define unzip		__libdw_bunzip2
+# define DWFL_E_ZLIB	DWFL_E_BZLIB
+# define MAGIC		"BZh"
+# define Z(what)	BZ_##what
+# define BZ_ERRNO	BZ_IO_ERROR
+# define z_stream	bz_stream
+# define inflateInit(z)	BZ2_bzDecompressInit (z, 0, 0)
+# define do_inflate(z)	BZ2_bzDecompress (z)
+# define inflateEnd(z)	BZ2_bzDecompressEnd (z)
+#else
+# define USE_INFLATE	0
+# define crc32		loser_crc32
+# include <zlib.h>
+# define unzip		__libdw_gunzip
+# define MAGIC		"\037\213"
+# define Z(what)	Z_##what
+#endif
+
+#define READ_SIZE		(1 << 20)
+
+struct unzip_state {
+#if !USE_INFLATE
+  gzFile zf;
+#endif
+  size_t mapped_size;
+  void **whole;
+  void *buffer;
+  size_t size;
+  void *input_buffer;
+  off_t input_pos;
+};
+
+static inline bool
+bigger_buffer (struct unzip_state *state, size_t start)
+{
+  size_t more = state->size ? state->size * 2 : start;
+  char *b = realloc (state->buffer, more);
+  while (unlikely (b == NULL) && more >= state->size + 1024)
+    b = realloc (state->buffer, more -= 1024);
+  if (unlikely (b == NULL))
+    return false;
+  state->buffer = b;
+  state->size = more;
+  return true;
+}
+
+static inline void
+smaller_buffer (struct unzip_state *state, size_t end)
+{
+  state->buffer =
+      realloc (state->buffer, end) ?: end == 0 ? NULL : state->buffer;
+  state->size = end;
+}
+
+static inline Dwfl_Error
+fail (struct unzip_state *state, Dwfl_Error failure)
+{
+  if (state->input_pos == (off_t) state->mapped_size)
+    *state->whole = state->input_buffer;
+  else
+    {
+      free (state->input_buffer);
+      *state->whole = NULL;
+    }
+  free (state->buffer);
+  return failure;
+}
+
+static inline Dwfl_Error
+zlib_fail (struct unzip_state *state, int result)
+{
+  switch (result)
+    {
+    case Z (MEM_ERROR):
+      return fail (state, DWFL_E_NOMEM);
+    case Z (ERRNO):
+      return fail (state, DWFL_E_ERRNO);
+    default:
+      return fail (state, DWFL_E_ZLIB);
+    }
+}
+
+#if !USE_INFLATE
+static Dwfl_Error
+open_stream (int fd, off_t start_offset, struct unzip_state *state)
+{
+    int d = dup (fd);
+    if (unlikely (d < 0))
+      return DWFL_E_BADELF;
+    if (start_offset != 0)
+      {
+	off_t off = lseek (d, start_offset, SEEK_SET);
+	if (off != start_offset)
+	  {
+	    close (d);
+	    return DWFL_E_BADELF;
+	  }
+      }
+    state->zf = gzdopen (d, "r");
+    if (unlikely (state->zf == NULL))
+      {
+	close (d);
+	return zlib_fail (state, Z (MEM_ERROR));
+      }
+
+    /* From here on, zlib will close D.  */
+
+    return DWFL_E_NOERROR;
+}
+#endif
+
+/* If this is not a compressed image, return DWFL_E_BADELF.
+   If we uncompressed it into *WHOLE, *WHOLE_SIZE, return DWFL_E_NOERROR.
+   Otherwise return an error for bad compressed data or I/O failure.
+   If we return an error after reading the first part of the file,
+   leave that portion malloc'd in *WHOLE, *WHOLE_SIZE.  If *WHOLE
+   is not null on entry, we'll use it in lieu of repeating a read.  */
+
+Dwfl_Error internal_function
+unzip (int fd, off_t start_offset,
+       void *mapped, size_t _mapped_size,
+       void **_whole, size_t *whole_size)
+{
+  struct unzip_state state =
+    {
+#if !USE_INFLATE
+      .zf = NULL,
+#endif
+      .mapped_size = _mapped_size,
+      .whole = _whole,
+      .buffer = NULL,
+      .size = 0,
+      .input_buffer = NULL,
+      .input_pos = 0
+    };
+
+  if (mapped == NULL)
+    {
+      if (*state.whole == NULL)
+	{
+	  state.input_buffer = malloc (READ_SIZE);
+	  if (unlikely (state.input_buffer == NULL))
+	    return DWFL_E_NOMEM;
+
+	  ssize_t n = pread_retry (fd, state.input_buffer, READ_SIZE, start_offset);
+	  if (unlikely (n < 0))
+	    return zlib_fail (&state, Z (ERRNO));
+
+	  state.input_pos = n;
+	  mapped = state.input_buffer;
+	  state.mapped_size = n;
+	}
+      else
+	{
+	  state.input_buffer = *state.whole;
+	  state.input_pos = state.mapped_size = *whole_size;
+	}
+    }
+
+#define NOMAGIC(magic) \
+  (state.mapped_size <= sizeof magic || \
+   memcmp (mapped, magic, sizeof magic - 1))
+
+  /* First, look at the header.  */
+  if (NOMAGIC (MAGIC)
+#ifdef MAGIC2
+      && NOMAGIC (MAGIC2)
+#endif
+      )
+    /* Not a compressed file.  */
+    return DWFL_E_BADELF;
+
+#if USE_INFLATE
+
+  /* This style actually only works with bzlib and liblzma.
+     The stupid zlib interface has nothing to grok the
+     gzip file headers except the slow gzFile interface.  */
+
+  z_stream z = { .next_in = mapped, .avail_in = state.mapped_size };
+  int result = inflateInit (&z);
+  if (result != Z (OK))
+    {
+      inflateEnd (&z);
+      return zlib_fail (&state, result);
+    }
+
+  do
+    {
+      if (z.avail_in == 0 && state.input_buffer != NULL)
+	{
+	  ssize_t n = pread_retry (fd, state.input_buffer, READ_SIZE,
+				   start_offset + state.input_pos);
+	  if (unlikely (n < 0))
+	    {
+	      inflateEnd (&z);
+	      return zlib_fail (&state, Z (ERRNO));
+	    }
+	  z.next_in = state.input_buffer;
+	  z.avail_in = n;
+	  state.input_pos += n;
+	}
+      if (z.avail_out == 0)
+	{
+	  ptrdiff_t pos = (void *) z.next_out - state.buffer;
+	  if (!bigger_buffer (&state, z.avail_in))
+	    {
+	      result = Z (MEM_ERROR);
+	      break;
+	    }
+	  z.next_out = state.buffer + pos;
+	  z.avail_out = state.size - pos;
+	}
+    }
+  while ((result = do_inflate (&z)) == Z (OK));
+
+#ifdef BZLIB
+  uint64_t total_out = (((uint64_t) z.total_out_hi32 << 32)
+			| z.total_out_lo32);
+  smaller_buffer (&state, total_out);
+#else
+  smaller_buffer (&state, z.total_out);
+#endif
+
+  inflateEnd (&z);
+
+  if (result != Z (STREAM_END))
+    return zlib_fail (&state, result);
+
+#else  /* gzip only.  */
+
+  /* Let the decompression library read the file directly.  */
+
+  Dwfl_Error result = open_stream (fd, start_offset, &state);
+
+  if (result == DWFL_E_NOERROR && gzdirect (state.zf))
+    {
+      gzclose (state.zf);
+      return fail (&state, DWFL_E_BADELF);
+    }
+
+  if (result != DWFL_E_NOERROR)
+    return fail (&state, result);
+
+  ptrdiff_t pos = 0;
+  while (1)
+    {
+      if (!bigger_buffer (&state, 1024))
+	{
+	  gzclose (state.zf);
+	  return zlib_fail (&state, Z (MEM_ERROR));
+	}
+      int n = gzread (state.zf, state.buffer + pos, state.size - pos);
+      if (n < 0)
+	{
+	  int code;
+	  gzerror (state.zf, &code);
+	  gzclose (state.zf);
+	  return zlib_fail (&state, code);
+	}
+      if (n == 0)
+	break;
+      pos += n;
+    }
+
+  gzclose (state.zf);
+  smaller_buffer (&state, pos);
+#endif
+
+  free (state.input_buffer);
+
+  *state.whole = state.buffer;
+  *whole_size = state.size;
+
+  return DWFL_E_NOERROR;
+}
diff --git a/third_party/elfutils/libdwfl/image-header.c b/third_party/elfutils/libdwfl/image-header.c
new file mode 100644
index 0000000..25fbfd9
--- /dev/null
+++ b/third_party/elfutils/libdwfl/image-header.c
@@ -0,0 +1,105 @@
+/* Linux kernel image support for libdwfl.
+   Copyright (C) 2009-2011 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include "system.h"
+
+#include <unistd.h>
+#include <endian.h>
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+# define LE16(x)	(x)
+#else
+# define LE16(x)	bswap_16 (x)
+#endif
+
+/* See Documentation/x86/boot.txt in Linux kernel sources
+   for an explanation of these format details.  */
+
+#define MAGIC1			0xaa55
+#define MAGIC2			0x53726448 /* "HdrS" little-endian */
+#define MIN_VERSION		0x0208
+
+#define H_START			(H_SETUP_SECTS & -4)
+#define H_SETUP_SECTS		0x1f1
+#define H_MAGIC1		0x1fe
+#define H_MAGIC2		0x202
+#define H_VERSION		0x206
+#define H_PAYLOAD_OFFSET	0x248
+#define H_PAYLOAD_LENGTH	0x24c
+#define H_END			0x250
+#define H_READ_SIZE		(H_END - H_START)
+
+Dwfl_Error
+internal_function
+__libdw_image_header (int fd, off_t *start_offset,
+		      void *mapped, size_t mapped_size)
+{
+  if (likely (mapped_size > H_END))
+    {
+      const void *header = mapped;
+      char header_buffer[H_READ_SIZE];
+      if (header == NULL)
+	{
+	  ssize_t n = pread_retry (fd, header_buffer, H_READ_SIZE,
+				   *start_offset + H_START);
+	  if (n < 0)
+	    return DWFL_E_ERRNO;
+	  if (n < H_READ_SIZE)
+	    return DWFL_E_BADELF;
+
+	  header = header_buffer - H_START;
+	}
+
+      if (*(uint16_t *) (header + H_MAGIC1) == LE16 (MAGIC1)
+	  && *(uint32_t *) (header + H_MAGIC2) == LE32 (MAGIC2)
+	  && LE16 (*(uint16_t *) (header + H_VERSION)) >= MIN_VERSION)
+	{
+	  /* The magic numbers match and the version field is sufficient.
+	     Extract the payload bounds.  */
+
+	  uint32_t offset = LE32 (*(uint32_t *) (header + H_PAYLOAD_OFFSET));
+	  uint32_t length = LE32 (*(uint32_t *) (header + H_PAYLOAD_LENGTH));
+
+	  offset += ((*(uint8_t *) (header + H_SETUP_SECTS) ?: 4) + 1) * 512;
+
+	  if (offset > H_END && offset < mapped_size
+	      && mapped_size - offset >= length)
+	    {
+	      /* It looks kosher.  Use it!  */
+	      *start_offset += offset;
+	      return DWFL_E_NOERROR;
+	    }
+	}
+    }
+  return DWFL_E_BADELF;
+}
diff --git a/third_party/elfutils/libdwfl/libdwfl.h b/third_party/elfutils/libdwfl/libdwfl.h
new file mode 100644
index 0000000..a0c1d35
--- /dev/null
+++ b/third_party/elfutils/libdwfl/libdwfl.h
@@ -0,0 +1,814 @@
+/* Interfaces for libdwfl.
+   Copyright (C) 2005-2010, 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBDWFL_H
+#define _LIBDWFL_H	1
+
+#include "libdw.h"
+#include <stdio.h>
+
+/* Handle for a session using the library.  */
+typedef struct Dwfl Dwfl;
+
+/* Handle for a module.  */
+typedef struct Dwfl_Module Dwfl_Module;
+
+/* Handle describing a line record.  */
+typedef struct Dwfl_Line Dwfl_Line;
+
+/* This holds information common for all the frames of one backtrace for
+   a partical thread/task/TID.  Several threads belong to one Dwfl.  */
+typedef struct Dwfl_Thread Dwfl_Thread;
+
+/* This holds everything we know about the state of the frame at a particular
+   PC location described by an FDE belonging to Dwfl_Thread.  */
+typedef struct Dwfl_Frame Dwfl_Frame;
+
+/* Callbacks.  */
+typedef struct
+{
+  int (*find_elf) (Dwfl_Module *mod, void **userdata,
+		   const char *modname, Dwarf_Addr base,
+		   char **file_name, Elf **elfp);
+
+  int (*find_debuginfo) (Dwfl_Module *mod, void **userdata,
+			 const char *modname, Dwarf_Addr base,
+			 const char *file_name,
+			 const char *debuglink_file, GElf_Word debuglink_crc,
+			 char **debuginfo_file_name);
+
+  /* Fill *ADDR with the loaded address of the section called SECNAME in
+     the given module.  Use (Dwarf_Addr) -1 if this section is omitted from
+     accessible memory.  This is called exactly once for each SHF_ALLOC
+     section that relocations affecting DWARF data refer to, so it can
+     easily be used to collect state about the sections referenced.  */
+  int (*section_address) (Dwfl_Module *mod, void **userdata,
+			  const char *modname, Dwarf_Addr base,
+			  const char *secname,
+			  GElf_Word shndx, const GElf_Shdr *shdr,
+			  Dwarf_Addr *addr);
+
+  char **debuginfo_path;	/* See dwfl_standard_find_debuginfo.  */
+} Dwfl_Callbacks;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Start a new session with the library.  */
+extern Dwfl *dwfl_begin (const Dwfl_Callbacks *callbacks)
+  __nonnull_attribute__ (1);
+
+
+/* End a session.  */
+extern void dwfl_end (Dwfl *);
+
+/* Return implementation's version string suitable for printing.  */
+extern const char *dwfl_version (Dwfl *);
+
+/* Return error code of last failing function call.  This value is kept
+   separately for each thread.  */
+extern int dwfl_errno (void);
+
+/* Return error string for ERROR.  If ERROR is zero, return error string
+   for most recent error or NULL if none occurred.  If ERROR is -1 the
+   behaviour is similar to the last case except that not NULL but a legal
+   string is returned.  */
+extern const char *dwfl_errmsg (int err);
+
+
+/* Start reporting the current set of segments and modules to the library.
+   All existing segments are wiped.  Existing modules are marked to be
+   deleted, and will not be found via dwfl_addrmodule et al if they are not
+   re-reported before dwfl_report_end is called.  */
+extern void dwfl_report_begin (Dwfl *dwfl);
+
+/* Report that segment NDX begins at PHDR->p_vaddr + BIAS.
+   If NDX is < 0, the value succeeding the last call's NDX
+   is used instead (zero on the first call).
+
+   If nonzero, the smallest PHDR->p_align value seen sets the
+   effective page size for the address space DWFL describes.
+   This is the granularity at which reported module boundary
+   addresses will be considered to fall in or out of a segment.
+
+   Returns -1 for errors, or NDX (or its assigned replacement) on success.
+
+   When NDX is the value succeeding the last call's NDX (or is implicitly
+   so as above), IDENT is nonnull and matches the value in the last call,
+   and the PHDR and BIAS values reflect a segment that would be contiguous,
+   in both memory and file, with the last segment reported, then this
+   segment may be coalesced internally with preceding segments.  When given
+   an address inside this segment, dwfl_addrsegment may return the NDX of a
+   preceding contiguous segment.  To prevent coalesced segments, always
+   pass a null pointer for IDENT.
+
+   The values passed are not stored (except to track coalescence).
+   The only information that can be extracted from DWFL later is the
+   mapping of an address to a segment index that starts at or below
+   it.  Reporting segments at all is optional.  Its only benefit to
+   the caller is to offer this quick lookup via dwfl_addrsegment,
+   or use other segment-based calls.  */
+extern int dwfl_report_segment (Dwfl *dwfl, int ndx,
+				const GElf_Phdr *phdr, GElf_Addr bias,
+				const void *ident);
+
+/* Report that a module called NAME spans addresses [START, END).
+   Returns the module handle, either existing or newly allocated,
+   or returns a null pointer for an allocation error.  */
+extern Dwfl_Module *dwfl_report_module (Dwfl *dwfl, const char *name,
+					Dwarf_Addr start, Dwarf_Addr end);
+
+/* Report a module to address BASE with start and end addresses computed
+   from the ELF program headers in the given file - see the table below.
+   FD may be -1 to open FILE_NAME.  On success, FD is consumed by the
+   library, and the `find_elf' callback will not be used for this module.
+	    ADD_P_VADDR  BASE
+   ET_EXEC  ignored      ignored
+   ET_DYN   false        absolute address where to place the file
+	    true         start address relative to ELF's phdr p_vaddr
+   ET_REL   ignored      absolute address where to place the file
+   ET_CORE  ignored      ignored
+   ET_DYN ELF phdr p_vaddr address can be non-zero if the shared library
+   has been prelinked by tool prelink(8).  */
+extern Dwfl_Module *dwfl_report_elf (Dwfl *dwfl, const char *name,
+				     const char *file_name, int fd,
+				     GElf_Addr base, bool add_p_vaddr);
+
+/* Similar, but report the module for offline use.  All ET_EXEC files
+   being reported must be reported before any relocatable objects.
+   If this is used, dwfl_report_module and dwfl_report_elf may not be
+   used in the same reporting session.  */
+extern Dwfl_Module *dwfl_report_offline (Dwfl *dwfl, const char *name,
+					 const char *file_name, int fd);
+
+
+/* Finish reporting the current set of modules to the library.
+   If REMOVED is not null, it's called for each module that
+   existed before but was not included in the current report.
+   Returns a nonzero return value from the callback.
+   The callback may call dwfl_report_module; doing so with the
+   details of the module being removed prevents its removal.
+   DWFL cannot be used until this function has returned zero.  */
+extern int dwfl_report_end (Dwfl *dwfl,
+			    int (*removed) (Dwfl_Module *, void *,
+					    const char *, Dwarf_Addr,
+					    void *arg),
+			    void *arg);
+
+/* Start reporting additional modules to the library.  No calls but
+   dwfl_report_* can be made on DWFL until dwfl_report_end is called.
+   This is like dwfl_report_begin, but all the old modules are kept on.
+   More dwfl_report_* calls can follow to add more modules.
+   When dwfl_report_end is called, no old modules will be removed.  */
+extern void dwfl_report_begin_add (Dwfl *dwfl);
+
+
+/* Return the name of the module, and for each non-null argument store
+   interesting details: *USERDATA is a location for storing your own
+   pointer, **USERDATA is initially null; *START and *END give the address
+   range covered by the module; *DWBIAS is the address bias for debugging
+   information, and *SYMBIAS for symbol table entries (either is -1 if not
+   yet accessed); *MAINFILE is the name of the ELF file, and *DEBUGFILE the
+   name of the debuginfo file (might be equal to *MAINFILE; either is null
+   if not yet accessed).  */
+extern const char *dwfl_module_info (Dwfl_Module *mod, void ***userdata,
+				     Dwarf_Addr *start, Dwarf_Addr *end,
+				     Dwarf_Addr *dwbias, Dwarf_Addr *symbias,
+				     const char **mainfile,
+				     const char **debugfile);
+
+/* Iterate through the modules, starting the walk with OFFSET == 0.
+   Calls *CALLBACK for each module as long as it returns DWARF_CB_OK.
+   When *CALLBACK returns another value, the walk stops and the
+   return value can be passed as OFFSET to resume it.  Returns 0 when
+   there are no more modules, or -1 for errors.  */
+extern ptrdiff_t dwfl_getmodules (Dwfl *dwfl,
+				  int (*callback) (Dwfl_Module *, void **,
+						   const char *, Dwarf_Addr,
+						   void *arg),
+				  void *arg,
+				  ptrdiff_t offset);
+
+/* Find the module containing the given address.  */
+extern Dwfl_Module *dwfl_addrmodule (Dwfl *dwfl, Dwarf_Addr address);
+
+/* Find the segment, if any, and module, if any, containing ADDRESS.
+   Returns a segment index returned by dwfl_report_segment, or -1
+   if no segment matches the address.  Regardless of the return value,
+   *MOD is always set to the module containing ADDRESS, or to null.  */
+extern int dwfl_addrsegment (Dwfl *dwfl, Dwarf_Addr address, Dwfl_Module **mod);
+
+
+
+/* Report the known build ID bits associated with a module.
+   If VADDR is nonzero, it gives the absolute address where those
+   bits are found within the module.  This can be called at any
+   time, but is usually used immediately after dwfl_report_module.
+   Once the module's main ELF file is opened, the ID note found
+   there takes precedence and cannot be changed.  */
+extern int dwfl_module_report_build_id (Dwfl_Module *mod,
+					const unsigned char *bits, size_t len,
+					GElf_Addr vaddr)
+  __nonnull_attribute__ (2);
+
+/* Extract the build ID bits associated with a module.
+   Returns -1 for errors, 0 if no ID is known, or the number of ID bytes.
+   When an ID is found, *BITS points to it; *VADDR is the absolute address
+   at which the ID bits are found within the module, or 0 if unknown.
+
+   This returns 0 when the module's main ELF file has not yet been loaded
+   and its build ID bits were not reported.  To ensure the ID is always
+   returned when determinable, call dwfl_module_getelf first.  */
+extern int dwfl_module_build_id (Dwfl_Module *mod,
+				 const unsigned char **bits, GElf_Addr *vaddr)
+  __nonnull_attribute__ (2, 3);
+
+
+/*** Standard callbacks ***/
+
+/* These standard find_elf and find_debuginfo callbacks are
+   controlled by a string specifying directories to look in.
+   If `debuginfo_path' is set in the Dwfl_Callbacks structure
+   and the char * it points to is not null, that supplies the
+   string.  Otherwise a default path is used.
+
+   If the first character of the string is + or - that enables or
+   disables CRC32 checksum validation when it's necessary.  The
+   remainder of the string is composed of elements separated by
+   colons.  Each element can start with + or - to override the
+   global checksum behavior.  This flag is never relevant when
+   working with build IDs, but it's always parsed in the path
+   string.  The remainder of the element indicates a directory.
+
+   Searches by build ID consult only the elements naming absolute
+   directory paths.  They look under those directories for a link
+   named ".build-id/xx/yy" or ".build-id/xx/yy.debug", where "xxyy"
+   is the lower-case hexadecimal representation of the ID bytes.
+
+   In searches for debuginfo by name, if the remainder of the
+   element is empty, the directory containing the main file is
+   tried; if it's an absolute path name, the absolute directory path
+   (and any subdirectory of that path) containing the main file is
+   taken as a subdirectory of this path; a relative path name is taken
+   as a subdirectory of the directory containing the main file.
+   Hence for /usr/bin/ls, the default string ":.debug:/usr/lib/debug"
+   says to look in /usr/bin, then /usr/bin/.debug, then the path subdirs
+   under /usr/lib/debug, in the order /usr/lib/debug/usr/bin, then
+   /usr/lib/debug/bin, and finally /usr/lib/debug, for the file name in
+   the .gnu_debuglink section (or "ls.debug" if none was found).  */
+
+/* Standard find_elf callback function working solely on build ID.
+   This can be tried first by any find_elf callback, to use the
+   bits passed to dwfl_module_report_build_id, if any.  */
+extern int dwfl_build_id_find_elf (Dwfl_Module *, void **,
+				   const char *, Dwarf_Addr,
+				   char **, Elf **);
+
+/* Standard find_debuginfo callback function working solely on build ID.
+   This can be tried first by any find_debuginfo callback,
+   to use the build ID bits from the main file when present.  */
+extern int dwfl_build_id_find_debuginfo (Dwfl_Module *, void **,
+					 const char *, Dwarf_Addr,
+					 const char *, const char *,
+					 GElf_Word, char **);
+
+/* Standard find_debuginfo callback function.
+   If a build ID is available, this tries first to use that.
+   If there is no build ID or no valid debuginfo found by ID,
+   it searches the debuginfo path by name, as described above.
+   Any file found in the path is validated by build ID if possible,
+   or else by CRC32 checksum if enabled, and skipped if it does not match.  */
+extern int dwfl_standard_find_debuginfo (Dwfl_Module *, void **,
+					 const char *, Dwarf_Addr,
+					 const char *, const char *,
+					 GElf_Word, char **);
+
+
+/* This callback must be used when using dwfl_offline_* to report modules,
+   if ET_REL is to be supported.  */
+extern int dwfl_offline_section_address (Dwfl_Module *, void **,
+					 const char *, Dwarf_Addr,
+					 const char *, GElf_Word,
+					 const GElf_Shdr *,
+					 Dwarf_Addr *addr);
+
+
+/* Callbacks for working with kernel modules in the running Linux kernel.  */
+extern int dwfl_linux_kernel_find_elf (Dwfl_Module *, void **,
+				       const char *, Dwarf_Addr,
+				       char **, Elf **);
+extern int dwfl_linux_kernel_module_section_address (Dwfl_Module *, void **,
+						     const char *, Dwarf_Addr,
+						     const char *, GElf_Word,
+						     const GElf_Shdr *,
+						     Dwarf_Addr *addr);
+
+/* Call dwfl_report_elf for the running Linux kernel.
+   Returns zero on success, -1 if dwfl_report_module failed,
+   or an errno code if opening the kernel binary failed.  */
+extern int dwfl_linux_kernel_report_kernel (Dwfl *dwfl);
+
+/* Call dwfl_report_module for each kernel module in the running Linux kernel.
+   Returns zero on success, -1 if dwfl_report_module failed,
+   or an errno code if reading the list of modules failed.  */
+extern int dwfl_linux_kernel_report_modules (Dwfl *dwfl);
+
+/* Report a kernel and its modules found on disk, for offline use.
+   If RELEASE starts with '/', it names a directory to look in;
+   if not, it names a directory to find under /lib/modules/;
+   if null, /lib/modules/`uname -r` is used.
+   Returns zero on success, -1 if dwfl_report_module failed,
+   or an errno code if finding the files on disk failed.
+
+   If PREDICATE is not null, it is called with each module to be reported;
+   its arguments are the module name, and the ELF file name or null if unknown,
+   and its return value should be zero to skip the module, one to report it,
+   or -1 to cause the call to fail and return errno.  */
+extern int dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release,
+					     int (*predicate) (const char *,
+							       const char *));
+
+/* Examine an ET_CORE file and report modules based on its contents.
+   This can follow a dwfl_report_offline call to bootstrap the
+   DT_DEBUG method of following the dynamic linker link_map chain, in
+   case the core file does not contain enough of the executable's text
+   segment to locate its PT_DYNAMIC in the dump.  In such case you need to
+   supply non-NULL EXECUTABLE, otherwise dynamic libraries will not be loaded
+   into the DWFL map.  This might call dwfl_report_elf on file names found in
+   the dump if reading some link_map files is the only way to ascertain those
+   modules' addresses.  Returns the number of modules reported, or -1 for
+   errors.  */
+extern int dwfl_core_file_report (Dwfl *dwfl, Elf *elf, const char *executable);
+
+/* Call dwfl_report_module for each file mapped into the address space of PID.
+   Returns zero on success, -1 if dwfl_report_module failed,
+   or an errno code if opening the proc files failed.  */
+extern int dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid);
+
+/* Similar, but reads an input stream in the format of Linux /proc/PID/maps
+   files giving module layout, not the file for a live process.  */
+extern int dwfl_linux_proc_maps_report (Dwfl *dwfl, FILE *);
+
+/* Trivial find_elf callback for use with dwfl_linux_proc_report.
+   This uses the module name as a file name directly and tries to open it
+   if it begin with a slash, or handles the magic string "[vdso]".  */
+extern int dwfl_linux_proc_find_elf (Dwfl_Module *mod, void **userdata,
+				     const char *module_name, Dwarf_Addr base,
+				     char **file_name, Elf **);
+
+/* Standard argument parsing for using a standard callback set.  */
+struct argp;
+extern const struct argp *dwfl_standard_argp (void) __const_attribute__;
+
+
+/*** Relocation of addresses from Dwfl ***/
+
+/* Return the number of relocatable bases associated with the module,
+   which is zero for ET_EXEC and one for ET_DYN.  Returns -1 for errors.  */
+extern int dwfl_module_relocations (Dwfl_Module *mod);
+
+/* Return the relocation base index associated with the *ADDRESS location,
+   and adjust *ADDRESS to be an offset relative to that base.
+   Returns -1 for errors.  */
+extern int dwfl_module_relocate_address (Dwfl_Module *mod,
+					 Dwarf_Addr *address);
+
+/* Return the ELF section name for the given relocation base index;
+   if SHNDXP is not null, set *SHNDXP to the ELF section index.
+   For ET_DYN, returns "" and sets *SHNDXP to SHN_ABS; the relocation
+   base is the runtime start address reported for the module.
+   Returns null for errors.  */
+extern const char *dwfl_module_relocation_info (Dwfl_Module *mod,
+						unsigned int idx,
+						GElf_Word *shndxp);
+
+/* Validate that ADDRESS and ADDRESS+OFFSET lie in a known module
+   and both within the same contiguous region for relocation purposes.
+   Returns zero for success and -1 for errors.  */
+extern int dwfl_validate_address (Dwfl *dwfl,
+				  Dwarf_Addr address, Dwarf_Sword offset);
+
+
+/*** ELF access functions ***/
+
+/* Fetch the module main ELF file (where the allocated sections
+   are found) for use with libelf.  If successful, fills in *BIAS
+   with the difference between addresses within the loaded module
+   and those in symbol tables or Dwarf information referring to it.  */
+extern Elf *dwfl_module_getelf (Dwfl_Module *, GElf_Addr *bias)
+  __nonnull_attribute__ (2);
+
+/* Return the number of symbols in the module's symbol table,
+   or -1 for errors.  */
+extern int dwfl_module_getsymtab (Dwfl_Module *mod);
+
+/* Return the index of the first global symbol in the module's symbol
+   table, or -1 for errors.  In each symbol table, all symbols with
+   STB_LOCAL binding precede the weak and global symbols.  This
+   function returns the symbol table index one greater than the last
+   local symbol.  */
+extern int dwfl_module_getsymtab_first_global (Dwfl_Module *mod);
+
+/* Fetch one entry from the module's symbol table.  On errors, returns
+   NULL.  If successful, fills in *SYM and returns the string for st_name.
+   This works like gelf_getsym except that st_value is always adjusted to
+   an absolute value based on the module's location, when the symbol is in
+   an SHF_ALLOC section.  If SHNDXP is non-null, it's set with the section
+   index (whether from st_shndx or extended index table); in case of a
+   symbol in a non-allocated section, *SHNDXP is instead set to -1.
+   Note that since symbols can come from either the main, debug or auxiliary
+   ELF symbol file (either dynsym or symtab) the section index can only
+   be reliably used to compare against special section constants like
+   SHN_UNDEF or SHN_ABS.  It is recommended to use dwfl_module_getsym_info
+   which doesn't have these deficiencies.  */
+extern const char *dwfl_module_getsym (Dwfl_Module *mod, int ndx,
+				       GElf_Sym *sym, GElf_Word *shndxp)
+  __nonnull_attribute__ (3);
+
+/* Fetch one entry from the module's symbol table and the associated
+   address value.  On errors, returns NULL.  If successful, fills in
+   *SYM, *ADDR and returns the string for st_name.  This works like
+   gelf_getsym.  *ADDR is set to the st_value adjusted to an absolute
+   value based on the module's location, when the symbol is in an
+   SHF_ALLOC section.  For non-ET_REL files, if the arch uses function
+   descriptors, and the st_value points to one, *ADDR will be resolved
+   to the actual function entry address.  The SYM->ST_VALUE itself
+   isn't adjusted in any way.  Fills in ELFP, if not NULL, with the
+   ELF file the symbol originally came from.  Note that symbols can
+   come from either the main, debug or auxiliary ELF symbol file
+   (either dynsym or symtab).  If SHNDXP is non-null, it's set with
+   the section index (whether from st_shndx or extended index table);
+   in case of a symbol in a non-allocated section, *SHNDXP is instead
+   set to -1.  Fills in BIAS, if not NULL, with the difference between
+   addresses within the loaded module and those in symbol table of the
+   ELF file.  Note that the address associated with the symbol might
+   be in a different section than the returned symbol.  The section in
+   the main elf file in which returned ADDR falls can be found with
+   dwfl_module_address_section.  */
+extern const char *dwfl_module_getsym_info (Dwfl_Module *mod, int ndx,
+					    GElf_Sym *sym, GElf_Addr *addr,
+					    GElf_Word *shndxp,
+					    Elf **elfp, Dwarf_Addr *bias)
+  __nonnull_attribute__ (3, 4);
+
+/* Find the symbol that ADDRESS lies inside, and return its name.  */
+extern const char *dwfl_module_addrname (Dwfl_Module *mod, GElf_Addr address);
+
+/* Find the symbol associated with ADDRESS.  Return its name or NULL
+   when nothing was found.  If the architecture uses function
+   descriptors, and symbol st_value points to one, ADDRESS wil be
+   matched against either the adjusted st_value or the associated
+   function entry value as described in dwfl_module_getsym_info.  If
+   OFFSET is not NULL it will be filled in with the difference from
+   the start of the symbol (or function entry).  If SYM is not NULL it
+   is filled in with the symbol associated with the matched ADDRESS.
+   The SYM->ST_VALUE itself isn't adjusted in any way.  Fills in ELFP,
+   if not NULL, with the ELF file the symbol originally came from.
+   Note that symbols can come from either the main, debug or auxiliary
+   ELF symbol file (either dynsym or symtab).  If SHNDXP is non-null,
+   it's set with the section index (whether from st_shndx or extended
+   index table).  Fills in BIAS, if not NULL, with the difference
+   between addresses within the loaded module and those in symbol
+   table of the ELF file.  Note that the address matched against the
+   symbol might be in a different section than the returned symbol.
+   The section in the main elf file in ADDRESS falls can be found with
+   dwfl_module_address_section.  */
+extern const char *dwfl_module_addrinfo (Dwfl_Module *mod, GElf_Addr address,
+					 GElf_Off *offset, GElf_Sym *sym,
+					 GElf_Word *shndxp, Elf **elfp,
+					 Dwarf_Addr *bias)
+  __nonnull_attribute__ (3);
+
+/* Find the symbol that ADDRESS lies inside, and return detailed
+   information as for dwfl_module_getsym (above).  Note that like
+   dwfl_module_getsym this function also adjusts SYM->ST_VALUE to an
+   absolute value based on the module's location.  ADDRESS is only
+   matched against this adjusted SYM->ST_VALUE.  This means that
+   depending on architecture this might only match symbols that
+   represent function descriptor addresses (and not function entry
+   addresses).  For these reasons it is recommended to use
+   dwfl_module_addrinfo instead.  */
+extern const char *dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr address,
+					GElf_Sym *sym, GElf_Word *shndxp)
+  __nonnull_attribute__ (3);
+
+/* Find the ELF section that *ADDRESS lies inside and return it.
+   On success, adjusts *ADDRESS to be relative to the section,
+   and sets *BIAS to the difference between addresses used in
+   the returned section's headers and run-time addresses.  */
+extern Elf_Scn *dwfl_module_address_section (Dwfl_Module *mod,
+					     Dwarf_Addr *address,
+					     Dwarf_Addr *bias)
+  __nonnull_attribute__ (2, 3);
+
+
+/*** Dwarf access functions ***/
+
+/* Fetch the module's debug information for use with libdw.
+   If successful, fills in *BIAS with the difference between
+   addresses within the loaded module and those  to use with libdw.  */
+extern Dwarf *dwfl_module_getdwarf (Dwfl_Module *, Dwarf_Addr *bias)
+     __nonnull_attribute__ (2);
+
+/* Get the libdw handle for each module.  */
+extern ptrdiff_t dwfl_getdwarf (Dwfl *,
+				int (*callback) (Dwfl_Module *, void **,
+						 const char *, Dwarf_Addr,
+						 Dwarf *, Dwarf_Addr, void *),
+				void *arg, ptrdiff_t offset);
+
+/* Look up the module containing ADDR and return its debugging information,
+   loading it if necessary.  */
+extern Dwarf *dwfl_addrdwarf (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias)
+     __nonnull_attribute__ (3);
+
+
+/* Find the CU containing ADDR and return its DIE.  */
+extern Dwarf_Die *dwfl_addrdie (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Addr *bias)
+     __nonnull_attribute__ (3);
+extern Dwarf_Die *dwfl_module_addrdie (Dwfl_Module *mod,
+				       Dwarf_Addr addr, Dwarf_Addr *bias)
+     __nonnull_attribute__ (3);
+
+/* Iterate through the CUs, start with null for LASTCU.  */
+extern Dwarf_Die *dwfl_nextcu (Dwfl *dwfl, Dwarf_Die *lastcu, Dwarf_Addr *bias)
+     __nonnull_attribute__ (3);
+extern Dwarf_Die *dwfl_module_nextcu (Dwfl_Module *mod,
+				      Dwarf_Die *lastcu, Dwarf_Addr *bias)
+     __nonnull_attribute__ (3);
+
+/* Return the module containing the CU DIE.  */
+extern Dwfl_Module *dwfl_cumodule (Dwarf_Die *cudie);
+
+
+/* Cache the source line information fo the CU and return the
+   number of Dwfl_Line entries it has.  */
+extern int dwfl_getsrclines (Dwarf_Die *cudie, size_t *nlines);
+
+/* Access one line number entry within the CU.  */
+extern Dwfl_Line *dwfl_onesrcline (Dwarf_Die *cudie, size_t idx);
+
+/* Get source for address.  */
+extern Dwfl_Line *dwfl_module_getsrc (Dwfl_Module *mod, Dwarf_Addr addr);
+extern Dwfl_Line *dwfl_getsrc (Dwfl *dwfl, Dwarf_Addr addr);
+
+/* Get address for source.  */
+extern int dwfl_module_getsrc_file (Dwfl_Module *mod,
+				    const char *fname, int lineno, int column,
+				    Dwfl_Line ***srcsp, size_t *nsrcs);
+
+/* Return the module containing this line record.  */
+extern Dwfl_Module *dwfl_linemodule (Dwfl_Line *line);
+
+/* Return the CU containing this line record.  */
+extern Dwarf_Die *dwfl_linecu (Dwfl_Line *line);
+
+/* Return the source file name and fill in other information.
+   Arguments may be null for unneeded fields.  */
+extern const char *dwfl_lineinfo (Dwfl_Line *line, Dwarf_Addr *addr,
+				  int *linep, int *colp,
+				  Dwarf_Word *mtime, Dwarf_Word *length);
+
+  /* Return the equivalent Dwarf_Line and the bias to apply to its address.  */
+extern Dwarf_Line *dwfl_dwarf_line (Dwfl_Line *line, Dwarf_Addr *bias);
+
+/* Return the compilation directory (AT_comp_dir) from this line's CU.  */
+extern const char *dwfl_line_comp_dir (Dwfl_Line *line);
+
+
+/*** Machine backend access functions ***/
+
+/* Return location expression to find return value given a
+   DW_TAG_subprogram, DW_TAG_subroutine_type, or similar DIE describing
+   function itself (whose DW_AT_type attribute describes its return type).
+   The given DIE must come from the given module.  Returns -1 for errors.
+   Returns zero if the function has no return value (e.g. "void" in C).
+   Otherwise, *LOCOPS gets a location expression to find the return value,
+   and returns the number of operations in the expression.  The pointer is
+   permanently allocated at least as long as the module is live.  */
+extern int dwfl_module_return_value_location (Dwfl_Module *mod,
+					      Dwarf_Die *functypedie,
+					      const Dwarf_Op **locops);
+
+/* Enumerate the DWARF register numbers and their names.
+   For each register, CALLBACK gets its DWARF number, a string describing
+   the register set (such as "integer" or "FPU"), a prefix used in
+   assembler syntax (such as "%" or "$", may be ""), and the name for the
+   register (contains identifier characters only, possibly all digits).
+   The REGNAME string is valid only during the callback. */
+extern int dwfl_module_register_names (Dwfl_Module *mod,
+				       int (*callback) (void *arg,
+							int regno,
+							const char *setname,
+							const char *prefix,
+							const char *regname,
+							int bits, int type),
+				       void *arg);
+
+
+/* Find the CFI for this module.  Returns NULL if there is no CFI.
+   On success, fills in *BIAS with the difference between addresses
+   within the loaded module and those in the CFI referring to it.
+   The pointer returned can be used until the module is cleaned up.
+   Calling these more than once returns the same pointers.
+
+   dwfl_module_dwarf_cfi gets the '.debug_frame' information found with the
+   rest of the DWARF information.  dwfl_module_eh_cfi gets the '.eh_frame'
+   information found linked into the text.  A module might have either or
+   both.  */
+extern Dwarf_CFI *dwfl_module_dwarf_cfi (Dwfl_Module *mod, Dwarf_Addr *bias);
+extern Dwarf_CFI *dwfl_module_eh_cfi (Dwfl_Module *mod, Dwarf_Addr *bias);
+
+
+typedef struct
+{
+  /* Called to iterate through threads.  Returns next TID (thread ID) on
+     success, a negative number on failure and zero if there are no more
+     threads.  dwfl_errno () should be set if negative number has been
+     returned.  *THREAD_ARGP is NULL on first call, and may be optionally
+     set by the implementation. The value set by the implementation will
+     be passed in on the next call to NEXT_THREAD.  THREAD_ARGP is never
+     NULL.  *THREAD_ARGP will be passed to set_initial_registers or
+     thread_detach callbacks together with Dwfl_Thread *thread.  This
+     method must not be NULL.  */
+  pid_t (*next_thread) (Dwfl *dwfl, void *dwfl_arg, void **thread_argp)
+    __nonnull_attribute__ (1);
+
+  /* Called to get a specific thread.  Returns true if there is a
+     thread with the given thread id number, returns false if no such
+     thread exists and will set dwfl_errno in that case.  THREAD_ARGP
+     is never NULL.  *THREAD_ARGP will be passed to
+     set_initial_registers or thread_detach callbacks together with
+     Dwfl_Thread *thread.  This method may be NULL and will then be
+     emulated using the next_thread callback. */
+  bool (*get_thread) (Dwfl *dwfl, pid_t tid, void *dwfl_arg,
+		      void **thread_argp)
+    __nonnull_attribute__ (1);
+
+  /* Called during unwinding to access memory (stack) state.  Returns true for
+     successfully read *RESULT or false and sets dwfl_errno () on failure.
+     This method may be NULL - in such case dwfl_thread_getframes will return
+     only the initial frame.  */
+  bool (*memory_read) (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result,
+                       void *dwfl_arg)
+    __nonnull_attribute__ (1, 3);
+
+  /* Called on initial unwind to get the initial register state of the first
+     frame.  Should call dwfl_thread_state_registers, possibly multiple times
+     for different ranges and possibly also dwfl_thread_state_register_pc, to
+     fill in initial (DWARF) register values.  After this call, till at least
+     thread_detach is called, the thread is assumed to be frozen, so that it is
+     safe to unwind.  Returns true on success or false and sets dwfl_errno ()
+     on failure.  In the case of a failure thread_detach will not be called.
+     This method must not be NULL.  */
+  bool (*set_initial_registers) (Dwfl_Thread *thread, void *thread_arg)
+    __nonnull_attribute__ (1);
+
+  /* Called by dwfl_end.  All thread_detach method calls have been already
+     done.  This method may be NULL.  */
+  void (*detach) (Dwfl *dwfl, void *dwfl_arg)
+    __nonnull_attribute__ (1);
+
+  /* Called when unwinding is done.  No callback will be called after
+     this method has been called.  Iff set_initial_registers was called for
+     a TID and it returned success thread_detach will be called before the
+     detach method above.  This method may be NULL.  */
+  void (*thread_detach) (Dwfl_Thread *thread, void *thread_arg)
+    __nonnull_attribute__ (1);
+} Dwfl_Thread_Callbacks;
+
+/* PID is the process id associated with the DWFL state.  Architecture of DWFL
+   modules is specified by ELF, ELF must remain valid during DWFL lifetime.
+   Use NULL ELF to detect architecture from DWFL, the function will then detect
+   it from arbitrary Dwfl_Module of DWFL.  DWFL_ARG is the callback backend
+   state.  DWFL_ARG will be provided to the callbacks.  *THREAD_CALLBACKS
+   function pointers must remain valid during lifetime of DWFL.  Function
+   returns true on success, false otherwise.  */
+bool dwfl_attach_state (Dwfl *dwfl, Elf *elf, pid_t pid,
+                        const Dwfl_Thread_Callbacks *thread_callbacks,
+			void *dwfl_arg)
+  __nonnull_attribute__ (1, 4);
+
+/* Calls dwfl_attach_state with Dwfl_Thread_Callbacks setup for extracting
+   thread state from the ELF core file.  Returns the pid number extracted
+   from the core file, or -1 for errors.  */
+extern int dwfl_core_file_attach (Dwfl *dwfl, Elf *elf);
+
+/* Calls dwfl_attach_state with Dwfl_Thread_Callbacks setup for extracting
+   thread state from the proc file system.  Uses ptrace to attach and stop
+   the thread under inspection and detaches when thread_detach is called
+   and unwinding for the thread is done, unless ASSUME_PTRACE_STOPPED is
+   true.  If ASSUME_PTRACE_STOPPED is true the caller should make sure that
+   the thread is ptrace attached and stopped before unwinding by calling
+   either dwfl_thread_getframes or dwfl_getthread_frames.  Returns zero on
+   success, -1 if dwfl_attach_state failed, or an errno code if opening the
+   proc files failed.  */
+extern int dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid,
+				   bool assume_ptrace_stopped);
+
+/* Return PID for the process associated with DWFL.  Function returns -1 if
+   dwfl_attach_state was not called for DWFL.  */
+pid_t dwfl_pid (Dwfl *dwfl)
+  __nonnull_attribute__ (1);
+
+/* Return DWFL from which THREAD was created using dwfl_getthreads.  */
+Dwfl *dwfl_thread_dwfl (Dwfl_Thread *thread)
+  __nonnull_attribute__ (1);
+
+/* Return positive TID (thread ID) for THREAD.  This function never fails.  */
+pid_t dwfl_thread_tid (Dwfl_Thread *thread)
+  __nonnull_attribute__ (1);
+
+/* Return thread for frame STATE.  This function never fails.  */
+Dwfl_Thread *dwfl_frame_thread (Dwfl_Frame *state)
+  __nonnull_attribute__ (1);
+
+/* Called by Dwfl_Thread_Callbacks.set_initial_registers implementation.
+   For every known continuous block of registers <FIRSTREG..FIRSTREG+NREGS)
+   (inclusive..exclusive) set their content to REGS (array of NREGS items).
+   Function returns false if any of the registers has invalid number.  */
+bool dwfl_thread_state_registers (Dwfl_Thread *thread, int firstreg,
+                                  unsigned nregs, const Dwarf_Word *regs)
+  __nonnull_attribute__ (1, 4);
+
+/* Called by Dwfl_Thread_Callbacks.set_initial_registers implementation.
+   If PC is not contained among DWARF registers passed by
+   dwfl_thread_state_registers on the target architecture pass the PC value
+   here.  */
+void dwfl_thread_state_register_pc (Dwfl_Thread *thread, Dwarf_Word pc)
+  __nonnull_attribute__ (1);
+
+/* Iterate through the threads for a process.  Returns zero if all threads have
+   been processed by the callback, returns -1 on error, or the value of the
+   callback when not DWARF_CB_OK.  -1 returned on error will set dwfl_errno ().
+   Keeps calling the callback with the next thread while the callback returns
+   DWARF_CB_OK, till there are no more threads.  */
+int dwfl_getthreads (Dwfl *dwfl,
+		     int (*callback) (Dwfl_Thread *thread, void *arg),
+		     void *arg)
+  __nonnull_attribute__ (1, 2);
+
+/* Iterate through the frames for a thread.  Returns zero if all frames
+   have been processed by the callback, returns -1 on error, or the value of
+   the callback when not DWARF_CB_OK.  -1 returned on error will
+   set dwfl_errno ().  Some systems return error instead of zero on end of the
+   backtrace, for cross-platform compatibility callers should consider error as
+   a zero.  Keeps calling the callback with the next frame while the callback
+   returns DWARF_CB_OK, till there are no more frames.  On start will call the
+   set_initial_registers callback and on return will call the detach_thread
+   callback of the Dwfl_Thread.  */
+int dwfl_thread_getframes (Dwfl_Thread *thread,
+			   int (*callback) (Dwfl_Frame *state, void *arg),
+			   void *arg)
+  __nonnull_attribute__ (1, 2);
+
+/* Like dwfl_thread_getframes, but specifying the thread by its unique
+   identifier number.  Returns zero if all frames have been processed
+   by the callback, returns -1 on error (and when no thread with
+   the given thread id number exists), or the value of the callback
+   when not DWARF_CB_OK.  -1 returned on error will set dwfl_errno ().  */
+int dwfl_getthread_frames (Dwfl *dwfl, pid_t tid,
+			   int (*callback) (Dwfl_Frame *thread, void *arg),
+			   void *arg)
+  __nonnull_attribute__ (1, 3);
+
+/* Return *PC (program counter) for thread-specific frame STATE.
+   Set *ISACTIVATION according to DWARF frame "activation" definition.
+   Typically you need to substract 1 from *PC if *ACTIVATION is false to safely
+   find function of the caller.  ACTIVATION may be NULL.  PC must not be NULL.
+   Function returns false if it failed to find *PC.  */
+bool dwfl_frame_pc (Dwfl_Frame *state, Dwarf_Addr *pc, bool *isactivation)
+  __nonnull_attribute__ (1, 2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* libdwfl.h */
diff --git a/third_party/elfutils/libdwfl/libdwflP.h b/third_party/elfutils/libdwfl/libdwflP.h
new file mode 100644
index 0000000..7d5f795
--- /dev/null
+++ b/third_party/elfutils/libdwfl/libdwflP.h
@@ -0,0 +1,772 @@
+/* Internal definitions for libdwfl.
+   Copyright (C) 2005-2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBDWFLP_H
+#define _LIBDWFLP_H	1
+
+#include <libdwfl.h>
+#include <libebl.h>
+#include <assert.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../libdw/libdwP.h"	/* We need its INTDECLs.  */
+#include "../libdwelf/libdwelfP.h"
+
+typedef struct Dwfl_Process Dwfl_Process;
+
+/* gettext helper macros.  */
+#define _(Str) dgettext ("elfutils", Str)
+
+#define DWFL_ERRORS							      \
+  DWFL_ERROR (NOERROR, N_("no error"))					      \
+  DWFL_ERROR (UNKNOWN_ERROR, N_("unknown error"))			      \
+  DWFL_ERROR (NOMEM, N_("out of memory"))				      \
+  DWFL_ERROR (ERRNO, N_("See errno"))					      \
+  DWFL_ERROR (LIBELF, N_("See elf_errno"))				      \
+  DWFL_ERROR (LIBDW, N_("See dwarf_errno"))				      \
+  DWFL_ERROR (LIBEBL, N_("See ebl_errno (XXX missing)"))		      \
+  DWFL_ERROR (ZLIB, N_("gzip decompression failed"))			      \
+  DWFL_ERROR (BZLIB, N_("bzip2 decompression failed"))			      \
+  DWFL_ERROR (LZMA, N_("LZMA decompression failed"))			      \
+  DWFL_ERROR (UNKNOWN_MACHINE, N_("no support library found for machine"))    \
+  DWFL_ERROR (NOREL, N_("Callbacks missing for ET_REL file"))		      \
+  DWFL_ERROR (BADRELTYPE, N_("Unsupported relocation type"))		      \
+  DWFL_ERROR (BADRELOFF, N_("r_offset is bogus"))			      \
+  DWFL_ERROR (BADSTROFF, N_("offset out of range"))			      \
+  DWFL_ERROR (RELUNDEF, N_("relocation refers to undefined symbol"))	      \
+  DWFL_ERROR (CB, N_("Callback returned failure"))			      \
+  DWFL_ERROR (NO_DWARF, N_("No DWARF information found"))		      \
+  DWFL_ERROR (NO_SYMTAB, N_("No symbol table found"))			      \
+  DWFL_ERROR (NO_PHDR, N_("No ELF program headers"))			      \
+  DWFL_ERROR (OVERLAP, N_("address range overlaps an existing module"))	      \
+  DWFL_ERROR (ADDR_OUTOFRANGE, N_("address out of range"))		      \
+  DWFL_ERROR (NO_MATCH, N_("no matching address range"))		      \
+  DWFL_ERROR (TRUNCATED, N_("image truncated"))				      \
+  DWFL_ERROR (ALREADY_ELF, N_("ELF file opened"))			      \
+  DWFL_ERROR (BADELF, N_("not a valid ELF file"))			      \
+  DWFL_ERROR (WEIRD_TYPE, N_("cannot handle DWARF type description"))	      \
+  DWFL_ERROR (WRONG_ID_ELF, N_("ELF file does not match build ID"))	      \
+  DWFL_ERROR (BAD_PRELINK, N_("corrupt .gnu.prelink_undo section data"))      \
+  DWFL_ERROR (LIBEBL_BAD, N_("Internal error due to ebl"))		      \
+  DWFL_ERROR (CORE_MISSING, N_("Missing data in core file"))		      \
+  DWFL_ERROR (INVALID_REGISTER, N_("Invalid register"))			      \
+  DWFL_ERROR (PROCESS_MEMORY_READ, N_("Error reading process memory"))	      \
+  DWFL_ERROR (PROCESS_NO_ARCH, N_("Couldn't find architecture of any ELF"))   \
+  DWFL_ERROR (PARSE_PROC, N_("Error parsing /proc filesystem"))		      \
+  DWFL_ERROR (INVALID_DWARF, N_("Invalid DWARF"))			      \
+  DWFL_ERROR (UNSUPPORTED_DWARF, N_("Unsupported DWARF"))		      \
+  DWFL_ERROR (NEXT_THREAD_FAIL, N_("Unable to find more threads"))	      \
+  DWFL_ERROR (ATTACH_STATE_CONFLICT, N_("Dwfl already has attached state"))   \
+  DWFL_ERROR (NO_ATTACH_STATE, N_("Dwfl has no attached state"))	      \
+  DWFL_ERROR (NO_UNWIND, N_("Unwinding not supported for this architecture")) \
+  DWFL_ERROR (INVALID_ARGUMENT, N_("Invalid argument"))			      \
+  DWFL_ERROR (NO_CORE_FILE, N_("Not an ET_CORE ELF file"))
+
+#define DWFL_ERROR(name, text) DWFL_E_##name,
+typedef enum { DWFL_ERRORS DWFL_E_NUM } Dwfl_Error;
+#undef	DWFL_ERROR
+
+#define OTHER_ERROR(name)	((unsigned int) DWFL_E_##name << 16)
+#define DWFL_E(name, errno)	(OTHER_ERROR (name) | (errno))
+
+extern int __libdwfl_canon_error (Dwfl_Error) internal_function;
+extern void __libdwfl_seterrno (Dwfl_Error) internal_function;
+
+/* Resources we might keep for the user about the core file that the
+   Dwfl might have been created from.  Can currently only be set
+   through std-argp.  */
+struct Dwfl_User_Core
+{
+  char *executable_for_core;	/* --executable if --core was specified.  */
+  Elf *core;                    /* non-NULL if we need to free it.  */
+  int fd;                       /* close if >= 0.  */
+};
+
+struct Dwfl
+{
+  const Dwfl_Callbacks *callbacks;
+
+  Dwfl_Module *modulelist;    /* List in order used by full traversals.  */
+
+  Dwfl_Process *process;
+  Dwfl_Error attacherr;      /* Previous error attaching process.  */
+
+  GElf_Addr offline_next_address;
+
+  GElf_Addr segment_align;	/* Smallest granularity of segments.  */
+
+  /* Binary search table in three parallel malloc'd arrays.  */
+  size_t lookup_elts;		/* Elements in use.  */
+  size_t lookup_alloc;		/* Elements allococated.  */
+  GElf_Addr *lookup_addr;	/* Start address of segment.  */
+  Dwfl_Module **lookup_module;	/* Module associated with segment, or null.  */
+  int *lookup_segndx;		/* User segment index, or -1.  */
+
+  /* Cache from last dwfl_report_segment call.  */
+  const void *lookup_tail_ident;
+  GElf_Off lookup_tail_vaddr;
+  GElf_Off lookup_tail_offset;
+  int lookup_tail_ndx;
+
+  struct Dwfl_User_Core *user_core;
+};
+
+#define OFFLINE_REDZONE		0x10000
+
+struct dwfl_file
+{
+  char *name;
+  int fd;
+  bool valid;			/* The build ID note has been matched.  */
+  bool relocated;		/* Partial relocation of all sections done.  */
+
+  Elf *elf;
+
+  /* This is the lowest p_vaddr in this ELF file, aligned to p_align.
+     For a file without phdrs, this is zero.  */
+  GElf_Addr vaddr;
+
+  /* This is an address chosen for synchronization between the main file
+     and the debug file.  See dwfl_module_getdwarf.c for how it's chosen.  */
+  GElf_Addr address_sync;
+};
+
+struct Dwfl_Module
+{
+  Dwfl *dwfl;
+  struct Dwfl_Module *next;	/* Link on Dwfl.modulelist.  */
+
+  void *userdata;
+
+  char *name;			/* Iterator name for this module.  */
+  GElf_Addr low_addr, high_addr;
+
+  struct dwfl_file main, debug, aux_sym;
+  GElf_Addr main_bias;
+  Ebl *ebl;
+  GElf_Half e_type;		/* GElf_Ehdr.e_type cache.  */
+  Dwfl_Error elferr;		/* Previous failure to open main file.  */
+
+  struct dwfl_relocation *reloc_info; /* Relocatable sections.  */
+
+  struct dwfl_file *symfile;	/* Either main or debug.  */
+  Elf_Data *symdata;		/* Data in the ELF symbol table section.  */
+  Elf_Data *aux_symdata;	/* Data in the auxiliary ELF symbol table.  */
+  size_t syments;		/* sh_size / sh_entsize of that section.  */
+  size_t aux_syments;		/* sh_size / sh_entsize of aux_sym section.  */
+  int first_global;		/* Index of first global symbol of table.  */
+  int aux_first_global;		/* Index of first global of aux_sym table.  */
+  Elf_Data *symstrdata;		/* Data for its string table.  */
+  Elf_Data *aux_symstrdata;	/* Data for aux_sym string table.  */
+  Elf_Data *symxndxdata;	/* Data in the extended section index table. */
+  Elf_Data *aux_symxndxdata;	/* Data in the extended auxiliary table. */
+
+  Dwarf *dw;			/* libdw handle for its debugging info.  */
+  Dwarf *alt;			/* Dwarf used for dwarf_setalt, or NULL.  */
+  int alt_fd; 			/* descriptor, only valid when alt != NULL.  */
+  Elf *alt_elf; 		/* Elf for alt Dwarf.  */
+
+  Dwfl_Error symerr;		/* Previous failure to load symbols.  */
+  Dwfl_Error dwerr;		/* Previous failure to load DWARF.  */
+
+  /* Known CU's in this module.  */
+  struct dwfl_cu *first_cu, **cu;
+
+  void *lazy_cu_root;		/* Table indexed by Dwarf_Off of CU.  */
+
+  struct dwfl_arange *aranges;	/* Mapping of addresses in module to CUs.  */
+
+  void *build_id_bits;		/* malloc'd copy of build ID bits.  */
+  GElf_Addr build_id_vaddr;	/* Address where they reside, 0 if unknown.  */
+  int build_id_len;		/* -1 for prior failure, 0 if unset.  */
+
+  unsigned int ncu;
+  unsigned int lazycu;		/* Possible users, deleted when none left.  */
+  unsigned int naranges;
+
+  Dwarf_CFI *dwarf_cfi;		/* Cached DWARF CFI for this module.  */
+  Dwarf_CFI *eh_cfi;		/* Cached EH CFI for this module.  */
+
+  int segment;			/* Index of first segment table entry.  */
+  bool gc;			/* Mark/sweep flag.  */
+  bool is_executable;		/* Use Dwfl::executable_for_core?  */
+};
+
+/* This holds information common for all the threads/tasks/TIDs of one process
+   for backtraces.  */
+
+struct Dwfl_Process
+{
+  struct Dwfl *dwfl;
+  pid_t pid;
+  const Dwfl_Thread_Callbacks *callbacks;
+  void *callbacks_arg;
+  struct ebl *ebl;
+  bool ebl_close:1;
+};
+
+/* See its typedef in libdwfl.h.  */
+
+struct Dwfl_Thread
+{
+  Dwfl_Process *process;
+  pid_t tid;
+  /* The current frame being unwound.  Initially it is the bottom frame.
+     Later the processed frames get freed and this pointer is updated.  */
+  Dwfl_Frame *unwound;
+  void *callbacks_arg;
+};
+
+/* See its typedef in libdwfl.h.  */
+
+struct Dwfl_Frame
+{
+  Dwfl_Thread *thread;
+  /* Previous (outer) frame.  */
+  Dwfl_Frame *unwound;
+  bool signal_frame : 1;
+  bool initial_frame : 1;
+  enum
+  {
+    /* This structure is still being initialized or there was an error
+       initializing it.  */
+    DWFL_FRAME_STATE_ERROR,
+    /* PC field is valid.  */
+    DWFL_FRAME_STATE_PC_SET,
+    /* PC field is undefined, this means the next (inner) frame was the
+       outermost frame.  */
+    DWFL_FRAME_STATE_PC_UNDEFINED
+  } pc_state;
+  /* Either initialized from appropriate REGS element or on some archs
+     initialized separately as the return address has no DWARF register.  */
+  Dwarf_Addr pc;
+  /* (1 << X) bitmask where 0 <= X < ebl_frame_nregs.  */
+  uint64_t regs_set[3];
+  /* REGS array size is ebl_frame_nregs.
+     REGS_SET tells which of the REGS are valid.  */
+  Dwarf_Addr regs[];
+};
+
+/* Fetch value from Dwfl_Frame->regs indexed by DWARF REGNO.
+   No error code is set if the function returns FALSE.  */
+bool __libdwfl_frame_reg_get (Dwfl_Frame *state, unsigned regno,
+			      Dwarf_Addr *val)
+  internal_function;
+
+/* Store value to Dwfl_Frame->regs indexed by DWARF REGNO.
+   No error code is set if the function returns FALSE.  */
+bool __libdwfl_frame_reg_set (Dwfl_Frame *state, unsigned regno,
+			      Dwarf_Addr val)
+  internal_function;
+
+/* Information cached about each CU in Dwfl_Module.dw.  */
+struct dwfl_cu
+{
+  /* This caches libdw information about the CU.  It's also the
+     address passed back to users, so we take advantage of the
+     fact that it's placed first to cast back.  */
+  Dwarf_Die die;
+
+  Dwfl_Module *mod;		/* Pointer back to containing module.  */
+
+  struct dwfl_cu *next;		/* CU immediately following in the file.  */
+
+  struct Dwfl_Lines *lines;
+};
+
+struct Dwfl_Lines
+{
+  struct dwfl_cu *cu;
+
+  /* This is what the opaque Dwfl_Line * pointers we pass to users are.
+     We need to recover pointers to our struct dwfl_cu and a record in
+     libdw's Dwarf_Line table.  To minimize the memory used in addition
+     to libdw's Dwarf_Lines buffer, we just point to our own index in
+     this table, and have one pointer back to the CU.  The indices here
+     match those in libdw's Dwarf_CU.lines->info table.  */
+  struct Dwfl_Line
+  {
+    unsigned int idx;		/* My index in the dwfl_cu.lines table.  */
+  } idx[0];
+};
+
+static inline struct dwfl_cu *
+dwfl_linecu_inline (const Dwfl_Line *line)
+{
+  const struct Dwfl_Lines *lines = ((const void *) line
+				    - offsetof (struct Dwfl_Lines,
+						idx[line->idx]));
+  return lines->cu;
+}
+#define dwfl_linecu dwfl_linecu_inline
+
+static inline GElf_Addr
+dwfl_adjusted_address (Dwfl_Module *mod, GElf_Addr addr)
+{
+  return addr + mod->main_bias;
+}
+
+static inline GElf_Addr
+dwfl_deadjust_address (Dwfl_Module *mod, GElf_Addr addr)
+{
+  return addr - mod->main_bias;
+}
+
+static inline Dwarf_Addr
+dwfl_adjusted_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
+{
+  return dwfl_adjusted_address (mod, (addr
+				      - mod->debug.address_sync
+				      + mod->main.address_sync));
+}
+
+static inline Dwarf_Addr
+dwfl_deadjust_dwarf_addr (Dwfl_Module *mod, Dwarf_Addr addr)
+{
+  return (dwfl_deadjust_address (mod, addr)
+	  - mod->main.address_sync
+	  + mod->debug.address_sync);
+}
+
+static inline Dwarf_Addr
+dwfl_adjusted_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
+{
+  return dwfl_adjusted_address (mod, (addr
+				      - mod->aux_sym.address_sync
+				      + mod->main.address_sync));
+}
+
+static inline Dwarf_Addr
+dwfl_deadjust_aux_sym_addr (Dwfl_Module *mod, Dwarf_Addr addr)
+{
+  return (dwfl_deadjust_address (mod, addr)
+	  - mod->main.address_sync
+	  + mod->aux_sym.address_sync);
+}
+
+static inline GElf_Addr
+dwfl_adjusted_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
+{
+  if (symelf == mod->main.elf)
+    return dwfl_adjusted_address (mod, addr);
+  if (symelf == mod->debug.elf)
+    return dwfl_adjusted_dwarf_addr (mod, addr);
+  return dwfl_adjusted_aux_sym_addr (mod, addr);
+}
+
+static inline GElf_Addr
+dwfl_deadjust_st_value (Dwfl_Module *mod, Elf *symelf, GElf_Addr addr)
+{
+  if (symelf == mod->main.elf)
+    return dwfl_deadjust_address (mod, addr);
+  if (symelf == mod->debug.elf)
+    return dwfl_deadjust_dwarf_addr (mod, addr);
+  return dwfl_deadjust_aux_sym_addr (mod, addr);
+}
+
+/* This describes a contiguous address range that lies in a single CU.
+   We condense runs of Dwarf_Arange entries for the same CU into this.  */
+struct dwfl_arange
+{
+  struct dwfl_cu *cu;
+  size_t arange;		/* Index in Dwarf_Aranges.  */
+};
+
+
+/* Structure used for keeping track of ptrace attaching a thread.
+   Shared by linux-pid-attach and linux-proc-maps.  If it has been setup
+   then get the instance through __libdwfl_get_pid_arg.  */
+struct __libdwfl_pid_arg
+{
+  /* /proc/PID/task/.  */
+  DIR *dir;
+  /* Elf for /proc/PID/exe.  Set to NULL if it couldn't be opened.  */
+  Elf *elf;
+  /* fd for /proc/PID/exe.  Set to -1 if it couldn't be opened.  */
+  int elf_fd;
+  /* It is 0 if not used.  */
+  pid_t tid_attached;
+  /* Valid only if TID_ATTACHED is not zero.  */
+  bool tid_was_stopped;
+  /* True if threads are ptrace stopped by caller.  */
+  bool assume_ptrace_stopped;
+};
+
+/* If DWfl is not NULL and a Dwfl_Process has been setup that has
+   Dwfl_Thread_Callbacks set to pid_thread_callbacks, then return the
+   callbacks_arg, which will be a struct __libdwfl_pid_arg.  Otherwise
+   returns NULL.  */
+extern struct __libdwfl_pid_arg *__libdwfl_get_pid_arg (Dwfl *dwfl)
+  internal_function;
+
+/* Makes sure the given tid is attached. On success returns true and
+   sets tid_was_stopped.  */
+extern bool __libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
+  internal_function;
+
+/* Detaches a tid that was attached through
+   __libdwfl_ptrace_attach. Must be given the tid_was_stopped as set
+   by __libdwfl_ptrace_attach.  */
+extern void __libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
+  internal_function;
+
+
+/* Internal wrapper for old dwfl_module_getsym and new dwfl_module_getsym_info.
+   adjust_st_value set to true returns adjusted SYM st_value, set to false
+   it will not adjust SYM at all, but does match against resolved *ADDR. */
+extern const char *__libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym *sym,
+				     GElf_Addr *addr, GElf_Word *shndxp,
+				     Elf **elfp, Dwarf_Addr *biasp,
+				     bool *resolved, bool adjust_st_value)
+  internal_function;
+
+/* Internal wrapper for old dwfl_module_addrsym and new dwfl_module_addrinfo.
+   adjust_st_value set to true returns adjusted SYM st_value, set to false
+   it will not adjust SYM at all, but does match against resolved values. */
+extern const char *__libdwfl_addrsym (Dwfl_Module *mod, GElf_Addr addr,
+				      GElf_Off *off, GElf_Sym *sym,
+				      GElf_Word *shndxp, Elf **elfp,
+				      Dwarf_Addr *bias,
+				      bool adjust_st_value) internal_function;
+
+extern void __libdwfl_module_free (Dwfl_Module *mod) internal_function;
+
+/* Find the main ELF file, update MOD->elferr and/or MOD->main.elf.  */
+extern void __libdwfl_getelf (Dwfl_Module *mod) internal_function;
+
+/* Process relocations in debugging sections in an ET_REL file.
+   FILE must be opened with ELF_C_READ_MMAP_PRIVATE or ELF_C_READ,
+   to make it possible to relocate the data in place (or ELF_C_RDWR or
+   ELF_C_RDWR_MMAP if you intend to modify the Elf file on disk).  After
+   this, dwarf_begin_elf on FILE will read the relocated data.
+
+   When DEBUG is false, apply partial relocation to all sections.  */
+extern Dwfl_Error __libdwfl_relocate (Dwfl_Module *mod, Elf *file, bool debug)
+  internal_function;
+
+/* Find the section index in mod->main.elf that contains the given
+   *ADDR.  Adjusts *ADDR to be section relative on success, returns
+   SHN_UNDEF on failure.  */
+extern size_t __libdwfl_find_section_ndx (Dwfl_Module *mod, Dwarf_Addr *addr)
+  internal_function;
+
+/* Process (simple) relocations in arbitrary section TSCN of an ET_REL file.
+   RELOCSCN is SHT_REL or SHT_RELA and TSCN is its sh_info target section.  */
+extern Dwfl_Error __libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
+					      Elf_Scn *relocscn, Elf_Scn *tscn,
+					      bool partial)
+  internal_function;
+
+/* Adjust *VALUE from section-relative to absolute.
+   MOD->dwfl->callbacks->section_address is called to determine the actual
+   address of a loaded section.  */
+extern Dwfl_Error __libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf,
+					    size_t *shstrndx_cache,
+					    Elf32_Word shndx,
+					    GElf_Addr *value)
+     internal_function;
+
+/* Ensure that MOD->ebl is set up.  */
+extern Dwfl_Error __libdwfl_module_getebl (Dwfl_Module *mod) internal_function;
+
+/* Install a new Dwarf_CFI in *SLOT (MOD->eh_cfi or MOD->dwarf_cfi).  */
+extern Dwarf_CFI *__libdwfl_set_cfi (Dwfl_Module *mod, Dwarf_CFI **slot,
+				     Dwarf_CFI *cfi)
+  internal_function;
+
+/* Iterate through all the CU's in the module.  Start by passing a null
+   LASTCU, and then pass the last *CU returned.  Success return with null
+   *CU no more CUs.  */
+extern Dwfl_Error __libdwfl_nextcu (Dwfl_Module *mod, struct dwfl_cu *lastcu,
+				    struct dwfl_cu **cu) internal_function;
+
+/* Find the CU by address.  */
+extern Dwfl_Error __libdwfl_addrcu (Dwfl_Module *mod, Dwarf_Addr addr,
+				    struct dwfl_cu **cu) internal_function;
+
+/* Ensure that CU->lines (and CU->cu->lines) is set up.  */
+extern Dwfl_Error __libdwfl_cu_getsrclines (struct dwfl_cu *cu)
+  internal_function;
+
+/* Look in ELF for an NT_GNU_BUILD_ID note.  Store it to BUILD_ID_BITS,
+   its vaddr in ELF to BUILD_ID_VADDR (it is unrelocated, even if MOD is not
+   NULL) and store length to BUILD_ID_LEN.  Returns -1 for errors, 1 if it was
+   stored and 0 if no note is found.  MOD may be NULL, MOD must be non-NULL
+   only if ELF is ET_REL.  */
+extern int __libdwfl_find_elf_build_id (Dwfl_Module *mod, Elf *elf,
+					const void **build_id_bits,
+					GElf_Addr *build_id_elfaddr,
+					int *build_id_len)
+  internal_function;
+
+/* Look in ELF for an NT_GNU_BUILD_ID note.  If SET is true, store it
+   in MOD and return its length.  If SET is false, instead compare it
+   to that stored in MOD and return 2 if they match, 1 if they do not.
+   Returns -1 for errors, 0 if no note is found.  */
+extern int __libdwfl_find_build_id (Dwfl_Module *mod, bool set, Elf *elf)
+  internal_function;
+
+/* Open a main or debuginfo file by its build ID, returns the fd.  */
+extern int __libdwfl_open_mod_by_build_id (Dwfl_Module *mod, bool debug,
+					   char **file_name) internal_function;
+
+/* Same, but takes an explicit build_id, can also be used for alt debug.  */
+extern int __libdwfl_open_by_build_id (Dwfl_Module *mod, bool debug,
+				       char **file_name, const size_t id_len,
+				       const uint8_t *id) internal_function;
+
+extern uint32_t __libdwfl_crc32 (uint32_t crc, unsigned char *buf, size_t len)
+  attribute_hidden;
+extern int __libdwfl_crc32_file (int fd, uint32_t *resp) attribute_hidden;
+
+
+/* Given ELF and some parameters return TRUE if the *P return value parameters
+   have been successfully filled in.  Any of the *P parameters can be NULL.  */
+extern bool __libdwfl_elf_address_range (Elf *elf, GElf_Addr base,
+					 bool add_p_vaddr, bool sanity,
+					 GElf_Addr *vaddrp,
+					 GElf_Addr *address_syncp,
+					 GElf_Addr *startp, GElf_Addr *endp,
+					 GElf_Addr *biasp, GElf_Half *e_typep)
+  internal_function;
+
+/* Meat of dwfl_report_elf, given elf_begin just called.
+   Consumes ELF on success, not on failure.  */
+extern Dwfl_Module *__libdwfl_report_elf (Dwfl *dwfl, const char *name,
+					  const char *file_name, int fd,
+					  Elf *elf, GElf_Addr base,
+					  bool add_p_vaddr, bool sanity)
+  internal_function;
+
+/* Meat of dwfl_report_offline.  */
+extern Dwfl_Module *__libdwfl_report_offline (Dwfl *dwfl, const char *name,
+					      const char *file_name,
+					      int fd, bool closefd,
+					      int (*predicate) (const char *,
+								const char *))
+  internal_function;
+
+/* Free PROCESS.  Unlink and free also any structures it references.  */
+extern void __libdwfl_process_free (Dwfl_Process *process)
+  internal_function;
+
+/* Update STATE->unwound for the unwound frame.
+   On error STATE->unwound == NULL
+   or STATE->unwound->pc_state == DWFL_FRAME_STATE_ERROR;
+   in such case dwfl_errno () is set.
+   If STATE->unwound->pc_state == DWFL_FRAME_STATE_PC_UNDEFINED
+   then STATE was the last valid frame.  */
+extern void __libdwfl_frame_unwind (Dwfl_Frame *state)
+  internal_function;
+
+/* Align segment START downwards or END upwards addresses according to DWFL.  */
+extern GElf_Addr __libdwfl_segment_start (Dwfl *dwfl, GElf_Addr start)
+  internal_function;
+extern GElf_Addr __libdwfl_segment_end (Dwfl *dwfl, GElf_Addr end)
+  internal_function;
+
+/* Decompression wrappers: decompress whole file into memory.  */
+extern Dwfl_Error __libdw_gunzip  (int fd, off_t start_offset,
+				   void *mapped, size_t mapped_size,
+				   void **whole, size_t *whole_size)
+  internal_function;
+extern Dwfl_Error __libdw_bunzip2 (int fd, off_t start_offset,
+				   void *mapped, size_t mapped_size,
+				   void **whole, size_t *whole_size)
+  internal_function;
+extern Dwfl_Error __libdw_unlzma (int fd, off_t start_offset,
+				  void *mapped, size_t mapped_size,
+				  void **whole, size_t *whole_size)
+  internal_function;
+
+/* Skip the image header before a file image: updates *START_OFFSET.  */
+extern Dwfl_Error __libdw_image_header (int fd, off_t *start_offset,
+					void *mapped, size_t mapped_size)
+  internal_function;
+
+/* Open Elf handle on *FDP.  This handles decompression and checks
+   elf_kind.  Succeed only for ELF_K_ELF, or also ELF_K_AR if ARCHIVE_OK.
+   Returns DWFL_E_NOERROR and sets *ELFP on success, resets *FDP to -1 if
+   it's no longer used.  Resets *FDP on failure too iff CLOSE_ON_FAIL.  */
+extern Dwfl_Error __libdw_open_file (int *fdp, Elf **elfp,
+				     bool close_on_fail, bool archive_ok)
+  internal_function;
+
+/* Fetch PT_DYNAMIC P_VADDR from ELF and store it to *VADDRP.  Return success.
+   *VADDRP is not modified if the function fails.  */
+extern bool __libdwfl_dynamic_vaddr_get (Elf *elf, GElf_Addr *vaddrp)
+  internal_function;
+
+/* These are working nicely for --core, but are not ready to be
+   exported interfaces quite yet.  */
+
+/* Type of callback function ...
+ */
+typedef bool Dwfl_Memory_Callback (Dwfl *dwfl, int segndx,
+				   void **buffer, size_t *buffer_available,
+				   GElf_Addr vaddr, size_t minread, void *arg);
+
+/* Type of callback function ...
+ */
+typedef bool Dwfl_Module_Callback (Dwfl_Module *mod, void **userdata,
+				   const char *name, Dwarf_Addr base,
+				   void **buffer, size_t *buffer_available,
+				   GElf_Off cost, GElf_Off worthwhile,
+				   GElf_Off whole, GElf_Off contiguous,
+				   void *arg, Elf **elfp);
+
+/* One shared library (or executable) info from DT_DEBUG link map.  */
+struct r_debug_info_module
+{
+  struct r_debug_info_module *next;
+  /* FD is -1 iff ELF is NULL.  */
+  int fd;
+  Elf *elf;
+  GElf_Addr l_ld;
+  /* START and END are both zero if not valid.  */
+  GElf_Addr start, end;
+  bool disk_file_has_build_id;
+  char name[0];
+};
+
+/* Information gathered from DT_DEBUG by dwfl_link_map_report hinted to
+   dwfl_segment_report_module.  */
+struct r_debug_info
+{
+  struct r_debug_info_module *module;
+};
+
+/* ...
+ */
+extern int dwfl_segment_report_module (Dwfl *dwfl, int ndx, const char *name,
+				       Dwfl_Memory_Callback *memory_callback,
+				       void *memory_callback_arg,
+				       Dwfl_Module_Callback *read_eagerly,
+				       void *read_eagerly_arg,
+				       const void *note_file,
+				       size_t note_file_size,
+				       const struct r_debug_info *r_debug_info);
+
+/* Report a module for entry in the dynamic linker's struct link_map list.
+   For each link_map entry, if an existing module resides at its address,
+   this just modifies that module's name and suggested file name.  If
+   no such module exists, this calls dwfl_report_elf on the l_name string.
+
+   If AUXV is not null, it points to AUXV_SIZE bytes of auxiliary vector
+   data as contained in an NT_AUXV note or read from a /proc/pid/auxv
+   file.  When this is available, it guides the search.  If AUXV is null
+   or the memory it points to is not accessible, then this search can
+   only find where to begin if the correct executable file was
+   previously reported and preloaded as with dwfl_report_elf.
+
+   Fill in R_DEBUG_INFO if it is not NULL.  It should be cleared by the
+   caller, this function does not touch fields it does not need to modify.
+   If R_DEBUG_INFO is not NULL then no modules get added to DWFL, caller
+   has to add them from filled in R_DEBUG_INFO.
+
+   Returns the number of modules found, or -1 for errors.  */
+extern int dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
+				 Dwfl_Memory_Callback *memory_callback,
+				 void *memory_callback_arg,
+				 struct r_debug_info *r_debug_info);
+
+
+/* Avoid PLT entries.  */
+INTDECL (dwfl_begin)
+INTDECL (dwfl_errmsg)
+INTDECL (dwfl_errno)
+INTDECL (dwfl_addrmodule)
+INTDECL (dwfl_addrsegment)
+INTDECL (dwfl_addrdwarf)
+INTDECL (dwfl_addrdie)
+INTDECL (dwfl_core_file_attach)
+INTDECL (dwfl_core_file_report)
+INTDECL (dwfl_getmodules)
+INTDECL (dwfl_module_addrdie)
+INTDECL (dwfl_module_address_section)
+INTDECL (dwfl_module_addrinfo)
+INTDECL (dwfl_module_addrsym)
+INTDECL (dwfl_module_build_id)
+INTDECL (dwfl_module_getdwarf)
+INTDECL (dwfl_module_getelf)
+INTDECL (dwfl_module_getsym)
+INTDECL (dwfl_module_getsym_info)
+INTDECL (dwfl_module_getsymtab)
+INTDECL (dwfl_module_getsymtab_first_global)
+INTDECL (dwfl_module_getsrc)
+INTDECL (dwfl_module_report_build_id)
+INTDECL (dwfl_report_elf)
+INTDECL (dwfl_report_begin)
+INTDECL (dwfl_report_begin_add)
+INTDECL (dwfl_report_module)
+INTDECL (dwfl_report_segment)
+INTDECL (dwfl_report_offline)
+INTDECL (dwfl_report_end)
+INTDECL (dwfl_build_id_find_elf)
+INTDECL (dwfl_build_id_find_debuginfo)
+INTDECL (dwfl_standard_find_debuginfo)
+INTDECL (dwfl_link_map_report)
+INTDECL (dwfl_linux_kernel_find_elf)
+INTDECL (dwfl_linux_kernel_module_section_address)
+INTDECL (dwfl_linux_proc_attach)
+INTDECL (dwfl_linux_proc_report)
+INTDECL (dwfl_linux_proc_maps_report)
+INTDECL (dwfl_linux_proc_find_elf)
+INTDECL (dwfl_linux_kernel_report_kernel)
+INTDECL (dwfl_linux_kernel_report_modules)
+INTDECL (dwfl_linux_kernel_report_offline)
+INTDECL (dwfl_offline_section_address)
+INTDECL (dwfl_module_relocate_address)
+INTDECL (dwfl_module_dwarf_cfi)
+INTDECL (dwfl_module_eh_cfi)
+INTDECL (dwfl_attach_state)
+INTDECL (dwfl_pid)
+INTDECL (dwfl_thread_dwfl)
+INTDECL (dwfl_thread_tid)
+INTDECL (dwfl_frame_thread)
+INTDECL (dwfl_thread_state_registers)
+INTDECL (dwfl_thread_state_register_pc)
+INTDECL (dwfl_getthread_frames)
+INTDECL (dwfl_getthreads)
+INTDECL (dwfl_thread_getframes)
+INTDECL (dwfl_frame_pc)
+
+/* Leading arguments standard to callbacks passed a Dwfl_Module.  */
+#define MODCB_ARGS(mod)	(mod), &(mod)->userdata, (mod)->name, (mod)->low_addr
+#define CBFAIL		(errno ? DWFL_E (ERRNO, errno) : DWFL_E_CB);
+
+
+/* The default used by dwfl_standard_find_debuginfo.  */
+#define DEFAULT_DEBUGINFO_PATH ":.debug:/usr/lib/debug"
+
+
+#endif	/* libdwflP.h */
diff --git a/third_party/elfutils/libdwfl/libdwfl_crc32.c b/third_party/elfutils/libdwfl/libdwfl_crc32.c
new file mode 100644
index 0000000..b89d0d3
--- /dev/null
+++ b/third_party/elfutils/libdwfl/libdwfl_crc32.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define crc32 attribute_hidden __libdwfl_crc32
+#define LIB_SYSTEM_H	1
+#include <libdwflP.h>
+#include "../lib/crc32.c"
diff --git a/third_party/elfutils/libdwfl/libdwfl_crc32_file.c b/third_party/elfutils/libdwfl/libdwfl_crc32_file.c
new file mode 100644
index 0000000..f849128
--- /dev/null
+++ b/third_party/elfutils/libdwfl/libdwfl_crc32_file.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define crc32_file attribute_hidden __libdwfl_crc32_file
+#define crc32 __libdwfl_crc32
+#include <libdwflP.h>
+#include "../lib/crc32_file.c"
diff --git a/third_party/elfutils/libdwfl/lines.c b/third_party/elfutils/libdwfl/lines.c
new file mode 100644
index 0000000..128c0c9
--- /dev/null
+++ b/third_party/elfutils/libdwfl/lines.c
@@ -0,0 +1,56 @@
+/* Fetch source line info for CU.
+   Copyright (C) 2005, 2006 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include "../libdw/libdwP.h"
+
+Dwfl_Error
+internal_function
+__libdwfl_cu_getsrclines (struct dwfl_cu *cu)
+{
+  if (cu->lines == NULL)
+    {
+      Dwarf_Lines *lines;
+      size_t nlines;
+      if (INTUSE(dwarf_getsrclines) (&cu->die, &lines, &nlines) != 0)
+	return DWFL_E_LIBDW;
+
+      cu->lines = malloc (offsetof (struct Dwfl_Lines, idx[nlines]));
+      if (cu->lines == NULL)
+	return DWFL_E_NOMEM;
+      cu->lines->cu = cu;
+      for (unsigned int i = 0; i < nlines; ++i)
+	cu->lines->idx[i].idx = i;
+    }
+
+  return DWFL_E_NOERROR;
+}
diff --git a/third_party/elfutils/libdwfl/link_map.c b/third_party/elfutils/libdwfl/link_map.c
new file mode 100644
index 0000000..29307c7
--- /dev/null
+++ b/third_party/elfutils/libdwfl/link_map.c
@@ -0,0 +1,1039 @@
+/* Report modules by examining dynamic linker data structures.
+   Copyright (C) 2008-2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include "libdwflP.h"
+#include "../libdw/memory-access.h"
+#include "system.h"
+
+#include <byteswap.h>
+#include <endian.h>
+#include <fcntl.h>
+
+/* This element is always provided and always has a constant value.
+   This makes it an easy thing to scan for to discern the format.  */
+#define PROBE_TYPE	AT_PHENT
+#define PROBE_VAL32	sizeof (Elf32_Phdr)
+#define PROBE_VAL64	sizeof (Elf64_Phdr)
+
+
+static inline bool
+do_check64 (const char *a64, uint_fast8_t *elfdata)
+{
+  /* The AUXV pointer might not even be naturally aligned for 64-bit
+     data, because note payloads in a core file are not aligned.  */
+  const char *typep = a64 + offsetof (Elf64_auxv_t, a_type);
+  uint64_t type = read_8ubyte_unaligned_noncvt (typep);
+  const char *valp = a64 + offsetof (Elf64_auxv_t, a_un.a_val);
+  uint64_t val = read_8ubyte_unaligned_noncvt (valp);
+
+  if (type == BE64 (PROBE_TYPE)
+      && val == BE64 (PROBE_VAL64))
+    {
+      *elfdata = ELFDATA2MSB;
+      return true;
+    }
+
+  if (type == LE64 (PROBE_TYPE)
+      && val == LE64 (PROBE_VAL64))
+    {
+      *elfdata = ELFDATA2LSB;
+      return true;
+    }
+
+  return false;
+}
+
+static inline bool
+do_check32 (const char *a32, uint_fast8_t *elfdata)
+{
+  /* The AUXV pointer might not even be naturally aligned for 32-bit
+     data, because note payloads in a core file are not aligned.  */
+  const char *typep = a32 + offsetof (Elf32_auxv_t, a_type);
+  uint32_t type = read_4ubyte_unaligned_noncvt (typep);
+  const char *valp = a32 + offsetof (Elf32_auxv_t, a_un.a_val);
+  uint32_t val = read_4ubyte_unaligned_noncvt (valp);
+
+  if (type == BE32 (PROBE_TYPE)
+      && val == BE32 (PROBE_VAL32))
+    {
+      *elfdata = ELFDATA2MSB;
+      return true;
+    }
+
+  if (type == LE32 (PROBE_TYPE)
+      && val == LE32 (PROBE_VAL32))
+    {
+      *elfdata = ELFDATA2LSB;
+      return true;
+    }
+
+  return false;
+}
+
+/* Examine an auxv data block and determine its format.
+   Return true iff we figured it out.  */
+static bool
+auxv_format_probe (const void *auxv, size_t size,
+		   uint_fast8_t *elfclass, uint_fast8_t *elfdata)
+{
+  for (size_t i = 0; i < size / sizeof (Elf64_auxv_t); ++i)
+    {
+      if (do_check64 (auxv + i * sizeof (Elf64_auxv_t), elfdata))
+	{
+	  *elfclass = ELFCLASS64;
+	  return true;
+	}
+
+      if (do_check32 (auxv + (i * 2) * sizeof (Elf32_auxv_t), elfdata)
+	  || do_check32 (auxv + (i * 2 + 1) * sizeof (Elf32_auxv_t), elfdata))
+	{
+	  *elfclass = ELFCLASS32;
+	  return true;
+	}
+    }
+
+  return false;
+}
+
+/* This is a Dwfl_Memory_Callback that wraps another memory callback.
+   If the underlying callback cannot fill the data, then this will
+   fall back to fetching data from module files.  */
+
+struct integrated_memory_callback
+{
+  Dwfl_Memory_Callback *memory_callback;
+  void *memory_callback_arg;
+  void *buffer;
+};
+
+static bool
+integrated_memory_callback (Dwfl *dwfl, int ndx,
+			       void **buffer, size_t *buffer_available,
+			       GElf_Addr vaddr,
+			       size_t minread,
+			       void *arg)
+{
+  struct integrated_memory_callback *info = arg;
+
+  if (ndx == -1)
+    {
+      /* Called for cleanup.  */
+      if (info->buffer != NULL)
+	{
+	  /* The last probe buffer came from the underlying callback.
+	     Let it do its cleanup.  */
+	  assert (*buffer == info->buffer); /* XXX */
+	  *buffer = info->buffer;
+	  info->buffer = NULL;
+	  return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available,
+					   vaddr, minread,
+					   info->memory_callback_arg);
+	}
+      *buffer = NULL;
+      *buffer_available = 0;
+      return false;
+    }
+
+  if (*buffer != NULL)
+    /* For a final-read request, we only use the underlying callback.  */
+    return (*info->memory_callback) (dwfl, ndx, buffer, buffer_available,
+				     vaddr, minread, info->memory_callback_arg);
+
+  /* Let the underlying callback try to fill this request.  */
+  if ((*info->memory_callback) (dwfl, ndx, &info->buffer, buffer_available,
+				vaddr, minread, info->memory_callback_arg))
+    {
+      *buffer = info->buffer;
+      return true;
+    }
+
+  /* Now look for module text covering this address.  */
+
+  Dwfl_Module *mod;
+  (void) INTUSE(dwfl_addrsegment) (dwfl, vaddr, &mod);
+  if (mod == NULL)
+    return false;
+
+  Dwarf_Addr bias;
+  Elf_Scn *scn = INTUSE(dwfl_module_address_section) (mod, &vaddr, &bias);
+  if (unlikely (scn == NULL))
+    {
+#if 0 // XXX would have to handle ndx=-1 cleanup calls passed down.
+      /* If we have no sections we can try to fill it from the module file
+	 based on its phdr mappings.  */
+      if (likely (mod->e_type != ET_REL) && mod->main.elf != NULL)
+	return INTUSE(dwfl_elf_phdr_memory_callback)
+	  (dwfl, 0, buffer, buffer_available,
+	   vaddr - mod->main.bias, minread, mod->main.elf);
+#endif
+      return false;
+    }
+
+  Elf_Data *data = elf_rawdata (scn, NULL);
+  if (unlikely (data == NULL))
+    // XXX throw error?
+    return false;
+
+  if (unlikely (data->d_size < vaddr))
+    return false;
+
+  /* Provide as much data as we have.  */
+  void *contents = data->d_buf + vaddr;
+  size_t avail = data->d_size - vaddr;
+  if (unlikely (avail < minread))
+    return false;
+
+  /* If probing for a string, make sure it's terminated.  */
+  if (minread == 0 && unlikely (memchr (contents, '\0', avail) == NULL))
+    return false;
+
+  /* We have it! */
+  *buffer = contents;
+  *buffer_available = avail;
+  return true;
+}
+
+static size_t
+addrsize (uint_fast8_t elfclass)
+{
+  return elfclass * 4;
+}
+
+/* Report a module for each struct link_map in the linked list at r_map
+   in the struct r_debug at R_DEBUG_VADDR.  For r_debug_info description
+   see dwfl_link_map_report in libdwflP.h.  If R_DEBUG_INFO is not NULL then no
+   modules get added to DWFL, caller has to add them from filled in
+   R_DEBUG_INFO.
+
+   For each link_map entry, if an existing module resides at its address,
+   this just modifies that module's name and suggested file name.  If
+   no such module exists, this calls dwfl_report_elf on the l_name string.
+
+   Returns the number of modules found, or -1 for errors.  */
+
+static int
+report_r_debug (uint_fast8_t elfclass, uint_fast8_t elfdata,
+		Dwfl *dwfl, GElf_Addr r_debug_vaddr,
+		Dwfl_Memory_Callback *memory_callback,
+		void *memory_callback_arg,
+		struct r_debug_info *r_debug_info)
+{
+  /* Skip r_version, to aligned r_map field.  */
+  GElf_Addr read_vaddr = r_debug_vaddr + addrsize (elfclass);
+
+  void *buffer = NULL;
+  size_t buffer_available = 0;
+  inline int release_buffer (int result)
+  {
+    if (buffer != NULL)
+      (void) (*memory_callback) (dwfl, -1, &buffer, &buffer_available, 0, 0,
+				 memory_callback_arg);
+    return result;
+  }
+
+  GElf_Addr addrs[4];
+  inline bool read_addrs (GElf_Addr vaddr, size_t n)
+  {
+    size_t nb = n * addrsize (elfclass); /* Address words -> bytes to read.  */
+
+    /* Read a new buffer if the old one doesn't cover these words.  */
+    if (buffer == NULL
+	|| vaddr < read_vaddr
+	|| vaddr - read_vaddr + nb > buffer_available)
+      {
+	release_buffer (0);
+
+	read_vaddr = vaddr;
+	int segndx = INTUSE(dwfl_addrsegment) (dwfl, vaddr, NULL);
+	if (unlikely (segndx < 0)
+	    || unlikely (! (*memory_callback) (dwfl, segndx,
+					       &buffer, &buffer_available,
+					       vaddr, nb, memory_callback_arg)))
+	  return true;
+      }
+
+    Elf32_Addr (*a32)[n] = vaddr - read_vaddr + buffer;
+    Elf64_Addr (*a64)[n] = (void *) a32;
+
+    if (elfclass == ELFCLASS32)
+      {
+	if (elfdata == ELFDATA2MSB)
+	  for (size_t i = 0; i < n; ++i)
+	    addrs[i] = BE32 (read_4ubyte_unaligned_noncvt (&(*a32)[i]));
+	else
+	  for (size_t i = 0; i < n; ++i)
+	    addrs[i] = LE32 (read_4ubyte_unaligned_noncvt (&(*a32)[i]));
+      }
+    else
+      {
+	if (elfdata == ELFDATA2MSB)
+	  for (size_t i = 0; i < n; ++i)
+	    addrs[i] = BE64 (read_8ubyte_unaligned_noncvt (&(*a64)[i]));
+	else
+	  for (size_t i = 0; i < n; ++i)
+	    addrs[i] = LE64 (read_8ubyte_unaligned_noncvt (&(*a64)[i]));
+      }
+
+    return false;
+  }
+
+  if (unlikely (read_addrs (read_vaddr, 1)))
+    return release_buffer (-1);
+
+  GElf_Addr next = addrs[0];
+
+  Dwfl_Module **lastmodp = &dwfl->modulelist;
+  int result = 0;
+
+  /* There can't be more elements in the link_map list than there are
+     segments.  DWFL->lookup_elts is probably twice that number, so it
+     is certainly above the upper bound.  If we iterate too many times,
+     there must be a loop in the pointers due to link_map clobberation.  */
+  size_t iterations = 0;
+  while (next != 0 && ++iterations < dwfl->lookup_elts)
+    {
+      if (read_addrs (next, 4))
+	return release_buffer (-1);
+
+      /* Unused: l_addr is the difference between the address in memory
+         and the ELF file when the core was created. We need to
+         recalculate the difference below because the ELF file we use
+         might be differently pre-linked.  */
+      // GElf_Addr l_addr = addrs[0];
+      GElf_Addr l_name = addrs[1];
+      GElf_Addr l_ld = addrs[2];
+      next = addrs[3];
+
+      /* If a clobbered or truncated memory image has no useful pointer,
+	 just skip this element.  */
+      if (l_ld == 0)
+	continue;
+
+      /* Fetch the string at the l_name address.  */
+      const char *name = NULL;
+      if (buffer != NULL
+	  && read_vaddr <= l_name
+	  && l_name + 1 - read_vaddr < buffer_available
+	  && memchr (l_name - read_vaddr + buffer, '\0',
+		     buffer_available - (l_name - read_vaddr)) != NULL)
+	name = l_name - read_vaddr + buffer;
+      else
+	{
+	  release_buffer (0);
+	  read_vaddr = l_name;
+	  int segndx = INTUSE(dwfl_addrsegment) (dwfl, l_name, NULL);
+	  if (likely (segndx >= 0)
+	      && (*memory_callback) (dwfl, segndx,
+				     &buffer, &buffer_available,
+				     l_name, 0, memory_callback_arg))
+	    name = buffer;
+	}
+
+      if (name != NULL && name[0] == '\0')
+	name = NULL;
+
+      if (iterations == 1
+	  && dwfl->user_core != NULL
+	  && dwfl->user_core->executable_for_core != NULL)
+	name = dwfl->user_core->executable_for_core;
+
+      struct r_debug_info_module *r_debug_info_module = NULL;
+      if (r_debug_info != NULL)
+	{
+	  /* Save link map information about valid shared library (or
+	     executable) which has not been found on disk.  */
+	  const char *name1 = name == NULL ? "" : name;
+	  r_debug_info_module = malloc (sizeof (*r_debug_info_module)
+					+ strlen (name1) + 1);
+	  if (unlikely (r_debug_info_module == NULL))
+	    return release_buffer (result);
+	  r_debug_info_module->fd = -1;
+	  r_debug_info_module->elf = NULL;
+	  r_debug_info_module->l_ld = l_ld;
+	  r_debug_info_module->start = 0;
+	  r_debug_info_module->end = 0;
+	  r_debug_info_module->disk_file_has_build_id = false;
+	  strcpy (r_debug_info_module->name, name1);
+	  r_debug_info_module->next = r_debug_info->module;
+	  r_debug_info->module = r_debug_info_module;
+	}
+
+      Dwfl_Module *mod = NULL;
+      if (name != NULL)
+	{
+	  /* This code is mostly inlined dwfl_report_elf.  */
+	  // XXX hook for sysroot
+	  int fd = open (name, O_RDONLY);
+	  if (fd >= 0)
+	    {
+	      Elf *elf;
+	      Dwfl_Error error = __libdw_open_file (&fd, &elf, true, false);
+	      GElf_Addr elf_dynamic_vaddr;
+	      if (error == DWFL_E_NOERROR
+		  && __libdwfl_dynamic_vaddr_get (elf, &elf_dynamic_vaddr))
+		{
+		  const void *build_id_bits;
+		  GElf_Addr build_id_elfaddr;
+		  int build_id_len;
+		  bool valid = true;
+
+		  if (__libdwfl_find_elf_build_id (NULL, elf, &build_id_bits,
+						   &build_id_elfaddr,
+						   &build_id_len) > 0
+		      && build_id_elfaddr != 0)
+		    {
+		      if (r_debug_info_module != NULL)
+			r_debug_info_module->disk_file_has_build_id = true;
+		      GElf_Addr build_id_vaddr = (build_id_elfaddr
+						  - elf_dynamic_vaddr + l_ld);
+
+		      release_buffer (0);
+		      int segndx = INTUSE(dwfl_addrsegment) (dwfl,
+							     build_id_vaddr,
+							     NULL);
+		      if (! (*memory_callback) (dwfl, segndx,
+						&buffer, &buffer_available,
+						build_id_vaddr, build_id_len,
+						memory_callback_arg))
+			{
+			  /* File has valid build-id which cannot be read from
+			     memory.  This happens for core files without bit 4
+			     (0x10) set in Linux /proc/PID/coredump_filter.  */
+			}
+		      else
+			{
+			  if (memcmp (build_id_bits, buffer, build_id_len) != 0)
+			    /* File has valid build-id which does not match
+			       the one in memory.  */
+			    valid = false;
+			  release_buffer (0);
+			}
+		    }
+
+		  if (valid)
+		    {
+		      // It is like l_addr but it handles differently prelinked
+		      // files at core dumping vs. core loading time.
+		      GElf_Addr base = l_ld - elf_dynamic_vaddr;
+		      if (r_debug_info_module == NULL)
+			{
+			  // XXX hook for sysroot
+			  mod = __libdwfl_report_elf (dwfl, basename (name),
+						      name, fd, elf, base,
+						      true, true);
+			  if (mod != NULL)
+			    {
+			      elf = NULL;
+			      fd = -1;
+			    }
+			}
+		      else if (__libdwfl_elf_address_range (elf, base, true,
+							    true, NULL, NULL,
+						    &r_debug_info_module->start,
+						    &r_debug_info_module->end,
+							    NULL, NULL))
+			{
+			  r_debug_info_module->elf = elf;
+			  r_debug_info_module->fd = fd;
+			  elf = NULL;
+			  fd = -1;
+			}
+		    }
+		  if (elf != NULL)
+		    elf_end (elf);
+		  if (fd != -1)
+		    close (fd);
+		}
+	    }
+	}
+
+      if (mod != NULL)
+	{
+	  ++result;
+
+	  /* Move this module to the end of the list, so that we end
+	     up with a list in the same order as the link_map chain.  */
+	  if (mod->next != NULL)
+	    {
+	      if (*lastmodp != mod)
+		{
+		  lastmodp = &dwfl->modulelist;
+		  while (*lastmodp != mod)
+		    lastmodp = &(*lastmodp)->next;
+		}
+	      *lastmodp = mod->next;
+	      mod->next = NULL;
+	      while (*lastmodp != NULL)
+		lastmodp = &(*lastmodp)->next;
+	      *lastmodp = mod;
+	    }
+
+	  lastmodp = &mod->next;
+	}
+    }
+
+  return release_buffer (result);
+}
+
+static GElf_Addr
+consider_executable (Dwfl_Module *mod, GElf_Addr at_phdr, GElf_Addr at_entry,
+		     uint_fast8_t *elfclass, uint_fast8_t *elfdata,
+		     Dwfl_Memory_Callback *memory_callback,
+		     void *memory_callback_arg)
+{
+  GElf_Ehdr ehdr;
+  if (unlikely (gelf_getehdr (mod->main.elf, &ehdr) == NULL))
+    return 0;
+
+  if (at_entry != 0)
+    {
+      /* If we have an AT_ENTRY value, reject this executable if
+	 its entry point address could not have supplied that.  */
+
+      if (ehdr.e_entry == 0)
+	return 0;
+
+      if (mod->e_type == ET_EXEC)
+	{
+	  if (ehdr.e_entry != at_entry)
+	    return 0;
+	}
+      else
+	{
+	  /* It could be a PIE.  */
+	}
+    }
+
+  // XXX this could be saved in the file cache: phdr vaddr, DT_DEBUG d_val vaddr
+  /* Find the vaddr of the DT_DEBUG's d_ptr.  This is the memory
+     address where &r_debug was written at runtime.  */
+  GElf_Xword align = mod->dwfl->segment_align;
+  GElf_Addr d_val_vaddr = 0;
+  size_t phnum;
+  if (elf_getphdrnum (mod->main.elf, &phnum) != 0)
+    return 0;
+
+  for (size_t i = 0; i < phnum; ++i)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (mod->main.elf, i, &phdr_mem);
+      if (phdr == NULL)
+	break;
+
+      if (phdr->p_align > 1 && (align == 0 || phdr->p_align < align))
+	align = phdr->p_align;
+
+      if (at_phdr != 0
+	  && phdr->p_type == PT_LOAD
+	  && (phdr->p_offset & -align) == (ehdr.e_phoff & -align))
+	{
+	  /* This is the segment that would map the phdrs.
+	     If we have an AT_PHDR value, reject this executable
+	     if its phdr mapping could not have supplied that.  */
+	  if (mod->e_type == ET_EXEC)
+	    {
+	      if (ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr != at_phdr)
+		return 0;
+	    }
+	  else
+	    {
+	      /* It could be a PIE.  If the AT_PHDR value and our
+		 phdr address don't match modulo ALIGN, then this
+		 could not have been the right PIE.  */
+	      if (((ehdr.e_phoff - phdr->p_offset + phdr->p_vaddr) & -align)
+		  != (at_phdr & -align))
+		return 0;
+
+	      /* Calculate the bias applied to the PIE's p_vaddr values.  */
+	      GElf_Addr bias = (at_phdr - (ehdr.e_phoff - phdr->p_offset
+					   + phdr->p_vaddr));
+
+	      /* Final sanity check: if we have an AT_ENTRY value,
+		 reject this PIE unless its biased e_entry matches.  */
+	      if (at_entry != 0 && at_entry != ehdr.e_entry + bias)
+		return 0;
+
+	      /* If we're changing the module's address range,
+		 we've just invalidated the module lookup table.  */
+	      GElf_Addr mod_bias = dwfl_adjusted_address (mod, 0);
+	      if (bias != mod_bias)
+		{
+		  mod->low_addr -= mod_bias;
+		  mod->high_addr -= mod_bias;
+		  mod->low_addr += bias;
+		  mod->high_addr += bias;
+
+		  free (mod->dwfl->lookup_module);
+		  mod->dwfl->lookup_module = NULL;
+		}
+	    }
+	}
+
+      if (phdr->p_type == PT_DYNAMIC)
+	{
+	  Elf_Data *data = elf_getdata_rawchunk (mod->main.elf, phdr->p_offset,
+						 phdr->p_filesz, ELF_T_DYN);
+	  if (data == NULL)
+	    continue;
+	  const size_t entsize = gelf_fsize (mod->main.elf,
+					     ELF_T_DYN, 1, EV_CURRENT);
+	  const size_t n = data->d_size / entsize;
+	  for (size_t j = 0; j < n; ++j)
+	    {
+	      GElf_Dyn dyn_mem;
+	      GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
+	      if (dyn != NULL && dyn->d_tag == DT_DEBUG)
+		{
+		  d_val_vaddr = phdr->p_vaddr + entsize * j + entsize / 2;
+		  break;
+		}
+	    }
+	}
+    }
+
+  if (d_val_vaddr != 0)
+    {
+      /* Now we have the final address from which to read &r_debug.  */
+      d_val_vaddr = dwfl_adjusted_address (mod, d_val_vaddr);
+
+      void *buffer = NULL;
+      size_t buffer_available = addrsize (ehdr.e_ident[EI_CLASS]);
+
+      int segndx = INTUSE(dwfl_addrsegment) (mod->dwfl, d_val_vaddr, NULL);
+
+      if ((*memory_callback) (mod->dwfl, segndx,
+			      &buffer, &buffer_available,
+			      d_val_vaddr, buffer_available,
+			      memory_callback_arg))
+	{
+	  const union
+	  {
+	    Elf32_Addr a32;
+	    Elf64_Addr a64;
+	  } *u = buffer;
+
+	  GElf_Addr vaddr;
+	  if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
+	    vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB
+		     ? BE32 (u->a32) : LE32 (u->a32));
+	  else
+	    vaddr = (ehdr.e_ident[EI_DATA] == ELFDATA2MSB
+		     ? BE64 (u->a64) : LE64 (u->a64));
+
+	  (*memory_callback) (mod->dwfl, -1, &buffer, &buffer_available, 0, 0,
+			      memory_callback_arg);
+
+	  if (*elfclass == ELFCLASSNONE)
+	    *elfclass = ehdr.e_ident[EI_CLASS];
+	  else if (*elfclass != ehdr.e_ident[EI_CLASS])
+	    return 0;
+
+	  if (*elfdata == ELFDATANONE)
+	    *elfdata = ehdr.e_ident[EI_DATA];
+	  else if (*elfdata != ehdr.e_ident[EI_DATA])
+	    return 0;
+
+	  return vaddr;
+	}
+    }
+
+  return 0;
+}
+
+/* Try to find an existing executable module with a DT_DEBUG.  */
+static GElf_Addr
+find_executable (Dwfl *dwfl, GElf_Addr at_phdr, GElf_Addr at_entry,
+		 uint_fast8_t *elfclass, uint_fast8_t *elfdata,
+		 Dwfl_Memory_Callback *memory_callback,
+		 void *memory_callback_arg)
+{
+  for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
+    if (mod->main.elf != NULL)
+      {
+	GElf_Addr r_debug_vaddr = consider_executable (mod, at_phdr, at_entry,
+						       elfclass, elfdata,
+						       memory_callback,
+						       memory_callback_arg);
+	if (r_debug_vaddr != 0)
+	  return r_debug_vaddr;
+      }
+
+  return 0;
+}
+
+
+int
+dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size,
+		      Dwfl_Memory_Callback *memory_callback,
+		      void *memory_callback_arg,
+		      struct r_debug_info *r_debug_info)
+{
+  GElf_Addr r_debug_vaddr = 0;
+
+  uint_fast8_t elfclass = ELFCLASSNONE;
+  uint_fast8_t elfdata = ELFDATANONE;
+  if (likely (auxv != NULL)
+      && likely (auxv_format_probe (auxv, auxv_size, &elfclass, &elfdata)))
+    {
+      GElf_Addr entry = 0;
+      GElf_Addr phdr = 0;
+      GElf_Xword phent = 0;
+      GElf_Xword phnum = 0;
+
+#define READ_AUXV32(ptr)	read_4ubyte_unaligned_noncvt (ptr)
+#define READ_AUXV64(ptr)	read_8ubyte_unaligned_noncvt (ptr)
+#define AUXV_SCAN(NN, BL) do                                            \
+	{                                                               \
+	  const Elf##NN##_auxv_t *av = auxv;                            \
+	  for (size_t i = 0; i < auxv_size / sizeof av[0]; ++i)         \
+	    {                                                           \
+	      const char *typep = auxv + i * sizeof (Elf##NN##_auxv_t); \
+	      typep += offsetof (Elf##NN##_auxv_t, a_type);             \
+	      uint##NN##_t type = READ_AUXV##NN (typep);                \
+	      const char *valp = auxv + i * sizeof (Elf##NN##_auxv_t);  \
+	      valp += offsetof (Elf##NN##_auxv_t, a_un.a_val);          \
+	      uint##NN##_t val = BL##NN (READ_AUXV##NN (valp));         \
+	      if (type == BL##NN (AT_ENTRY))                            \
+		entry = val;                                            \
+	      else if (type == BL##NN (AT_PHDR))                        \
+		phdr = val;                                             \
+	      else if (type == BL##NN (AT_PHNUM))                       \
+		phnum = val;                                            \
+	      else if (type == BL##NN (AT_PHENT))                       \
+		phent = val;                                            \
+	      else if (type == BL##NN (AT_PAGESZ))                      \
+		{                                                       \
+		  if (val > 1                                           \
+		      && (dwfl->segment_align == 0                      \
+			  || val < dwfl->segment_align))                \
+		    dwfl->segment_align = val;                          \
+		}                                                       \
+	    }                                                           \
+	}                                                               \
+      while (0)
+
+      if (elfclass == ELFCLASS32)
+	{
+	  if (elfdata == ELFDATA2MSB)
+	    AUXV_SCAN (32, BE);
+	  else
+	    AUXV_SCAN (32, LE);
+	}
+      else
+	{
+	  if (elfdata == ELFDATA2MSB)
+	    AUXV_SCAN (64, BE);
+	  else
+	    AUXV_SCAN (64, LE);
+	}
+
+      /* If we found the phdr dimensions, search phdrs for PT_DYNAMIC.  */
+      GElf_Addr dyn_vaddr = 0;
+      GElf_Xword dyn_filesz = 0;
+      GElf_Addr dyn_bias = (GElf_Addr) -1;
+
+      inline bool consider_phdr (GElf_Word type,
+				 GElf_Addr vaddr, GElf_Xword filesz)
+      {
+	switch (type)
+	  {
+	  case PT_PHDR:
+	    if (dyn_bias == (GElf_Addr) -1
+		/* Do a sanity check on the putative address.  */
+		&& ((vaddr & (dwfl->segment_align - 1))
+		    == (phdr & (dwfl->segment_align - 1))))
+	      {
+		dyn_bias = phdr - vaddr;
+		return dyn_vaddr != 0;
+	      }
+	    break;
+
+	  case PT_DYNAMIC:
+	    dyn_vaddr = vaddr;
+	    dyn_filesz = filesz;
+	    return dyn_bias != (GElf_Addr) -1;
+	  }
+
+	return false;
+      }
+
+      if (phdr != 0 && phnum != 0)
+	{
+	  Dwfl_Module *phdr_mod;
+	  int phdr_segndx = INTUSE(dwfl_addrsegment) (dwfl, phdr, &phdr_mod);
+	  Elf_Data in =
+	    {
+	      .d_type = ELF_T_PHDR,
+	      .d_version = EV_CURRENT,
+	      .d_size = phnum * phent,
+	      .d_buf = NULL
+	    };
+	  bool in_ok = (*memory_callback) (dwfl, phdr_segndx, &in.d_buf,
+					   &in.d_size, phdr, phnum * phent,
+					   memory_callback_arg);
+	  bool in_from_exec = false;
+	  if (! in_ok
+	      && dwfl->user_core != NULL
+	      && dwfl->user_core->executable_for_core != NULL)
+	    {
+	      /* AUXV -> PHDR -> DYNAMIC
+		 Both AUXV and DYNAMIC should be always present in a core file.
+		 PHDR may be missing in core file, try to read it from
+		 EXECUTABLE_FOR_CORE to find where DYNAMIC is located in the
+		 core file.  */
+
+	      int fd = open (dwfl->user_core->executable_for_core, O_RDONLY);
+	      Elf *elf;
+	      Dwfl_Error error = DWFL_E_ERRNO;
+	      if (fd != -1)
+		error = __libdw_open_file (&fd, &elf, true, false);
+	      if (error != DWFL_E_NOERROR)
+		{
+		  __libdwfl_seterrno (error);
+		  return false;
+		}
+	      GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
+	      if (ehdr == NULL)
+		{
+		  elf_end (elf);
+		  close (fd);
+		  __libdwfl_seterrno (DWFL_E_LIBELF);
+		  return false;
+		}
+	      size_t e_phnum;
+	      if (elf_getphdrnum (elf, &e_phnum) != 0)
+		{
+		  elf_end (elf);
+		  close (fd);
+		  __libdwfl_seterrno (DWFL_E_LIBELF);
+		  return false;
+		}
+	      if (e_phnum != phnum || ehdr->e_phentsize != phent)
+		{
+		  elf_end (elf);
+		  close (fd);
+		  __libdwfl_seterrno (DWFL_E_BADELF);
+		  return false;
+		}
+	      off_t off = ehdr->e_phoff;
+	      assert (in.d_buf == NULL);
+	      /* Note this in the !in_ok path.  That means memory_callback
+		 failed.  But the callback might still have reset the d_size
+		 value (to zero).  So explicitly set it here again.  */
+	      in.d_size = phnum * phent;
+	      in.d_buf = malloc (in.d_size);
+	      if (unlikely (in.d_buf == NULL))
+		{
+		  elf_end (elf);
+		  close (fd);
+		  __libdwfl_seterrno (DWFL_E_NOMEM);
+		  return false;
+		}
+	      ssize_t nread = pread_retry (fd, in.d_buf, in.d_size, off);
+	      elf_end (elf);
+	      close (fd);
+	      if (nread != (ssize_t) in.d_size)
+		{
+		  free (in.d_buf);
+		  __libdwfl_seterrno (DWFL_E_ERRNO);
+		  return false;
+		}
+	      in_ok = true;
+	      in_from_exec = true;
+	    }
+	  if (in_ok)
+	    {
+	      if (unlikely (phnum > SIZE_MAX / phent))
+		{
+		  __libdwfl_seterrno (DWFL_E_NOMEM);
+		  return false;
+		}
+	      size_t nbytes = phnum * phent;
+	      void *buf = malloc (nbytes);
+	      Elf32_Phdr (*p32)[phnum] = buf;
+	      Elf64_Phdr (*p64)[phnum] = buf;
+	      if (unlikely (buf == NULL))
+		{
+		  __libdwfl_seterrno (DWFL_E_NOMEM);
+		  return false;
+		}
+	      Elf_Data out =
+		{
+		  .d_type = ELF_T_PHDR,
+		  .d_version = EV_CURRENT,
+		  .d_size = phnum * phent,
+		  .d_buf = buf
+		};
+	      in.d_size = out.d_size;
+	      if (likely ((elfclass == ELFCLASS32
+			   ? elf32_xlatetom : elf64_xlatetom)
+			  (&out, &in, elfdata) != NULL))
+		{
+		  /* We are looking for PT_DYNAMIC.  */
+		  if (elfclass == ELFCLASS32)
+		    {
+		      for (size_t i = 0; i < phnum; ++i)
+			if (consider_phdr ((*p32)[i].p_type,
+					   (*p32)[i].p_vaddr,
+					   (*p32)[i].p_filesz))
+			  break;
+		    }
+		  else
+		    {
+		      for (size_t i = 0; i < phnum; ++i)
+			if (consider_phdr ((*p64)[i].p_type,
+					   (*p64)[i].p_vaddr,
+					   (*p64)[i].p_filesz))
+			  break;
+		    }
+		}
+
+	      if (in_from_exec)
+		free (in.d_buf);
+	      else
+		(*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
+				    memory_callback_arg);
+	      free (buf);
+	    }
+	  else
+	    /* We could not read the executable's phdrs from the
+	       memory image.  If we have a presupplied executable,
+	       we can still use the AT_PHDR and AT_ENTRY values to
+	       verify it, and to adjust its bias if it's a PIE.
+
+	       If there was an ET_EXEC module presupplied that contains
+	       the AT_PHDR address, then we only consider that one.
+	       We'll either accept it if its phdr location and e_entry
+	       make sense or reject it if they don't.  If there is no
+	       presupplied ET_EXEC, then look for a presupplied module,
+	       which might be a PIE (ET_DYN) that needs its bias adjusted.  */
+	    r_debug_vaddr = ((phdr_mod == NULL
+			      || phdr_mod->main.elf == NULL
+			      || phdr_mod->e_type != ET_EXEC)
+			     ? find_executable (dwfl, phdr, entry,
+						&elfclass, &elfdata,
+						memory_callback,
+						memory_callback_arg)
+			     : consider_executable (phdr_mod, phdr, entry,
+						    &elfclass, &elfdata,
+						    memory_callback,
+						    memory_callback_arg));
+	}
+
+      /* If we found PT_DYNAMIC, search it for DT_DEBUG.  */
+      if (dyn_filesz != 0)
+	{
+	  if (dyn_bias != (GElf_Addr) -1)
+	    dyn_vaddr += dyn_bias;
+
+	  Elf_Data in =
+	    {
+	      .d_type = ELF_T_DYN,
+	      .d_version = EV_CURRENT,
+	      .d_size = dyn_filesz,
+	      .d_buf = NULL
+	    };
+	  int dyn_segndx = dwfl_addrsegment (dwfl, dyn_vaddr, NULL);
+	  if ((*memory_callback) (dwfl, dyn_segndx, &in.d_buf, &in.d_size,
+				  dyn_vaddr, dyn_filesz, memory_callback_arg))
+	    {
+	      void *buf = malloc (dyn_filesz);
+	      Elf32_Dyn (*d32)[dyn_filesz / sizeof (Elf32_Dyn)] = buf;
+	      Elf64_Dyn (*d64)[dyn_filesz / sizeof (Elf64_Dyn)] = buf;
+	      if (unlikely (buf == NULL))
+		{
+		  __libdwfl_seterrno (DWFL_E_NOMEM);
+		  return false;
+		}
+	      Elf_Data out =
+		{
+		  .d_type = ELF_T_DYN,
+		  .d_version = EV_CURRENT,
+		  .d_size = dyn_filesz,
+		  .d_buf = buf
+		};
+	      in.d_size = out.d_size;
+	      if (likely ((elfclass == ELFCLASS32
+			   ? elf32_xlatetom : elf64_xlatetom)
+			  (&out, &in, elfdata) != NULL))
+		{
+		  /* We are looking for DT_DEBUG.  */
+		  if (elfclass == ELFCLASS32)
+		    {
+		      size_t n = dyn_filesz / sizeof (Elf32_Dyn);
+		      for (size_t i = 0; i < n; ++i)
+			if ((*d32)[i].d_tag == DT_DEBUG)
+			  {
+			    r_debug_vaddr = (*d32)[i].d_un.d_val;
+			    break;
+			  }
+		    }
+		  else
+		    {
+		      size_t n = dyn_filesz / sizeof (Elf64_Dyn);
+		      for (size_t i = 0; i < n; ++i)
+			if ((*d64)[i].d_tag == DT_DEBUG)
+			  {
+			    r_debug_vaddr = (*d64)[i].d_un.d_val;
+			    break;
+			  }
+		    }
+		}
+
+	      (*memory_callback) (dwfl, -1, &in.d_buf, &in.d_size, 0, 0,
+				  memory_callback_arg);
+	      free (buf);
+	    }
+	}
+    }
+  else
+    /* We have to look for a presupplied executable file to determine
+       the vaddr of its dynamic section and DT_DEBUG therein.  */
+    r_debug_vaddr = find_executable (dwfl, 0, 0, &elfclass, &elfdata,
+				     memory_callback, memory_callback_arg);
+
+  if (r_debug_vaddr == 0)
+    return 0;
+
+  /* For following pointers from struct link_map, we will use an
+     integrated memory access callback that can consult module text
+     elided from the core file.  This is necessary when the l_name
+     pointer for the dynamic linker's own entry is a pointer into the
+     executable's .interp section.  */
+  struct integrated_memory_callback mcb =
+    {
+      .memory_callback = memory_callback,
+      .memory_callback_arg = memory_callback_arg
+    };
+
+  /* Now we can follow the dynamic linker's library list.  */
+  return report_r_debug (elfclass, elfdata, dwfl, r_debug_vaddr,
+			 &integrated_memory_callback, &mcb, r_debug_info);
+}
+INTDEF (dwfl_link_map_report)
diff --git a/third_party/elfutils/libdwfl/linux-core-attach.c b/third_party/elfutils/libdwfl/linux-core-attach.c
new file mode 100644
index 0000000..9f05f72
--- /dev/null
+++ b/third_party/elfutils/libdwfl/linux-core-attach.c
@@ -0,0 +1,430 @@
+/* Get Dwarf Frame state for target core file.
+   Copyright (C) 2013, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <fcntl.h>
+#include "system.h"
+
+#include "../libdw/memory-access.h"
+
+struct core_arg
+{
+  Elf *core;
+  Elf_Data *note_data;
+  size_t thread_note_offset;
+  Ebl *ebl;
+};
+
+struct thread_arg
+{
+  struct core_arg *core_arg;
+  size_t note_offset;
+};
+
+static bool
+core_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result,
+		  void *dwfl_arg)
+{
+  Dwfl_Process *process = dwfl->process;
+  struct core_arg *core_arg = dwfl_arg;
+  Elf *core = core_arg->core;
+  assert (core != NULL);
+  static size_t phnum;
+  if (elf_getphdrnum (core, &phnum) < 0)
+    {
+      __libdwfl_seterrno (DWFL_E_LIBELF);
+      return false;
+    }
+  for (size_t cnt = 0; cnt < phnum; ++cnt)
+    {
+      GElf_Phdr phdr_mem, *phdr = gelf_getphdr (core, cnt, &phdr_mem);
+      if (phdr == NULL || phdr->p_type != PT_LOAD)
+	continue;
+      /* Bias is zero here, a core file itself has no bias.  */
+      GElf_Addr start = __libdwfl_segment_start (dwfl, phdr->p_vaddr);
+      GElf_Addr end = __libdwfl_segment_end (dwfl,
+					     phdr->p_vaddr + phdr->p_memsz);
+      unsigned bytes = ebl_get_elfclass (process->ebl) == ELFCLASS64 ? 8 : 4;
+      if (addr < start || addr + bytes > end)
+	continue;
+      Elf_Data *data;
+      data = elf_getdata_rawchunk (core, phdr->p_offset + addr - start,
+				   bytes, ELF_T_ADDR);
+      if (data == NULL)
+	{
+	  __libdwfl_seterrno (DWFL_E_LIBELF);
+	  return false;
+	}
+      assert (data->d_size == bytes);
+      if (bytes == 8)
+	*result = read_8ubyte_unaligned_noncvt (data->d_buf);
+      else
+	*result = read_4ubyte_unaligned_noncvt (data->d_buf);
+      return true;
+    }
+  __libdwfl_seterrno (DWFL_E_ADDR_OUTOFRANGE);
+  return false;
+}
+
+static pid_t
+core_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
+		  void **thread_argp)
+{
+  struct core_arg *core_arg = dwfl_arg;
+  Elf *core = core_arg->core;
+  GElf_Nhdr nhdr;
+  size_t name_offset;
+  size_t desc_offset;
+  Elf_Data *note_data = core_arg->note_data;
+  size_t offset;
+
+  struct thread_arg *thread_arg;
+  if (*thread_argp == NULL)
+    {
+      core_arg->thread_note_offset = 0;
+      thread_arg = malloc (sizeof (*thread_arg));
+      if (thread_arg == NULL)
+	{
+	  __libdwfl_seterrno (DWFL_E_NOMEM);
+	  return -1;
+	}
+      thread_arg->core_arg = core_arg;
+      *thread_argp = thread_arg;
+    }
+  else
+    thread_arg = (struct thread_arg *) *thread_argp;
+
+  while (offset = core_arg->thread_note_offset, offset < note_data->d_size
+	 && (core_arg->thread_note_offset = gelf_getnote (note_data, offset,
+							  &nhdr, &name_offset,
+							  &desc_offset)) > 0)
+    {
+      /* Do not check NAME for now, help broken Linux kernels.  */
+      const char *name = (nhdr.n_namesz == 0
+			  ? "" : note_data->d_buf + name_offset);
+      const char *desc = note_data->d_buf + desc_offset;
+      GElf_Word regs_offset;
+      size_t nregloc;
+      const Ebl_Register_Location *reglocs;
+      size_t nitems;
+      const Ebl_Core_Item *items;
+      if (! ebl_core_note (core_arg->ebl, &nhdr, name,
+			   &regs_offset, &nregloc, &reglocs, &nitems, &items))
+	{
+	  /* This note may be just not recognized, skip it.  */
+	  continue;
+	}
+      if (nhdr.n_type != NT_PRSTATUS)
+	continue;
+      const Ebl_Core_Item *item;
+      for (item = items; item < items + nitems; item++)
+	if (strcmp (item->name, "pid") == 0)
+	  break;
+      if (item == items + nitems)
+	continue;
+      uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset);
+      val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
+		? be32toh (val32) : le32toh (val32));
+      pid_t tid = (int32_t) val32;
+      eu_static_assert (sizeof val32 <= sizeof tid);
+      thread_arg->note_offset = offset;
+      return tid;
+    }
+
+  free (thread_arg);
+  return 0;
+}
+
+static bool
+core_set_initial_registers (Dwfl_Thread *thread, void *thread_arg_voidp)
+{
+  struct thread_arg *thread_arg = thread_arg_voidp;
+  struct core_arg *core_arg = thread_arg->core_arg;
+  Elf *core = core_arg->core;
+  size_t offset = thread_arg->note_offset;
+  GElf_Nhdr nhdr;
+  size_t name_offset;
+  size_t desc_offset;
+  Elf_Data *note_data = core_arg->note_data;
+  size_t nregs = ebl_frame_nregs (core_arg->ebl);
+  assert (nregs > 0);
+  assert (offset < note_data->d_size);
+  size_t getnote_err = gelf_getnote (note_data, offset, &nhdr, &name_offset,
+				     &desc_offset);
+  /* __libdwfl_attach_state_for_core already verified the note is there.  */
+  assert (getnote_err != 0);
+  /* Do not check NAME for now, help broken Linux kernels.  */
+  const char *name = (nhdr.n_namesz == 0
+		      ? "" : note_data->d_buf + name_offset);
+  const char *desc = note_data->d_buf + desc_offset;
+  GElf_Word regs_offset;
+  size_t nregloc;
+  const Ebl_Register_Location *reglocs;
+  size_t nitems;
+  const Ebl_Core_Item *items;
+  int core_note_err = ebl_core_note (core_arg->ebl, &nhdr, name, &regs_offset,
+				     &nregloc, &reglocs, &nitems, &items);
+  /* __libdwfl_attach_state_for_core already verified the note is there.  */
+  assert (core_note_err != 0);
+  assert (nhdr.n_type == NT_PRSTATUS);
+  const Ebl_Core_Item *item;
+  for (item = items; item < items + nitems; item++)
+    if (strcmp (item->name, "pid") == 0)
+      break;
+  assert (item < items + nitems);
+  pid_t tid;
+  {
+    uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset);
+    val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
+	     ? be32toh (val32) : le32toh (val32));
+    tid = (int32_t) val32;
+    eu_static_assert (sizeof val32 <= sizeof tid);
+  }
+  /* core_next_thread already found this TID there.  */
+  assert (tid == INTUSE(dwfl_thread_tid) (thread));
+  for (item = items; item < items + nitems; item++)
+    if (item->pc_register)
+      break;
+  if (item < items + nitems)
+    {
+      Dwarf_Word pc;
+      switch (gelf_getclass (core) == ELFCLASS32 ? 32 : 64)
+      {
+	case 32:;
+	  uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset);
+	  val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
+		   ? be32toh (val32) : le32toh (val32));
+	  /* Do a host width conversion.  */
+	  pc = val32;
+	  break;
+	case 64:;
+	  uint64_t val64 = read_8ubyte_unaligned_noncvt (desc + item->offset);
+	  val64 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
+		   ? be64toh (val64) : le64toh (val64));
+	  pc = val64;
+	  break;
+	default:
+	  abort ();
+      }
+      INTUSE(dwfl_thread_state_register_pc) (thread, pc);
+    }
+  desc += regs_offset;
+  for (size_t regloci = 0; regloci < nregloc; regloci++)
+    {
+      const Ebl_Register_Location *regloc = reglocs + regloci;
+      // Iterate even regs out of NREGS range so that we can find pc_register.
+      if (regloc->bits != 32 && regloc->bits != 64)
+	continue;
+      const char *reg_desc = desc + regloc->offset;
+      for (unsigned regno = regloc->regno;
+	   regno < regloc->regno + (regloc->count ?: 1U);
+	   regno++)
+	{
+	  /* PPC provides DWARF register 65 irrelevant for
+	     CFI which clashes with register 108 (LR) we need.
+	     LR (108) is provided earlier (in NT_PRSTATUS) than the # 65.
+	     FIXME: It depends now on their order in core notes.
+	     FIXME: It uses private function.  */
+	  if (regno < nregs
+	      && __libdwfl_frame_reg_get (thread->unwound, regno, NULL))
+	    continue;
+	  Dwarf_Word val;
+	  switch (regloc->bits)
+	  {
+	    case 32:;
+	      uint32_t val32 = read_4ubyte_unaligned_noncvt (reg_desc);
+	      reg_desc += sizeof val32;
+	      val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
+		       ? be32toh (val32) : le32toh (val32));
+	      /* Do a host width conversion.  */
+	      val = val32;
+	      break;
+	    case 64:;
+	      uint64_t val64 = read_8ubyte_unaligned_noncvt (reg_desc);
+	      reg_desc += sizeof val64;
+	      val64 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
+		       ? be64toh (val64) : le64toh (val64));
+	      assert (sizeof (*thread->unwound->regs) == sizeof val64);
+	      val = val64;
+	      break;
+	    default:
+	      abort ();
+	  }
+	  /* Registers not valid for CFI are just ignored.  */
+	  if (regno < nregs)
+	    INTUSE(dwfl_thread_state_registers) (thread, regno, 1, &val);
+	  if (regloc->pc_register)
+	    INTUSE(dwfl_thread_state_register_pc) (thread, val);
+	  reg_desc += regloc->pad;
+	}
+    }
+  return true;
+}
+
+static void
+core_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
+{
+  struct core_arg *core_arg = dwfl_arg;
+  ebl_closebackend (core_arg->ebl);
+  free (core_arg);
+}
+
+static const Dwfl_Thread_Callbacks core_thread_callbacks =
+{
+  core_next_thread,
+  NULL, /* get_thread */
+  core_memory_read,
+  core_set_initial_registers,
+  core_detach,
+  NULL, /* core_thread_detach */
+};
+
+int
+dwfl_core_file_attach (Dwfl *dwfl, Elf *core)
+{
+  Dwfl_Error err = DWFL_E_NOERROR;
+  Ebl *ebl = ebl_openbackend (core);
+  if (ebl == NULL)
+    {
+      err = DWFL_E_LIBEBL;
+    fail_err:
+      if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
+	dwfl->attacherr = __libdwfl_canon_error (err);
+      __libdwfl_seterrno (err);
+      return -1;
+    }
+  size_t nregs = ebl_frame_nregs (ebl);
+  if (nregs == 0)
+    {
+      err = DWFL_E_NO_UNWIND;
+    fail:
+      ebl_closebackend (ebl);
+      goto fail_err;
+    }
+  GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (core, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      err = DWFL_E_LIBELF;
+      goto fail;
+    }
+  if (ehdr->e_type != ET_CORE)
+    {
+      err = DWFL_E_NO_CORE_FILE;
+      goto fail;
+    }
+  size_t phnum;
+  if (elf_getphdrnum (core, &phnum) < 0)
+    {
+      err = DWFL_E_LIBELF;
+      goto fail;
+    }
+  pid_t pid = -1;
+  Elf_Data *note_data = NULL;
+  for (size_t cnt = 0; cnt < phnum; ++cnt)
+    {
+      GElf_Phdr phdr_mem, *phdr = gelf_getphdr (core, cnt, &phdr_mem);
+      if (phdr != NULL && phdr->p_type == PT_NOTE)
+	{
+	  note_data = elf_getdata_rawchunk (core, phdr->p_offset,
+					    phdr->p_filesz, ELF_T_NHDR);
+	  break;
+	}
+    }
+  if (note_data == NULL)
+    {
+      err = DWFL_E_LIBELF;
+      goto fail;
+    }
+  size_t offset = 0;
+  GElf_Nhdr nhdr;
+  size_t name_offset;
+  size_t desc_offset;
+  while (offset < note_data->d_size
+	 && (offset = gelf_getnote (note_data, offset,
+				    &nhdr, &name_offset, &desc_offset)) > 0)
+    {
+      /* Do not check NAME for now, help broken Linux kernels.  */
+      const char *name = (nhdr.n_namesz == 0
+			  ? "" : note_data->d_buf + name_offset);
+      const char *desc = note_data->d_buf + desc_offset;
+      GElf_Word regs_offset;
+      size_t nregloc;
+      const Ebl_Register_Location *reglocs;
+      size_t nitems;
+      const Ebl_Core_Item *items;
+      if (! ebl_core_note (ebl, &nhdr, name,
+			   &regs_offset, &nregloc, &reglocs, &nitems, &items))
+	{
+	  /* This note may be just not recognized, skip it.  */
+	  continue;
+	}
+      if (nhdr.n_type != NT_PRPSINFO)
+	continue;
+      const Ebl_Core_Item *item;
+      for (item = items; item < items + nitems; item++)
+	if (strcmp (item->name, "pid") == 0)
+	  break;
+      if (item == items + nitems)
+	continue;
+      uint32_t val32 = read_4ubyte_unaligned_noncvt (desc + item->offset);
+      val32 = (elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB
+		? be32toh (val32) : le32toh (val32));
+      pid = (int32_t) val32;
+      eu_static_assert (sizeof val32 <= sizeof pid);
+      break;
+    }
+  if (pid == -1)
+    {
+      /* No valid NT_PRPSINFO recognized in this CORE.  */
+      err = DWFL_E_BADELF;
+      goto fail;
+    }
+  struct core_arg *core_arg = malloc (sizeof *core_arg);
+  if (core_arg == NULL)
+    {
+      err = DWFL_E_NOMEM;
+      goto fail;
+    }
+  core_arg->core = core;
+  core_arg->note_data = note_data;
+  core_arg->thread_note_offset = 0;
+  core_arg->ebl = ebl;
+  if (! INTUSE(dwfl_attach_state) (dwfl, core, pid, &core_thread_callbacks,
+				   core_arg))
+    {
+      free (core_arg);
+      ebl_closebackend (ebl);
+      return -1;
+    }
+  return pid;
+}
+INTDEF (dwfl_core_file_attach)
diff --git a/third_party/elfutils/libdwfl/linux-kernel-modules.c b/third_party/elfutils/libdwfl/linux-kernel-modules.c
new file mode 100644
index 0000000..9d0fef2
--- /dev/null
+++ b/third_party/elfutils/libdwfl/linux-kernel-modules.c
@@ -0,0 +1,979 @@
+/* Standard libdwfl callbacks for debugging the running Linux kernel.
+   Copyright (C) 2005-2011, 2013, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* In case we have a bad fts we include this before config.h because it
+   can't handle _FILE_OFFSET_BITS.
+   Everything we need here is fine if its declarations just come first.
+   Also, include sys/types.h before fts. On some systems fts.h is not self
+   contained. */
+#ifdef BAD_FTS
+  #include <sys/types.h>
+  #include <fts.h>
+#endif
+
+#include <config.h>
+#include <system.h>
+
+#include "libdwflP.h"
+#include <inttypes.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/utsname.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/* If fts.h is included before config.h, its indirect inclusions may not
+   give us the right LFS aliases of these functions, so map them manually.  */
+#ifdef BAD_FTS
+  #ifdef _FILE_OFFSET_BITS
+    #define open open64
+    #define fopen fopen64
+  #endif
+#else
+  #include <sys/types.h>
+  #include <fts.h>
+#endif
+
+
+#define KERNEL_MODNAME	"kernel"
+
+#define MODULEDIRFMT	"/lib/modules/%s"
+
+#define KNOTESFILE	"/sys/kernel/notes"
+#define	MODNOTESFMT	"/sys/module/%s/notes"
+#define KSYMSFILE	"/proc/kallsyms"
+#define MODULELIST	"/proc/modules"
+#define	SECADDRDIRFMT	"/sys/module/%s/sections/"
+#define MODULE_SECT_NAME_LEN 32	/* Minimum any linux/module.h has had.  */
+
+
+static const char *vmlinux_suffixes[] =
+  {
+    ".gz",
+#ifdef USE_BZLIB
+    ".bz2",
+#endif
+#ifdef USE_LZMA
+    ".xz",
+#endif
+  };
+
+/* Try to open the given file as it is or under the debuginfo directory.  */
+static int
+try_kernel_name (Dwfl *dwfl, char **fname, bool try_debug)
+{
+  if (*fname == NULL)
+    return -1;
+
+  /* Don't bother trying *FNAME itself here if the path will cause it to be
+     tried because we give its own basename as DEBUGLINK_FILE.  */
+  int fd = ((((dwfl->callbacks->debuginfo_path
+	       ? *dwfl->callbacks->debuginfo_path : NULL)
+	      ?: DEFAULT_DEBUGINFO_PATH)[0] == ':') ? -1
+	    : TEMP_FAILURE_RETRY (open (*fname, O_RDONLY)));
+
+  if (fd < 0)
+    {
+      Dwfl_Module fakemod = { .dwfl = dwfl };
+
+      if (try_debug)
+	/* Passing NULL for DEBUGLINK_FILE searches for both the basenamer
+	   "vmlinux" and the default of basename + ".debug", to look for
+	   "vmlinux.debug" files.  */
+	fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0,
+						   *fname, NULL, 0,
+						   &fakemod.debug.name);
+      else
+	/* Try the file's unadorned basename as DEBUGLINK_FILE,
+	   to look only for "vmlinux" files.  */
+	fd = INTUSE(dwfl_standard_find_debuginfo) (&fakemod, NULL, NULL, 0,
+						   *fname, basename (*fname),
+						   0, &fakemod.debug.name);
+
+      if (fakemod.debug.name != NULL)
+	{
+	  free (*fname);
+	  *fname = fakemod.debug.name;
+	}
+    }
+
+  if (fd < 0)
+    for (size_t i = 0;
+	 i < sizeof vmlinux_suffixes / sizeof vmlinux_suffixes[0];
+	 ++i)
+      {
+	char *zname;
+	if (asprintf (&zname, "%s%s", *fname, vmlinux_suffixes[i]) > 0)
+	  {
+	    fd = TEMP_FAILURE_RETRY (open (zname, O_RDONLY));
+	    if (fd < 0)
+	      free (zname);
+	    else
+	      {
+		free (*fname);
+		*fname = zname;
+	      }
+	  }
+      }
+
+  if (fd < 0)
+    {
+      free (*fname);
+      *fname = NULL;
+    }
+
+  return fd;
+}
+
+static inline const char *
+kernel_release (void)
+{
+#ifdef __linux__
+  /* Cache the `uname -r` string we'll use.  */
+  static struct utsname utsname;
+  if (utsname.release[0] == '\0' && uname (&utsname) != 0)
+    return NULL;
+  return utsname.release;
+#else
+  /* Used for finding the running linux kernel, which isn't supported
+     on non-linux kernel systems.  */
+  errno = ENOTSUP;
+  return NULL;
+#endif
+}
+
+static int
+find_kernel_elf (Dwfl *dwfl, const char *release, char **fname)
+{
+  if ((release[0] == '/'
+       ? asprintf (fname, "%s/vmlinux", release)
+       : asprintf (fname, "/boot/vmlinux-%s", release)) < 0)
+    return -1;
+
+  int fd = try_kernel_name (dwfl, fname, true);
+  if (fd < 0 && release[0] != '/')
+    {
+      free (*fname);
+      if (asprintf (fname, MODULEDIRFMT "/vmlinux", release) < 0)
+	return -1;
+      fd = try_kernel_name (dwfl, fname, true);
+    }
+
+  return fd;
+}
+
+static int
+get_release (Dwfl *dwfl, const char **release)
+{
+  if (dwfl == NULL)
+    return -1;
+
+  const char *release_string = release == NULL ? NULL : *release;
+  if (release_string == NULL)
+    {
+      release_string = kernel_release ();
+      if (release_string == NULL)
+	return errno;
+      if (release != NULL)
+	*release = release_string;
+    }
+
+  return 0;
+}
+
+static int
+report_kernel (Dwfl *dwfl, const char **release,
+	       int (*predicate) (const char *module, const char *file))
+{
+  int result = get_release (dwfl, release);
+  if (unlikely (result != 0))
+    return result;
+
+  char *fname;
+  int fd = find_kernel_elf (dwfl, *release, &fname);
+
+  if (fd < 0)
+    result = ((predicate != NULL && !(*predicate) (KERNEL_MODNAME, NULL))
+	      ? 0 : errno ?: ENOENT);
+  else
+    {
+      bool report = true;
+
+      if (predicate != NULL)
+	{
+	  /* Let the predicate decide whether to use this one.  */
+	  int want = (*predicate) (KERNEL_MODNAME, fname);
+	  if (want < 0)
+	    result = errno;
+	  report = want > 0;
+	}
+
+      if (report)
+	{
+	  /* Note that on some architectures (e.g. x86_64) the vmlinux
+	     is ET_EXEC, while on others (e.g. ppc64) it is ET_DYN.
+	     In both cases the phdr p_vaddr load address will be non-zero.
+	     We want the image to be placed as if it was ET_DYN, so
+	     pass true for add_p_vaddr which will do the right thing
+	     (in combination with a zero base) in either case.  */
+	  Dwfl_Module *mod = INTUSE(dwfl_report_elf) (dwfl, KERNEL_MODNAME,
+						      fname, fd, 0, true);
+	  if (mod == NULL)
+	    result = -1;
+	  else
+	    /* The kernel is ET_EXEC, but always treat it as relocatable.  */
+	    mod->e_type = ET_DYN;
+	}
+
+      free (fname);
+
+      if (!report || result < 0)
+	close (fd);
+    }
+
+  return result;
+}
+
+/* Look for a kernel debug archive.  If we find one, report all its modules.
+   If not, return ENOENT.  */
+static int
+report_kernel_archive (Dwfl *dwfl, const char **release,
+		       int (*predicate) (const char *module, const char *file))
+{
+  int result = get_release (dwfl, release);
+  if (unlikely (result != 0))
+    return result;
+
+  char *archive;
+  int res = (((*release)[0] == '/')
+	     ? asprintf (&archive, "%s/debug.a", *release)
+	     : asprintf (&archive, MODULEDIRFMT "/debug.a", *release));
+  if (unlikely (res < 0))
+    return ENOMEM;
+
+  int fd = try_kernel_name (dwfl, &archive, false);
+  if (fd < 0)
+    result = errno ?: ENOENT;
+  else
+    {
+      /* We have the archive file open!  */
+      Dwfl_Module *last = __libdwfl_report_offline (dwfl, NULL, archive, fd,
+						    true, predicate);
+      if (unlikely (last == NULL))
+	result = -1;
+      else
+	{
+	  /* Find the kernel and move it to the head of the list.  */
+	  Dwfl_Module **tailp = &dwfl->modulelist, **prevp = tailp;
+	  for (Dwfl_Module *m = *prevp; m != NULL; m = *(prevp = &m->next))
+	    if (!m->gc && m->e_type != ET_REL && !strcmp (m->name, "kernel"))
+	      {
+		*prevp = m->next;
+		m->next = *tailp;
+		*tailp = m;
+		break;
+	      }
+	}
+    }
+
+  free (archive);
+  return result;
+}
+
+static size_t
+check_suffix (const FTSENT *f, size_t namelen)
+{
+#define TRY(sfx)							\
+  if ((namelen ? f->fts_namelen == namelen + sizeof sfx - 1		\
+       : f->fts_namelen >= sizeof sfx)					\
+      && !memcmp (f->fts_name + f->fts_namelen - (sizeof sfx - 1),	\
+		  sfx, sizeof sfx))					\
+    return sizeof sfx - 1
+
+  TRY (".ko");
+  TRY (".ko.gz");
+#if USE_BZLIB
+  TRY (".ko.bz2");
+#endif
+#if USE_LZMA
+  TRY (".ko.xz");
+#endif
+
+  return 0;
+
+#undef	TRY
+}
+
+/* Report a kernel and all its modules found on disk, for offline use.
+   If RELEASE starts with '/', it names a directory to look in;
+   if not, it names a directory to find under /lib/modules/;
+   if null, /lib/modules/`uname -r` is used.
+   Returns zero on success, -1 if dwfl_report_module failed,
+   or an errno code if finding the files on disk failed.  */
+int
+dwfl_linux_kernel_report_offline (Dwfl *dwfl, const char *release,
+				  int (*predicate) (const char *module,
+						    const char *file))
+{
+  int result = report_kernel_archive (dwfl, &release, predicate);
+  if (result != ENOENT)
+    return result;
+
+  /* First report the kernel.  */
+  result = report_kernel (dwfl, &release, predicate);
+  if (result == 0)
+    {
+      /* Do "find /lib/modules/RELEASE -name *.ko".  */
+
+      char *modulesdir[] = { NULL, NULL };
+      if (release[0] == '/')
+	modulesdir[0] = (char *) release;
+      else
+	{
+	  if (asprintf (&modulesdir[0], MODULEDIRFMT, release) < 0)
+	    return errno;
+	}
+
+      FTS *fts = fts_open (modulesdir, FTS_NOSTAT | FTS_LOGICAL, NULL);
+      if (modulesdir[0] == (char *) release)
+	modulesdir[0] = NULL;
+      if (fts == NULL)
+	{
+	  free (modulesdir[0]);
+	  return errno;
+	}
+
+      FTSENT *f;
+      while ((f = fts_read (fts)) != NULL)
+	{
+	  /* Skip a "source" subtree, which tends to be large.
+	     This insane hard-coding of names is what depmod does too.  */
+	  if (f->fts_namelen == sizeof "source" - 1
+	      && !strcmp (f->fts_name, "source"))
+	    {
+	      fts_set (fts, f, FTS_SKIP);
+	      continue;
+	    }
+
+	  switch (f->fts_info)
+	    {
+	    case FTS_F:
+	    case FTS_SL:
+	    case FTS_NSOK:;
+	      /* See if this file name matches "*.ko".  */
+	      const size_t suffix = check_suffix (f, 0);
+	      if (suffix)
+		{
+		  /* We have a .ko file to report.  Following the algorithm
+		     by which the kernel makefiles set KBUILD_MODNAME, we
+		     replace all ',' or '-' with '_' in the file name and
+		     call that the module name.  Modules could well be
+		     built using different embedded names than their file
+		     names.  To handle that, we would have to look at the
+		     __this_module.name contents in the module's text.  */
+
+		  char *name = strndup (f->fts_name, f->fts_namelen - suffix);
+		  if (unlikely (name == NULL))
+		    {
+		      __libdwfl_seterrno (DWFL_E_NOMEM);
+		      result = -1;
+		      break;
+		    }
+		  for (size_t i = 0; i < f->fts_namelen - suffix; ++i)
+		    if (name[i] == '-' || name[i] == ',')
+		      name[i] = '_';
+
+		  if (predicate != NULL)
+		    {
+		      /* Let the predicate decide whether to use this one.  */
+		      int want = (*predicate) (name, f->fts_path);
+		      if (want < 0)
+			{
+			  result = -1;
+			  free (name);
+			  break;
+			}
+		      if (!want)
+			{
+			  free (name);
+			  continue;
+			}
+		    }
+
+		  if (dwfl_report_offline (dwfl, name, f->fts_path, -1) == NULL)
+		    {
+		      free (name);
+		      result = -1;
+		      break;
+		    }
+		  free (name);
+		}
+	      continue;
+
+	    case FTS_ERR:
+	    case FTS_DNR:
+	    case FTS_NS:
+	      result = f->fts_errno;
+	      break;
+
+	    case FTS_SLNONE:
+	    default:
+	      continue;
+	    }
+
+	  /* We only get here in error cases.  */
+	  break;
+	}
+      fts_close (fts);
+      free (modulesdir[0]);
+    }
+
+  return result;
+}
+INTDEF (dwfl_linux_kernel_report_offline)
+
+
+/* State of read_address used by intuit_kernel_bounds. */
+struct read_address_state {
+  FILE *f;
+  char *line;
+  size_t linesz;
+  size_t n;
+  char *p;
+  const char *type;
+};
+
+static inline bool
+read_address (struct read_address_state *state, Dwarf_Addr *addr)
+{
+  if ((state->n = getline (&state->line, &state->linesz, state->f)) < 1 ||
+      state->line[state->n - 2] == ']')
+    return false;
+  *addr = strtoull (state->line, &state->p, 16);
+  state->p += strspn (state->p, " \t");
+  state->type = strsep (&state->p, " \t\n");
+  if (state->type == NULL)
+    return false;
+  return state->p != NULL && state->p != state->line;
+}
+
+
+/* Grovel around to guess the bounds of the runtime kernel image.  */
+static int
+intuit_kernel_bounds (Dwarf_Addr *start, Dwarf_Addr *end, Dwarf_Addr *notes)
+{
+  struct read_address_state state = { NULL, NULL, 0, 0, NULL, NULL };
+
+  state.f = fopen (KSYMSFILE, "r");
+  if (state.f == NULL)
+    return errno;
+
+  (void) __fsetlocking (state.f, FSETLOCKING_BYCALLER);
+
+  *notes = 0;
+
+  int result;
+  do
+    result = read_address (&state, start) ? 0 : -1;
+  while (result == 0 && strchr ("TtRr", *state.type) == NULL);
+
+  if (result == 0)
+    {
+      *end = *start;
+      while (read_address (&state, end))
+	if (*notes == 0 && !strcmp (state.p, "__start_notes\n"))
+	  *notes = *end;
+
+      Dwarf_Addr round_kernel = sysconf (_SC_PAGESIZE);
+      *start &= -(Dwarf_Addr) round_kernel;
+      *end += round_kernel - 1;
+      *end &= -(Dwarf_Addr) round_kernel;
+      if (*start >= *end || *end - *start < round_kernel)
+	result = -1;
+    }
+  free (state.line);
+
+  if (result == -1)
+    result = ferror_unlocked (state.f) ? errno : ENOEXEC;
+
+  fclose (state.f);
+
+  return result;
+}
+
+
+/* Look for a build ID note in NOTESFILE and associate the ID with MOD.  */
+static int
+check_notes (Dwfl_Module *mod, const char *notesfile,
+	     Dwarf_Addr vaddr, const char *secname)
+{
+  int fd = open (notesfile, O_RDONLY);
+  if (fd < 0)
+    return 1;
+
+  assert (sizeof (Elf32_Nhdr) == sizeof (GElf_Nhdr));
+  assert (sizeof (Elf64_Nhdr) == sizeof (GElf_Nhdr));
+  union
+  {
+    GElf_Nhdr nhdr;
+    unsigned char data[8192];
+  } buf;
+
+  ssize_t n = read (fd, buf.data, sizeof buf);
+  close (fd);
+
+  if (n <= 0)
+    return 1;
+
+  unsigned char *p = buf.data;
+  while (p < &buf.data[n])
+    {
+      /* No translation required since we are reading the native kernel.  */
+      GElf_Nhdr *nhdr = (void *) p;
+      p += sizeof *nhdr;
+      unsigned char *name = p;
+      p += (nhdr->n_namesz + 3) & -4U;
+      unsigned char *bits = p;
+      p += (nhdr->n_descsz + 3) & -4U;
+
+      if (p <= &buf.data[n]
+	  && nhdr->n_type == NT_GNU_BUILD_ID
+	  && nhdr->n_namesz == sizeof "GNU"
+	  && !memcmp (name, "GNU", sizeof "GNU"))
+	{
+	  /* Found it.  For a module we must figure out its VADDR now.  */
+
+	  if (secname != NULL
+	      && (INTUSE(dwfl_linux_kernel_module_section_address)
+		  (mod, NULL, mod->name, 0, secname, 0, NULL, &vaddr) != 0
+		  || vaddr == (GElf_Addr) -1l))
+	    vaddr = 0;
+
+	  if (vaddr != 0)
+	    vaddr += bits - buf.data;
+	  return INTUSE(dwfl_module_report_build_id) (mod, bits,
+						      nhdr->n_descsz, vaddr);
+	}
+    }
+
+  return 0;
+}
+
+/* Look for a build ID for the kernel.  */
+static int
+check_kernel_notes (Dwfl_Module *kernelmod, GElf_Addr vaddr)
+{
+  return check_notes (kernelmod, KNOTESFILE, vaddr, NULL) < 0 ? -1 : 0;
+}
+
+/* Look for a build ID for a loaded kernel module.  */
+static int
+check_module_notes (Dwfl_Module *mod)
+{
+  char *dirs[2] = { NULL, NULL };
+  if (asprintf (&dirs[0], MODNOTESFMT, mod->name) < 0)
+    return ENOMEM;
+
+  FTS *fts = fts_open (dirs, FTS_NOSTAT | FTS_LOGICAL, NULL);
+  if (fts == NULL)
+    {
+      free (dirs[0]);
+      return 0;
+    }
+
+  int result = 0;
+  FTSENT *f;
+  while ((f = fts_read (fts)) != NULL)
+    {
+      switch (f->fts_info)
+	{
+	case FTS_F:
+	case FTS_SL:
+	case FTS_NSOK:
+	  result = check_notes (mod, f->fts_accpath, 0, f->fts_name);
+	  if (result > 0)	/* Nothing found.  */
+	    {
+	      result = 0;
+	      continue;
+	    }
+	  break;
+
+	case FTS_ERR:
+	case FTS_DNR:
+	  result = f->fts_errno;
+	  break;
+
+	case FTS_NS:
+	case FTS_SLNONE:
+	default:
+	  continue;
+	}
+
+      /* We only get here when finished or in error cases.  */
+      break;
+    }
+  fts_close (fts);
+  free (dirs[0]);
+
+  return result;
+}
+
+int
+dwfl_linux_kernel_report_kernel (Dwfl *dwfl)
+{
+  Dwarf_Addr start = 0;
+  Dwarf_Addr end = 0;
+
+  #define report() \
+    (INTUSE(dwfl_report_module) (dwfl, KERNEL_MODNAME, start, end))
+
+  /* This is a bit of a kludge.  If we already reported the kernel,
+     don't bother figuring it out again--it never changes.  */
+  for (Dwfl_Module *m = dwfl->modulelist; m != NULL; m = m->next)
+    if (!strcmp (m->name, KERNEL_MODNAME))
+      {
+	start = m->low_addr;
+	end = m->high_addr;
+	return report () == NULL ? -1 : 0;
+      }
+
+  /* Try to figure out the bounds of the kernel image without
+     looking for any vmlinux file.  */
+  Dwarf_Addr notes;
+  /* The compiler cannot deduce that if intuit_kernel_bounds returns
+     zero NOTES will be initialized.  Fake the initialization.  */
+  asm ("" : "=m" (notes));
+  int result = intuit_kernel_bounds (&start, &end, &notes);
+  if (result == 0)
+    {
+      Dwfl_Module *mod = report ();
+      return unlikely (mod == NULL) ? -1 : check_kernel_notes (mod, notes);
+    }
+  if (result != ENOENT)
+    return result;
+
+  /* Find the ELF file for the running kernel and dwfl_report_elf it.  */
+  return report_kernel (dwfl, NULL, NULL);
+}
+INTDEF (dwfl_linux_kernel_report_kernel)
+
+
+static inline bool
+subst_name (char from, char to,
+            const char * const module_name,
+            char * const alternate_name,
+            const size_t namelen)
+{
+  const char *n = memchr (module_name, from, namelen);
+  if (n == NULL)
+    return false;
+  char *a = mempcpy (alternate_name, module_name, n - module_name);
+  *a++ = to;
+  ++n;
+  const char *p;
+  while ((p = memchr (n, from, namelen - (n - module_name))) != NULL)
+    {
+      a = mempcpy (a, n, p - n);
+      *a++ = to;
+      n = p + 1;
+    }
+  memcpy (a, n, namelen - (n - module_name) + 1);
+  return true;
+}
+
+/* Dwfl_Callbacks.find_elf for the running Linux kernel and its modules.  */
+
+int
+dwfl_linux_kernel_find_elf (Dwfl_Module *mod,
+			    void **userdata __attribute__ ((unused)),
+			    const char *module_name,
+			    Dwarf_Addr base __attribute__ ((unused)),
+			    char **file_name, Elf **elfp)
+{
+  if (mod->build_id_len > 0)
+    {
+      int fd = INTUSE(dwfl_build_id_find_elf) (mod, NULL, NULL, 0,
+					       file_name, elfp);
+      if (fd >= 0 || mod->main.elf != NULL || errno != 0)
+	return fd;
+    }
+
+  const char *release = kernel_release ();
+  if (release == NULL)
+    return errno;
+
+  if (!strcmp (module_name, KERNEL_MODNAME))
+    return find_kernel_elf (mod->dwfl, release, file_name);
+
+  /* Do "find /lib/modules/`uname -r` -name MODULE_NAME.ko".  */
+
+  char *modulesdir[] = { NULL, NULL };
+  if (asprintf (&modulesdir[0], MODULEDIRFMT, release) < 0)
+    return -1;
+
+  FTS *fts = fts_open (modulesdir, FTS_NOSTAT | FTS_LOGICAL, NULL);
+  if (fts == NULL)
+    {
+      free (modulesdir[0]);
+      return -1;
+    }
+
+  size_t namelen = strlen (module_name);
+
+  /* This is a kludge.  There is no actual necessary relationship between
+     the name of the .ko file installed and the module name the kernel
+     knows it by when it's loaded.  The kernel's only idea of the module
+     name comes from the name embedded in the object's magic
+     .gnu.linkonce.this_module section.
+
+     In practice, these module names match the .ko file names except for
+     some using '_' and some using '-'.  So our cheap kludge is to look for
+     two files when either a '_' or '-' appears in a module name, one using
+     only '_' and one only using '-'.  */
+
+  char *alternate_name = malloc (namelen + 1);
+  if (unlikely (alternate_name == NULL))
+    {
+      free (modulesdir[0]);
+      return ENOMEM;
+    }
+  if (!subst_name ('-', '_', module_name, alternate_name, namelen) &&
+      !subst_name ('_', '-', module_name, alternate_name, namelen))
+    alternate_name[0] = '\0';
+
+  FTSENT *f;
+  int error = ENOENT;
+  while ((f = fts_read (fts)) != NULL)
+    {
+      /* Skip a "source" subtree, which tends to be large.
+	 This insane hard-coding of names is what depmod does too.  */
+      if (f->fts_namelen == sizeof "source" - 1
+	  && !strcmp (f->fts_name, "source"))
+	{
+	  fts_set (fts, f, FTS_SKIP);
+	  continue;
+	}
+
+      error = ENOENT;
+      switch (f->fts_info)
+	{
+	case FTS_F:
+	case FTS_SL:
+	case FTS_NSOK:
+	  /* See if this file name is "MODULE_NAME.ko".  */
+	  if (check_suffix (f, namelen)
+	      && (!memcmp (f->fts_name, module_name, namelen)
+		  || !memcmp (f->fts_name, alternate_name, namelen)))
+	    {
+	      int fd = open (f->fts_accpath, O_RDONLY);
+	      *file_name = strdup (f->fts_path);
+	      fts_close (fts);
+	      free (modulesdir[0]);
+	      free (alternate_name);
+	      if (fd < 0)
+		free (*file_name);
+	      else if (*file_name == NULL)
+		{
+		  close (fd);
+		  fd = -1;
+		}
+	      return fd;
+	    }
+	  break;
+
+	case FTS_ERR:
+	case FTS_DNR:
+	case FTS_NS:
+	  error = f->fts_errno;
+	  break;
+
+	case FTS_SLNONE:
+	default:
+	  break;
+	}
+    }
+
+  fts_close (fts);
+  free (modulesdir[0]);
+  free (alternate_name);
+  errno = error;
+  return -1;
+}
+INTDEF (dwfl_linux_kernel_find_elf)
+
+
+/* Dwfl_Callbacks.section_address for kernel modules in the running Linux.
+   We read the information from /sys/module directly.  */
+
+int
+dwfl_linux_kernel_module_section_address
+(Dwfl_Module *mod __attribute__ ((unused)),
+ void **userdata __attribute__ ((unused)),
+ const char *modname, Dwarf_Addr base __attribute__ ((unused)),
+ const char *secname, Elf32_Word shndx __attribute__ ((unused)),
+ const GElf_Shdr *shdr __attribute__ ((unused)),
+ Dwarf_Addr *addr)
+{
+  char *sysfile;
+  if (asprintf (&sysfile, SECADDRDIRFMT "%s", modname, secname) < 0)
+    return DWARF_CB_ABORT;
+
+  FILE *f = fopen (sysfile, "r");
+  free (sysfile);
+
+  if (f == NULL)
+    {
+      if (errno == ENOENT)
+	{
+	  /* The .modinfo and .data.percpu sections are never kept
+	     loaded in the kernel.  If the kernel was compiled without
+	     CONFIG_MODULE_UNLOAD, the .exit.* sections are not
+	     actually loaded at all.
+
+	     Setting *ADDR to -1 tells the caller this section is
+	     actually absent from memory.  */
+
+	  if (!strcmp (secname, ".modinfo")
+	      || !strcmp (secname, ".data.percpu")
+	      || !strncmp (secname, ".exit", 5))
+	    {
+	      *addr = (Dwarf_Addr) -1l;
+	      return DWARF_CB_OK;
+	    }
+
+	  /* The goofy PPC64 module_frob_arch_sections function tweaks
+	     the section names as a way to control other kernel code's
+	     behavior, and this cruft leaks out into the /sys information.
+	     The file name for ".init*" may actually look like "_init*".  */
+
+	  const bool is_init = !strncmp (secname, ".init", 5);
+	  if (is_init)
+	    {
+	      if (asprintf (&sysfile, SECADDRDIRFMT "_%s",
+			    modname, &secname[1]) < 0)
+		return ENOMEM;
+	      f = fopen (sysfile, "r");
+	      free (sysfile);
+	      if (f != NULL)
+		goto ok;
+	    }
+
+	  /* The kernel truncates section names to MODULE_SECT_NAME_LEN - 1.
+	     In case that size increases in the future, look for longer
+	     truncated names first.  */
+	  size_t namelen = strlen (secname);
+	  if (namelen >= MODULE_SECT_NAME_LEN)
+	    {
+	      int len = asprintf (&sysfile, SECADDRDIRFMT "%s",
+				  modname, secname);
+	      if (len < 0)
+		return DWARF_CB_ABORT;
+	      char *end = sysfile + len;
+	      do
+		{
+		  *--end = '\0';
+		  f = fopen (sysfile, "r");
+		  if (is_init && f == NULL && errno == ENOENT)
+		    {
+		      sysfile[len - namelen] = '_';
+		      f = fopen (sysfile, "r");
+		      sysfile[len - namelen] = '.';
+		    }
+		}
+	      while (f == NULL && errno == ENOENT
+		     && end - &sysfile[len - namelen] >= MODULE_SECT_NAME_LEN);
+	      free (sysfile);
+
+	      if (f != NULL)
+		goto ok;
+	    }
+	}
+
+      return DWARF_CB_ABORT;
+    }
+
+ ok:
+  (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
+
+  int result = (fscanf (f, "%" PRIx64 "\n", addr) == 1 ? 0
+		: ferror_unlocked (f) ? errno : ENOEXEC);
+  fclose (f);
+
+  if (result == 0)
+    return DWARF_CB_OK;
+
+  errno = result;
+  return DWARF_CB_ABORT;
+}
+INTDEF (dwfl_linux_kernel_module_section_address)
+
+int
+dwfl_linux_kernel_report_modules (Dwfl *dwfl)
+{
+  FILE *f = fopen (MODULELIST, "r");
+  if (f == NULL)
+    return errno;
+
+  (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
+
+  int result = 0;
+  Dwarf_Addr modaddr;
+  unsigned long int modsz;
+  char modname[128];
+  char *line = NULL;
+  size_t linesz = 0;
+  /* We can't just use fscanf here because it's not easy to distinguish \n
+     from other whitespace so as to take the optional word following the
+     address but always stop at the end of the line.  */
+  while (getline (&line, &linesz, f) > 0
+	 && sscanf (line, "%128s %lu %*s %*s %*s %" PRIx64 " %*s\n",
+		    modname, &modsz, &modaddr) == 3)
+    {
+      Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, modname,
+						     modaddr, modaddr + modsz);
+      if (mod == NULL)
+	{
+	  result = -1;
+	  break;
+	}
+
+      result = check_module_notes (mod);
+    }
+  free (line);
+
+  if (result == 0)
+    result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC;
+
+  fclose (f);
+
+  return result;
+}
+INTDEF (dwfl_linux_kernel_report_modules)
diff --git a/third_party/elfutils/libdwfl/linux-pid-attach.c b/third_party/elfutils/libdwfl/linux-pid-attach.c
new file mode 100644
index 0000000..e6a5c41
--- /dev/null
+++ b/third_party/elfutils/libdwfl/linux-pid-attach.c
@@ -0,0 +1,444 @@
+/* Get Dwarf Frame state for target live PID process.
+   Copyright (C) 2013, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libelfP.h"
+#include "libdwflP.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <dirent.h>
+#include <unistd.h>
+
+#ifdef __linux__
+
+#include <sys/ptrace.h>
+#include <sys/syscall.h>
+
+static bool
+linux_proc_pid_is_stopped (pid_t pid)
+{
+  char buffer[64];
+  FILE *procfile;
+  bool retval, have_state;
+
+  snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
+  procfile = fopen (buffer, "r");
+  if (procfile == NULL)
+    return false;
+
+  have_state = false;
+  while (fgets (buffer, sizeof (buffer), procfile) != NULL)
+    if (strncmp (buffer, "State:", 6) == 0)
+      {
+	have_state = true;
+	break;
+      }
+  retval = (have_state && strstr (buffer, "T (stopped)") != NULL);
+  fclose (procfile);
+  return retval;
+}
+
+bool
+internal_function
+__libdwfl_ptrace_attach (pid_t tid, bool *tid_was_stoppedp)
+{
+  if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
+    {
+      __libdwfl_seterrno (DWFL_E_ERRNO);
+      return false;
+    }
+  *tid_was_stoppedp = linux_proc_pid_is_stopped (tid);
+  if (*tid_was_stoppedp)
+    {
+      /* Make sure there is a SIGSTOP signal pending even when the process is
+	 already State: T (stopped).  Older kernels might fail to generate
+	 a SIGSTOP notification in that case in response to our PTRACE_ATTACH
+	 above.  Which would make the waitpid below wait forever.  So emulate
+	 it.  Since there can only be one SIGSTOP notification pending this is
+	 safe.  See also gdb/linux-nat.c linux_nat_post_attach_wait.  */
+      syscall (__NR_tkill, tid, SIGSTOP);
+      ptrace (PTRACE_CONT, tid, NULL, NULL);
+    }
+  for (;;)
+    {
+      int status;
+      if (waitpid (tid, &status, __WALL) != tid || !WIFSTOPPED (status))
+	{
+	  int saved_errno = errno;
+	  ptrace (PTRACE_DETACH, tid, NULL, NULL);
+	  errno = saved_errno;
+	  __libdwfl_seterrno (DWFL_E_ERRNO);
+	  return false;
+	}
+      if (WSTOPSIG (status) == SIGSTOP)
+	break;
+      if (ptrace (PTRACE_CONT, tid, NULL,
+		  (void *) (uintptr_t) WSTOPSIG (status)) != 0)
+	{
+	  int saved_errno = errno;
+	  ptrace (PTRACE_DETACH, tid, NULL, NULL);
+	  errno = saved_errno;
+	  __libdwfl_seterrno (DWFL_E_ERRNO);
+	  return false;
+	}
+    }
+  return true;
+}
+
+static bool
+pid_memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result, void *arg)
+{
+  struct __libdwfl_pid_arg *pid_arg = arg;
+  pid_t tid = pid_arg->tid_attached;
+  assert (tid > 0);
+  Dwfl_Process *process = dwfl->process;
+  if (ebl_get_elfclass (process->ebl) == ELFCLASS64)
+    {
+#if SIZEOF_LONG == 8
+      errno = 0;
+      *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
+      return errno == 0;
+#else /* SIZEOF_LONG != 8 */
+      /* This should not happen.  */
+      return false;
+#endif /* SIZEOF_LONG != 8 */
+    }
+#if SIZEOF_LONG == 8
+  /* We do not care about reads unaliged to 4 bytes boundary.
+     But 0x...ffc read of 8 bytes could overrun a page.  */
+  bool lowered = (addr & 4) != 0;
+  if (lowered)
+    addr -= 4;
+#endif /* SIZEOF_LONG == 8 */
+  errno = 0;
+  *result = ptrace (PTRACE_PEEKDATA, tid, (void *) (uintptr_t) addr, NULL);
+  if (errno != 0)
+    return false;
+#if SIZEOF_LONG == 8
+# if BYTE_ORDER == BIG_ENDIAN
+  if (! lowered)
+    *result >>= 32;
+# else
+  if (lowered)
+    *result >>= 32;
+# endif
+#endif /* SIZEOF_LONG == 8 */
+  *result &= 0xffffffff;
+  return true;
+}
+
+static pid_t
+pid_next_thread (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg,
+		 void **thread_argp)
+{
+  struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
+  struct dirent *dirent;
+  /* Start fresh on first traversal. */
+  if (*thread_argp == NULL)
+    rewinddir (pid_arg->dir);
+  do
+    {
+      errno = 0;
+      dirent = readdir (pid_arg->dir);
+      if (dirent == NULL)
+	{
+	  if (errno != 0)
+	    {
+	      __libdwfl_seterrno (DWFL_E_ERRNO);
+	      return -1;
+	    }
+	  return 0;
+	}
+    }
+  while (strcmp (dirent->d_name, ".") == 0
+	 || strcmp (dirent->d_name, "..") == 0);
+  char *end;
+  errno = 0;
+  long tidl = strtol (dirent->d_name, &end, 10);
+  if (errno != 0)
+    {
+      __libdwfl_seterrno (DWFL_E_ERRNO);
+      return -1;
+    }
+  pid_t tid = tidl;
+  if (tidl <= 0 || (end && *end) || tid != tidl)
+    {
+      __libdwfl_seterrno (DWFL_E_PARSE_PROC);
+      return -1;
+    }
+  *thread_argp = dwfl_arg;
+  return tid;
+}
+
+/* Just checks that the thread id exists.  */
+static bool
+pid_getthread (Dwfl *dwfl __attribute__ ((unused)), pid_t tid,
+	       void *dwfl_arg, void **thread_argp)
+{
+  *thread_argp = dwfl_arg;
+  if (kill (tid, 0) < 0)
+    {
+      __libdwfl_seterrno (DWFL_E_ERRNO);
+      return false;
+    }
+  return true;
+}
+
+/* Implement the ebl_set_initial_registers_tid setfunc callback.  */
+
+static bool
+pid_thread_state_registers_cb (int firstreg, unsigned nregs,
+			       const Dwarf_Word *regs, void *arg)
+{
+  Dwfl_Thread *thread = (Dwfl_Thread *) arg;
+  if (firstreg < 0)
+    {
+      assert (firstreg == -1);
+      assert (nregs == 1);
+      INTUSE(dwfl_thread_state_register_pc) (thread, *regs);
+      return true;
+    }
+  assert (nregs > 0);
+  return INTUSE(dwfl_thread_state_registers) (thread, firstreg, nregs, regs);
+}
+
+static bool
+pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
+{
+  struct __libdwfl_pid_arg *pid_arg = thread_arg;
+  assert (pid_arg->tid_attached == 0);
+  pid_t tid = INTUSE(dwfl_thread_tid) (thread);
+  if (! pid_arg->assume_ptrace_stopped
+      && ! __libdwfl_ptrace_attach (tid, &pid_arg->tid_was_stopped))
+    return false;
+  pid_arg->tid_attached = tid;
+  Dwfl_Process *process = thread->process;
+  Ebl *ebl = process->ebl;
+  return ebl_set_initial_registers_tid (ebl, tid,
+					pid_thread_state_registers_cb, thread);
+}
+
+static void
+pid_detach (Dwfl *dwfl __attribute__ ((unused)), void *dwfl_arg)
+{
+  struct __libdwfl_pid_arg *pid_arg = dwfl_arg;
+  elf_end (pid_arg->elf);
+  close (pid_arg->elf_fd);
+  closedir (pid_arg->dir);
+  free (pid_arg);
+}
+
+void
+internal_function
+__libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
+{
+  /* This handling is needed only on older Linux kernels such as
+     2.6.32-358.23.2.el6.ppc64.  Later kernels such as
+     3.11.7-200.fc19.x86_64 remember the T (stopped) state
+     themselves and no longer need to pass SIGSTOP during
+     PTRACE_DETACH.  */
+  ptrace (PTRACE_DETACH, tid, NULL,
+	  (void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
+}
+
+static void
+pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
+{
+  struct __libdwfl_pid_arg *pid_arg = thread_arg;
+  pid_t tid = INTUSE(dwfl_thread_tid) (thread);
+  assert (pid_arg->tid_attached == tid);
+  pid_arg->tid_attached = 0;
+  if (! pid_arg->assume_ptrace_stopped)
+    __libdwfl_ptrace_detach (tid, pid_arg->tid_was_stopped);
+}
+
+static const Dwfl_Thread_Callbacks pid_thread_callbacks =
+{
+  pid_next_thread,
+  pid_getthread,
+  pid_memory_read,
+  pid_set_initial_registers,
+  pid_detach,
+  pid_thread_detach,
+};
+
+int
+dwfl_linux_proc_attach (Dwfl *dwfl, pid_t pid, bool assume_ptrace_stopped)
+{
+  char buffer[36];
+  FILE *procfile;
+  int err = 0; /* The errno to return and set for dwfl->attcherr.  */
+
+  /* Make sure to report the actual PID (thread group leader) to
+     dwfl_attach_state.  */
+  snprintf (buffer, sizeof (buffer), "/proc/%ld/status", (long) pid);
+  procfile = fopen (buffer, "r");
+  if (procfile == NULL)
+    {
+      err = errno;
+    fail:
+      if (dwfl->process == NULL && dwfl->attacherr == DWFL_E_NOERROR)
+	{
+	  errno = err;
+	  dwfl->attacherr = __libdwfl_canon_error (DWFL_E_ERRNO);
+	}
+      return err;
+    }
+
+  char *line = NULL;
+  size_t linelen = 0;
+  while (getline (&line, &linelen, procfile) >= 0)
+    if (strncmp (line, "Tgid:", 5) == 0)
+      {
+	errno = 0;
+	char *endptr;
+	long val = strtol (&line[5], &endptr, 10);
+	if ((errno == ERANGE && val == LONG_MAX)
+	    || *endptr != '\n' || val < 0 || val != (pid_t) val)
+	  pid = 0;
+	else
+	  pid = (pid_t) val;
+	break;
+      }
+  free (line);
+  fclose (procfile);
+
+  if (pid == 0)
+    {
+      err = ESRCH;
+      goto fail;
+    }
+
+  char name[64];
+  int i = snprintf (name, sizeof (name), "/proc/%ld/task", (long) pid);
+  assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
+  DIR *dir = opendir (name);
+  if (dir == NULL)
+    {
+      err = errno;
+      goto fail;
+    }
+
+  Elf *elf;
+  i = snprintf (name, sizeof (name), "/proc/%ld/exe", (long) pid);
+  assert (i > 0 && i < (ssize_t) sizeof (name) - 1);
+  int elf_fd = open (name, O_RDONLY);
+  if (elf_fd >= 0)
+    {
+      elf = elf_begin (elf_fd, ELF_C_READ_MMAP, NULL);
+      if (elf == NULL)
+	{
+	  /* Just ignore, dwfl_attach_state will fall back to trying
+	     to associate the Dwfl with one of the existing DWfl_Module
+	     ELF images (to know the machine/class backend to use).  */
+	  close (elf_fd);
+	  elf_fd = -1;
+	}
+    }
+  else
+    elf = NULL;
+  struct __libdwfl_pid_arg *pid_arg = malloc (sizeof *pid_arg);
+  if (pid_arg == NULL)
+    {
+      elf_end (elf);
+      close (elf_fd);
+      closedir (dir);
+      err = ENOMEM;
+      goto fail;
+    }
+  pid_arg->dir = dir;
+  pid_arg->elf = elf;
+  pid_arg->elf_fd = elf_fd;
+  pid_arg->tid_attached = 0;
+  pid_arg->assume_ptrace_stopped = assume_ptrace_stopped;
+  if (! INTUSE(dwfl_attach_state) (dwfl, elf, pid, &pid_thread_callbacks,
+				   pid_arg))
+    {
+      elf_end (elf);
+      close (elf_fd);
+      closedir (dir);
+      free (pid_arg);
+      return -1;
+    }
+  return 0;
+}
+INTDEF (dwfl_linux_proc_attach)
+
+struct __libdwfl_pid_arg *
+internal_function
+__libdwfl_get_pid_arg (Dwfl *dwfl)
+{
+  if (dwfl != NULL && dwfl->process != NULL
+      && dwfl->process->callbacks == &pid_thread_callbacks)
+    return (struct __libdwfl_pid_arg *) dwfl->process->callbacks_arg;
+
+  return NULL;
+}
+
+#else	/* __linux__ */
+
+bool
+internal_function
+__libdwfl_ptrace_attach (pid_t tid __attribute__ ((unused)),
+			 bool *tid_was_stoppedp __attribute__ ((unused)))
+{
+  errno = ENOSYS;
+  __libdwfl_seterrno (DWFL_E_ERRNO);
+  return false;
+}
+
+void
+internal_function
+__libdwfl_ptrace_detach (pid_t tid __attribute__ ((unused)),
+			 bool tid_was_stopped __attribute__ ((unused)))
+{
+}
+
+int
+dwfl_linux_proc_attach (Dwfl *dwfl __attribute__ ((unused)),
+			pid_t pid __attribute__ ((unused)),
+			bool assume_ptrace_stopped __attribute__ ((unused)))
+{
+  return ENOSYS;
+}
+INTDEF (dwfl_linux_proc_attach)
+
+struct __libdwfl_pid_arg *
+internal_function
+__libdwfl_get_pid_arg (Dwfl *dwfl __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+#endif /* ! __linux __ */
+
diff --git a/third_party/elfutils/libdwfl/linux-proc-maps.c b/third_party/elfutils/libdwfl/linux-proc-maps.c
new file mode 100644
index 0000000..c4438c0
--- /dev/null
+++ b/third_party/elfutils/libdwfl/linux-proc-maps.c
@@ -0,0 +1,440 @@
+/* Standard libdwfl callbacks for debugging a live Linux process.
+   Copyright (C) 2005-2010, 2013, 2014, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+#include <endian.h>
+#include "system.h"
+
+
+#define PROCMAPSFMT	"/proc/%d/maps"
+#define PROCMEMFMT	"/proc/%d/mem"
+#define PROCAUXVFMT	"/proc/%d/auxv"
+#define PROCEXEFMT	"/proc/%d/exe"
+
+
+/* Return ELFCLASS64 or ELFCLASS32 for the main ELF executable.  Return
+   ELFCLASSNONE for an error.  */
+
+static unsigned char
+get_pid_class (pid_t pid)
+{
+  char *fname;
+  if (asprintf (&fname, PROCEXEFMT, pid) < 0)
+    return ELFCLASSNONE;
+
+  int fd = open (fname, O_RDONLY);
+  free (fname);
+  if (fd < 0)
+    return ELFCLASSNONE;
+
+  unsigned char buf[EI_CLASS + 1];
+  ssize_t nread = pread_retry (fd, &buf, sizeof buf, 0);
+  close (fd);
+  if (nread != sizeof buf || buf[EI_MAG0] != ELFMAG0
+      || buf[EI_MAG1] != ELFMAG1 || buf[EI_MAG2] != ELFMAG2
+      || buf[EI_MAG3] != ELFMAG3
+      || (buf[EI_CLASS] != ELFCLASS64 && buf[EI_CLASS] != ELFCLASS32))
+    return ELFCLASSNONE;
+
+  return buf[EI_CLASS];
+}
+
+/* Search /proc/PID/auxv for the AT_SYSINFO_EHDR tag.
+
+   It would be easiest to call get_pid_class and parse everything according to
+   the 32-bit or 64-bit class.  But this would bring the overhead of syscalls
+   to open and read the "/proc/%d/exe" file.
+
+   Therefore this function tries to parse the "/proc/%d/auxv" content both
+   ways, as if it were the 32-bit format and also if it were the 64-bit format.
+   Only if it gives some valid data in both cases get_pid_class gets called.
+   In most cases only one of the format bit sizes gives valid data and the
+   get_pid_class call overhead can be saved.  */
+
+static int
+grovel_auxv (pid_t pid, Dwfl *dwfl, GElf_Addr *sysinfo_ehdr)
+{
+  char *fname;
+  if (asprintf (&fname, PROCAUXVFMT, pid) < 0)
+    return ENOMEM;
+
+  int fd = open (fname, O_RDONLY);
+  free (fname);
+  if (fd < 0)
+    return errno == ENOENT ? 0 : errno;
+
+  GElf_Addr sysinfo_ehdr64 = 0;
+  GElf_Addr sysinfo_ehdr32 = 0;
+  GElf_Addr segment_align64 = dwfl->segment_align;
+  GElf_Addr segment_align32 = dwfl->segment_align;
+  off_t offset = 0;
+  ssize_t nread;
+  union
+  {
+    Elf64_auxv_t a64[64];
+    Elf32_auxv_t a32[128];
+  } d;
+  do
+    {
+      eu_static_assert (sizeof d.a64 == sizeof d.a32);
+      nread = pread_retry (fd, d.a64, sizeof d.a64, offset);
+      if (nread < 0)
+	{
+	  int ret = errno;
+	  close (fd);
+	  return ret;
+	}
+      for (size_t a32i = 0; a32i < nread / sizeof d.a32[0]; a32i++)
+	{
+	  const Elf32_auxv_t *a32 = d.a32 + a32i;
+	  switch (a32->a_type)
+	  {
+	    case AT_SYSINFO_EHDR:
+	      sysinfo_ehdr32 = a32->a_un.a_val;
+	      break;
+	    case AT_PAGESZ:
+	      segment_align32 = a32->a_un.a_val;
+	      break;
+	  }
+	}
+      for (size_t a64i = 0; a64i < nread / sizeof d.a64[0]; a64i++)
+	{
+	  const Elf64_auxv_t *a64 = d.a64 + a64i;
+	  switch (a64->a_type)
+	  {
+	    case AT_SYSINFO_EHDR:
+	      sysinfo_ehdr64 = a64->a_un.a_val;
+	      break;
+	    case AT_PAGESZ:
+	      segment_align64 = a64->a_un.a_val;
+	      break;
+	  }
+	}
+      offset += nread;
+    }
+  while (nread == sizeof d.a64);
+
+  close (fd);
+
+  bool valid64 = sysinfo_ehdr64 != 0 || segment_align64 != dwfl->segment_align;
+  bool valid32 = sysinfo_ehdr32 != 0 || segment_align32 != dwfl->segment_align;
+
+  unsigned char pid_class = ELFCLASSNONE;
+  if (valid64 && valid32)
+    pid_class = get_pid_class (pid);
+
+  if (pid_class == ELFCLASS64 || (valid64 && ! valid32))
+    {
+      *sysinfo_ehdr = sysinfo_ehdr64;
+      dwfl->segment_align = segment_align64;
+      return 0;
+    }
+  if (pid_class == ELFCLASS32 || (! valid64 && valid32))
+    {
+      *sysinfo_ehdr = sysinfo_ehdr32;
+      dwfl->segment_align = segment_align32;
+      return 0;
+    }
+  return ENOEXEC;
+}
+
+static inline bool
+do_report (Dwfl *dwfl, char **plast_file, Dwarf_Addr low, Dwarf_Addr high)
+{
+  if (*plast_file != NULL)
+    {
+      Dwfl_Module *mod = INTUSE(dwfl_report_module) (dwfl, *plast_file,
+						     low, high);
+      free (*plast_file);
+      *plast_file = NULL;
+      if (unlikely (mod == NULL))
+        return true;
+    }
+  return false;
+}
+
+#define report() do_report(dwfl, &last_file, low, high)
+
+static int
+proc_maps_report (Dwfl *dwfl, FILE *f, GElf_Addr sysinfo_ehdr, pid_t pid)
+{
+  unsigned int last_dmajor = -1, last_dminor = -1;
+  uint64_t last_ino = -1;
+  char *last_file = NULL;
+  Dwarf_Addr low = 0, high = 0;
+
+  char *line = NULL;
+  size_t linesz;
+  ssize_t len;
+  while ((len = getline (&line, &linesz, f)) > 0)
+    {
+      if (line[len - 1] == '\n')
+	line[len - 1] = '\0';
+
+      Dwarf_Addr start, end, offset;
+      unsigned int dmajor, dminor;
+      uint64_t ino;
+      int nread = -1;
+      if (sscanf (line, "%" PRIx64 "-%" PRIx64 " %*s %" PRIx64
+		  " %x:%x %" PRIi64 " %n",
+		  &start, &end, &offset, &dmajor, &dminor, &ino, &nread) < 6
+	  || nread <= 0)
+	{
+	  free (line);
+	  free (last_file);
+	  return ENOEXEC;
+	}
+
+      /* If this is the special mapping AT_SYSINFO_EHDR pointed us at,
+	 report the last one and then this special one.  */
+      if (start == sysinfo_ehdr && start != 0)
+	{
+	  if (report ())
+	    {
+	    bad_report:
+	      free (line);
+	      return -1;
+	    }
+
+	  low = start;
+	  high = end;
+	  if (asprintf (&last_file, "[vdso: %d]", (int) pid) < 0
+	      || report ())
+	    goto bad_report;
+	}
+
+      char *file = line + nread + strspn (line + nread, " \t");
+      if (file[0] != '/' || (ino == 0 && dmajor == 0 && dminor == 0))
+	/* This line doesn't indicate a file mapping.  */
+	continue;
+
+      if (last_file != NULL
+	  && ino == last_ino && dmajor == last_dmajor && dminor == last_dminor)
+	{
+	  /* This is another portion of the same file's mapping.  */
+	  if (strcmp (last_file, file) != 0)
+	    {
+	      free (last_file);
+	      goto bad_report;
+	    }
+	  high = end;
+	}
+      else
+	{
+	  /* This is a different file mapping.  Report the last one.  */
+	  if (report ())
+	    goto bad_report;
+	  low = start;
+	  high = end;
+	  last_file = strdup (file);
+	  last_ino = ino;
+	  last_dmajor = dmajor;
+	  last_dminor = dminor;
+	}
+    }
+  free (line);
+
+  int result = ferror_unlocked (f) ? errno : feof_unlocked (f) ? 0 : ENOEXEC;
+
+  /* Report the final one.  */
+  bool lose = report ();
+
+  return result != 0 ? result : lose ? -1 : 0;
+}
+
+int
+dwfl_linux_proc_maps_report (Dwfl *dwfl, FILE *f)
+{
+  return proc_maps_report (dwfl, f, 0, 0);
+}
+INTDEF (dwfl_linux_proc_maps_report)
+
+int
+dwfl_linux_proc_report (Dwfl *dwfl, pid_t pid)
+{
+  if (dwfl == NULL)
+    return -1;
+
+  /* We'll notice the AT_SYSINFO_EHDR address specially when we hit it.  */
+  GElf_Addr sysinfo_ehdr = 0;
+  int result = grovel_auxv (pid, dwfl, &sysinfo_ehdr);
+  if (result != 0)
+    return result;
+
+  char *fname;
+  if (asprintf (&fname, PROCMAPSFMT, pid) < 0)
+    return ENOMEM;
+
+  FILE *f = fopen (fname, "r");
+  free (fname);
+  if (f == NULL)
+    return errno;
+
+  (void) __fsetlocking (f, FSETLOCKING_BYCALLER);
+
+  result = proc_maps_report (dwfl, f, sysinfo_ehdr, pid);
+
+  fclose (f);
+
+  return result;
+}
+INTDEF (dwfl_linux_proc_report)
+
+static ssize_t
+read_proc_memory (void *arg, void *data, GElf_Addr address,
+		  size_t minread, size_t maxread)
+{
+  const int fd = *(const int *) arg;
+
+  /* This code relies on the fact the Linux kernel accepts negative
+     offsets when seeking /dev/$$/mem files, as a special case. In
+     particular pread cannot be used here, because it will always
+     return EINVAL when passed a negative offset.  */
+
+  if (lseek (fd, (off_t) address, SEEK_SET) == -1)
+    return -1;
+
+  ssize_t nread = read (fd, data, maxread);
+
+  if (nread > 0 && (size_t) nread < minread)
+    nread = 0;
+  return nread;
+}
+
+extern Elf *elf_from_remote_memory (GElf_Addr ehdr_vma,
+				    GElf_Xword pagesize,
+				    GElf_Addr *loadbasep,
+				    ssize_t (*read_memory) (void *arg,
+							    void *data,
+							    GElf_Addr address,
+							    size_t minread,
+							    size_t maxread),
+				    void *arg);
+
+
+/* Dwfl_Callbacks.find_elf */
+
+int
+dwfl_linux_proc_find_elf (Dwfl_Module *mod __attribute__ ((unused)),
+			  void **userdata __attribute__ ((unused)),
+			  const char *module_name, Dwarf_Addr base,
+			  char **file_name, Elf **elfp)
+{
+  int pid = -1;
+  if (module_name[0] == '/')
+    {
+      /* When this callback is used together with dwfl_linux_proc_report
+	 then we might see mappings of special character devices.  Make
+	 sure we only open and return regular files.  Special devices
+	 might hang on open or read.  (deleted) files are super special.
+	 The image might come from memory if we are attached.  */
+      struct stat sb;
+      if (stat (module_name, &sb) == -1 || (sb.st_mode & S_IFMT) != S_IFREG)
+	{
+	  if (strcmp (strrchr (module_name, ' ') ?: "", " (deleted)") == 0)
+	    pid = INTUSE(dwfl_pid) (mod->dwfl);
+	  else
+	    return -1;
+	}
+
+      if (pid == -1)
+	{
+	  int fd = open (module_name, O_RDONLY);
+	  if (fd >= 0)
+	    {
+	      *file_name = strdup (module_name);
+	      if (*file_name == NULL)
+		{
+		  close (fd);
+		  return ENOMEM;
+		}
+	    }
+	  return fd;
+	}
+    }
+
+  if (pid != -1 || sscanf (module_name, "[vdso: %d]", &pid) == 1)
+    {
+      /* Special case for in-memory ELF image.  */
+
+      bool detach = false;
+      bool tid_was_stopped = false;
+      struct __libdwfl_pid_arg *pid_arg = __libdwfl_get_pid_arg (mod->dwfl);
+      if (pid_arg != NULL && ! pid_arg->assume_ptrace_stopped)
+	{
+	  /* If any thread is already attached we are fine.  Read
+	     through that thread.  It doesn't have to be the main
+	     thread pid.  */
+	  pid_t tid = pid_arg->tid_attached;
+	  if (tid != 0)
+	    pid = tid;
+	  else
+	    detach = __libdwfl_ptrace_attach (pid, &tid_was_stopped);
+	}
+
+      char *fname;
+      if (asprintf (&fname, PROCMEMFMT, pid) < 0)
+	goto detach;
+
+      int fd = open (fname, O_RDONLY);
+      free (fname);
+      if (fd < 0)
+	goto detach;
+
+      *elfp = elf_from_remote_memory (base, sysconf (_SC_PAGESIZE), NULL,
+				      &read_proc_memory, &fd);
+
+      close (fd);
+
+      *file_name = NULL;
+
+    detach:
+      if (detach)
+	__libdwfl_ptrace_detach (pid, tid_was_stopped);
+      return -1;
+    }
+
+  return -1;
+}
+INTDEF (dwfl_linux_proc_find_elf)
diff --git a/third_party/elfutils/libdwfl/lzma.c b/third_party/elfutils/libdwfl/lzma.c
new file mode 100644
index 0000000..3edfdc2
--- /dev/null
+++ b/third_party/elfutils/libdwfl/lzma.c
@@ -0,0 +1,4 @@
+/* liblzma is pretty close to zlib and bzlib.  */
+
+#define LZMA
+#include "gzip.c"
diff --git a/third_party/elfutils/libdwfl/offline.c b/third_party/elfutils/libdwfl/offline.c
new file mode 100644
index 0000000..80c80a1
--- /dev/null
+++ b/third_party/elfutils/libdwfl/offline.c
@@ -0,0 +1,315 @@
+/* Recover relocatibility for addresses computed from debug information.
+   Copyright (C) 2005-2009, 2012 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+#include <fcntl.h>
+#include <unistd.h>
+
+/* Since dwfl_report_elf lays out the sections already, this will only be
+   called when the section headers of the debuginfo file are being
+   consulted instead, or for the section placed at 0.  With binutils
+   strip-to-debug, the symbol table is in the debuginfo file and relocation
+   looks there.  */
+int
+dwfl_offline_section_address (Dwfl_Module *mod,
+			      void **userdata __attribute__ ((unused)),
+			      const char *modname __attribute__ ((unused)),
+			      Dwarf_Addr base __attribute__ ((unused)),
+			      const char *secname __attribute__ ((unused)),
+			      Elf32_Word shndx,
+			      const GElf_Shdr *shdr __attribute__ ((unused)),
+			      Dwarf_Addr *addr)
+{
+  assert (mod->e_type == ET_REL);
+  assert (shdr->sh_addr == 0);
+  assert (shdr->sh_flags & SHF_ALLOC);
+  assert (shndx != 0);
+
+  if (mod->debug.elf == NULL)
+    /* We are only here because sh_addr is zero even though layout is complete.
+       The first section in the first file under -e is placed at 0.  */
+    return 0;
+
+  /* The section numbers might not match between the two files.
+     The best we can rely on is the order of SHF_ALLOC sections.  */
+
+  Elf_Scn *ourscn = elf_getscn (mod->debug.elf, shndx);
+  Elf_Scn *scn = NULL;
+  uint_fast32_t skip_alloc = 0;
+  while ((scn = elf_nextscn (mod->debug.elf, scn)) != ourscn)
+    {
+      assert (scn != NULL);
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *sh = gelf_getshdr (scn, &shdr_mem);
+      if (unlikely (sh == NULL))
+	return -1;
+      if (sh->sh_flags & SHF_ALLOC)
+	++skip_alloc;
+    }
+
+  scn = NULL;
+  while ((scn = elf_nextscn (mod->main.elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *main_shdr = gelf_getshdr (scn, &shdr_mem);
+      if (unlikely (main_shdr == NULL))
+	return -1;
+      if ((main_shdr->sh_flags & SHF_ALLOC) && skip_alloc-- == 0)
+	{
+	  assert (main_shdr->sh_flags == shdr->sh_flags);
+	  *addr = main_shdr->sh_addr;
+	  return 0;
+	}
+    }
+
+  /* This should never happen.  */
+  return -1;
+}
+INTDEF (dwfl_offline_section_address)
+
+/* Forward declarations.  */
+static Dwfl_Module *process_elf (Dwfl *dwfl, const char *name,
+				 const char *file_name, int fd, Elf *elf);
+static Dwfl_Module *process_archive (Dwfl *dwfl, const char *name,
+				     const char *file_name, int fd, Elf *elf,
+				     int (*predicate) (const char *module,
+						       const char *file));
+
+/* Report one module for an ELF file, or many for an archive.
+   Always consumes ELF and FD.  */
+static Dwfl_Module *
+process_file (Dwfl *dwfl, const char *name, const char *file_name, int fd,
+	      Elf *elf, int (*predicate) (const char *module,
+					  const char *file))
+{
+  switch (elf_kind (elf))
+    {
+    default:
+    case ELF_K_NONE:
+      __libdwfl_seterrno (elf == NULL ? DWFL_E_LIBELF : DWFL_E_BADELF);
+      return NULL;
+
+    case ELF_K_ELF:
+      return process_elf (dwfl, name, file_name, fd, elf);
+
+    case ELF_K_AR:
+      return process_archive (dwfl, name, file_name, fd, elf, predicate);
+    }
+}
+
+/* Report the open ELF file as a module.  Always consumes ELF and FD.  */
+static Dwfl_Module *
+process_elf (Dwfl *dwfl, const char *name, const char *file_name, int fd,
+	     Elf *elf)
+{
+  Dwfl_Module *mod = __libdwfl_report_elf (dwfl, name, file_name, fd, elf,
+					   dwfl->offline_next_address, true,
+					   false);
+  if (mod != NULL)
+    {
+      /* If this is an ET_EXEC file with fixed addresses, the address range
+	 it consumed may or may not intersect with the arbitrary range we
+	 will use for relocatable modules.  Make sure we always use a free
+	 range for the offline allocations.  If this module did use
+	 offline_next_address, it may have rounded it up for the module's
+	 alignment requirements.  */
+      if ((dwfl->offline_next_address >= mod->low_addr
+	   || mod->low_addr - dwfl->offline_next_address < OFFLINE_REDZONE)
+	  && dwfl->offline_next_address < mod->high_addr + OFFLINE_REDZONE)
+	dwfl->offline_next_address = mod->high_addr + OFFLINE_REDZONE;
+
+      /* Don't keep the file descriptor around.  */
+      if (mod->main.fd != -1 && elf_cntl (mod->main.elf, ELF_C_FDREAD) == 0)
+	{
+	  close (mod->main.fd);
+	  mod->main.fd = -1;
+	}
+    }
+
+  return mod;
+}
+
+/* Always consumes MEMBER.  Returns elf_next result on success.
+   For errors returns ELF_C_NULL with *MOD set to null.  */
+static Elf_Cmd
+process_archive_member (Dwfl *dwfl, const char *name, const char *file_name,
+			int (*predicate) (const char *module, const char *file),
+			int fd, Elf *member, Dwfl_Module **mod)
+{
+  const Elf_Arhdr *h = elf_getarhdr (member);
+  if (unlikely (h == NULL))
+    {
+      __libdwfl_seterrno (DWFL_E_LIBELF);
+    fail:
+      elf_end (member);
+      *mod = NULL;
+      return ELF_C_NULL;
+    }
+
+  if (!strcmp (h->ar_name, "/") || !strcmp (h->ar_name, "//")
+      || !strcmp (h->ar_name, "/SYM64/"))
+    {
+    skip:;
+      /* Skip this and go to the next.  */
+      Elf_Cmd result = elf_next (member);
+      elf_end (member);
+      return result;
+    }
+
+  char *member_name;
+  if (unlikely (asprintf (&member_name, "%s(%s)", file_name, h->ar_name) < 0))
+    {
+    nomem:
+      __libdwfl_seterrno (DWFL_E_NOMEM);
+      elf_end (member);
+      *mod = NULL;
+      return ELF_C_NULL;
+    }
+
+  char *module_name = NULL;
+  if (name == NULL || name[0] == '\0')
+    name = h->ar_name;
+  else if (unlikely (asprintf (&module_name, "%s:%s", name, h->ar_name) < 0))
+    {
+      free (member_name);
+      goto nomem;
+    }
+  else
+    name = module_name;
+
+  if (predicate != NULL)
+    {
+      /* Let the predicate decide whether to use this one.  */
+      int want = (*predicate) (name, member_name);
+      if (want <= 0)
+	{
+	  free (member_name);
+	  free (module_name);
+	  if (unlikely (want < 0))
+	    {
+	      __libdwfl_seterrno (DWFL_E_CB);
+	      goto fail;
+	    }
+	  goto skip;
+	}
+    }
+
+  /* We let __libdwfl_report_elf cache the fd in mod->main.fd,
+     though it's the same fd for all the members.
+     On module teardown we will close it only on the last Elf reference.  */
+  *mod = process_file (dwfl, name, member_name, fd, member, predicate);
+  free (member_name);
+  free (module_name);
+
+  if (*mod == NULL)		/* process_file called elf_end.  */
+    return ELF_C_NULL;
+
+  /* Advance the archive-reading offset for the next iteration.  */
+  return elf_next (member);
+}
+
+/* Report each member of the archive as its own module.  */
+static Dwfl_Module *
+process_archive (Dwfl *dwfl, const char *name, const char *file_name, int fd,
+		 Elf *archive,
+		 int (*predicate) (const char *module, const char *file))
+
+{
+  Dwfl_Module *mod = NULL;
+  Elf *member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive);
+  if (unlikely (member == NULL)) /* Empty archive.  */
+    {
+      __libdwfl_seterrno (DWFL_E_BADELF);
+      return NULL;
+    }
+
+  while (process_archive_member (dwfl, name, file_name, predicate,
+				 fd, member, &mod) != ELF_C_NULL)
+    member = elf_begin (fd, ELF_C_READ_MMAP_PRIVATE, archive);
+
+  /* We can drop the archive Elf handle even if we're still using members
+     in live modules.  When the last module's elf_end on a member returns
+     zero, that module will close FD.  If no modules survived the predicate,
+     we are all done with the file right here.  */
+  if (mod != NULL		/* If no modules, caller will clean up.  */
+      && elf_end (archive) == 0)
+    close (fd);
+
+  return mod;
+}
+
+Dwfl_Module *
+internal_function
+__libdwfl_report_offline (Dwfl *dwfl, const char *name,
+			  const char *file_name, int fd, bool closefd,
+			  int (*predicate) (const char *module,
+					    const char *file))
+{
+  Elf *elf;
+  Dwfl_Error error = __libdw_open_file (&fd, &elf, closefd, true);
+  if (error != DWFL_E_NOERROR)
+    {
+      __libdwfl_seterrno (error);
+      return NULL;
+    }
+  Dwfl_Module *mod = process_file (dwfl, name, file_name, fd, elf, predicate);
+  if (mod == NULL)
+    {
+      elf_end (elf);
+      if (closefd)
+	close (fd);
+    }
+  return mod;
+}
+
+Dwfl_Module *
+dwfl_report_offline (Dwfl *dwfl, const char *name,
+		     const char *file_name, int fd)
+{
+  if (dwfl == NULL)
+    return NULL;
+
+  bool closefd = false;
+  if (fd < 0)
+    {
+      closefd = true;
+      fd = open (file_name, O_RDONLY);
+      if (fd < 0)
+	{
+	  __libdwfl_seterrno (DWFL_E_ERRNO);
+	  return NULL;
+	}
+    }
+
+  return __libdwfl_report_offline (dwfl, name, file_name, fd, closefd, NULL);
+}
+INTDEF (dwfl_report_offline)
diff --git a/third_party/elfutils/libdwfl/open.c b/third_party/elfutils/libdwfl/open.c
new file mode 100644
index 0000000..4e0461b
--- /dev/null
+++ b/third_party/elfutils/libdwfl/open.c
@@ -0,0 +1,180 @@
+/* Decompression support for libdwfl: zlib (gzip), bzlib (bzip2) or lzma (xz).
+   Copyright (C) 2009, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "../libelf/libelfP.h"
+#undef	_
+#include "libdwflP.h"
+
+#include <unistd.h>
+
+#if !USE_BZLIB
+# define __libdw_bunzip2(...)	DWFL_E_BADELF
+#endif
+
+#if !USE_LZMA
+# define __libdw_unlzma(...)	DWFL_E_BADELF
+#endif
+
+/* Consumes and replaces *ELF only on success.  */
+static Dwfl_Error
+decompress (int fd __attribute__ ((unused)), Elf **elf)
+{
+  Dwfl_Error error = DWFL_E_BADELF;
+  void *buffer = NULL;
+  size_t size = 0;
+
+  const off_t offset = (*elf)->start_offset;
+  void *const mapped = ((*elf)->map_address == NULL ? NULL
+			: (*elf)->map_address + offset);
+  const size_t mapped_size = (*elf)->maximum_size;
+  if (mapped_size == 0)
+    return error;
+
+  error = __libdw_gunzip (fd, offset, mapped, mapped_size, &buffer, &size);
+  if (error == DWFL_E_BADELF)
+    error = __libdw_bunzip2 (fd, offset, mapped, mapped_size, &buffer, &size);
+  if (error == DWFL_E_BADELF)
+    error = __libdw_unlzma (fd, offset, mapped, mapped_size, &buffer, &size);
+
+  if (error == DWFL_E_NOERROR)
+    {
+      if (unlikely (size == 0))
+	{
+	  error = DWFL_E_BADELF;
+	  free (buffer);
+	}
+      else
+	{
+	  Elf *memelf = elf_memory (buffer, size);
+	  if (memelf == NULL)
+	    {
+	      error = DWFL_E_LIBELF;
+	      free (buffer);
+	    }
+	  else
+	    {
+	      memelf->flags |= ELF_F_MALLOCED;
+	      elf_end (*elf);
+	      *elf = memelf;
+	    }
+	}
+    }
+  else
+    free (buffer);
+
+  return error;
+}
+
+static Dwfl_Error
+what_kind (int fd, Elf **elfp, Elf_Kind *kind, bool *close_fd)
+{
+  Dwfl_Error error = DWFL_E_NOERROR;
+  *kind = elf_kind (*elfp);
+  if (unlikely (*kind == ELF_K_NONE))
+    {
+      if (unlikely (*elfp == NULL))
+	error = DWFL_E_LIBELF;
+      else
+	{
+	  error = decompress (fd, elfp);
+	  if (error == DWFL_E_NOERROR)
+	    {
+	      *close_fd = true;
+	      *kind = elf_kind (*elfp);
+	    }
+	}
+    }
+  return error;
+}
+
+Dwfl_Error internal_function
+__libdw_open_file (int *fdp, Elf **elfp, bool close_on_fail, bool archive_ok)
+{
+  bool close_fd = false;
+
+  Elf *elf = elf_begin (*fdp, ELF_C_READ_MMAP_PRIVATE, NULL);
+
+  Elf_Kind kind;
+  Dwfl_Error error = what_kind (*fdp, &elf, &kind, &close_fd);
+  if (error == DWFL_E_BADELF)
+    {
+      /* It's not an ELF file or a compressed file.
+	 See if it's an image with a header preceding the real file.  */
+
+      off_t offset = elf->start_offset;
+      error = __libdw_image_header (*fdp, &offset,
+				    (elf->map_address == NULL ? NULL
+				     : elf->map_address + offset),
+				    elf->maximum_size);
+      if (error == DWFL_E_NOERROR)
+	{
+	  /* Pure evil.  libelf needs some better interfaces.  */
+	  elf->kind = ELF_K_AR;
+	  elf->state.ar.elf_ar_hdr.ar_name = "libdwfl is faking you out";
+	  elf->state.ar.elf_ar_hdr.ar_size = elf->maximum_size - offset;
+	  elf->state.ar.offset = offset - sizeof (struct ar_hdr);
+	  Elf *subelf = elf_begin (-1, ELF_C_READ_MMAP_PRIVATE, elf);
+	  elf->kind = ELF_K_NONE;
+	  if (unlikely (subelf == NULL))
+	    error = DWFL_E_LIBELF;
+	  else
+	    {
+	      subelf->parent = NULL;
+	      subelf->flags |= elf->flags & (ELF_F_MMAPPED | ELF_F_MALLOCED);
+	      elf->flags &= ~(ELF_F_MMAPPED | ELF_F_MALLOCED);
+	      elf_end (elf);
+	      elf = subelf;
+	      error = what_kind (*fdp, &elf, &kind, &close_fd);
+	    }
+	}
+    }
+
+  if (error == DWFL_E_NOERROR
+      && kind != ELF_K_ELF
+      && !(archive_ok && kind == ELF_K_AR))
+    error = DWFL_E_BADELF;
+
+  if (error != DWFL_E_NOERROR)
+    {
+      elf_end (elf);
+      elf = NULL;
+    }
+
+  if (error == DWFL_E_NOERROR ? close_fd : close_on_fail)
+    {
+      close (*fdp);
+      *fdp = -1;
+    }
+
+  *elfp = elf;
+  return error;
+}
diff --git a/third_party/elfutils/libdwfl/relocate.c b/third_party/elfutils/libdwfl/relocate.c
new file mode 100644
index 0000000..1768243
--- /dev/null
+++ b/third_party/elfutils/libdwfl/relocate.c
@@ -0,0 +1,789 @@
+/* Relocate debug information.
+   Copyright (C) 2005-2011, 2014, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+typedef uint8_t GElf_Byte;
+
+/* Adjust *VALUE to add the load address of the SHNDX section.
+   We update the section header in place to cache the result.  */
+
+Dwfl_Error
+internal_function
+__libdwfl_relocate_value (Dwfl_Module *mod, Elf *elf, size_t *shstrndx,
+			  Elf32_Word shndx, GElf_Addr *value)
+{
+  /* No adjustment needed for section zero, it is never loaded.
+     Handle it first, just in case the ELF file has strange section
+     zero flags set.  */
+  if (shndx == 0)
+    return DWFL_E_NOERROR;
+
+  Elf_Scn *refscn = elf_getscn (elf, shndx);
+  GElf_Shdr refshdr_mem, *refshdr = gelf_getshdr (refscn, &refshdr_mem);
+  if (refshdr == NULL)
+    return DWFL_E_LIBELF;
+
+  if (refshdr->sh_addr == 0 && (refshdr->sh_flags & SHF_ALLOC))
+    {
+      /* This is a loaded section.  Find its actual
+	 address and update the section header.  */
+
+      if (*shstrndx == SHN_UNDEF
+	  && unlikely (elf_getshdrstrndx (elf, shstrndx) < 0))
+	return DWFL_E_LIBELF;
+
+      const char *name = elf_strptr (elf, *shstrndx, refshdr->sh_name);
+      if (unlikely (name == NULL))
+	return DWFL_E_LIBELF;
+
+      if ((*mod->dwfl->callbacks->section_address) (MODCB_ARGS (mod),
+						    name, shndx, refshdr,
+						    &refshdr->sh_addr))
+	return CBFAIL;
+
+      if (refshdr->sh_addr == (Dwarf_Addr) -1l)
+	/* The callback indicated this section wasn't really loaded but we
+	   don't really care.  */
+	refshdr->sh_addr = 0;	/* Make no adjustment below.  */
+
+      /* Update the in-core file's section header to show the final
+	 load address (or unloadedness).  This serves as a cache,
+	 so we won't get here again for the same section.  */
+      if (likely (refshdr->sh_addr != 0)
+	  && unlikely (! gelf_update_shdr (refscn, refshdr)))
+	return DWFL_E_LIBELF;
+    }
+
+  if (refshdr->sh_flags & SHF_ALLOC)
+    /* Apply the adjustment.  */
+    *value += dwfl_adjusted_address (mod, refshdr->sh_addr);
+
+  return DWFL_E_NOERROR;
+}
+
+
+/* Cache used by relocate_getsym.  */
+struct reloc_symtab_cache
+{
+  Elf *symelf;
+  Elf_Data *symdata;
+  Elf_Data *symxndxdata;
+  Elf_Data *symstrdata;
+  size_t symshstrndx;
+  size_t strtabndx;
+};
+#define RELOC_SYMTAB_CACHE(cache)	\
+  struct reloc_symtab_cache cache =	\
+    { NULL, NULL, NULL, NULL, SHN_UNDEF, SHN_UNDEF }
+
+/* This is just doing dwfl_module_getsym, except that we must always use
+   the symbol table in RELOCATED itself when it has one, not MOD->symfile.  */
+static Dwfl_Error
+relocate_getsym (Dwfl_Module *mod,
+		 Elf *relocated, struct reloc_symtab_cache *cache,
+		 int symndx, GElf_Sym *sym, GElf_Word *shndx)
+{
+  if (cache->symdata == NULL)
+    {
+      if (mod->symfile == NULL || mod->symfile->elf != relocated)
+	{
+	  /* We have to look up the symbol table in the file we are
+	     relocating, if it has its own.  These reloc sections refer to
+	     the symbol table in this file, and a symbol table in the main
+	     file might not match.  However, some tools did produce ET_REL
+	     .debug files with relocs but no symtab of their own.  */
+	  Elf_Scn *scn = NULL;
+	  while ((scn = elf_nextscn (relocated, scn)) != NULL)
+	    {
+	      GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
+	      if (shdr != NULL)
+		{
+		  /* We need uncompressed data.  */
+		  if ((shdr->sh_type == SHT_SYMTAB
+		       || shdr->sh_type == SHT_SYMTAB_SHNDX)
+		      && (shdr->sh_flags & SHF_COMPRESSED) != 0)
+		    if (elf_compress (scn, 0, 0) < 0)
+		      return DWFL_E_LIBELF;
+
+		  switch (shdr->sh_type)
+		    {
+		    default:
+		      continue;
+		    case SHT_SYMTAB:
+		      cache->symelf = relocated;
+		      cache->symdata = elf_getdata (scn, NULL);
+		      cache->strtabndx = shdr->sh_link;
+		      if (unlikely (cache->symdata == NULL))
+			return DWFL_E_LIBELF;
+		      break;
+		    case SHT_SYMTAB_SHNDX:
+		      cache->symxndxdata = elf_getdata (scn, NULL);
+		      if (unlikely (cache->symxndxdata == NULL))
+			return DWFL_E_LIBELF;
+		      break;
+		    }
+		}
+	      if (cache->symdata != NULL && cache->symxndxdata != NULL)
+		break;
+	    }
+	}
+      if (cache->symdata == NULL)
+	{
+	  /* We might not have looked for a symbol table file yet,
+	     when coming from __libdwfl_relocate_section.  */
+	  if (unlikely (mod->symfile == NULL)
+	      && unlikely (INTUSE(dwfl_module_getsymtab) (mod) < 0))
+	    return dwfl_errno ();
+
+	  /* The symbol table we have already cached is the one from
+	     the file being relocated, so it's what we need.  Or else
+	     this is an ET_REL .debug file with no .symtab of its own;
+	     the symbols refer to the section indices in the main file.  */
+	  cache->symelf = mod->symfile->elf;
+	  cache->symdata = mod->symdata;
+	  cache->symxndxdata = mod->symxndxdata;
+	  cache->symstrdata = mod->symstrdata;
+	}
+    }
+
+  if (unlikely (gelf_getsymshndx (cache->symdata, cache->symxndxdata,
+				  symndx, sym, shndx) == NULL))
+    return DWFL_E_LIBELF;
+
+  if (sym->st_shndx != SHN_XINDEX)
+    *shndx = sym->st_shndx;
+
+  switch (sym->st_shndx)
+    {
+    case SHN_ABS:
+    case SHN_UNDEF:
+      return DWFL_E_NOERROR;
+
+    case SHN_COMMON:
+      sym->st_value = 0;	/* Value is size, not helpful. */
+      return DWFL_E_NOERROR;
+    }
+
+  return __libdwfl_relocate_value (mod, cache->symelf, &cache->symshstrndx,
+				   *shndx, &sym->st_value);
+}
+
+/* Handle an undefined symbol.  We really only support ET_REL for Linux
+   kernel modules, and offline archives.  The behavior of the Linux module
+   loader is very simple and easy to mimic.  It only matches magically
+   exported symbols, and we match any defined symbols.  But we get the same
+   answer except when the module's symbols are undefined and would prevent
+   it from being loaded.  */
+static Dwfl_Error
+resolve_symbol (Dwfl_Module *referer, struct reloc_symtab_cache *symtab,
+		GElf_Sym *sym, GElf_Word shndx)
+{
+  /* First we need its name.  */
+  if (sym->st_name != 0)
+    {
+      if (symtab->symstrdata == NULL)
+	{
+	  /* Cache the strtab for this symtab.  */
+	  assert (referer->symfile == NULL
+		  || referer->symfile->elf != symtab->symelf);
+
+	  Elf_Scn *scn = elf_getscn (symtab->symelf, symtab->strtabndx);
+	  if (scn == NULL)
+	    return DWFL_E_LIBELF;
+
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (shdr == NULL)
+	    return DWFL_E_LIBELF;
+
+	  if (symtab->symshstrndx == SHN_UNDEF
+	      && elf_getshdrstrndx (symtab->symelf, &symtab->symshstrndx) < 0)
+	    return DWFL_E_LIBELF;
+
+	  const char *sname = elf_strptr (symtab->symelf, symtab->symshstrndx,
+					  shdr->sh_name);
+	  if (sname == NULL)
+	    return DWFL_E_LIBELF;
+
+	  /* If the section is already decompressed, that isn't an error.  */
+	  if (strncmp (sname, ".zdebug", strlen (".zdebug")) == 0)
+	    elf_compress_gnu (scn, 0, 0);
+
+	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	    if (elf_compress (scn, 0, 0) < 0)
+	      return DWFL_E_LIBELF;
+
+	  symtab->symstrdata = elf_getdata (scn, NULL);
+	  if (unlikely (symtab->symstrdata == NULL
+			|| symtab->symstrdata->d_buf == NULL))
+	    return DWFL_E_LIBELF;
+	}
+      if (unlikely (sym->st_name >= symtab->symstrdata->d_size))
+	return DWFL_E_BADSTROFF;
+
+      const char *name = symtab->symstrdata->d_buf;
+      name += sym->st_name;
+
+      for (Dwfl_Module *m = referer->dwfl->modulelist; m != NULL; m = m->next)
+	if (m != referer)
+	  {
+	    /* Get this module's symtab.
+	       If we got a fresh error reading the table, report it.
+	       If we just have no symbols in this module, no harm done.  */
+	    if (m->symdata == NULL
+		&& m->symerr == DWFL_E_NOERROR
+		&& INTUSE(dwfl_module_getsymtab) (m) < 0
+		&& m->symerr != DWFL_E_NO_SYMTAB)
+	      return m->symerr;
+
+	    for (size_t ndx = 1; ndx < m->syments; ++ndx)
+	      {
+		sym = gelf_getsymshndx (m->symdata, m->symxndxdata,
+					ndx, sym, &shndx);
+		if (unlikely (sym == NULL))
+		  return DWFL_E_LIBELF;
+		if (sym->st_shndx != SHN_XINDEX)
+		  shndx = sym->st_shndx;
+
+		/* We are looking for a defined global symbol with a name.  */
+		if (shndx == SHN_UNDEF || shndx == SHN_COMMON
+		    || GELF_ST_BIND (sym->st_info) == STB_LOCAL
+		    || sym->st_name == 0)
+		  continue;
+
+		/* Get this candidate symbol's name.  */
+		if (unlikely (sym->st_name >= m->symstrdata->d_size))
+		  return DWFL_E_BADSTROFF;
+		const char *n = m->symstrdata->d_buf;
+		n += sym->st_name;
+
+		/* Does the name match?  */
+		if (strcmp (name, n))
+		  continue;
+
+		/* We found it!  */
+		if (shndx == SHN_ABS) /* XXX maybe should apply bias? */
+		  return DWFL_E_NOERROR;
+
+		if (m->e_type != ET_REL)
+		  {
+		    sym->st_value = dwfl_adjusted_st_value (m, m->symfile->elf,
+							    sym->st_value);
+		    return DWFL_E_NOERROR;
+		  }
+
+		/* In an ET_REL file, the symbol table values are relative
+		   to the section, not to the module's load base.  */
+		size_t symshstrndx = SHN_UNDEF;
+		return __libdwfl_relocate_value (m, m->symfile->elf,
+						 &symshstrndx,
+						 shndx, &sym->st_value);
+	      }
+	  }
+    }
+
+  return DWFL_E_RELUNDEF;
+}
+
+/* Apply one relocation.  Returns true for any invalid data.  */
+static Dwfl_Error
+relocate (Dwfl_Module * const mod,
+          Elf * const relocated,
+          struct reloc_symtab_cache * const reloc_symtab,
+          Elf_Data * const tdata,
+          const GElf_Ehdr * const ehdr,
+          GElf_Addr offset,
+          const GElf_Sxword *addend,
+          int rtype,
+          int symndx)
+{
+    /* First see if this is a reloc we can handle.
+       If we are skipping it, don't bother resolving the symbol.  */
+
+    if (unlikely (rtype == 0))
+      /* In some odd situations, the linker can leave R_*_NONE relocs
+	 behind.  This is probably bogus ld -r behavior, but the only
+	 cases it's known to appear in are harmless: DWARF data
+	 referring to addresses in a section that has been discarded.
+	 So we just pretend it's OK without further relocation.  */
+      return DWFL_E_NOERROR;
+
+    Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype);
+    if (unlikely (type == ELF_T_NUM))
+      return DWFL_E_BADRELTYPE;
+
+    /* First, resolve the symbol to an absolute value.  */
+    GElf_Addr value;
+
+    if (symndx == STN_UNDEF)
+      /* When strip removes a section symbol referring to a
+	 section moved into the debuginfo file, it replaces
+	 that symbol index in relocs with STN_UNDEF.  We
+	 don't actually need the symbol, because those relocs
+	 are always references relative to the nonallocated
+	 debugging sections, which start at zero.  */
+      value = 0;
+    else
+      {
+	GElf_Sym sym;
+	GElf_Word shndx;
+	Dwfl_Error error = relocate_getsym (mod, relocated, reloc_symtab,
+					    symndx, &sym, &shndx);
+	if (unlikely (error != DWFL_E_NOERROR))
+	  return error;
+
+	if (shndx == SHN_UNDEF || shndx == SHN_COMMON)
+	  {
+	    /* Maybe we can figure it out anyway.  */
+	    error = resolve_symbol (mod, reloc_symtab, &sym, shndx);
+	    if (error != DWFL_E_NOERROR
+		&& !(error == DWFL_E_RELUNDEF && shndx == SHN_COMMON))
+	      return error;
+	  }
+
+	value = sym.st_value;
+      }
+
+    /* These are the types we can relocate.  */
+#define TYPES		DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half);	\
+    DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword);			\
+    DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
+    size_t size;
+    switch (type)
+      {
+#define DO_TYPE(NAME, Name)			\
+	case ELF_T_##NAME:			\
+	  size = sizeof (GElf_##Name);		\
+	break
+	TYPES;
+#undef DO_TYPE
+      default:
+	return DWFL_E_BADRELTYPE;
+      }
+
+    if (offset > tdata->d_size || tdata->d_size - offset < size)
+      return DWFL_E_BADRELOFF;
+
+#define DO_TYPE(NAME, Name) GElf_##Name Name;
+    union { TYPES; } tmpbuf;
+#undef DO_TYPE
+    Elf_Data tmpdata =
+      {
+	.d_type = type,
+	.d_buf = &tmpbuf,
+	.d_size = size,
+	.d_version = EV_CURRENT,
+      };
+    Elf_Data rdata =
+      {
+	.d_type = type,
+	.d_buf = tdata->d_buf + offset,
+	.d_size = size,
+	.d_version = EV_CURRENT,
+      };
+
+    /* XXX check for overflow? */
+    if (addend)
+      {
+	/* For the addend form, we have the value already.  */
+	value += *addend;
+	switch (type)
+	  {
+#define DO_TYPE(NAME, Name)			\
+	    case ELF_T_##NAME:			\
+	      tmpbuf.Name = value;		\
+	    break
+	    TYPES;
+#undef DO_TYPE
+	  default:
+	    abort ();
+	  }
+      }
+    else
+      {
+	/* Extract the original value and apply the reloc.  */
+	Elf_Data *d = gelf_xlatetom (relocated, &tmpdata, &rdata,
+				     ehdr->e_ident[EI_DATA]);
+	if (d == NULL)
+	  return DWFL_E_LIBELF;
+	assert (d == &tmpdata);
+	switch (type)
+	  {
+#define DO_TYPE(NAME, Name)				\
+	    case ELF_T_##NAME:				\
+	      tmpbuf.Name += (GElf_##Name) value;	\
+	    break
+	    TYPES;
+#undef DO_TYPE
+	  default:
+	    abort ();
+	  }
+      }
+
+    /* Now convert the relocated datum back to the target
+       format.  This will write into rdata.d_buf, which
+       points into the raw section data being relocated.  */
+    Elf_Data *s = gelf_xlatetof (relocated, &rdata, &tmpdata,
+				 ehdr->e_ident[EI_DATA]);
+    if (s == NULL)
+      return DWFL_E_LIBELF;
+    assert (s == &rdata);
+
+    /* We have applied this relocation!  */
+    return DWFL_E_NOERROR;
+}
+
+static inline void
+check_badreltype (bool *first_badreltype,
+                  Dwfl_Module *mod,
+                  Dwfl_Error *result)
+{
+  if (*first_badreltype)
+    {
+       *first_badreltype = false;
+       if (ebl_get_elfmachine (mod->ebl) == EM_NONE)
+          /* This might be because ebl_openbackend failed to find
+             any libebl_CPU.so library.  Diagnose that clearly.  */
+          *result = DWFL_E_UNKNOWN_MACHINE;
+     }
+}
+
+static Dwfl_Error
+relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
+		  size_t shstrndx, struct reloc_symtab_cache *reloc_symtab,
+		  Elf_Scn *scn, GElf_Shdr *shdr,
+		  Elf_Scn *tscn, bool debugscn, bool partial)
+{
+  /* First, fetch the name of the section these relocations apply to.
+     Then try to decompress both relocation and target section.  */
+  GElf_Shdr tshdr_mem;
+  GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
+  if (tshdr == NULL)
+    return DWFL_E_LIBELF;
+
+  const char *tname = elf_strptr (relocated, shstrndx, tshdr->sh_name);
+  if (tname == NULL)
+    return DWFL_E_LIBELF;
+
+  if (debugscn && ! ebl_debugscn_p (mod->ebl, tname))
+    /* This relocation section is not for a debugging section.
+       Nothing to do here.  */
+    return DWFL_E_NOERROR;
+
+  if (strncmp (tname, ".zdebug", strlen ("zdebug")) == 0)
+    elf_compress_gnu (tscn, 0, 0);
+
+  if ((tshdr->sh_flags & SHF_COMPRESSED) != 0)
+    if (elf_compress (tscn, 0, 0) < 0)
+      return DWFL_E_LIBELF;
+
+  /* Reload Shdr in case section was just decompressed.  */
+  tshdr = gelf_getshdr (tscn, &tshdr_mem);
+  if (tshdr == NULL)
+    return DWFL_E_LIBELF;
+
+  if (unlikely (tshdr->sh_type == SHT_NOBITS)
+      || unlikely (tshdr->sh_size == 0))
+    /* No contents to relocate.  */
+    return DWFL_E_NOERROR;
+
+  const char *sname = elf_strptr (relocated, shstrndx, shdr->sh_name);
+  if (sname == NULL)
+    return DWFL_E_LIBELF;
+
+  if (strncmp (sname, ".zdebug", strlen ("zdebug")) == 0)
+    elf_compress_gnu (scn, 0, 0);
+
+  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+    if (elf_compress (scn, 0, 0) < 0)
+      return DWFL_E_LIBELF;
+
+  /* Reload Shdr in case section was just decompressed.  */
+  GElf_Shdr shdr_mem;
+  shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr == NULL)
+    return DWFL_E_LIBELF;
+
+  /* Fetch the section data that needs the relocations applied.  */
+  Elf_Data *tdata = elf_rawdata (tscn, NULL);
+  if (tdata == NULL)
+    return DWFL_E_LIBELF;
+
+  /* If either the section that needs the relocation applied, or the
+     section that the relocations come from overlap one of the ehdrs,
+     shdrs or phdrs data then we refuse to do the relocations.  It
+     isn't illegal for ELF section data to overlap the header data,
+     but updating the (relocation) data might corrupt the in-memory
+     libelf headers causing strange corruptions or errors.  */
+  size_t ehsize = gelf_fsize (relocated, ELF_T_EHDR, 1, EV_CURRENT);
+  if (unlikely (shdr->sh_offset < ehsize
+		|| tshdr->sh_offset < ehsize))
+    return DWFL_E_BADELF;
+
+  GElf_Off shdrs_start = ehdr->e_shoff;
+  size_t shnums;
+  if (elf_getshdrnum (relocated, &shnums) < 0)
+    return DWFL_E_LIBELF;
+  /* Overflows will have been checked by elf_getshdrnum/get|rawdata.  */
+  size_t shentsize = gelf_fsize (relocated, ELF_T_SHDR, 1, EV_CURRENT);
+  GElf_Off shdrs_end = shdrs_start + shnums * shentsize;
+  if (unlikely ((shdrs_start < shdr->sh_offset + shdr->sh_size
+		 && shdr->sh_offset < shdrs_end)
+		|| (shdrs_start < tshdr->sh_offset + tshdr->sh_size
+		    && tshdr->sh_offset < shdrs_end)))
+    return DWFL_E_BADELF;
+
+  GElf_Off phdrs_start = ehdr->e_phoff;
+  size_t phnums;
+  if (elf_getphdrnum (relocated, &phnums) < 0)
+    return DWFL_E_LIBELF;
+  if (phdrs_start != 0 && phnums != 0)
+    {
+      /* Overflows will have been checked by elf_getphdrnum/get|rawdata.  */
+      size_t phentsize = gelf_fsize (relocated, ELF_T_PHDR, 1, EV_CURRENT);
+      GElf_Off phdrs_end = phdrs_start + phnums * phentsize;
+      if (unlikely ((phdrs_start < shdr->sh_offset + shdr->sh_size
+		     && shdr->sh_offset < phdrs_end)
+		    || (phdrs_start < tshdr->sh_offset + tshdr->sh_size
+			&& tshdr->sh_offset < phdrs_end)))
+	return DWFL_E_BADELF;
+    }
+
+  /* Fetch the relocation section and apply each reloc in it.  */
+  Elf_Data *reldata = elf_getdata (scn, NULL);
+  if (reldata == NULL)
+    return DWFL_E_LIBELF;
+
+  Dwfl_Error result = DWFL_E_NOERROR;
+  bool first_badreltype = true;
+
+  size_t sh_entsize
+    = gelf_fsize (relocated, shdr->sh_type == SHT_REL ? ELF_T_REL : ELF_T_RELA,
+		  1, EV_CURRENT);
+  size_t nrels = shdr->sh_size / sh_entsize;
+  size_t complete = 0;
+  if (shdr->sh_type == SHT_REL)
+    for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
+      {
+	GElf_Rel rel_mem, *r = gelf_getrel (reldata, relidx, &rel_mem);
+	if (r == NULL)
+	  return DWFL_E_LIBELF;
+	result = relocate (mod, relocated, reloc_symtab, tdata, ehdr,
+			   r->r_offset, NULL,
+			   GELF_R_TYPE (r->r_info),
+			   GELF_R_SYM (r->r_info));
+	check_badreltype (&first_badreltype, mod, &result);
+	if (partial)
+	  switch (result)
+	    {
+	    case DWFL_E_NOERROR:
+	      /* We applied the relocation.  Elide it.  */
+	      memset (&rel_mem, 0, sizeof rel_mem);
+	      if (unlikely (gelf_update_rel (reldata, relidx, &rel_mem) == 0))
+		return DWFL_E_LIBELF;
+	      ++complete;
+	      break;
+	    case DWFL_E_BADRELTYPE:
+	    case DWFL_E_RELUNDEF:
+	      /* We couldn't handle this relocation.  Skip it.  */
+	      result = DWFL_E_NOERROR;
+	      break;
+	    default:
+	      break;
+	    }
+      }
+  else
+    for (size_t relidx = 0; !result && relidx < nrels; ++relidx)
+      {
+	GElf_Rela rela_mem, *r = gelf_getrela (reldata, relidx,
+					       &rela_mem);
+	if (r == NULL)
+	  return DWFL_E_LIBELF;
+	result = relocate (mod, relocated, reloc_symtab, tdata, ehdr,
+			   r->r_offset, &r->r_addend,
+			   GELF_R_TYPE (r->r_info),
+			   GELF_R_SYM (r->r_info));
+	check_badreltype (&first_badreltype, mod, &result);
+	if (partial)
+	  switch (result)
+	    {
+	    case DWFL_E_NOERROR:
+	      /* We applied the relocation.  Elide it.  */
+	      memset (&rela_mem, 0, sizeof rela_mem);
+	      if (unlikely (gelf_update_rela (reldata, relidx,
+					      &rela_mem) == 0))
+		return DWFL_E_LIBELF;
+	      ++complete;
+	      break;
+	    case DWFL_E_BADRELTYPE:
+	    case DWFL_E_RELUNDEF:
+	      /* We couldn't handle this relocation.  Skip it.  */
+	      result = DWFL_E_NOERROR;
+	      break;
+	    default:
+	      break;
+	    }
+      }
+
+  if (likely (result == DWFL_E_NOERROR))
+    {
+      if (!partial || complete == nrels)
+	/* Mark this relocation section as being empty now that we have
+	   done its work.  This affects unstrip -R, so e.g. it emits an
+	   empty .rela.debug_info along with a .debug_info that has
+	   already been fully relocated.  */
+	nrels = 0;
+      else if (complete != 0)
+	{
+	  /* We handled some of the relocations but not all.
+	     We've zeroed out the ones we processed.
+	     Now remove them from the section.  */
+
+	  size_t next = 0;
+	  if (shdr->sh_type == SHT_REL)
+	    for (size_t relidx = 0; relidx < nrels; ++relidx)
+	      {
+		GElf_Rel rel_mem;
+		GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem);
+		if (unlikely (r == NULL))
+		  return DWFL_E_LIBELF;
+		if (r->r_info != 0 || r->r_offset != 0)
+		  {
+		    if (next != relidx)
+		      if (unlikely (gelf_update_rel (reldata, next, r) == 0))
+			return DWFL_E_LIBELF;
+		    ++next;
+		  }
+	      }
+	  else
+	    for (size_t relidx = 0; relidx < nrels; ++relidx)
+	      {
+		GElf_Rela rela_mem;
+		GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem);
+		if (unlikely (r == NULL))
+		  return DWFL_E_LIBELF;
+		if (r->r_info != 0 || r->r_offset != 0 || r->r_addend != 0)
+		  {
+		    if (next != relidx)
+		      if (unlikely (gelf_update_rela (reldata, next, r) == 0))
+			return DWFL_E_LIBELF;
+		    ++next;
+		  }
+	      }
+	  nrels = next;
+	}
+
+      shdr->sh_size = reldata->d_size = nrels * sh_entsize;
+      if (unlikely (gelf_update_shdr (scn, shdr) == 0))
+	return DWFL_E_LIBELF;
+    }
+
+  return result;
+}
+
+Dwfl_Error
+internal_function
+__libdwfl_relocate (Dwfl_Module *mod, Elf *debugfile, bool debug)
+{
+  assert (mod->e_type == ET_REL);
+
+  GElf_Ehdr ehdr_mem;
+  const GElf_Ehdr *ehdr = gelf_getehdr (debugfile, &ehdr_mem);
+  if (ehdr == NULL)
+    return DWFL_E_LIBELF;
+
+  size_t d_shstrndx;
+  if (elf_getshdrstrndx (debugfile, &d_shstrndx) < 0)
+    return DWFL_E_LIBELF;
+
+  RELOC_SYMTAB_CACHE (reloc_symtab);
+
+  /* Look at each section in the debuginfo file, and process the
+     relocation sections for debugging sections.  */
+  Dwfl_Error result = DWFL_E_NOERROR;
+  Elf_Scn *scn = NULL;
+  while (result == DWFL_E_NOERROR
+	 && (scn = elf_nextscn (debugfile, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (unlikely (shdr == NULL))
+	return DWFL_E_LIBELF;
+
+      if ((shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+	  && shdr->sh_size != 0)
+	{
+	  /* It's a relocation section.  */
+
+	  Elf_Scn *tscn = elf_getscn (debugfile, shdr->sh_info);
+	  if (unlikely (tscn == NULL))
+	    result = DWFL_E_LIBELF;
+	  else
+	    result = relocate_section (mod, debugfile, ehdr, d_shstrndx,
+				       &reloc_symtab, scn, shdr, tscn,
+				       debug, !debug);
+	}
+    }
+
+  return result;
+}
+
+Dwfl_Error
+internal_function
+__libdwfl_relocate_section (Dwfl_Module *mod, Elf *relocated,
+			    Elf_Scn *relocscn, Elf_Scn *tscn, bool partial)
+{
+  GElf_Ehdr ehdr_mem;
+  GElf_Shdr shdr_mem;
+
+  RELOC_SYMTAB_CACHE (reloc_symtab);
+
+  size_t shstrndx;
+  if (elf_getshdrstrndx (relocated, &shstrndx) < 0)
+    return DWFL_E_LIBELF;
+
+  Dwfl_Error result = __libdwfl_module_getebl (mod);
+  if (unlikely (result != DWFL_E_NOERROR))
+    return result;
+
+  GElf_Ehdr *ehdr = gelf_getehdr (relocated, &ehdr_mem);
+  if (unlikely (ehdr == NULL))
+    return DWFL_E_LIBELF;
+
+  GElf_Shdr *shdr = gelf_getshdr (relocscn, &shdr_mem);
+  if (unlikely (shdr == NULL))
+    return DWFL_E_LIBELF;
+
+  return relocate_section (mod, relocated, ehdr, shstrndx, &reloc_symtab,
+			   relocscn, shdr, tscn, false, partial);
+}
diff --git a/third_party/elfutils/libdwfl/segment.c b/third_party/elfutils/libdwfl/segment.c
new file mode 100644
index 0000000..d9599a7
--- /dev/null
+++ b/third_party/elfutils/libdwfl/segment.c
@@ -0,0 +1,337 @@
+/* Manage address space lookup table for libdwfl.
+   Copyright (C) 2008, 2009, 2010, 2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwflP.h"
+
+GElf_Addr
+internal_function
+__libdwfl_segment_start (Dwfl *dwfl, GElf_Addr start)
+{
+  if (dwfl->segment_align > 1)
+    start &= -dwfl->segment_align;
+  return start;
+}
+
+GElf_Addr
+internal_function
+__libdwfl_segment_end (Dwfl *dwfl, GElf_Addr end)
+{
+  if (dwfl->segment_align > 1)
+    end = (end + dwfl->segment_align - 1) & -dwfl->segment_align;
+  return end;
+}
+
+static bool
+insert (Dwfl *dwfl, size_t i, GElf_Addr start, GElf_Addr end, int segndx)
+{
+  bool need_start = (i == 0 || dwfl->lookup_addr[i - 1] != start);
+  bool need_end = (i + 1 >= dwfl->lookup_elts
+		   || dwfl->lookup_addr[i + 1] != end);
+  size_t need = need_start + need_end;
+  if (need == 0)
+    return false;
+
+  if (dwfl->lookup_alloc - dwfl->lookup_elts < need)
+    {
+      size_t n = dwfl->lookup_alloc == 0 ? 16 : dwfl->lookup_alloc * 2;
+      GElf_Addr *naddr = realloc (dwfl->lookup_addr, sizeof naddr[0] * n);
+      if (unlikely (naddr == NULL))
+	return true;
+      int *nsegndx = realloc (dwfl->lookup_segndx, sizeof nsegndx[0] * n);
+      if (unlikely (nsegndx == NULL))
+	{
+	  if (naddr != dwfl->lookup_addr)
+	    free (naddr);
+	  return true;
+	}
+      dwfl->lookup_alloc = n;
+      dwfl->lookup_addr = naddr;
+      dwfl->lookup_segndx = nsegndx;
+
+      if (dwfl->lookup_module != NULL)
+	{
+	  /* Make sure this array is big enough too.  */
+	  Dwfl_Module **old = dwfl->lookup_module;
+	  dwfl->lookup_module = realloc (dwfl->lookup_module,
+					 sizeof dwfl->lookup_module[0] * n);
+	  if (unlikely (dwfl->lookup_module == NULL))
+	    {
+	      free (old);
+	      return true;
+	    }
+	}
+    }
+
+  if (unlikely (i < dwfl->lookup_elts))
+    {
+      const size_t move = dwfl->lookup_elts - i;
+      memmove (&dwfl->lookup_addr[i + need], &dwfl->lookup_addr[i],
+	       move * sizeof dwfl->lookup_addr[0]);
+      memmove (&dwfl->lookup_segndx[i + need], &dwfl->lookup_segndx[i],
+	       move * sizeof dwfl->lookup_segndx[0]);
+      if (dwfl->lookup_module != NULL)
+	memmove (&dwfl->lookup_module[i + need], &dwfl->lookup_module[i],
+		 move * sizeof dwfl->lookup_module[0]);
+    }
+
+  if (need_start)
+    {
+      dwfl->lookup_addr[i] = start;
+      dwfl->lookup_segndx[i] = segndx;
+      if (dwfl->lookup_module != NULL)
+	dwfl->lookup_module[i] = NULL;
+      ++i;
+    }
+  else
+    dwfl->lookup_segndx[i - 1] = segndx;
+
+  if (need_end)
+    {
+      dwfl->lookup_addr[i] = end;
+      dwfl->lookup_segndx[i] = -1;
+      if (dwfl->lookup_module != NULL)
+	dwfl->lookup_module[i] = NULL;
+    }
+
+  dwfl->lookup_elts += need;
+
+  return false;
+}
+
+static int
+lookup (Dwfl *dwfl, GElf_Addr address, int hint)
+{
+  if (hint >= 0
+      && address >= dwfl->lookup_addr[hint]
+      && ((size_t) hint + 1 == dwfl->lookup_elts
+	  || address < dwfl->lookup_addr[hint + 1]))
+    return hint;
+
+  /* Do binary search on the array indexed by module load address.  */
+  size_t l = 0, u = dwfl->lookup_elts;
+  while (l < u)
+    {
+      size_t idx = (l + u) / 2;
+      if (address < dwfl->lookup_addr[idx])
+	u = idx;
+      else
+	{
+	  l = idx + 1;
+	  if (l == dwfl->lookup_elts || address < dwfl->lookup_addr[l])
+	    return idx;
+	}
+    }
+
+  return -1;
+}
+
+static bool
+reify_segments (Dwfl *dwfl)
+{
+  int hint = -1;
+  int highest = -1;
+  bool fixup = false;
+  for (Dwfl_Module *mod = dwfl->modulelist; mod != NULL; mod = mod->next)
+    if (! mod->gc)
+      {
+	const GElf_Addr start = __libdwfl_segment_start (dwfl, mod->low_addr);
+	const GElf_Addr end = __libdwfl_segment_end (dwfl, mod->high_addr);
+	bool resized = false;
+
+	int idx = lookup (dwfl, start, hint);
+	if (unlikely (idx < 0))
+	  {
+	    /* Module starts below any segment.  Insert a low one.  */
+	    if (unlikely (insert (dwfl, 0, start, end, -1)))
+	      return true;
+	    idx = 0;
+	    resized = true;
+	  }
+	else if (dwfl->lookup_addr[idx] > start)
+	  {
+	    /* The module starts in the middle of this segment.  Split it.  */
+	    if (unlikely (insert (dwfl, idx + 1, start, end,
+				  dwfl->lookup_segndx[idx])))
+	      return true;
+	    ++idx;
+	    resized = true;
+	  }
+	else if (dwfl->lookup_addr[idx] < start)
+	  {
+	    /* The module starts past the end of this segment.
+	       Add a new one.  */
+	    if (unlikely (insert (dwfl, idx + 1, start, end, -1)))
+	      return true;
+	    ++idx;
+	    resized = true;
+	  }
+
+	if ((size_t) idx + 1 < dwfl->lookup_elts
+	    && end < dwfl->lookup_addr[idx + 1])
+	  {
+	    /* The module ends in the middle of this segment.  Split it.  */
+	    if (unlikely (insert (dwfl, idx + 1,
+				  end, dwfl->lookup_addr[idx + 1], -1)))
+	      return true;
+	    resized = true;
+	  }
+
+	if (dwfl->lookup_module == NULL)
+	  {
+	    dwfl->lookup_module = calloc (dwfl->lookup_alloc,
+					  sizeof dwfl->lookup_module[0]);
+	    if (unlikely (dwfl->lookup_module == NULL))
+	      return true;
+	  }
+
+	/* Cache a backpointer in the module.  */
+	mod->segment = idx;
+
+	/* Put MOD in the table for each segment that's inside it.  */
+	do
+	  dwfl->lookup_module[idx++] = mod;
+	while ((size_t) idx < dwfl->lookup_elts
+	       && dwfl->lookup_addr[idx] < end);
+	assert (dwfl->lookup_module[mod->segment] == mod);
+
+	if (resized && idx - 1 >= highest)
+	  /* Expanding the lookup tables invalidated backpointers
+	     we've already stored.  Reset those ones.  */
+	  fixup = true;
+
+	highest = idx - 1;
+	hint = (size_t) idx < dwfl->lookup_elts ? idx : -1;
+      }
+
+  if (fixup)
+    /* Reset backpointer indices invalidated by table insertions.  */
+    for (size_t idx = 0; idx < dwfl->lookup_elts; ++idx)
+      if (dwfl->lookup_module[idx] != NULL)
+	dwfl->lookup_module[idx]->segment = idx;
+
+  return false;
+}
+
+int
+dwfl_addrsegment (Dwfl *dwfl, Dwarf_Addr address, Dwfl_Module **mod)
+{
+  if (unlikely (dwfl == NULL))
+    return -1;
+
+  if (unlikely (dwfl->lookup_module == NULL)
+      && mod != NULL
+      && unlikely (reify_segments (dwfl)))
+    {
+      __libdwfl_seterrno (DWFL_E_NOMEM);
+      return -1;
+    }
+
+  int idx = lookup (dwfl, address, -1);
+  if (likely (mod != NULL))
+    {
+      if (unlikely (idx < 0) || unlikely (dwfl->lookup_module == NULL))
+	*mod = NULL;
+      else
+	{
+	  *mod = dwfl->lookup_module[idx];
+
+	  /* If this segment does not have a module, but the address is
+	     the upper boundary of the previous segment's module, use that.  */
+	  if (*mod == NULL && idx > 0 && dwfl->lookup_addr[idx] == address)
+	    {
+	      *mod = dwfl->lookup_module[idx - 1];
+	      if (*mod != NULL && (*mod)->high_addr != address)
+		*mod = NULL;
+	    }
+	}
+    }
+
+  if (likely (idx >= 0))
+    /* Translate internal segment table index to user segment index.  */
+    idx = dwfl->lookup_segndx[idx];
+
+  return idx;
+}
+INTDEF (dwfl_addrsegment)
+
+int
+dwfl_report_segment (Dwfl *dwfl, int ndx, const GElf_Phdr *phdr, GElf_Addr bias,
+		     const void *ident)
+{
+  if (dwfl == NULL)
+    return -1;
+
+  if (ndx < 0)
+    ndx = dwfl->lookup_tail_ndx;
+
+  if (phdr->p_align > 1 && (dwfl->segment_align <= 1 ||
+			    phdr->p_align < dwfl->segment_align))
+    dwfl->segment_align = phdr->p_align;
+
+  if (unlikely (dwfl->lookup_module != NULL))
+    {
+      free (dwfl->lookup_module);
+      dwfl->lookup_module = NULL;
+    }
+
+  GElf_Addr start = __libdwfl_segment_start (dwfl, bias + phdr->p_vaddr);
+  GElf_Addr end = __libdwfl_segment_end (dwfl,
+					 bias + phdr->p_vaddr + phdr->p_memsz);
+
+  /* Coalesce into the last one if contiguous and matching.  */
+  if (ndx != dwfl->lookup_tail_ndx
+      || ident == NULL
+      || ident != dwfl->lookup_tail_ident
+      || start != dwfl->lookup_tail_vaddr
+      || phdr->p_offset != dwfl->lookup_tail_offset)
+    {
+      /* Normally just appending keeps us sorted.  */
+
+      size_t i = dwfl->lookup_elts;
+      while (i > 0 && unlikely (start < dwfl->lookup_addr[i - 1]))
+	--i;
+
+      if (unlikely (insert (dwfl, i, start, end, ndx)))
+	{
+	  __libdwfl_seterrno (DWFL_E_NOMEM);
+	  return -1;
+	}
+    }
+
+  dwfl->lookup_tail_ident = ident;
+  dwfl->lookup_tail_vaddr = end;
+  dwfl->lookup_tail_offset = end - bias - phdr->p_vaddr + phdr->p_offset;
+  dwfl->lookup_tail_ndx = ndx + 1;
+
+  return ndx;
+}
+INTDEF (dwfl_report_segment)
diff --git a/third_party/elfutils/libebl/ChangeLog b/third_party/elfutils/libebl/ChangeLog
new file mode 100644
index 0000000..3ecd732
--- /dev/null
+++ b/third_party/elfutils/libebl/ChangeLog
@@ -0,0 +1,1123 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* eblobjnote.c (ebl_object_note): Use FALLTHROUGH macro instead of
+	comment.
+
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpic_CFLAGS.
+
+2017-07-19  Gustavo Romero <gromero@linux.vnet.ibm.com>
+
+	* eblcorenotetypename.c: Add ppc64 HTM SPRs note as known type.
+
+2017-07-20  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am (gen_SOURCES): Add ebl_data_marker_symbol.c.
+	* ebl-hooks.h (data_marker_symbol): New hook.
+	* ebl_data_marker_symbol.c: New file.
+	* eblopenbackend.c (default_data_marker_symbol): New function.
+	(fill_defaults): Add default_data_marker_symbol.
+	* libebl.h (ebl_data_marker_symbol): New function.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* libebl.h: Use __pure_attribute__.
+
+2017-02-15  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* eblmachineflagname.c: Include system.h.
+	* eblopenbackend.c: Likewise.
+
+2016-07-08  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (gen_SOURCES): Remove eblstrtab.c.
+	* eblstrtab.c: Removed.
+	* libebl.h (Ebl_Strtab): Removed.
+	(Ebl_Strent): Removed.
+	(ebl_strtabinit): Removed.
+	(ebl_strtabfree): Removed.
+	(ebl_strtabadd): Removed.
+	(ebl_strtabfinalize): Removed.
+	(ebl_strtaboffset): Removed.
+	(ebl_string): Removed.
+
+2016-07-06  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (gen_SOURCES): Remove eblobjecttypename.c,
+	eblshflagscombine.c, eblwstrtab.c and eblgstrtab.c.
+	* ebl-hooks.h (object_type_name): Removed.
+	(sh_flags_combine): Likewise.
+	* eblgstrtab.c: Removed.
+	* eblobjecttypename.c: Removed.
+	* eblopenbackend.c (default_object_type_name): Removed.
+	(default_sh_flags_combine): Likewise.
+	(fill_defaults): Removed object_type_name and sh_flags_combine.
+	* eblshflagscombine.c: Removed.
+	* eblwstrtab.c: Removed.
+	* libebl.h (ebl_object_type_name): Removed.
+	(ebl_sh_flags_combine): Likewise.
+	(ebl_wstrtab*): Removed.
+	(ebl_gstrtab*): Likewise.
+
+2016-06-28  Richard Henderson <rth@redhat.com>
+
+	* ebl-hooks.h (EBLHOOK(disasm)): Add ebl parameter.
+	* eblopenbackend.c (machines): Add EM_BPF entry.
+
+2016-05-20  Andreas Schwab  <schwab@linux-m68k.org>
+
+	* eblopenbackend.c (machines) [EM_68K]: Set class and data.
+
+2016-02-12  Mark Wielaard  <mjw@redhat.com>
+
+	* eblobjnotetypename.c (ebl_object_note_type_name): Check name is
+	"Go" and use new goknowntypes then. Otherwise check name is not
+	"GNU" and return "unknown".
+
+2016-01-09  Mark Wielaard  <mjw@redhat.com>
+
+	* eblobjnote.c (ebl_object_note): Add brackets around if statement
+	body.
+
+2015-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* eblopenbackend.c (default_debugscn_p): Also match .zdebug sections.
+
+2015-12-08  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* libebl.h: Prototype for ebl_ra_offset.
+	* eblabicfi.c (ebl_ra_offset): New function.
+	* libeblP.h (struct ebl): new field ra_offset;
+
+2015-09-24  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid
+	relocation overflows in some platforms.
+
+2015-09-22  Mark Wielaard  <mjw@redhat.com>
+
+	* *.c: Remove old-style function definitions.
+
+2015-09-09  Chih-Hung Hsieh  <chh@google.com>
+
+	* ebldwarftoregno.c (ebl_dwarf_to_regno): Remove redundant NULL tests
+	on parameters declared with __nonnull_attribute__.
+	* eblinitreg.c (ebl_frame_nregs): Likewise.
+	* eblnormalizepc.c (ebl_normalize_pc): Likewise.
+	* eblunwind.c (ebl_unwind): Likewise.
+
+2015-09-04  Chih-Hung Hsieh  <chh@google.com>
+
+	* eblopenbackend.c (ebl_openbackend_machine): Replace K&R function
+	definition with ansi-C definitions.
+	* eblstother.c (ebl_check_st_other_bits): Likewise.
+
+2015-06-12  Mark Wielaard  <mjw@redhat.com>
+
+	* eblcheckreloctargettype.c (ebl_check_reloc_target_type): Allow
+	SHT_INIT_ARRAY, SHT_FINI_ARRAY and SHT_PREINIT_ARRAY.
+
+2015-05-17  Mark Wielaard  <mjw@redhat.com>
+
+	* eblobjnote.c (ebl_object_note): If allocation buf is large, then
+	allocate it with malloc.
+
+2015-05-17  Mark Wielaard  <mjw@redhat.com>
+
+	* eblopenbackend.c (MAX_PREFIX_LEN): New define (16).
+	(openbackend): Stack allocate symname array using MAX_PREFIX_LEN.
+
+2015-01-27  Mark Wielaard  <mjw@redhat.com>
+
+	* libebl.h: Add comment from README that this is completely
+	UNSUPPORTED.
+
+2014-11-22  Mark Wielaard  <mjw@redhat.com>
+
+	* ebl-hooks.h (bss_plt_p): Remove ehdr argument.
+	* eblbsspltp.c (ebl_bss_plt_p): Likewise.
+	* eblopenbackend.c (default_bss_plt_p): Likewise.
+	* libebl.h (ebl_bss_plt_p): Likewise.
+
+2014-11-17  Mark Wielaard  <mjw@redhat.com>
+
+	* ebldebugscnp.c (ebl_debugscn_p): Check name is not NULL.
+
+2014-06-17  Mark Wielaard  <mjw@redhat.com>
+
+	* eblinitreg.c (ebl_func_addr_mask): New function.
+	* libebl.h (ebl_func_addr_mask): Define.
+	* libeblP.h (struct ebl): Add func_addr_mask.
+
+2014-05-19  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (gen_SOURCES): Add eblcheckreloctargettype.c.
+	* eblcheckreloctargettype.c: New file.
+	* ebl-hooks.h (check_reloc_target_type): New hook.
+	* eblopenbackend.c (default_check_reloc_target_type): New function.
+	(fill_defaults): Assign default_check_reloc_target_type to
+	check_reloc_target_type.
+	* libebl.h (ebl_check_reloc_target_type): New function definition.
+
+2013-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (gen_SOURCES): Add eblresolvesym.c.
+	* ebl-hooks.h (resolve_sym_value): New entry.
+	* eblresolvesym.c: New file.
+	* libebl.h (ebl_resolve_sym_value): New definition.
+	* libeblP.h (fd_addr): New field.
+	(fd_data): Likewise.
+
+2013-12-18  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	unwinder: s390 and s390x
+	* Makefile.am (gen_SOURCES): Add eblnormalizepc.c and eblunwind.c.
+	* ebl-hooks.h (normalize_pc, unwind): New.
+	* eblnormalizepc.c: New file.
+	* eblunwind.c: New file.
+	* libebl.h (Ebl_Register_Location): Add field pc_register.
+	(ebl_normalize_pc): New declaration.
+	(ebl_tid_registers_get_t, ebl_pid_memory_read_t): New definitions.
+	(ebl_unwind): New declaration.
+
+2013-12-15  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	unwinder: ppc and ppc64
+	* Makefile.am (gen_SOURCES): Add ebldwarftoregno.c.
+	* ebl-hooks.h (dwarf_to_regno): New.
+	* ebldwarftoregno.c: New file.
+	* libebl.h (Ebl_Core_Item): New field pc_register.
+	(ebl_tid_registers_t): Add FIRSTREG -1 to the comment.
+	(ebl_dwarf_to_regno): New.
+
+2013-11-25  Petr Machata  <pmachata@redhat.com>
+
+	* eblopenbackend.c (machines): Add entry for AArch64.
+
+2013-11-14  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Code cleanup: Remove const in prototype
+	* libebl.h (ebl_tid_registers_t): Remove const from firstreg.
+
+2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (gen_SOURCES): Add eblinitreg.c.
+	* ebl-hooks.h (set_initial_registers_tid): New entry.
+	* eblinitreg.c: New file.
+	* libebl.h (ebl_tid_registers_t): New definition.
+	(ebl_set_initial_registers_tid, ebl_frame_nregs): New declarations.
+	* libeblP.h (struct ebl): New entry frame_nregs.
+
+2013-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* libebl.h (ebl_abi_cfi): Document restrictions using register
+	rules.
+
+2013-09-26  Petr Machata  <pmachata@redhat.com>
+
+	* eblcorenotetypename.c: Handle NT_ARM_TLS, NT_ARM_HW_BREAK,
+	NT_ARM_HW_WATCH, NT_SIGINFO, NT_FILE.
+
+2013-09-25  Mark Wielaard  <mjw@redhat.com>
+
+	* eblsectionstripp.c (ebl_section_strip_p): Check shdr_l is not NULL.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+
+2012-10-12  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* ebl-hooks.h (abi_cfi): Extend its comment for return value.
+	* eblopenbackend.c (default_abi_cfi): Return -1.
+	* libebl.h (ebl_abi_cfi): Extend its comment for return value.
+
+2012-08-30  Petr Machata  <pmachata@redhat.com>
+
+	* eblcorenotetypename.c: Handle PPC_VSX, X86_XSTATE,
+	S390_HIGH_GPRS, S390_TIMER, S390_TODCMP, S390_TODPREG, S390_CTRS,
+	S390_PREFIX, S390_LAST_BREAK, S390_SYSTEM_CALL, and ARM_VFP.
+
+2012-08-22  Jeff Kenton  <jkenton@tilera.com>
+
+	* eblopenbackend.c (machines): Add tilegx.
+
+2011-06-26  Mark Wielaard  <mjw@redhat.com>
+
+	* eblopenbackend.c (default_debugscn_p): Add .debug_macro.
+
+2011-04-26  Mark Wielaard  <mjw@redhat.com>
+
+	* libebl.h (ebl_object_note_type_name): Add const char *name arg.
+	* eblhooks.h (object_note_type_name): Likewise.
+	* eblopenbackend.c (default_object_note_type_name): Likewise.
+	* eblobjnotetypename.c (ebl_object_note_type_name): Likewise.
+	And print version if name is "stapsdt".
+	* eblobjnote.c (ebl_object_note): Add output for "stapsdt" notes.
+
+2011-03-21  Marek Polacek  <mpolacek@redhat.com>
+
+	* ebldynamictagname.c: Fix typo in TLSDESC_GOT.
+
+2011-03-10  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (gen_SOURCES): Add eblstother.c.
+	* eblstother.c: New file.
+	* ebl-hooks.h: Add check_st_other_bits hook.
+	* eblopenbackend.c (default_check_st_other_bits): New function.
+	(fill_defaults): Hook default_check_st_other_bits.
+	* libebl.h (ebl_check_st_other_bits): New prototype.
+
+2010-07-07  Roland McGrath  <roland@redhat.com>
+
+	* eblopenbackend.c (default_debugscn_p): Match .gdb_index section.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Use config/eu.am for common stuff.
+
+2010-01-04  Roland McGrath  <roland@redhat.com>
+
+	* eblcorenote.c (ebl_core_note): Take GElf_Nhdr * and name data
+	pointer instead of only n_type and n_descsz.
+	* libebl.h: Update declaration.
+	* ebl-hooks.h: Update core_note hook signature.
+	* eblopenbackend.c (default_core_note): Likewise.
+
+2009-10-14  Roland McGrath  <roland@redhat.com>
+
+	* eblobjnote.c (ebl_object_note): Clean up NT_GNU_GOLD_VERSION printing.
+
+2009-10-05  Roland McGrath  <roland@redhat.com>
+
+	* eblopenbackend.c (default_debugscn_p): Match .debug_pubtypes and
+	.debug_types too.
+
+2009-09-02  Petr Machata  <pmachata@redhat.com>
+
+	* libebl/eblstrtab.c (morememory): Allocate memory in multiples of
+	pagesize.
+
+2009-08-06  Petr Machata  <pmachata@redhat.com>
+
+	* libebl/eblstrtab.c (ebl_strtabfinalize): Only call copystrings
+	if we have any strings to copy.
+
+2009-07-26  Mark Wielaard  <mjw@redhat.com>
+
+	* eblobjnote.c (ebl_object_note): Handle NT_GNU_GOLD_VERSION.
+
+	* eblobjnotetypename.c (ebl_object_note_type_name): Recognize
+	NT_GNU_GOLD_VERSION.
+
+2009-07-08  Roland McGrath  <roland@redhat.com>
+
+	* ebl-hooks.h: Add abi_cfi hook.
+	* eblopenbackend.c (default_abi_cfi): New function.
+	(fill_defaults): Add initializer.
+	* eblabicfi.c: New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	* libebl.h: Declare ebl_abi_cfi.
+
+2009-07-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblsymbolbindingname.c (ebl_symbol_binding_name): Handle
+	STB_GNU_UNIQUE.
+
+	* eblsymboltypename.c (ebl_symbol_type_name): Only handle STT_GNU_IFUNC
+	if the binary is marked as being for Linux.
+
+2009-04-01  Roland McGrath  <roland@redhat.com>
+
+	* eblsymboltypename.c (ebl_symbol_type_name): Add STT_GNU_IFUNC.
+
+	* eblauxvinfo.c (AUXV_TYPES): Add RANDOM and BASE_PLATFORM.
+
+2009-02-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblreloctypename.c (ebl_reloc_type_name): Return "<INVALID RELOC>"
+	instead of "???" for invalid relocations.
+
+2008-08-01  Roland McGrath  <roland@redhat.com>
+
+	* eblcorenotetypename.c: Handle NT_386_IOPERM.
+
+2008-07-28  Roland McGrath  <roland@redhat.com>
+
+	* eblauxvinfo.c (AUXV_TYPES): Add EXECFN.
+
+	* eblauxvinfo.c (ebl_auxv_info): Handle missing elements of standard
+	table.
+
+2008-07-04  Roland McGrath  <roland@redhat.com>
+
+	* libebl.h: Declare ebl_syscall_abi.
+	* ebl_syscall_abi.c: New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	* ebl-hooks.h: New hook syscall_abi.
+	* eblopenbackend.c (default_syscall_abi): New function.
+	(fill_defaults): Use it.
+
+2008-03-31  Roland McGrath  <roland@redhat.com>
+
+	* ebldynamictagname.c (ebl_dynamic_tag_name): Use hex for unknown tag.
+
+	* ebl-hooks.h: Add check_special_section hook.
+	* eblopenbackend.c (fill_defaults): Set new hook to ...
+	(default_check_special_section): ... this, new function.
+	* ebl_check_special_section.c: New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	* libebl.h: Declare it.
+
+2008-02-20  Roland McGrath  <roland@redhat.com>
+
+	* libebl.h: Declare ebl_check_object_attribute.
+	* eblcheckobjattr.c: New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	* ebl-hooks.h: Add check_object_attribute hook.
+	* eblopenbackend.c (default_check_object_attribute): New function.
+	(fill_defaults): Initialize pointer to it.
+
+2008-02-19  Roland McGrath  <roland@redhat.com>
+
+	* eblsectiontypename.c (ebl_section_type_name):
+	Handle SHT_GNU_ATTRIBUTES.
+
+2008-02-08  Roland McGrath  <roland@redhat.com>
+
+	* eblcorenotetypename.c (ebl_core_note_type_name): Handle NT_PPC_SPE.
+
+2008-01-30  Roland McGrath  <roland@redhat.com>
+
+	* eblcorenotetypename.c (ebl_core_note_type_name): Handle NT_386_TLS.
+
+2007-10-18  Roland McGrath  <roland@redhat.com>
+
+	* eblcorenotetypename.c (ebl_core_note_type_name): Handle NT_PPC_VMX.
+
+2007-10-11  Roland McGrath  <roland@redhat.com>
+
+	* eblobjnote.c (ebl_object_note): Translate target format (byte-swap)
+	for NT_GNU_ABI_TAG contents.
+
+2007-08-22  Roland McGrath  <roland@redhat.com>
+
+	* libebl.h (Ebl_Core_Item): New member `group'.
+
+2007-08-19  Roland McGrath  <roland@redhat.com>
+
+	* ebl-hooks.h: Add new hook auxv_info.
+	* eblopenbackend.c (default_auxv_info): New function.
+	(fill_defaults): Initialize auxv_info hook.
+	* eblauxvinfo.c : New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	* libebl.h: Declare ebl_auxv_info.
+
+	* eblcorenote.c: Rewritten with new signature.
+	* Makefile.am (gen_SOURCES): Add it.
+	* libebl.h (Ebl_Register_Location, Ebl_Core_Item): New types.
+	(ebl_core_note_info): Completely revamp signature.
+	* ebl-hooks.h: Update decl.
+	* eblopenbackend.c (default_core_note): Update signature.
+
+2007-07-09  Roland McGrath  <roland@redhat.com>
+
+	* eblobjnotetypename.c (ebl_object_note_type_name): Handle
+	NT_GNU_HWCAP, NT_GNU_BUILD_ID.
+
+	* eblobjnote.c (ebl_object_note): Handle NT_GNU_BUILD_ID.
+
+2007-04-22  Roland McGrath  <roland@redhat.com>
+
+	* eblcorenotetypename.c (ebl_core_note_type_name): Handle NT_PRXFPREG.
+
+2007-03-10  Roland McGrath  <roland@redhat.com>
+
+	* eblcorenote.c (ebl_core_note): For normally-zero types,
+	print in hex if not zero.
+
+2007-01-11  Roland McGrath  <roland@redhat.com>
+
+	* ebl-hooks.h (machine_section_flag_check): New hook.
+	* libebl.h: Declare ebl_machine_section_flag_check.
+	* eblmachinesectionflagcheck.c: New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	* eblopenbackend.c (default_machine_section_flag_check): New function.
+	(fill_defaults): Use it.
+
+2006-09-04  Roland McGrath  <roland@redhat.com>
+
+	* ebl-hooks.h: Replace register_name hook with register_info.
+	Also yield natural bit width and base type encoding.
+	* eblopenbackend.c (default_register_name): Renamed
+	default_register_info, new args added.
+	(fill_defaults): Update initialization.
+	* eblregname.c: File renamed ...
+	* eblreginfo.c: ... to this.
+	(ebl_register_name): Renamed to ebl_register_info, new args added.
+	* libebl.h: Update decl.
+
+	* Makefile.am (gen_SOURCES): Update list.
+
+2006-07-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* ebldynamictagname.c: Add support for DT_GNU_HASH.
+	* ebldynamictagcheck.c: Likewise.
+	* eblsectiontypename.c: Add support for SHT_GNU_HASH.
+
+2006-07-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (gen_SOURCES): Add eblsysvhashentrysize.c.
+	* libeblP.h (struct ebl): Add sysvhash_entrysize element.
+	* eblopenbackend.c (fill_defaults): Initialize sysvhash_entrysize.
+
+	* eblopenbackend.c (openbackend): If possible, fill machine, class,
+	and data values in from the ELF file.
+
+2006-07-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (gen_SOURCES): Add eblrelativerelocp.c.
+	* eblrelativerelocp.c: New file.
+	* ebl-hooks.c: Add relative_reloc_p.
+	* eblopenbackend.c (default_relative_reloc_p): New function.
+	(fill_defaults): Hook it up.
+	* libebl.h: Declare ebl_relative_reloc_p.
+
+2006-06-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (gen_SOURCES): Add eblnonerelocp.c.
+	* eblnonerelocp.c: New file.
+	* ebl-hooks.c: Add none_reloc_p.
+	* eblopenbackend.c (default_none_reloc_p): New function.
+	(fill_defaults): Hook it up.
+	* libebl.h: Declare ebl_none_reloc_p.
+
+2006-05-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* libebl.h: Add extern "C".
+
+2005-11-25  Roland McGrath  <roland@redhat.com>
+
+	* eblregname.c: New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	* ebl-hooks.h: Declare register_name hook.
+	* libebl.h: Declare ebl_register_name.
+	* eblopenbackend.c (default_register_name): New function.
+	(fill_defaults): Use it.
+
+2005-11-16  Roland McGrath  <roland@redhat.com>
+
+	* libebl.h: Use "" for elf-knowledge.h, not <>.
+
+2005-11-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Removed everything for building libebl_*.so modules,
+	now in ../backends/Makefile.am instead.
+	* alpha_init.c: Moved to ../backends.
+	* alpha_reloc.def: Likewise.
+	* alpha_retval.c: Likewise.
+	* alpha_symbol.c: Likewise.
+	* arm_init.c: Likewise.
+	* arm_reloc.def: Likewise.
+	* arm_symbol.c: Likewise.
+	* common-reloc.c: Likewise.
+	* i386_corenote.c: Likewise.
+	* i386_init.c: Likewise.
+	* i386_reloc.def: Likewise.
+	* i386_retval.c: Likewise.
+	* i386_symbol.c: Likewise.
+	* ia64_init.c: Likewise.
+	* ia64_reloc.def: Likewise.
+	* ia64_symbol.c: Likewise.
+	* libebl_CPU.h: Likewise.
+	* ppc64_init.c: Likewise.
+	* ppc64_reloc.def: Likewise.
+	* ppc64_retval.c: Likewise.
+	* ppc64_symbol.c: Likewise.
+	* ppc_init.c: Likewise.
+	* ppc_reloc.def: Likewise.
+	* ppc_retval.c: Likewise.
+	* ppc_symbol.c: Likewise.
+	* s390_init.c: Likewise.
+	* s390_reloc.def: Likewise.
+	* s390_symbol.c: Likewise.
+	* sh_init.c: Likewise.
+	* sh_reloc.def: Likewise.
+	* sh_symbol.c: Likewise.
+	* sparc_init.c: Likewise.
+	* sparc_reloc.def: Likewise.
+	* sparc_symbol.c: Likewise.
+	* x86_64_corenote.c: Likewise.
+	* x86_64_init.c: Likewise.
+	* x86_64_reloc.def: Likewise.
+	* x86_64_retval.c: Likewise.
+	* x86_64_symbol.c: Likewise.
+
+	* libebl.h: Comment fixes.
+
+	* alpha_retval.c: New file.
+	* Makefile.am (alpha_SRCS): Add it.
+	* alpha_init.c (alpha_init): Initialize return_value_location hook.
+
+	* ppc64_retval.c: New file.
+	* Makefile.am (ppc64_SRCS): Add it.
+	* ppc64_init.c (ppc64_init): Initialize return_value_location hook.
+
+	* ppc_retval.c: New file.
+	* Makefile.am (ppc_SRCS): Add it.
+	* ppc_init.c (ppc_init): Initialize return_value_location hook.
+
+2005-11-14  Roland McGrath  <roland@redhat.com>
+
+	* ia64_init.c (ia64_init): Initialize EH->reloc_simple_type.
+	* sh_init.c (sh_init): Likewise.
+	* x86_64_init.c (x86_64_init): Likewise.
+
+	* sparc_symbol.c (sparc_reloc_simple_type): New function.
+	* sparc_init.c (sparc_init): Use it.
+
+	* arm_symbol.c (arm_reloc_simple_type): New function.
+	* arm_init.c (arm_init): Use it.
+
+	* alpha_symbol.c (alpha_reloc_simple_type): New function.
+	* alpha_init.c (alpha_init): Use it.
+
+	* ia64_reloc.def: Update bits per H. J. Lu <hjl@lucon.org>.
+
+	* arm_reloc.def: Update bits per Daniel Jacobowitz <drow@false.org>.
+
+	* alpha_reloc.def: Update bits per Richard Henderson <rth@redhat.com>.
+
+2005-11-13  Roland McGrath  <roland@redhat.com>
+
+	* x86_64_retval.c: New file.
+	* Makefile.am (x86_64_SRCS): Add it.
+	* x86_64_init.c (x86_64_init): Use x86_64_return_value_location.
+
+	* i386_retval.c: New file.
+	* Makefile.am (i386_SRCS): Add it.
+	(libdw): New variable.
+	(libebl_%.so): Use $(libdw) in link; use --as-needed.
+	* i386_init.c (i386_init): Use i386_return_value_location.
+
+	* eblretval.c: New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	(INCLUDES): Search in libdw.
+	* libebl.h: Include <libdw.h>.   Declare ebl_return_value_location.
+	* ebl-hooks.h: Declare return_value_location hook.
+	* eblopenbackend.c (default_return_value_location): New function.
+	(fill_defaults): Use it.
+
+2005-11-10  Roland McGrath  <roland@redhat.com>
+
+	* s390_init.c: New file.
+	* s390_reloc.def: New file.
+	* s390_symbol.c: New file.
+	* Makefile.am (modules, libebl_pic): Add s390.
+	(s390_SRCS, libebl_s390_pic_a_SOURCES): New variables.
+	(am_libebl_s390_pic_a_OBJECTS): New variable.
+
+	* ppc64_init.c: Use common-reloc.c.
+	* ppc64_symbol.c (ppc64_backend_name): Removed.
+	(ppc64_reloc_type_check, ppc64_reloc_type_name): Likewise.
+	(ppc64_copy_reloc_p, ppc64_reloc_valid_use): Likewise.
+
+	* ppc_init.c: Use common-reloc.c.
+	* ppc_symbol.c (ppc_backend_name): Removed.
+	(ppc_reloc_type_name, ppc_reloc_type_check): Likewise.
+	(ppc_reloc_valid_use, ppc_copy_reloc_p): Likewise.
+
+	* sparc_init.c: Use common-reloc.c.
+	* sparc_symbol.c (sparc_backend_name): Removed.
+	(sparc_reloc_type_name, sparc_reloc_type_check): Likewise.
+	(sparc_copy_reloc_p): Likewise.
+
+	* arm_init.c: Use common-reloc.c.
+	* arm_symbol.c (arm_backend_name): Removed.
+	(arm_reloc_type_name, arm_reloc_type_check, arm_copy_reloc_p): Removed.
+
+	* alpha_init.c: Use common-reloc.c.
+	* alpha_symbol.c (alpha_backend_name): Removed.
+	(alpha_reloc_type_name, alpha_reloc_type_check): Likewise.
+	(alpha_copy_reloc_p): Likewise.
+
+	* ia64_symbol.c (ia64_backend_name): Removed.
+	(ia64_reloc_type_name, ia64_reloc_type_check): Likewise.
+	(ia64_copy_reloc_p): Likewise.
+
+	* x86_64_init.c: Use common-reloc.c.
+	* x86_64_symbol.c (x86_64_backend_name): Removed.
+	(x86_64_copy_reloc_p, x86_64_reloc_valid_use): Likewise.
+	(x86_64_reloc_type_check, x86_64_reloc_type_name): Likewise.
+
+	* sh_init.c: Use common-reloc.c.
+	* sh_symbol.c: All functions removed.
+	(sh_reloc_simple_type): New function.
+	(sh_gotpc_reloc_check): New function.
+
+	* common-reloc.c: New file.
+	* Makefile.am (noinst_HEADERS): Add it.
+	* i386_init.c: Include it.
+
+	* sh_reloc.def: New file.
+	* i386_reloc.def: New file.
+	* alpha_reloc.def: New file.
+	* arm_reloc.def: New file.
+	* i386_reloc.def: New file.
+	* ia64_reloc.def: New file.
+	* ppc64_reloc.def: New file.
+	* ppc_reloc.def: New file.
+	* sh_reloc.def: New file.
+	* sparc_reloc.def: New file.
+	* x86_64_reloc.def: New file.
+	* Makefile.am (EXTRA_DIST): Add $(modules:=_reloc.def).
+
+	* libebl_alpha.map: Removed.
+	* libebl_ia64.map: Removed.
+	* libebl_ppc.map: Removed.
+	* libebl_sparc.map: Removed.
+	* libebl_arm.map: Removed.
+	* libebl_i386.map: Removed.
+	* libebl_ppc64.map: Removed.
+	* libebl_sh.map: Removed.
+	* libebl_x86_64.map: Removed.
+	* Makefile.am (EXTRA_DIST): Remove them.
+	(libebl_%.map, libebl_%.so): New pattern rules.
+
+	* libebl_alpha.h: Removed.
+	* libebl_ia64.h: Removed.
+	* libebl_ppc.h: Removed.
+	* libebl_sparc.h: Removed.
+	* libebl_arm.h: Removed.
+	* libebl_i386.h: Removed.
+	* libebl_ppc64.h: Removed.
+	* libebl_sh.h: Removed.
+	* libebl_x86_64.h: Removed.
+	* Makefile.am (noinst_HEADERS): Remove them.
+
+	* x86_64_corenote.c: Use libebl_CPU.h instead.
+	* x86_64_symbol.c: Likewise.
+	* i386_corenote.c: Likewise.
+
+2005-11-09  Roland McGrath  <roland@redhat.com>
+
+	* ia64_symbol.c (ia64_reloc_simple_type): New function.
+
+	* ebl-hooks.h (reloc_simple_type): Take the Ebl handle, not Elf handle.
+	* eblrelocsimpletype.c (ebl_reloc_simple_type): Update caller.
+	* eblopenbackend.c (default_reloc_simple_type): Update signature.
+	* i386_symbol.c (i386_reloc_simple_type): Likewise.
+	* ppc64_symbol.c (ppc64_reloc_simple_type): Likewise.
+	* ppc_symbol.c (ppc_reloc_simple_type): Likewise.
+	* x86_64_symbol.c (x86_64_reloc_simple_type): Likewise.
+
+	* i386_symbol.c (i386_backend_name): Removed.
+	(i386_reloc_type_name, i386_reloc_type_check): Likewise.
+	(i386_reloc_valid_use): Removed.
+	(i386_copy_reloc_p): Removed.
+
+	* alpha_destr.c: Removed.
+	* arm_destr.c: Removed.
+	* i386_destr.c: Removed.
+	* ia64_destr.c: Removed.
+	* ppc64_destr.c: Removed.
+	* ppc_destr.c: Removed.
+	* sh_destr.c: Removed.
+	* sparc_destr.c: Removed.
+	* x86_64_destr.c: Removed.
+
+	* ebl-hooks.h: New file, broken out of ...
+	* libeblP.h (struct ebl): ... here.  #include that for hook
+	declarations, after defining EBLHOOK macro.
+	* libebl_CPU.h: New file.
+	* Makefile.am (noinst_HEADERS): Add them.
+
+	* libeblP.h (struct ebl): Use uint_fast16_t for machine,
+	and uint_fast8_t for class and data.
+
+2005-08-14  Roland McGrath  <roland@redhat.com>
+
+	* ia64_symbol.c (ia64_section_type_name): New function.
+	(ia64_dynamic_tag_check): New function.
+	(ia64_reloc_valid_use): New function.
+	* libebl_ia64.h: Declare them.
+	* ia64_init.c (ia64_init): Use them.
+	* Makefile.am (libebl_ia64.so): Link with libelf.
+
+2005-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Use $(LINK) not $(CC) when creating DSOs.
+
+2005-08-13  Roland McGrath  <roland@redhat.com>
+
+	* ia64_symbol.c (ia64_machine_flag_check): New function.
+	* libebl_ia64.h: Declare it.
+	* ia64_init.c (ia64_init): Use it.
+
+2005-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* libebl.h: Add ehdr parameter to ebl_bss_plt_p and
+	ebl_check_special_symbol.
+	* libeblP.h (struct ebl): Adjust callback functions.
+	* eblopenbackend.c: Adjust dummy functions.
+	* ebl_check_special_symbol.c: Add parameter and pass it on.
+	* eblbsspltp.c: Likewise.
+	* ppc_symbol.c (find_dyn_got): With ehdr passed, simplify search for
+	the dynamic section entry.
+	(ppc_check_special_symbol): Add ehdr parameter.
+	(ppc_bss_plt_p): Likewise.
+	* libebl_ppc.h: Adjust prototypes.
+	* ppc64_symbol.c (ppc_check_special_symbol): Add ehdr parameter.
+	(ppc_bss_plt_p): Likewise.
+	* libebl_ppc64.h: Adjust prototypes.
+
+2005-08-12  Roland McGrath  <roland@redhat.com>
+
+	* ppc_symbol.c (find_dyn_got): New function, broken out of ...
+	(ppc_bss_plt_p): ... here.  Call that.
+	(ppc_check_special_symbol): Use find_dyn_got to fetch value to check
+	against _GLOBAL_OFFSET_TABLE_.
+
+	* libeblP.h (struct ebl): Add bss_plt_p hook.
+	* eblopenbackend.c (default_bss_plt_p): New function.
+	(fill_defaults): Use it.
+	* eblbsspltp.c: New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	* libebl.h: Declare ebl_bss_plt_p.
+	* ppc_symbol.c (ppc_bss_plt_p): New function.
+	* libebl_ppc.h: Declare it.
+	* ppc_init.c (ppc_init): Use it.
+	* ppc64_symbol.c (ppc64_bss_plt_p): New function.
+	* libebl_ppc64.h: Declare it.
+	* ppc64_init.c (ppc64_init): Use it.
+
+	* ebl_check_special_symbol.c: New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	* libebl.h: Declare ebl_check_special_symbol.
+	* libeblP.h (struct ebl): Add check_special_symbol hook.
+	* eblopenbackend.c (default_check_special_symbol): New function.
+	(fill_defaults): Use it.
+	* ppc_symbol.c (ppc_check_special_symbol): New function.
+	* libebl_ppc.h: Add prototype.
+	* ppc_init.c (ppc_init): Use it.
+	* ppc64_symbol.c (ppc64_check_special_symbol): New function.
+	* libebl_ppc64.h: Add prototype.
+	* ppc64_init.c (ppc64_init): Use it.
+
+2005-08-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* ppc_init.c: Add support for new DT_PPC_* and R_PPC_* values.
+	* ppc_symbol.c: Likewise.
+	* libebl_ppc.h: Likewise.
+	* ppc64_init.c: There is now also a dynamic_tag_check functions
+	* ppc64_symbol.c: Add dynamic_tag_check.
+	* libebl_ppc64.h: Add prototype.
+	* alpha_init.c: Add support for new DT_ALPHA_* value.
+	* alpha_symbol.c: Likewise.
+	* libebl_alpha.h: Likewise.
+
+2005-08-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* libebl_alpha.map: Remove unnecessary exports.
+	* libebl_arm.map: Likewise.
+	* libebl_i386.map: Likewise.
+	* libebl_ia64.map: Likewise.
+	* libebl_ppc.map: Likewise.
+	* libebl_ppc64.map: Likewise.
+	* libebl_sh.map: Likewise.
+	* libebl_sparc.map: Likewise.
+	* libebl_x86_64.map: Likewise.
+
+2005-08-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (libebl_a_SOURCES): Add eblelfclass.c, eblelfdata.c,
+	and eblelfmachine.c.
+	* elbopenbackend.c (machines): Add class and data fields.  Initialize
+	them.
+	(ebl_openbackend): Initialize machine, class, data fields in result.
+	* libebl.h: Declare Add eblelfclass, eblelfdata, and eblelfmachine.
+	* libeblP.h (Ebl): Add machine, class, data fields.
+
+2005-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblsectionstripp.c: New file.
+	* Makefile.am (gen_SOURCES): Add eblsectionstripp.c.
+	* i386_init.c (i386_init): Install specific debugscn_p callback.
+	* i386_symbol.c (i386_debugscn_p): New function.
+	* libebl.h: Declare ebl_section_strip_p.
+	* libebl_i386.h: Declare i386_debugscn_p.
+
+	* libebl.h: Move Ebl definition to...
+	* libeblP.h: ...here.
+
+2005-07-21  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (install-ebl-modules): New target, commands from ...
+	(install): ... here.  Make this depend on it.
+	(LIBEBL_SUBDIR): New variable, substituted by configure.
+	(install-ebl-modules): Install in $(libdir)/$(LIBEBL_SUBDIR).
+	* eblopenbackend.c (openbackend): Use LIBEBL_SUBDIR in module name.
+
+2005-07-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblcopyrelocp.c: New file.
+	* Makefile.am (gen_SOURCES): Add eblcopyrelocp.c.
+	* libebl.h: Declare ebl_copy_reloc_p.
+	* eblopenbackend.c (fill_defaults): Fill in copy_reloc_p.
+	(default_copy_reloc_p): New function.
+	* alpha_init.c: Define and use arch-specific copy_reloc_p function.
+	* alpha_symbol.c: Likewise.
+	* arm_init.c: Likewise.
+	* arm_symbol.c: Likewise.
+	* i386_init.c: Likewise.
+	* i386_symbol.c: Likewise.
+	* ia64_init.c: Likewise.
+	* ia64_symbol.c: Likewise.
+	* ppc64_init.c: Likewise.
+	* ppc64_symbol.c: Likewise.
+	* ppc_init.c: Likewise.
+	* ppc_symbol.c: Likewise.
+	* sh_init.c: Likewise.
+	* sh_symbol.c: Likewise.
+	* sparc_init.c: Likewise.
+	* sparc_symbol.c: Likewise.
+	* x86_64_init.c: Likewise.
+	* x86_64_symbol.c: Likewise.
+	* libebl_alpha.h: Declare the copy_reloc_p function.
+	* libebl_arm.h: Likewise.
+	* libebl_i386.h: Likewise.
+	* libebl_ia64.h: Likewise.
+	* libebl_ppc.h: Likewise.
+	* libebl_ppc64.h: Likewise.
+	* libebl_sh.h: Likewise.
+	* libebl_sparc.h: Likewise.
+	* libebl_x86_64.h: Likewise.
+
+2005-05-31  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (libebl_*_so_SOURCES): Set to $(*_SRCS) so dependency
+	tracking works right.
+
+2005-05-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* libebl_x86_64.map: Add x86_64_core_note.
+
+2005-05-19  Roland McGrath  <roland@redhat.com>
+
+	* libebl_i386.map: Add i386_reloc_valid_use, i386_reloc_simple_type.
+	* libebl_ppc.map: Add ppc_reloc_simple_type.
+	* libebl_ppc64.map: Add ppc64_reloc_simple_type.
+	* libebl_x86_64.map: Add x86_64_reloc_simple_type.
+
+2005-05-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblcorenote.c: Handle new AT_* values and files with different
+	endianess.
+	* Makefile.am (x86_64_SRCS): Add x86_64_corenote.c.
+	* x86-64_corenote.c: New file.
+	* x86_64_init.c: Hook in x86_64_corenote.
+	* i386_corenote.c: Make file usable on 64-bit platforms.
+
+	* eblopenbackend.c: If modules version comparison fails, reinitialize
+	hooks.
+
+2005-05-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblopenbackend.c: Require the init function to return a string.
+	Compare it with MODVERSION from config.h.
+	* alpha_init.c: Change return type.  Return MODVERSION or NULL.
+	* arm_init.c: Likewise.
+	* eblopenbackend.c: Likewise.
+	* i386_init.c: Likewise.
+	* ia64_init.c: Likewise.
+	* ppc64_init.c: Likewise.
+	* ppc_init.c: Likewise.
+	* sh_init.c: Likewise.
+	* sparc_init.c: Likewise.
+	* x86_64_init.c: Likewise.
+	* libeblP.h: Adjust ebl_bhinit_t.
+	* libebl_alpha.h: Adjust init function prototype.
+	* libebl_arm.h: Likewise.
+	* libebl_i386.h: Likewise.
+	* libebl_ia64.h: Likewise.
+	* libebl_ppc.h: Likewise.
+	* libebl_ppc64.h: Likewise.
+	* libebl_sh.h: Likewise.
+	* libebl_sparc.h: Likewise.
+	* libebl_x86_64.h: Likewise.
+
+	* mips_destr.c: Removed.
+	* mips_init.c: Removed.
+	* mips_symbol.c: Removed.
+	* libebl_mips.h: Removed.
+	* libebl_mips.map: Removed.
+
+2005-05-03  Roland McGrath  <roland@redhat.com>
+
+	* libebl.h (Ebl): Add `reloc_simple_type' member.
+	* eblopenbackend.c (default_reloc_simple_type): New function.
+	(openbackend): Use that as default reloc_simple_type callback.
+	* eblrelocsimpletype.c: New file.
+	* Makefile.am (gen_SOURCES): Add it.
+	* i386_symbol.c (i386_reloc_simple_type): New function.
+	* libebl_i386.h: Declare it.
+	* i386_init.c (i386_init): Use it.
+	* x86_64_symbol.c (x86_64_reloc_simple_type): New function.
+	* libebl_x86_64.h: Declare it.
+	* x86_64_init.c (x86_64_init): Use it.
+	* ppc_symbol.c (ppc_reloc_simple_type): New function.
+	* libebl_ppc.h: Declare it.
+	* ppc_init.c (ppc_init): Use it.
+	* ppc64_symbol.c (ppc64_reloc_simple_type): New function.
+	* libebl_ppc64.h: Declare it.
+	* ppc64_init.c (ppc64_init): Use it.
+
+2005-03-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblcorenote.c (ebl_core_note): Add support for AT_SECURE.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add -Wformat=2.
+
+2005-02-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* alpha_destr.c: Add __attribute__((unused)) where needed.
+	* alpha_init.c: Likewise.
+	* alpha_symbol.c: Likewise.
+	* arm_destr.c: Likewise.
+	* arm_init.c: Likewise.
+	* arm_symbol.c: Likewise.
+	* i386_corenote.c: Likewise.
+	* i386_destr.c: Likewise.
+	* i386_init.c: Likewise.
+	* i386_symbol.c: Likewise.
+	* ia64_destr.c: Likewise.
+	* ia64_init.c: Likewise.
+	* ia64_symbol.c: Likewise.
+	* mips_destr.c: Likewise.
+	* mips_init.c: Likewise.
+	* mips_symbol.c: Likewise.
+	* ppc64_destr.c: Likewise.
+	* ppc64_init.c: Likewise.
+	* ppc64_symbol.c: Likewise.
+	* ppc_destr.c: Likewise.
+	* ppc_init.c: Likewise.
+	* ppc_symbol.c: Likewise.
+	* sh_destr.c: Likewise.
+	* sh_init.c: Likewise.
+	* sh_symbol.c: Likewise.
+	* sparc_destr.c: Likewise.
+	* sparc_init.c: Likewise.
+	* sparc_symbol.c: Likewise.
+	* x86_64_destr.c: Likewise.
+	* x86_64_init.c: Likewise.
+	* x86_64_symbol.c: Likewise.
+
+	* x86_64_symbol.c (reloc_map_table): Fix entries for R_X86_64_64
+	and R_X86_64_32..
+
+2005-02-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblstrtab.c: A few cleanups.
+
+	* eblopenbackend.c: Mark unused parameters.
+
+	* eblgstrtab.c: Cleanups a few printf format strings.
+
+	* Makefile.am: Cleanup AM_CFLAGS handling.  Add -Wunused -Wextra.
+
+2005-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Check for text relocations in constructed DSOs.
+
+	* eblstrtab.c: Minor cleanups.
+
+	* Makefile.am (AM_CFLAGS): Add -std=gnu99 and -fmudflap for MUDFLAP.
+
+2004-08-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add LIBSTR definition with base name of
+	the lib directory.
+	* eblopenbackend.c (openbackend): Use LIBSTR instead of hardcoded
+	lib in path to ebl modules.
+
+2004-04-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Add rules for ppc and ppc64 ebl module.
+	* ppc_init..c: New file.
+	* ppc_destr.c: New file.
+	* ppc_symbol.c: New file.
+	* libebl_ppc.h: New file.
+	* libebl_ppc.map: New file.
+	* ppc64_init..c: New file.
+	* ppc64_destr.c: New file.
+	* ppc64_symbol.c: New file.
+	* libebl_ppc64.h: New file.
+	* libebl_ppc64.map: New file.
+
+2004-01-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support building with mudflap.
+
+2004-01-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* libeblP.h (_): Use elfutils domain.
+
+2004-01-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblsectionname.c: Add support for SHN_BEFORE and SHN_AFTER.
+
+2004-01-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblsegmenttypename.c ((ebl_segment_type_name): Add support for
+	PT_GNU_RELRO.
+
+2004-01-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* libebl.h: Remove last traces of libtool.
+
+2004-01-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf-knowledge.h: Move to libelf subdir.
+
+	* Makefile.am (EXTRA_DIST): Remove libebl.map.
+	* libebl.map: Removed.
+
+2003-12-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblsectiontypename.c (ebl_section_type_name): Add support for
+	SHT_SUNW_move, SHT_CHECKSUM, and SHT_GNU_LIBLIST.
+
+2003-11-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* ia64_symbol.c (ia64_dynamic_tag_name): New function.
+	* libebl_ia64.h (ia64_dynamic_tag_name): Declare.
+	* ia64_init.c (ia64_init): Register i164_dynamic_tag_name.
+
+2003-09-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* ia64_init.c (ia64_init): Initialize segment_type_name callback.
+	* ia64_symbol.c (ia64_segment_type_name): Define.
+	* libebl_ia64.h (ia64_segment_type_name): Declare.
+
+2003-09-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add -fpic.
+
+2003-08-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (install): Remove dependency on libebl.so.
+
+2003-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* eblopenbackend.c: Adjust relative path to arch-specific DSOs
+	assuming the code ends up in the application.  Add second dlopen()
+	try without any path, just the filename.
+	* Makefile.in: Remove rules to build and install libebl.so.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+        * Moved to CVS archive.
diff --git a/third_party/elfutils/libebl/Makefile.am b/third_party/elfutils/libebl/Makefile.am
new file mode 100644
index 0000000..737de6b
--- /dev/null
+++ b/third_party/elfutils/libebl/Makefile.am
@@ -0,0 +1,63 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 2000-2010, 2013, 2016, 2017 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * 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
+##
+## or both in parallel, as here.
+##
+## elfutils 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.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+AM_CFLAGS += $(fpic_CFLAGS)
+AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libdw -I$(srcdir)/../libasm
+VERSION = 1
+LIBEBL_SUBDIR = @LIBEBL_SUBDIR@
+
+lib_LIBRARIES = libebl.a
+
+pkginclude_HEADERS = libebl.h
+
+gen_SOURCES = eblopenbackend.c eblclosebackend.c \
+	      eblreloctypename.c eblsegmenttypename.c \
+	      eblsectiontypename.c eblmachineflagname.c \
+	      eblsymboltypename.c ebldynamictagname.c eblsectionname.c \
+	      eblsymbolbindingname.c eblbackendname.c eblosabiname.c \
+	      eblmachineflagcheck.c eblmachinesectionflagcheck.c \
+	      eblreloctypecheck.c eblrelocvaliduse.c eblrelocsimpletype.c \
+	      ebldynamictagcheck.c eblcorenotetypename.c eblobjnotetypename.c \
+	      eblcorenote.c eblobjnote.c ebldebugscnp.c \
+	      eblgotpcreloccheck.c eblcopyrelocp.c eblsectionstripp.c \
+	      eblelfclass.c eblelfdata.c eblelfmachine.c \
+	      ebl_check_special_symbol.c eblbsspltp.c eblretval.c \
+	      eblreginfo.c eblnonerelocp.c eblrelativerelocp.c \
+	      eblsysvhashentrysize.c eblauxvinfo.c eblcheckobjattr.c \
+	      ebl_check_special_section.c ebl_syscall_abi.c eblabicfi.c \
+	      eblstother.c eblinitreg.c ebldwarftoregno.c eblnormalizepc.c \
+	      eblunwind.c eblresolvesym.c eblcheckreloctargettype.c \
+	      ebl_data_marker_symbol.c
+
+libebl_a_SOURCES = $(gen_SOURCES)
+
+noinst_HEADERS = libeblP.h ebl-hooks.h
+
+CLEANFILES += $(am_libebl_pic_a_OBJECTS)
diff --git a/third_party/elfutils/libebl/ebl-hooks.h b/third_party/elfutils/libebl/ebl-hooks.h
new file mode 100644
index 0000000..f3a0e64
--- /dev/null
+++ b/third_party/elfutils/libebl/ebl-hooks.h
@@ -0,0 +1,192 @@
+/* Backend hook signatures internal interface for libebl.
+   Copyright (C) 2000-2011, 2013, 2014, 2016, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* Return symbolic representation of relocation type.  */
+const char *EBLHOOK(reloc_type_name) (int, char *, size_t);
+
+/* Check relocation type.  */
+bool EBLHOOK(reloc_type_check) (int);
+
+/* Check if relocation type is for simple absolute relocations.  */
+Elf_Type EBLHOOK(reloc_simple_type) (Ebl *, int);
+
+/* Check relocation type use.  */
+bool EBLHOOK(reloc_valid_use) (Elf *, int);
+
+/* Return true if the symbol type is that referencing the GOT.  */
+bool EBLHOOK(gotpc_reloc_check) (Elf *, int);
+
+/* Return symbolic representation of segment type.  */
+const char *EBLHOOK(segment_type_name) (int, char *, size_t);
+
+/* Return symbolic representation of section type.  */
+const char *EBLHOOK(section_type_name) (int, char *, size_t);
+
+/* Return section name.  */
+const char *EBLHOOK(section_name) (int, int, char *, size_t);
+
+/* Return next machine flag name.  */
+const char *EBLHOOK(machine_flag_name) (GElf_Word *);
+
+/* Check whether machine flags are valid.  */
+bool EBLHOOK(machine_flag_check) (GElf_Word);
+
+/* Check whether SHF_MASKPROC flag bits are valid.  */
+bool EBLHOOK(machine_section_flag_check) (GElf_Xword);
+
+/* Check whether the section with the given index, header, and name
+   is a special machine section that is valid despite a combination
+   of flags or other details that are not generically valid.  */
+bool EBLHOOK(check_special_section) (Ebl *, int,
+				     const GElf_Shdr *, const char *);
+
+/* Return symbolic representation of symbol type.  */
+const char *EBLHOOK(symbol_type_name) (int, char *, size_t);
+
+/* Return symbolic representation of symbol binding.  */
+const char *EBLHOOK(symbol_binding_name) (int, char *, size_t);
+
+/* Return symbolic representation of dynamic tag.  */
+const char *EBLHOOK(dynamic_tag_name) (int64_t, char *, size_t);
+
+/* Check dynamic tag.  */
+bool EBLHOOK(dynamic_tag_check) (int64_t);
+
+/* Return symbolic representation of OS ABI.  */
+const char *EBLHOOK(osabi_name) (int, char *, size_t);
+
+/* Name of a note entry type for core files.  */
+const char *EBLHOOK(core_note_type_name) (uint32_t, char *, size_t);
+
+/* Name of a note entry type for object files.  */
+const char *EBLHOOK(object_note_type_name) (const char *, uint32_t,
+					    char *, size_t);
+
+/* Describe core note format.  */
+int EBLHOOK(core_note) (const GElf_Nhdr *, const char *,
+			GElf_Word *, size_t *, const Ebl_Register_Location **,
+			size_t *, const Ebl_Core_Item **);
+
+/* Handle object file note.  */
+bool EBLHOOK(object_note) (const char *, uint32_t, uint32_t, const char *);
+
+/* Check object attribute.  */
+bool EBLHOOK(check_object_attribute) (Ebl *, const char *, int, uint64_t,
+				      const char **, const char **);
+
+/* Check reloc target section type.  */
+bool EBLHOOK(check_reloc_target_type) (Ebl *, Elf64_Word);
+
+/* Describe auxv element type.  */
+int EBLHOOK(auxv_info) (GElf_Xword, const char **, const char **);
+
+/* Check section name for being that of a debug informatino section.  */
+bool EBLHOOK(debugscn_p) (const char *);
+
+/* Check whether given relocation is a copy relocation.  */
+bool EBLHOOK(copy_reloc_p) (int);
+
+/* Check whether given relocation is a no-op relocation.  */
+bool EBLHOOK(none_reloc_p) (int);
+
+/* Check whether given relocation is a relative relocation.  */
+bool EBLHOOK(relative_reloc_p) (int);
+
+/* Check whether given symbol's value is ok despite normal checks.  */
+bool EBLHOOK(check_special_symbol) (Elf *, GElf_Ehdr *, const GElf_Sym *,
+			      const char *, const GElf_Shdr *);
+
+/* Check if this is a data marker symbol.  e.g. '$d' symbols for ARM.  */
+bool EBLHOOK(data_marker_symbol) (const GElf_Sym *sym, const char *sname);
+
+/* Check whether only valid bits are set on the st_other symbol flag.
+   Standard ST_VISIBILITY have already been masked off.  */
+bool EBLHOOK(check_st_other_bits) (unsigned char st_other);
+
+/* Check if backend uses a bss PLT in this file.  */
+bool EBLHOOK(bss_plt_p) (Elf *);
+
+/* Return location expression to find return value given the
+   DW_AT_type DIE of a DW_TAG_subprogram DIE.  */
+int EBLHOOK(return_value_location) (Dwarf_Die *functypedie,
+				    const Dwarf_Op **locp);
+
+/* Return register name information.  */
+ssize_t EBLHOOK(register_info) (Ebl *ebl,
+				int regno, char *name, size_t namelen,
+				const char **prefix, const char **setname,
+				int *bits, int *type);
+
+/* Return system call ABI registers.  */
+int EBLHOOK(syscall_abi) (Ebl *ebl, int *sp, int *pc,
+			  int *callno, int args[6]);
+
+/* Disassembler function.  */
+int EBLHOOK(disasm) (Ebl *ebl, const uint8_t **startp, const uint8_t *end,
+		     GElf_Addr addr, const char *fmt, DisasmOutputCB_t outcb,
+		     DisasmGetSymCB_t symcb, void *outcbarg, void *symcbarg);
+
+/* Supply the machine-specific state of CFI before CIE initial programs.
+   Function returns 0 on success and -1 on error.  */
+int EBLHOOK(abi_cfi) (Ebl *ebl, Dwarf_CIE *abi_info);
+
+/* Fetch process data from live TID and call SETFUNC one or more times.
+   Method should be present only when EBL_FRAME_NREGS > 0, otherwise the
+   backend doesn't support unwinding.  */
+bool EBLHOOK(set_initial_registers_tid) (pid_t tid,
+					 ebl_tid_registers_t *setfunc,
+					 void *arg);
+
+/* Convert *REGNO as is in DWARF to a lower range suitable for
+   Dwarf_Frame->REGS indexing.  */
+bool EBLHOOK(dwarf_to_regno) (Ebl *ebl, unsigned *regno);
+
+/* Optionally modify *PC as fetched from inferior data into valid PC
+   instruction pointer.  */
+void EBLHOOK(normalize_pc) (Ebl *ebl, Dwarf_Addr *pc);
+
+/* Get previous frame state for an existing frame state.  Method is called only
+   if unwinder could not find CFI for current PC.  PC is for the
+   existing frame.  SETFUNC sets register in the previous frame.  GETFUNC gets
+   register from the existing frame.  Note that GETFUNC vs. SETFUNC act on
+   a disjunct set of registers.  READFUNC reads memory.  ARG has to be passed
+   for SETFUNC, GETFUNC and READFUNC.  *SIGNAL_FRAMEP is initialized to false,
+   it can be set to true if existing frame is a signal frame.  SIGNAL_FRAMEP is
+   never NULL.  */
+bool EBLHOOK(unwind) (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc,
+		      ebl_tid_registers_get_t *getfunc,
+		      ebl_pid_memory_read_t *readfunc, void *arg,
+		      bool *signal_framep);
+
+/* Returns true if the value can be resolved to an address in an
+   allocated section, which will be returned in *ADDR.
+   (e.g. function descriptor resolving)  */
+bool EBLHOOK(resolve_sym_value) (Ebl *ebl, GElf_Addr *addr);
+
+/* Destructor for ELF backend handle.  */
+void EBLHOOK(destr) (struct ebl *);
diff --git a/third_party/elfutils/libebl/ebl_check_special_section.c b/third_party/elfutils/libebl/ebl_check_special_section.c
new file mode 100644
index 0000000..903b69d
--- /dev/null
+++ b/third_party/elfutils/libebl/ebl_check_special_section.c
@@ -0,0 +1,41 @@
+/* Check for a special section allowed to violate generic constraints.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_check_special_section (Ebl *ebl, int ndx, const GElf_Shdr *shdr,
+			   const char *sname)
+{
+  return ebl != NULL && ebl->check_special_section (ebl, ndx, shdr, sname);
+}
diff --git a/third_party/elfutils/libebl/ebl_check_special_symbol.c b/third_party/elfutils/libebl/ebl_check_special_symbol.c
new file mode 100644
index 0000000..bdcb026
--- /dev/null
+++ b/third_party/elfutils/libebl/ebl_check_special_symbol.c
@@ -0,0 +1,45 @@
+/* Check special symbol's st_value.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+bool
+ebl_check_special_symbol (Ebl *ebl, GElf_Ehdr *ehdr, const GElf_Sym *sym,
+			  const char *name, const GElf_Shdr *destshdr)
+{
+  if (ebl == NULL)
+    return false;
+
+  return ebl->check_special_symbol (ebl->elf, ehdr, sym, name, destshdr);
+}
diff --git a/third_party/elfutils/libebl/ebl_data_marker_symbol.c b/third_party/elfutils/libebl/ebl_data_marker_symbol.c
new file mode 100644
index 0000000..922d720
--- /dev/null
+++ b/third_party/elfutils/libebl/ebl_data_marker_symbol.c
@@ -0,0 +1,44 @@
+/* Check whether a symbol is a special data marker.
+   Copyright (C) 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+bool
+ebl_data_marker_symbol (Ebl *ebl, const GElf_Sym *sym, const char *sname)
+{
+  if (ebl == NULL)
+    return false;
+
+  return ebl->data_marker_symbol (sym, sname);
+}
diff --git a/third_party/elfutils/libebl/ebl_syscall_abi.c b/third_party/elfutils/libebl/ebl_syscall_abi.c
new file mode 100644
index 0000000..a25369d
--- /dev/null
+++ b/third_party/elfutils/libebl/ebl_syscall_abi.c
@@ -0,0 +1,40 @@
+/* Return system call ABI mapped to DWARF register numbers.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_syscall_abi (Ebl *ebl, int *sp, int *pc, int *callno, int *args)
+{
+  return ebl != NULL ? ebl->syscall_abi (ebl, sp, pc, callno, args) : -1;
+}
diff --git a/third_party/elfutils/libebl/eblabicfi.c b/third_party/elfutils/libebl/eblabicfi.c
new file mode 100644
index 0000000..8bf189f
--- /dev/null
+++ b/third_party/elfutils/libebl/eblabicfi.c
@@ -0,0 +1,46 @@
+/* Return ABI-specific DWARF CFI details.
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info)
+{
+  return ebl == NULL ? -1 : ebl->abi_cfi (ebl, abi_info);
+}
+
+int
+ebl_ra_offset (Ebl *ebl)
+{
+  return ebl->ra_offset;
+}
diff --git a/third_party/elfutils/libebl/eblauxvinfo.c b/third_party/elfutils/libebl/eblauxvinfo.c
new file mode 100644
index 0000000..ce1141b
--- /dev/null
+++ b/third_party/elfutils/libebl/eblauxvinfo.c
@@ -0,0 +1,100 @@
+/* Describe known auxv types.
+   Copyright (C) 2007, 2008, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <libeblP.h>
+
+#define AUXV_TYPES							      \
+  TYPE (NULL, "")							      \
+  TYPE (IGNORE, "")							      \
+  TYPE (EXECFD, "d")							      \
+  TYPE (EXECFN, "s")							      \
+  TYPE (PHDR, "p")							      \
+  TYPE (PHENT, "u")							      \
+  TYPE (PHNUM, "u")							      \
+  TYPE (PAGESZ, "u")							      \
+  TYPE (BASE, "p")							      \
+  TYPE (FLAGS, "x")							      \
+  TYPE (ENTRY, "p")							      \
+  TYPE (NOTELF, "")							      \
+  TYPE (UID, "u")							      \
+  TYPE (EUID, "u")							      \
+  TYPE (GID, "u")							      \
+  TYPE (EGID, "u")							      \
+  TYPE (CLKTCK, "u")							      \
+  TYPE (PLATFORM, "s")							      \
+  TYPE (BASE_PLATFORM, "s")						      \
+  TYPE (HWCAP, "x")							      \
+  TYPE (FPUCW, "x")							      \
+  TYPE (DCACHEBSIZE, "d")						      \
+  TYPE (ICACHEBSIZE, "d")						      \
+  TYPE (UCACHEBSIZE, "d")						      \
+  TYPE (IGNOREPPC, "")							      \
+  TYPE (SECURE, "u")							      \
+  TYPE (SYSINFO, "p")							      \
+  TYPE (SYSINFO_EHDR, "p")						      \
+  TYPE (L1I_CACHESHAPE, "d")						      \
+  TYPE (L1D_CACHESHAPE, "d")						      \
+  TYPE (L2_CACHESHAPE, "d")						      \
+  TYPE (L3_CACHESHAPE, "d")						      \
+  TYPE (RANDOM, "p")
+
+static const struct
+{
+  const char *name, *format;
+} auxv_types[] =
+  {
+#define TYPE(name, fmt) [AT_##name] = { #name, fmt },
+    AUXV_TYPES
+#undef	TYPE
+  };
+#define nauxv_types (sizeof auxv_types / sizeof auxv_types[0])
+
+int
+ebl_auxv_info (Ebl *ebl, GElf_Xword a_type, const char **name,
+	       const char **format)
+{
+  int result = ebl->auxv_info (a_type, name, format);
+  if (result == 0 && a_type < nauxv_types && auxv_types[a_type].name != NULL)
+    {
+      /* The machine specific function did not know this type.  */
+      *name = auxv_types[a_type].name;
+      *format = auxv_types[a_type].format;
+      result = 1;
+    }
+  return result;
+}
diff --git a/third_party/elfutils/libebl/eblbackendname.c b/third_party/elfutils/libebl/eblbackendname.c
new file mode 100644
index 0000000..a2b2df6
--- /dev/null
+++ b/third_party/elfutils/libebl/eblbackendname.c
@@ -0,0 +1,42 @@
+/* Return backend name.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_backend_name (Ebl *ebl)
+{
+  return ebl != NULL ? ebl->emulation : gettext ("No backend");
+}
diff --git a/third_party/elfutils/libebl/eblbsspltp.c b/third_party/elfutils/libebl/eblbsspltp.c
new file mode 100644
index 0000000..24c4a08
--- /dev/null
+++ b/third_party/elfutils/libebl/eblbsspltp.c
@@ -0,0 +1,41 @@
+/* Check if backend uses a bss PLT.
+   Copyright (C) 2005, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+bool
+ebl_bss_plt_p (Ebl *ebl)
+{
+  return ebl == NULL ? false : ebl->bss_plt_p (ebl->elf);
+}
diff --git a/third_party/elfutils/libebl/eblcheckobjattr.c b/third_party/elfutils/libebl/eblcheckobjattr.c
new file mode 100644
index 0000000..b590a03
--- /dev/null
+++ b/third_party/elfutils/libebl/eblcheckobjattr.c
@@ -0,0 +1,56 @@
+/* Check object attributes.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <libeblP.h>
+
+
+bool
+ebl_check_object_attribute (Ebl *ebl, const char *vendor, int tag,
+			    uint64_t value, const char **tag_name,
+			    const char **value_name)
+{
+  if (ebl->check_object_attribute (ebl, vendor, tag, value,
+				   tag_name, value_name))
+    return true;
+
+  if (strcmp (vendor, "gnu"))
+    return false;
+
+  if (tag == 32)
+    {
+      *tag_name = "compatibility";
+      return true;
+    }
+
+  return false;
+}
diff --git a/third_party/elfutils/libebl/eblcheckreloctargettype.c b/third_party/elfutils/libebl/eblcheckreloctargettype.c
new file mode 100644
index 0000000..e0d57c1
--- /dev/null
+++ b/third_party/elfutils/libebl/eblcheckreloctargettype.c
@@ -0,0 +1,54 @@
+/* Check whether a section type is a valid target for relocation.
+   Copyright (C) 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type)
+{
+  if (ebl->check_reloc_target_type (ebl, sh_type))
+    return true;
+
+  switch (sh_type)
+    {
+      case SHT_PROGBITS:
+      case SHT_NOBITS:
+      case SHT_INIT_ARRAY:
+      case SHT_FINI_ARRAY:
+      case SHT_PREINIT_ARRAY:
+	return true;
+
+      default:
+	return false;
+    }
+}
diff --git a/third_party/elfutils/libebl/eblclosebackend.c b/third_party/elfutils/libebl/eblclosebackend.c
new file mode 100644
index 0000000..67fbdfe
--- /dev/null
+++ b/third_party/elfutils/libebl/eblclosebackend.c
@@ -0,0 +1,54 @@
+/* Free ELF backend handle.
+   Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dlfcn.h>
+#include <stdlib.h>
+
+#include <libeblP.h>
+
+
+void
+ebl_closebackend (Ebl *ebl)
+{
+  if (ebl != NULL)
+    {
+      /* Run the destructor.  */
+      ebl->destr (ebl);
+
+      /* Close the dynamically loaded object.  */
+      if (ebl->dlhandle != NULL)
+	(void) dlclose (ebl->dlhandle);
+
+      /* Free the resources.  */
+      free (ebl);
+    }
+}
diff --git a/third_party/elfutils/libebl/eblcopyrelocp.c b/third_party/elfutils/libebl/eblcopyrelocp.c
new file mode 100644
index 0000000..0458c4f
--- /dev/null
+++ b/third_party/elfutils/libebl/eblcopyrelocp.c
@@ -0,0 +1,41 @@
+/* Check whether given relocation is a copy relocation.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_copy_reloc_p (Ebl *ebl, int reloc)
+{
+  return ebl->copy_reloc_p (reloc);
+}
diff --git a/third_party/elfutils/libebl/eblcorenote.c b/third_party/elfutils/libebl/eblcorenote.c
new file mode 100644
index 0000000..783f981
--- /dev/null
+++ b/third_party/elfutils/libebl/eblcorenote.c
@@ -0,0 +1,80 @@
+/* Describe known core note formats.
+   Copyright (C) 2007, 2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <libeblP.h>
+
+
+int
+ebl_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const char *name,
+	       GElf_Word *regs_offset, size_t *nregloc,
+	       const Ebl_Register_Location **reglocs, size_t *nitems,
+	       const Ebl_Core_Item **items)
+{
+  int result = ebl->core_note (nhdr, name,
+			       regs_offset, nregloc, reglocs, nitems, items);
+  if (result == 0)
+    {
+      /* The machine specific function did not know this type.  */
+
+      *regs_offset = 0;
+      *nregloc = 0;
+      *reglocs = NULL;
+      switch (nhdr->n_type)
+	{
+#define ITEMS(type, table)				\
+	  case type:					\
+	    *items = table;				\
+	    *nitems = sizeof table / sizeof table[0];	\
+	    result = 1;					\
+	    break
+
+	  static const Ebl_Core_Item platform[] =
+	    {
+	      {
+		.name = "Platform",
+		.type = ELF_T_BYTE, .count = 0, .format = 's'
+	      }
+	    };
+	  ITEMS (NT_PLATFORM, platform);
+
+#undef	ITEMS
+	}
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/libebl/eblcorenotetypename.c b/third_party/elfutils/libebl/eblcorenotetypename.c
new file mode 100644
index 0000000..d3a56fa
--- /dev/null
+++ b/third_party/elfutils/libebl/eblcorenotetypename.c
@@ -0,0 +1,107 @@
+/* Return note type name.
+   Copyright (C) 2002, 2007, 2008, 2012, 2013 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <libeblP.h>
+
+const char *
+ebl_core_note_type_name (Ebl *ebl, uint32_t type, char *buf, size_t len)
+{
+  const char *res = ebl->core_note_type_name (type, buf, len);
+
+  if (res == NULL)
+    {
+      static const char *knowntypes[] =
+	{
+#define KNOWNSTYPE(name) [NT_##name] = #name
+	  KNOWNSTYPE (PRSTATUS),
+	  KNOWNSTYPE (FPREGSET),
+	  KNOWNSTYPE (PRPSINFO),
+	  KNOWNSTYPE (TASKSTRUCT),
+	  KNOWNSTYPE (PLATFORM),
+	  KNOWNSTYPE (AUXV),
+	  KNOWNSTYPE (GWINDOWS),
+	  KNOWNSTYPE (ASRS),
+	  KNOWNSTYPE (PSTATUS),
+	  KNOWNSTYPE (PSINFO),
+	  KNOWNSTYPE (PRCRED),
+	  KNOWNSTYPE (UTSNAME),
+	  KNOWNSTYPE (LWPSTATUS),
+	  KNOWNSTYPE (LWPSINFO),
+	  KNOWNSTYPE (PRFPXREG)
+#undef KNOWNSTYPE
+	};
+
+      /* Handle standard names.  */
+      if (type < sizeof (knowntypes) / sizeof (knowntypes[0])
+	  && knowntypes[type] != NULL)
+	res = knowntypes[type];
+      else
+	switch (type)
+	  {
+#define KNOWNSTYPE(name) case NT_##name: res = #name; break
+	    KNOWNSTYPE (PRXFPREG);
+	    KNOWNSTYPE (PPC_VMX);
+	    KNOWNSTYPE (PPC_SPE);
+	    KNOWNSTYPE (PPC_VSX);
+	    KNOWNSTYPE (PPC_TM_SPR);
+	    KNOWNSTYPE (386_TLS);
+	    KNOWNSTYPE (386_IOPERM);
+	    KNOWNSTYPE (X86_XSTATE);
+	    KNOWNSTYPE (S390_HIGH_GPRS);
+	    KNOWNSTYPE (S390_TIMER);
+	    KNOWNSTYPE (S390_TODCMP);
+	    KNOWNSTYPE (S390_TODPREG);
+	    KNOWNSTYPE (S390_CTRS);
+	    KNOWNSTYPE (S390_PREFIX);
+	    KNOWNSTYPE (S390_LAST_BREAK);
+	    KNOWNSTYPE (S390_SYSTEM_CALL);
+	    KNOWNSTYPE (ARM_VFP);
+	    KNOWNSTYPE (ARM_TLS);
+	    KNOWNSTYPE (ARM_HW_BREAK);
+	    KNOWNSTYPE (ARM_HW_WATCH);
+	    KNOWNSTYPE (ARM_SYSTEM_CALL);
+	    KNOWNSTYPE (SIGINFO);
+	    KNOWNSTYPE (FILE);
+#undef KNOWNSTYPE
+
+	  default:
+	    snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type);
+
+	    res = buf;
+	  }
+    }
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/ebldebugscnp.c b/third_party/elfutils/libebl/ebldebugscnp.c
new file mode 100644
index 0000000..2964fdb
--- /dev/null
+++ b/third_party/elfutils/libebl/ebldebugscnp.c
@@ -0,0 +1,42 @@
+/* Check section name for being that of a debug informatino section.
+   Copyright (C) 2002, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdint.h>
+#include <libeblP.h>
+
+
+bool
+ebl_debugscn_p (Ebl *ebl, const char *name)
+{
+  return name != NULL && ebl->debugscn_p (name);
+}
diff --git a/third_party/elfutils/libebl/ebldwarftoregno.c b/third_party/elfutils/libebl/ebldwarftoregno.c
new file mode 100644
index 0000000..c664496
--- /dev/null
+++ b/third_party/elfutils/libebl/ebldwarftoregno.c
@@ -0,0 +1,40 @@
+/* Convert *REGNO as is in DWARF to a lower range.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+bool
+ebl_dwarf_to_regno (Ebl *ebl, unsigned *regno)
+{
+  /* ebl is declared NN */
+  return ebl->dwarf_to_regno == NULL ? true : ebl->dwarf_to_regno (ebl, regno);
+}
diff --git a/third_party/elfutils/libebl/ebldynamictagcheck.c b/third_party/elfutils/libebl/ebldynamictagcheck.c
new file mode 100644
index 0000000..c2311cc
--- /dev/null
+++ b/third_party/elfutils/libebl/ebldynamictagcheck.c
@@ -0,0 +1,54 @@
+/* Check dynamic tag.
+   Copyright (C) 2001, 2002, 2006 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+bool
+ebl_dynamic_tag_check (Ebl *ebl, int64_t tag)
+{
+  bool res = ebl != NULL ? ebl->dynamic_tag_check (tag) : false;
+
+  if (!res
+      && ((tag >= 0 && tag < DT_NUM)
+	  || (tag >= DT_GNU_PRELINKED && tag <= DT_SYMINENT)
+	  || (tag >= DT_GNU_HASH && tag <= DT_SYMINFO)
+	  || tag == DT_VERSYM
+	  || (tag >= DT_RELACOUNT && tag <= DT_VERNEEDNUM)
+	  || tag == DT_AUXILIARY
+	  || tag == DT_FILTER))
+    res = true;
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/ebldynamictagname.c b/third_party/elfutils/libebl/ebldynamictagname.c
new file mode 100644
index 0000000..3aaccd0
--- /dev/null
+++ b/third_party/elfutils/libebl/ebldynamictagname.c
@@ -0,0 +1,109 @@
+/* Return dynamic tag name.
+   Copyright (C) 2001, 2002, 2006, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_dynamic_tag_name (Ebl *ebl, int64_t tag, char *buf, size_t len)
+{
+  const char *res = ebl != NULL ? ebl->dynamic_tag_name (tag, buf, len) : NULL;
+
+  if (res == NULL)
+    {
+      if (tag >= 0 && tag < DT_NUM)
+	{
+	  static const char *stdtags[] =
+	    {
+	      "NULL", "NEEDED", "PLTRELSZ", "PLTGOT", "HASH", "STRTAB",
+	      "SYMTAB", "RELA", "RELASZ", "RELAENT", "STRSZ", "SYMENT",
+	      "INIT", "FINI", "SONAME", "RPATH", "SYMBOLIC", "REL", "RELSZ",
+	      "RELENT", "PLTREL", "DEBUG", "TEXTREL", "JMPREL", "BIND_NOW",
+	      "INIT_ARRAY", "FINI_ARRAY", "INIT_ARRAYSZ", "FINI_ARRAYSZ",
+	      "RUNPATH", "FLAGS", "ENCODING", "PREINIT_ARRAY",
+	      "PREINIT_ARRAYSZ"
+	    };
+
+	  res = stdtags[tag];
+	}
+      else if (tag == DT_VERSYM)
+	res = "VERSYM";
+      else if (tag >= DT_GNU_PRELINKED && tag <= DT_SYMINENT)
+	{
+	  static const char *valrntags[] =
+	    {
+	      "GNU_PRELINKED", "GNU_CONFLICTSZ", "GNU_LIBLISTSZ",
+	      "CHECKSUM", "PLTPADSZ", "MOVEENT", "MOVESZ", "FEATURE_1",
+	      "POSFLAG_1", "SYMINSZ", "SYMINENT"
+	    };
+
+	  res = valrntags[tag - DT_GNU_PRELINKED];
+	}
+      else if (tag >= DT_GNU_HASH && tag <= DT_SYMINFO)
+	{
+	  static const char *addrrntags[] =
+	    {
+	      "GNU_HASH", "TLSDESC_PLT", "TLSDESC_GOT",
+	      "GNU_CONFLICT", "GNU_LIBLIST", "CONFIG", "DEPAUDIT", "AUDIT",
+	      "PLTPAD", "MOVETAB", "SYMINFO"
+	    };
+
+	  res = addrrntags[tag - DT_GNU_HASH];
+	}
+      else if (tag >= DT_RELACOUNT && tag <= DT_VERNEEDNUM)
+	{
+	  static const char *suntags[] =
+	    {
+	      "RELACOUNT", "RELCOUNT", "FLAGS_1", "VERDEF", "VERDEFNUM",
+	      "VERNEED", "VERNEEDNUM"
+	    };
+
+	  res = suntags[tag - DT_RELACOUNT];
+	}
+      else if (tag == DT_AUXILIARY)
+	res = "AUXILIARY";
+      else if (tag == DT_FILTER)
+	res = "FILTER";
+      else
+	{
+	  snprintf (buf, len, gettext ("<unknown>: %#" PRIx64), tag);
+
+	  res = buf;
+
+	}
+    }
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/eblelfclass.c b/third_party/elfutils/libebl/eblelfclass.c
new file mode 100644
index 0000000..2ffef30
--- /dev/null
+++ b/third_party/elfutils/libebl/eblelfclass.c
@@ -0,0 +1,41 @@
+/* Return ELF class.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_get_elfclass (Ebl *ebl)
+{
+  return ebl->class;
+}
diff --git a/third_party/elfutils/libebl/eblelfdata.c b/third_party/elfutils/libebl/eblelfdata.c
new file mode 100644
index 0000000..072924b
--- /dev/null
+++ b/third_party/elfutils/libebl/eblelfdata.c
@@ -0,0 +1,41 @@
+/* Return ELF data encoding.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_get_elfdata (Ebl *ebl)
+{
+  return ebl->data;
+}
diff --git a/third_party/elfutils/libebl/eblelfmachine.c b/third_party/elfutils/libebl/eblelfmachine.c
new file mode 100644
index 0000000..c2c8627
--- /dev/null
+++ b/third_party/elfutils/libebl/eblelfmachine.c
@@ -0,0 +1,41 @@
+/* Return ELF machine.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_get_elfmachine (Ebl *ebl)
+{
+  return ebl->machine;
+}
diff --git a/third_party/elfutils/libebl/eblgotpcreloccheck.c b/third_party/elfutils/libebl/eblgotpcreloccheck.c
new file mode 100644
index 0000000..7c9c079
--- /dev/null
+++ b/third_party/elfutils/libebl/eblgotpcreloccheck.c
@@ -0,0 +1,42 @@
+/* Return true if the symbol type is that referencing the GOT.  E.g.,
+   R_386_GOTPC.
+   Copyright (C) 2003 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_gotpc_reloc_check (Ebl *ebl, int reloc)
+{
+  return ebl != NULL ? ebl->gotpc_reloc_check (ebl->elf, reloc) : false;
+}
diff --git a/third_party/elfutils/libebl/eblinitreg.c b/third_party/elfutils/libebl/eblinitreg.c
new file mode 100644
index 0000000..8a3fb18
--- /dev/null
+++ b/third_party/elfutils/libebl/eblinitreg.c
@@ -0,0 +1,59 @@
+/* Fetch live process Dwfl_Frame from PID.
+   Copyright (C) 2013, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+#include <assert.h>
+
+bool
+ebl_set_initial_registers_tid (Ebl *ebl, pid_t tid,
+			       ebl_tid_registers_t *setfunc,
+			       void *arg)
+{
+  /* Otherwise caller could not allocate THREAD frame of proper size.
+     If set_initial_registers_tid is unsupported then FRAME_NREGS is zero.  */
+  assert (ebl->set_initial_registers_tid != NULL);
+  return ebl->set_initial_registers_tid (tid, setfunc, arg);
+}
+
+size_t
+ebl_frame_nregs (Ebl *ebl)
+{
+  /* ebl is declared NN */
+  return ebl->frame_nregs;
+}
+
+GElf_Addr
+ebl_func_addr_mask (Ebl *ebl)
+{
+  return ((ebl == NULL || ebl->func_addr_mask == 0)
+	  ? ~(GElf_Addr)0 : ebl->func_addr_mask);
+}
diff --git a/third_party/elfutils/libebl/eblmachineflagcheck.c b/third_party/elfutils/libebl/eblmachineflagcheck.c
new file mode 100644
index 0000000..e98b600
--- /dev/null
+++ b/third_party/elfutils/libebl/eblmachineflagcheck.c
@@ -0,0 +1,41 @@
+/* Check machine flag.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_machine_flag_check (Ebl *ebl, Elf64_Word flags)
+{
+  return ebl != NULL ? ebl->machine_flag_check (flags) : (flags == 0);
+}
diff --git a/third_party/elfutils/libebl/eblmachineflagname.c b/third_party/elfutils/libebl/eblmachineflagname.c
new file mode 100644
index 0000000..5f44077
--- /dev/null
+++ b/third_party/elfutils/libebl/eblmachineflagname.c
@@ -0,0 +1,88 @@
+/* Return machine flag names.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <system.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_machine_flag_name (Ebl *ebl, Elf64_Word flags, char *buf, size_t len)
+{
+  const char *res;
+
+  if (flags == 0)
+    res = "";
+  else
+    {
+      char *cp = buf;
+      int first = 1;
+      const char *machstr;
+      size_t machstrlen;
+
+      do
+	{
+	  if (! first)
+	    {
+	      if (cp + 1 >= buf + len)
+		break;
+	      *cp++ = ',';
+	    }
+
+	  machstr = ebl != NULL ? ebl->machine_flag_name (&flags) : NULL;
+	  if (machstr == NULL)
+	    {
+	      /* No more known flag.  */
+	      snprintf (cp, buf + len - cp, "%#x", flags);
+	      break;
+	    }
+
+	  machstrlen = strlen (machstr) + 1;
+	  if ((size_t) (buf + len - cp) < machstrlen)
+	    {
+	      *((char *) mempcpy (cp, machstr, buf + len - cp - 1)) = '\0';
+	      break;
+	    }
+
+	  cp = mempcpy (cp, machstr, machstrlen);
+
+	  first = 0;
+	}
+      while (flags != 0);
+
+      res = buf;
+    }
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/eblmachinesectionflagcheck.c b/third_party/elfutils/libebl/eblmachinesectionflagcheck.c
new file mode 100644
index 0000000..a73b230
--- /dev/null
+++ b/third_party/elfutils/libebl/eblmachinesectionflagcheck.c
@@ -0,0 +1,40 @@
+/* Check SHF_MASKPROC flags.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_machine_section_flag_check (Ebl *ebl, GElf_Xword flags)
+{
+  return ebl != NULL ? ebl->machine_section_flag_check (flags) : (flags == 0);
+}
diff --git a/third_party/elfutils/libebl/eblnonerelocp.c b/third_party/elfutils/libebl/eblnonerelocp.c
new file mode 100644
index 0000000..e51a3b0
--- /dev/null
+++ b/third_party/elfutils/libebl/eblnonerelocp.c
@@ -0,0 +1,41 @@
+/* Check whether given relocation is a no-op relocation.
+   Copyright (C) 2006 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2006.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_none_reloc_p (Ebl *ebl, int reloc)
+{
+  return ebl->none_reloc_p (reloc);
+}
diff --git a/third_party/elfutils/libebl/eblnormalizepc.c b/third_party/elfutils/libebl/eblnormalizepc.c
new file mode 100644
index 0000000..1629353
--- /dev/null
+++ b/third_party/elfutils/libebl/eblnormalizepc.c
@@ -0,0 +1,41 @@
+/* Modify PC as fetched from inferior data into valid PC.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+void
+ebl_normalize_pc (Ebl *ebl, Dwarf_Addr *pc)
+{
+  /* ebl is declared NN */
+  if (ebl->normalize_pc != NULL)
+    ebl->normalize_pc (ebl, pc);
+}
diff --git a/third_party/elfutils/libebl/eblobjnote.c b/third_party/elfutils/libebl/eblobjnote.c
new file mode 100644
index 0000000..ca4f155
--- /dev/null
+++ b/third_party/elfutils/libebl/eblobjnote.c
@@ -0,0 +1,233 @@
+/* Print contents of object file note.
+   Copyright (C) 2002, 2007, 2009, 2011, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libeblP.h>
+
+
+void
+ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
+		 uint32_t descsz, const char *desc)
+{
+  if (! ebl->object_note (name, type, descsz, desc))
+    {
+      /* The machine specific function did not know this type.  */
+
+      if (strcmp ("stapsdt", name) == 0)
+	{
+	  if (type != 3)
+	    {
+	      printf (gettext ("unknown SDT version %u\n"), type);
+	      return;
+	    }
+
+	  /* Descriptor starts with three addresses, pc, base ref and
+	     semaphore.  Then three zero terminated strings provider,
+	     name and arguments.  */
+
+	  union
+	  {
+	    Elf64_Addr a64[3];
+	    Elf32_Addr a32[3];
+	  } addrs;
+
+	  size_t addrs_size = gelf_fsize (ebl->elf, ELF_T_ADDR, 3, EV_CURRENT);
+	  if (descsz < addrs_size + 3)
+	    {
+	    invalid_sdt:
+	      printf (gettext ("invalid SDT probe descriptor\n"));
+	      return;
+	    }
+
+	  Elf_Data src =
+	    {
+	      .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
+	      .d_buf = (void *) desc, .d_size = addrs_size
+	    };
+
+	  Elf_Data dst =
+	    {
+	      .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
+	      .d_buf = &addrs, .d_size = addrs_size
+	    };
+
+	  if (gelf_xlatetom (ebl->elf, &dst, &src,
+			     elf_getident (ebl->elf, NULL)[EI_DATA]) == NULL)
+	    {
+	      printf ("%s\n", elf_errmsg (-1));
+	      return;
+	    }
+
+	  const char *provider = desc + addrs_size;
+	  const char *pname = memchr (provider, '\0', desc + descsz - provider);
+	  if (pname == NULL)
+	    goto invalid_sdt;
+
+	  ++pname;
+	  const char *args = memchr (pname, '\0', desc + descsz - pname);
+	  if (args == NULL ||
+	      memchr (++args, '\0', desc + descsz - pname) != desc + descsz - 1)
+	    goto invalid_sdt;
+
+	  GElf_Addr pc;
+	  GElf_Addr base;
+	  GElf_Addr sem;
+	  if (gelf_getclass (ebl->elf) == ELFCLASS32)
+	    {
+	      pc = addrs.a32[0];
+	      base = addrs.a32[1];
+	      sem = addrs.a32[2];
+	    }
+	  else
+	    {
+	      pc = addrs.a64[0];
+	      base = addrs.a64[1];
+	      sem = addrs.a64[2];
+	    }
+
+	  printf (gettext ("    PC: "));
+	  printf ("%#" PRIx64 ",", pc);
+	  printf (gettext (" Base: "));
+	  printf ("%#" PRIx64 ",", base);
+	  printf (gettext (" Semaphore: "));
+	  printf ("%#" PRIx64 "\n", sem);
+	  printf (gettext ("    Provider: "));
+	  printf ("%s,", provider);
+	  printf (gettext (" Name: "));
+	  printf ("%s,", pname);
+	  printf (gettext (" Args: "));
+	  printf ("'%s'\n", args);
+	  return;
+	}
+
+      switch (type)
+	{
+	case NT_GNU_BUILD_ID:
+	  if (strcmp (name, "GNU") == 0 && descsz > 0)
+	    {
+	      printf (gettext ("    Build ID: "));
+	      uint_fast32_t i;
+	      for (i = 0; i < descsz - 1; ++i)
+		printf ("%02" PRIx8, (uint8_t) desc[i]);
+	      printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
+	    }
+	  break;
+
+	case NT_GNU_GOLD_VERSION:
+	  if (strcmp (name, "GNU") == 0 && descsz > 0)
+	    /* A non-null terminated version string.  */
+	    printf (gettext ("    Linker version: %.*s\n"),
+		    (int) descsz, desc);
+	  break;
+
+	case NT_GNU_ABI_TAG:
+	  if (strcmp (name, "GNU") == 0 && descsz >= 8 && descsz % 4 == 0)
+	    {
+	      Elf_Data in =
+		{
+		  .d_version = EV_CURRENT,
+		  .d_type = ELF_T_WORD,
+		  .d_size = descsz,
+		  .d_buf = (void *) desc
+		};
+	      /* Normally NT_GNU_ABI_TAG is just 4 words (16 bytes).  If it
+		 is much (4*) larger dynamically allocate memory to convert.  */
+#define FIXED_TAG_BYTES 16
+	      uint32_t sbuf[FIXED_TAG_BYTES];
+	      uint32_t *buf;
+	      if (unlikely (descsz / 4 > FIXED_TAG_BYTES))
+		{
+		  buf = malloc (descsz);
+		  if (unlikely (buf == NULL))
+		    return;
+		}
+	      else
+		buf = sbuf;
+	      Elf_Data out =
+		{
+		  .d_version = EV_CURRENT,
+		  .d_type = ELF_T_WORD,
+		  .d_size = descsz,
+		  .d_buf = buf
+		};
+
+	      if (elf32_xlatetom (&out, &in, ebl->data) != NULL)
+		{
+		  const char *os;
+		  switch (buf[0])
+		    {
+		    case ELF_NOTE_OS_LINUX:
+		      os = "Linux";
+		      break;
+
+		    case ELF_NOTE_OS_GNU:
+		      os = "GNU";
+		      break;
+
+		    case ELF_NOTE_OS_SOLARIS2:
+		      os = "Solaris";
+		      break;
+
+		    case ELF_NOTE_OS_FREEBSD:
+		      os = "FreeBSD";
+		      break;
+
+		    default:
+		      os = "???";
+		      break;
+		    }
+
+		  printf (gettext ("    OS: %s, ABI: "), os);
+		  for (size_t cnt = 1; cnt < descsz / 4; ++cnt)
+		    {
+		      if (cnt > 1)
+			putchar_unlocked ('.');
+		      printf ("%" PRIu32, buf[cnt]);
+		    }
+		  putchar_unlocked ('\n');
+		}
+	      if (descsz / 4 > FIXED_TAG_BYTES)
+		free (buf);
+	      break;
+	    }
+	  FALLTHROUGH;
+
+	default:
+	  /* Unknown type.  */
+	  break;
+	}
+    }
+}
diff --git a/third_party/elfutils/libebl/eblobjnotetypename.c b/third_party/elfutils/libebl/eblobjnotetypename.c
new file mode 100644
index 0000000..db040d2
--- /dev/null
+++ b/third_party/elfutils/libebl/eblobjnotetypename.c
@@ -0,0 +1,109 @@
+/* Return note type name.
+   Copyright (C) 2002, 2007, 2009, 2011, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_object_note_type_name (Ebl *ebl, const char *name, uint32_t type,
+			   char *buf, size_t len)
+{
+  const char *res = ebl->object_note_type_name (name, type, buf, len);
+
+  if (res == NULL)
+    {
+      if (strcmp (name, "stapsdt") == 0)
+	{
+	  snprintf (buf, len, "Version: %" PRIu32, type);
+	  return buf;
+	}
+
+#define ELF_NOTE_GOPKGLIST 1
+#define ELF_NOTE_GOABIHASH 2
+#define ELF_NOTE_GODEPS    3
+#define ELF_NOTE_GOBUILDID 4
+
+      static const char *goknowntypes[] =
+	{
+#define KNOWNSTYPE(name) [ELF_NOTE_GO##name] = #name
+	  KNOWNSTYPE (PKGLIST),
+	  KNOWNSTYPE (ABIHASH),
+	  KNOWNSTYPE (DEPS),
+	  KNOWNSTYPE (BUILDID),
+#undef KNOWNSTYPE
+	};
+
+      if (strcmp (name, "Go") == 0)
+	{
+	  if (type < sizeof (goknowntypes) / sizeof (goknowntypes[0])
+	      && goknowntypes[type] != NULL)
+	    return goknowntypes[type];
+	  else
+	    {
+	      snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type);
+	      return buf;
+	    }
+	}
+
+      if (strcmp (name, "GNU") != 0)
+	{
+	  snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type);
+	  return buf;
+	}
+
+      static const char *knowntypes[] =
+	{
+#define KNOWNSTYPE(name) [NT_##name] = #name
+	  KNOWNSTYPE (VERSION),
+	  KNOWNSTYPE (GNU_HWCAP),
+	  KNOWNSTYPE (GNU_BUILD_ID),
+	  KNOWNSTYPE (GNU_GOLD_VERSION),
+	};
+
+      /* Handle standard names.  */
+      if (type < sizeof (knowntypes) / sizeof (knowntypes[0])
+	  && knowntypes[type] != NULL)
+	res = knowntypes[type];
+      else
+	{
+	  snprintf (buf, len, "%s: %" PRIu32, gettext ("<unknown>"), type);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/eblopenbackend.c b/third_party/elfutils/libebl/eblopenbackend.c
new file mode 100644
index 0000000..1f81477
--- /dev/null
+++ b/third_party/elfutils/libebl/eblopenbackend.c
@@ -0,0 +1,758 @@
+/* Generate ELF backend handle.
+   Copyright (C) 2000-2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <dlfcn.h>
+#include <error.h>
+#include <libelfP.h>
+#include <dwarf.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <system.h>
+#include <libeblP.h>
+
+
+/* This table should contain the complete list of architectures as far
+   as the ELF specification is concerned.  */
+/* XXX When things are stable replace the string pointers with char
+   arrays to avoid relocations.  */
+static const struct
+{
+  const char *dsoname;
+  const char *emulation;
+  const char *prefix;
+  int prefix_len;
+  int em;
+  int class;
+  int data;
+} machines[] =
+{
+  { "i386", "elf_i386", "i386", 4, EM_386, ELFCLASS32, ELFDATA2LSB },
+  { "ia64", "elf_ia64", "ia64", 4, EM_IA_64, ELFCLASS64, ELFDATA2LSB },
+  { "alpha", "elf_alpha", "alpha", 5, EM_ALPHA, ELFCLASS64, ELFDATA2LSB },
+  { "x86_64", "elf_x86_64", "x86_64", 6, EM_X86_64, ELFCLASS64, ELFDATA2LSB },
+  { "ppc", "elf_ppc", "ppc", 3, EM_PPC, ELFCLASS32, ELFDATA2MSB },
+  { "ppc64", "elf_ppc64", "ppc64", 5, EM_PPC64, ELFCLASS64, ELFDATA2MSB },
+  { "tilegx", "elf_tilegx", "tilegx", 6, EM_TILEGX, ELFCLASS64, ELFDATA2LSB },
+  // XXX class and machine fields need to be filled in for all archs.
+  { "sh", "elf_sh", "sh", 2, EM_SH, 0, 0 },
+  { "arm", "ebl_arm", "arm", 3, EM_ARM, 0, 0 },
+  { "sparc", "elf_sparcv9", "sparc", 5, EM_SPARCV9, 0, 0 },
+  { "sparc", "elf_sparc", "sparc", 5, EM_SPARC, 0, 0 },
+  { "sparc", "elf_sparcv8plus", "sparc", 5, EM_SPARC32PLUS, 0, 0 },
+  { "s390", "ebl_s390", "s390", 4, EM_S390, 0, 0 },
+
+  { "m32", "elf_m32", "m32", 3, EM_M32, 0, 0 },
+  { "m68k", "elf_m68k", "m68k", 4, EM_68K, ELFCLASS32, ELFDATA2MSB },
+  { "m88k", "elf_m88k", "m88k", 4, EM_88K, 0, 0 },
+  { "i860", "elf_i860", "i860", 4, EM_860, 0, 0 },
+  { "s370", "ebl_s370", "s370", 4, EM_S370, 0, 0 },
+  { "parisc", "elf_parisc", "parisc", 6, EM_PARISC, 0, 0 },
+  { "vpp500", "elf_vpp500", "vpp500", 5, EM_VPP500, 0, 0 },
+  { "sparc", "elf_v8plus", "v8plus", 6, EM_SPARC32PLUS, 0, 0 },
+  { "i960", "elf_i960", "i960", 4, EM_960, 0, 0 },
+  { "v800", "ebl_v800", "v800", 4, EM_V800, 0, 0 },
+  { "fr20", "ebl_fr20", "fr20", 4, EM_FR20, 0, 0 },
+  { "rh32", "ebl_rh32", "rh32", 4, EM_RH32, 0, 0 },
+  { "rce", "ebl_rce", "rce", 3, EM_RCE, 0, 0 },
+  { "tricore", "elf_tricore", "tricore", 7, EM_TRICORE, 0, 0 },
+  { "arc", "elf_arc", "arc", 3, EM_ARC, 0, 0 },
+  { "h8", "elf_h8_300", "h8_300", 6, EM_H8_300, 0, 0 },
+  { "h8", "elf_h8_300h", "h8_300h", 6, EM_H8_300H, 0, 0 },
+  { "h8", "elf_h8s", "h8s", 6, EM_H8S, 0, 0 },
+  { "h8", "elf_h8_500", "h8_500", 6, EM_H8_500, 0, 0 },
+  { "coldfire", "elf_coldfire", "coldfire", 8, EM_COLDFIRE, 0, 0 },
+  { "m68k", "elf_68hc12", "68hc12", 6, EM_68HC12, 0, 0 },
+  { "mma", "elf_mma", "mma", 3, EM_MMA, 0, 0 },
+  { "pcp", "elf_pcp", "pcp", 3, EM_PCP, 0, 0 },
+  { "ncpu", "elf_ncpu", "ncpu", 4, EM_NCPU, 0, 0 },
+  { "ndr1", "elf_ndr1", "ndr1", 4, EM_NDR1, 0, 0 },
+  { "starcore", "elf_starcore", "starcore", 8, EM_STARCORE, 0, 0 },
+  { "me16", "elf_me16", "em16", 4, EM_ME16, 0, 0 },
+  { "st100", "elf_st100", "st100", 5, EM_ST100, 0, 0 },
+  { "tinyj", "elf_tinyj", "tinyj", 5, EM_TINYJ, 0, 0 },
+  { "pdsp", "elf_pdsp", "pdsp", 4, EM_PDSP, 0, 0 },
+  { "fx66", "elf_fx66", "fx66", 4, EM_FX66, 0, 0 },
+  { "st9plus", "elf_st9plus", "st9plus", 7, EM_ST9PLUS, 0, 0 },
+  { "st7", "elf_st7", "st7", 3, EM_ST7, 0, 0 },
+  { "m68k", "elf_68hc16", "68hc16", 6, EM_68HC16, 0, 0 },
+  { "m68k", "elf_68hc11", "68hc11", 6, EM_68HC11, 0, 0 },
+  { "m68k", "elf_68hc08", "68hc08", 6, EM_68HC08, 0, 0 },
+  { "m68k", "elf_68hc05", "68hc05", 6, EM_68HC05, 0, 0 },
+  { "svx", "elf_svx", "svx", 3, EM_SVX, 0, 0 },
+  { "st19", "elf_st19", "st19", 4, EM_ST19, 0, 0 },
+  { "vax", "elf_vax", "vax", 3, EM_VAX, 0, 0 },
+  { "cris", "elf_cris", "cris", 4, EM_CRIS, 0, 0 },
+  { "javelin", "elf_javelin", "javelin", 7, EM_JAVELIN, 0, 0 },
+  { "firepath", "elf_firepath", "firepath", 8, EM_FIREPATH, 0, 0 },
+  { "zsp", "elf_zsp", "zsp", 3, EM_ZSP, 0, 0 },
+  { "mmix", "elf_mmix", "mmix", 4, EM_MMIX, 0, 0 },
+  { "hunay", "elf_huany", "huany", 5, EM_HUANY, 0, 0 },
+  { "prism", "elf_prism", "prism", 5, EM_PRISM, 0, 0 },
+  { "avr", "elf_avr", "avr", 3, EM_AVR, 0, 0 },
+  { "fr30", "elf_fr30", "fr30", 4, EM_FR30, 0, 0 },
+  { "dv10", "elf_dv10", "dv10", 4, EM_D10V, 0, 0 },
+  { "dv30", "elf_dv30", "dv30", 4, EM_D30V, 0, 0 },
+  { "v850", "elf_v850", "v850", 4, EM_V850, 0, 0 },
+  { "m32r", "elf_m32r", "m32r", 4, EM_M32R, 0, 0 },
+  { "mn10300", "elf_mn10300", "mn10300", 7, EM_MN10300, 0, 0 },
+  { "mn10200", "elf_mn10200", "mn10200", 7, EM_MN10200, 0, 0 },
+  { "pj", "elf_pj", "pj", 2, EM_PJ, 0, 0 },
+  { "openrisc", "elf_openrisc", "openrisc", 8, EM_OPENRISC, 0, 0 },
+  { "arc", "elf_arc_a5", "arc_a5", 6, EM_ARC_A5, 0, 0 },
+  { "xtensa", "elf_xtensa", "xtensa", 6, EM_XTENSA, 0, 0 },
+  { "aarch64", "elf_aarch64", "aarch64", 7, EM_AARCH64, ELFCLASS64, 0 },
+  { "bpf", "elf_bpf", "bpf", 3, EM_BPF, 0, 0 },
+};
+#define nmachines (sizeof (machines) / sizeof (machines[0]))
+
+/* No machine prefix should be larger than this.  */
+#define MAX_PREFIX_LEN 16
+
+/* Default callbacks.  Mostly they just return the error value.  */
+static const char *default_reloc_type_name (int ignore, char *buf, size_t len);
+static bool default_reloc_type_check (int ignore);
+static bool default_reloc_valid_use (Elf *elf, int ignore);
+static Elf_Type default_reloc_simple_type (Ebl *ebl, int ignore);
+static bool default_gotpc_reloc_check (Elf *elf, int ignore);
+static const char *default_segment_type_name (int ignore, char *buf,
+					      size_t len);
+static const char *default_section_type_name (int ignore, char *buf,
+					      size_t len);
+static const char *default_section_name (int ignore, int ignore2, char *buf,
+					 size_t len);
+static const char *default_machine_flag_name (Elf64_Word *ignore);
+static bool default_machine_flag_check (Elf64_Word flags);
+static bool default_machine_section_flag_check (GElf_Xword flags);
+static const char *default_symbol_type_name (int ignore, char *buf,
+					     size_t len);
+static const char *default_symbol_binding_name (int ignore, char *buf,
+						size_t len);
+static const char *default_dynamic_tag_name (int64_t ignore, char *buf,
+					     size_t len);
+static bool default_dynamic_tag_check (int64_t ignore);
+static const char *default_osabi_name (int ignore, char *buf, size_t len);
+static void default_destr (struct ebl *ignore);
+static const char *default_core_note_type_name (uint32_t, char *buf,
+						size_t len);
+static const char *default_object_note_type_name (const char *name, uint32_t,
+						  char *buf, size_t len);
+static int default_core_note (const GElf_Nhdr *nhdr, const char *name,
+			      GElf_Word *regs_offset, size_t *nregloc,
+			      const Ebl_Register_Location **reglocs,
+			      size_t *nitems, const Ebl_Core_Item **);
+static int default_auxv_info (GElf_Xword a_type,
+			      const char **name, const char **format);
+static bool default_object_note (const char *name, uint32_t type,
+				 uint32_t descsz, const char *desc);
+static bool default_debugscn_p (const char *name);
+static bool default_copy_reloc_p (int reloc);
+static bool default_none_reloc_p (int reloc);
+static bool default_relative_reloc_p (int reloc);
+static bool default_check_special_symbol (Elf *elf, GElf_Ehdr *ehdr,
+					  const GElf_Sym *sym,
+					  const char *name,
+					  const GElf_Shdr *destshdr);
+static bool default_data_marker_symbol (const GElf_Sym *sym, const char *sname);
+static bool default_check_st_other_bits (unsigned char st_other);
+static bool default_check_special_section (Ebl *, int,
+					   const GElf_Shdr *, const char *);
+static bool default_bss_plt_p (Elf *elf);
+static int default_return_value_location (Dwarf_Die *functypedie,
+					  const Dwarf_Op **locops);
+static ssize_t default_register_info (Ebl *ebl,
+				      int regno, char *name, size_t namelen,
+				      const char **prefix,
+				      const char **setname,
+				      int *bits, int *type);
+static int default_syscall_abi (Ebl *ebl, int *sp, int *pc,
+				int *callno, int args[6]);
+static bool default_check_object_attribute (Ebl *ebl, const char *vendor,
+					    int tag, uint64_t value,
+					    const char **tag_name,
+					    const char **value_name);
+static bool default_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type);
+static int default_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info);
+
+
+static void
+fill_defaults (Ebl *result)
+{
+  result->reloc_type_name = default_reloc_type_name;
+  result->reloc_type_check = default_reloc_type_check;
+  result->reloc_valid_use = default_reloc_valid_use;
+  result->reloc_simple_type = default_reloc_simple_type;
+  result->gotpc_reloc_check = default_gotpc_reloc_check;
+  result->segment_type_name = default_segment_type_name;
+  result->section_type_name = default_section_type_name;
+  result->section_name = default_section_name;
+  result->machine_flag_name = default_machine_flag_name;
+  result->machine_flag_check = default_machine_flag_check;
+  result->machine_section_flag_check = default_machine_section_flag_check;
+  result->check_special_section = default_check_special_section;
+  result->symbol_type_name = default_symbol_type_name;
+  result->symbol_binding_name = default_symbol_binding_name;
+  result->dynamic_tag_name = default_dynamic_tag_name;
+  result->dynamic_tag_check = default_dynamic_tag_check;
+  result->osabi_name = default_osabi_name;
+  result->core_note_type_name = default_core_note_type_name;
+  result->object_note_type_name = default_object_note_type_name;
+  result->core_note = default_core_note;
+  result->auxv_info = default_auxv_info;
+  result->object_note = default_object_note;
+  result->debugscn_p = default_debugscn_p;
+  result->copy_reloc_p = default_copy_reloc_p;
+  result->none_reloc_p = default_none_reloc_p;
+  result->relative_reloc_p = default_relative_reloc_p;
+  result->check_special_symbol = default_check_special_symbol;
+  result->data_marker_symbol = default_data_marker_symbol;
+  result->check_st_other_bits = default_check_st_other_bits;
+  result->bss_plt_p = default_bss_plt_p;
+  result->return_value_location = default_return_value_location;
+  result->register_info = default_register_info;
+  result->syscall_abi = default_syscall_abi;
+  result->check_object_attribute = default_check_object_attribute;
+  result->check_reloc_target_type = default_check_reloc_target_type;
+  result->disasm = NULL;
+  result->abi_cfi = default_abi_cfi;
+  result->destr = default_destr;
+  result->sysvhash_entrysize = sizeof (Elf32_Word);
+}
+
+
+/* Find an appropriate backend for the file associated with ELF.  */
+static Ebl *
+openbackend (Elf *elf, const char *emulation, GElf_Half machine)
+{
+  Ebl *result;
+  size_t cnt;
+
+  /* First allocate the data structure for the result.  We do this
+     here since this assures that the structure is always large
+     enough.  */
+  result = (Ebl *) calloc (1, sizeof (Ebl));
+  if (result == NULL)
+    {
+      // XXX uncomment
+      // __libebl_seterror (ELF_E_NOMEM);
+      return NULL;
+    }
+
+  /* Fill in the default callbacks.  The initializer for the machine
+     specific module can overwrite the values.  */
+  fill_defaults (result);
+
+  /* XXX Currently all we do is to look at 'e_machine' value in the
+     ELF header.  With an internal mapping table from EM_* value to
+     DSO name we try to load the appropriate module to handle this
+     binary type.
+
+     Multiple modules for the same machine type are possible and they
+     will be tried in sequence.  The lookup process will only stop
+     when a module which can handle the machine type is found or all
+     available matching modules are tried.  */
+  for (cnt = 0; cnt < nmachines; ++cnt)
+    if ((emulation != NULL && strcmp (emulation, machines[cnt].emulation) == 0)
+	|| (emulation == NULL && machines[cnt].em == machine))
+      {
+	/* Well, we know the emulation name now.  */
+	result->emulation = machines[cnt].emulation;
+
+	/* We access some data structures directly.  Make sure the 32 and
+	   64 bit variants are laid out the same.  */
+	assert (offsetof (Elf32_Ehdr, e_machine)
+		== offsetof (Elf64_Ehdr, e_machine));
+	assert (sizeof (((Elf32_Ehdr *) 0)->e_machine)
+		== sizeof (((Elf64_Ehdr *) 0)->e_machine));
+	assert (offsetof (Elf, state.elf32.ehdr)
+		== offsetof (Elf, state.elf64.ehdr));
+
+	/* Prefer taking the information from the ELF file.  */
+	if (elf == NULL)
+	  {
+	    result->machine = machines[cnt].em;
+	    result->class = machines[cnt].class;
+	    result->data = machines[cnt].data;
+	  }
+	else
+	  {
+	    result->machine = elf->state.elf32.ehdr->e_machine;
+	    result->class = elf->state.elf32.ehdr->e_ident[EI_CLASS];
+	    result->data = elf->state.elf32.ehdr->e_ident[EI_DATA];
+	  }
+
+#ifndef LIBEBL_SUBDIR
+# define LIBEBL_SUBDIR PACKAGE
+#endif
+#define ORIGINDIR "$ORIGIN/../$LIB/" LIBEBL_SUBDIR "/"
+
+	/* Give it a try.  At least the machine type matches.  First
+           try to load the module.  */
+	char dsoname[100];
+	strcpy (stpcpy (stpcpy (dsoname, ORIGINDIR "libebl_"),
+			machines[cnt].dsoname),
+		".so");
+
+	void *h = dlopen (dsoname, RTLD_LAZY);
+	if (h == NULL)
+	  {
+	    strcpy (stpcpy (stpcpy (dsoname, "libebl_"),
+			    machines[cnt].dsoname),
+		    ".so");
+	    h = dlopen (dsoname, RTLD_LAZY);
+	  }
+
+	  /* Try without an explicit path.  */
+	if (h != NULL)
+	  {
+	    /* We managed to load the object.  Now see whether the
+	       initialization function likes our file.  */
+	    static const char version[] = MODVERSION;
+	    const char *modversion;
+	    ebl_bhinit_t initp;
+
+	    // We use a static number to help the compiler see we don't
+	    // overflow the stack with an arbitrary number.
+	    assert (machines[cnt].prefix_len <= MAX_PREFIX_LEN);
+	    char symname[MAX_PREFIX_LEN + sizeof "_init"];
+
+	    strcpy (mempcpy (symname, machines[cnt].prefix,
+			     machines[cnt].prefix_len), "_init");
+
+	    initp = (ebl_bhinit_t) dlsym (h, symname);
+	    if (initp != NULL
+		&& (modversion = initp (elf, machine, result, sizeof (Ebl)))
+		&& strcmp (version, modversion) == 0)
+	      {
+		/* We found a module to handle our file.  */
+		result->dlhandle = h;
+		result->elf = elf;
+
+		/* A few entries are mandatory.  */
+		assert (result->name != NULL);
+		assert (result->destr != NULL);
+
+		return result;
+	      }
+
+	    /* Not the module we need.  */
+	    (void) dlclose (h);
+	  }
+
+	/* We cannot find a DSO but the emulation/machine ID matches.
+	   Return that information.  */
+	result->dlhandle = NULL;
+	result->elf = elf;
+	result->name = machines[cnt].prefix;
+	fill_defaults (result);
+
+	return result;
+      }
+
+  /* Nothing matched.  We use only the default callbacks.   */
+  result->dlhandle = NULL;
+  result->elf = elf;
+  result->emulation = "<unknown>";
+  result->name = "<unknown>";
+  fill_defaults (result);
+
+  return result;
+}
+
+
+/* Find an appropriate backend for the file associated with ELF.  */
+Ebl *
+ebl_openbackend (Elf *elf)
+{
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr;
+
+  /* Get the ELF header of the object.  */
+  ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      // XXX uncomment
+      // __libebl_seterror (elf_errno ());
+      return NULL;
+    }
+
+  return openbackend (elf, NULL, ehdr->e_machine);
+}
+
+
+/* Find backend without underlying ELF file.  */
+Ebl *
+ebl_openbackend_machine (GElf_Half machine)
+{
+  return openbackend (NULL, NULL, machine);
+}
+
+
+/* Find backend with given emulation name.  */
+Ebl *
+ebl_openbackend_emulation (const char *emulation)
+{
+  return openbackend (NULL, emulation, EM_NONE);
+}
+
+
+/* Default callbacks.  Mostly they just return the error value.  */
+static const char *
+default_reloc_type_name (int ignore __attribute__ ((unused)),
+			 char *buf __attribute__ ((unused)),
+			 size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static bool
+default_reloc_type_check (int ignore __attribute__ ((unused)))
+{
+  return false;
+}
+
+static bool
+default_reloc_valid_use (Elf *elf __attribute__ ((unused)),
+			 int ignore __attribute__ ((unused)))
+{
+  return false;
+}
+
+static Elf_Type
+default_reloc_simple_type (Ebl *eh __attribute__ ((unused)),
+			   int ignore __attribute__ ((unused)))
+{
+  return ELF_T_NUM;
+}
+
+static bool
+default_gotpc_reloc_check (Elf *elf __attribute__ ((unused)),
+			   int ignore __attribute__ ((unused)))
+{
+  return false;
+}
+
+static const char *
+default_segment_type_name (int ignore __attribute__ ((unused)),
+			   char *buf __attribute__ ((unused)),
+			   size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_section_type_name (int ignore __attribute__ ((unused)),
+			   char *buf __attribute__ ((unused)),
+			   size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_section_name (int ignore __attribute__ ((unused)),
+		      int ignore2 __attribute__ ((unused)),
+		      char *buf __attribute__ ((unused)),
+		      size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_machine_flag_name (Elf64_Word *ignore __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static bool
+default_machine_flag_check (Elf64_Word flags __attribute__ ((unused)))
+{
+  return flags == 0;
+}
+
+static bool
+default_machine_section_flag_check (GElf_Xword flags)
+{
+  return flags == 0;
+}
+
+static bool
+default_check_special_section (Ebl *ebl __attribute__ ((unused)),
+			       int ndx __attribute__ ((unused)),
+			       const GElf_Shdr *shdr __attribute__ ((unused)),
+			       const char *sname __attribute__ ((unused)))
+{
+  return false;
+}
+
+static const char *
+default_symbol_type_name (int ignore __attribute__ ((unused)),
+			  char *buf __attribute__ ((unused)),
+			  size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_symbol_binding_name (int ignore __attribute__ ((unused)),
+			     char *buf __attribute__ ((unused)),
+			     size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_dynamic_tag_name (int64_t ignore __attribute__ ((unused)),
+			  char *buf __attribute__ ((unused)),
+			  size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static bool
+default_dynamic_tag_check (int64_t ignore __attribute__ ((unused)))
+{
+  return false;
+}
+
+static void
+default_destr (struct ebl *ignore __attribute__ ((unused)))
+{
+}
+
+static const char *
+default_osabi_name (int ignore __attribute__ ((unused)),
+		    char *buf __attribute__ ((unused)),
+		    size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static const char *
+default_core_note_type_name (uint32_t ignore __attribute__ ((unused)),
+			     char *buf __attribute__ ((unused)),
+			     size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static int
+default_auxv_info (GElf_Xword a_type __attribute__ ((unused)),
+		   const char **name __attribute__ ((unused)),
+		   const char **format __attribute__ ((unused)))
+{
+  return 0;
+}
+
+static int
+default_core_note (const GElf_Nhdr *nhdr __attribute__ ((unused)),
+		   const char *name __attribute__ ((unused)),
+		   GElf_Word *ro __attribute__ ((unused)),
+		   size_t *nregloc  __attribute__ ((unused)),
+		   const Ebl_Register_Location **reglocs
+		   __attribute__ ((unused)),
+		   size_t *nitems __attribute__ ((unused)),
+		   const Ebl_Core_Item **items __attribute__ ((unused)))
+{
+  return 0;
+}
+
+static const char *
+default_object_note_type_name (const char *name __attribute__ ((unused)),
+			       uint32_t ignore __attribute__ ((unused)),
+			       char *buf __attribute__ ((unused)),
+			       size_t len __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static bool
+default_object_note (const char *name __attribute__ ((unused)),
+		     uint32_t type __attribute__ ((unused)),
+		     uint32_t descsz __attribute__ ((unused)),
+		     const char *desc __attribute__ ((unused)))
+{
+  return NULL;
+}
+
+static bool
+default_debugscn_p (const char *name)
+{
+  /* We know by default only about the DWARF debug sections which have
+     fixed names.  */
+  static const char *dwarf_scn_names[] =
+    {
+      /* DWARF 1 */
+      ".debug",
+      ".line",
+      /* GNU DWARF 1 extensions */
+      ".debug_srcinfo",
+      ".debug_sfnames",
+      /* DWARF 1.1 and DWARF 2 */
+      ".debug_aranges",
+      ".debug_pubnames",
+      /* DWARF 2 */
+      ".debug_info",
+      ".debug_abbrev",
+      ".debug_line",
+      ".debug_frame",
+      ".debug_str",
+      ".debug_loc",
+      ".debug_macinfo",
+      /* DWARF 3 */
+      ".debug_ranges",
+      ".debug_pubtypes",
+      /* DWARF 4 */
+      ".debug_types",
+      /* GDB DWARF 4 extension */
+      ".gdb_index",
+      /* GNU/DWARF 5 extension/proposal */
+      ".debug_macro",
+      /* SGI/MIPS DWARF 2 extensions */
+      ".debug_weaknames",
+      ".debug_funcnames",
+      ".debug_typenames",
+      ".debug_varnames"
+    };
+  const size_t ndwarf_scn_names = (sizeof (dwarf_scn_names)
+				   / sizeof (dwarf_scn_names[0]));
+  for (size_t cnt = 0; cnt < ndwarf_scn_names; ++cnt)
+    if (strcmp (name, dwarf_scn_names[cnt]) == 0
+	|| (strncmp (name, ".zdebug", strlen (".zdebug")) == 0
+	    && strcmp (&name[2], &dwarf_scn_names[cnt][1]) == 0))
+      return true;
+
+  return false;
+}
+
+static bool
+default_copy_reloc_p (int reloc __attribute__ ((unused)))
+{
+  return false;
+}
+strong_alias (default_copy_reloc_p, default_none_reloc_p)
+strong_alias (default_copy_reloc_p, default_relative_reloc_p)
+
+static bool
+default_check_special_symbol (Elf *elf __attribute__ ((unused)),
+			      GElf_Ehdr *ehdr __attribute__ ((unused)),
+			      const GElf_Sym *sym __attribute__ ((unused)),
+			      const char *name __attribute__ ((unused)),
+			      const GElf_Shdr *destshdr __attribute__ ((unused)))
+{
+  return false;
+}
+
+static bool
+default_data_marker_symbol (const GElf_Sym *sym __attribute__ ((unused)),
+			    const char *sname __attribute__ ((unused)))
+{
+  return false;
+}
+
+static bool
+default_check_st_other_bits (unsigned char st_other __attribute__ ((unused)))
+{
+  return false;
+}
+
+
+static bool
+default_bss_plt_p (Elf *elf __attribute__ ((unused)))
+{
+  return false;
+}
+
+static int
+default_return_value_location (Dwarf_Die *functypedie __attribute__ ((unused)),
+			       const Dwarf_Op **locops __attribute__ ((unused)))
+{
+  return -2;
+}
+
+static ssize_t
+default_register_info (Ebl *ebl __attribute__ ((unused)),
+		       int regno, char *name, size_t namelen,
+		       const char **prefix,
+		       const char **setname,
+		       int *bits, int *type)
+{
+  if (name == NULL)
+    return 0;
+
+  *setname = "???";
+  *prefix = "";
+  *bits = -1;
+  *type = DW_ATE_void;
+  return snprintf (name, namelen, "reg%d", regno);
+}
+
+static int
+default_syscall_abi (Ebl *ebl __attribute__ ((unused)),
+		     int *sp, int *pc, int *callno, int args[6])
+{
+  *sp = *pc = *callno = -1;
+  args[0] = -1;
+  args[1] = -1;
+  args[2] = -1;
+  args[3] = -1;
+  args[4] = -1;
+  args[5] = -1;
+  return -1;
+}
+
+static bool
+default_check_object_attribute (Ebl *ebl __attribute__ ((unused)),
+				const char *vendor  __attribute__ ((unused)),
+				int tag __attribute__ ((unused)),
+				uint64_t value __attribute__ ((unused)),
+				const char **tag_name, const char **value_name)
+{
+  *tag_name = NULL;
+  *value_name = NULL;
+  return false;
+}
+
+static bool
+default_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)),
+				 Elf64_Word sh_type __attribute__ ((unused)))
+{
+  return false;
+}
+
+static int
+default_abi_cfi (Ebl *ebl __attribute__ ((unused)),
+		 Dwarf_CIE *abi_info __attribute__ ((unused)))
+{
+  return -1;
+}
diff --git a/third_party/elfutils/libebl/eblosabiname.c b/third_party/elfutils/libebl/eblosabiname.c
new file mode 100644
index 0000000..b60f2af
--- /dev/null
+++ b/third_party/elfutils/libebl/eblosabiname.c
@@ -0,0 +1,80 @@
+/* Return OS ABI name
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_osabi_name (Ebl *ebl, int osabi, char *buf, size_t len)
+{
+  const char *res = ebl != NULL ? ebl->osabi_name (osabi, buf, len) : NULL;
+
+  if (res == NULL)
+    {
+      if (osabi == ELFOSABI_NONE)
+	res = "UNIX - System V";
+      else if (osabi == ELFOSABI_HPUX)
+	res = "HP/UX";
+      else if (osabi == ELFOSABI_NETBSD)
+	res = "NetBSD";
+      else if (osabi == ELFOSABI_LINUX)
+	res = "Linux";
+      else if (osabi == ELFOSABI_SOLARIS)
+	res = "Solaris";
+      else if (osabi == ELFOSABI_AIX)
+	res = "AIX";
+      else if (osabi == ELFOSABI_IRIX)
+	res = "Irix";
+      else if (osabi == ELFOSABI_FREEBSD)
+	res = "FreeBSD";
+      else if (osabi == ELFOSABI_TRU64)
+	res = "TRU64";
+      else if (osabi == ELFOSABI_MODESTO)
+	res = "Modesto";
+      else if (osabi == ELFOSABI_OPENBSD)
+	res = "OpenBSD";
+      else if (osabi == ELFOSABI_ARM)
+	res = "Arm";
+      else if (osabi == ELFOSABI_STANDALONE)
+	res = gettext ("Stand alone");
+      else
+	{
+	  snprintf (buf, len, "%s: %d", gettext ("<unknown>"), osabi);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/eblreginfo.c b/third_party/elfutils/libebl/eblreginfo.c
new file mode 100644
index 0000000..acc4849
--- /dev/null
+++ b/third_party/elfutils/libebl/eblreginfo.c
@@ -0,0 +1,44 @@
+/* Return register name information.
+   Copyright (C) 2005, 2006 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+ssize_t
+ebl_register_info (Ebl *ebl, int regno, char *name, size_t namelen,
+		   const char **prefix, const char **setname,
+		   int *bits, int *type)
+{
+  return ebl == NULL ? -1 : ebl->register_info (ebl, regno, name, namelen,
+						prefix, setname, bits, type);
+}
diff --git a/third_party/elfutils/libebl/eblrelativerelocp.c b/third_party/elfutils/libebl/eblrelativerelocp.c
new file mode 100644
index 0000000..51f5dce
--- /dev/null
+++ b/third_party/elfutils/libebl/eblrelativerelocp.c
@@ -0,0 +1,41 @@
+/* Check whether given relocation is a relative relocation.
+   Copyright (C) 2006 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2006.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_relative_reloc_p (Ebl *ebl, int reloc)
+{
+  return ebl->relative_reloc_p (reloc);
+}
diff --git a/third_party/elfutils/libebl/eblrelocsimpletype.c b/third_party/elfutils/libebl/eblrelocsimpletype.c
new file mode 100644
index 0000000..9bd2928
--- /dev/null
+++ b/third_party/elfutils/libebl/eblrelocsimpletype.c
@@ -0,0 +1,40 @@
+/* Check relocation type for simple types.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+Elf_Type
+ebl_reloc_simple_type (Ebl *ebl, int reloc)
+{
+  return ebl != NULL ? ebl->reloc_simple_type (ebl, reloc) : ELF_T_NUM;
+}
diff --git a/third_party/elfutils/libebl/eblreloctypecheck.c b/third_party/elfutils/libebl/eblreloctypecheck.c
new file mode 100644
index 0000000..80e67ef
--- /dev/null
+++ b/third_party/elfutils/libebl/eblreloctypecheck.c
@@ -0,0 +1,41 @@
+/* Check relocation type.
+   Copyright (C) 2001, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_reloc_type_check (Ebl *ebl, int reloc)
+{
+  return ebl != NULL ? ebl->reloc_type_check (reloc) : false;
+}
diff --git a/third_party/elfutils/libebl/eblreloctypename.c b/third_party/elfutils/libebl/eblreloctypename.c
new file mode 100644
index 0000000..e53ec0c
--- /dev/null
+++ b/third_party/elfutils/libebl/eblreloctypename.c
@@ -0,0 +1,49 @@
+/* Return relocation type name.
+   Copyright (C) 2001, 2002, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_reloc_type_name (Ebl *ebl, int reloc, char *buf, size_t len)
+{
+  const char *res;
+
+  res = ebl != NULL ? ebl->reloc_type_name (reloc, buf, len) : NULL;
+  if (res == NULL)
+    /* There are no generic relocation type names.  */
+    res = "<INVALID RELOC>";
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/eblrelocvaliduse.c b/third_party/elfutils/libebl/eblrelocvaliduse.c
new file mode 100644
index 0000000..f0bed34
--- /dev/null
+++ b/third_party/elfutils/libebl/eblrelocvaliduse.c
@@ -0,0 +1,41 @@
+/* Check relocation type use.
+   Copyright (C) 2003 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_reloc_valid_use (Ebl *ebl, int reloc)
+{
+  return ebl != NULL ? ebl->reloc_valid_use (ebl->elf, reloc) : false;
+}
diff --git a/third_party/elfutils/libebl/eblresolvesym.c b/third_party/elfutils/libebl/eblresolvesym.c
new file mode 100644
index 0000000..470f6f0
--- /dev/null
+++ b/third_party/elfutils/libebl/eblresolvesym.c
@@ -0,0 +1,43 @@
+/* Resolve a symbol value to an allocated section of the Elf file.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+#include <assert.h>
+
+bool
+ebl_resolve_sym_value (Ebl *ebl, GElf_Addr *addr)
+{
+  if (ebl == NULL || ebl->resolve_sym_value == NULL)
+    return false;
+
+  return ebl->resolve_sym_value (ebl, addr);
+}
diff --git a/third_party/elfutils/libebl/eblretval.c b/third_party/elfutils/libebl/eblretval.c
new file mode 100644
index 0000000..7c03982
--- /dev/null
+++ b/third_party/elfutils/libebl/eblretval.c
@@ -0,0 +1,42 @@
+/* Return location expression to find return value given a function type DIE.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <libeblP.h>
+
+
+int
+ebl_return_value_location (Ebl *ebl, Dwarf_Die *functypedie,
+			   const Dwarf_Op **locops)
+{
+  return ebl == NULL ? -1 : ebl->return_value_location (functypedie, locops);
+}
diff --git a/third_party/elfutils/libebl/eblsectionname.c b/third_party/elfutils/libebl/eblsectionname.c
new file mode 100644
index 0000000..21c537f
--- /dev/null
+++ b/third_party/elfutils/libebl/eblsectionname.c
@@ -0,0 +1,90 @@
+/* Return section name.
+   Copyright (C) 2001, 2002, 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_section_name (Ebl *ebl, int section, int xsection, char *buf, size_t len,
+		  const char *scnnames[], size_t shnum)
+{
+  const char *res = ebl != NULL ? ebl->section_name (section, xsection,
+						     buf, len) : NULL;
+
+  if (res == NULL)
+    {
+      if (section == SHN_UNDEF)
+	res = "UNDEF";
+      else if (section == SHN_ABS)
+	res = "ABS";
+      else if (section == SHN_COMMON)
+	res = "COMMON";
+      else if (section == SHN_BEFORE)
+	res = "BEFORE";
+      else if (section == SHN_AFTER)
+	res = "AFTER";
+      else if ((section < SHN_LORESERVE || section == SHN_XINDEX)
+	       && (size_t) section < shnum)
+	{
+	  int idx = section != SHN_XINDEX ? section : xsection;
+
+	  if (scnnames != NULL)
+	    res = scnnames[idx];
+	  else
+	    {
+	      snprintf (buf, len, "%d", idx);
+	      res = buf;
+	    }
+	}
+      else
+	{
+	  /* Handle OS-specific section names.  */
+	  if (section == SHN_XINDEX)
+	    snprintf (buf, len, "%s: %d", "XINDEX", xsection);
+	  else if (section >= SHN_LOOS && section <= SHN_HIOS)
+	    snprintf (buf, len, "LOOS+%x", section - SHN_LOOS);
+	  /* Handle processor-specific section names.  */
+	  else if (section >= SHN_LOPROC && section <= SHN_HIPROC)
+	    snprintf (buf, len, "LOPROC+%x", section - SHN_LOPROC);
+	  else if (section >= SHN_LORESERVE && section <= SHN_HIRESERVE)
+	    snprintf (buf, len, "LORESERVE+%x", section - SHN_LORESERVE);
+	  else
+	    snprintf (buf, len, "%s: %d", gettext ("<unknown>"), section);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/eblsectionstripp.c b/third_party/elfutils/libebl/eblsectionstripp.c
new file mode 100644
index 0000000..c6cda63
--- /dev/null
+++ b/third_party/elfutils/libebl/eblsectionstripp.c
@@ -0,0 +1,67 @@
+/* Check whether section can be stripped.
+   Copyright (C) 2005, 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include "libeblP.h"
+
+
+bool
+ebl_section_strip_p (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr,
+		     const char *name, bool remove_comment,
+		     bool only_remove_debug)
+{
+  /* If only debug information should be removed check the name.  There
+     is unfortunately no other way.  */
+  if (unlikely (only_remove_debug))
+    {
+      if (ebl_debugscn_p (ebl, name))
+	return true;
+
+      if (shdr->sh_type == SHT_RELA || shdr->sh_type == SHT_REL)
+	{
+	  Elf_Scn *scn_l = elf_getscn (ebl->elf, (shdr)->sh_info);
+	  GElf_Shdr shdr_mem_l;
+	  GElf_Shdr *shdr_l = gelf_getshdr (scn_l, &shdr_mem_l);
+	  if (shdr_l != NULL)
+	    {
+	      const char *s_l = elf_strptr (ebl->elf, ehdr->e_shstrndx,
+					    shdr_l->sh_name);
+	      if (s_l != NULL && ebl_debugscn_p (ebl, s_l))
+		return true;
+	    }
+	}
+
+      return false;
+    }
+
+  return SECTION_STRIP_P (shdr, name, remove_comment);
+}
diff --git a/third_party/elfutils/libebl/eblsectiontypename.c b/third_party/elfutils/libebl/eblsectiontypename.c
new file mode 100644
index 0000000..5dc1ec6
--- /dev/null
+++ b/third_party/elfutils/libebl/eblsectiontypename.c
@@ -0,0 +1,123 @@
+/* Return section type name.
+   Copyright (C) 2001, 2002, 2006, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_section_type_name (Ebl *ebl, int section, char *buf, size_t len)
+{
+  const char *res = ebl->section_type_name (section, buf, len);
+
+  if (res == NULL)
+    {
+      static const char *knowntypes[] =
+	{
+#define KNOWNSTYPE(name) [SHT_##name] = #name
+	  KNOWNSTYPE (NULL),
+	  KNOWNSTYPE (PROGBITS),
+	  KNOWNSTYPE (SYMTAB),
+	  KNOWNSTYPE (STRTAB),
+	  KNOWNSTYPE (RELA),
+	  KNOWNSTYPE (HASH),
+	  KNOWNSTYPE (DYNAMIC),
+	  KNOWNSTYPE (NOTE),
+	  KNOWNSTYPE (NOBITS),
+	  KNOWNSTYPE (REL),
+	  KNOWNSTYPE (SHLIB),
+	  KNOWNSTYPE (DYNSYM),
+	  KNOWNSTYPE (INIT_ARRAY),
+	  KNOWNSTYPE (FINI_ARRAY),
+	  KNOWNSTYPE (PREINIT_ARRAY),
+	  KNOWNSTYPE (GROUP),
+	  KNOWNSTYPE (SYMTAB_SHNDX)
+	};
+
+      /* Handle standard names.  */
+      if ((size_t) section < sizeof (knowntypes) / sizeof (knowntypes[0])
+	  && knowntypes[section] != NULL)
+	res = knowntypes[section];
+      /* The symbol versioning/Sun extensions.  */
+      else if (section >= SHT_LOSUNW && section <= SHT_HISUNW)
+	{
+	  static const char *sunwtypes[] =
+	    {
+#undef KNOWNSTYPE
+#define KNOWNSTYPE(name) [SHT_##name - SHT_LOSUNW] = #name
+	      KNOWNSTYPE (SUNW_move),
+	      KNOWNSTYPE (SUNW_COMDAT),
+	      KNOWNSTYPE (SUNW_syminfo),
+	      KNOWNSTYPE (GNU_verdef),
+	      KNOWNSTYPE (GNU_verneed),
+	      KNOWNSTYPE (GNU_versym)
+	    };
+	  res = sunwtypes[section - SHT_LOSUNW];
+	}
+      else
+	/* A few GNU additions.  */
+	switch (section)
+	  {
+	  case SHT_CHECKSUM:
+	    res = "CHECKSUM";
+	    break;
+	  case SHT_GNU_LIBLIST:
+	    res = "GNU_LIBLIST";
+	    break;
+	  case SHT_GNU_HASH:
+	    res = "GNU_HASH";
+	    break;
+	  case SHT_GNU_ATTRIBUTES:
+	    res = "GNU_ATTRIBUTES";
+	    break;
+
+	  default:
+	    /* Handle OS-specific section names.  */
+	    if (section >= SHT_LOOS && section <= SHT_HIOS)
+	      snprintf (buf, len, "SHT_LOOS+%x", section - SHT_LOOS);
+	    /* Handle processor-specific section names.  */
+	    else if (section >= SHT_LOPROC && section <= SHT_HIPROC)
+	      snprintf (buf, len, "SHT_LOPROC+%x", section - SHT_LOPROC);
+	    else if ((unsigned int) section >= SHT_LOUSER
+		     && (unsigned int) section <= SHT_HIUSER)
+	      snprintf (buf, len, "SHT_LOUSER+%x", section - SHT_LOUSER);
+	    else
+	      snprintf (buf, len, "%s: %d", gettext ("<unknown>"), section);
+
+	    res = buf;
+	    break;
+	  }
+    }
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/eblsegmenttypename.c b/third_party/elfutils/libebl/eblsegmenttypename.c
new file mode 100644
index 0000000..14eda76
--- /dev/null
+++ b/third_party/elfutils/libebl/eblsegmenttypename.c
@@ -0,0 +1,86 @@
+/* Return segment type name.
+   Copyright (C) 2001, 2002, 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_segment_type_name (Ebl *ebl, int segment, char *buf, size_t len)
+{
+  const char *res;
+
+  res = ebl != NULL ? ebl->segment_type_name (segment, buf, len) : NULL;
+  if (res == NULL)
+    {
+      static const char *ptypes[PT_NUM] =
+	{
+#define PTYPE(name) [PT_##name] = #name
+	  PTYPE (NULL),
+	  PTYPE (LOAD),
+	  PTYPE (DYNAMIC),
+	  PTYPE (INTERP),
+	  PTYPE (NOTE),
+	  PTYPE (SHLIB),
+	  PTYPE (PHDR),
+	  PTYPE (TLS)
+	};
+
+      /* Is it one of the standard segment types?  */
+      if (segment >= PT_NULL && segment < PT_NUM)
+	res = ptypes[segment];
+      else if (segment == PT_GNU_EH_FRAME)
+	res = "GNU_EH_FRAME";
+      else if (segment == PT_GNU_STACK)
+	res = "GNU_STACK";
+      else if (segment == PT_GNU_RELRO)
+	res = "GNU_RELRO";
+      else if (segment == PT_SUNWBSS)
+	res = "SUNWBSS";
+      else if (segment == PT_SUNWSTACK)
+	res = "SUNWSTACK";
+      else
+	{
+	  if (segment >= PT_LOOS && segment <= PT_HIOS)
+	    snprintf (buf, len, "LOOS+%d", segment - PT_LOOS);
+	  else if (segment >= PT_LOPROC && segment <= PT_HIPROC)
+	    snprintf (buf, len, "LOPROC+%d", segment - PT_LOPROC);
+	  else
+	    snprintf (buf, len, "%s: %d", gettext ("<unknown>"), segment);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/eblstother.c b/third_party/elfutils/libebl/eblstother.c
new file mode 100644
index 0000000..273f6fc
--- /dev/null
+++ b/third_party/elfutils/libebl/eblstother.c
@@ -0,0 +1,41 @@
+/* Check st_other flag.
+   Copyright (C) 2011 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+bool
+ebl_check_st_other_bits (Ebl *ebl, unsigned char st_other)
+{
+  return ((st_other ^ GELF_ST_VISIBILITY (st_other)) == 0
+	  || ebl->check_st_other_bits (st_other ^ GELF_ST_VISIBILITY (st_other)));
+}
diff --git a/third_party/elfutils/libebl/eblsymbolbindingname.c b/third_party/elfutils/libebl/eblsymbolbindingname.c
new file mode 100644
index 0000000..9797425
--- /dev/null
+++ b/third_party/elfutils/libebl/eblsymbolbindingname.c
@@ -0,0 +1,74 @@
+/* Return symbol binding name.
+   Copyright (C) 2001, 2002, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_symbol_binding_name (Ebl *ebl, int binding, char *buf, size_t len)
+{
+  const char *res;
+
+  res = ebl != NULL ? ebl->symbol_type_name (binding, buf, len) : NULL;
+  if (res == NULL)
+    {
+      static const char *stb_names[STB_NUM] =
+	{
+	  "LOCAL", "GLOBAL", "WEAK"
+	};
+
+      /* Standard binding?  */
+      if (binding < STB_NUM)
+	res = stb_names[binding];
+      else
+	{
+	  char *ident;
+
+	  if (binding >= STB_LOPROC && binding <= STB_HIPROC)
+	    snprintf (buf, len, "LOPROC+%d", binding - STB_LOPROC);
+	  else if (binding == STB_GNU_UNIQUE
+		   && (ident = elf_getident (ebl->elf, NULL)) != NULL
+		   && ident[EI_OSABI] == ELFOSABI_LINUX)
+	    return "GNU_UNIQUE";
+	  else if (binding >= STB_LOOS && binding <= STB_HIOS)
+	    snprintf (buf, len, "LOOS+%d", binding - STB_LOOS);
+	  else
+	    snprintf (buf, len, gettext ("<unknown>: %d"), binding);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/eblsymboltypename.c b/third_party/elfutils/libebl/eblsymboltypename.c
new file mode 100644
index 0000000..09fa874
--- /dev/null
+++ b/third_party/elfutils/libebl/eblsymboltypename.c
@@ -0,0 +1,80 @@
+/* Return symbol type name.
+   Copyright (C) 2001, 2002, 2009 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <libeblP.h>
+
+
+const char *
+ebl_symbol_type_name (Ebl *ebl, int symbol, char *buf, size_t len)
+{
+  const char *res;
+
+  res = ebl != NULL ? ebl->symbol_type_name (symbol, buf, len) : NULL;
+  if (res == NULL)
+    {
+      static const char *stt_names[STT_NUM] =
+	{
+	  [STT_NOTYPE] = "NOTYPE",
+	  [STT_OBJECT] = "OBJECT",
+	  [STT_FUNC] = "FUNC",
+	  [STT_SECTION] = "SECTION",
+	  [STT_FILE] = "FILE",
+	  [STT_COMMON] = "COMMON",
+	  [STT_TLS] = "TLS"
+	};
+
+      /* Standard type?  */
+      if (symbol < STT_NUM)
+	res = stt_names[symbol];
+      else
+	{
+	  char *ident;
+
+	  if (symbol >= STT_LOPROC && symbol <= STT_HIPROC)
+	    snprintf (buf, len, "LOPROC+%d", symbol - STT_LOPROC);
+	  else if (symbol == STT_GNU_IFUNC
+		   && (ident = elf_getident (ebl->elf, NULL)) != NULL
+		   && ident[EI_OSABI] == ELFOSABI_LINUX)
+	    return "GNU_IFUNC";
+	  else if (symbol >= STT_LOOS && symbol <= STT_HIOS)
+	    snprintf (buf, len, "LOOS+%d", symbol - STT_LOOS);
+	  else
+	    snprintf (buf, len, gettext ("<unknown>: %d"), symbol);
+
+	  res = buf;
+	}
+    }
+
+  return res;
+}
diff --git a/third_party/elfutils/libebl/eblsysvhashentrysize.c b/third_party/elfutils/libebl/eblsysvhashentrysize.c
new file mode 100644
index 0000000..2049431
--- /dev/null
+++ b/third_party/elfutils/libebl/eblsysvhashentrysize.c
@@ -0,0 +1,41 @@
+/* Return OS ABI name
+   Copyright (C) 2006 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2006.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+
+int
+ebl_sysvhash_entrysize (Ebl *ebl)
+{
+  return ebl->sysvhash_entrysize;
+}
diff --git a/third_party/elfutils/libebl/eblunwind.c b/third_party/elfutils/libebl/eblunwind.c
new file mode 100644
index 0000000..2970d03
--- /dev/null
+++ b/third_party/elfutils/libebl/eblunwind.c
@@ -0,0 +1,44 @@
+/* Get previous frame state for an existing frame state.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+
+bool
+ebl_unwind (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc,
+	    ebl_tid_registers_get_t *getfunc, ebl_pid_memory_read_t *readfunc,
+	    void *arg, bool *signal_framep)
+{
+  /* ebl is declared NN */
+  if (ebl->unwind == NULL)
+    return false;
+  return ebl->unwind (ebl, pc, setfunc, getfunc, readfunc, arg, signal_framep);
+}
diff --git a/third_party/elfutils/libebl/libebl.h b/third_party/elfutils/libebl/libebl.h
new file mode 100644
index 0000000..882bdb9
--- /dev/null
+++ b/third_party/elfutils/libebl/libebl.h
@@ -0,0 +1,412 @@
+/* Interface for libebl.
+   Copyright (C) 2000-2010, 2013, 2014, 2015, 2016, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+
+/* This is the interface for the Elfutils Backend Library.
+   It is a completely UNSUPPORTED interface.  Don't use any libebl
+   function directly.  These are only for internal elfutils backends
+   and tools.  There is NO source or binary compatible guarantee.
+
+   The ABI of the backend modules is not guaranteed.  Really, no guarantee
+   whatsoever.  We are enforcing this in the code.  The modules and their
+   users must match.  No third-party EBL module are supported or allowed.
+   The only reason there are separate modules is to not have the code for
+   all architectures in all the binaries.  */
+
+
+#ifndef _LIBEBL_H
+#define _LIBEBL_H 1
+
+#include <gelf.h>
+#include "libdw.h"
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "elf-knowledge.h"
+
+
+/* Opaque type for the handle.  */
+typedef struct ebl Ebl;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Get backend handle for object associated with ELF handle.  */
+extern Ebl *ebl_openbackend (Elf *elf);
+/* Similar but without underlying ELF file.  */
+extern Ebl *ebl_openbackend_machine (GElf_Half machine);
+/* Similar but with emulation name given.  */
+extern Ebl *ebl_openbackend_emulation (const char *emulation);
+
+/* Free resources allocated for backend handle.  */
+extern void ebl_closebackend (Ebl *bh);
+
+
+/* Information about the descriptor.  */
+
+/* Get ELF machine.  */
+extern int ebl_get_elfmachine (Ebl *ebl) __pure_attribute__;
+
+/* Get ELF class.  */
+extern int ebl_get_elfclass (Ebl *ebl) __pure_attribute__;
+
+/* Get ELF data encoding.  */
+extern int ebl_get_elfdata (Ebl *ebl) __pure_attribute__;
+
+
+/* Function to call the callback functions including default ELF
+   handling.  */
+
+/* Return backend name.  */
+extern const char *ebl_backend_name (Ebl *ebl);
+
+/* Return relocation type name.  */
+extern const char *ebl_reloc_type_name (Ebl *ebl, int reloc,
+					char *buf, size_t len);
+
+/* Check relocation type.  */
+extern bool ebl_reloc_type_check (Ebl *ebl, int reloc);
+
+/* Check relocation type use.  */
+extern bool ebl_reloc_valid_use (Ebl *ebl, int reloc);
+
+/* Check if relocation type is for simple absolute relocations.
+   Return ELF_T_{BYTE,HALF,SWORD,SXWORD} for a simple type, else ELF_T_NUM.  */
+extern Elf_Type ebl_reloc_simple_type (Ebl *ebl, int reloc);
+
+/* Return true if the symbol type is that referencing the GOT.  E.g.,
+   R_386_GOTPC.  */
+extern bool ebl_gotpc_reloc_check (Ebl *ebl, int reloc);
+
+/* Return segment type name.  */
+extern const char *ebl_segment_type_name (Ebl *ebl, int segment,
+					  char *buf, size_t len);
+
+/* Return section type name.  */
+extern const char *ebl_section_type_name (Ebl *ebl, int section,
+					  char *buf, size_t len);
+
+/* Return section name.  */
+extern const char *ebl_section_name (Ebl *ebl, int section, int xsection,
+				     char *buf, size_t len,
+				     const char *scnnames[], size_t shnum);
+
+/* Return machine flag names.  */
+extern const char *ebl_machine_flag_name (Ebl *ebl, GElf_Word flags,
+					  char *buf, size_t len);
+
+/* Check whether machine flag is valid.  */
+extern bool ebl_machine_flag_check (Ebl *ebl, GElf_Word flags);
+
+/* Check whether SHF_MASKPROC flags are valid.  */
+extern bool ebl_machine_section_flag_check (Ebl *ebl, GElf_Xword flags);
+
+/* Check whether the section with the given index, header, and name
+   is a special machine section that is valid despite a combination
+   of flags or other details that are not generically valid.  */
+extern bool ebl_check_special_section (Ebl *ebl, int ndx,
+				       const GElf_Shdr *shdr, const char *name);
+
+/* Return symbol type name.  */
+extern const char *ebl_symbol_type_name (Ebl *ebl, int symbol,
+					 char *buf, size_t len);
+
+/* Return symbol binding name.  */
+extern const char *ebl_symbol_binding_name (Ebl *ebl, int binding,
+					    char *buf, size_t len);
+
+/* Return dynamic tag name.  */
+extern const char *ebl_dynamic_tag_name (Ebl *ebl, int64_t tag,
+					 char *buf, size_t len);
+
+/* Check dynamic tag.  */
+extern bool ebl_dynamic_tag_check (Ebl *ebl, int64_t tag);
+
+/* Check whether given symbol's st_value and st_size are OK despite failing
+   normal checks.  */
+extern bool ebl_check_special_symbol (Ebl *ebl, GElf_Ehdr *ehdr,
+				      const GElf_Sym *sym, const char *name,
+				      const GElf_Shdr *destshdr);
+
+/* Check if this is a data marker symbol.  e.g. '$d' symbols for ARM.  */
+extern bool ebl_data_marker_symbol (Ebl *ebl, const GElf_Sym *sym,
+				    const char *sname);
+
+/* Check whether only valid bits are set on the st_other symbol flag.  */
+extern bool ebl_check_st_other_bits (Ebl *ebl, unsigned char st_other);
+
+/* Return symbolic representation of OS ABI.  */
+extern const char *ebl_osabi_name (Ebl *ebl, int osabi, char *buf, size_t len);
+
+
+/* Return name of the note section type for a core file.  */
+extern const char *ebl_core_note_type_name (Ebl *ebl, uint32_t type, char *buf,
+					    size_t len);
+
+/* Return name of the note section type for an object file.  */
+extern const char *ebl_object_note_type_name (Ebl *ebl, const char *name,
+					      uint32_t type, char *buf,
+					      size_t len);
+
+/* Print information about object note if available.  */
+extern void ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
+			     uint32_t descsz, const char *desc);
+
+/* Check whether an attribute in a .gnu_attributes section is recognized.
+   Fills in *TAG_NAME with the name for this tag.
+   If VALUE is a known value for that tag, also fills in *VALUE_NAME.  */
+extern bool ebl_check_object_attribute (Ebl *ebl, const char *vendor,
+					int tag, uint64_t value,
+					const char **tag_name,
+					const char **value_name);
+
+/* Check whether a section type is a valid reloc target.  */
+extern bool ebl_check_reloc_target_type (Ebl *ebl, Elf64_Word sh_type);
+
+
+/* Check section name for being that of a debug informatino section.  */
+extern bool ebl_debugscn_p (Ebl *ebl, const char *name);
+
+/* Check whether given relocation is a copy relocation.  */
+extern bool ebl_copy_reloc_p (Ebl *ebl, int reloc);
+
+/* Check whether given relocation is a no-op relocation.  */
+extern bool ebl_none_reloc_p (Ebl *ebl, int reloc);
+
+/* Check whether given relocation is a relative relocation.  */
+extern bool ebl_relative_reloc_p (Ebl *ebl, int reloc);
+
+/* Check whether section should be stripped.  */
+extern bool ebl_section_strip_p (Ebl *ebl, const GElf_Ehdr *ehdr,
+				 const GElf_Shdr *shdr, const char *name,
+				 bool remove_comment, bool only_remove_debug);
+
+/* Check if backend uses a bss PLT in this file.  */
+extern bool ebl_bss_plt_p (Ebl *ebl);
+
+/* Return size of entry in SysV-style hash table.  */
+extern int ebl_sysvhash_entrysize (Ebl *ebl);
+
+/* Return location expression to find return value given a
+   DW_TAG_subprogram, DW_TAG_subroutine_type, or similar DIE describing
+   function itself (whose DW_AT_type attribute describes its return type).
+   Returns -1 for a libdw error (see dwarf_errno).
+   Returns -2 for an unrecognized type formation.
+   Returns zero if the function has no return value (e.g. "void" in C).
+   Otherwise, *LOCOPS gets a location expression to find the return value,
+   and returns the number of operations in the expression.  The pointer is
+   permanently allocated at least as long as the Ebl handle is open.  */
+extern int ebl_return_value_location (Ebl *ebl,
+				      Dwarf_Die *functypedie,
+				      const Dwarf_Op **locops);
+
+/* Fill in register information given DWARF register numbers.
+   If NAME is null, return the maximum REGNO + 1 that has a name.
+   Otherwise, store in NAME the name for DWARF register number REGNO
+   and return the number of bytes written (including '\0' terminator).
+   Return -1 if NAMELEN is too short or REGNO is negative or too large.
+   Return 0 if REGNO is unused (a gap in the DWARF number assignment).
+   On success, set *SETNAME to a description like "integer" or "FPU"
+   fit for "%s registers" title display, and *PREFIX to the string
+   that precedes NAME in canonical assembler syntax (e.g. "%" or "$").
+   The NAME string contains identifier characters only (maybe just digits).  */
+extern ssize_t ebl_register_info (Ebl *ebl,
+				  int regno, char *name, size_t namelen,
+				  const char **prefix, const char **setname,
+				  int *bits, int *type);
+
+/* Fill in the DWARF register numbers for the registers used in system calls.
+   The SP and PC are what kernel reports call the user stack pointer and PC.
+   The CALLNO and ARGS are the system call number and incoming arguments.
+   Each of these is filled with the DWARF register number corresponding,
+   or -1 if there is none.  Returns zero when the information is available.  */
+extern int ebl_syscall_abi (Ebl *ebl, int *sp, int *pc,
+			    int *callno, int args[6]);
+
+/* Supply the ABI-specified state of DWARF CFI before CIE initial programs.
+
+   The DWARF 3.0 spec says that the default initial states of all registers
+   are "undefined", unless otherwise specified by the machine/compiler ABI.
+
+   This default is wrong for every machine with the CFI generated by GCC.
+   The EH unwinder does not really distinguish "same_value" and "undefined",
+   since it doesn't matter for unwinding (in either case there is no change
+   to make for that register).  GCC generates CFI that says nothing at all
+   about registers it hasn't spilled somewhere.  For our unwinder to give
+   the true story, the backend must supply an initial state that uses
+   "same_value" rules for all the callee-saves registers.
+
+   This can fill in the initial_instructions, initial_instructions_end
+   members of *ABI_INFO to point at a CFI instruction stream to process
+   before each CIE's initial instructions.  It should set the
+   data_alignment_factor member if it affects the initial instructions.
+
+   The callback should not use the register rules DW_CFA_expression or
+   DW_CFA_val_expression.  Defining the CFA using DW_CFA_def_cfa_expression
+   is allowed.  This is an implementation detail since register rules
+   store expressions as offsets from the .eh_frame or .debug_frame data.
+
+   As a shorthand for some common cases, for this instruction stream
+   we overload some CFI instructions that cannot be used in a CIE:
+
+	DW_CFA_restore		-- Change default rule for all unmentioned
+				   registers from undefined to same_value.
+
+   This function can also fill in ABI_INFO->return_address_register with the
+   DWARF register number that identifies the actual PC in machine state.
+   If there is no canonical DWARF register number with that meaning, it's
+   left unchanged (callers usually initialize with (Dwarf_Word) -1).
+   This value is not used by CFI per se.
+
+   Function returns 0 on success and -1 for error or unsupported by the
+   backend.  */
+extern int ebl_abi_cfi (Ebl *ebl, Dwarf_CIE *abi_info)
+  __nonnull_attribute__ (2);
+
+/* Register map info. */
+typedef struct
+{
+  Dwarf_Half offset;		/* Byte offset in register data block.  */
+  Dwarf_Half regno;		/* DWARF register number.  */
+  uint8_t bits;			/* Bits of data for one register.  */
+  uint8_t pad;			/* Bytes of padding after register's data.  */
+  Dwarf_Half count;		/* Consecutive register numbers here.  */
+  bool pc_register;
+} Ebl_Register_Location;
+
+/* Non-register data items in core notes.  */
+typedef struct
+{
+  const char *name;		/* Printable identifier.  */
+  const char *group;		/* Identifier for category of related items.  */
+  Dwarf_Half offset;		/* Byte offset in note data.  */
+  Dwarf_Half count;
+  Elf_Type type;
+  char format;
+  bool thread_identifier;
+  bool pc_register;
+} Ebl_Core_Item;
+
+/* Describe the format of a core file note with the given header and NAME.
+   NAME is not guaranteed terminated, it's NHDR->n_namesz raw bytes.  */
+extern int ebl_core_note (Ebl *ebl, const GElf_Nhdr *nhdr, const char *name,
+			  GElf_Word *regs_offset, size_t *nregloc,
+			  const Ebl_Register_Location **reglocs,
+			  size_t *nitems, const Ebl_Core_Item **items)
+  __nonnull_attribute__ (1, 2, 3, 4, 5, 6, 7, 8);
+
+/* Describe the auxv type number.  */
+extern int ebl_auxv_info (Ebl *ebl, GElf_Xword a_type,
+			  const char **name, const char **format)
+  __nonnull_attribute__ (1, 3, 4);
+
+/* Callback type for ebl_set_initial_registers_tid.
+   Register -1 is mapped to PC (if arch PC has no DWARF number).
+   If FIRSTREG is -1 then NREGS has to be 1.  */
+typedef bool (ebl_tid_registers_t) (int firstreg, unsigned nregs,
+				    const Dwarf_Word *regs, void *arg)
+  __nonnull_attribute__ (3);
+
+/* Callback to fetch process data from live TID.
+   EBL architecture has to have EBL_FRAME_NREGS > 0, otherwise the
+   backend doesn't support unwinding and this function call may crash.  */
+extern bool ebl_set_initial_registers_tid (Ebl *ebl,
+					   pid_t tid,
+					   ebl_tid_registers_t *setfunc,
+					   void *arg)
+  __nonnull_attribute__ (1, 3);
+
+/* Number of registers to allocate for ebl_set_initial_registers_tid.
+   EBL architecture can unwind iff EBL_FRAME_NREGS > 0.  */
+extern size_t ebl_frame_nregs (Ebl *ebl)
+  __nonnull_attribute__ (1);
+
+/* Offset to apply to the value of the return_address_register, as
+   fetched from a Dwarf CFI.  This is used by some backends, where the
+   return_address_register actually contains the call address.  */
+extern int ebl_ra_offset (Ebl *ebl)
+  __nonnull_attribute__ (1);
+
+/* Mask to use for function symbol or unwind return addresses in case
+   the architecture adds some extra non-address bits to it.  This is
+   different from ebl_resolve_sym_value which only works for actual
+   symbol addresses (in non-ET_REL files) that might resolve to an
+   address in a different section.  ebl_func_addr_mask is called to
+   turn a given function value into the a real address or offset (the
+   original value might not be a real address).  This works for all
+   cases where an actual function address (or offset in ET_REL symbol
+   tables) is needed.  */
+extern GElf_Addr ebl_func_addr_mask (Ebl *ebl);
+
+/* Convert *REGNO as is in DWARF to a lower range suitable for
+   Dwarf_Frame->REGS indexing.  */
+extern bool ebl_dwarf_to_regno (Ebl *ebl, unsigned *regno)
+  __nonnull_attribute__ (1, 2);
+
+/* Modify PC as fetched from inferior data into valid PC.  */
+extern void ebl_normalize_pc (Ebl *ebl, Dwarf_Addr *pc)
+  __nonnull_attribute__ (1, 2);
+
+/* Callback type for ebl_unwind's parameter getfunc.  */
+typedef bool (ebl_tid_registers_get_t) (int firstreg, unsigned nregs,
+					Dwarf_Word *regs, void *arg)
+  __nonnull_attribute__ (3);
+
+/* Callback type for ebl_unwind's parameter readfunc.  */
+typedef bool (ebl_pid_memory_read_t) (Dwarf_Addr addr, Dwarf_Word *data,
+				      void *arg)
+  __nonnull_attribute__ (3);
+
+/* Get previous frame state for an existing frame state.  Method is called only
+   if unwinder could not find CFI for current PC.  PC is for the
+   existing frame.  SETFUNC sets register in the previous frame.  GETFUNC gets
+   register from the existing frame.  Note that GETFUNC vs. SETFUNC act on
+   a disjunct set of registers.  READFUNC reads memory.  ARG has to be passed
+   for SETFUNC, GETFUNC and READFUNC.  *SIGNAL_FRAMEP is initialized to false,
+   it can be set to true if existing frame is a signal frame.  SIGNAL_FRAMEP is
+   never NULL.  */
+extern bool ebl_unwind (Ebl *ebl, Dwarf_Addr pc, ebl_tid_registers_t *setfunc,
+			ebl_tid_registers_get_t *getfunc,
+			ebl_pid_memory_read_t *readfunc, void *arg,
+			bool *signal_framep)
+  __nonnull_attribute__ (1, 3, 4, 5, 7);
+
+/* Returns true if the value can be resolved to an address in an
+   allocated section, which will be returned in *ADDR
+   (e.g. function descriptor resolving)  */
+extern bool ebl_resolve_sym_value (Ebl *ebl, GElf_Addr *addr)
+   __nonnull_attribute__ (2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* libebl.h */
diff --git a/third_party/elfutils/libebl/libeblP.h b/third_party/elfutils/libebl/libeblP.h
new file mode 100644
index 0000000..5b339b3
--- /dev/null
+++ b/third_party/elfutils/libebl/libeblP.h
@@ -0,0 +1,103 @@
+/* Internal definitions for interface for libebl.
+   Copyright (C) 2000-2009, 2013, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBEBLP_H
+#define _LIBEBLP_H 1
+
+#include <gelf.h>
+#include <libasm.h>
+#include <libebl.h>
+#include <libintl.h>
+
+
+/* Backend handle.  */
+struct ebl
+{
+  /* Machine name.  */
+  const char *name;
+
+  /* Emulation name.  */
+  const char *emulation;
+
+  /* ELF machine, class, and data encoding.  */
+  uint_fast16_t machine;
+  uint_fast8_t class;
+  uint_fast8_t data;
+
+  /* The libelf handle (if known).  */
+  Elf *elf;
+
+  /* See ebl-hooks.h for the declarations of the hook functions.  */
+# define EBLHOOK(name) (*name)
+# include "ebl-hooks.h"
+# undef EBLHOOK
+
+  /* Size of entry in Sysv-style hash table.  */
+  int sysvhash_entrysize;
+
+  /* Number of registers to allocate for ebl_set_initial_registers_tid.
+     Ebl architecture can unwind iff FRAME_NREGS > 0.  */
+  size_t frame_nregs;
+
+  /* Offset to apply to the value of the return_address_register, as
+     fetched from a Dwarf CFI.  This is used by some backends, where
+     the return_address_register actually contains the call
+     address.  */
+  int ra_offset;
+
+  /* Mask to use to turn a function value into a real function address
+     in case the architecture adds some extra non-address bits to it.
+     If not initialized (0) then ebl_func_addr_mask will return ~0,
+     otherwise it should be the actual mask to use.  */
+  GElf_Addr func_addr_mask;
+
+  /* Function descriptor load address and table as used by
+     ebl_resolve_sym_value if available for this arch.  */
+  GElf_Addr fd_addr;
+  Elf_Data *fd_data;
+
+  /* Internal data.  */
+  void *dlhandle;
+};
+
+
+/* Type of the initialization functions in the backend modules.  */
+typedef const char *(*ebl_bhinit_t) (Elf *, GElf_Half, Ebl *, size_t);
+
+
+/* gettext helper macros.  */
+#undef _
+#define _(Str) dgettext ("elfutils", Str)
+
+
+/* LEB128 constant helper macros.  */
+#define ULEB128_7(x)	(BUILD_BUG_ON_ZERO ((x) >= (1U << 7)) + (x))
+
+#define BUILD_BUG_ON_ZERO(x) (sizeof (char [(x) ? -1 : 1]) - 1)
+
+#endif	/* libeblP.h */
diff --git a/third_party/elfutils/libelf/ChangeLog b/third_party/elfutils/libelf/ChangeLog
new file mode 100644
index 0000000..55ab25c
--- /dev/null
+++ b/third_party/elfutils/libelf/ChangeLog
@@ -0,0 +1,1529 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* elf32_updatenull.c (updatenull_wrlock): Use FALLTHROUGH macro
+	instead of comment.
+	* elf_begin.c (read_unmmaped_file): Likewise.
+	(elf_begin): Likewise.
+	* elf_cntl.c (elf_cntl): Likewise.
+
+2017-10-04  Mark Wielaard  <mark@klomp.org>
+
+	* elf_begin.c (file_read_elf): Skip sanity checking e_shoff if scncnt
+	is zero, we won't use it then.
+
+2017-10-04  Mark Wielaard  <mark@klomp.org>
+
+	* libelfP.h: Add ELF_E_INVALID_ELF to error values enum.
+	* elf_error.c (ELF_E_INVALID_ELF_IDX): New define. Use it as value
+	for ELF_E_INVALID_ELF in msgidx.
+	* elf_getshdrstrndx.c (elf_getshdrstrndx): Distinquish between pread
+	failing and not having enough data.
+	* elf_begin.c (get_shnum): Likewise. Explicitly set libelf errno on
+	too large value.
+	(file_read_elf): Make sure to always set libelf errno when returning
+	NULL. Distinquish between i/o file and elf data errors.
+
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* gelf_xlate.c: Use attribute_packed.
+
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* libelfP.h: Use attribute_hidden.
+
+2017-04-27  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpic_CFLAGS and dso_LDFLAGS.
+
+2017-08-15  Mark Wielaard  <mark@klomp.org>
+
+	* elf.h: Update from glibc. Add new powerpc note descriptors.
+
+2017-07-19  Gustavo Romero <gromero@linux.vnet.ibm.com>
+
+	* elf.h: Add known type in notes segment descriptor for HTM SPRs.
+
+2017-02-17  Ulf hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Add libelf_so_DEPS, which include libeu.a,
+	libelf_so_LIBS.
+	(libelf_so_LDLIBS): Add $(libelf_so_DEPS).
+	(libelf.so$(EXEEXT): Use $(libelf_so_LIBS), require libelf.map
+	from the right directory.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* libelfP.h: Don't include config.h.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* elf_begin.c: Use F_GETFD rather than F_GETFL.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* libelf.h: Define macros for various function attributes and use
+	them.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* elf_update.c: Set ELF_F_MMAPPED flag if we mmap from elf_update.
+
+2017-04-19  Mark Wielaard  <mark@klomp.org>
+
+	* elf_getarsym.c (elf_getarsym): Initialize n to zero.
+
+2017-03-27  Mark Wielaard  <mark@klomp.org>
+
+	* elf32_updatefile.c (updatemmap): Always update last_positition.
+	(updatefile): Likewise.
+
+2017-03-24  Mark Wielaard  <mark@klomp.org>
+
+	* elf_compress.c (__libelf_decompress): Check insane compression
+	ratios before trying to allocate output buffer.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* gelf.h (gelf_newehdr): Change return type to void *.
+	(gelf_newphdr): Likewise.
+	* gelf_newehdr.c (gelf_newehdr): Likewise.
+	* gelf_newphdr.c (gelf_newphdr): Likewise.
+
+2016-10-21  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Sanity check
+	offset and size before trying to malloc and read data.
+
+2016-10-26  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (read_file): Always set maxsize when parent == NULL.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* elf_getarsym.c (elf_getarsym): Open code rawmemchr when not
+	available.
+	* elf_strptr.c: Include stdbool.h.
+	(validate_str): New function.
+	(elf_strptr): Use validate_str instead of memrchr.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* elf32_updatefile.c: Remove sys/param.h include.
+	* elf32_updatenull.c: Likewise. Add system.h include.
+	* elf_begin.c: Remove sys/param.h.
+	* elf_compress: Likewise. Add system.h include.
+	(MAX): Remove definition.
+
+2016-08-07  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_compress.c (__libelf_reset_rawdata): Check scn->flags and
+	free rawdata_base when malloced. Set ELF_F_MALLOCED for scn->flags.
+	* elf_end.c (elf_end): Check scn->flags and free rawdata_base if
+	malloced.
+	* libelfP.h (struct Elf_Scn): Document flags ELF_F_MALLOCED usage.
+
+2016-07-06  Mark Wielaard  <mjw@redhat.com>
+
+	* elf-knowledge.h (SH_FLAGS_COMBINE): Removed.
+	(SH_FLAGS_IMPORTANT): Likewise.
+
+2016-07-06  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatenull.c (updatenull_wrlock): Ignore e_type when
+	updating phdrs.
+	* elf_getphdrnum.c (__elf_getphdrnum_chk_rdlock): Only do sanity
+	checking if phdrs haven't been read in yet.
+
+2016-06-24  John Ogness  <john.ogness@linutronix.de>
+
+	* elf32_updatenull.c (updatenull_wrlock): Find first section.
+	* elf_nextscn.c (elf_nextscn): When scn is NULL start from 0th
+	section.
+
+2016-06-28  Richard Henderson  <rth@redhat.com>
+
+	* elf.h: Update from glibc.  Add lots of new EM_* definitions.
+
+2016-04-14  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_compress.c (__libelf_compress): Free out_buf if deflateInit
+	fails.
+
+2016-02-13  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Free scns when out of memory.
+
+2016-01-28  Mark Wielaard  <mjw@redhat.com>
+
+	* elf.h: Update from glibc. Add new i386 and x86_64 relocations.
+
+2016-02-12  Mark Wielaard  <mjw@redhat.com>
+
+	* elf.h: Update from glibc. Add NT_ARM_SYSTEM_CALL.
+
+2016-02-04  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Don't adjust align
+	for SHT_NOBITS sections.
+
+2016-01-22  Chih-Hung Hsieh <chh@google.com>
+
+	* elf_compress.c (__libelf_compress): Move nested function
+	'do_deflate_cleanup' to file scope to compile with clang.
+	* elf_strptr.c (elf_strptr): Move nested function 'get_zdata'
+	to file scope to compile with clang.
+
+2016-01-13  Mark Wielaard  <mjw@redhat.com>
+
+	* libelf.h: Check SHF_COMPRESSED is defined. If not define it and the
+	associated ELF compression types/defines.
+
+2015-11-26  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_compress.c (__libelf_decompress_elf): New function, extracted
+	from...
+	(elf_compress): here. Check zdata_base use __libelf_decompress_elf.
+	* elf_strptr.c (elf_strptr): If SHF_COMPRESSED check, uncompress and
+	use zdata.
+	* libelfP.h (struct Elf_Scn): Add zdata_size and zdata_align.
+	(__libelf_decompress_elf): New internal function definition.
+
+2015-10-21  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libelf_a_SOURCES): Add elf_compress.c and
+	elf_compress_gnu.c.
+	* elf_compress.c: New file.
+	* elf_compress_gnu.c: Likewise.
+	* elf_begin.c (file_read_elf): Make a writable copy of the shdrs
+	for ELF_C_READ_MMAP.
+	* elf_end.c (elf_end): Free zdata_base.
+	* elf_error.c: Add ELF_E_ALREADY_COMPRESSED,
+	ELF_E_UNKNOWN_COMPRESSION_TYPE, ELF_E_COMPRESS_ERROR and
+	ELF_E_DECOMPRESS_ERROR.
+	* elf_data.c (__libelf_data_type): New internal function extracted
+	from convert_data.
+	(convert_data): Handle SHF_COMPRESSED.
+	* elf32_updatenull.c (updatenull_wrlock): Check sh_entsize against
+	uncompressed section data size if SHF_COMPRESSED.
+	* elf32_getshdr.c (load_shdr_wrlock): Adjust assert to account for
+	ELF_C_READ_MMAP.
+	* libelf.h: Define elf_compress and elf_compress_gnu.
+	* libelf.map (ELFUTILS_1.7): Add elf_compress and elf_compress_gnu.
+	* libelfP.h: Add ELF_E_ALREADY_COMPRESSED,
+	ELF_E_UNKNOWN_COMPRESSION_TYPE, ELF_E_COMPRESS_ERROR and
+	ELF_E_DECOMPRESS_ERROR. Define __libelf_data_type.
+	(__libelf_compress): New internal function definition.
+	(__libelf_decompress): Likewise.
+	(__libelf_reset_rawdata): Likewise.
+	(__libelf_data_type): Likewise.
+	(struct Elf_Scn): Add zdata_base.
+
+2015-11-19  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libelf_a_SOURCES): Add elf32_getchdr.c,
+	elf64_getchdr.c and gelf_getchdr.c.
+	(noinst_HEADERS): Add chdr_xlate.h.
+	* abstract.h: Define Chdr32 and Chdr64.
+	* chdr_xlate.h: New file.
+	* elf32_getchdr.c: New file.
+	* elf64_getchdr.c: New file.
+	* elf_error.c: Add ELF_E_NOT_COMPRESSED, ELF_E_INVALID_SECTION_TYPE
+	and ELF_E_INVALID_SECTION_FLAGS.
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Set d_type to
+	ELF_T_CHDR for SHF_COMPRESSED sections.
+	* exttypes.h: Add Chdr32 and Chdr64.
+	* gelf.h (GElf_Chdr): New typedef.
+	(gelf_getchdr): New function definition.
+	* gelf_fsize.c (__libelf_type_sizes): Add ELF_T_CHDR.
+	* gelf_getchdr.c: New file.
+	* gelf_xlate.c (__elf_xfctstom): Add ELF_T_CHDR cvt_chdr.
+	* gelf_xlate.h: Add Chdr.
+	* libelf.h (Elf_Type): Add ELF_T_CHDR.
+	(elf32_getchdr): New function definition.
+	(elf64_getchdr): Likewise.
+	* libelf.map (ELFUTILS_1.7): New sections add elf32_getchdr,
+	elf64_getchdr and gelf_getchdr.
+	* libelfP.h: Add ELF_E_NOT_COMPRESSED, ELF_E_INVALID_SECTION_TYPE
+	and ELF_E_INVALID_SECTION_FLAGS.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libelf_so_LDLIBS): Add -lz.
+
+2015-10-14  Mark Wielaard  <mjw@redhat.com>
+
+	* elf.h: Update from glibc. Add section compression constants and
+	structures.
+
+2015-10-20  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* elf_begin.c (get_shnum): Elf64_Shdr.sh_size is an Elf64_Xword.
+	Fix the size argument to pread_retry.
+
+2015-10-13  Chih-Hung Hsieh  <chh@google.com>
+
+	* elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Move nested
+	function 'fill_mmap' to file scope.
+	* elf_begin.c (elf_begin): Move nested function 'lock_dup_elf'
+	to file scope.
+
+2015-10-09  Josh Stone  <jistone@redhat.com>
+
+	* libelf.h: Replace loff_t with int64_t throughout.
+
+2015-10-05  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_update.c (write_file): Only use posix_fallocate when using
+	mmap. Only report failure when errno is ENOSPC.
+
+2015-10-09  Josh Stone  <jistone@redhat.com>
+
+	* libelfP.h (struct Elf): Replace off64_t with off_t.
+	* elf_getdata_rawchunk.c (elf_getdata_rawchunk): Likewise.
+
+2015-10-05  Chih-Hung Hsieh <chh@google.com>
+
+	* elf_getarsym.c (elf_getarsym): Do not use
+	union of variable length arrays.
+
+2015-10-05  Josh Stone  <jistone@redhat.com>
+
+	* Makefile.am (libelf.so): Add AM_V_CCLD and AM_V_at silencers.
+
+2015-09-24  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* Makefile.am (AM_CFLAGS): Use -fPIC instead of -fpic to avoid
+	relocation overflows in some platforms.
+
+2015-09-29  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatenull.c (default_ehdr): Set e_version when EV_NONE.
+	(updatenull_wrlock): Always set e_shentsize.
+
+2015-09-23  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_getehdr.c (getehdr_wrlock): Mark as internal_function.
+	* elf32_getshdr.c (getshdr_rdlock): Likewise.
+	(getshdr_wrlock): Likewise.
+	* elf_error.c (__libelf_seterrno): Likewise.
+	* elf_getphdrnum.c (__elf_getphdrnum_rdlock): Likewise.
+	(__elf_getphdrnum_chk_rdlock): Likewise.
+	* elf_getshdrnum.c (__elf_getphdrnum_rdlock): Likewise.
+	(__elf_getphdrnum_chk_rdlock): Likewise.
+	* elf_getshdrnum.c (__elf_getshdrnum_rdlock): Likewise.
+	* elf_readall.c (__libelf_readall): Likewise.
+	* gelf_getehdr.c (__gelf_getehdr_rdlock): Likewise.
+
+2015-09-22  Mark Wielaard  <mjw@redhat.com>
+
+	* *.c: Remove old-style function definitions.
+
+2015-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* dl-hash.h: Update from glibc.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (updatefile): Always free shdr_data and scns
+	when allocated on failure paths.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* nlist.c (nlist): Check symscn shdr exists before use.
+
+2015-06-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_update.c (write_file): Always also use ftruncate before
+	posix_fallocate to make sure file has the right size.
+
+2015-06-04  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (__libelf_type_aligns): Add entries for ELF_T_EHDR,
+	ELF_T_OFF, ELF_T_PHDR, ELF_T_SHDR, ELF_T_SWORD, ELF_T_XWORD,
+	ELF_T_SXWORD, ELF_T_GNUHASH, ELF_T_AUXV.
+	* elf_getdata_rawchunk.c (elf_getdata_rawchunk): Check alignment
+	of rawdata against requested type.
+
+2015-06-02  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (convert_data): Make sure source data is properly
+	aligned for type before calling actual conversion function.
+
+2015-06-04  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (get_shnum): Check alignment of Shdr, not Ehdr before
+	direct access.
+
+2015-06-02  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (file_read_elf): Split checks for ehdr and shdr
+	alignment, drop phdr alignment check.
+
+2015-05-31  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_getshdr.c (load_shdr_wrlock): Allocate shdrs with malloc,
+	not alloca and free after conversion when a copy needs to be made.
+
+2015-05-31  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_getphdr.c (getphdr_wrlock): Allocate phdrs with malloc, not
+	alloca and free after conversion when a copy needs to be made.
+
+2015-05-31  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getarsym.c (elf_getarsym): Allocate temporary file_date with
+	malloc, not alloca also in !ALLOW_UNALIGNED case.
+
+2015-05-30  Mark Wielaard  <mjw@redhat.com>
+
+	* gelf_xlate.c (elf_cvt_Byte): Only call memmove with non-zero size.
+
+2015-05-30  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Only call mempcpy and update
+	last_position when d_size is non-zero.
+
+2015-05-17  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (updatefile): Allocate shdr_data and scns
+	with malloc, not alloca. Free after writing section headers.
+
+2015-05-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Allocate temporary shdr storage
+	with malloc, not alloca. Free after writing section header.
+
+2015-05-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getarsym.c (elf_getarsym): Allocate temporary file_date with
+	malloc, not alloca. Call free after out.
+
+2015-05-14  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_update.c (write_file): Use posix_fallocate instead of
+	ftruncate to extend file if necessary.
+
+2015-05-13  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatenull.c (default_ehdr): If e_phnum is zero then set
+	e_phoff also to zero.
+
+2015-05-12  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatenull.c (updatenull_wrlock): Check that sh_addralign
+	is a powerof2.
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Clamp large d_aligns
+	to the elf image offset.
+
+2015-05-12  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_newphdr.c (newphdr): Call __libelf_seterrno with
+	ELF_E_INVALID_INDEX before failing. Check whether section zero shdr
+	actually exists if we need to put extended phnum in section zero.
+
+2015-05-08  Mark Wielaard  <mjw@redhat.com>
+
+	* nlist.c (nlist): Call gelf_fsize with EV_CURRENT.
+
+2015-01-03  Mark Wielaard  <mjw@redhat.com>
+
+	* version_xlate.h (elf_cvt_Verdef): Use memmove to copy src to dest.
+	(elf_cvt_Verneed): Likewise.
+
+2015-03-28  Mark Wielaard  <mjw@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2015-03-23  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatenull.c (updatenull_wrlock): Don't extend size with
+	SHT_NOBITS sh_offset.
+
+2015-02-18  Mark Wielaard  <mjw@redhat.com>
+
+	* libelfP.h (__libelf_set_data_list_rdlock): Make internal_function.
+
+2015-02-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* elf32_updatenull.c (__elfw2(LIBELFBITS,updatenull_wrlock)): Consider
+	sh_addralign 0 as 1.
+
+2015-01-22  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_strptr (elf_strptr): Make sure returned string is NUL
+	terminated.
+
+2015-01-21  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_strptr.c (elf_strptr): Check data_list_rear == NULL instead
+	of rawdata_base != NULL before using rawdata directly.
+
+2015-01-20  Mark Wielaard  <mjw@redhat.com>
+
+	* libelfP.h (__elf_strptr_internal): New function declaration.
+	* elf_getdata.c (__libelf_set_data_list_rdlock): New internal
+	function extracted from...
+	(__elf_getdata_rdlock): ... here.
+	* elf_newdata.c (elf_newdata): Check scn->rawdata_base and update
+	datalist if necessary.
+
+2015-01-20  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_strptr.c (elf_strptr): Call __elf[32|64]_getshdr_rdlock if
+	necessary.
+
+2014-12-30  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getphdrnum.c (__elf_getphdrnum_chk_rdlock): New function.
+	(elf_getphdrnum): Call __elf_getphdrnum_chk_rdlock.
+	* gelf_getphdr (gelf_getphdr): Call __elf_getphdrnum_chk_rdlock
+	and always check ndx against phnum.
+	* libelfP.h (__elf_getphdrnum_chk_rdlock): New internal function.
+
+2014-12-25  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (__libelf_next_arhdr_wrlock): ar_size cannot be
+	negative. Include start_offset in maxsize.
+
+2014-12-28  Alexander Cherepanov  <cherepan@mccme.ru>
+
+	* elf_begin.c (read_long_names): Don't miss '/' right after
+	another '/'. Fixes a dir traversal vuln in ar extraction.
+
+2014-12-18  Ulrich Drepper  <drepper@gmail.com>
+
+	* Makefile.am: Suppress output of textrel_check command.
+
+2014-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (read_long_names): Make sure long_names len fits
+	in mapped ELF file.
+
+2014-12-15  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getarsym.c (elf_getarsym): Check index_size doesn't overflow.
+
+2014-12-15  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (read_long_names): Clear any garbage left in the
+	name table.
+
+2014-12-11  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (file_read_elf): Correct ELF64 section offset check.
+
+2014-12-11  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (read_long_names): Check for offset overflow.
+	(__libelf_next_arhdr_wrlock): Likewise. Sanity check the ar_size.
+	Don't allow it to go beyond end of file.
+
+2014-12-09  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getarsym.c (elf_getarsym): Make sure n * w doesn't overflow.
+
+2014-11-27  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libelf.so): Use textrel_check.
+
+2014-11-23  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata_rawchunk.c (elf_getdata_rawchunk): Change signed
+	overflow check to unsigned.
+
+2014-11-23  Mark Wielaard  <mjw@redhat.com>
+
+	* note_xlate.h (elf_cvt_note): Copy over any leftover data if
+	src != dest. The data is probably part of truncated name/desc.
+
+2014-11-22  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getphdrnum.c (elf_getphdrnum): Sanity check the
+	__elf_getphdrnum_rdlock result.
+
+2014-11-18  Mark Wielaard  <mjw@redhat.com>
+
+	* version_xlate.h (elf_cvt_Verdef): Check for overflow.
+	(elf_cvt_Verneed): Likewise.
+
+2014-11-17  Mark Wielaard  <mjw@redhat.com>
+
+	* elf-knowledge.h (SECTION_STRIP_P): Check name is not NULL.
+
+2014-11-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getshdrstrndx.c: Check there are section headers before
+	handling SHN_XINDEX.
+
+2014-11-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_getphdr.c (getphdr_wrlock): Check e_phoff isn't zero.
+	Check for too many pheaders.
+	* elf_getphdrnum.c (__elf_getphdrnum_rdlock): Check section zero
+	actually exists before handling PN_XNUM.
+
+2014-11-16  Mark Wielaard  <mjw@redhat.com>
+
+	* gelf_getnote.c (gelf_getnote): Check padding overflow.
+
+2014-11-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Declare offset, size
+	and align as Elf64_Off and Elf64_Xword not size_t.
+
+2014-11-14  Mark Wielaard  <mjw@redhat.com>
+
+	* gelf_getnote.c (gelf_getnote): Check offset overflow.
+
+2014-11-13  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Fix unsigned overflow
+	check.
+
+2014-11-08  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (__libelf_next_arhdr_wrlock): Use mempcpy not __mempcpy.
+
+2014-11-07  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_begin.c (file_read_elf): Correct sh_size check.
+	* elf_getdata.c (__libelf_set_rawdata_wrlock): Check for unsigned
+	overflow.
+
+2014-09-10  Petr Machata  <pmachata@redhat.com>
+
+	* elf_begin (read_unmmaped_file): Call __libelf_seterrno if the
+	file is unreadable.
+
+2014-07-07  Mark Wielaard  <mjw@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2014-04-13  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Remove !MUDFLAP conditions.
+	* elf_begin.c (read_file): Don't clear use_mmap when _MUDFLAP is
+	defined.
+	* elf_update.c (write_file): Remove _MUDFLAP condition.
+
+2014-01-17  Jakub Jelinek  <jakub@redhat.com>
+	    Roland McGrath  <roland@redhat.com>
+
+	* libelfP.h (INVALID_NDX): Define.
+	* gelf_getdyn.c (gelf_getdyn): Use it.  Remove ndx < 0 test if any.
+	* gelf_getlib.c (gelf_getlib): Likewise.
+	* gelf_getmove.c (gelf_getmove): Likewise.
+	* gelf_getrel.c (gelf_getrel): Likewise.
+	* gelf_getrela.c (gelf_getrela): Likewise.
+	* gelf_getsym.c (gelf_getsym): Likewise.
+	* gelf_getsyminfo.c (gelf_getsyminfo): Likewise.
+	* gelf_getsymshndx.c (gelf_getsymshndx): Likewise.
+	* gelf_getversym.c (gelf_getversym): Likewise.
+	* gelf_update_dyn.c (gelf_update_dyn): Likewise.
+	* gelf_update_lib.c (gelf_update_lib): Likewise.
+	* gelf_update_move.c (gelf_update_move): Likewise.
+	* gelf_update_rel.c (gelf_update_rel): Likewise.
+	* gelf_update_rela.c (gelf_update_rela): Likewise.
+	* gelf_update_sym.c (gelf_update_sym): Likewise.
+	* gelf_update_syminfo.c (gelf_update_syminfo): Likewise.
+	* gelf_update_symshndx.c (gelf_update_symshndx): Likewise.
+	* gelf_update_versym.c (gelf_update_versym): Likewise.
+
+2014-01-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* elf32_getphdr.c (elfw2(LIBELFBITS,getphdr)): Check if program header
+	table fits into object's bounds.
+	* elf_getshdrstrndx.c (elf_getshstrndx): Add elf->start_offset to
+	elf->map_address.  Check if first section header fits into object's
+	bounds.
+	* elf32_getshdr.c (elfw2(LIBELFBITS,getshdr)):
+	Check if section header table fits into object's bounds.
+	* elf_begin.c (get_shnum): Ensure section headers fits into
+	object's bounds.
+	(file_read_elf): Make sure scncnt is small enough to allocate both
+	ElfXX_Shdr and Elf_Scn array.  Make sure section and program header
+	tables fit into object's bounds.  Avoid memory leak on failure.
+	* elf_newscn.c (elf_newscn): Check for overflow.
+	* elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Likewise.
+	(__elfw2(LIBELFBITS,updatefile)): Likewise.
+	* elf32_newphdr.c (elfw2(LIBELFBITS,newphdr)): Likewise.
+	* elf_getarsym.c (elf_getarsym): Likewise.
+
+2013-11-08  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (elfXX_updatemmap): Only memcpy ehdr when not
+	already directly mmapped.
+
+2013-11-05  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_updatefile.c (elfXX_updatefile): Copy all section headers
+	if elf->flags dirty.
+
+2013-11-01  Michael Forney  <mforney@mforney.org>
+
+	* Makefile.am: Use READELF.
+
+2013-10-01  Petr Machata  <pmachata@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2013-06-17  Petr Machata  <pmachata@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2013-08-28  Namhyung Kim  <namhyung@gmail.com>
+
+	* gelf.h (gelf_fsize): Fix typo in comment.
+
+2013-08-28  Mark Wielaard  <mjw@redhat.com>
+
+	* gelf_getauxv.c (gelf_getauxv): Add missing whitespace.
+
+2013-08-27  Mark Wielaard  <mjw@redhat.com>
+
+	* gelf_getauxv.c (gelf_getauxv): Remove unnecessary casts to char *.
+
+2013-08-25  Kurt Roeckx  <kurt@roeckx.be>
+
+	* gelf_getauxv.c (gelf_getauxv): Use memcpy instead of pointer
+	dereference to avoid alignment problems.
+
+2013-01-07  Roland McGrath  <roland@hack.frob.com>
+
+	* elf_getarsym.c (elf_getarsym): Copy FILE_DATA into stack space if it
+	would be unaligned and !ALLOW_UNALIGNED.
+
+	* elf_getarsym.c (read_number_entries): Use memcpy instead of pointer
+	dereference so as not to assume the field is naturally aligned.
+
+2012-09-17  Petr Machata  <pmachata@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2012-08-16  Roland McGrath  <roland@hack.frob.com>
+
+	* elf.h: Update from glibc.
+
+2012-08-14  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_checksum.c (ebl_debugscn_p): Removed unused define and
+	confusing outdated comment.
+
+2012-08-01  Petr Machata  <pmachata@redhat.com>
+
+	* elf_getarsym (read_number_entries): New function.
+	(elf_getarsym): Handle 64-bit symbol table, stored in special
+	entry named "/SYM64/".
+	* elf_begin.c (__libelf_next_arhdr_wrlock): Don't reject archive
+	because it contains 64-bit symbol table.
+
+2012-07-19  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_getshdr.c (load_shdr_wrlock): Add elf->flags & ELF_F_MALLOCED
+	to asserts.
+
+2012-07-17  Petr Machata  <pmachata@redhat.com>
+
+	* elf32_xlatetom.c (elfw2(LIBELFBITS, xlatetom)): Do not check for
+	integer number of records in case of ELF_T_NHDR.
+
+2012-04-02  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32_offscn.c: Do not match SHT_NOBITS sections at OFFSET unless
+	there are no nonempty sections at that offset.
+
+2012-03-21  Roland McGrath  <roland@hack.frob.com>
+
+	* elf-knowledge.h (SECTION_STRIP_P): Remove < SHT_NUM check.
+
+2011-02-26  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_end.c (elf_end): Call rwlock_unlock before rwlock_fini.
+
+2011-01-05  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* elf_getdata_rawchunk.c (elf_getdata_rawchunk): Fix off64_t overflow
+	when MAXIMUM_SIZE == ~0.
+
+2010-08-18  Roland McGrath  <roland@redhat.com>
+
+	* gelf_fsize.c (__libelf_type_sizes): Add entries for ELF_T_LIB
+	and ELF_T_GNUHASH.
+	Reported by Mark Hatle <mark.hatle@windriver.com>.
+
+	* exttypes.h: Add cases for ElfNN_Lib.
+	Reported by Mark Hatle <mark.hatle@windriver.com>.
+
+2010-06-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* gelf_update_shdr.c: Implicitly set ELF_F_DIRTY bit.
+	* gelf_update_phdr.c: Likewise.
+	* gelf_update_ehdr.c: Likewise.
+
+2010-04-14  Roland McGrath  <roland@redhat.com>
+
+	* elf32_getphdr.c: Check for e_phoff/size outside the file bounds.
+	* elf_begin.c (file_read_elf): Don't set .phdr here.
+
+2010-04-13  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2010-04-06  Roland McGrath  <roland@redhat.com>
+
+	* elf_error.c (ELF_E_FD_MISMATCH_IDX): Avoid nonobvious abbreviation
+	in error message.
+
+2010-04-01  Petr Machata  <pmachata@redhat.com>
+
+	* elf_getdata.c (__elf_getdata_rdlock): Initialize data.s for data
+	that do not need a conversion.
+
+2010-03-11  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2010-03-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2010-02-17  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (file_read_elf): Leave section rawdata_base and
+	data_base pointers null when [sh_offset,sh_size) points outside
+	the mapped file.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Use config/eu.am for common stuff.
+
+2010-01-07  Roland McGrath  <roland@redhat.com>
+
+	* elf32_getphdr.c: Use __elf_getphdrnum_rdlock.
+	* gelf_getphdr.c: Likewise.
+	* gelf_update_phdr.c: Likewise.
+	* elf32_updatefile.c (__elf32_updatemmap, __elf32_updatefile): Likewise.
+	* elf32_updatenull.c (__elf32_updatenull_wrlock): Likewise.
+	* elf32_newphdr.c: Clear section 0's sh_info when resetting e_phnum.
+	If COUNT is too large, use store PN_XNUM instead and set sh_info.
+	* elf_begin.c (file_read_elf): Always allocate space we can use later
+	for section 0 if doing RDWR.
+
+	* elf_getphdrnum.c: New file.
+	* Makefile.am (libelf_a_SOURCES): Add it.
+	* libelf.h: Declare elf_getphdrnum.
+	* libelfP.h: Declare __elf_getphdrnum_rdlock.
+	* libelf.map (ELFUTILS_1.6): New set, add elf_getphdrnum.
+
+	* elf.h: Update from glibc.
+
+2009-10-23  Lubomir Rintel  <lkundrak@v3.sk>
+
+	* elf32_updatefile.c (fill_mmap): When starting past shdr_end, start
+	filling from section start, not shdr_end.
+
+2009-11-10  Roland McGrath  <roland@redhat.com>
+
+	* elf_readall.c (__libelf_readall): Fetch file size if not yet known.
+
+2009-11-06  Mark Wielaard  <mjw@redhat.com>
+
+	* elf_next.c (elf_next): Mark the archive header as unusable when
+	there is no next ar element.
+
+2009-08-12  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (libelf.so): Use -Wl,-z,defs not -defs.
+
+2009-07-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2009-07-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (__elfXX_updatemmap): Fix handling of gaps between
+	sections.  Patch by Lubomir Rintel <lkundrak@v3.sk>.
+
+2009-07-08  Roland McGrath  <roland@redhat.com>
+
+	* libelfP.h (struct Elf): Remove unused ar.has_index field.
+	Reorder various members for optimal packing.
+
+2009-07-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2009-06-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (libelf_a_SOURCES): Replace elf_getshnum.c and
+	elf_getshstrndx.c with elf_getshdrnum.c and elf_getshdrstrndx.c.
+	* elf_getshnum.c: Renamed to...
+	* elf_getshdrnum.c: ...this.  Rename function and add old name as
+	alias.  Likewise for internal functions with derived names.
+	* elf_getshstrndx.c: Renamed to...
+	* elf_getshdrstrndx.c: ...this.  Rename function and add old name as
+	alias.  Likewise for internal functions with derived names.
+	* libelf.h: Add prototypes for new names.  Make old names as
+	deprecated.
+	* libelfP.h: Rename internal function prototypes.
+	* libelf.map: Export for names.
+	* elf32_checksum.c: Don't use deprecated functions.
+	* elf32_getshdr.c: Likewise.
+
+2009-06-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2009-04-14  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2009-04-01  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2009-02-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (updatefile): For the zeroth section we still
+	have to copy the section header.
+
+2009-02-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_strptr.c: Add comment re possible problem.
+
+2009-01-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatenull.c (updatenull_wrlock): Fix comment of
+	ELF_F_LAYOUT behaviour re section header table.
+
+2009-01-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (__elfXX_updatemmap): Fill the gap between
+	sections even if only the section at the start of the gap has been
+	changed.
+	(__elfXX_updatefile): Likewise.
+
+2009-01-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (__elfXX_updatemmap): Skip most of the loop to
+	handle sections for NOBITS sections.
+	(elfXX_updatefile): Likewise.
+
+	* elf32_updatefile.c (__elfXX_updatemmap): When skipping non-NOBITS
+	sections we haven't loaded, update last_position based on scn_start,
+	not based on old value.  Don't run the loop for the dummy section 0.
+	(elfXX_updatefile): Don't run the loop for the dummy section 0.
+
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* libelfP.h (_): We only have one translation domain, elfutils.
+
+	* Makefile.am: Use USE_LOCKS instead of USE_TLS.
+	* elf_error.c: Always use __thread.  Remove all !USE_TLS code.
+
+2009-01-04  Roland McGrath  <roland@redhat.com>
+
+	* note_xlate.h (elf_cvt_note): Don't examine a size too small to
+	container a note header.
+
+2008-12-11  Roland McGrath  <roland@redhat.com>
+
+	* elf32_updatefile.c (__elfw2(LIBELFBITS,updatemmap)): Handle
+	placement offset going backwards, for out-of-order or overlapping
+	(bogus) sh_offset layouts.  It's a dumb use, but should not crash.
+	(__elfw2(LIBELFBITS,updatefile)): Likewise.
+	Fixes RHBZ#476136.
+
+	* libelf.h (Elf_Data): Whitespace fix.
+
+2008-12-10  Roland McGrath  <roland@redhat.com>
+
+	* elf_getarhdr.c (elf_getarhdr): Fix missing rename in last change.
+
+2008-10-22  Petr Machata  <pmachata@redhat.com>
+
+	* elf_rawfile.c (elf_rawfile): Lock around elf-> references.
+
+2008-10-21  Petr Machata  <pmachata@redhat.com>
+
+	* libelfP.h: Rename getehdr_rdlock to getehdr_wrlock.
+	* elf32_getehdr.c (getehdr_rdlock): Move the code to new function
+	getehdr_impl and make it a wrapper.  Rename to getehdr_wrlock.
+	(getehdr_impl): Guard elf->class init with wrlock.
+	(getehdr): Also make it a wrapper of getehdr_impl.
+	* elf32_updatenull.c (updatenull_wrlock): Call getehdr_wrlock.
+
+2008-10-20  Petr Machata  <pmachata@redhat.com>
+
+	* elf_getdata_rawchunk.c (elf_getdata_rawchunk): Lock around the
+	code that reads mutable elf state.  Relock to write lock to chain
+	the new chunk on the elf rawchunks list.
+
+2008-10-20  Petr Machata  <pmachata@redhat.com>
+
+	* elf32_checksum.c (checksum): Place a lock around the code that
+	processes data.  Make it wrlock if the code needs to xlate the
+	data before processing.
+
+2008-10-16  Petr Machata  <pmachata@redhat.com>
+
+	* elf_begin.c
+	(__libelf_next_arhdr): Rename to __libelf_next_arhdr_wrlock.
+	(dup_elf): Adjust the call.
+	(elf_begin): New local function lock_dup_elf.  Relocks the elf if
+	necessary before calling dup.  Call this instead of dup_elf.
+	* elf_getarhdr.c
+	(elf_getarhdr): Lock before calling __libelf_next_arhdr_wrlock.
+	* elf_next.c (elf_next): Likewise.
+	* elf_rand.c (elf_rand): Likewise.
+
+2008-10-14  Petr Machata  <pmachata@redhat.com>
+
+	* elf_getdata.c (__elf_getdata_rdlock): Lock before converting.
+
+2008-11-26  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2008-10-06  Roland McGrath  <roland@redhat.com>
+
+	* elf_getarhdr.c (elf_getarhdr): Return NULL when passed NULL.
+
+2008-08-27  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (get_shnum): Avoid misaligned reads for matching endian.
+
+	* libelfP.h [!ALLOW_UNALIGNED] (__libelf_type_align): Fix CLASS index.
+
+2008-08-25  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (libelf_so_LDLIBS): New variable.
+	(libelf.so): Use it in the link.
+
+2008-08-21  Petr Machata  <pmachata@redhat.com>
+
+	* elf_getdata.c, libelfP.h
+	(__elf_getdata_internal): Rename to __elf_getdata_rdlock.
+	(__libelf_set_rawdata_wrlock): New function.
+	(__libelf_set_rawdata): Make it a wrapper that calls *_wrlock.
+	* elf32_updatenull.c, libelfP.h
+	(__elfNN_updatenull): Rename to __elfNN_updatenull_wrlock.
+
+2008-08-21  Petr Machata  <pmachata@redhat.com>
+
+	* elf32_getphdr.c, libelfP.h
+	(__elfNN_getphdr_internal): Drop.  Move __elfNN_getphdr_internal
+	code to __elfNN_getphdr_wrlock.
+	(__elfNN_getphdr_rdlock, __elfNN_getphdr_wrlock): New functions.
+	(__elfNN_getphdr_rdlock, __elfNN_getphdr_wrlock): Make these
+	wrappers of getphdr_impl.
+
+2008-08-21  Petr Machata  <pmachata@redhat.com>
+
+	* elf32_getehdr.c, libelfP.h
+	(__elfNN_getehdr_internal): Rename to __elfNN_getehdr_rdlock.
+	* gelf_getehdr, libelfP.h:
+	(__gelf_getehdr_internal): Rename to __gelf_getehdr_rdlock.
+
+2008-08-21  Petr Machata  <pmachata@redhat.com>
+
+	* elf32_getshdr.c
+	(__elfNN_getshdr_internal): Drop.
+	(load_shdr_wrlock, scn_valid): New functions, contain bits of
+	behaviour from __elfNN_getshdr_internal.
+	(__elfNN_getshdr_rdlock, __elfNN_getshdr_wrlock): Replacements for
+	dropped _internal functions above.
+	* elf_getshnum.c
+	(__elf_getshnum_internal): Rename to __elf_getshnum_rdlock.
+
+2008-08-04  Petr Machata  <pmachata@redhat.com>
+
+	* libelfP.h (RWLOCK_RDLOCK, RWLOCK_WRLOCK, RWLOCK_UNLOCK): New macros.
+
+2008-07-28  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2008-03-31  Roland McGrath  <roland@redhat.com>
+
+	* elf32_offscn.c: Make sure shdrs have been read in.
+
+2008-02-19  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2008-02-08  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2008-01-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_strptr.c (elf_strptr): Don't fail if the ELF file is currently
+	under construction and no raw data can be read from disk.
+
+2008-01-30  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2008-01-26  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (__libelf_next_arhdr): Rewrite conversions using a macro.
+	Fixes various pastos in wrong type in sizeof, wrong string parsed.
+
+2008-01-20  Roland McGrath  <roland@redhat.com>
+
+	* elf_getaroff.c: Calculate from start_offset, instead of using
+	parent's state.ar.offset field.
+
+2008-01-08  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (euinclude): Variable removed.
+	(pkginclude_HEADERS): Set this instead of euinclude_HEADERS.
+
+2008-01-03  Roland McGrath  <roland@redhat.com>
+
+	* common.h: Add __attribute__ ((unused)) to static functions.
+
+2007-12-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (libelf_a_SOURCES): Add elf_scnshndx.
+	* libelfP.h (struct Elf_Scn): Add shndx_index field.
+	Declare __elf_scnshndx_internal.
+	* elf32_getshdr.c: Record location of extended section header.
+	* elf_begin.c (file_read_elf): Likewise.
+	* elf_scnshndx.c: New file.
+	* libelf.h: Declare elf_scnshndx.
+	* libelf.map: Add elf_scnshndx to version ELFUTILS_1.4.
+
+2007-11-12  Roland McGrath  <roland@redhat.com>
+
+	* libelf.h: Replace off64_t with loff_t throughout.
+	Only that type name is unconditionally defined by <sys/types.h>
+
+2007-11-03  Roland McGrath  <roland@redhat.com>
+
+	* libelf.h (Elf_Data): Comment fix.
+
+2007-10-18  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2007-10-07  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (__libelf_next_arhdr): Fix fencepost error and wrong
+	member access in terminating name with no trailing /.  Trim trailing
+	spaces when there is no /.
+
+2007-10-04  Roland McGrath  <roland@redhat.com>
+
+	* elf_end.c (elf_end): Don't free ELF->state.ar.ar_sym when it's -1l.
+
+2007-10-03  Roland McGrath  <roland@redhat.com>
+
+	* libelf.h (Elf_Data): Use off64_t for d_off.
+	(Elf_Arhdr): Use off64_t for ar_size.
+	(elf_update, elf_getbase, elf_getaroff): Return off64_t.
+
+	* gelf_rawchunk.c: File removed.
+	* gelf_freechunk.c: File removed.
+	* Makefile.am (libelf_a_SOURCES): Remove them.
+	* libelf.map (ELFUTILS_1.0): Remove exports.
+	* gelf.h: Remove decls.
+
+	* elf_getdata_rawchunk.c: New file.
+	* Makefile.am (libelf_a_SOURCES): Add it.
+	* libelf.map (ELFUTILS_1.3): Add elf_getdata_rawchunk.
+	* libelf.h: Declare it.
+	* libelfP.h (Elf_Data_Chunk): New type.
+	(struct Elf.elf): New member `rawchunks'.
+	* elf_end.c (elf_end): Free recorded rawchunk buffers.
+
+2007-08-24  Roland McGrath  <roland@redhat.com>
+
+	* gelf_getnote.c: New file.
+	* Makefile.am (libelf_a_SOURCES): Add it.
+	* gelf.h: Declare gelf_getnote.
+	* libelf.map (ELFUTILS_1.3): Add gelf_getnote.
+
+	* libelfP.h (NOTE_ALIGN): New macro.
+	* note_xlate.h: New file.
+	* Makefile.am (noinst_HEADERS): Add it.
+	* gelf_xlate.c: Include it.
+	(__elf_xfctstom): Use elf_cvt_note.
+	* elf_getdata.c (shtype_map, __libelf_type_align): Handle SHT_NOTE.
+	(__libelf_set_rawdata): Likewise.
+
+2007-08-19  Roland McGrath  <roland@redhat.com>
+
+	* gelf_update_auxv.c: New file.
+	* gelf_getauxv.c: New file.
+	* Makefile.am (libelf_a_SOURCES): Add them.
+	* gelf.h: Declare gelf_getauxv, gelf_update_auxv.
+	* libelf.map (ELFUTILS_1.3): New set, inherits fom ELFUTILS_1.2.
+	Export gelf_getauxv, gelf_update_auxv.
+
+	* libelf.h (Elf_Type): Add ELF_T_AUXV.
+	* abstract.h: Add auxv_t entries.
+	* exttypes.h: Likewise.
+	* gelf_xlate.h: Likewise.
+	* gelf_xlate.c (__elf_xfctstom): Add ELF_T_AUXV entries.
+	* gelf_fsize.c (__libelf_type_sizes): Likewise.
+
+2007-08-12  Roland McGrath  <roland@redhat.com>
+
+	* elf32_updatefile.c (compare_sections): Sort secondarily on sh_size,
+	and only tertiarily on index.
+
+2007-07-09  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2007-04-22  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2007-03-18  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (get_shnum): Fix test for e_shoff being out of bounds.
+	Return zero when the section headers do not fit within MAXSIZE.
+
+2007-03-09  Roland McGrath  <roland@redhat.com>
+
+	* libelfP.h (LIBELF_EV_IDX): New macro.
+	(__libelf_type_align): New macro.
+	[! ALLOW_UNALIGNED]: Declare __libc_type_aligns array.
+	* elf_getdata.c (shtype_map): Convert to just Elf_Type[][].
+	(convert_data, __libelf_set_rawdata): Use that, __libelf_type_align,
+	and __libelf_type_sizes, in place of old table.
+	(__libc_type_aligns): New const variable.
+
+2007-02-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile (libelf.so): Build with -z relro.
+
+	* elf_begin.c (read_file): When using ELF_C_READ_MMAP use MAP_PRIVATE.
+
+2007-01-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* nlist.c: Close file descriptor before returning.
+
+2007-01-20  Roland McGrath  <roland@redhat.com>
+
+	* gnuhash_xlate.h (elf_cvt_gnuhash): Fix fence-post error so we
+	convert the final word.
+
+	* elf32_getshdr.c: Don't byteswap shdr fields when EI_DATA matches
+	MY_ELFDATA on !ALLOW_UNALIGNED machines.
+
+2007-01-18  Roland McGrath  <roland@redhat.com>
+
+	* gelf_rawchunk.c (gelf_rawchunk): Clear RESULT pointer after freeing
+	it on read error.
+
+2006-10-13  Roland McGrath  <roland@redhat.com>
+
+	* elf32_updatenull.c: Look for and accept phdr also for ET_CORE.
+	* elf_error.c (msgstr): Change ELF_E_INVALID_PHDR string.
+
+2006-08-29  Roland McGrath  <roland@redhat.com>
+
+	* elf32_getphdr.c: Don't byteswap phdr fields when EI_DATA matches
+	MY_ELFDATA on !ALLOW_UNALIGNED machines.
+	Reported by Christian Aichinger <Greek0@gmx.net>.
+
+	* Makefile.am (CLEANFILES): Add libelf.so.$(VERSION).
+
+2006-08-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h (DT_VALNUM): Update.
+	(DT_ADDRNUM): Likewise.
+
+2006-07-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c: Adjust for internal_function_def removal.
+	* elf32_updatenull.c: Likewise.
+	* elf_begin.c: Likewise.
+	* elf_getdata.c: Likewise.
+
+2006-07-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* libelf.h: Define ELF_T_GNUHASH.
+	* elf_getdata.c (TYPEIDX): Handle SHT_GNU_HASH.
+	(shtype_map): Add SHT_GNU_HASH entries.
+	* gelf_xlate.c (__elf_xfctstom): Add ELF_T_GNUHASH entries.
+	* gnuhash_xlate.h: New file.
+	* Makefile.am (noinst_HEADERS): Add gnuhash_xlate.h.
+
+2006-07-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_gnu_hash.c: New file.
+	* libelf.h: Declare elf_gnu_hash.
+	* Makefile.am (libelf_a_SOURCES): Add elf_gnu_hash.
+	* libelf.map: Add elf_gnu_map for version ELFUTILS_1.2.
+
+2006-06-15  Roland McGrath  <roland@redhat.com>
+
+	* libelf.h (elf_getarsym): Fix comment typo.
+	Rename second parameter to be more explanatory.
+	(elf_getident, elf_rawhide): Likewise.
+
+2006-05-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Preserve section content if
+	copying would overwrite them.
+	Fix msync paramters.
+
+2006-04-04  Roland McGrath  <roland@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Handle other-endian case.
+
+2006-04-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (updatemmap): Cleanups.  Remove shdr_dest
+	variable.  Before writing sections, make a copy of the section
+	header data if necessary.  Don't write section header while
+	writing the section constent, it might overwrite some sections.
+	Restore the pointer afterwards.
+	* elf32_updatenull.c (updatenull): If the offset of a section in a
+	file changed make sure we read the section so that it'll be written
+	out.
+
+	* elf_update.c: Remove debug message.
+
+2005-12-07  Roland McGrath  <roland@redhat.com>
+
+	* gelf_xlate.c [! ALLOW_UNALIGNED] (union unaligned): New type.
+	(FETCH, STORE): New macros.
+	(INLINE3): Use those to do alignment-friendly conversion.
+
+	* elf32_getshdr.c: Include map_address and start_offset in alignment
+	calculations.
+	* elf32_getphdr.c: Likewise.
+
+2005-11-19  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2005-11-17  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2005-11-10  Roland McGrath  <roland@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2005-09-09  Roland McGrath  <roland@redhat.com>
+
+	* elf_update.c (write_file): Stat the file and fchmod it after update
+	if its mode had S_ISUID or S_ISGID bits set.
+
+2005-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_getphdr.c: Include <system.h>.  Use pread_retry instead of
+	pread.  And branch prediction where useful.
+	* elf_begin.c: Likewise.
+	* elf_getdata.c: Likewise.
+	* elf_getshstrndx.c: Likewise.
+	* elf_readall.c: Likewise.
+	* gelf_rawchunk.c: Likewise.
+	* elf32_updatefile.c: Include <system.h>.  Use pread_retry instead of
+	pread.  And branch prediction where useful.
+	* elf_getarsym.c: Don't define pread_retry here.
+
+	* Makefile.am: Use $(LINK) not $(CC) when creating DSO.
+	(%.os): Use COMPILE.os.
+	(COMPILE.os): Filter out gconv options.
+
+2005-08-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_begin.c (file_read_elf): Avoid reading ELF header from file
+	again.  Instead accept additional parameter which points to it if we
+	don't use mmap.
+	(get_shnum): Use passed in e_ident value as source of ELF header.
+
+2005-08-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_begin.c (__libelf_next_arhdr): Use TEMP_FAILURE_RETRY.
+
+	* Makefile (libelf_a_SOURCES): Add elf_getaroff.c.
+	* libelf.map: Export elf_getaroff.
+	* libelf.h: Declare elf_getaroff.
+	* elf_getaroff.c: New file.
+
+2005-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_begin.c (get_shnum): Optimize memory handling.  Always read from
+	mapped file if available.  Fix access to 64-bit sh_size.  Recognize
+	overflow.
+	(file_read_elf): Likewise.
+
+2005-08-12  Roland McGrath  <roland@redhat.com>
+
+	* elf32_offscn.c: Do not match empty sections at OFFSET unless
+	there are no nonempty sections at that offset.
+
+2005-08-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2005-08-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (AM_CFLAGS): Add -fpic when BUILD_STATIC.
+
+2005-08-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* libelf.map: Move elf32_offscn, elf64_offscn, and gelf_offscn in
+	new version ELFUTILS_1.1.1.
+
+2005-08-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_error.c: Add handling of ELF_E_INVALID_OFFSET.
+	* elf32_offscn.c: New file.
+	* elf64_offscn.c: New file.
+	* gelf_offscn.c: New file.
+	* Makefile.am (libelf_a_SOURCES): Add elf32_offscn.c, elf64_offscn.c,
+	and gelf_offscn.c.
+	* libelf.sym: Export new symbols.
+
+2005-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf-knowledge.h (SECTION_STRIP_P): Don't handle removal of debug
+	sections here anymore.
+	* elf32_checksum.c: Adjust for change in SECTION_STRIP_P interface.
+
+	* elf_update.c (elf_update): Get write lock, not read lock.
+
+	* elf32_updatenull.c (updatenull): Get section headers if necessary
+	and possible.
+
+2005-07-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatenull.c (updatenull): If program header hasn't been loaded
+	yet, try to do it now.
+	Don't unnecessarily update overflow of section count in zeroth section
+	sh_size field.
+	If section content hasn't been read yet, do it before looking for the
+	block size.  If no section data present, infer size of section header.
+
+2005-05-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update again.
+
+2005-05-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2005-05-08  Roland McGrath  <roland@redhat.com>
+
+	* elf_begin.c (read_file) [_MUDFLAP]: Don't use mmap for now.
+	* elf_update.c (write_file) [_MUDFLAP]: Likewise.
+
+2005-03-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_checksum.c: Use INTUSE and INTDEF to avoid PLTs.
+	* elf_end.c: Likewise.
+	* elf_getdata.c: Likewise.
+	* gelf_getehdr.c: Likewise.
+	* nlist.c: Likewise.
+	* libelfP.h: Add declarations of internal functions.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* common.h (CONVERT): Make sure all values are unsigned.
+	(CONVERT_TO): Likewise.
+
+	* Makefile.am (AM_CFLAGS): Add -Wformat=2.
+	Fix rule to build libelf.so.
+
+2005-02-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Cleanup AM_CFLAGS handling.  Add -Wunused -Wextra.
+	Remove lint handling.
+	* elf32_getphdr.c: Minor cleanups.
+	* elf32_getshdr.c: Likewise.
+	* elf32_updatefile.c: Likewise.
+	* elf32_updatenull.c: Likewise.
+	* elf_begin.c: Likewise.
+	* elf_error.c: Likewise.
+	* elf_getarsym.c: Likewise.
+	* elf_getdata.c: Likewise.
+	* elf_update.c: Likewise.
+	* gelf_xlate.c: Likewise.
+
+2005-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Check for text relocations in constructed DSO.
+
+	* Makefile.am [MUDFLAP] (AM_CFLAGS): Add -Werror -fpic -fmudflap.
+
+2005-02-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* gelf_getehdr.c (gelf_getehdr): Slight optimization.
+
+	* elf32_checksum.c (checksum): Do not look at NOBITS sections.
+
+	* gelf.h: Add gelf_checksum prototype.
+
+2004-09-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_checksum.c: Make compile with gcc 4.0.
+	* elf32_updatefile.c: Likewise.
+	* elf32_updatenull.c: Likewise.
+	* elf_begin.c: Likewise.
+	* elf_error.c: Likewise.
+	* elf_getdata.c: Likewise.
+	* elf_getident.c: Likewise.
+
+2004-04-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Update from glibc.
+
+2004-01-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf_update.c: Fix locking.
+	* elf_clone.c: Likewise.
+
+	* libelf.h: Define ELF_T_LIB.
+	* gelf_getlib.c: New file.
+	* gelf_update_lib.c: New file.
+	* gelf.h: Declare the new functions.  Define GElf_Lib.
+	* abstract.h: Define Lib, Lib32, Lib64.
+	* gelf_xlate.c (__elf_xfctstom): Add ELF_T_LIB entry.
+	* gelf_xlate.h: Add entry for ElfXX_Lib.
+	* elf_getdata.c: Recognize SHT_GNU_LIBLIST as a known section type.
+	* libelf.map: Add new symbols to ELFUTILS_1.1.
+	* Makefile.am (libelf_a_SOURCES): Add gelf_getlib.c and
+	gelf_update_lib.c.
+
+2004-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support building with mudflap.
+
+	* gelf_xlate.c (INLINE3): Avoid using cast as lvalue.
+	* dl-hash.h (_dl_elf_hash): Likewise.
+
+2004-01-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf-knowledge.h: New file.  From libelf subdir.
+	* Makefile.am (euincludedir): Define.
+	(euinclude_HEADERS): Add elf-knowledge.h.
+
+2003-09-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf.h: Define some PT_IA_64_HP_* constants.
+
+2003-09-23  Jakub Jelinek  <jakub@redhat.com>
+
+	* libelfP.h (struct Elf): Move state.elf64.sizestr_offset after
+	state.elf64.scnincr to match state.elf{,32}.
+
+2003-08-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32_updatefile.c (__updatemmap): When writing back file where
+	some sections have not been read in, count their sizes based on
+	the section header.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* Moved to CVS archive.
diff --git a/third_party/elfutils/libelf/Makefile.am b/third_party/elfutils/libelf/Makefile.am
new file mode 100644
index 0000000..ddaeaa2
--- /dev/null
+++ b/third_party/elfutils/libelf/Makefile.am
@@ -0,0 +1,131 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 1996-2010, 2015 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file is free software; you can redistribute it and/or modify
+## it under the terms of either
+##
+##   * the GNU Lesser General Public License as published by the Free
+##     Software Foundation; either version 3 of the License, or (at
+##     your option) any later version
+##
+## or
+##
+##   * 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
+##
+## or both in parallel, as here.
+##
+## elfutils 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.
+##
+## You should have received copies of the GNU General Public License and
+## the GNU Lesser General Public License along with this program.  If
+## not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+if BUILD_STATIC
+AM_CFLAGS += $(fpic_CFLAGS)
+endif
+GCC_INCLUDE = -I$(shell $(CC) -print-file-name=include)
+VERSION = 1
+
+lib_LIBRARIES = libelf.a
+noinst_LIBRARIES = libelf_pic.a
+noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so)
+include_HEADERS = libelf.h gelf.h nlist.h
+
+pkginclude_HEADERS = elf-knowledge.h
+
+libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
+		   elf_begin.c elf_next.c elf_rand.c elf_end.c elf_kind.c \
+		   gelf_getclass.c elf_getbase.c elf_getident.c \
+		   elf32_fsize.c elf64_fsize.c gelf_fsize.c \
+		   elf32_xlatetof.c elf32_xlatetom.c elf64_xlatetof.c \
+		   elf64_xlatetom.c gelf_xlate.c \
+		   elf32_getehdr.c elf64_getehdr.c gelf_getehdr.c \
+		   elf32_newehdr.c elf64_newehdr.c gelf_newehdr.c \
+		   gelf_update_ehdr.c \
+		   elf32_getphdr.c elf64_getphdr.c gelf_getphdr.c \
+		   elf32_newphdr.c elf64_newphdr.c gelf_newphdr.c \
+		   gelf_update_phdr.c \
+		   elf_getarhdr.c elf_getarsym.c \
+		   elf_rawfile.c elf_readall.c elf_cntl.c \
+		   elf_getscn.c elf_nextscn.c elf_ndxscn.c elf_newscn.c \
+		   elf32_getshdr.c elf64_getshdr.c gelf_getshdr.c \
+		   gelf_update_shdr.c \
+		   elf_strptr.c elf_rawdata.c elf_getdata.c elf_newdata.c \
+		   elf_getdata_rawchunk.c \
+		   elf_flagelf.c elf_flagehdr.c elf_flagphdr.c elf_flagscn.c \
+		   elf_flagshdr.c elf_flagdata.c elf_memory.c \
+		   elf_update.c elf32_updatenull.c elf64_updatenull.c \
+		   elf32_updatefile.c elf64_updatefile.c \
+		   gelf_getsym.c gelf_update_sym.c \
+		   gelf_getversym.c gelf_getverneed.c gelf_getvernaux.c \
+		   gelf_getverdef.c gelf_getverdaux.c \
+		   gelf_getrel.c gelf_getrela.c \
+		   gelf_update_rel.c gelf_update_rela.c \
+		   gelf_getdyn.c gelf_update_dyn.c \
+		   gelf_getmove.c gelf_update_move.c \
+		   gelf_getsyminfo.c gelf_update_syminfo.c \
+		   gelf_getauxv.c gelf_update_auxv.c \
+		   gelf_getnote.c \
+		   gelf_xlatetof.c gelf_xlatetom.c \
+		   nlist.c \
+		   gelf_getsymshndx.c gelf_update_symshndx.c \
+		   gelf_update_versym.c gelf_update_verneed.c \
+		   gelf_update_vernaux.c gelf_update_verdef.c \
+		   gelf_update_verdaux.c \
+		   elf_getphdrnum.c elf_getshdrnum.c elf_getshdrstrndx.c \
+		   gelf_checksum.c elf32_checksum.c elf64_checksum.c \
+		   libelf_crc32.c libelf_next_prime.c \
+		   elf_clone.c \
+		   gelf_getlib.c gelf_update_lib.c \
+		   elf32_offscn.c elf64_offscn.c gelf_offscn.c \
+		   elf_getaroff.c \
+		   elf_gnu_hash.c \
+		   elf_scnshndx.c \
+		   elf32_getchdr.c elf64_getchdr.c gelf_getchdr.c \
+		   elf_compress.c elf_compress_gnu.c
+
+libelf_pic_a_SOURCES =
+am_libelf_pic_a_OBJECTS = $(libelf_a_SOURCES:.c=.os)
+
+libelf_so_DEPS = ../lib/libeu.a
+libelf_so_LDLIBS = $(libelf_so_DEPS) -lz
+if USE_LOCKS
+libelf_so_LDLIBS += -lpthread
+endif
+
+libelf_so_LIBS = libelf_pic.a
+libelf_so_SOURCES =
+libelf.so$(EXEEXT): $(srcdir)/libelf.map $(libelf_so_LIBS) $(libelf_so_DEPS)
+	$(AM_V_CCLD)$(LINK) $(dso_LDFLAGS) -o $@ \
+		-Wl,--soname,$@.$(VERSION) \
+		-Wl,--version-script,$<,--no-undefined \
+		-Wl,--whole-archive $(libelf_so_LIBS) -Wl,--no-whole-archive \
+		$(libelf_so_LDLIBS)
+	@$(textrel_check)
+	$(AM_V_at)ln -fs $@ $@.$(VERSION)
+
+install: install-am libelf.so
+	$(mkinstalldirs) $(DESTDIR)$(libdir)
+	$(INSTALL_PROGRAM) libelf.so $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so
+	ln -fs libelf-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libelf.so.$(VERSION)
+	ln -fs libelf.so.$(VERSION) $(DESTDIR)$(libdir)/libelf.so
+
+uninstall: uninstall-am
+	rm -f $(DESTDIR)$(libdir)/libelf-$(PACKAGE_VERSION).so
+	rm -f $(DESTDIR)$(libdir)/libelf.so.$(VERSION)
+	rm -f $(DESTDIR)$(libdir)/libelf.so
+
+noinst_HEADERS = elf.h abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \
+		 version_xlate.h gnuhash_xlate.h note_xlate.h dl-hash.h \
+		 chdr_xlate.h
+EXTRA_DIST = libelf.map
+
+CLEANFILES += $(am_libelf_pic_a_OBJECTS) libelf.so.$(VERSION)
diff --git a/third_party/elfutils/libelf/abstract.h b/third_party/elfutils/libelf/abstract.h
new file mode 100644
index 0000000..d4515f2
--- /dev/null
+++ b/third_party/elfutils/libelf/abstract.h
@@ -0,0 +1,330 @@
+/* Abstract description of component ELF types.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+/* ELF header.  */
+#define Ehdr(Bits, Ext) \
+START (Bits, Ehdr, Ext##Ehdr)						      \
+  TYPE_EXTRA (unsigned char e_ident[EI_NIDENT];)			      \
+  TYPE_XLATE (memmove (tdest->e_ident, tsrc->e_ident, EI_NIDENT);)	      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_type)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_machine)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), e_version)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Addr), e_entry)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Off), e_phoff)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Off), e_shoff)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), e_flags)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_ehsize)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_phentsize)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_phnum)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_shentsize)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_shnum)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), e_shstrndx)			      \
+END (Bits, Ext##Ehdr)
+
+#define Ehdr32(Ext) \
+  Ehdr(32, Ext)
+#define Ehdr64(Ext) \
+  Ehdr(64, Ext)
+
+
+/* Program header.  */
+#define Phdr32(Ext) \
+START (32, Phdr, Ext##Phdr)						      \
+  TYPE_NAME (ElfW2(32, Ext##Word), p_type)				      \
+  TYPE_NAME (ElfW2(32, Ext##Off), p_offset)				      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), p_vaddr)				      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), p_paddr)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), p_filesz)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), p_memsz)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), p_flags)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), p_align)				      \
+END (32, Ext##Phdr)
+#define Phdr64(Ext) \
+START (64, Phdr, Ext##Phdr)						      \
+  TYPE_NAME (ElfW2(64, Ext##Word), p_type)				      \
+  TYPE_NAME (ElfW2(64, Ext##Word), p_flags)				      \
+  TYPE_NAME (ElfW2(64, Ext##Off), p_offset)				      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), p_vaddr)				      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), p_paddr)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), p_filesz)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), p_memsz)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), p_align)				      \
+END (64, Ext##Phdr)
+
+
+/* Section header.  */
+#define Shdr32(Ext) \
+START (32, Shdr, Ext##Shdr)						      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_name)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_type)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_flags)				      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), sh_addr)				      \
+  TYPE_NAME (ElfW2(32, Ext##Off), sh_offset)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_size)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_link)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_info)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_addralign)			      \
+  TYPE_NAME (ElfW2(32, Ext##Word), sh_entsize)				      \
+END (32, Ext##Shdr)
+#define Shdr64(Ext) \
+START (64, Shdr, Ext##Shdr)						      \
+  TYPE_NAME (ElfW2(64, Ext##Word), sh_name)				      \
+  TYPE_NAME (ElfW2(64, Ext##Word), sh_type)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), sh_flags)				      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), sh_addr)				      \
+  TYPE_NAME (ElfW2(64, Ext##Off), sh_offset)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), sh_size)				      \
+  TYPE_NAME (ElfW2(64, Ext##Word), sh_link)				      \
+  TYPE_NAME (ElfW2(64, Ext##Word), sh_info)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), sh_addralign)			      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), sh_entsize)				      \
+END (64, Ext##Shdr)
+
+
+/* Symbol table.  */
+#define Sym32(Ext) \
+START (32, Sym, Ext##Sym)						      \
+  TYPE_NAME (ElfW2(32, Ext##Word), st_name)				      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), st_value)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), st_size)				      \
+  TYPE_EXTRA (unsigned char st_info;)					      \
+  TYPE_XLATE (tdest->st_info = tsrc->st_info;)				      \
+  TYPE_EXTRA (unsigned char st_other;)					      \
+  TYPE_XLATE (tdest->st_other = tsrc->st_other;)			      \
+  TYPE_NAME (ElfW2(32, Ext##Half), st_shndx)				      \
+END (32, Ext##Sym)
+#define Sym64(Ext) \
+START (64, Sym, Ext##Sym)						      \
+  TYPE_NAME (ElfW2(64, Ext##Word), st_name)				      \
+  TYPE_EXTRA (unsigned char st_info;)					      \
+  TYPE_XLATE (tdest->st_info = tsrc->st_info;)				      \
+  TYPE_EXTRA (unsigned char st_other;)					      \
+  TYPE_XLATE (tdest->st_other = tsrc->st_other;)			      \
+  TYPE_NAME (ElfW2(64, Ext##Half), st_shndx)				      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), st_value)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), st_size)				      \
+END (64, Ext##Sym)
+
+
+/* Relocation.  */
+#define Rel32(Ext) \
+START (32, Rel, Ext##Rel)						      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), r_offset)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), r_info)				      \
+END (32, Ext##Rel)
+#define Rel64(Ext) \
+START (64, Rel, Ext##Rel)						      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), r_offset)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), r_info)				      \
+END (64, Ext##Rel)
+
+#define Rela32(Ext) \
+START (32, Rela, Ext##Rela)						      \
+  TYPE_NAME (ElfW2(32, Ext##Addr), r_offset)				      \
+  TYPE_NAME (ElfW2(32, Ext##Word), r_info)				      \
+  TYPE_NAME (ElfW2(32, Ext##Sword), r_addend)				      \
+END (32, Ext##Rela)
+#define Rela64(Ext) \
+START (64, Rela, Ext##Rela)						      \
+  TYPE_NAME (ElfW2(64, Ext##Addr), r_offset)				      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), r_info)				      \
+  TYPE_NAME (ElfW2(64, Ext##Sxword), r_addend)				      \
+END (64, Ext##Rela)
+
+
+/* Note entry header.  */
+#define Note(Bits, Ext) \
+START (Bits, Nhdr, Ext##Nhdr)						      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), n_namesz)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), n_descsz)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), n_type)				      \
+END (Bits, Ext##Nhdr)
+
+#define Note32(Ext) \
+  Note (32, Ext)
+#define Note64(Ext) \
+  Note (64, Ext)
+
+
+/* Dynamic section data.  */
+#define Dyn32(Ext) \
+START (32, Dyn, Ext##Dyn)						      \
+  TYPE_NAME (ElfW2(32, Ext##Sword), d_tag)				      \
+  TYPE_EXTRA (union {)							      \
+  TYPE_EXTRA (ElfW2(32, Ext##Word) d_val;)				      \
+  TYPE_EXTRA (ElfW2(32, Ext##Addr) d_ptr;)				      \
+  TYPE_XLATE (Elf32_cvt_Addr1 (&tdest->d_un.d_val, &tsrc->d_un.d_val);)	      \
+  TYPE_EXTRA (ElfW2(32, Ext##Off) d_off;)				      \
+  TYPE_EXTRA (} d_un;)							      \
+END (32, Ext##Dyn)
+#define Dyn64(Ext) \
+START (64, Dyn, Ext##Dyn)						      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), d_tag)				      \
+  TYPE_EXTRA (union {)							      \
+  TYPE_EXTRA (ElfW2(64, Ext##Xword) d_val;)				      \
+  TYPE_EXTRA (ElfW2(64, Ext##Addr) d_ptr;)				      \
+  TYPE_XLATE (Elf64_cvt_Addr1 (&tdest->d_un.d_val, &tsrc->d_un.d_val);)	      \
+  TYPE_EXTRA (} d_un;)							      \
+END (64, Ext##Dyn)
+
+
+#ifndef GENERATE_CONVERSION
+/* Version definitions.  */
+# define Verdef(Bits, Ext) \
+START (Bits, Verdef, Ext##Verdef)					      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vd_version)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vd_flags)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vd_ndx)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vd_cnt)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vd_hash)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vd_aux)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vd_next)				      \
+END (Bits, Ext##Verdef)
+
+# define Verdef32(Ext) \
+  Verdef (32, Ext)
+# define Verdef64(Ext) \
+  Verdef (64, Ext)
+
+# define Verdaux(Bits, Ext) \
+START (Bits, Verdaux, Ext##Verdaux)					      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vda_name)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vda_next)				      \
+END (Bits, Ext##Verdaux)
+
+# define Verdaux32(Ext) \
+  Verdaux (32, Ext)
+# define Verdaux64(Ext) \
+  Verdaux (64, Ext)
+
+/* Required versions.  */
+# define Verneed(Bits, Ext) \
+START (Bits, Verneed, Ext##Verneed)					      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vn_version)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vn_cnt)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vn_file)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vn_aux)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vn_next)				      \
+END (Bits, Ext##Verneed)
+
+# define Verneed32(Ext) \
+  Verneed (32, Ext)
+# define Verneed64(Ext) \
+  Verneed (64, Ext)
+
+# define Vernaux(Bits, Ext) \
+START (Bits, Vernaux, Ext##Vernaux)					      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vna_hash)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vna_flags)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), vna_other)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vna_name)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), vna_next)				      \
+END (Bits, Ext##Vernaux)
+
+# define Vernaux32(Ext) \
+  Vernaux (32, Ext)
+# define Vernaux64(Ext) \
+  Vernaux (64, Ext)
+#endif
+
+/* Symbol information.  */
+#define Syminfo(Bits, Ext) \
+START (Bits, Syminfo, Ext##Syminfo)					      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), si_boundto)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), si_flags)				      \
+END (Bits, Ext##Syminfo)
+
+#define Syminfo32(Ext) \
+  Syminfo (32, Ext)
+#define Syminfo64(Ext) \
+  Syminfo (64, Ext)
+
+/* Move information.  */
+#define Move(Bits, Ext) \
+START (Bits, Move, Ext##Move)						      \
+  TYPE_NAME (ElfW2(Bits, Ext##Xword), m_value)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Xword), m_info)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Xword), m_poffset)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), m_repeat)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Half), m_stride)				      \
+END (Bits, Ext##Move)
+
+#define Move32(Ext) \
+  Move (32, Ext)
+#define Move64(Ext) \
+  Move (64, Ext)
+
+#define Lib(Bits, Ext) \
+START (Bits, Lib, Ext##Lib)						      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), l_name)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), l_time_stamp)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), l_checksum)			      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), l_version)				      \
+  TYPE_NAME (ElfW2(Bits, Ext##Word), l_flags)				      \
+END (Bits, Ext##Lib)
+
+#define Lib32(Ext) \
+  Lib (32, Ext)
+#define Lib64(Ext) \
+  Lib (64, Ext)
+
+#define auxv_t32(Ext) \
+START (32, auxv_t, Ext##auxv_t)						      \
+  TYPE_NAME (ElfW2(32, Ext##Word), a_type)				      \
+  TYPE_EXTRA (union {)							      \
+  TYPE_EXTRA (ElfW2(32, Ext##Word) a_val;)				      \
+  TYPE_XLATE (Elf32_cvt_Addr1 (&tdest->a_un.a_val, &tsrc->a_un.a_val);)	      \
+  TYPE_EXTRA (} a_un;)							      \
+END (32, Ext##auxv_t)
+#define auxv_t64(Ext) \
+START (64, auxv_t, Ext##auxv_t)						      \
+  TYPE_NAME (ElfW2(64, Ext##Xword), a_type)				      \
+  TYPE_EXTRA (union {)							      \
+  TYPE_EXTRA (ElfW2(64, Ext##Xword) a_val;)				      \
+  TYPE_XLATE (Elf64_cvt_Addr1 (&tdest->a_un.a_val, &tsrc->a_un.a_val);)	      \
+  TYPE_EXTRA (} a_un;)							      \
+END (64, Ext##auxv_t)
+
+/* Note that there is actual compression data right after the Chdr.
+   So we also have a separate conversion function for the whole
+   section.  */
+#define Chdr32(Ext) \
+START (32, Chdr, Ext##Chdr)						\
+  TYPE_NAME (ElfW2(32, Ext##Word), ch_type)				\
+  TYPE_NAME (ElfW2(32, Ext##Word), ch_size)				\
+  TYPE_NAME (ElfW2(32, Ext##Word), ch_addralign)			\
+END (32, Ext##Chdr)
+
+#define Chdr64(Ext) \
+START (64, Chdr, Ext##Chdr)						\
+  TYPE_NAME (ElfW2(64, Ext##Word), ch_type)				\
+  TYPE_NAME (ElfW2(64, Ext##Word), ch_reserved)				\
+  TYPE_NAME (ElfW2(64, Ext##Xword), ch_size)				\
+  TYPE_NAME (ElfW2(64, Ext##Xword), ch_addralign)			\
+END (64, Ext##Chdr)
diff --git a/third_party/elfutils/libelf/chdr_xlate.h b/third_party/elfutils/libelf/chdr_xlate.h
new file mode 100644
index 0000000..70782b4
--- /dev/null
+++ b/third_party/elfutils/libelf/chdr_xlate.h
@@ -0,0 +1,33 @@
+#include "common.h"
+
+/* These functions convert a while section, one Chdr plus compression data.  */
+
+static void
+Elf32_cvt_chdr (void *dest, const void *src, size_t len, int encode)
+{
+  if (len == 0)
+    return;
+
+  /* Move everything over, if necessary, we only need to xlate the
+     header, not the compressed data following it.  */
+  if (dest != src)
+    memmove (dest, src, len);
+
+  if (len >= sizeof (Elf32_Chdr))
+    Elf32_cvt_Chdr (dest, src, sizeof (Elf32_Chdr), encode);
+}
+
+static void
+Elf64_cvt_chdr (void *dest, const void *src, size_t len, int encode)
+{
+  if (len == 0)
+    return;
+
+  /* Move everything over, if necessary, we only need to xlate the
+     header, not the compressed data following it.  */
+  if (dest != src)
+    memmove (dest, src, len);
+
+  if (len >= sizeof (Elf64_Chdr))
+    Elf64_cvt_Chdr (dest, src, sizeof (Elf64_Chdr), encode);
+}
diff --git a/third_party/elfutils/libelf/common.h b/third_party/elfutils/libelf/common.h
new file mode 100644
index 0000000..744f1bb
--- /dev/null
+++ b/third_party/elfutils/libelf/common.h
@@ -0,0 +1,163 @@
+/* Common definitions for handling files in memory or only on disk.
+   Copyright (C) 1998, 1999, 2000, 2002, 2005, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _COMMON_H
+#define _COMMON_H       1
+
+#include <ar.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+static inline Elf_Kind
+__attribute__ ((unused))
+determine_kind (void *buf, size_t len)
+{
+  /* First test for an archive.  */
+  if (len >= SARMAG && memcmp (buf, ARMAG, SARMAG) == 0)
+    return ELF_K_AR;
+
+  /* Next try ELF files.  */
+  if (len >= EI_NIDENT && memcmp (buf, ELFMAG, SELFMAG) == 0)
+    {
+      /* Could be an ELF file.  */
+      int eclass = (int) ((unsigned char *) buf)[EI_CLASS];
+      int data = (int) ((unsigned char *) buf)[EI_DATA];
+      int version = (int) ((unsigned char *) buf)[EI_VERSION];
+
+      if (eclass > ELFCLASSNONE && eclass < ELFCLASSNUM
+	  && data > ELFDATANONE && data < ELFDATANUM
+	  && version > EV_NONE && version < EV_NUM)
+	return ELF_K_ELF;
+    }
+
+  /* We do not know this file type.  */
+  return ELF_K_NONE;
+}
+
+
+/* Allocate an Elf descriptor and fill in the generic information.  */
+static inline Elf *
+__attribute__ ((unused))
+allocate_elf (int fildes, void *map_address, off_t offset, size_t maxsize,
+              Elf_Cmd cmd, Elf *parent, Elf_Kind kind, size_t extra)
+{
+  Elf *result = (Elf *) calloc (1, sizeof (Elf) + extra);
+  if (result == NULL)
+    __libelf_seterrno (ELF_E_NOMEM);
+  else
+    {
+      result->kind = kind;
+      result->ref_count = 1;
+      result->cmd = cmd;
+      result->fildes = fildes;
+      result->start_offset = offset;
+      result->maximum_size = maxsize;
+      result->map_address = map_address;
+      result->parent = parent;
+
+      rwlock_init (result->lock);
+    }
+
+  return result;
+}
+
+
+/* Acquire lock for the descriptor and all children.  */
+static void
+__attribute__ ((unused))
+libelf_acquire_all (Elf *elf)
+{
+  rwlock_wrlock (elf->lock);
+
+  if (elf->kind == ELF_K_AR)
+    {
+      Elf *child = elf->state.ar.children;
+
+      while (child != NULL)
+	{
+	  if (child->ref_count != 0)
+	    libelf_acquire_all (child);
+	  child = child->next;
+	}
+    }
+}
+
+/* Release own lock and those of the children.  */
+static void
+__attribute__ ((unused))
+libelf_release_all (Elf *elf)
+{
+  if (elf->kind == ELF_K_AR)
+    {
+      Elf *child = elf->state.ar.children;
+
+      while (child != NULL)
+	{
+	  if (child->ref_count != 0)
+	    libelf_release_all (child);
+	  child = child->next;
+	}
+    }
+
+  rwlock_unlock (elf->lock);
+}
+
+
+/* Macro to convert endianess in place.  It determines the function it
+   has to use itself.  */
+#define CONVERT(Var) \
+  (Var) = (sizeof (Var) == 1						      \
+	   ? (unsigned char) (Var)					      \
+	   : (sizeof (Var) == 2						      \
+	      ? bswap_16 (Var)						      \
+	      : (sizeof (Var) == 4					      \
+		 ? bswap_32 (Var)					      \
+		 : bswap_64 (Var))))
+
+#define CONVERT_TO(Dst, Var) \
+  (Dst) = (sizeof (Var) == 1						      \
+	   ? (unsigned char) (Var)					      \
+	   : (sizeof (Var) == 2						      \
+	      ? bswap_16 (Var)						      \
+	      : (sizeof (Var) == 4					      \
+		 ? bswap_32 (Var)					      \
+		 : bswap_64 (Var))))
+
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define MY_ELFDATA	ELFDATA2LSB
+#else
+# define MY_ELFDATA	ELFDATA2MSB
+#endif
+
+#endif	/* common.h */
diff --git a/third_party/elfutils/libelf/dl-hash.h b/third_party/elfutils/libelf/dl-hash.h
new file mode 100644
index 0000000..6ee5d1a
--- /dev/null
+++ b/third_party/elfutils/libelf/dl-hash.h
@@ -0,0 +1,75 @@
+/* Compute hash value for given string according to ELF standard.
+   Copyright (C) 1995-2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _DL_HASH_H
+#define _DL_HASH_H	1
+
+
+/* This is the hashing function specified by the ELF ABI.  In the
+   first five operations no overflow is possible so we optimized it a
+   bit.  */
+static unsigned int
+__attribute__ ((unused))
+_dl_elf_hash (const char *name_arg)
+{
+  const unsigned char *name = (const unsigned char *) name_arg;
+  unsigned long int hash = *name;
+  if (hash != 0 && name[1] != '\0')
+    {
+      hash = (hash << 4) + name[1];
+      if (name[2] != '\0')
+	{
+	  hash = (hash << 4) + name[2];
+	  if (name[3] != '\0')
+	    {
+	      hash = (hash << 4) + name[3];
+	      if (name[4] != '\0')
+		{
+		  hash = (hash << 4) + name[4];
+		  name += 5;
+		  while (*name != '\0')
+		    {
+		      unsigned long int hi;
+		      hash = (hash << 4) + *name++;
+		      hi = hash & 0xf0000000;
+
+		      /* The algorithm specified in the ELF ABI is as
+			 follows:
+
+			 if (hi != 0)
+			   hash ^= hi >> 24;
+
+			 hash &= ~hi;
+
+			 But the following is equivalent and a lot
+			 faster, especially on modern processors.  */
+
+		      hash ^= hi >> 24;
+		    }
+
+		  /* Second part of the modified formula.  This
+		     operation can be lifted outside the loop.  */
+		  hash &= 0x0fffffff;
+		}
+	    }
+	}
+    }
+  return hash;
+}
+
+#endif /* dl-hash.h */
diff --git a/third_party/elfutils/libelf/elf-knowledge.h b/third_party/elfutils/libelf/elf-knowledge.h
new file mode 100644
index 0000000..64f5887
--- /dev/null
+++ b/third_party/elfutils/libelf/elf-knowledge.h
@@ -0,0 +1,80 @@
+/* Accumulation of various pieces of knowledge about ELF.
+   Copyright (C) 2000-2012, 2014, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ELF_KNOWLEDGE_H
+#define _ELF_KNOWLEDGE_H	1
+
+#include <stdbool.h>
+
+
+/* Test whether a section can be stripped or not.  */
+#define SECTION_STRIP_P(shdr, name, remove_comment) \
+  /* Sections which are allocated are not removed.  */			      \
+  (((shdr)->sh_flags & SHF_ALLOC) == 0					      \
+   /* We never remove .note sections.  */				      \
+   && (shdr)->sh_type != SHT_NOTE					      \
+   && (((shdr)->sh_type) != SHT_PROGBITS				      \
+       /* Never remove .gnu.warning.* sections.  */			      \
+       || (name != NULL							      \
+	   && strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) != 0\
+	   /* We remove .comment sections only if explicitly told to do so. */\
+	   && (remove_comment						      \
+	       || strcmp (name, ".comment") != 0))))
+
+
+/* Test whether `sh_info' field in section header contains a section
+   index.  There are two kinds of sections doing this:
+
+   - the sections containing relocation information reference in this
+     field the section to which the relocations apply;
+
+   - section with the SHF_INFO_LINK flag set to signal that `sh_info'
+     references a section.  This allows correct handling of unknown
+     sections.  */
+#define SH_INFO_LINK_P(Shdr) \
+  ((Shdr)->sh_type == SHT_REL || (Shdr)->sh_type == SHT_RELA		      \
+   || ((Shdr)->sh_flags & SHF_INFO_LINK) != 0)
+
+
+/* Size of an entry in the hash table.  The ELF specification says all
+   entries are regardless of platform 32-bits in size.  Early 64-bit
+   ports (namely Alpha for Linux) got this wrong.  The wording was not
+   clear.
+
+   Several years later the ABI for the 64-bit S390s was developed.
+   Many things were copied from the IA-64 ABI (which uses the correct
+   32-bit entry size) but what do these people do?  They use 64-bit
+   entries.  It is really shocking to see what kind of morons are out
+   there.  And even worse: they are allowed to design ABIs.  */
+#define SH_ENTSIZE_HASH(Ehdr) \
+  ((Ehdr)->e_machine == EM_ALPHA					      \
+   || ((Ehdr)->e_machine == EM_S390					      \
+       && (Ehdr)->e_ident[EI_CLASS] == ELFCLASS64) ? 8 : 4)
+
+#endif	/* elf-knowledge.h */
diff --git a/third_party/elfutils/libelf/elf.h b/third_party/elfutils/libelf/elf.h
new file mode 100644
index 0000000..84a7126
--- /dev/null
+++ b/third_party/elfutils/libelf/elf.h
@@ -0,0 +1,3778 @@
+/* This file defines standard ELF types, structures, and macros.
+   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ELF_H
+#define	_ELF_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Standard ELF types.  */
+
+#include <stdint.h>
+
+/* Type for a 16-bit quantity.  */
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+/* Types for signed and unsigned 32-bit quantities.  */
+typedef uint32_t Elf32_Word;
+typedef	int32_t  Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef	int32_t  Elf64_Sword;
+
+/* Types for signed and unsigned 64-bit quantities.  */
+typedef uint64_t Elf32_Xword;
+typedef	int64_t  Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef	int64_t  Elf64_Sxword;
+
+/* Type of addresses.  */
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+/* Type of file offsets.  */
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+/* Type for section indices, which are 16-bit quantities.  */
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+/* Type for version symbol information.  */
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+
+/* The ELF file header.  This appears at the start of every ELF file.  */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf32_Half	e_type;			/* Object file type */
+  Elf32_Half	e_machine;		/* Architecture */
+  Elf32_Word	e_version;		/* Object file version */
+  Elf32_Addr	e_entry;		/* Entry point virtual address */
+  Elf32_Off	e_phoff;		/* Program header table file offset */
+  Elf32_Off	e_shoff;		/* Section header table file offset */
+  Elf32_Word	e_flags;		/* Processor-specific flags */
+  Elf32_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf32_Half	e_phentsize;		/* Program header table entry size */
+  Elf32_Half	e_phnum;		/* Program header table entry count */
+  Elf32_Half	e_shentsize;		/* Section header table entry size */
+  Elf32_Half	e_shnum;		/* Section header table entry count */
+  Elf32_Half	e_shstrndx;		/* Section header string table index */
+} Elf32_Ehdr;
+
+typedef struct
+{
+  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
+  Elf64_Half	e_type;			/* Object file type */
+  Elf64_Half	e_machine;		/* Architecture */
+  Elf64_Word	e_version;		/* Object file version */
+  Elf64_Addr	e_entry;		/* Entry point virtual address */
+  Elf64_Off	e_phoff;		/* Program header table file offset */
+  Elf64_Off	e_shoff;		/* Section header table file offset */
+  Elf64_Word	e_flags;		/* Processor-specific flags */
+  Elf64_Half	e_ehsize;		/* ELF header size in bytes */
+  Elf64_Half	e_phentsize;		/* Program header table entry size */
+  Elf64_Half	e_phnum;		/* Program header table entry count */
+  Elf64_Half	e_shentsize;		/* Section header table entry size */
+  Elf64_Half	e_shnum;		/* Section header table entry count */
+  Elf64_Half	e_shstrndx;		/* Section header string table index */
+} Elf64_Ehdr;
+
+/* Fields in the e_ident array.  The EI_* macros are indices into the
+   array.  The macros under each EI_* macro are the values the byte
+   may have.  */
+
+#define EI_MAG0		0		/* File identification byte 0 index */
+#define ELFMAG0		0x7f		/* Magic number byte 0 */
+
+#define EI_MAG1		1		/* File identification byte 1 index */
+#define ELFMAG1		'E'		/* Magic number byte 1 */
+
+#define EI_MAG2		2		/* File identification byte 2 index */
+#define ELFMAG2		'L'		/* Magic number byte 2 */
+
+#define EI_MAG3		3		/* File identification byte 3 index */
+#define ELFMAG3		'F'		/* Magic number byte 3 */
+
+/* Conglomeration of the identification bytes, for easy testing as a word.  */
+#define	ELFMAG		"\177ELF"
+#define	SELFMAG		4
+
+#define EI_CLASS	4		/* File class byte index */
+#define ELFCLASSNONE	0		/* Invalid class */
+#define ELFCLASS32	1		/* 32-bit objects */
+#define ELFCLASS64	2		/* 64-bit objects */
+#define ELFCLASSNUM	3
+
+#define EI_DATA		5		/* Data encoding byte index */
+#define ELFDATANONE	0		/* Invalid data encoding */
+#define ELFDATA2LSB	1		/* 2's complement, little endian */
+#define ELFDATA2MSB	2		/* 2's complement, big endian */
+#define ELFDATANUM	3
+
+#define EI_VERSION	6		/* File version byte index */
+					/* Value must be EV_CURRENT */
+
+#define EI_OSABI	7		/* OS ABI identification */
+#define ELFOSABI_NONE		0	/* UNIX System V ABI */
+#define ELFOSABI_SYSV		0	/* Alias.  */
+#define ELFOSABI_HPUX		1	/* HP-UX */
+#define ELFOSABI_NETBSD		2	/* NetBSD.  */
+#define ELFOSABI_GNU		3	/* Object uses GNU ELF extensions.  */
+#define ELFOSABI_LINUX		ELFOSABI_GNU /* Compatibility alias.  */
+#define ELFOSABI_SOLARIS	6	/* Sun Solaris.  */
+#define ELFOSABI_AIX		7	/* IBM AIX.  */
+#define ELFOSABI_IRIX		8	/* SGI Irix.  */
+#define ELFOSABI_FREEBSD	9	/* FreeBSD.  */
+#define ELFOSABI_TRU64		10	/* Compaq TRU64 UNIX.  */
+#define ELFOSABI_MODESTO	11	/* Novell Modesto.  */
+#define ELFOSABI_OPENBSD	12	/* OpenBSD.  */
+#define ELFOSABI_ARM_AEABI	64	/* ARM EABI */
+#define ELFOSABI_ARM		97	/* ARM */
+#define ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
+
+#define EI_ABIVERSION	8		/* ABI version */
+
+#define EI_PAD		9		/* Byte index of padding bytes */
+
+/* Legal values for e_type (object file type).  */
+
+#define ET_NONE		0		/* No file type */
+#define ET_REL		1		/* Relocatable file */
+#define ET_EXEC		2		/* Executable file */
+#define ET_DYN		3		/* Shared object file */
+#define ET_CORE		4		/* Core file */
+#define	ET_NUM		5		/* Number of defined types */
+#define ET_LOOS		0xfe00		/* OS-specific range start */
+#define ET_HIOS		0xfeff		/* OS-specific range end */
+#define ET_LOPROC	0xff00		/* Processor-specific range start */
+#define ET_HIPROC	0xffff		/* Processor-specific range end */
+
+/* Legal values for e_machine (architecture).  */
+
+#define EM_NONE		 0	/* No machine */
+#define EM_M32		 1	/* AT&T WE 32100 */
+#define EM_SPARC	 2	/* SUN SPARC */
+#define EM_386		 3	/* Intel 80386 */
+#define EM_68K		 4	/* Motorola m68k family */
+#define EM_88K		 5	/* Motorola m88k family */
+#define EM_IAMCU	 6	/* Intel MCU */
+#define EM_860		 7	/* Intel 80860 */
+#define EM_MIPS		 8	/* MIPS R3000 big-endian */
+#define EM_S370		 9	/* IBM System/370 */
+#define EM_MIPS_RS3_LE	10	/* MIPS R3000 little-endian */
+				/* reserved 11-14 */
+#define EM_PARISC	15	/* HPPA */
+				/* reserved 16 */
+#define EM_VPP500	17	/* Fujitsu VPP500 */
+#define EM_SPARC32PLUS	18	/* Sun's "v8plus" */
+#define EM_960		19	/* Intel 80960 */
+#define EM_PPC		20	/* PowerPC */
+#define EM_PPC64	21	/* PowerPC 64-bit */
+#define EM_S390		22	/* IBM S390 */
+#define EM_SPU		23	/* IBM SPU/SPC */
+				/* reserved 24-35 */
+#define EM_V800		36	/* NEC V800 series */
+#define EM_FR20		37	/* Fujitsu FR20 */
+#define EM_RH32		38	/* TRW RH-32 */
+#define EM_RCE		39	/* Motorola RCE */
+#define EM_ARM		40	/* ARM */
+#define EM_FAKE_ALPHA	41	/* Digital Alpha */
+#define EM_SH		42	/* Hitachi SH */
+#define EM_SPARCV9	43	/* SPARC v9 64-bit */
+#define EM_TRICORE	44	/* Siemens Tricore */
+#define EM_ARC		45	/* Argonaut RISC Core */
+#define EM_H8_300	46	/* Hitachi H8/300 */
+#define EM_H8_300H	47	/* Hitachi H8/300H */
+#define EM_H8S		48	/* Hitachi H8S */
+#define EM_H8_500	49	/* Hitachi H8/500 */
+#define EM_IA_64	50	/* Intel Merced */
+#define EM_MIPS_X	51	/* Stanford MIPS-X */
+#define EM_COLDFIRE	52	/* Motorola Coldfire */
+#define EM_68HC12	53	/* Motorola M68HC12 */
+#define EM_MMA		54	/* Fujitsu MMA Multimedia Accelerator */
+#define EM_PCP		55	/* Siemens PCP */
+#define EM_NCPU		56	/* Sony nCPU embeeded RISC */
+#define EM_NDR1		57	/* Denso NDR1 microprocessor */
+#define EM_STARCORE	58	/* Motorola Start*Core processor */
+#define EM_ME16		59	/* Toyota ME16 processor */
+#define EM_ST100	60	/* STMicroelectronic ST100 processor */
+#define EM_TINYJ	61	/* Advanced Logic Corp. Tinyj emb.fam */
+#define EM_X86_64	62	/* AMD x86-64 architecture */
+#define EM_PDSP		63	/* Sony DSP Processor */
+#define EM_PDP10	64	/* Digital PDP-10 */
+#define EM_PDP11	65	/* Digital PDP-11 */
+#define EM_FX66		66	/* Siemens FX66 microcontroller */
+#define EM_ST9PLUS	67	/* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7		68	/* STmicroelectronics ST7 8 bit mc */
+#define EM_68HC16	69	/* Motorola MC68HC16 microcontroller */
+#define EM_68HC11	70	/* Motorola MC68HC11 microcontroller */
+#define EM_68HC08	71	/* Motorola MC68HC08 microcontroller */
+#define EM_68HC05	72	/* Motorola MC68HC05 microcontroller */
+#define EM_SVX		73	/* Silicon Graphics SVx */
+#define EM_ST19		74	/* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX		75	/* Digital VAX */
+#define EM_CRIS		76	/* Axis Communications 32-bit emb.proc */
+#define EM_JAVELIN	77	/* Infineon Technologies 32-bit emb.proc */
+#define EM_FIREPATH	78	/* Element 14 64-bit DSP Processor */
+#define EM_ZSP		79	/* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX		80	/* Donald Knuth's educational 64-bit proc */
+#define EM_HUANY	81	/* Harvard University machine-independent object files */
+#define EM_PRISM	82	/* SiTera Prism */
+#define EM_AVR		83	/* Atmel AVR 8-bit microcontroller */
+#define EM_FR30		84	/* Fujitsu FR30 */
+#define EM_D10V		85	/* Mitsubishi D10V */
+#define EM_D30V		86	/* Mitsubishi D30V */
+#define EM_V850		87	/* NEC v850 */
+#define EM_M32R		88	/* Mitsubishi M32R */
+#define EM_MN10300	89	/* Matsushita MN10300 */
+#define EM_MN10200	90	/* Matsushita MN10200 */
+#define EM_PJ		91	/* picoJava */
+#define EM_OPENRISC	92	/* OpenRISC 32-bit embedded processor */
+#define EM_ARC_COMPACT	93	/* ARC International ARCompact */
+#define EM_XTENSA	94	/* Tensilica Xtensa Architecture */
+#define EM_VIDEOCORE	95	/* Alphamosaic VideoCore */
+#define EM_TMM_GPP	96	/* Thompson Multimedia General Purpose Proc */
+#define EM_NS32K	97	/* National Semi. 32000 */
+#define EM_TPC		98	/* Tenor Network TPC */
+#define EM_SNP1K	99	/* Trebia SNP 1000 */
+#define EM_ST200	100	/* STMicroelectronics ST200 */
+#define EM_IP2K		101	/* Ubicom IP2xxx */
+#define EM_MAX		102	/* MAX processor */
+#define EM_CR		103	/* National Semi. CompactRISC */
+#define EM_F2MC16	104	/* Fujitsu F2MC16 */
+#define EM_MSP430	105	/* Texas Instruments msp430 */
+#define EM_BLACKFIN	106	/* Analog Devices Blackfin DSP */
+#define EM_SE_C33	107	/* Seiko Epson S1C33 family */
+#define EM_SEP		108	/* Sharp embedded microprocessor */
+#define EM_ARCA		109	/* Arca RISC */
+#define EM_UNICORE	110	/* PKU-Unity & MPRC Peking Uni. mc series */
+#define EM_EXCESS	111	/* eXcess configurable cpu */
+#define EM_DXP		112	/* Icera Semi. Deep Execution Processor */
+#define EM_ALTERA_NIOS2 113	/* Altera Nios II */
+#define EM_CRX		114	/* National Semi. CompactRISC CRX */
+#define EM_XGATE	115	/* Motorola XGATE */
+#define EM_C166		116	/* Infineon C16x/XC16x */
+#define EM_M16C		117	/* Renesas M16C */
+#define EM_DSPIC30F	118	/* Microchip Technology dsPIC30F */
+#define EM_CE		119	/* Freescale Communication Engine RISC */
+#define EM_M32C		120	/* Renesas M32C */
+				/* reserved 121-130 */
+#define EM_TSK3000	131	/* Altium TSK3000 */
+#define EM_RS08		132	/* Freescale RS08 */
+#define EM_SHARC	133	/* Analog Devices SHARC family */
+#define EM_ECOG2	134	/* Cyan Technology eCOG2 */
+#define EM_SCORE7	135	/* Sunplus S+core7 RISC */
+#define EM_DSP24	136	/* New Japan Radio (NJR) 24-bit DSP */
+#define EM_VIDEOCORE3	137	/* Broadcom VideoCore III */
+#define EM_LATTICEMICO32 138	/* RISC for Lattice FPGA */
+#define EM_SE_C17	139	/* Seiko Epson C17 */
+#define EM_TI_C6000	140	/* Texas Instruments TMS320C6000 DSP */
+#define EM_TI_C2000	141	/* Texas Instruments TMS320C2000 DSP */
+#define EM_TI_C5500	142	/* Texas Instruments TMS320C55x DSP */
+#define EM_TI_ARP32	143	/* Texas Instruments App. Specific RISC */
+#define EM_TI_PRU	144	/* Texas Instruments Prog. Realtime Unit */
+				/* reserved 145-159 */
+#define EM_MMDSP_PLUS	160	/* STMicroelectronics 64bit VLIW DSP */
+#define EM_CYPRESS_M8C	161	/* Cypress M8C */
+#define EM_R32C		162	/* Renesas R32C */
+#define EM_TRIMEDIA	163	/* NXP Semi. TriMedia */
+#define EM_QDSP6	164	/* QUALCOMM DSP6 */
+#define EM_8051		165	/* Intel 8051 and variants */
+#define EM_STXP7X	166	/* STMicroelectronics STxP7x */
+#define EM_NDS32	167	/* Andes Tech. compact code emb. RISC */
+#define EM_ECOG1X	168	/* Cyan Technology eCOG1X */
+#define EM_MAXQ30	169	/* Dallas Semi. MAXQ30 mc */
+#define EM_XIMO16	170	/* New Japan Radio (NJR) 16-bit DSP */
+#define EM_MANIK	171	/* M2000 Reconfigurable RISC */
+#define EM_CRAYNV2	172	/* Cray NV2 vector architecture */
+#define EM_RX		173	/* Renesas RX */
+#define EM_METAG	174	/* Imagination Tech. META */
+#define EM_MCST_ELBRUS	175	/* MCST Elbrus */
+#define EM_ECOG16	176	/* Cyan Technology eCOG16 */
+#define EM_CR16		177	/* National Semi. CompactRISC CR16 */
+#define EM_ETPU		178	/* Freescale Extended Time Processing Unit */
+#define EM_SLE9X	179	/* Infineon Tech. SLE9X */
+#define EM_L10M		180	/* Intel L10M */
+#define EM_K10M		181	/* Intel K10M */
+				/* reserved 182 */
+#define EM_AARCH64	183	/* ARM AARCH64 */
+				/* reserved 184 */
+#define EM_AVR32	185	/* Amtel 32-bit microprocessor */
+#define EM_STM8		186	/* STMicroelectronics STM8 */
+#define EM_TILE64	187	/* Tileta TILE64 */
+#define EM_TILEPRO	188	/* Tilera TILEPro */
+#define EM_MICROBLAZE	189	/* Xilinx MicroBlaze */
+#define EM_CUDA		190	/* NVIDIA CUDA */
+#define EM_TILEGX	191	/* Tilera TILE-Gx */
+#define EM_CLOUDSHIELD	192	/* CloudShield */
+#define EM_COREA_1ST	193	/* KIPO-KAIST Core-A 1st gen. */
+#define EM_COREA_2ND	194	/* KIPO-KAIST Core-A 2nd gen. */
+#define EM_ARC_COMPACT2	195	/* Synopsys ARCompact V2 */
+#define EM_OPEN8	196	/* Open8 RISC */
+#define EM_RL78		197	/* Renesas RL78 */
+#define EM_VIDEOCORE5	198	/* Broadcom VideoCore V */
+#define EM_78KOR	199	/* Renesas 78KOR */
+#define EM_56800EX	200	/* Freescale 56800EX DSC */
+#define EM_BA1		201	/* Beyond BA1 */
+#define EM_BA2		202	/* Beyond BA2 */
+#define EM_XCORE	203	/* XMOS xCORE */
+#define EM_MCHP_PIC	204	/* Microchip 8-bit PIC(r) */
+				/* reserved 205-209 */
+#define EM_KM32		210	/* KM211 KM32 */
+#define EM_KMX32	211	/* KM211 KMX32 */
+#define EM_EMX16	212	/* KM211 KMX16 */
+#define EM_EMX8		213	/* KM211 KMX8 */
+#define EM_KVARC	214	/* KM211 KVARC */
+#define EM_CDP		215	/* Paneve CDP */
+#define EM_COGE		216	/* Cognitive Smart Memory Processor */
+#define EM_COOL		217	/* Bluechip CoolEngine */
+#define EM_NORC		218	/* Nanoradio Optimized RISC */
+#define EM_CSR_KALIMBA	219	/* CSR Kalimba */
+#define EM_Z80		220	/* Zilog Z80 */
+#define EM_VISIUM	221	/* Controls and Data Services VISIUMcore */
+#define EM_FT32		222	/* FTDI Chip FT32 */
+#define EM_MOXIE	223	/* Moxie processor */
+#define EM_AMDGPU	224	/* AMD GPU */
+				/* reserved 225-242 */
+#define EM_RISCV	243	/* RISC-V */
+
+#define EM_BPF		247	/* Linux BPF -- in-kernel virtual machine */
+
+#define EM_NUM		248
+
+/* Old spellings/synonyms.  */
+
+#define EM_ARC_A5	EM_ARC_COMPACT
+
+/* If it is necessary to assign new unofficial EM_* values, please
+   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+   chances of collision with official or non-GNU unofficial values.  */
+
+#define EM_ALPHA	0x9026
+
+/* Legal values for e_version (version).  */
+
+#define EV_NONE		0		/* Invalid ELF version */
+#define EV_CURRENT	1		/* Current version */
+#define EV_NUM		2
+
+/* Section header.  */
+
+typedef struct
+{
+  Elf32_Word	sh_name;		/* Section name (string tbl index) */
+  Elf32_Word	sh_type;		/* Section type */
+  Elf32_Word	sh_flags;		/* Section flags */
+  Elf32_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf32_Off	sh_offset;		/* Section file offset */
+  Elf32_Word	sh_size;		/* Section size in bytes */
+  Elf32_Word	sh_link;		/* Link to another section */
+  Elf32_Word	sh_info;		/* Additional section information */
+  Elf32_Word	sh_addralign;		/* Section alignment */
+  Elf32_Word	sh_entsize;		/* Entry size if section holds table */
+} Elf32_Shdr;
+
+typedef struct
+{
+  Elf64_Word	sh_name;		/* Section name (string tbl index) */
+  Elf64_Word	sh_type;		/* Section type */
+  Elf64_Xword	sh_flags;		/* Section flags */
+  Elf64_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf64_Off	sh_offset;		/* Section file offset */
+  Elf64_Xword	sh_size;		/* Section size in bytes */
+  Elf64_Word	sh_link;		/* Link to another section */
+  Elf64_Word	sh_info;		/* Additional section information */
+  Elf64_Xword	sh_addralign;		/* Section alignment */
+  Elf64_Xword	sh_entsize;		/* Entry size if section holds table */
+} Elf64_Shdr;
+
+/* Special section indices.  */
+
+#define SHN_UNDEF	0		/* Undefined section */
+#define SHN_LORESERVE	0xff00		/* Start of reserved indices */
+#define SHN_LOPROC	0xff00		/* Start of processor-specific */
+#define SHN_BEFORE	0xff00		/* Order section before all others
+					   (Solaris).  */
+#define SHN_AFTER	0xff01		/* Order section after all others
+					   (Solaris).  */
+#define SHN_HIPROC	0xff1f		/* End of processor-specific */
+#define SHN_LOOS	0xff20		/* Start of OS-specific */
+#define SHN_HIOS	0xff3f		/* End of OS-specific */
+#define SHN_ABS		0xfff1		/* Associated symbol is absolute */
+#define SHN_COMMON	0xfff2		/* Associated symbol is common */
+#define SHN_XINDEX	0xffff		/* Index is in extra table.  */
+#define SHN_HIRESERVE	0xffff		/* End of reserved indices */
+
+/* Legal values for sh_type (section type).  */
+
+#define SHT_NULL	  0		/* Section header table entry unused */
+#define SHT_PROGBITS	  1		/* Program data */
+#define SHT_SYMTAB	  2		/* Symbol table */
+#define SHT_STRTAB	  3		/* String table */
+#define SHT_RELA	  4		/* Relocation entries with addends */
+#define SHT_HASH	  5		/* Symbol hash table */
+#define SHT_DYNAMIC	  6		/* Dynamic linking information */
+#define SHT_NOTE	  7		/* Notes */
+#define SHT_NOBITS	  8		/* Program space with no data (bss) */
+#define SHT_REL		  9		/* Relocation entries, no addends */
+#define SHT_SHLIB	  10		/* Reserved */
+#define SHT_DYNSYM	  11		/* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY	  14		/* Array of constructors */
+#define SHT_FINI_ARRAY	  15		/* Array of destructors */
+#define SHT_PREINIT_ARRAY 16		/* Array of pre-constructors */
+#define SHT_GROUP	  17		/* Section group */
+#define SHT_SYMTAB_SHNDX  18		/* Extended section indeces */
+#define	SHT_NUM		  19		/* Number of defined types.  */
+#define SHT_LOOS	  0x60000000	/* Start OS-specific.  */
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5	/* Object attributes.  */
+#define SHT_GNU_HASH	  0x6ffffff6	/* GNU-style hash table.  */
+#define SHT_GNU_LIBLIST	  0x6ffffff7	/* Prelink library list */
+#define SHT_CHECKSUM	  0x6ffffff8	/* Checksum for DSO content.  */
+#define SHT_LOSUNW	  0x6ffffffa	/* Sun-specific low bound.  */
+#define SHT_SUNW_move	  0x6ffffffa
+#define SHT_SUNW_COMDAT   0x6ffffffb
+#define SHT_SUNW_syminfo  0x6ffffffc
+#define SHT_GNU_verdef	  0x6ffffffd	/* Version definition section.  */
+#define SHT_GNU_verneed	  0x6ffffffe	/* Version needs section.  */
+#define SHT_GNU_versym	  0x6fffffff	/* Version symbol table.  */
+#define SHT_HISUNW	  0x6fffffff	/* Sun-specific high bound.  */
+#define SHT_HIOS	  0x6fffffff	/* End OS-specific type */
+#define SHT_LOPROC	  0x70000000	/* Start of processor-specific */
+#define SHT_HIPROC	  0x7fffffff	/* End of processor-specific */
+#define SHT_LOUSER	  0x80000000	/* Start of application-specific */
+#define SHT_HIUSER	  0x8fffffff	/* End of application-specific */
+
+/* Legal values for sh_flags (section flags).  */
+
+#define SHF_WRITE	     (1 << 0)	/* Writable */
+#define SHF_ALLOC	     (1 << 1)	/* Occupies memory during execution */
+#define SHF_EXECINSTR	     (1 << 2)	/* Executable */
+#define SHF_MERGE	     (1 << 4)	/* Might be merged */
+#define SHF_STRINGS	     (1 << 5)	/* Contains nul-terminated strings */
+#define SHF_INFO_LINK	     (1 << 6)	/* `sh_info' contains SHT index */
+#define SHF_LINK_ORDER	     (1 << 7)	/* Preserve order after combining */
+#define SHF_OS_NONCONFORMING (1 << 8)	/* Non-standard OS specific handling
+					   required */
+#define SHF_GROUP	     (1 << 9)	/* Section is member of a group.  */
+#define SHF_TLS		     (1 << 10)	/* Section hold thread-local data.  */
+#define SHF_COMPRESSED	     (1 << 11)	/* Section with compressed data. */
+#define SHF_MASKOS	     0x0ff00000	/* OS-specific.  */
+#define SHF_MASKPROC	     0xf0000000	/* Processor-specific */
+#define SHF_ORDERED	     (1 << 30)	/* Special ordering requirement
+					   (Solaris).  */
+#define SHF_EXCLUDE	     (1U << 31)	/* Section is excluded unless
+					   referenced or allocated (Solaris).*/
+
+/* Section compression header.  Used when SHF_COMPRESSED is set.  */
+
+typedef struct
+{
+  Elf32_Word	ch_type;	/* Compression format.  */
+  Elf32_Word	ch_size;	/* Uncompressed data size.  */
+  Elf32_Word	ch_addralign;	/* Uncompressed data alignment.  */
+} Elf32_Chdr;
+
+typedef struct
+{
+  Elf64_Word	ch_type;	/* Compression format.  */
+  Elf64_Word	ch_reserved;
+  Elf64_Xword	ch_size;	/* Uncompressed data size.  */
+  Elf64_Xword	ch_addralign;	/* Uncompressed data alignment.  */
+} Elf64_Chdr;
+
+/* Legal values for ch_type (compression algorithm).  */
+#define ELFCOMPRESS_ZLIB	1	   /* ZLIB/DEFLATE algorithm.  */
+#define ELFCOMPRESS_LOOS	0x60000000 /* Start of OS-specific.  */
+#define ELFCOMPRESS_HIOS	0x6fffffff /* End of OS-specific.  */
+#define ELFCOMPRESS_LOPROC	0x70000000 /* Start of processor-specific.  */
+#define ELFCOMPRESS_HIPROC	0x7fffffff /* End of processor-specific.  */
+
+/* Section group handling.  */
+#define GRP_COMDAT	0x1		/* Mark group as COMDAT.  */
+
+/* Symbol table entry.  */
+
+typedef struct
+{
+  Elf32_Word	st_name;		/* Symbol name (string tbl index) */
+  Elf32_Addr	st_value;		/* Symbol value */
+  Elf32_Word	st_size;		/* Symbol size */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char	st_other;		/* Symbol visibility */
+  Elf32_Section	st_shndx;		/* Section index */
+} Elf32_Sym;
+
+typedef struct
+{
+  Elf64_Word	st_name;		/* Symbol name (string tbl index) */
+  unsigned char	st_info;		/* Symbol type and binding */
+  unsigned char st_other;		/* Symbol visibility */
+  Elf64_Section	st_shndx;		/* Section index */
+  Elf64_Addr	st_value;		/* Symbol value */
+  Elf64_Xword	st_size;		/* Symbol size */
+} Elf64_Sym;
+
+/* The syminfo section if available contains additional information about
+   every dynamic symbol.  */
+
+typedef struct
+{
+  Elf32_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf32_Half si_flags;			/* Per symbol flags */
+} Elf32_Syminfo;
+
+typedef struct
+{
+  Elf64_Half si_boundto;		/* Direct bindings, symbol bound to */
+  Elf64_Half si_flags;			/* Per symbol flags */
+} Elf64_Syminfo;
+
+/* Possible values for si_boundto.  */
+#define SYMINFO_BT_SELF		0xffff	/* Symbol bound to self */
+#define SYMINFO_BT_PARENT	0xfffe	/* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE	0xff00	/* Beginning of reserved entries */
+
+/* Possible bitmasks for si_flags.  */
+#define SYMINFO_FLG_DIRECT	0x0001	/* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU	0x0002	/* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY	0x0004	/* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD	0x0008	/* Symbol bound to object to be lazy
+					   loaded */
+/* Syminfo version values.  */
+#define SYMINFO_NONE		0
+#define SYMINFO_CURRENT		1
+#define SYMINFO_NUM		2
+
+
+/* How to extract and insert information held in the st_info field.  */
+
+#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val)		((val) & 0xf)
+#define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
+#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
+
+#define STB_LOCAL	0		/* Local symbol */
+#define STB_GLOBAL	1		/* Global symbol */
+#define STB_WEAK	2		/* Weak symbol */
+#define	STB_NUM		3		/* Number of defined types.  */
+#define STB_LOOS	10		/* Start of OS-specific */
+#define STB_GNU_UNIQUE	10		/* Unique symbol.  */
+#define STB_HIOS	12		/* End of OS-specific */
+#define STB_LOPROC	13		/* Start of processor-specific */
+#define STB_HIPROC	15		/* End of processor-specific */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_NOTYPE	0		/* Symbol type is unspecified */
+#define STT_OBJECT	1		/* Symbol is a data object */
+#define STT_FUNC	2		/* Symbol is a code object */
+#define STT_SECTION	3		/* Symbol associated with a section */
+#define STT_FILE	4		/* Symbol's name is file name */
+#define STT_COMMON	5		/* Symbol is a common data object */
+#define STT_TLS		6		/* Symbol is thread-local data object*/
+#define	STT_NUM		7		/* Number of defined types.  */
+#define STT_LOOS	10		/* Start of OS-specific */
+#define STT_GNU_IFUNC	10		/* Symbol is indirect code object */
+#define STT_HIOS	12		/* End of OS-specific */
+#define STT_LOPROC	13		/* Start of processor-specific */
+#define STT_HIPROC	15		/* End of processor-specific */
+
+
+/* Symbol table indices are found in the hash buckets and chain table
+   of a symbol hash table section.  This special index value indicates
+   the end of a chain, meaning no further symbols are found in that bucket.  */
+
+#define STN_UNDEF	0		/* End of a chain.  */
+
+
+/* How to extract and insert information held in the st_other field.  */
+
+#define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
+
+/* For ELF64 the definitions are the same.  */
+#define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
+
+/* Symbol visibility specification encoded in the st_other field.  */
+#define STV_DEFAULT	0		/* Default symbol visibility rules */
+#define STV_INTERNAL	1		/* Processor specific hidden class */
+#define STV_HIDDEN	2		/* Sym unavailable in other modules */
+#define STV_PROTECTED	3		/* Not preemptible, not exported */
+
+
+/* Relocation table entry without addend (in section of type SHT_REL).  */
+
+typedef struct
+{
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+} Elf32_Rel;
+
+/* I have seen two different definitions of the Elf64_Rel and
+   Elf64_Rela structures, so we'll leave them out until Novell (or
+   whoever) gets their act together.  */
+/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+} Elf64_Rel;
+
+/* Relocation table entry with addend (in section of type SHT_RELA).  */
+
+typedef struct
+{
+  Elf32_Addr	r_offset;		/* Address */
+  Elf32_Word	r_info;			/* Relocation type and symbol index */
+  Elf32_Sword	r_addend;		/* Addend */
+} Elf32_Rela;
+
+typedef struct
+{
+  Elf64_Addr	r_offset;		/* Address */
+  Elf64_Xword	r_info;			/* Relocation type and symbol index */
+  Elf64_Sxword	r_addend;		/* Addend */
+} Elf64_Rela;
+
+/* How to extract and insert information held in the r_info field.  */
+
+#define ELF32_R_SYM(val)		((val) >> 8)
+#define ELF32_R_TYPE(val)		((val) & 0xff)
+#define ELF32_R_INFO(sym, type)		(((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i)			((i) >> 32)
+#define ELF64_R_TYPE(i)			((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type)		((((Elf64_Xword) (sym)) << 32) + (type))
+
+/* Program segment header.  */
+
+typedef struct
+{
+  Elf32_Word	p_type;			/* Segment type */
+  Elf32_Off	p_offset;		/* Segment file offset */
+  Elf32_Addr	p_vaddr;		/* Segment virtual address */
+  Elf32_Addr	p_paddr;		/* Segment physical address */
+  Elf32_Word	p_filesz;		/* Segment size in file */
+  Elf32_Word	p_memsz;		/* Segment size in memory */
+  Elf32_Word	p_flags;		/* Segment flags */
+  Elf32_Word	p_align;		/* Segment alignment */
+} Elf32_Phdr;
+
+typedef struct
+{
+  Elf64_Word	p_type;			/* Segment type */
+  Elf64_Word	p_flags;		/* Segment flags */
+  Elf64_Off	p_offset;		/* Segment file offset */
+  Elf64_Addr	p_vaddr;		/* Segment virtual address */
+  Elf64_Addr	p_paddr;		/* Segment physical address */
+  Elf64_Xword	p_filesz;		/* Segment size in file */
+  Elf64_Xword	p_memsz;		/* Segment size in memory */
+  Elf64_Xword	p_align;		/* Segment alignment */
+} Elf64_Phdr;
+
+/* Special value for e_phnum.  This indicates that the real number of
+   program headers is too large to fit into e_phnum.  Instead the real
+   value is in the field sh_info of section 0.  */
+
+#define PN_XNUM		0xffff
+
+/* Legal values for p_type (segment type).  */
+
+#define	PT_NULL		0		/* Program header table entry unused */
+#define PT_LOAD		1		/* Loadable program segment */
+#define PT_DYNAMIC	2		/* Dynamic linking information */
+#define PT_INTERP	3		/* Program interpreter */
+#define PT_NOTE		4		/* Auxiliary information */
+#define PT_SHLIB	5		/* Reserved */
+#define PT_PHDR		6		/* Entry for header table itself */
+#define PT_TLS		7		/* Thread-local storage segment */
+#define	PT_NUM		8		/* Number of defined types */
+#define PT_LOOS		0x60000000	/* Start of OS-specific */
+#define PT_GNU_EH_FRAME	0x6474e550	/* GCC .eh_frame_hdr segment */
+#define PT_GNU_STACK	0x6474e551	/* Indicates stack executability */
+#define PT_GNU_RELRO	0x6474e552	/* Read-only after relocation */
+#define PT_LOSUNW	0x6ffffffa
+#define PT_SUNWBSS	0x6ffffffa	/* Sun Specific segment */
+#define PT_SUNWSTACK	0x6ffffffb	/* Stack segment */
+#define PT_HISUNW	0x6fffffff
+#define PT_HIOS		0x6fffffff	/* End of OS-specific */
+#define PT_LOPROC	0x70000000	/* Start of processor-specific */
+#define PT_HIPROC	0x7fffffff	/* End of processor-specific */
+
+/* Legal values for p_flags (segment flags).  */
+
+#define PF_X		(1 << 0)	/* Segment is executable */
+#define PF_W		(1 << 1)	/* Segment is writable */
+#define PF_R		(1 << 2)	/* Segment is readable */
+#define PF_MASKOS	0x0ff00000	/* OS-specific */
+#define PF_MASKPROC	0xf0000000	/* Processor-specific */
+
+/* Legal values for note segment descriptor types for core files. */
+
+#define NT_PRSTATUS	1		/* Contains copy of prstatus struct */
+#define NT_FPREGSET	2		/* Contains copy of fpregset struct */
+#define NT_PRPSINFO	3		/* Contains copy of prpsinfo struct */
+#define NT_PRXREG	4		/* Contains copy of prxregset struct */
+#define NT_TASKSTRUCT	4		/* Contains copy of task structure */
+#define NT_PLATFORM	5		/* String from sysinfo(SI_PLATFORM) */
+#define NT_AUXV		6		/* Contains copy of auxv array */
+#define NT_GWINDOWS	7		/* Contains copy of gwindows struct */
+#define NT_ASRS		8		/* Contains copy of asrset struct */
+#define NT_PSTATUS	10		/* Contains copy of pstatus struct */
+#define NT_PSINFO	13		/* Contains copy of psinfo struct */
+#define NT_PRCRED	14		/* Contains copy of prcred struct */
+#define NT_UTSNAME	15		/* Contains copy of utsname struct */
+#define NT_LWPSTATUS	16		/* Contains copy of lwpstatus struct */
+#define NT_LWPSINFO	17		/* Contains copy of lwpinfo struct */
+#define NT_PRFPXREG	20		/* Contains copy of fprxregset struct */
+#define NT_SIGINFO	0x53494749	/* Contains copy of siginfo_t,
+					   size might increase */
+#define NT_FILE		0x46494c45	/* Contains information about mapped
+					   files */
+#define NT_PRXFPREG	0x46e62b7f	/* Contains copy of user_fxsr_struct */
+#define NT_PPC_VMX	0x100		/* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE	0x101		/* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX	0x102		/* PowerPC VSX registers */
+#define NT_PPC_TAR	0x103		/* Target Address Register */
+#define NT_PPC_PPR	0x104		/* Program Priority Register */
+#define NT_PPC_DSCR	0x105		/* Data Stream Control Register */
+#define NT_PPC_EBB	0x106		/* Event Based Branch Registers */
+#define NT_PPC_PMU	0x107		/* Performance Monitor Registers */
+#define NT_PPC_TM_CGPR	0x108		/* TM checkpointed GPR Registers */
+#define NT_PPC_TM_CFPR	0x109		/* TM checkpointed FPR Registers */
+#define NT_PPC_TM_CVMX	0x10a		/* TM checkpointed VMX Registers */
+#define NT_PPC_TM_CVSX	0x10b		/* TM checkpointed VSX Registers */
+#define NT_PPC_TM_SPR	0x10c		/* TM Special Purpose Registers */
+#define NT_PPC_TM_CTAR	0x10d		/* TM checkpointed Target Address
+					   Register */
+#define NT_PPC_TM_CPPR	0x10e		/* TM checkpointed Program Priority
+					   Register */
+#define NT_PPC_TM_CDSCR	0x10f		/* TM checkpointed Data Stream Control
+					   Register */
+#define NT_386_TLS	0x200		/* i386 TLS slots (struct user_desc) */
+#define NT_386_IOPERM	0x201		/* x86 io permission bitmap (1=deny) */
+#define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */
+#define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves */
+#define NT_S390_TIMER	0x301		/* s390 timer register */
+#define NT_S390_TODCMP	0x302		/* s390 TOD clock comparator register */
+#define NT_S390_TODPREG	0x303		/* s390 TOD programmable register */
+#define NT_S390_CTRS	0x304		/* s390 control registers */
+#define NT_S390_PREFIX	0x305		/* s390 prefix register */
+#define NT_S390_LAST_BREAK	0x306	/* s390 breaking event address */
+#define NT_S390_SYSTEM_CALL	0x307	/* s390 system call restart data */
+#define NT_S390_TDB	0x308		/* s390 transaction diagnostic block */
+#define NT_ARM_VFP	0x400		/* ARM VFP/NEON registers */
+#define NT_ARM_TLS	0x401		/* ARM TLS register */
+#define NT_ARM_HW_BREAK	0x402		/* ARM hardware breakpoint registers */
+#define NT_ARM_HW_WATCH	0x403		/* ARM hardware watchpoint registers */
+#define NT_ARM_SYSTEM_CALL	0x404	/* ARM system call number */
+
+/* Legal values for the note segment descriptor types for object files.  */
+
+#define NT_VERSION	1		/* Contains a version string.  */
+
+
+/* Dynamic section entry.  */
+
+typedef struct
+{
+  Elf32_Sword	d_tag;			/* Dynamic entry type */
+  union
+    {
+      Elf32_Word d_val;			/* Integer value */
+      Elf32_Addr d_ptr;			/* Address value */
+    } d_un;
+} Elf32_Dyn;
+
+typedef struct
+{
+  Elf64_Sxword	d_tag;			/* Dynamic entry type */
+  union
+    {
+      Elf64_Xword d_val;		/* Integer value */
+      Elf64_Addr d_ptr;			/* Address value */
+    } d_un;
+} Elf64_Dyn;
+
+/* Legal values for d_tag (dynamic entry type).  */
+
+#define DT_NULL		0		/* Marks end of dynamic section */
+#define DT_NEEDED	1		/* Name of needed library */
+#define DT_PLTRELSZ	2		/* Size in bytes of PLT relocs */
+#define DT_PLTGOT	3		/* Processor defined value */
+#define DT_HASH		4		/* Address of symbol hash table */
+#define DT_STRTAB	5		/* Address of string table */
+#define DT_SYMTAB	6		/* Address of symbol table */
+#define DT_RELA		7		/* Address of Rela relocs */
+#define DT_RELASZ	8		/* Total size of Rela relocs */
+#define DT_RELAENT	9		/* Size of one Rela reloc */
+#define DT_STRSZ	10		/* Size of string table */
+#define DT_SYMENT	11		/* Size of one symbol table entry */
+#define DT_INIT		12		/* Address of init function */
+#define DT_FINI		13		/* Address of termination function */
+#define DT_SONAME	14		/* Name of shared object */
+#define DT_RPATH	15		/* Library search path (deprecated) */
+#define DT_SYMBOLIC	16		/* Start symbol search here */
+#define DT_REL		17		/* Address of Rel relocs */
+#define DT_RELSZ	18		/* Total size of Rel relocs */
+#define DT_RELENT	19		/* Size of one Rel reloc */
+#define DT_PLTREL	20		/* Type of reloc in PLT */
+#define DT_DEBUG	21		/* For debugging; unspecified */
+#define DT_TEXTREL	22		/* Reloc might modify .text */
+#define DT_JMPREL	23		/* Address of PLT relocs */
+#define	DT_BIND_NOW	24		/* Process relocations of object */
+#define	DT_INIT_ARRAY	25		/* Array with addresses of init fct */
+#define	DT_FINI_ARRAY	26		/* Array with addresses of fini fct */
+#define	DT_INIT_ARRAYSZ	27		/* Size in bytes of DT_INIT_ARRAY */
+#define	DT_FINI_ARRAYSZ	28		/* Size in bytes of DT_FINI_ARRAY */
+#define DT_RUNPATH	29		/* Library search path */
+#define DT_FLAGS	30		/* Flags for the object being loaded */
+#define DT_ENCODING	32		/* Start of encoded range */
+#define DT_PREINIT_ARRAY 32		/* Array with addresses of preinit fct*/
+#define DT_PREINIT_ARRAYSZ 33		/* size in bytes of DT_PREINIT_ARRAY */
+#define	DT_NUM		34		/* Number used */
+#define DT_LOOS		0x6000000d	/* Start of OS-specific */
+#define DT_HIOS		0x6ffff000	/* End of OS-specific */
+#define DT_LOPROC	0x70000000	/* Start of processor-specific */
+#define DT_HIPROC	0x7fffffff	/* End of processor-specific */
+#define	DT_PROCNUM	DT_MIPS_NUM	/* Most used by any processor */
+
+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+   Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
+   approach.  */
+#define DT_VALRNGLO	0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5	/* Prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6	/* Size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7	/* Size of library list */
+#define DT_CHECKSUM	0x6ffffdf8
+#define DT_PLTPADSZ	0x6ffffdf9
+#define DT_MOVEENT	0x6ffffdfa
+#define DT_MOVESZ	0x6ffffdfb
+#define DT_FEATURE_1	0x6ffffdfc	/* Feature selection (DTF_*).  */
+#define DT_POSFLAG_1	0x6ffffdfd	/* Flags for DT_* entries, effecting
+					   the following DT_* entry.  */
+#define DT_SYMINSZ	0x6ffffdfe	/* Size of syminfo table (in bytes) */
+#define DT_SYMINENT	0x6ffffdff	/* Entry size of syminfo */
+#define DT_VALRNGHI	0x6ffffdff
+#define DT_VALTAGIDX(tag)	(DT_VALRNGHI - (tag))	/* Reverse order! */
+#define DT_VALNUM 12
+
+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+   Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+
+   If any adjustment is made to the ELF object after it has been
+   built these entries will need to be adjusted.  */
+#define DT_ADDRRNGLO	0x6ffffe00
+#define DT_GNU_HASH	0x6ffffef5	/* GNU-style hash table.  */
+#define DT_TLSDESC_PLT	0x6ffffef6
+#define DT_TLSDESC_GOT	0x6ffffef7
+#define DT_GNU_CONFLICT	0x6ffffef8	/* Start of conflict section */
+#define DT_GNU_LIBLIST	0x6ffffef9	/* Library list */
+#define DT_CONFIG	0x6ffffefa	/* Configuration information.  */
+#define DT_DEPAUDIT	0x6ffffefb	/* Dependency auditing.  */
+#define DT_AUDIT	0x6ffffefc	/* Object auditing.  */
+#define	DT_PLTPAD	0x6ffffefd	/* PLT padding.  */
+#define	DT_MOVETAB	0x6ffffefe	/* Move table.  */
+#define DT_SYMINFO	0x6ffffeff	/* Syminfo table.  */
+#define DT_ADDRRNGHI	0x6ffffeff
+#define DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))	/* Reverse order! */
+#define DT_ADDRNUM 11
+
+/* The versioning entry types.  The next are defined as part of the
+   GNU extension.  */
+#define DT_VERSYM	0x6ffffff0
+
+#define DT_RELACOUNT	0x6ffffff9
+#define DT_RELCOUNT	0x6ffffffa
+
+/* These were chosen by Sun.  */
+#define DT_FLAGS_1	0x6ffffffb	/* State flags, see DF_1_* below.  */
+#define	DT_VERDEF	0x6ffffffc	/* Address of version definition
+					   table */
+#define	DT_VERDEFNUM	0x6ffffffd	/* Number of version definitions */
+#define	DT_VERNEED	0x6ffffffe	/* Address of table with needed
+					   versions */
+#define	DT_VERNEEDNUM	0x6fffffff	/* Number of needed versions */
+#define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))	/* Reverse order! */
+#define DT_VERSIONTAGNUM 16
+
+/* Sun added these machine-independent extensions in the "processor-specific"
+   range.  Be compatible.  */
+#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
+#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
+#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM	3
+
+/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
+#define DF_ORIGIN	0x00000001	/* Object may use DF_ORIGIN */
+#define DF_SYMBOLIC	0x00000002	/* Symbol resolutions starts here */
+#define DF_TEXTREL	0x00000004	/* Object contains text relocations */
+#define DF_BIND_NOW	0x00000008	/* No lazy binding for this object */
+#define DF_STATIC_TLS	0x00000010	/* Module uses the static TLS model */
+
+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
+   entry in the dynamic section.  */
+#define DF_1_NOW	0x00000001	/* Set RTLD_NOW for this object.  */
+#define DF_1_GLOBAL	0x00000002	/* Set RTLD_GLOBAL for this object.  */
+#define DF_1_GROUP	0x00000004	/* Set RTLD_GROUP for this object.  */
+#define DF_1_NODELETE	0x00000008	/* Set RTLD_NODELETE for this object.*/
+#define DF_1_LOADFLTR	0x00000010	/* Trigger filtee loading at runtime.*/
+#define DF_1_INITFIRST	0x00000020	/* Set RTLD_INITFIRST for this object*/
+#define DF_1_NOOPEN	0x00000040	/* Set RTLD_NOOPEN for this object.  */
+#define DF_1_ORIGIN	0x00000080	/* $ORIGIN must be handled.  */
+#define DF_1_DIRECT	0x00000100	/* Direct binding enabled.  */
+#define DF_1_TRANS	0x00000200
+#define DF_1_INTERPOSE	0x00000400	/* Object is used to interpose.  */
+#define DF_1_NODEFLIB	0x00000800	/* Ignore default lib search path.  */
+#define DF_1_NODUMP	0x00001000	/* Object can't be dldump'ed.  */
+#define DF_1_CONFALT	0x00002000	/* Configuration alternative created.*/
+#define DF_1_ENDFILTEE	0x00004000	/* Filtee terminates filters search. */
+#define	DF_1_DISPRELDNE	0x00008000	/* Disp reloc applied at build time. */
+#define	DF_1_DISPRELPND	0x00010000	/* Disp reloc applied at run-time.  */
+#define	DF_1_NODIRECT	0x00020000	/* Object has no-direct binding. */
+#define	DF_1_IGNMULDEF	0x00040000
+#define	DF_1_NOKSYMS	0x00080000
+#define	DF_1_NOHDR	0x00100000
+#define	DF_1_EDITED	0x00200000	/* Object is modified after built.  */
+#define	DF_1_NORELOC	0x00400000
+#define	DF_1_SYMINTPOSE	0x00800000	/* Object has individual interposers.  */
+#define	DF_1_GLOBAUDIT	0x01000000	/* Global auditing required.  */
+#define	DF_1_SINGLETON	0x02000000	/* Singleton symbols are used.  */
+
+/* Flags for the feature selection in DT_FEATURE_1.  */
+#define DTF_1_PARINIT	0x00000001
+#define DTF_1_CONFEXP	0x00000002
+
+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
+#define DF_P1_LAZYLOAD	0x00000001	/* Lazyload following object.  */
+#define DF_P1_GROUPPERM	0x00000002	/* Symbols from next object are not
+					   generally available.  */
+
+/* Version definition sections.  */
+
+typedef struct
+{
+  Elf32_Half	vd_version;		/* Version revision */
+  Elf32_Half	vd_flags;		/* Version information */
+  Elf32_Half	vd_ndx;			/* Version Index */
+  Elf32_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vd_hash;		/* Version name hash value */
+  Elf32_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf32_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} Elf32_Verdef;
+
+typedef struct
+{
+  Elf64_Half	vd_version;		/* Version revision */
+  Elf64_Half	vd_flags;		/* Version information */
+  Elf64_Half	vd_ndx;			/* Version Index */
+  Elf64_Half	vd_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vd_hash;		/* Version name hash value */
+  Elf64_Word	vd_aux;			/* Offset in bytes to verdaux array */
+  Elf64_Word	vd_next;		/* Offset in bytes to next verdef
+					   entry */
+} Elf64_Verdef;
+
+
+/* Legal values for vd_version (version revision).  */
+#define VER_DEF_NONE	0		/* No version */
+#define VER_DEF_CURRENT	1		/* Current version */
+#define VER_DEF_NUM	2		/* Given version number */
+
+/* Legal values for vd_flags (version information flags).  */
+#define VER_FLG_BASE	0x1		/* Version definition of file itself */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
+
+/* Versym symbol index values.  */
+#define	VER_NDX_LOCAL		0	/* Symbol is local.  */
+#define	VER_NDX_GLOBAL		1	/* Symbol is global.  */
+#define	VER_NDX_LORESERVE	0xff00	/* Beginning of reserved entries.  */
+#define	VER_NDX_ELIMINATE	0xff01	/* Symbol is to be eliminated.  */
+
+/* Auxialiary version information.  */
+
+typedef struct
+{
+  Elf32_Word	vda_name;		/* Version or dependency names */
+  Elf32_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} Elf32_Verdaux;
+
+typedef struct
+{
+  Elf64_Word	vda_name;		/* Version or dependency names */
+  Elf64_Word	vda_next;		/* Offset in bytes to next verdaux
+					   entry */
+} Elf64_Verdaux;
+
+
+/* Version dependency section.  */
+
+typedef struct
+{
+  Elf32_Half	vn_version;		/* Version of structure */
+  Elf32_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf32_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf32_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf32_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} Elf32_Verneed;
+
+typedef struct
+{
+  Elf64_Half	vn_version;		/* Version of structure */
+  Elf64_Half	vn_cnt;			/* Number of associated aux entries */
+  Elf64_Word	vn_file;		/* Offset of filename for this
+					   dependency */
+  Elf64_Word	vn_aux;			/* Offset in bytes to vernaux array */
+  Elf64_Word	vn_next;		/* Offset in bytes to next verneed
+					   entry */
+} Elf64_Verneed;
+
+
+/* Legal values for vn_version (version revision).  */
+#define VER_NEED_NONE	 0		/* No version */
+#define VER_NEED_CURRENT 1		/* Current version */
+#define VER_NEED_NUM	 2		/* Given version number */
+
+/* Auxiliary needed version information.  */
+
+typedef struct
+{
+  Elf32_Word	vna_hash;		/* Hash value of dependency name */
+  Elf32_Half	vna_flags;		/* Dependency specific information */
+  Elf32_Half	vna_other;		/* Unused */
+  Elf32_Word	vna_name;		/* Dependency name string offset */
+  Elf32_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} Elf32_Vernaux;
+
+typedef struct
+{
+  Elf64_Word	vna_hash;		/* Hash value of dependency name */
+  Elf64_Half	vna_flags;		/* Dependency specific information */
+  Elf64_Half	vna_other;		/* Unused */
+  Elf64_Word	vna_name;		/* Dependency name string offset */
+  Elf64_Word	vna_next;		/* Offset in bytes to next vernaux
+					   entry */
+} Elf64_Vernaux;
+
+
+/* Legal values for vna_flags.  */
+#define VER_FLG_WEAK	0x2		/* Weak version identifier */
+
+
+/* Auxiliary vector.  */
+
+/* This vector is normally only used by the program interpreter.  The
+   usual definition in an ABI supplement uses the name auxv_t.  The
+   vector is not usually defined in a standard <elf.h> file, but it
+   can't hurt.  We rename it to avoid conflicts.  The sizes of these
+   types are an arrangement between the exec server and the program
+   interpreter, so we don't fully specify them here.  */
+
+typedef struct
+{
+  uint32_t a_type;		/* Entry type */
+  union
+    {
+      uint32_t a_val;		/* Integer value */
+      /* We use to have pointer elements added here.  We cannot do that,
+	 though, since it does not work when using 32-bit definitions
+	 on 64-bit platforms and vice versa.  */
+    } a_un;
+} Elf32_auxv_t;
+
+typedef struct
+{
+  uint64_t a_type;		/* Entry type */
+  union
+    {
+      uint64_t a_val;		/* Integer value */
+      /* We use to have pointer elements added here.  We cannot do that,
+	 though, since it does not work when using 32-bit definitions
+	 on 64-bit platforms and vice versa.  */
+    } a_un;
+} Elf64_auxv_t;
+
+/* Legal values for a_type (entry type).  */
+
+#define AT_NULL		0		/* End of vector */
+#define AT_IGNORE	1		/* Entry should be ignored */
+#define AT_EXECFD	2		/* File descriptor of program */
+#define AT_PHDR		3		/* Program headers for program */
+#define AT_PHENT	4		/* Size of program header entry */
+#define AT_PHNUM	5		/* Number of program headers */
+#define AT_PAGESZ	6		/* System page size */
+#define AT_BASE		7		/* Base address of interpreter */
+#define AT_FLAGS	8		/* Flags */
+#define AT_ENTRY	9		/* Entry point of program */
+#define AT_NOTELF	10		/* Program is not ELF */
+#define AT_UID		11		/* Real uid */
+#define AT_EUID		12		/* Effective uid */
+#define AT_GID		13		/* Real gid */
+#define AT_EGID		14		/* Effective gid */
+#define AT_CLKTCK	17		/* Frequency of times() */
+
+/* Some more special a_type values describing the hardware.  */
+#define AT_PLATFORM	15		/* String identifying platform.  */
+#define AT_HWCAP	16		/* Machine-dependent hints about
+					   processor capabilities.  */
+
+/* This entry gives some information about the FPU initialization
+   performed by the kernel.  */
+#define AT_FPUCW	18		/* Used FPU control word.  */
+
+/* Cache block sizes.  */
+#define AT_DCACHEBSIZE	19		/* Data cache block size.  */
+#define AT_ICACHEBSIZE	20		/* Instruction cache block size.  */
+#define AT_UCACHEBSIZE	21		/* Unified cache block size.  */
+
+/* A special ignored value for PPC, used by the kernel to control the
+   interpretation of the AUXV. Must be > 16.  */
+#define AT_IGNOREPPC	22		/* Entry should be ignored.  */
+
+#define	AT_SECURE	23		/* Boolean, was exec setuid-like?  */
+
+#define AT_BASE_PLATFORM 24		/* String identifying real platforms.*/
+
+#define AT_RANDOM	25		/* Address of 16 random bytes.  */
+
+#define AT_HWCAP2	26		/* More machine-dependent hints about
+					   processor capabilities.  */
+
+#define AT_EXECFN	31		/* Filename of executable.  */
+
+/* Pointer to the global system page used for system calls and other
+   nice things.  */
+#define AT_SYSINFO	32
+#define AT_SYSINFO_EHDR	33
+
+/* Shapes of the caches.  Bits 0-3 contains associativity; bits 4-7 contains
+   log2 of line size; mask those to get cache size.  */
+#define AT_L1I_CACHESHAPE	34
+#define AT_L1D_CACHESHAPE	35
+#define AT_L2_CACHESHAPE	36
+#define AT_L3_CACHESHAPE	37
+
+/* Shapes of the caches, with more room to describe them.
+   *GEOMETRY are comprised of cache line size in bytes in the bottom 16 bits
+   and the cache associativity in the next 16 bits.  */
+#define AT_L1I_CACHESIZE	40
+#define AT_L1I_CACHEGEOMETRY	41
+#define AT_L1D_CACHESIZE	42
+#define AT_L1D_CACHEGEOMETRY	43
+#define AT_L2_CACHESIZE		44
+#define AT_L2_CACHEGEOMETRY	45
+#define AT_L3_CACHESIZE		46
+#define AT_L3_CACHEGEOMETRY	47
+
+/* Note section contents.  Each entry in the note section begins with
+   a header of a fixed form.  */
+
+typedef struct
+{
+  Elf32_Word n_namesz;			/* Length of the note's name.  */
+  Elf32_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf32_Word n_type;			/* Type of the note.  */
+} Elf32_Nhdr;
+
+typedef struct
+{
+  Elf64_Word n_namesz;			/* Length of the note's name.  */
+  Elf64_Word n_descsz;			/* Length of the note's descriptor.  */
+  Elf64_Word n_type;			/* Type of the note.  */
+} Elf64_Nhdr;
+
+/* Known names of notes.  */
+
+/* Solaris entries in the note section have this name.  */
+#define ELF_NOTE_SOLARIS	"SUNW Solaris"
+
+/* Note entries for GNU systems have this name.  */
+#define ELF_NOTE_GNU		"GNU"
+
+
+/* Defined types of notes for Solaris.  */
+
+/* Value of descriptor (one word) is desired pagesize for the binary.  */
+#define ELF_NOTE_PAGESIZE_HINT	1
+
+
+/* Defined note types for GNU systems.  */
+
+/* ABI information.  The descriptor consists of words:
+   word 0: OS descriptor
+   word 1: major version of the ABI
+   word 2: minor version of the ABI
+   word 3: subminor version of the ABI
+*/
+#define NT_GNU_ABI_TAG	1
+#define ELF_NOTE_ABI	NT_GNU_ABI_TAG /* Old name.  */
+
+/* Known OSes.  These values can appear in word 0 of an
+   NT_GNU_ABI_TAG note section entry.  */
+#define ELF_NOTE_OS_LINUX	0
+#define ELF_NOTE_OS_GNU		1
+#define ELF_NOTE_OS_SOLARIS2	2
+#define ELF_NOTE_OS_FREEBSD	3
+
+/* Synthetic hwcap information.  The descriptor begins with two words:
+   word 0: number of entries
+   word 1: bitmask of enabled entries
+   Then follow variable-length entries, one byte followed by a
+   '\0'-terminated hwcap name string.  The byte gives the bit
+   number to test if enabled, (1U << bit) & bitmask.  */
+#define NT_GNU_HWCAP	2
+
+/* Build ID bits as generated by ld --build-id.
+   The descriptor consists of any nonzero number of bytes.  */
+#define NT_GNU_BUILD_ID	3
+
+/* Version note generated by GNU gold containing a version string.  */
+#define NT_GNU_GOLD_VERSION	4
+
+
+/* Move records.  */
+typedef struct
+{
+  Elf32_Xword m_value;		/* Symbol value.  */
+  Elf32_Word m_info;		/* Size and index.  */
+  Elf32_Word m_poffset;		/* Symbol offset.  */
+  Elf32_Half m_repeat;		/* Repeat count.  */
+  Elf32_Half m_stride;		/* Stride info.  */
+} Elf32_Move;
+
+typedef struct
+{
+  Elf64_Xword m_value;		/* Symbol value.  */
+  Elf64_Xword m_info;		/* Size and index.  */
+  Elf64_Xword m_poffset;	/* Symbol offset.  */
+  Elf64_Half m_repeat;		/* Repeat count.  */
+  Elf64_Half m_stride;		/* Stride info.  */
+} Elf64_Move;
+
+/* Macro to construct move records.  */
+#define ELF32_M_SYM(info)	((info) >> 8)
+#define ELF32_M_SIZE(info)	((unsigned char) (info))
+#define ELF32_M_INFO(sym, size)	(((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info)	ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info)	ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size)	ELF32_M_INFO (sym, size)
+
+
+/* Motorola 68k specific definitions.  */
+
+/* Values for Elf32_Ehdr.e_flags.  */
+#define EF_CPU32	0x00810000
+
+/* m68k relocs.  */
+
+#define R_68K_NONE	0		/* No reloc */
+#define R_68K_32	1		/* Direct 32 bit  */
+#define R_68K_16	2		/* Direct 16 bit  */
+#define R_68K_8		3		/* Direct 8 bit  */
+#define R_68K_PC32	4		/* PC relative 32 bit */
+#define R_68K_PC16	5		/* PC relative 16 bit */
+#define R_68K_PC8	6		/* PC relative 8 bit */
+#define R_68K_GOT32	7		/* 32 bit PC relative GOT entry */
+#define R_68K_GOT16	8		/* 16 bit PC relative GOT entry */
+#define R_68K_GOT8	9		/* 8 bit PC relative GOT entry */
+#define R_68K_GOT32O	10		/* 32 bit GOT offset */
+#define R_68K_GOT16O	11		/* 16 bit GOT offset */
+#define R_68K_GOT8O	12		/* 8 bit GOT offset */
+#define R_68K_PLT32	13		/* 32 bit PC relative PLT address */
+#define R_68K_PLT16	14		/* 16 bit PC relative PLT address */
+#define R_68K_PLT8	15		/* 8 bit PC relative PLT address */
+#define R_68K_PLT32O	16		/* 32 bit PLT offset */
+#define R_68K_PLT16O	17		/* 16 bit PLT offset */
+#define R_68K_PLT8O	18		/* 8 bit PLT offset */
+#define R_68K_COPY	19		/* Copy symbol at runtime */
+#define R_68K_GLOB_DAT	20		/* Create GOT entry */
+#define R_68K_JMP_SLOT	21		/* Create PLT entry */
+#define R_68K_RELATIVE	22		/* Adjust by program base */
+#define R_68K_TLS_GD32      25          /* 32 bit GOT offset for GD */
+#define R_68K_TLS_GD16      26          /* 16 bit GOT offset for GD */
+#define R_68K_TLS_GD8       27          /* 8 bit GOT offset for GD */
+#define R_68K_TLS_LDM32     28          /* 32 bit GOT offset for LDM */
+#define R_68K_TLS_LDM16     29          /* 16 bit GOT offset for LDM */
+#define R_68K_TLS_LDM8      30          /* 8 bit GOT offset for LDM */
+#define R_68K_TLS_LDO32     31          /* 32 bit module-relative offset */
+#define R_68K_TLS_LDO16     32          /* 16 bit module-relative offset */
+#define R_68K_TLS_LDO8      33          /* 8 bit module-relative offset */
+#define R_68K_TLS_IE32      34          /* 32 bit GOT offset for IE */
+#define R_68K_TLS_IE16      35          /* 16 bit GOT offset for IE */
+#define R_68K_TLS_IE8       36          /* 8 bit GOT offset for IE */
+#define R_68K_TLS_LE32      37          /* 32 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_LE16      38          /* 16 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_LE8       39          /* 8 bit offset relative to
+					   static TLS block */
+#define R_68K_TLS_DTPMOD32  40          /* 32 bit module number */
+#define R_68K_TLS_DTPREL32  41          /* 32 bit module-relative offset */
+#define R_68K_TLS_TPREL32   42          /* 32 bit TP-relative offset */
+/* Keep this the last entry.  */
+#define R_68K_NUM	43
+
+/* Intel 80386 specific definitions.  */
+
+/* i386 relocs.  */
+
+#define R_386_NONE	   0		/* No reloc */
+#define R_386_32	   1		/* Direct 32 bit  */
+#define R_386_PC32	   2		/* PC relative 32 bit */
+#define R_386_GOT32	   3		/* 32 bit GOT entry */
+#define R_386_PLT32	   4		/* 32 bit PLT address */
+#define R_386_COPY	   5		/* Copy symbol at runtime */
+#define R_386_GLOB_DAT	   6		/* Create GOT entry */
+#define R_386_JMP_SLOT	   7		/* Create PLT entry */
+#define R_386_RELATIVE	   8		/* Adjust by program base */
+#define R_386_GOTOFF	   9		/* 32 bit offset to GOT */
+#define R_386_GOTPC	   10		/* 32 bit PC relative offset to GOT */
+#define R_386_32PLT	   11
+#define R_386_TLS_TPOFF	   14		/* Offset in static TLS block */
+#define R_386_TLS_IE	   15		/* Address of GOT entry for static TLS
+					   block offset */
+#define R_386_TLS_GOTIE	   16		/* GOT entry for static TLS block
+					   offset */
+#define R_386_TLS_LE	   17		/* Offset relative to static TLS
+					   block */
+#define R_386_TLS_GD	   18		/* Direct 32 bit for GNU version of
+					   general dynamic thread local data */
+#define R_386_TLS_LDM	   19		/* Direct 32 bit for GNU version of
+					   local dynamic thread local data
+					   in LE code */
+#define R_386_16	   20
+#define R_386_PC16	   21
+#define R_386_8		   22
+#define R_386_PC8	   23
+#define R_386_TLS_GD_32	   24		/* Direct 32 bit for general dynamic
+					   thread local data */
+#define R_386_TLS_GD_PUSH  25		/* Tag for pushl in GD TLS code */
+#define R_386_TLS_GD_CALL  26		/* Relocation for call to
+					   __tls_get_addr() */
+#define R_386_TLS_GD_POP   27		/* Tag for popl in GD TLS code */
+#define R_386_TLS_LDM_32   28		/* Direct 32 bit for local dynamic
+					   thread local data in LE code */
+#define R_386_TLS_LDM_PUSH 29		/* Tag for pushl in LDM TLS code */
+#define R_386_TLS_LDM_CALL 30		/* Relocation for call to
+					   __tls_get_addr() in LDM code */
+#define R_386_TLS_LDM_POP  31		/* Tag for popl in LDM TLS code */
+#define R_386_TLS_LDO_32   32		/* Offset relative to TLS block */
+#define R_386_TLS_IE_32	   33		/* GOT entry for negated static TLS
+					   block offset */
+#define R_386_TLS_LE_32	   34		/* Negated offset relative to static
+					   TLS block */
+#define R_386_TLS_DTPMOD32 35		/* ID of module containing symbol */
+#define R_386_TLS_DTPOFF32 36		/* Offset in TLS block */
+#define R_386_TLS_TPOFF32  37		/* Negated offset in static TLS block */
+#define R_386_SIZE32	   38 		/* 32-bit symbol size */
+#define R_386_TLS_GOTDESC  39		/* GOT offset for TLS descriptor.  */
+#define R_386_TLS_DESC_CALL 40		/* Marker of call through TLS
+					   descriptor for
+					   relaxation.  */
+#define R_386_TLS_DESC     41		/* TLS descriptor containing
+					   pointer to code and to
+					   argument, returning the TLS
+					   offset for the symbol.  */
+#define R_386_IRELATIVE	   42		/* Adjust indirectly by program base */
+#define R_386_GOT32X	   43		/* Load from 32 bit GOT entry,
+					   relaxable. */
+/* Keep this the last entry.  */
+#define R_386_NUM	   44
+
+/* SUN SPARC specific definitions.  */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_SPARC_REGISTER	13	/* Global register reserved to app. */
+
+/* Values for Elf64_Ehdr.e_flags.  */
+
+#define EF_SPARCV9_MM		3
+#define EF_SPARCV9_TSO		0
+#define EF_SPARCV9_PSO		1
+#define EF_SPARCV9_RMO		2
+#define EF_SPARC_LEDATA		0x800000 /* little endian data */
+#define EF_SPARC_EXT_MASK	0xFFFF00
+#define EF_SPARC_32PLUS		0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1	0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1		0x000400 /* HAL R1 extensions */
+#define EF_SPARC_SUN_US3	0x000800 /* Sun UltraSPARCIII extensions */
+
+/* SPARC relocs.  */
+
+#define R_SPARC_NONE		0	/* No reloc */
+#define R_SPARC_8		1	/* Direct 8 bit */
+#define R_SPARC_16		2	/* Direct 16 bit */
+#define R_SPARC_32		3	/* Direct 32 bit */
+#define R_SPARC_DISP8		4	/* PC relative 8 bit */
+#define R_SPARC_DISP16		5	/* PC relative 16 bit */
+#define R_SPARC_DISP32		6	/* PC relative 32 bit */
+#define R_SPARC_WDISP30		7	/* PC relative 30 bit shifted */
+#define R_SPARC_WDISP22		8	/* PC relative 22 bit shifted */
+#define R_SPARC_HI22		9	/* High 22 bit */
+#define R_SPARC_22		10	/* Direct 22 bit */
+#define R_SPARC_13		11	/* Direct 13 bit */
+#define R_SPARC_LO10		12	/* Truncated 10 bit */
+#define R_SPARC_GOT10		13	/* Truncated 10 bit GOT entry */
+#define R_SPARC_GOT13		14	/* 13 bit GOT entry */
+#define R_SPARC_GOT22		15	/* 22 bit GOT entry shifted */
+#define R_SPARC_PC10		16	/* PC relative 10 bit truncated */
+#define R_SPARC_PC22		17	/* PC relative 22 bit shifted */
+#define R_SPARC_WPLT30		18	/* 30 bit PC relative PLT address */
+#define R_SPARC_COPY		19	/* Copy symbol at runtime */
+#define R_SPARC_GLOB_DAT	20	/* Create GOT entry */
+#define R_SPARC_JMP_SLOT	21	/* Create PLT entry */
+#define R_SPARC_RELATIVE	22	/* Adjust by program base */
+#define R_SPARC_UA32		23	/* Direct 32 bit unaligned */
+
+/* Additional Sparc64 relocs.  */
+
+#define R_SPARC_PLT32		24	/* Direct 32 bit ref to PLT entry */
+#define R_SPARC_HIPLT22		25	/* High 22 bit PLT entry */
+#define R_SPARC_LOPLT10		26	/* Truncated 10 bit PLT entry */
+#define R_SPARC_PCPLT32		27	/* PC rel 32 bit ref to PLT entry */
+#define R_SPARC_PCPLT22		28	/* PC rel high 22 bit PLT entry */
+#define R_SPARC_PCPLT10		29	/* PC rel trunc 10 bit PLT entry */
+#define R_SPARC_10		30	/* Direct 10 bit */
+#define R_SPARC_11		31	/* Direct 11 bit */
+#define R_SPARC_64		32	/* Direct 64 bit */
+#define R_SPARC_OLO10		33	/* 10bit with secondary 13bit addend */
+#define R_SPARC_HH22		34	/* Top 22 bits of direct 64 bit */
+#define R_SPARC_HM10		35	/* High middle 10 bits of ... */
+#define R_SPARC_LM22		36	/* Low middle 22 bits of ... */
+#define R_SPARC_PC_HH22		37	/* Top 22 bits of pc rel 64 bit */
+#define R_SPARC_PC_HM10		38	/* High middle 10 bit of ... */
+#define R_SPARC_PC_LM22		39	/* Low miggle 22 bits of ... */
+#define R_SPARC_WDISP16		40	/* PC relative 16 bit shifted */
+#define R_SPARC_WDISP19		41	/* PC relative 19 bit shifted */
+#define R_SPARC_GLOB_JMP	42	/* was part of v9 ABI but was removed */
+#define R_SPARC_7		43	/* Direct 7 bit */
+#define R_SPARC_5		44	/* Direct 5 bit */
+#define R_SPARC_6		45	/* Direct 6 bit */
+#define R_SPARC_DISP64		46	/* PC relative 64 bit */
+#define R_SPARC_PLT64		47	/* Direct 64 bit ref to PLT entry */
+#define R_SPARC_HIX22		48	/* High 22 bit complemented */
+#define R_SPARC_LOX10		49	/* Truncated 11 bit complemented */
+#define R_SPARC_H44		50	/* Direct high 12 of 44 bit */
+#define R_SPARC_M44		51	/* Direct mid 22 of 44 bit */
+#define R_SPARC_L44		52	/* Direct low 10 of 44 bit */
+#define R_SPARC_REGISTER	53	/* Global register usage */
+#define R_SPARC_UA64		54	/* Direct 64 bit unaligned */
+#define R_SPARC_UA16		55	/* Direct 16 bit unaligned */
+#define R_SPARC_TLS_GD_HI22	56
+#define R_SPARC_TLS_GD_LO10	57
+#define R_SPARC_TLS_GD_ADD	58
+#define R_SPARC_TLS_GD_CALL	59
+#define R_SPARC_TLS_LDM_HI22	60
+#define R_SPARC_TLS_LDM_LO10	61
+#define R_SPARC_TLS_LDM_ADD	62
+#define R_SPARC_TLS_LDM_CALL	63
+#define R_SPARC_TLS_LDO_HIX22	64
+#define R_SPARC_TLS_LDO_LOX10	65
+#define R_SPARC_TLS_LDO_ADD	66
+#define R_SPARC_TLS_IE_HI22	67
+#define R_SPARC_TLS_IE_LO10	68
+#define R_SPARC_TLS_IE_LD	69
+#define R_SPARC_TLS_IE_LDX	70
+#define R_SPARC_TLS_IE_ADD	71
+#define R_SPARC_TLS_LE_HIX22	72
+#define R_SPARC_TLS_LE_LOX10	73
+#define R_SPARC_TLS_DTPMOD32	74
+#define R_SPARC_TLS_DTPMOD64	75
+#define R_SPARC_TLS_DTPOFF32	76
+#define R_SPARC_TLS_DTPOFF64	77
+#define R_SPARC_TLS_TPOFF32	78
+#define R_SPARC_TLS_TPOFF64	79
+#define R_SPARC_GOTDATA_HIX22	80
+#define R_SPARC_GOTDATA_LOX10	81
+#define R_SPARC_GOTDATA_OP_HIX22	82
+#define R_SPARC_GOTDATA_OP_LOX10	83
+#define R_SPARC_GOTDATA_OP	84
+#define R_SPARC_H34		85
+#define R_SPARC_SIZE32		86
+#define R_SPARC_SIZE64		87
+#define R_SPARC_WDISP10		88
+#define R_SPARC_JMP_IREL	248
+#define R_SPARC_IRELATIVE	249
+#define R_SPARC_GNU_VTINHERIT	250
+#define R_SPARC_GNU_VTENTRY	251
+#define R_SPARC_REV32		252
+/* Keep this the last entry.  */
+#define R_SPARC_NUM		253
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
+
+#define DT_SPARC_REGISTER	0x70000001
+#define DT_SPARC_NUM		2
+
+/* MIPS R3000 specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_MIPS_NOREORDER	1     /* A .noreorder directive was used.  */
+#define EF_MIPS_PIC		2     /* Contains PIC code.  */
+#define EF_MIPS_CPIC		4     /* Uses PIC calling sequence.  */
+#define EF_MIPS_XGOT		8
+#define EF_MIPS_64BIT_WHIRL	16
+#define EF_MIPS_ABI2		32
+#define EF_MIPS_ABI_ON32	64
+#define EF_MIPS_FP64		512  /* Uses FP64 (12 callee-saved).  */
+#define EF_MIPS_NAN2008	1024  /* Uses IEEE 754-2008 NaN encoding.  */
+#define EF_MIPS_ARCH		0xf0000000 /* MIPS architecture level.  */
+
+/* Legal values for MIPS architecture level.  */
+
+#define EF_MIPS_ARCH_1		0x00000000 /* -mips1 code.  */
+#define EF_MIPS_ARCH_2		0x10000000 /* -mips2 code.  */
+#define EF_MIPS_ARCH_3		0x20000000 /* -mips3 code.  */
+#define EF_MIPS_ARCH_4		0x30000000 /* -mips4 code.  */
+#define EF_MIPS_ARCH_5		0x40000000 /* -mips5 code.  */
+#define EF_MIPS_ARCH_32		0x50000000 /* MIPS32 code.  */
+#define EF_MIPS_ARCH_64		0x60000000 /* MIPS64 code.  */
+#define EF_MIPS_ARCH_32R2	0x70000000 /* MIPS32r2 code.  */
+#define EF_MIPS_ARCH_64R2	0x80000000 /* MIPS64r2 code.  */
+
+/* The following are unofficial names and should not be used.  */
+
+#define E_MIPS_ARCH_1		EF_MIPS_ARCH_1
+#define E_MIPS_ARCH_2		EF_MIPS_ARCH_2
+#define E_MIPS_ARCH_3		EF_MIPS_ARCH_3
+#define E_MIPS_ARCH_4		EF_MIPS_ARCH_4
+#define E_MIPS_ARCH_5		EF_MIPS_ARCH_5
+#define E_MIPS_ARCH_32		EF_MIPS_ARCH_32
+#define E_MIPS_ARCH_64		EF_MIPS_ARCH_64
+
+/* Special section indices.  */
+
+#define SHN_MIPS_ACOMMON	0xff00	/* Allocated common symbols.  */
+#define SHN_MIPS_TEXT		0xff01	/* Allocated test symbols.  */
+#define SHN_MIPS_DATA		0xff02	/* Allocated data symbols.  */
+#define SHN_MIPS_SCOMMON 	0xff03	/* Small common symbols.  */
+#define SHN_MIPS_SUNDEFINED	0xff04	/* Small undefined symbols.  */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_MIPS_LIBLIST	0x70000000 /* Shared objects used in link.  */
+#define SHT_MIPS_MSYM		0x70000001
+#define SHT_MIPS_CONFLICT	0x70000002 /* Conflicting symbols.  */
+#define SHT_MIPS_GPTAB		0x70000003 /* Global data area sizes.  */
+#define SHT_MIPS_UCODE		0x70000004 /* Reserved for SGI/MIPS compilers */
+#define SHT_MIPS_DEBUG		0x70000005 /* MIPS ECOFF debugging info.  */
+#define SHT_MIPS_REGINFO	0x70000006 /* Register usage information.  */
+#define SHT_MIPS_PACKAGE	0x70000007
+#define SHT_MIPS_PACKSYM	0x70000008
+#define SHT_MIPS_RELD		0x70000009
+#define SHT_MIPS_IFACE		0x7000000b
+#define SHT_MIPS_CONTENT	0x7000000c
+#define SHT_MIPS_OPTIONS	0x7000000d /* Miscellaneous options.  */
+#define SHT_MIPS_SHDR		0x70000010
+#define SHT_MIPS_FDESC		0x70000011
+#define SHT_MIPS_EXTSYM		0x70000012
+#define SHT_MIPS_DENSE		0x70000013
+#define SHT_MIPS_PDESC		0x70000014
+#define SHT_MIPS_LOCSYM		0x70000015
+#define SHT_MIPS_AUXSYM		0x70000016
+#define SHT_MIPS_OPTSYM		0x70000017
+#define SHT_MIPS_LOCSTR		0x70000018
+#define SHT_MIPS_LINE		0x70000019
+#define SHT_MIPS_RFDESC		0x7000001a
+#define SHT_MIPS_DELTASYM	0x7000001b
+#define SHT_MIPS_DELTAINST	0x7000001c
+#define SHT_MIPS_DELTACLASS	0x7000001d
+#define SHT_MIPS_DWARF		0x7000001e /* DWARF debugging information.  */
+#define SHT_MIPS_DELTADECL	0x7000001f
+#define SHT_MIPS_SYMBOL_LIB	0x70000020
+#define SHT_MIPS_EVENTS		0x70000021 /* Event section.  */
+#define SHT_MIPS_TRANSLATE	0x70000022
+#define SHT_MIPS_PIXIE		0x70000023
+#define SHT_MIPS_XLATE		0x70000024
+#define SHT_MIPS_XLATE_DEBUG	0x70000025
+#define SHT_MIPS_WHIRL		0x70000026
+#define SHT_MIPS_EH_REGION	0x70000027
+#define SHT_MIPS_XLATE_OLD	0x70000028
+#define SHT_MIPS_PDR_EXCEPTION	0x70000029
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_MIPS_GPREL		0x10000000 /* Must be in global data area.  */
+#define SHF_MIPS_MERGE		0x20000000
+#define SHF_MIPS_ADDR		0x40000000
+#define SHF_MIPS_STRINGS	0x80000000
+#define SHF_MIPS_NOSTRIP	0x08000000
+#define SHF_MIPS_LOCAL		0x04000000
+#define SHF_MIPS_NAMES		0x02000000
+#define SHF_MIPS_NODUPE		0x01000000
+
+
+/* Symbol tables.  */
+
+/* MIPS specific values for `st_other'.  */
+#define STO_MIPS_DEFAULT		0x0
+#define STO_MIPS_INTERNAL		0x1
+#define STO_MIPS_HIDDEN			0x2
+#define STO_MIPS_PROTECTED		0x3
+#define STO_MIPS_PLT			0x8
+#define STO_MIPS_SC_ALIGN_UNUSED	0xff
+
+/* MIPS specific values for `st_info'.  */
+#define STB_MIPS_SPLIT_COMMON		13
+
+/* Entries found in sections of type SHT_MIPS_GPTAB.  */
+
+typedef union
+{
+  struct
+    {
+      Elf32_Word gt_current_g_value;	/* -G value used for compilation.  */
+      Elf32_Word gt_unused;		/* Not used.  */
+    } gt_header;			/* First entry in section.  */
+  struct
+    {
+      Elf32_Word gt_g_value;		/* If this value were used for -G.  */
+      Elf32_Word gt_bytes;		/* This many bytes would be used.  */
+    } gt_entry;				/* Subsequent entries in section.  */
+} Elf32_gptab;
+
+/* Entry found in sections of type SHT_MIPS_REGINFO.  */
+
+typedef struct
+{
+  Elf32_Word ri_gprmask;		/* General registers used.  */
+  Elf32_Word ri_cprmask[4];		/* Coprocessor registers used.  */
+  Elf32_Sword ri_gp_value;		/* $gp register value.  */
+} Elf32_RegInfo;
+
+/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
+
+typedef struct
+{
+  unsigned char kind;		/* Determines interpretation of the
+				   variable part of descriptor.  */
+  unsigned char size;		/* Size of descriptor, including header.  */
+  Elf32_Section section;	/* Section header index of section affected,
+				   0 for global options.  */
+  Elf32_Word info;		/* Kind-specific information.  */
+} Elf_Options;
+
+/* Values for `kind' field in Elf_Options.  */
+
+#define ODK_NULL	0	/* Undefined.  */
+#define ODK_REGINFO	1	/* Register usage information.  */
+#define ODK_EXCEPTIONS	2	/* Exception processing options.  */
+#define ODK_PAD		3	/* Section padding options.  */
+#define ODK_HWPATCH	4	/* Hardware workarounds performed */
+#define ODK_FILL	5	/* record the fill value used by the linker. */
+#define ODK_TAGS	6	/* reserve space for desktop tools to write. */
+#define ODK_HWAND	7	/* HW workarounds.  'AND' bits when merging. */
+#define ODK_HWOR	8	/* HW workarounds.  'OR' bits when merging.  */
+
+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
+
+#define OEX_FPU_MIN	0x1f	/* FPE's which MUST be enabled.  */
+#define OEX_FPU_MAX	0x1f00	/* FPE's which MAY be enabled.  */
+#define OEX_PAGE0	0x10000	/* page zero must be mapped.  */
+#define OEX_SMM		0x20000	/* Force sequential memory mode?  */
+#define OEX_FPDBUG	0x40000	/* Force floating point debug mode?  */
+#define OEX_PRECISEFP	OEX_FPDBUG
+#define OEX_DISMISS	0x80000	/* Dismiss invalid address faults?  */
+
+#define OEX_FPU_INVAL	0x10
+#define OEX_FPU_DIV0	0x08
+#define OEX_FPU_OFLO	0x04
+#define OEX_FPU_UFLO	0x02
+#define OEX_FPU_INEX	0x01
+
+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
+
+#define OHW_R4KEOP	0x1	/* R4000 end-of-page patch.  */
+#define OHW_R8KPFETCH	0x2	/* may need R8000 prefetch patch.  */
+#define OHW_R5KEOP	0x4	/* R5000 end-of-page patch.  */
+#define OHW_R5KCVTL	0x8	/* R5000 cvt.[ds].l bug.  clean=1.  */
+
+#define OPAD_PREFIX	0x1
+#define OPAD_POSTFIX	0x2
+#define OPAD_SYMBOL	0x4
+
+/* Entry found in `.options' section.  */
+
+typedef struct
+{
+  Elf32_Word hwp_flags1;	/* Extra flags.  */
+  Elf32_Word hwp_flags2;	/* Extra flags.  */
+} Elf_Options_Hw;
+
+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
+
+#define OHWA0_R4KEOP_CHECKED	0x00000001
+#define OHWA1_R4KEOP_CLEAN	0x00000002
+
+/* MIPS relocs.  */
+
+#define R_MIPS_NONE		0	/* No reloc */
+#define R_MIPS_16		1	/* Direct 16 bit */
+#define R_MIPS_32		2	/* Direct 32 bit */
+#define R_MIPS_REL32		3	/* PC relative 32 bit */
+#define R_MIPS_26		4	/* Direct 26 bit shifted */
+#define R_MIPS_HI16		5	/* High 16 bit */
+#define R_MIPS_LO16		6	/* Low 16 bit */
+#define R_MIPS_GPREL16		7	/* GP relative 16 bit */
+#define R_MIPS_LITERAL		8	/* 16 bit literal entry */
+#define R_MIPS_GOT16		9	/* 16 bit GOT entry */
+#define R_MIPS_PC16		10	/* PC relative 16 bit */
+#define R_MIPS_CALL16		11	/* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32		12	/* GP relative 32 bit */
+
+#define R_MIPS_SHIFT5		16
+#define R_MIPS_SHIFT6		17
+#define R_MIPS_64		18
+#define R_MIPS_GOT_DISP		19
+#define R_MIPS_GOT_PAGE		20
+#define R_MIPS_GOT_OFST		21
+#define R_MIPS_GOT_HI16		22
+#define R_MIPS_GOT_LO16		23
+#define R_MIPS_SUB		24
+#define R_MIPS_INSERT_A		25
+#define R_MIPS_INSERT_B		26
+#define R_MIPS_DELETE		27
+#define R_MIPS_HIGHER		28
+#define R_MIPS_HIGHEST		29
+#define R_MIPS_CALL_HI16	30
+#define R_MIPS_CALL_LO16	31
+#define R_MIPS_SCN_DISP		32
+#define R_MIPS_REL16		33
+#define R_MIPS_ADD_IMMEDIATE	34
+#define R_MIPS_PJUMP		35
+#define R_MIPS_RELGOT		36
+#define R_MIPS_JALR		37
+#define R_MIPS_TLS_DTPMOD32	38	/* Module number 32 bit */
+#define R_MIPS_TLS_DTPREL32	39	/* Module-relative offset 32 bit */
+#define R_MIPS_TLS_DTPMOD64	40	/* Module number 64 bit */
+#define R_MIPS_TLS_DTPREL64	41	/* Module-relative offset 64 bit */
+#define R_MIPS_TLS_GD		42	/* 16 bit GOT offset for GD */
+#define R_MIPS_TLS_LDM		43	/* 16 bit GOT offset for LDM */
+#define R_MIPS_TLS_DTPREL_HI16	44	/* Module-relative offset, high 16 bits */
+#define R_MIPS_TLS_DTPREL_LO16	45	/* Module-relative offset, low 16 bits */
+#define R_MIPS_TLS_GOTTPREL	46	/* 16 bit GOT offset for IE */
+#define R_MIPS_TLS_TPREL32	47	/* TP-relative offset, 32 bit */
+#define R_MIPS_TLS_TPREL64	48	/* TP-relative offset, 64 bit */
+#define R_MIPS_TLS_TPREL_HI16	49	/* TP-relative offset, high 16 bits */
+#define R_MIPS_TLS_TPREL_LO16	50	/* TP-relative offset, low 16 bits */
+#define R_MIPS_GLOB_DAT		51
+#define R_MIPS_COPY		126
+#define R_MIPS_JUMP_SLOT        127
+/* Keep this the last entry.  */
+#define R_MIPS_NUM		128
+
+/* Legal values for p_type field of Elf32_Phdr.  */
+
+#define PT_MIPS_REGINFO	  0x70000000	/* Register usage information. */
+#define PT_MIPS_RTPROC	  0x70000001	/* Runtime procedure table. */
+#define PT_MIPS_OPTIONS	  0x70000002
+#define PT_MIPS_ABIFLAGS  0x70000003	/* FP mode requirement. */
+
+/* Special program header types.  */
+
+#define PF_MIPS_LOCAL	0x10000000
+
+/* Legal values for d_tag field of Elf32_Dyn.  */
+
+#define DT_MIPS_RLD_VERSION  0x70000001	/* Runtime linker interface version */
+#define DT_MIPS_TIME_STAMP   0x70000002	/* Timestamp */
+#define DT_MIPS_ICHECKSUM    0x70000003	/* Checksum */
+#define DT_MIPS_IVERSION     0x70000004	/* Version string (string tbl index) */
+#define DT_MIPS_FLAGS	     0x70000005	/* Flags */
+#define DT_MIPS_BASE_ADDRESS 0x70000006	/* Base address */
+#define DT_MIPS_MSYM	     0x70000007
+#define DT_MIPS_CONFLICT     0x70000008	/* Address of CONFLICT section */
+#define DT_MIPS_LIBLIST	     0x70000009	/* Address of LIBLIST section */
+#define DT_MIPS_LOCAL_GOTNO  0x7000000a	/* Number of local GOT entries */
+#define DT_MIPS_CONFLICTNO   0x7000000b	/* Number of CONFLICT entries */
+#define DT_MIPS_LIBLISTNO    0x70000010	/* Number of LIBLIST entries */
+#define DT_MIPS_SYMTABNO     0x70000011	/* Number of DYNSYM entries */
+#define DT_MIPS_UNREFEXTNO   0x70000012	/* First external DYNSYM */
+#define DT_MIPS_GOTSYM	     0x70000013	/* First GOT entry in DYNSYM */
+#define DT_MIPS_HIPAGENO     0x70000014	/* Number of GOT page table entries */
+#define DT_MIPS_RLD_MAP	     0x70000016	/* Address of run time loader map.  */
+#define DT_MIPS_DELTA_CLASS  0x70000017	/* Delta C++ class definition.  */
+#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
+						DT_MIPS_DELTA_CLASS.  */
+#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
+						DT_MIPS_DELTA_INSTANCE.  */
+#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
+					     DT_MIPS_DELTA_RELOC.  */
+#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
+					   relocations refer to.  */
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
+					   DT_MIPS_DELTA_SYM.  */
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
+					     class declaration.  */
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
+						DT_MIPS_DELTA_CLASSSYM.  */
+#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
+#define DT_MIPS_PIXIE_INIT   0x70000023
+#define DT_MIPS_SYMBOL_LIB   0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS	     0x70000029 /* Address of .options.  */
+#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
+						    function stored in GOT.  */
+#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
+					   by rld on dlopen() calls.  */
+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
+#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
+#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
+/* The address of .got.plt in an executable using the new non-PIC ABI.  */
+#define DT_MIPS_PLTGOT	     0x70000032
+/* The base of the PLT in an executable using the new non-PIC ABI if that
+   PLT is writable.  For a non-writable PLT, this is omitted or has a zero
+   value.  */
+#define DT_MIPS_RWPLT        0x70000034
+/* An alternative description of the classic MIPS RLD_MAP that is usable
+   in a PIE as it stores a relative offset from the address of the tag
+   rather than an absolute address.  */
+#define DT_MIPS_RLD_MAP_REL  0x70000035
+#define DT_MIPS_NUM	     0x36
+
+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
+
+#define RHF_NONE		   0		/* No flags */
+#define RHF_QUICKSTART		   (1 << 0)	/* Use quickstart */
+#define RHF_NOTPOT		   (1 << 1)	/* Hash size not power of 2 */
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)	/* Ignore LD_LIBRARY_PATH */
+#define RHF_NO_MOVE		   (1 << 3)
+#define RHF_SGI_ONLY		   (1 << 4)
+#define RHF_GUARANTEE_INIT	   (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS	   (1 << 6)
+#define RHF_GUARANTEE_START_INIT   (1 << 7)
+#define RHF_PIXIE		   (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD	   (1 << 9)
+#define RHF_REQUICKSTART	   (1 << 10)
+#define RHF_REQUICKSTARTED	   (1 << 11)
+#define RHF_CORD		   (1 << 12)
+#define RHF_NO_UNRES_UNDEF	   (1 << 13)
+#define RHF_RLD_ORDER_SAFE	   (1 << 14)
+
+/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
+
+typedef struct
+{
+  Elf32_Word l_name;		/* Name (string table index) */
+  Elf32_Word l_time_stamp;	/* Timestamp */
+  Elf32_Word l_checksum;	/* Checksum */
+  Elf32_Word l_version;		/* Interface version */
+  Elf32_Word l_flags;		/* Flags */
+} Elf32_Lib;
+
+typedef struct
+{
+  Elf64_Word l_name;		/* Name (string table index) */
+  Elf64_Word l_time_stamp;	/* Timestamp */
+  Elf64_Word l_checksum;	/* Checksum */
+  Elf64_Word l_version;		/* Interface version */
+  Elf64_Word l_flags;		/* Flags */
+} Elf64_Lib;
+
+
+/* Legal values for l_flags.  */
+
+#define LL_NONE		  0
+#define LL_EXACT_MATCH	  (1 << 0)	/* Require exact match */
+#define LL_IGNORE_INT_VER (1 << 1)	/* Ignore interface version */
+#define LL_REQUIRE_MINOR  (1 << 2)
+#define LL_EXPORTS	  (1 << 3)
+#define LL_DELAY_LOAD	  (1 << 4)
+#define LL_DELTA	  (1 << 5)
+
+/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
+
+typedef Elf32_Addr Elf32_Conflict;
+
+typedef struct
+{
+  /* Version of flags structure.  */
+  Elf32_Half version;
+  /* The level of the ISA: 1-5, 32, 64.  */
+  unsigned char isa_level;
+  /* The revision of ISA: 0 for MIPS V and below, 1-n otherwise.  */
+  unsigned char isa_rev;
+  /* The size of general purpose registers.  */
+  unsigned char gpr_size;
+  /* The size of co-processor 1 registers.  */
+  unsigned char cpr1_size;
+  /* The size of co-processor 2 registers.  */
+  unsigned char cpr2_size;
+  /* The floating-point ABI.  */
+  unsigned char fp_abi;
+  /* Processor-specific extension.  */
+  Elf32_Word isa_ext;
+  /* Mask of ASEs used.  */
+  Elf32_Word ases;
+  /* Mask of general flags.  */
+  Elf32_Word flags1;
+  Elf32_Word flags2;
+} Elf_MIPS_ABIFlags_v0;
+
+/* Values for the register size bytes of an abi flags structure.  */
+
+#define MIPS_AFL_REG_NONE	0x00	 /* No registers.  */
+#define MIPS_AFL_REG_32		0x01	 /* 32-bit registers.  */
+#define MIPS_AFL_REG_64		0x02	 /* 64-bit registers.  */
+#define MIPS_AFL_REG_128	0x03	 /* 128-bit registers.  */
+
+/* Masks for the ases word of an ABI flags structure.  */
+
+#define MIPS_AFL_ASE_DSP	0x00000001 /* DSP ASE.  */
+#define MIPS_AFL_ASE_DSPR2	0x00000002 /* DSP R2 ASE.  */
+#define MIPS_AFL_ASE_EVA	0x00000004 /* Enhanced VA Scheme.  */
+#define MIPS_AFL_ASE_MCU	0x00000008 /* MCU (MicroController) ASE.  */
+#define MIPS_AFL_ASE_MDMX	0x00000010 /* MDMX ASE.  */
+#define MIPS_AFL_ASE_MIPS3D	0x00000020 /* MIPS-3D ASE.  */
+#define MIPS_AFL_ASE_MT		0x00000040 /* MT ASE.  */
+#define MIPS_AFL_ASE_SMARTMIPS	0x00000080 /* SmartMIPS ASE.  */
+#define MIPS_AFL_ASE_VIRT	0x00000100 /* VZ ASE.  */
+#define MIPS_AFL_ASE_MSA	0x00000200 /* MSA ASE.  */
+#define MIPS_AFL_ASE_MIPS16	0x00000400 /* MIPS16 ASE.  */
+#define MIPS_AFL_ASE_MICROMIPS	0x00000800 /* MICROMIPS ASE.  */
+#define MIPS_AFL_ASE_XPA	0x00001000 /* XPA ASE.  */
+#define MIPS_AFL_ASE_MASK	0x00001fff /* All ASEs.  */
+
+/* Values for the isa_ext word of an ABI flags structure.  */
+
+#define MIPS_AFL_EXT_XLR	  1   /* RMI Xlr instruction.  */
+#define MIPS_AFL_EXT_OCTEON2	  2   /* Cavium Networks Octeon2.  */
+#define MIPS_AFL_EXT_OCTEONP	  3   /* Cavium Networks OcteonP.  */
+#define MIPS_AFL_EXT_LOONGSON_3A  4   /* Loongson 3A.  */
+#define MIPS_AFL_EXT_OCTEON	  5   /* Cavium Networks Octeon.  */
+#define MIPS_AFL_EXT_5900	  6   /* MIPS R5900 instruction.  */
+#define MIPS_AFL_EXT_4650	  7   /* MIPS R4650 instruction.  */
+#define MIPS_AFL_EXT_4010	  8   /* LSI R4010 instruction.  */
+#define MIPS_AFL_EXT_4100	  9   /* NEC VR4100 instruction.  */
+#define MIPS_AFL_EXT_3900	  10  /* Toshiba R3900 instruction.  */
+#define MIPS_AFL_EXT_10000	  11  /* MIPS R10000 instruction.  */
+#define MIPS_AFL_EXT_SB1	  12  /* Broadcom SB-1 instruction.  */
+#define MIPS_AFL_EXT_4111	  13  /* NEC VR4111/VR4181 instruction.  */
+#define MIPS_AFL_EXT_4120	  14  /* NEC VR4120 instruction.  */
+#define MIPS_AFL_EXT_5400	  15  /* NEC VR5400 instruction.  */
+#define MIPS_AFL_EXT_5500	  16  /* NEC VR5500 instruction.  */
+#define MIPS_AFL_EXT_LOONGSON_2E  17  /* ST Microelectronics Loongson 2E.  */
+#define MIPS_AFL_EXT_LOONGSON_2F  18  /* ST Microelectronics Loongson 2F.  */
+
+/* Masks for the flags1 word of an ABI flags structure.  */
+#define MIPS_AFL_FLAGS1_ODDSPREG  1  /* Uses odd single-precision registers.  */
+
+/* Object attribute values.  */
+enum
+{
+  /* Not tagged or not using any ABIs affected by the differences.  */
+  Val_GNU_MIPS_ABI_FP_ANY = 0,
+  /* Using hard-float -mdouble-float.  */
+  Val_GNU_MIPS_ABI_FP_DOUBLE = 1,
+  /* Using hard-float -msingle-float.  */
+  Val_GNU_MIPS_ABI_FP_SINGLE = 2,
+  /* Using soft-float.  */
+  Val_GNU_MIPS_ABI_FP_SOFT = 3,
+  /* Using -mips32r2 -mfp64.  */
+  Val_GNU_MIPS_ABI_FP_OLD_64 = 4,
+  /* Using -mfpxx.  */
+  Val_GNU_MIPS_ABI_FP_XX = 5,
+  /* Using -mips32r2 -mfp64.  */
+  Val_GNU_MIPS_ABI_FP_64 = 6,
+  /* Using -mips32r2 -mfp64 -mno-odd-spreg.  */
+  Val_GNU_MIPS_ABI_FP_64A = 7,
+  /* Maximum allocated FP ABI value.  */
+  Val_GNU_MIPS_ABI_FP_MAX = 7
+};
+
+/* HPPA specific definitions.  */
+
+/* Legal values for e_flags field of Elf32_Ehdr.  */
+
+#define EF_PARISC_TRAPNIL	0x00010000 /* Trap nil pointer dereference.  */
+#define EF_PARISC_EXT		0x00020000 /* Program uses arch. extensions. */
+#define EF_PARISC_LSB		0x00040000 /* Program expects little endian. */
+#define EF_PARISC_WIDE		0x00080000 /* Program expects wide mode.  */
+#define EF_PARISC_NO_KABP	0x00100000 /* No kernel assisted branch
+					      prediction.  */
+#define EF_PARISC_LAZYSWAP	0x00400000 /* Allow lazy swapping.  */
+#define EF_PARISC_ARCH		0x0000ffff /* Architecture version.  */
+
+/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
+
+#define EFA_PARISC_1_0		    0x020b /* PA-RISC 1.0 big-endian.  */
+#define EFA_PARISC_1_1		    0x0210 /* PA-RISC 1.1 big-endian.  */
+#define EFA_PARISC_2_0		    0x0214 /* PA-RISC 2.0 big-endian.  */
+
+/* Additional section indeces.  */
+
+#define SHN_PARISC_ANSI_COMMON	0xff00	   /* Section for tenatively declared
+					      symbols in ANSI C.  */
+#define SHN_PARISC_HUGE_COMMON	0xff01	   /* Common blocks in huge model.  */
+
+/* Legal values for sh_type field of Elf32_Shdr.  */
+
+#define SHT_PARISC_EXT		0x70000000 /* Contains product specific ext. */
+#define SHT_PARISC_UNWIND	0x70000001 /* Unwind information.  */
+#define SHT_PARISC_DOC		0x70000002 /* Debug info for optimized code. */
+
+/* Legal values for sh_flags field of Elf32_Shdr.  */
+
+#define SHF_PARISC_SHORT	0x20000000 /* Section with short addressing. */
+#define SHF_PARISC_HUGE		0x40000000 /* Section far from gp.  */
+#define SHF_PARISC_SBP		0x80000000 /* Static branch prediction code. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
+
+#define STT_PARISC_MILLICODE	13	/* Millicode function entry point.  */
+
+#define STT_HP_OPAQUE		(STT_LOOS + 0x1)
+#define STT_HP_STUB		(STT_LOOS + 0x2)
+
+/* HPPA relocs.  */
+
+#define R_PARISC_NONE		0	/* No reloc.  */
+#define R_PARISC_DIR32		1	/* Direct 32-bit reference.  */
+#define R_PARISC_DIR21L		2	/* Left 21 bits of eff. address.  */
+#define R_PARISC_DIR17R		3	/* Right 17 bits of eff. address.  */
+#define R_PARISC_DIR17F		4	/* 17 bits of eff. address.  */
+#define R_PARISC_DIR14R		6	/* Right 14 bits of eff. address.  */
+#define R_PARISC_PCREL32	9	/* 32-bit rel. address.  */
+#define R_PARISC_PCREL21L	10	/* Left 21 bits of rel. address.  */
+#define R_PARISC_PCREL17R	11	/* Right 17 bits of rel. address.  */
+#define R_PARISC_PCREL17F	12	/* 17 bits of rel. address.  */
+#define R_PARISC_PCREL14R	14	/* Right 14 bits of rel. address.  */
+#define R_PARISC_DPREL21L	18	/* Left 21 bits of rel. address.  */
+#define R_PARISC_DPREL14R	22	/* Right 14 bits of rel. address.  */
+#define R_PARISC_GPREL21L	26	/* GP-relative, left 21 bits.  */
+#define R_PARISC_GPREL14R	30	/* GP-relative, right 14 bits.  */
+#define R_PARISC_LTOFF21L	34	/* LT-relative, left 21 bits.  */
+#define R_PARISC_LTOFF14R	38	/* LT-relative, right 14 bits.  */
+#define R_PARISC_SECREL32	41	/* 32 bits section rel. address.  */
+#define R_PARISC_SEGBASE	48	/* No relocation, set segment base.  */
+#define R_PARISC_SEGREL32	49	/* 32 bits segment rel. address.  */
+#define R_PARISC_PLTOFF21L	50	/* PLT rel. address, left 21 bits.  */
+#define R_PARISC_PLTOFF14R	54	/* PLT rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_FPTR32	57	/* 32 bits LT-rel. function pointer. */
+#define R_PARISC_LTOFF_FPTR21L	58	/* LT-rel. fct ptr, left 21 bits. */
+#define R_PARISC_LTOFF_FPTR14R	62	/* LT-rel. fct ptr, right 14 bits. */
+#define R_PARISC_FPTR64		64	/* 64 bits function address.  */
+#define R_PARISC_PLABEL32	65	/* 32 bits function address.  */
+#define R_PARISC_PLABEL21L	66	/* Left 21 bits of fdesc address.  */
+#define R_PARISC_PLABEL14R	70	/* Right 14 bits of fdesc address.  */
+#define R_PARISC_PCREL64	72	/* 64 bits PC-rel. address.  */
+#define R_PARISC_PCREL22F	74	/* 22 bits PC-rel. address.  */
+#define R_PARISC_PCREL14WR	75	/* PC-rel. address, right 14 bits.  */
+#define R_PARISC_PCREL14DR	76	/* PC rel. address, right 14 bits.  */
+#define R_PARISC_PCREL16F	77	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16WF	78	/* 16 bits PC-rel. address.  */
+#define R_PARISC_PCREL16DF	79	/* 16 bits PC-rel. address.  */
+#define R_PARISC_DIR64		80	/* 64 bits of eff. address.  */
+#define R_PARISC_DIR14WR	83	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR14DR	84	/* 14 bits of eff. address.  */
+#define R_PARISC_DIR16F		85	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16WF	86	/* 16 bits of eff. address.  */
+#define R_PARISC_DIR16DF	87	/* 16 bits of eff. address.  */
+#define R_PARISC_GPREL64	88	/* 64 bits of GP-rel. address.  */
+#define R_PARISC_GPREL14WR	91	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL14DR	92	/* GP-rel. address, right 14 bits.  */
+#define R_PARISC_GPREL16F	93	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16WF	94	/* 16 bits GP-rel. address.  */
+#define R_PARISC_GPREL16DF	95	/* 16 bits GP-rel. address.  */
+#define R_PARISC_LTOFF64	96	/* 64 bits LT-rel. address.  */
+#define R_PARISC_LTOFF14WR	99	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF14DR	100	/* LT-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF16F	101	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16WF	102	/* 16 bits LT-rel. address.  */
+#define R_PARISC_LTOFF16DF	103	/* 16 bits LT-rel. address.  */
+#define R_PARISC_SECREL64	104	/* 64 bits section rel. address.  */
+#define R_PARISC_SEGREL64	112	/* 64 bits segment rel. address.  */
+#define R_PARISC_PLTOFF14WR	115	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF14DR	116	/* PLT-rel. address, right 14 bits.  */
+#define R_PARISC_PLTOFF16F	117	/* 16 bits LT-rel. address.  */
+#define R_PARISC_PLTOFF16WF	118	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_PLTOFF16DF	119	/* 16 bits PLT-rel. address.  */
+#define R_PARISC_LTOFF_FPTR64	120	/* 64 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR14WR	123	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR14DR	124	/* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR16F	125	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16WF	126	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LTOFF_FPTR16DF	127	/* 16 bits LT-rel. function ptr.  */
+#define R_PARISC_LORESERVE	128
+#define R_PARISC_COPY		128	/* Copy relocation.  */
+#define R_PARISC_IPLT		129	/* Dynamic reloc, imported PLT */
+#define R_PARISC_EPLT		130	/* Dynamic reloc, exported PLT */
+#define R_PARISC_TPREL32	153	/* 32 bits TP-rel. address.  */
+#define R_PARISC_TPREL21L	154	/* TP-rel. address, left 21 bits.  */
+#define R_PARISC_TPREL14R	158	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_LTOFF_TP21L	162	/* LT-TP-rel. address, left 21 bits. */
+#define R_PARISC_LTOFF_TP14R	166	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14F	167	/* 14 bits LT-TP-rel. address.  */
+#define R_PARISC_TPREL64	216	/* 64 bits TP-rel. address.  */
+#define R_PARISC_TPREL14WR	219	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL14DR	220	/* TP-rel. address, right 14 bits.  */
+#define R_PARISC_TPREL16F	221	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16WF	222	/* 16 bits TP-rel. address.  */
+#define R_PARISC_TPREL16DF	223	/* 16 bits TP-rel. address.  */
+#define R_PARISC_LTOFF_TP64	224	/* 64 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP14WR	227	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14DR	228	/* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP16F	229	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16WF	230	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_LTOFF_TP16DF	231	/* 16 bits LT-TP-rel. address.  */
+#define R_PARISC_GNU_VTENTRY	232
+#define R_PARISC_GNU_VTINHERIT	233
+#define R_PARISC_TLS_GD21L	234	/* GD 21-bit left.  */
+#define R_PARISC_TLS_GD14R	235	/* GD 14-bit right.  */
+#define R_PARISC_TLS_GDCALL	236	/* GD call to __t_g_a.  */
+#define R_PARISC_TLS_LDM21L	237	/* LD module 21-bit left.  */
+#define R_PARISC_TLS_LDM14R	238	/* LD module 14-bit right.  */
+#define R_PARISC_TLS_LDMCALL	239	/* LD module call to __t_g_a.  */
+#define R_PARISC_TLS_LDO21L	240	/* LD offset 21-bit left.  */
+#define R_PARISC_TLS_LDO14R	241	/* LD offset 14-bit right.  */
+#define R_PARISC_TLS_DTPMOD32	242	/* DTP module 32-bit.  */
+#define R_PARISC_TLS_DTPMOD64	243	/* DTP module 64-bit.  */
+#define R_PARISC_TLS_DTPOFF32	244	/* DTP offset 32-bit.  */
+#define R_PARISC_TLS_DTPOFF64	245	/* DTP offset 32-bit.  */
+#define R_PARISC_TLS_LE21L	R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R	R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L	R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R	R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32	R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64	R_PARISC_TPREL64
+#define R_PARISC_HIRESERVE	255
+
+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PT_HP_TLS		(PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE		(PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION	(PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL	(PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM		(PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC		(PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE	(PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK	(PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM		(PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF		(PT_LOOS + 0x9)
+#define PT_HP_PARALLEL		(PT_LOOS + 0x10)
+#define PT_HP_FASTBIND		(PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT		(PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT		(PT_LOOS + 0x13)
+#define PT_HP_STACK		(PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT	0x70000000
+#define PT_PARISC_UNWIND	0x70000001
+
+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
+
+#define PF_PARISC_SBP		0x08000000
+
+#define PF_HP_PAGE_SIZE		0x00100000
+#define PF_HP_FAR_SHARED	0x00200000
+#define PF_HP_NEAR_SHARED	0x00400000
+#define PF_HP_CODE		0x01000000
+#define PF_HP_MODIFY		0x02000000
+#define PF_HP_LAZYSWAP		0x04000000
+#define PF_HP_SBP		0x08000000
+
+
+/* Alpha specific definitions.  */
+
+/* Legal values for e_flags field of Elf64_Ehdr.  */
+
+#define EF_ALPHA_32BIT		1	/* All addresses must be < 2GB.  */
+#define EF_ALPHA_CANRELAX	2	/* Relocations for relaxing exist.  */
+
+/* Legal values for sh_type field of Elf64_Shdr.  */
+
+/* These two are primerily concerned with ECOFF debugging info.  */
+#define SHT_ALPHA_DEBUG		0x70000001
+#define SHT_ALPHA_REGINFO	0x70000002
+
+/* Legal values for sh_flags field of Elf64_Shdr.  */
+
+#define SHF_ALPHA_GPREL		0x10000000
+
+/* Legal values for st_other field of Elf64_Sym.  */
+#define STO_ALPHA_NOPV		0x80	/* No PV required.  */
+#define STO_ALPHA_STD_GPLOAD	0x88	/* PV only used for initial ldgp.  */
+
+/* Alpha relocs.  */
+
+#define R_ALPHA_NONE		0	/* No reloc */
+#define R_ALPHA_REFLONG		1	/* Direct 32 bit */
+#define R_ALPHA_REFQUAD		2	/* Direct 64 bit */
+#define R_ALPHA_GPREL32		3	/* GP relative 32 bit */
+#define R_ALPHA_LITERAL		4	/* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE		5	/* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP		6	/* Add displacement to GP */
+#define R_ALPHA_BRADDR		7	/* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT		8	/* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16		9	/* PC relative 16 bit */
+#define R_ALPHA_SREL32		10	/* PC relative 32 bit */
+#define R_ALPHA_SREL64		11	/* PC relative 64 bit */
+#define R_ALPHA_GPRELHIGH	17	/* GP relative 32 bit, high 16 bits */
+#define R_ALPHA_GPRELLOW	18	/* GP relative 32 bit, low 16 bits */
+#define R_ALPHA_GPREL16		19	/* GP relative 16 bit */
+#define R_ALPHA_COPY		24	/* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT	25	/* Create GOT entry */
+#define R_ALPHA_JMP_SLOT	26	/* Create PLT entry */
+#define R_ALPHA_RELATIVE	27	/* Adjust by program base */
+#define R_ALPHA_TLS_GD_HI	28
+#define R_ALPHA_TLSGD		29
+#define R_ALPHA_TLS_LDM		30
+#define R_ALPHA_DTPMOD64	31
+#define R_ALPHA_GOTDTPREL	32
+#define R_ALPHA_DTPREL64	33
+#define R_ALPHA_DTPRELHI	34
+#define R_ALPHA_DTPRELLO	35
+#define R_ALPHA_DTPREL16	36
+#define R_ALPHA_GOTTPREL	37
+#define R_ALPHA_TPREL64		38
+#define R_ALPHA_TPRELHI		39
+#define R_ALPHA_TPRELLO		40
+#define R_ALPHA_TPREL16		41
+/* Keep this the last entry.  */
+#define R_ALPHA_NUM		46
+
+/* Magic values of the LITUSE relocation addend.  */
+#define LITUSE_ALPHA_ADDR	0
+#define LITUSE_ALPHA_BASE	1
+#define LITUSE_ALPHA_BYTOFF	2
+#define LITUSE_ALPHA_JSR	3
+#define LITUSE_ALPHA_TLS_GD	4
+#define LITUSE_ALPHA_TLS_LDM	5
+
+/* Legal values for d_tag of Elf64_Dyn.  */
+#define DT_ALPHA_PLTRO		(DT_LOPROC + 0)
+#define DT_ALPHA_NUM		1
+
+/* PowerPC specific declarations */
+
+/* Values for Elf32/64_Ehdr.e_flags.  */
+#define EF_PPC_EMB		0x80000000	/* PowerPC embedded flag */
+
+/* Cygnus local bits below */
+#define EF_PPC_RELOCATABLE	0x00010000	/* PowerPC -mrelocatable flag*/
+#define EF_PPC_RELOCATABLE_LIB	0x00008000	/* PowerPC -mrelocatable-lib
+						   flag */
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE		0
+#define R_PPC_ADDR32		1	/* 32bit absolute address */
+#define R_PPC_ADDR24		2	/* 26bit address, 2 bits ignored.  */
+#define R_PPC_ADDR16		3	/* 16bit absolute address */
+#define R_PPC_ADDR16_LO		4	/* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI		5	/* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA		6	/* adjusted high 16bit */
+#define R_PPC_ADDR14		7	/* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN	8
+#define R_PPC_ADDR14_BRNTAKEN	9
+#define R_PPC_REL24		10	/* PC relative 26 bit */
+#define R_PPC_REL14		11	/* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN	12
+#define R_PPC_REL14_BRNTAKEN	13
+#define R_PPC_GOT16		14
+#define R_PPC_GOT16_LO		15
+#define R_PPC_GOT16_HI		16
+#define R_PPC_GOT16_HA		17
+#define R_PPC_PLTREL24		18
+#define R_PPC_COPY		19
+#define R_PPC_GLOB_DAT		20
+#define R_PPC_JMP_SLOT		21
+#define R_PPC_RELATIVE		22
+#define R_PPC_LOCAL24PC		23
+#define R_PPC_UADDR32		24
+#define R_PPC_UADDR16		25
+#define R_PPC_REL32		26
+#define R_PPC_PLT32		27
+#define R_PPC_PLTREL32		28
+#define R_PPC_PLT16_LO		29
+#define R_PPC_PLT16_HI		30
+#define R_PPC_PLT16_HA		31
+#define R_PPC_SDAREL16		32
+#define R_PPC_SECTOFF		33
+#define R_PPC_SECTOFF_LO	34
+#define R_PPC_SECTOFF_HI	35
+#define R_PPC_SECTOFF_HA	36
+
+/* PowerPC relocations defined for the TLS access ABI.  */
+#define R_PPC_TLS		67 /* none	(sym+add)@tls */
+#define R_PPC_DTPMOD32		68 /* word32	(sym+add)@dtpmod */
+#define R_PPC_TPREL16		69 /* half16*	(sym+add)@tprel */
+#define R_PPC_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
+#define R_PPC_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
+#define R_PPC_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
+#define R_PPC_TPREL32		73 /* word32	(sym+add)@tprel */
+#define R_PPC_DTPREL16		74 /* half16*	(sym+add)@dtprel */
+#define R_PPC_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
+#define R_PPC_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
+#define R_PPC_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
+#define R_PPC_DTPREL32		78 /* word32	(sym+add)@dtprel */
+#define R_PPC_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
+#define R_PPC_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
+#define R_PPC_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
+#define R_PPC_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
+#define R_PPC_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
+#define R_PPC_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
+#define R_PPC_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
+#define R_PPC_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
+#define R_PPC_GOT_TPREL16	87 /* half16*	(sym+add)@got@tprel */
+#define R_PPC_GOT_TPREL16_LO	88 /* half16	(sym+add)@got@tprel@l */
+#define R_PPC_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
+#define R_PPC_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
+#define R_PPC_GOT_DTPREL16	91 /* half16*	(sym+add)@got@dtprel */
+#define R_PPC_GOT_DTPREL16_LO	92 /* half16*	(sym+add)@got@dtprel@l */
+#define R_PPC_GOT_DTPREL16_HI	93 /* half16*	(sym+add)@got@dtprel@h */
+#define R_PPC_GOT_DTPREL16_HA	94 /* half16*	(sym+add)@got@dtprel@ha */
+#define R_PPC_TLSGD		95 /* none	(sym+add)@tlsgd */
+#define R_PPC_TLSLD		96 /* none	(sym+add)@tlsld */
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+   in the SVR4 ELF ABI.  */
+#define R_PPC_EMB_NADDR32	101
+#define R_PPC_EMB_NADDR16	102
+#define R_PPC_EMB_NADDR16_LO	103
+#define R_PPC_EMB_NADDR16_HI	104
+#define R_PPC_EMB_NADDR16_HA	105
+#define R_PPC_EMB_SDAI16	106
+#define R_PPC_EMB_SDA2I16	107
+#define R_PPC_EMB_SDA2REL	108
+#define R_PPC_EMB_SDA21		109	/* 16 bit offset in SDA */
+#define R_PPC_EMB_MRKREF	110
+#define R_PPC_EMB_RELSEC16	111
+#define R_PPC_EMB_RELST_LO	112
+#define R_PPC_EMB_RELST_HI	113
+#define R_PPC_EMB_RELST_HA	114
+#define R_PPC_EMB_BIT_FLD	115
+#define R_PPC_EMB_RELSDA	116	/* 16 bit relative offset in SDA */
+
+/* Diab tool relocations.  */
+#define R_PPC_DIAB_SDA21_LO	180	/* like EMB_SDA21, but lower 16 bit */
+#define R_PPC_DIAB_SDA21_HI	181	/* like EMB_SDA21, but high 16 bit */
+#define R_PPC_DIAB_SDA21_HA	182	/* like EMB_SDA21, adjusted high 16 */
+#define R_PPC_DIAB_RELSDA_LO	183	/* like EMB_RELSDA, but lower 16 bit */
+#define R_PPC_DIAB_RELSDA_HI	184	/* like EMB_RELSDA, but high 16 bit */
+#define R_PPC_DIAB_RELSDA_HA	185	/* like EMB_RELSDA, adjusted high 16 */
+
+/* GNU extension to support local ifunc.  */
+#define R_PPC_IRELATIVE		248
+
+/* GNU relocs used in PIC code sequences.  */
+#define R_PPC_REL16		249	/* half16   (sym+add-.) */
+#define R_PPC_REL16_LO		250	/* half16   (sym+add-.)@l */
+#define R_PPC_REL16_HI		251	/* half16   (sym+add-.)@h */
+#define R_PPC_REL16_HA		252	/* half16   (sym+add-.)@ha */
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+   that may still be in object files.  */
+#define R_PPC_TOC16		255
+
+/* PowerPC specific values for the Dyn d_tag field.  */
+#define DT_PPC_GOT		(DT_LOPROC + 0)
+#define DT_PPC_OPT		(DT_LOPROC + 1)
+#define DT_PPC_NUM		2
+
+/* PowerPC specific values for the DT_PPC_OPT Dyn entry.  */
+#define PPC_OPT_TLS		1
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE		R_PPC_NONE
+#define R_PPC64_ADDR32		R_PPC_ADDR32 /* 32bit absolute address */
+#define R_PPC64_ADDR24		R_PPC_ADDR24 /* 26bit address, word aligned */
+#define R_PPC64_ADDR16		R_PPC_ADDR16 /* 16bit absolute address */
+#define R_PPC64_ADDR16_LO	R_PPC_ADDR16_LO	/* lower 16bits of address */
+#define R_PPC64_ADDR16_HI	R_PPC_ADDR16_HI	/* high 16bits of address. */
+#define R_PPC64_ADDR16_HA	R_PPC_ADDR16_HA /* adjusted high 16bits.  */
+#define R_PPC64_ADDR14		R_PPC_ADDR14 /* 16bit address, word aligned */
+#define R_PPC64_ADDR14_BRTAKEN	R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN	R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24		R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
+#define R_PPC64_REL14		R_PPC_REL14 /* PC relative 16 bit */
+#define R_PPC64_REL14_BRTAKEN	R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN	R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16		R_PPC_GOT16
+#define R_PPC64_GOT16_LO	R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI	R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA	R_PPC_GOT16_HA
+
+#define R_PPC64_COPY		R_PPC_COPY
+#define R_PPC64_GLOB_DAT	R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT	R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE	R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32		R_PPC_UADDR32
+#define R_PPC64_UADDR16		R_PPC_UADDR16
+#define R_PPC64_REL32		R_PPC_REL32
+#define R_PPC64_PLT32		R_PPC_PLT32
+#define R_PPC64_PLTREL32	R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO	R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI	R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA	R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF		R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO	R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI	R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA	R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30		37 /* word30 (S + A - P) >> 2 */
+#define R_PPC64_ADDR64		38 /* doubleword64 S + A */
+#define R_PPC64_ADDR16_HIGHER	39 /* half16 #higher(S + A) */
+#define R_PPC64_ADDR16_HIGHERA	40 /* half16 #highera(S + A) */
+#define R_PPC64_ADDR16_HIGHEST	41 /* half16 #highest(S + A) */
+#define R_PPC64_ADDR16_HIGHESTA	42 /* half16 #highesta(S + A) */
+#define R_PPC64_UADDR64		43 /* doubleword64 S + A */
+#define R_PPC64_REL64		44 /* doubleword64 S + A - P */
+#define R_PPC64_PLT64		45 /* doubleword64 L + A */
+#define R_PPC64_PLTREL64	46 /* doubleword64 L + A - P */
+#define R_PPC64_TOC16		47 /* half16* S + A - .TOC */
+#define R_PPC64_TOC16_LO	48 /* half16 #lo(S + A - .TOC.) */
+#define R_PPC64_TOC16_HI	49 /* half16 #hi(S + A - .TOC.) */
+#define R_PPC64_TOC16_HA	50 /* half16 #ha(S + A - .TOC.) */
+#define R_PPC64_TOC		51 /* doubleword64 .TOC */
+#define R_PPC64_PLTGOT16	52 /* half16* M + A */
+#define R_PPC64_PLTGOT16_LO	53 /* half16 #lo(M + A) */
+#define R_PPC64_PLTGOT16_HI	54 /* half16 #hi(M + A) */
+#define R_PPC64_PLTGOT16_HA	55 /* half16 #ha(M + A) */
+
+#define R_PPC64_ADDR16_DS	56 /* half16ds* (S + A) >> 2 */
+#define R_PPC64_ADDR16_LO_DS	57 /* half16ds  #lo(S + A) >> 2 */
+#define R_PPC64_GOT16_DS	58 /* half16ds* (G + A) >> 2 */
+#define R_PPC64_GOT16_LO_DS	59 /* half16ds  #lo(G + A) >> 2 */
+#define R_PPC64_PLT16_LO_DS	60 /* half16ds  #lo(L + A) >> 2 */
+#define R_PPC64_SECTOFF_DS	61 /* half16ds* (R + A) >> 2 */
+#define R_PPC64_SECTOFF_LO_DS	62 /* half16ds  #lo(R + A) >> 2 */
+#define R_PPC64_TOC16_DS	63 /* half16ds* (S + A - .TOC.) >> 2 */
+#define R_PPC64_TOC16_LO_DS	64 /* half16ds  #lo(S + A - .TOC.) >> 2 */
+#define R_PPC64_PLTGOT16_DS	65 /* half16ds* (M + A) >> 2 */
+#define R_PPC64_PLTGOT16_LO_DS	66 /* half16ds  #lo(M + A) >> 2 */
+
+/* PowerPC64 relocations defined for the TLS access ABI.  */
+#define R_PPC64_TLS		67 /* none	(sym+add)@tls */
+#define R_PPC64_DTPMOD64	68 /* doubleword64 (sym+add)@dtpmod */
+#define R_PPC64_TPREL16		69 /* half16*	(sym+add)@tprel */
+#define R_PPC64_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
+#define R_PPC64_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
+#define R_PPC64_TPREL64		73 /* doubleword64 (sym+add)@tprel */
+#define R_PPC64_DTPREL16	74 /* half16*	(sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
+#define R_PPC64_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
+#define R_PPC64_DTPREL64	78 /* doubleword64 (sym+add)@dtprel */
+#define R_PPC64_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
+#define R_PPC64_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
+#define R_PPC64_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
+#define R_PPC64_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
+#define R_PPC64_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
+#define R_PPC64_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
+#define R_PPC64_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
+#define R_PPC64_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
+#define R_PPC64_GOT_TPREL16_DS	87 /* half16ds*	(sym+add)@got@tprel */
+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
+#define R_PPC64_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
+#define R_PPC64_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
+#define R_PPC64_GOT_DTPREL16_DS	91 /* half16ds*	(sym+add)@got@dtprel */
+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
+#define R_PPC64_GOT_DTPREL16_HI	93 /* half16	(sym+add)@got@dtprel@h */
+#define R_PPC64_GOT_DTPREL16_HA	94 /* half16	(sym+add)@got@dtprel@ha */
+#define R_PPC64_TPREL16_DS	95 /* half16ds*	(sym+add)@tprel */
+#define R_PPC64_TPREL16_LO_DS	96 /* half16ds	(sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HIGHER	97 /* half16	(sym+add)@tprel@higher */
+#define R_PPC64_TPREL16_HIGHERA	98 /* half16	(sym+add)@tprel@highera */
+#define R_PPC64_TPREL16_HIGHEST	99 /* half16	(sym+add)@tprel@highest */
+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16	(sym+add)@tprel@highesta */
+#define R_PPC64_DTPREL16_DS	101 /* half16ds* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO_DS	102 /* half16ds	(sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HIGHER	103 /* half16	(sym+add)@dtprel@higher */
+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16	(sym+add)@dtprel@highera */
+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16	(sym+add)@dtprel@highest */
+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16	(sym+add)@dtprel@highesta */
+#define R_PPC64_TLSGD		107 /* none	(sym+add)@tlsgd */
+#define R_PPC64_TLSLD		108 /* none	(sym+add)@tlsld */
+#define R_PPC64_TOCSAVE		109 /* none */
+
+/* Added when HA and HI relocs were changed to report overflows.  */
+#define R_PPC64_ADDR16_HIGH	110
+#define R_PPC64_ADDR16_HIGHA	111
+#define R_PPC64_TPREL16_HIGH	112
+#define R_PPC64_TPREL16_HIGHA	113
+#define R_PPC64_DTPREL16_HIGH	114
+#define R_PPC64_DTPREL16_HIGHA	115
+
+/* GNU extension to support local ifunc.  */
+#define R_PPC64_JMP_IREL	247
+#define R_PPC64_IRELATIVE	248
+#define R_PPC64_REL16		249	/* half16   (sym+add-.) */
+#define R_PPC64_REL16_LO	250	/* half16   (sym+add-.)@l */
+#define R_PPC64_REL16_HI	251	/* half16   (sym+add-.)@h */
+#define R_PPC64_REL16_HA	252	/* half16   (sym+add-.)@ha */
+
+/* e_flags bits specifying ABI.
+   1 for original function descriptor using ABI,
+   2 for revised ABI without function descriptors,
+   0 for unspecified or not using any features affected by the differences.  */
+#define EF_PPC64_ABI	3
+
+/* PowerPC64 specific values for the Dyn d_tag field.  */
+#define DT_PPC64_GLINK  (DT_LOPROC + 0)
+#define DT_PPC64_OPD	(DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
+#define DT_PPC64_OPT	(DT_LOPROC + 3)
+#define DT_PPC64_NUM    4
+
+/* PowerPC64 specific bits in the DT_PPC64_OPT Dyn entry.  */
+#define PPC64_OPT_TLS		1
+#define PPC64_OPT_MULTI_TOC	2
+#define PPC64_OPT_LOCALENTRY	4
+
+/* PowerPC64 specific values for the Elf64_Sym st_other field.  */
+#define STO_PPC64_LOCAL_BIT	5
+#define STO_PPC64_LOCAL_MASK	(7 << STO_PPC64_LOCAL_BIT)
+#define PPC64_LOCAL_ENTRY_OFFSET(other)				\
+ (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2)
+
+
+/* ARM specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_ARM_RELEXEC		0x01
+#define EF_ARM_HASENTRY		0x02
+#define EF_ARM_INTERWORK	0x04
+#define EF_ARM_APCS_26		0x08
+#define EF_ARM_APCS_FLOAT	0x10
+#define EF_ARM_PIC		0x20
+#define EF_ARM_ALIGN8		0x40 /* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI		0x80
+#define EF_ARM_OLD_ABI		0x100
+#define EF_ARM_SOFT_FLOAT	0x200
+#define EF_ARM_VFP_FLOAT	0x400
+#define EF_ARM_MAVERICK_FLOAT	0x800
+
+#define EF_ARM_ABI_FLOAT_SOFT	0x200   /* NB conflicts with EF_ARM_SOFT_FLOAT */
+#define EF_ARM_ABI_FLOAT_HARD	0x400   /* NB conflicts with EF_ARM_VFP_FLOAT */
+
+
+/* Other constants defined in the ARM ELF spec. version B-01.  */
+/* NB. These conflict with values defined above.  */
+#define EF_ARM_SYMSARESORTED	0x04
+#define EF_ARM_DYNSYMSUSESEGIDX	0x08
+#define EF_ARM_MAPSYMSFIRST	0x10
+#define EF_ARM_EABIMASK		0XFF000000
+
+/* Constants defined in AAELF.  */
+#define EF_ARM_BE8	    0x00800000
+#define EF_ARM_LE8	    0x00400000
+
+#define EF_ARM_EABI_VERSION(flags)	((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN	0x00000000
+#define EF_ARM_EABI_VER1	0x01000000
+#define EF_ARM_EABI_VER2	0x02000000
+#define EF_ARM_EABI_VER3	0x03000000
+#define EF_ARM_EABI_VER4	0x04000000
+#define EF_ARM_EABI_VER5	0x05000000
+
+/* Additional symbol types for Thumb.  */
+#define STT_ARM_TFUNC		STT_LOPROC /* A Thumb function.  */
+#define STT_ARM_16BIT		STT_HIPROC /* A Thumb label.  */
+
+/* ARM-specific values for sh_flags */
+#define SHF_ARM_ENTRYSECT	0x10000000 /* Section contains an entry point */
+#define SHF_ARM_COMDEF		0x80000000 /* Section may be multiply defined
+					      in the input to a link step.  */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB		0x10000000 /* Segment contains the location
+					      addressed by the static base. */
+#define PF_ARM_PI		0x20000000 /* Position-independent segment.  */
+#define PF_ARM_ABS		0x40000000 /* Absolute segment.  */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_ARM_EXIDX		(PT_LOPROC + 1)	/* ARM unwind segment.  */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_ARM_EXIDX		(SHT_LOPROC + 1) /* ARM unwind section.  */
+#define SHT_ARM_PREEMPTMAP	(SHT_LOPROC + 2) /* Preemption details.  */
+#define SHT_ARM_ATTRIBUTES	(SHT_LOPROC + 3) /* ARM attributes section.  */
+
+
+/* AArch64 relocs.  */
+
+#define R_AARCH64_NONE            0	/* No relocation.  */
+
+/* ILP32 AArch64 relocs.  */
+#define R_AARCH64_P32_ABS32		  1	/* Direct 32 bit.  */
+#define R_AARCH64_P32_COPY		180	/* Copy symbol at runtime.  */
+#define R_AARCH64_P32_GLOB_DAT		181	/* Create GOT entry.  */
+#define R_AARCH64_P32_JUMP_SLOT		182	/* Create PLT entry.  */
+#define R_AARCH64_P32_RELATIVE		183	/* Adjust by program base.  */
+#define R_AARCH64_P32_TLS_DTPMOD	184	/* Module number, 32 bit.  */
+#define R_AARCH64_P32_TLS_DTPREL	185	/* Module-relative offset, 32 bit.  */
+#define R_AARCH64_P32_TLS_TPREL		186	/* TP-relative offset, 32 bit.  */
+#define R_AARCH64_P32_TLSDESC		187	/* TLS Descriptor.  */
+#define R_AARCH64_P32_IRELATIVE		188	/* STT_GNU_IFUNC relocation. */
+
+/* LP64 AArch64 relocs.  */
+#define R_AARCH64_ABS64         257	/* Direct 64 bit. */
+#define R_AARCH64_ABS32         258	/* Direct 32 bit.  */
+#define R_AARCH64_ABS16		259	/* Direct 16-bit.  */
+#define R_AARCH64_PREL64	260	/* PC-relative 64-bit.	*/
+#define R_AARCH64_PREL32	261	/* PC-relative 32-bit.	*/
+#define R_AARCH64_PREL16	262	/* PC-relative 16-bit.	*/
+#define R_AARCH64_MOVW_UABS_G0	263	/* Dir. MOVZ imm. from bits 15:0.  */
+#define R_AARCH64_MOVW_UABS_G0_NC 264	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G1	265	/* Dir. MOVZ imm. from bits 31:16.  */
+#define R_AARCH64_MOVW_UABS_G1_NC 266	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G2	267	/* Dir. MOVZ imm. from bits 47:32.  */
+#define R_AARCH64_MOVW_UABS_G2_NC 268	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_UABS_G3	269	/* Dir. MOV{K,Z} imm. from 63:48.  */
+#define R_AARCH64_MOVW_SABS_G0	270	/* Dir. MOV{N,Z} imm. from 15:0.  */
+#define R_AARCH64_MOVW_SABS_G1	271	/* Dir. MOV{N,Z} imm. from 31:16.  */
+#define R_AARCH64_MOVW_SABS_G2	272	/* Dir. MOV{N,Z} imm. from 47:32.  */
+#define R_AARCH64_LD_PREL_LO19	273	/* PC-rel. LD imm. from bits 20:2.  */
+#define R_AARCH64_ADR_PREL_LO21	274	/* PC-rel. ADR imm. from bits 20:0.  */
+#define R_AARCH64_ADR_PREL_PG_HI21 275	/* Page-rel. ADRP imm. from 32:12.  */
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check.  */
+#define R_AARCH64_ADD_ABS_LO12_NC 277	/* Dir. ADD imm. from bits 11:0.  */
+#define R_AARCH64_LDST8_ABS_LO12_NC 278	/* Likewise for LD/ST; no check. */
+#define R_AARCH64_TSTBR14	279	/* PC-rel. TBZ/TBNZ imm. from 15:2.  */
+#define R_AARCH64_CONDBR19	280	/* PC-rel. cond. br. imm. from 20:2. */
+#define R_AARCH64_JUMP26	282	/* PC-rel. B imm. from bits 27:2.  */
+#define R_AARCH64_CALL26	283	/* Likewise for CALL.  */
+#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1.  */
+#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2.  */
+#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3.  */
+#define R_AARCH64_MOVW_PREL_G0	287	/* PC-rel. MOV{N,Z} imm. from 15:0.  */
+#define R_AARCH64_MOVW_PREL_G0_NC 288	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G1	289	/* PC-rel. MOV{N,Z} imm. from 31:16. */
+#define R_AARCH64_MOVW_PREL_G1_NC 290	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G2	291	/* PC-rel. MOV{N,Z} imm. from 47:32. */
+#define R_AARCH64_MOVW_PREL_G2_NC 292	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_PREL_G3	293	/* PC-rel. MOV{N,Z} imm. from 63:48. */
+#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4.  */
+#define R_AARCH64_MOVW_GOTOFF_G0 300	/* GOT-rel. off. MOV{N,Z} imm. 15:0. */
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G1 302	/* GOT-rel. o. MOV{N,Z} imm. 31:16.  */
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G2 304	/* GOT-rel. o. MOV{N,Z} imm. 47:32.  */
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305	/* Likewise for MOVK; no check.  */
+#define R_AARCH64_MOVW_GOTOFF_G3 306	/* GOT-rel. o. MOV{N,Z} imm. 63:48.  */
+#define R_AARCH64_GOTREL64	307	/* GOT-relative 64-bit.  */
+#define R_AARCH64_GOTREL32	308	/* GOT-relative 32-bit.  */
+#define R_AARCH64_GOT_LD_PREL19	309	/* PC-rel. GOT off. load imm. 20:2.  */
+#define R_AARCH64_LD64_GOTOFF_LO15 310	/* GOT-rel. off. LD/ST imm. 14:3.  */
+#define R_AARCH64_ADR_GOT_PAGE	311	/* P-page-rel. GOT off. ADRP 32:12.  */
+#define R_AARCH64_LD64_GOT_LO12_NC 312	/* Dir. GOT off. LD/ST imm. 11:3.  */
+#define R_AARCH64_LD64_GOTPAGE_LO15 313	/* GOT-page-rel. GOT off. LD/ST 14:3 */
+#define R_AARCH64_TLSGD_ADR_PREL21 512	/* PC-relative ADR imm. 20:0.  */
+#define R_AARCH64_TLSGD_ADR_PAGE21 513	/* page-rel. ADRP imm. 32:12.  */
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514	/* direct ADD imm. from 11:0.  */
+#define R_AARCH64_TLSGD_MOVW_G1	515	/* GOT-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516	/* GOT-rel. MOVK imm. 15:0.  */
+#define R_AARCH64_TLSLD_ADR_PREL21 517	/* Like 512; local dynamic model.  */
+#define R_AARCH64_TLSLD_ADR_PAGE21 518	/* Like 513; local dynamic model.  */
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519	/* Like 514; local dynamic model.  */
+#define R_AARCH64_TLSLD_MOVW_G1	520	/* Like 515; local dynamic model.  */
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521	/* Like 516; local dynamic model.  */
+#define R_AARCH64_TLSLD_LD_PREL19 522	/* TLS PC-rel. load imm. 20:2.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0.  */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0.  */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check.  */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0.  */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1.  */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2.  */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3.  */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check.  */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0.  */
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12.  */
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3.  */
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0.  */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0.  */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check.  */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0.  */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1.  */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check.  */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2.  */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check.  */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3.  */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check.  */
+#define R_AARCH64_TLSDESC_LD_PREL19 560	/* PC-rel. load immediate 20:2.  */
+#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0.  */
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12.  */
+#define R_AARCH64_TLSDESC_LD64_LO12 563	/* Direct LD off. from 11:3.  */
+#define R_AARCH64_TLSDESC_ADD_LO12 564	/* Direct ADD imm. from 11:0.  */
+#define R_AARCH64_TLSDESC_OFF_G1 565	/* GOT-rel. MOV{N,Z} imm. 31:16.  */
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566	/* GOT-rel. MOVK imm. 15:0; no ck.  */
+#define R_AARCH64_TLSDESC_LDR	567	/* Relax LDR.  */
+#define R_AARCH64_TLSDESC_ADD	568	/* Relax ADD.  */
+#define R_AARCH64_TLSDESC_CALL	569	/* Relax BLR.  */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4.  */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check.  */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check.  */
+#define R_AARCH64_COPY         1024	/* Copy symbol at runtime.  */
+#define R_AARCH64_GLOB_DAT     1025	/* Create GOT entry.  */
+#define R_AARCH64_JUMP_SLOT    1026	/* Create PLT entry.  */
+#define R_AARCH64_RELATIVE     1027	/* Adjust by program base.  */
+#define R_AARCH64_TLS_DTPMOD   1028	/* Module number, 64 bit.  */
+#define R_AARCH64_TLS_DTPREL   1029	/* Module-relative offset, 64 bit.  */
+#define R_AARCH64_TLS_TPREL    1030	/* TP-relative offset, 64 bit.  */
+#define R_AARCH64_TLSDESC      1031	/* TLS Descriptor.  */
+#define R_AARCH64_IRELATIVE	1032	/* STT_GNU_IFUNC relocation.  */
+
+/* ARM relocs.  */
+
+#define R_ARM_NONE		0	/* No reloc */
+#define R_ARM_PC24		1	/* Deprecated PC relative 26
+					   bit branch.  */
+#define R_ARM_ABS32		2	/* Direct 32 bit  */
+#define R_ARM_REL32		3	/* PC relative 32 bit */
+#define R_ARM_PC13		4
+#define R_ARM_ABS16		5	/* Direct 16 bit */
+#define R_ARM_ABS12		6	/* Direct 12 bit */
+#define R_ARM_THM_ABS5		7	/* Direct & 0x7C (LDR, STR).  */
+#define R_ARM_ABS8		8	/* Direct 8 bit */
+#define R_ARM_SBREL32		9
+#define R_ARM_THM_PC22		10	/* PC relative 24 bit (Thumb32 BL).  */
+#define R_ARM_THM_PC8		11	/* PC relative & 0x3FC
+					   (Thumb16 LDR, ADD, ADR).  */
+#define R_ARM_AMP_VCALL9	12
+#define R_ARM_SWI24		13	/* Obsolete static relocation.  */
+#define R_ARM_TLS_DESC		13      /* Dynamic relocation.  */
+#define R_ARM_THM_SWI8		14	/* Reserved.  */
+#define R_ARM_XPC25		15	/* Reserved.  */
+#define R_ARM_THM_XPC22		16	/* Reserved.  */
+#define R_ARM_TLS_DTPMOD32	17	/* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32	18	/* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32	19	/* Offset in static TLS block */
+#define R_ARM_COPY		20	/* Copy symbol at runtime */
+#define R_ARM_GLOB_DAT		21	/* Create GOT entry */
+#define R_ARM_JUMP_SLOT		22	/* Create PLT entry */
+#define R_ARM_RELATIVE		23	/* Adjust by program base */
+#define R_ARM_GOTOFF		24	/* 32 bit offset to GOT */
+#define R_ARM_GOTPC		25	/* 32 bit PC relative offset to GOT */
+#define R_ARM_GOT32		26	/* 32 bit GOT entry */
+#define R_ARM_PLT32		27	/* Deprecated, 32 bit PLT address.  */
+#define R_ARM_CALL		28	/* PC relative 24 bit (BL, BLX).  */
+#define R_ARM_JUMP24		29	/* PC relative 24 bit
+					   (B, BL<cond>).  */
+#define R_ARM_THM_JUMP24	30	/* PC relative 24 bit (Thumb32 B.W).  */
+#define R_ARM_BASE_ABS		31	/* Adjust by program base.  */
+#define R_ARM_ALU_PCREL_7_0	32	/* Obsolete.  */
+#define R_ARM_ALU_PCREL_15_8	33	/* Obsolete.  */
+#define R_ARM_ALU_PCREL_23_15	34	/* Obsolete.  */
+#define R_ARM_LDR_SBREL_11_0	35	/* Deprecated, prog. base relative.  */
+#define R_ARM_ALU_SBREL_19_12	36	/* Deprecated, prog. base relative.  */
+#define R_ARM_ALU_SBREL_27_20	37	/* Deprecated, prog. base relative.  */
+#define R_ARM_TARGET1		38
+#define R_ARM_SBREL31		39	/* Program base relative.  */
+#define R_ARM_V4BX		40
+#define R_ARM_TARGET2		41
+#define R_ARM_PREL31		42	/* 32 bit PC relative.  */
+#define R_ARM_MOVW_ABS_NC	43	/* Direct 16-bit (MOVW).  */
+#define R_ARM_MOVT_ABS		44	/* Direct high 16-bit (MOVT).  */
+#define R_ARM_MOVW_PREL_NC	45	/* PC relative 16-bit (MOVW).  */
+#define R_ARM_MOVT_PREL		46	/* PC relative (MOVT).  */
+#define R_ARM_THM_MOVW_ABS_NC	47	/* Direct 16 bit (Thumb32 MOVW).  */
+#define R_ARM_THM_MOVT_ABS	48	/* Direct high 16 bit
+					   (Thumb32 MOVT).  */
+#define R_ARM_THM_MOVW_PREL_NC	49	/* PC relative 16 bit
+					   (Thumb32 MOVW).  */
+#define R_ARM_THM_MOVT_PREL	50	/* PC relative high 16 bit
+					   (Thumb32 MOVT).  */
+#define R_ARM_THM_JUMP19	51	/* PC relative 20 bit
+					   (Thumb32 B<cond>.W).  */
+#define R_ARM_THM_JUMP6		52	/* PC relative X & 0x7E
+					   (Thumb16 CBZ, CBNZ).  */
+#define R_ARM_THM_ALU_PREL_11_0	53	/* PC relative 12 bit
+					   (Thumb32 ADR.W).  */
+#define R_ARM_THM_PC12		54	/* PC relative 12 bit
+					   (Thumb32 LDR{D,SB,H,SH}).  */
+#define R_ARM_ABS32_NOI		55	/* Direct 32-bit.  */
+#define R_ARM_REL32_NOI		56	/* PC relative 32-bit.  */
+#define R_ARM_ALU_PC_G0_NC	57	/* PC relative (ADD, SUB).  */
+#define R_ARM_ALU_PC_G0		58	/* PC relative (ADD, SUB).  */
+#define R_ARM_ALU_PC_G1_NC	59	/* PC relative (ADD, SUB).  */
+#define R_ARM_ALU_PC_G1		60	/* PC relative (ADD, SUB).  */
+#define R_ARM_ALU_PC_G2		61	/* PC relative (ADD, SUB).  */
+#define R_ARM_LDR_PC_G1		62	/* PC relative (LDR,STR,LDRB,STRB).  */
+#define R_ARM_LDR_PC_G2		63	/* PC relative (LDR,STR,LDRB,STRB).  */
+#define R_ARM_LDRS_PC_G0	64	/* PC relative (STR{D,H},
+					   LDR{D,SB,H,SH}).  */
+#define R_ARM_LDRS_PC_G1	65	/* PC relative (STR{D,H},
+					   LDR{D,SB,H,SH}).  */
+#define R_ARM_LDRS_PC_G2	66	/* PC relative (STR{D,H},
+					   LDR{D,SB,H,SH}).  */
+#define R_ARM_LDC_PC_G0		67	/* PC relative (LDC, STC).  */
+#define R_ARM_LDC_PC_G1		68	/* PC relative (LDC, STC).  */
+#define R_ARM_LDC_PC_G2		69	/* PC relative (LDC, STC).  */
+#define R_ARM_ALU_SB_G0_NC	70	/* Program base relative (ADD,SUB).  */
+#define R_ARM_ALU_SB_G0		71	/* Program base relative (ADD,SUB).  */
+#define R_ARM_ALU_SB_G1_NC	72	/* Program base relative (ADD,SUB).  */
+#define R_ARM_ALU_SB_G1		73	/* Program base relative (ADD,SUB).  */
+#define R_ARM_ALU_SB_G2		74	/* Program base relative (ADD,SUB).  */
+#define R_ARM_LDR_SB_G0		75	/* Program base relative (LDR,
+					   STR, LDRB, STRB).  */
+#define R_ARM_LDR_SB_G1		76	/* Program base relative
+					   (LDR, STR, LDRB, STRB).  */
+#define R_ARM_LDR_SB_G2		77	/* Program base relative
+					   (LDR, STR, LDRB, STRB).  */
+#define R_ARM_LDRS_SB_G0	78	/* Program base relative
+					   (LDR, STR, LDRB, STRB).  */
+#define R_ARM_LDRS_SB_G1	79	/* Program base relative
+					   (LDR, STR, LDRB, STRB).  */
+#define R_ARM_LDRS_SB_G2	80	/* Program base relative
+					   (LDR, STR, LDRB, STRB).  */
+#define R_ARM_LDC_SB_G0		81	/* Program base relative (LDC,STC).  */
+#define R_ARM_LDC_SB_G1		82	/* Program base relative (LDC,STC).  */
+#define R_ARM_LDC_SB_G2		83	/* Program base relative (LDC,STC).  */
+#define R_ARM_MOVW_BREL_NC	84	/* Program base relative 16
+					   bit (MOVW).  */
+#define R_ARM_MOVT_BREL		85	/* Program base relative high
+					   16 bit (MOVT).  */
+#define R_ARM_MOVW_BREL		86	/* Program base relative 16
+					   bit (MOVW).  */
+#define R_ARM_THM_MOVW_BREL_NC	87	/* Program base relative 16
+					   bit (Thumb32 MOVW).  */
+#define R_ARM_THM_MOVT_BREL	88	/* Program base relative high
+					   16 bit (Thumb32 MOVT).  */
+#define R_ARM_THM_MOVW_BREL	89	/* Program base relative 16
+					   bit (Thumb32 MOVW).  */
+#define R_ARM_TLS_GOTDESC	90
+#define R_ARM_TLS_CALL		91
+#define R_ARM_TLS_DESCSEQ	92	/* TLS relaxation.  */
+#define R_ARM_THM_TLS_CALL	93
+#define R_ARM_PLT32_ABS		94
+#define R_ARM_GOT_ABS		95	/* GOT entry.  */
+#define R_ARM_GOT_PREL		96	/* PC relative GOT entry.  */
+#define R_ARM_GOT_BREL12	97	/* GOT entry relative to GOT
+					   origin (LDR).  */
+#define R_ARM_GOTOFF12		98	/* 12 bit, GOT entry relative
+					   to GOT origin (LDR, STR).  */
+#define R_ARM_GOTRELAX		99
+#define R_ARM_GNU_VTENTRY	100
+#define R_ARM_GNU_VTINHERIT	101
+#define R_ARM_THM_PC11		102	/* PC relative & 0xFFE (Thumb16 B).  */
+#define R_ARM_THM_PC9		103	/* PC relative & 0x1FE
+					   (Thumb16 B/B<cond>).  */
+#define R_ARM_TLS_GD32		104	/* PC-rel 32 bit for global dynamic
+					   thread local data */
+#define R_ARM_TLS_LDM32		105	/* PC-rel 32 bit for local dynamic
+					   thread local data */
+#define R_ARM_TLS_LDO32		106	/* 32 bit offset relative to TLS
+					   block */
+#define R_ARM_TLS_IE32		107	/* PC-rel 32 bit for GOT entry of
+					   static TLS block offset */
+#define R_ARM_TLS_LE32		108	/* 32 bit offset relative to static
+					   TLS block */
+#define R_ARM_TLS_LDO12		109	/* 12 bit relative to TLS
+					   block (LDR, STR).  */
+#define R_ARM_TLS_LE12		110	/* 12 bit relative to static
+					   TLS block (LDR, STR).  */
+#define R_ARM_TLS_IE12GP	111	/* 12 bit GOT entry relative
+					   to GOT origin (LDR).  */
+#define R_ARM_ME_TOO		128	/* Obsolete.  */
+#define R_ARM_THM_TLS_DESCSEQ	129
+#define R_ARM_THM_TLS_DESCSEQ16	129
+#define R_ARM_THM_TLS_DESCSEQ32	130
+#define R_ARM_THM_GOT_BREL12	131	/* GOT entry relative to GOT
+					   origin, 12 bit (Thumb32 LDR).  */
+#define R_ARM_IRELATIVE		160
+#define R_ARM_RXPC25		249
+#define R_ARM_RSBREL32		250
+#define R_ARM_THM_RPC22		251
+#define R_ARM_RREL32		252
+#define R_ARM_RABS22		253
+#define R_ARM_RPC24		254
+#define R_ARM_RBASE		255
+/* Keep this the last entry.  */
+#define R_ARM_NUM		256
+
+/* IA-64 specific declarations.  */
+
+/* Processor specific flags for the Ehdr e_flags field.  */
+#define EF_IA_64_MASKOS		0x0000000f	/* os-specific flags */
+#define EF_IA_64_ABI64		0x00000010	/* 64-bit ABI */
+#define EF_IA_64_ARCH		0xff000000	/* arch. version mask */
+
+/* Processor specific values for the Phdr p_type field.  */
+#define PT_IA_64_ARCHEXT	(PT_LOPROC + 0)	/* arch extension bits */
+#define PT_IA_64_UNWIND		(PT_LOPROC + 1)	/* ia64 unwind bits */
+#define PT_IA_64_HP_OPT_ANOT	(PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT	(PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK	(PT_LOOS + 0x14)
+
+/* Processor specific flags for the Phdr p_flags field.  */
+#define PF_IA_64_NORECOV	0x80000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Shdr sh_type field.  */
+#define SHT_IA_64_EXT		(SHT_LOPROC + 0) /* extension bits */
+#define SHT_IA_64_UNWIND	(SHT_LOPROC + 1) /* unwind bits */
+
+/* Processor specific flags for the Shdr sh_flags field.  */
+#define SHF_IA_64_SHORT		0x10000000	/* section near gp */
+#define SHF_IA_64_NORECOV	0x20000000	/* spec insns w/o recovery */
+
+/* Processor specific values for the Dyn d_tag field.  */
+#define DT_IA_64_PLT_RESERVE	(DT_LOPROC + 0)
+#define DT_IA_64_NUM		1
+
+/* IA-64 relocations.  */
+#define R_IA64_NONE		0x00	/* none */
+#define R_IA64_IMM14		0x21	/* symbol + addend, add imm14 */
+#define R_IA64_IMM22		0x22	/* symbol + addend, add imm22 */
+#define R_IA64_IMM64		0x23	/* symbol + addend, mov imm64 */
+#define R_IA64_DIR32MSB		0x24	/* symbol + addend, data4 MSB */
+#define R_IA64_DIR32LSB		0x25	/* symbol + addend, data4 LSB */
+#define R_IA64_DIR64MSB		0x26	/* symbol + addend, data8 MSB */
+#define R_IA64_DIR64LSB		0x27	/* symbol + addend, data8 LSB */
+#define R_IA64_GPREL22		0x2a	/* @gprel(sym + add), add imm22 */
+#define R_IA64_GPREL64I		0x2b	/* @gprel(sym + add), mov imm64 */
+#define R_IA64_GPREL32MSB	0x2c	/* @gprel(sym + add), data4 MSB */
+#define R_IA64_GPREL32LSB	0x2d	/* @gprel(sym + add), data4 LSB */
+#define R_IA64_GPREL64MSB	0x2e	/* @gprel(sym + add), data8 MSB */
+#define R_IA64_GPREL64LSB	0x2f	/* @gprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF22		0x32	/* @ltoff(sym + add), add imm22 */
+#define R_IA64_LTOFF64I		0x33	/* @ltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF22		0x3a	/* @pltoff(sym + add), add imm22 */
+#define R_IA64_PLTOFF64I	0x3b	/* @pltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF64MSB	0x3e	/* @pltoff(sym + add), data8 MSB */
+#define R_IA64_PLTOFF64LSB	0x3f	/* @pltoff(sym + add), data8 LSB */
+#define R_IA64_FPTR64I		0x43	/* @fptr(sym + add), mov imm64 */
+#define R_IA64_FPTR32MSB	0x44	/* @fptr(sym + add), data4 MSB */
+#define R_IA64_FPTR32LSB	0x45	/* @fptr(sym + add), data4 LSB */
+#define R_IA64_FPTR64MSB	0x46	/* @fptr(sym + add), data8 MSB */
+#define R_IA64_FPTR64LSB	0x47	/* @fptr(sym + add), data8 LSB */
+#define R_IA64_PCREL60B		0x48	/* @pcrel(sym + add), brl */
+#define R_IA64_PCREL21B		0x49	/* @pcrel(sym + add), ptb, call */
+#define R_IA64_PCREL21M		0x4a	/* @pcrel(sym + add), chk.s */
+#define R_IA64_PCREL21F		0x4b	/* @pcrel(sym + add), fchkf */
+#define R_IA64_PCREL32MSB	0x4c	/* @pcrel(sym + add), data4 MSB */
+#define R_IA64_PCREL32LSB	0x4d	/* @pcrel(sym + add), data4 LSB */
+#define R_IA64_PCREL64MSB	0x4e	/* @pcrel(sym + add), data8 MSB */
+#define R_IA64_PCREL64LSB	0x4f	/* @pcrel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_FPTR22	0x52	/* @ltoff(@fptr(s+a)), imm22 */
+#define R_IA64_LTOFF_FPTR64I	0x53	/* @ltoff(@fptr(s+a)), imm64 */
+#define R_IA64_LTOFF_FPTR32MSB	0x54	/* @ltoff(@fptr(s+a)), data4 MSB */
+#define R_IA64_LTOFF_FPTR32LSB	0x55	/* @ltoff(@fptr(s+a)), data4 LSB */
+#define R_IA64_LTOFF_FPTR64MSB	0x56	/* @ltoff(@fptr(s+a)), data8 MSB */
+#define R_IA64_LTOFF_FPTR64LSB	0x57	/* @ltoff(@fptr(s+a)), data8 LSB */
+#define R_IA64_SEGREL32MSB	0x5c	/* @segrel(sym + add), data4 MSB */
+#define R_IA64_SEGREL32LSB	0x5d	/* @segrel(sym + add), data4 LSB */
+#define R_IA64_SEGREL64MSB	0x5e	/* @segrel(sym + add), data8 MSB */
+#define R_IA64_SEGREL64LSB	0x5f	/* @segrel(sym + add), data8 LSB */
+#define R_IA64_SECREL32MSB	0x64	/* @secrel(sym + add), data4 MSB */
+#define R_IA64_SECREL32LSB	0x65	/* @secrel(sym + add), data4 LSB */
+#define R_IA64_SECREL64MSB	0x66	/* @secrel(sym + add), data8 MSB */
+#define R_IA64_SECREL64LSB	0x67	/* @secrel(sym + add), data8 LSB */
+#define R_IA64_REL32MSB		0x6c	/* data 4 + REL */
+#define R_IA64_REL32LSB		0x6d	/* data 4 + REL */
+#define R_IA64_REL64MSB		0x6e	/* data 8 + REL */
+#define R_IA64_REL64LSB		0x6f	/* data 8 + REL */
+#define R_IA64_LTV32MSB		0x74	/* symbol + addend, data4 MSB */
+#define R_IA64_LTV32LSB		0x75	/* symbol + addend, data4 LSB */
+#define R_IA64_LTV64MSB		0x76	/* symbol + addend, data8 MSB */
+#define R_IA64_LTV64LSB		0x77	/* symbol + addend, data8 LSB */
+#define R_IA64_PCREL21BI	0x79	/* @pcrel(sym + add), 21bit inst */
+#define R_IA64_PCREL22		0x7a	/* @pcrel(sym + add), 22bit inst */
+#define R_IA64_PCREL64I		0x7b	/* @pcrel(sym + add), 64bit inst */
+#define R_IA64_IPLTMSB		0x80	/* dynamic reloc, imported PLT, MSB */
+#define R_IA64_IPLTLSB		0x81	/* dynamic reloc, imported PLT, LSB */
+#define R_IA64_COPY		0x84	/* copy relocation */
+#define R_IA64_SUB		0x85	/* Addend and symbol difference */
+#define R_IA64_LTOFF22X		0x86	/* LTOFF22, relaxable.  */
+#define R_IA64_LDXMOV		0x87	/* Use of LTOFF22X.  */
+#define R_IA64_TPREL14		0x91	/* @tprel(sym + add), imm14 */
+#define R_IA64_TPREL22		0x92	/* @tprel(sym + add), imm22 */
+#define R_IA64_TPREL64I		0x93	/* @tprel(sym + add), imm64 */
+#define R_IA64_TPREL64MSB	0x96	/* @tprel(sym + add), data8 MSB */
+#define R_IA64_TPREL64LSB	0x97	/* @tprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_TPREL22	0x9a	/* @ltoff(@tprel(s+a)), imm2 */
+#define R_IA64_DTPMOD64MSB	0xa6	/* @dtpmod(sym + add), data8 MSB */
+#define R_IA64_DTPMOD64LSB	0xa7	/* @dtpmod(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPMOD22	0xaa	/* @ltoff(@dtpmod(sym + add)), imm22 */
+#define R_IA64_DTPREL14		0xb1	/* @dtprel(sym + add), imm14 */
+#define R_IA64_DTPREL22		0xb2	/* @dtprel(sym + add), imm22 */
+#define R_IA64_DTPREL64I	0xb3	/* @dtprel(sym + add), imm64 */
+#define R_IA64_DTPREL32MSB	0xb4	/* @dtprel(sym + add), data4 MSB */
+#define R_IA64_DTPREL32LSB	0xb5	/* @dtprel(sym + add), data4 LSB */
+#define R_IA64_DTPREL64MSB	0xb6	/* @dtprel(sym + add), data8 MSB */
+#define R_IA64_DTPREL64LSB	0xb7	/* @dtprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPREL22	0xba	/* @ltoff(@dtprel(s+a)), imm22 */
+
+/* SH specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field.  */
+#define EF_SH_MACH_MASK		0x1f
+#define EF_SH_UNKNOWN		0x0
+#define EF_SH1			0x1
+#define EF_SH2			0x2
+#define EF_SH3			0x3
+#define EF_SH_DSP		0x4
+#define EF_SH3_DSP		0x5
+#define EF_SH4AL_DSP		0x6
+#define EF_SH3E			0x8
+#define EF_SH4			0x9
+#define EF_SH2E			0xb
+#define EF_SH4A			0xc
+#define EF_SH2A			0xd
+#define EF_SH4_NOFPU		0x10
+#define EF_SH4A_NOFPU		0x11
+#define EF_SH4_NOMMU_NOFPU	0x12
+#define EF_SH2A_NOFPU		0x13
+#define EF_SH3_NOMMU		0x14
+#define EF_SH2A_SH4_NOFPU	0x15
+#define EF_SH2A_SH3_NOFPU	0x16
+#define EF_SH2A_SH4		0x17
+#define EF_SH2A_SH3E		0x18
+
+/* SH relocs.  */
+#define	R_SH_NONE		0
+#define	R_SH_DIR32		1
+#define	R_SH_REL32		2
+#define	R_SH_DIR8WPN		3
+#define	R_SH_IND12W		4
+#define	R_SH_DIR8WPL		5
+#define	R_SH_DIR8WPZ		6
+#define	R_SH_DIR8BP		7
+#define	R_SH_DIR8W		8
+#define	R_SH_DIR8L		9
+#define	R_SH_SWITCH16		25
+#define	R_SH_SWITCH32		26
+#define	R_SH_USES		27
+#define	R_SH_COUNT		28
+#define	R_SH_ALIGN		29
+#define	R_SH_CODE		30
+#define	R_SH_DATA		31
+#define	R_SH_LABEL		32
+#define	R_SH_SWITCH8		33
+#define	R_SH_GNU_VTINHERIT	34
+#define	R_SH_GNU_VTENTRY	35
+#define	R_SH_TLS_GD_32		144
+#define	R_SH_TLS_LD_32		145
+#define	R_SH_TLS_LDO_32		146
+#define	R_SH_TLS_IE_32		147
+#define	R_SH_TLS_LE_32		148
+#define	R_SH_TLS_DTPMOD32	149
+#define	R_SH_TLS_DTPOFF32	150
+#define	R_SH_TLS_TPOFF32	151
+#define	R_SH_GOT32		160
+#define	R_SH_PLT32		161
+#define	R_SH_COPY		162
+#define	R_SH_GLOB_DAT		163
+#define	R_SH_JMP_SLOT		164
+#define	R_SH_RELATIVE		165
+#define	R_SH_GOTOFF		166
+#define	R_SH_GOTPC		167
+/* Keep this the last entry.  */
+#define	R_SH_NUM		256
+
+/* S/390 specific definitions.  */
+
+/* Valid values for the e_flags field.  */
+
+#define EF_S390_HIGH_GPRS    0x00000001  /* High GPRs kernel facility needed.  */
+
+/* Additional s390 relocs */
+
+#define R_390_NONE		0	/* No reloc.  */
+#define R_390_8			1	/* Direct 8 bit.  */
+#define R_390_12		2	/* Direct 12 bit.  */
+#define R_390_16		3	/* Direct 16 bit.  */
+#define R_390_32		4	/* Direct 32 bit.  */
+#define R_390_PC32		5	/* PC relative 32 bit.	*/
+#define R_390_GOT12		6	/* 12 bit GOT offset.  */
+#define R_390_GOT32		7	/* 32 bit GOT offset.  */
+#define R_390_PLT32		8	/* 32 bit PC relative PLT address.  */
+#define R_390_COPY		9	/* Copy symbol at runtime.  */
+#define R_390_GLOB_DAT		10	/* Create GOT entry.  */
+#define R_390_JMP_SLOT		11	/* Create PLT entry.  */
+#define R_390_RELATIVE		12	/* Adjust by program base.  */
+#define R_390_GOTOFF32		13	/* 32 bit offset to GOT.	 */
+#define R_390_GOTPC		14	/* 32 bit PC relative offset to GOT.  */
+#define R_390_GOT16		15	/* 16 bit GOT offset.  */
+#define R_390_PC16		16	/* PC relative 16 bit.	*/
+#define R_390_PC16DBL		17	/* PC relative 16 bit shifted by 1.  */
+#define R_390_PLT16DBL		18	/* 16 bit PC rel. PLT shifted by 1.  */
+#define R_390_PC32DBL		19	/* PC relative 32 bit shifted by 1.  */
+#define R_390_PLT32DBL		20	/* 32 bit PC rel. PLT shifted by 1.  */
+#define R_390_GOTPCDBL		21	/* 32 bit PC rel. GOT shifted by 1.  */
+#define R_390_64		22	/* Direct 64 bit.  */
+#define R_390_PC64		23	/* PC relative 64 bit.	*/
+#define R_390_GOT64		24	/* 64 bit GOT offset.  */
+#define R_390_PLT64		25	/* 64 bit PC relative PLT address.  */
+#define R_390_GOTENT		26	/* 32 bit PC rel. to GOT entry >> 1. */
+#define R_390_GOTOFF16		27	/* 16 bit offset to GOT. */
+#define R_390_GOTOFF64		28	/* 64 bit offset to GOT. */
+#define R_390_GOTPLT12		29	/* 12 bit offset to jump slot.	*/
+#define R_390_GOTPLT16		30	/* 16 bit offset to jump slot.	*/
+#define R_390_GOTPLT32		31	/* 32 bit offset to jump slot.	*/
+#define R_390_GOTPLT64		32	/* 64 bit offset to jump slot.	*/
+#define R_390_GOTPLTENT		33	/* 32 bit rel. offset to jump slot.  */
+#define R_390_PLTOFF16		34	/* 16 bit offset from GOT to PLT. */
+#define R_390_PLTOFF32		35	/* 32 bit offset from GOT to PLT. */
+#define R_390_PLTOFF64		36	/* 16 bit offset from GOT to PLT. */
+#define R_390_TLS_LOAD		37	/* Tag for load insn in TLS code.  */
+#define R_390_TLS_GDCALL	38	/* Tag for function call in general
+					   dynamic TLS code. */
+#define R_390_TLS_LDCALL	39	/* Tag for function call in local
+					   dynamic TLS code. */
+#define R_390_TLS_GD32		40	/* Direct 32 bit for general dynamic
+					   thread local data.  */
+#define R_390_TLS_GD64		41	/* Direct 64 bit for general dynamic
+					  thread local data.  */
+#define R_390_TLS_GOTIE12	42	/* 12 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_TLS_GOTIE32	43	/* 32 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_TLS_GOTIE64	44	/* 64 bit GOT offset for static TLS
+					   block offset. */
+#define R_390_TLS_LDM32		45	/* Direct 32 bit for local dynamic
+					   thread local data in LE code.  */
+#define R_390_TLS_LDM64		46	/* Direct 64 bit for local dynamic
+					   thread local data in LE code.  */
+#define R_390_TLS_IE32		47	/* 32 bit address of GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_IE64		48	/* 64 bit address of GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_IEENT		49	/* 32 bit rel. offset to GOT entry for
+					   negated static TLS block offset.  */
+#define R_390_TLS_LE32		50	/* 32 bit negated offset relative to
+					   static TLS block.  */
+#define R_390_TLS_LE64		51	/* 64 bit negated offset relative to
+					   static TLS block.  */
+#define R_390_TLS_LDO32		52	/* 32 bit offset relative to TLS
+					   block.  */
+#define R_390_TLS_LDO64		53	/* 64 bit offset relative to TLS
+					   block.  */
+#define R_390_TLS_DTPMOD	54	/* ID of module containing symbol.  */
+#define R_390_TLS_DTPOFF	55	/* Offset in TLS block.	 */
+#define R_390_TLS_TPOFF		56	/* Negated offset in static TLS
+					   block.  */
+#define R_390_20		57	/* Direct 20 bit.  */
+#define R_390_GOT20		58	/* 20 bit GOT offset.  */
+#define R_390_GOTPLT20		59	/* 20 bit offset to jump slot.  */
+#define R_390_TLS_GOTIE20	60	/* 20 bit GOT offset for static TLS
+					   block offset.  */
+#define R_390_IRELATIVE         61      /* STT_GNU_IFUNC relocation.  */
+/* Keep this the last entry.  */
+#define R_390_NUM		62
+
+
+/* CRIS relocations.  */
+#define R_CRIS_NONE		0
+#define R_CRIS_8		1
+#define R_CRIS_16		2
+#define R_CRIS_32		3
+#define R_CRIS_8_PCREL		4
+#define R_CRIS_16_PCREL		5
+#define R_CRIS_32_PCREL		6
+#define R_CRIS_GNU_VTINHERIT	7
+#define R_CRIS_GNU_VTENTRY	8
+#define R_CRIS_COPY		9
+#define R_CRIS_GLOB_DAT		10
+#define R_CRIS_JUMP_SLOT	11
+#define R_CRIS_RELATIVE		12
+#define R_CRIS_16_GOT		13
+#define R_CRIS_32_GOT		14
+#define R_CRIS_16_GOTPLT	15
+#define R_CRIS_32_GOTPLT	16
+#define R_CRIS_32_GOTREL	17
+#define R_CRIS_32_PLT_GOTREL	18
+#define R_CRIS_32_PLT_PCREL	19
+
+#define R_CRIS_NUM		20
+
+
+/* AMD x86-64 relocations.  */
+#define R_X86_64_NONE		0	/* No reloc */
+#define R_X86_64_64		1	/* Direct 64 bit  */
+#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
+#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
+#define R_X86_64_PLT32		4	/* 32 bit PLT address */
+#define R_X86_64_COPY		5	/* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
+#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
+#define R_X86_64_RELATIVE	8	/* Adjust by program base */
+#define R_X86_64_GOTPCREL	9	/* 32 bit signed PC relative
+					   offset to GOT */
+#define R_X86_64_32		10	/* Direct 32 bit zero extended */
+#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
+#define R_X86_64_16		12	/* Direct 16 bit zero extended */
+#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
+#define R_X86_64_8		14	/* Direct 8 bit sign extended  */
+#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64	16	/* ID of module containing symbol */
+#define R_X86_64_DTPOFF64	17	/* Offset in module's TLS block */
+#define R_X86_64_TPOFF64	18	/* Offset in initial TLS block */
+#define R_X86_64_TLSGD		19	/* 32 bit signed PC relative offset
+					   to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD		20	/* 32 bit signed PC relative offset
+					   to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32	21	/* Offset in TLS block */
+#define R_X86_64_GOTTPOFF	22	/* 32 bit signed PC relative offset
+					   to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32	23	/* Offset in initial TLS block */
+#define R_X86_64_PC64		24	/* PC relative 64 bit */
+#define R_X86_64_GOTOFF64	25	/* 64 bit offset to GOT */
+#define R_X86_64_GOTPC32	26	/* 32 bit signed pc relative
+					   offset to GOT */
+#define R_X86_64_GOT64		27	/* 64-bit GOT entry offset */
+#define R_X86_64_GOTPCREL64	28	/* 64-bit PC relative offset
+					   to GOT entry */
+#define R_X86_64_GOTPC64	29	/* 64-bit PC relative offset to GOT */
+#define R_X86_64_GOTPLT64	30 	/* like GOT64, says PLT entry needed */
+#define R_X86_64_PLTOFF64	31	/* 64-bit GOT relative offset
+					   to PLT entry */
+#define R_X86_64_SIZE32		32	/* Size of symbol plus 32-bit addend */
+#define R_X86_64_SIZE64		33	/* Size of symbol plus 64-bit addend */
+#define R_X86_64_GOTPC32_TLSDESC 34	/* GOT offset for TLS descriptor.  */
+#define R_X86_64_TLSDESC_CALL   35	/* Marker for call through TLS
+					   descriptor.  */
+#define R_X86_64_TLSDESC        36	/* TLS descriptor.  */
+#define R_X86_64_IRELATIVE	37	/* Adjust indirectly by program base */
+#define R_X86_64_RELATIVE64	38	/* 64-bit adjust by program base */
+					/* 39 Reserved was R_X86_64_PC32_BND */
+					/* 40 Reserved was R_X86_64_PLT32_BND */
+#define R_X86_64_GOTPCRELX	41	/* Load from 32 bit signed pc relative
+					   offset to GOT entry without REX
+					   prefix, relaxable.  */
+#define R_X86_64_REX_GOTPCRELX	42	/* Load from 32 bit signed pc relative
+					   offset to GOT entry with REX prefix,
+					   relaxable.  */
+#define R_X86_64_NUM		43
+
+
+/* AM33 relocations.  */
+#define R_MN10300_NONE		0	/* No reloc.  */
+#define R_MN10300_32		1	/* Direct 32 bit.  */
+#define R_MN10300_16		2	/* Direct 16 bit.  */
+#define R_MN10300_8		3	/* Direct 8 bit.  */
+#define R_MN10300_PCREL32	4	/* PC-relative 32-bit.  */
+#define R_MN10300_PCREL16	5	/* PC-relative 16-bit signed.  */
+#define R_MN10300_PCREL8	6	/* PC-relative 8-bit signed.  */
+#define R_MN10300_GNU_VTINHERIT	7	/* Ancient C++ vtable garbage... */
+#define R_MN10300_GNU_VTENTRY	8	/* ... collection annotation.  */
+#define R_MN10300_24		9	/* Direct 24 bit.  */
+#define R_MN10300_GOTPC32	10	/* 32-bit PCrel offset to GOT.  */
+#define R_MN10300_GOTPC16	11	/* 16-bit PCrel offset to GOT.  */
+#define R_MN10300_GOTOFF32	12	/* 32-bit offset from GOT.  */
+#define R_MN10300_GOTOFF24	13	/* 24-bit offset from GOT.  */
+#define R_MN10300_GOTOFF16	14	/* 16-bit offset from GOT.  */
+#define R_MN10300_PLT32		15	/* 32-bit PCrel to PLT entry.  */
+#define R_MN10300_PLT16		16	/* 16-bit PCrel to PLT entry.  */
+#define R_MN10300_GOT32		17	/* 32-bit offset to GOT entry.  */
+#define R_MN10300_GOT24		18	/* 24-bit offset to GOT entry.  */
+#define R_MN10300_GOT16		19	/* 16-bit offset to GOT entry.  */
+#define R_MN10300_COPY		20	/* Copy symbol at runtime.  */
+#define R_MN10300_GLOB_DAT	21	/* Create GOT entry.  */
+#define R_MN10300_JMP_SLOT	22	/* Create PLT entry.  */
+#define R_MN10300_RELATIVE	23	/* Adjust by program base.  */
+#define R_MN10300_TLS_GD	24	/* 32-bit offset for global dynamic.  */
+#define R_MN10300_TLS_LD	25	/* 32-bit offset for local dynamic.  */
+#define R_MN10300_TLS_LDO	26	/* Module-relative offset.  */
+#define R_MN10300_TLS_GOTIE	27	/* GOT offset for static TLS block
+					   offset.  */
+#define R_MN10300_TLS_IE	28	/* GOT address for static TLS block
+					   offset.  */
+#define R_MN10300_TLS_LE	29	/* Offset relative to static TLS
+					   block.  */
+#define R_MN10300_TLS_DTPMOD	30	/* ID of module containing symbol.  */
+#define R_MN10300_TLS_DTPOFF	31	/* Offset in module TLS block.  */
+#define R_MN10300_TLS_TPOFF	32	/* Offset in static TLS block.  */
+#define R_MN10300_SYM_DIFF	33	/* Adjustment for next reloc as needed
+					   by linker relaxation.  */
+#define R_MN10300_ALIGN		34	/* Alignment requirement for linker
+					   relaxation.  */
+#define R_MN10300_NUM		35
+
+
+/* M32R relocs.  */
+#define R_M32R_NONE		0	/* No reloc. */
+#define R_M32R_16		1	/* Direct 16 bit. */
+#define R_M32R_32		2	/* Direct 32 bit. */
+#define R_M32R_24		3	/* Direct 24 bit. */
+#define R_M32R_10_PCREL		4	/* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL		5	/* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL		6	/* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO		7	/* High 16 bit with unsigned low. */
+#define R_M32R_HI16_SLO		8	/* High 16 bit with signed low. */
+#define R_M32R_LO16		9	/* Low 16 bit. */
+#define R_M32R_SDA16		10	/* 16 bit offset in SDA. */
+#define R_M32R_GNU_VTINHERIT	11
+#define R_M32R_GNU_VTENTRY	12
+/* M32R relocs use SHT_RELA.  */
+#define R_M32R_16_RELA		33	/* Direct 16 bit. */
+#define R_M32R_32_RELA		34	/* Direct 32 bit. */
+#define R_M32R_24_RELA		35	/* Direct 24 bit. */
+#define R_M32R_10_PCREL_RELA	36	/* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL_RELA	37	/* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL_RELA	38	/* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO_RELA	39	/* High 16 bit with unsigned low */
+#define R_M32R_HI16_SLO_RELA	40	/* High 16 bit with signed low */
+#define R_M32R_LO16_RELA	41	/* Low 16 bit */
+#define R_M32R_SDA16_RELA	42	/* 16 bit offset in SDA */
+#define R_M32R_RELA_GNU_VTINHERIT	43
+#define R_M32R_RELA_GNU_VTENTRY	44
+#define R_M32R_REL32		45	/* PC relative 32 bit.  */
+
+#define R_M32R_GOT24		48	/* 24 bit GOT entry */
+#define R_M32R_26_PLTREL	49	/* 26 bit PC relative to PLT shifted */
+#define R_M32R_COPY		50	/* Copy symbol at runtime */
+#define R_M32R_GLOB_DAT		51	/* Create GOT entry */
+#define R_M32R_JMP_SLOT		52	/* Create PLT entry */
+#define R_M32R_RELATIVE		53	/* Adjust by program base */
+#define R_M32R_GOTOFF		54	/* 24 bit offset to GOT */
+#define R_M32R_GOTPC24		55	/* 24 bit PC relative offset to GOT */
+#define R_M32R_GOT16_HI_ULO	56	/* High 16 bit GOT entry with unsigned
+					   low */
+#define R_M32R_GOT16_HI_SLO	57	/* High 16 bit GOT entry with signed
+					   low */
+#define R_M32R_GOT16_LO		58	/* Low 16 bit GOT entry */
+#define R_M32R_GOTPC_HI_ULO	59	/* High 16 bit PC relative offset to
+					   GOT with unsigned low */
+#define R_M32R_GOTPC_HI_SLO	60	/* High 16 bit PC relative offset to
+					   GOT with signed low */
+#define R_M32R_GOTPC_LO		61	/* Low 16 bit PC relative offset to
+					   GOT */
+#define R_M32R_GOTOFF_HI_ULO	62	/* High 16 bit offset to GOT
+					   with unsigned low */
+#define R_M32R_GOTOFF_HI_SLO	63	/* High 16 bit offset to GOT
+					   with signed low */
+#define R_M32R_GOTOFF_LO	64	/* Low 16 bit offset to GOT */
+#define R_M32R_NUM		256	/* Keep this the last entry. */
+
+/* MicroBlaze relocations */
+#define R_MICROBLAZE_NONE		0	/* No reloc. */
+#define R_MICROBLAZE_32 		1	/* Direct 32 bit. */
+#define R_MICROBLAZE_32_PCREL		2	/* PC relative 32 bit. */
+#define R_MICROBLAZE_64_PCREL		3	/* PC relative 64 bit. */
+#define R_MICROBLAZE_32_PCREL_LO	4	/* Low 16 bits of PCREL32. */
+#define R_MICROBLAZE_64 		5	/* Direct 64 bit. */
+#define R_MICROBLAZE_32_LO		6	/* Low 16 bit. */
+#define R_MICROBLAZE_SRO32		7	/* Read-only small data area. */
+#define R_MICROBLAZE_SRW32		8	/* Read-write small data area. */
+#define R_MICROBLAZE_64_NONE		9	/* No reloc. */
+#define R_MICROBLAZE_32_SYM_OP_SYM	10	/* Symbol Op Symbol relocation. */
+#define R_MICROBLAZE_GNU_VTINHERIT	11	/* GNU C++ vtable hierarchy. */
+#define R_MICROBLAZE_GNU_VTENTRY	12	/* GNU C++ vtable member usage. */
+#define R_MICROBLAZE_GOTPC_64		13	/* PC-relative GOT offset.  */
+#define R_MICROBLAZE_GOT_64		14	/* GOT entry offset.  */
+#define R_MICROBLAZE_PLT_64		15	/* PLT offset (PC-relative).  */
+#define R_MICROBLAZE_REL		16	/* Adjust by program base.  */
+#define R_MICROBLAZE_JUMP_SLOT		17	/* Create PLT entry.  */
+#define R_MICROBLAZE_GLOB_DAT		18	/* Create GOT entry.  */
+#define R_MICROBLAZE_GOTOFF_64		19	/* 64 bit offset to GOT. */
+#define R_MICROBLAZE_GOTOFF_32		20	/* 32 bit offset to GOT. */
+#define R_MICROBLAZE_COPY		21	/* Runtime copy.  */
+#define R_MICROBLAZE_TLS		22	/* TLS Reloc. */
+#define R_MICROBLAZE_TLSGD		23	/* TLS General Dynamic. */
+#define R_MICROBLAZE_TLSLD		24	/* TLS Local Dynamic. */
+#define R_MICROBLAZE_TLSDTPMOD32	25	/* TLS Module ID. */
+#define R_MICROBLAZE_TLSDTPREL32	26	/* TLS Offset Within TLS Block. */
+#define R_MICROBLAZE_TLSDTPREL64	27	/* TLS Offset Within TLS Block. */
+#define R_MICROBLAZE_TLSGOTTPREL32	28	/* TLS Offset From Thread Pointer. */
+#define R_MICROBLAZE_TLSTPREL32 	29	/* TLS Offset From Thread Pointer. */
+
+/* Legal values for d_tag (dynamic entry type).  */
+#define DT_NIOS2_GP             0x70000002 /* Address of _gp.  */
+
+/* Nios II relocations.  */
+#define R_NIOS2_NONE		0	/* No reloc.  */
+#define R_NIOS2_S16		1	/* Direct signed 16 bit.  */
+#define R_NIOS2_U16		2	/* Direct unsigned 16 bit.  */
+#define R_NIOS2_PCREL16		3	/* PC relative 16 bit.  */
+#define R_NIOS2_CALL26		4	/* Direct call.  */
+#define R_NIOS2_IMM5		5	/* 5 bit constant expression.  */
+#define R_NIOS2_CACHE_OPX	6	/* 5 bit expression, shift 22.  */
+#define R_NIOS2_IMM6		7	/* 6 bit constant expression.  */
+#define R_NIOS2_IMM8		8	/* 8 bit constant expression.  */
+#define R_NIOS2_HI16		9	/* High 16 bit.  */
+#define R_NIOS2_LO16		10	/* Low 16 bit.  */
+#define R_NIOS2_HIADJ16		11	/* High 16 bit, adjusted.  */
+#define R_NIOS2_BFD_RELOC_32	12	/* 32 bit symbol value + addend.  */
+#define R_NIOS2_BFD_RELOC_16	13	/* 16 bit symbol value + addend.  */
+#define R_NIOS2_BFD_RELOC_8	14	/* 8 bit symbol value + addend.  */
+#define R_NIOS2_GPREL		15	/* 16 bit GP pointer offset.  */
+#define R_NIOS2_GNU_VTINHERIT	16	/* GNU C++ vtable hierarchy.  */
+#define R_NIOS2_GNU_VTENTRY	17	/* GNU C++ vtable member usage.  */
+#define R_NIOS2_UJMP		18	/* Unconditional branch.  */
+#define R_NIOS2_CJMP		19	/* Conditional branch.  */
+#define R_NIOS2_CALLR		20	/* Indirect call through register.  */
+#define R_NIOS2_ALIGN		21	/* Alignment requirement for
+					   linker relaxation.  */
+#define R_NIOS2_GOT16		22	/* 16 bit GOT entry.  */
+#define R_NIOS2_CALL16		23	/* 16 bit GOT entry for function.  */
+#define R_NIOS2_GOTOFF_LO	24	/* %lo of offset to GOT pointer.  */
+#define R_NIOS2_GOTOFF_HA	25	/* %hiadj of offset to GOT pointer.  */
+#define R_NIOS2_PCREL_LO	26	/* %lo of PC relative offset.  */
+#define R_NIOS2_PCREL_HA	27	/* %hiadj of PC relative offset.  */
+#define R_NIOS2_TLS_GD16	28	/* 16 bit GOT offset for TLS GD.  */
+#define R_NIOS2_TLS_LDM16	29	/* 16 bit GOT offset for TLS LDM.  */
+#define R_NIOS2_TLS_LDO16	30	/* 16 bit module relative offset.  */
+#define R_NIOS2_TLS_IE16	31	/* 16 bit GOT offset for TLS IE.  */
+#define R_NIOS2_TLS_LE16	32	/* 16 bit LE TP-relative offset.  */
+#define R_NIOS2_TLS_DTPMOD	33	/* Module number.  */
+#define R_NIOS2_TLS_DTPREL	34	/* Module-relative offset.  */
+#define R_NIOS2_TLS_TPREL	35	/* TP-relative offset.  */
+#define R_NIOS2_COPY		36	/* Copy symbol at runtime.  */
+#define R_NIOS2_GLOB_DAT	37	/* Create GOT entry.  */
+#define R_NIOS2_JUMP_SLOT	38	/* Create PLT entry.  */
+#define R_NIOS2_RELATIVE	39	/* Adjust by program base.  */
+#define R_NIOS2_GOTOFF		40	/* 16 bit offset to GOT pointer.  */
+#define R_NIOS2_CALL26_NOAT	41	/* Direct call in .noat section.  */
+#define R_NIOS2_GOT_LO		42	/* %lo() of GOT entry.  */
+#define R_NIOS2_GOT_HA		43	/* %hiadj() of GOT entry.  */
+#define R_NIOS2_CALL_LO		44	/* %lo() of function GOT entry.  */
+#define R_NIOS2_CALL_HA		45	/* %hiadj() of function GOT entry.  */
+
+/* TILEPro relocations.  */
+#define R_TILEPRO_NONE		0	/* No reloc */
+#define R_TILEPRO_32		1	/* Direct 32 bit */
+#define R_TILEPRO_16		2	/* Direct 16 bit */
+#define R_TILEPRO_8		3	/* Direct 8 bit */
+#define R_TILEPRO_32_PCREL	4	/* PC relative 32 bit */
+#define R_TILEPRO_16_PCREL	5	/* PC relative 16 bit */
+#define R_TILEPRO_8_PCREL	6	/* PC relative 8 bit */
+#define R_TILEPRO_LO16		7	/* Low 16 bit */
+#define R_TILEPRO_HI16		8	/* High 16 bit */
+#define R_TILEPRO_HA16		9	/* High 16 bit, adjusted */
+#define R_TILEPRO_COPY		10	/* Copy relocation */
+#define R_TILEPRO_GLOB_DAT	11	/* Create GOT entry */
+#define R_TILEPRO_JMP_SLOT	12	/* Create PLT entry */
+#define R_TILEPRO_RELATIVE	13	/* Adjust by program base */
+#define R_TILEPRO_BROFF_X1	14	/* X1 pipe branch offset */
+#define R_TILEPRO_JOFFLONG_X1	15	/* X1 pipe jump offset */
+#define R_TILEPRO_JOFFLONG_X1_PLT 16	/* X1 pipe jump offset to PLT */
+#define R_TILEPRO_IMM8_X0	17	/* X0 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y0	18	/* Y0 pipe 8-bit */
+#define R_TILEPRO_IMM8_X1	19	/* X1 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y1	20	/* Y1 pipe 8-bit */
+#define R_TILEPRO_MT_IMM15_X1	21	/* X1 pipe mtspr */
+#define R_TILEPRO_MF_IMM15_X1	22	/* X1 pipe mfspr */
+#define R_TILEPRO_IMM16_X0	23	/* X0 pipe 16-bit */
+#define R_TILEPRO_IMM16_X1	24	/* X1 pipe 16-bit */
+#define R_TILEPRO_IMM16_X0_LO	25	/* X0 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X1_LO	26	/* X1 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X0_HI	27	/* X0 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X1_HI	28	/* X1 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X0_HA	29	/* X0 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X1_HA	30	/* X1 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X0_PCREL 31	/* X0 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X1_PCREL 32	/* X1 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X0_LO_PCREL 33	/* X0 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X1_LO_PCREL 34	/* X1 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X0_HI_PCREL 35	/* X0 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X1_HI_PCREL 36	/* X1 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X0_HA_PCREL 37	/* X0 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X1_HA_PCREL 38	/* X1 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X0_GOT	39	/* X0 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT	40	/* X1 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_LO 41	/* X0 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_LO 42	/* X1 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HI 43	/* X0 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HI 44	/* X1 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HA 45	/* X0 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HA 46	/* X1 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_MMSTART_X0	47	/* X0 pipe mm "start" */
+#define R_TILEPRO_MMEND_X0	48	/* X0 pipe mm "end" */
+#define R_TILEPRO_MMSTART_X1	49	/* X1 pipe mm "start" */
+#define R_TILEPRO_MMEND_X1	50	/* X1 pipe mm "end" */
+#define R_TILEPRO_SHAMT_X0	51	/* X0 pipe shift amount */
+#define R_TILEPRO_SHAMT_X1	52	/* X1 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y0	53	/* Y0 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y1	54	/* Y1 pipe shift amount */
+#define R_TILEPRO_DEST_IMM8_X1	55	/* X1 pipe destination 8-bit */
+/* Relocs 56-59 are currently not defined.  */
+#define R_TILEPRO_TLS_GD_CALL	60	/* "jal" for TLS GD */
+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61	/* X0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62	/* X1 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63	/* Y0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64	/* Y1 pipe "addi" for TLS GD */
+#define R_TILEPRO_TLS_IE_LOAD	65	/* "lw_tls" for TLS IE */
+#define R_TILEPRO_IMM16_X0_TLS_GD 66	/* X0 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD 67	/* X1 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68	/* X0 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69	/* X1 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70	/* X0 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71	/* X1 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72	/* X0 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73	/* X1 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE 74	/* X0 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE 75	/* X1 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76	/* X0 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77	/* X1 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78	/* X0 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79	/* X1 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80	/* X0 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81	/* X1 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_TLS_DTPMOD32	82	/* ID of module containing symbol */
+#define R_TILEPRO_TLS_DTPOFF32	83	/* Offset in TLS block */
+#define R_TILEPRO_TLS_TPOFF32	84	/* Offset in static TLS block */
+#define R_TILEPRO_IMM16_X0_TLS_LE 85	/* X0 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE 86	/* X1 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87	/* X0 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88	/* X1 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89	/* X0 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90	/* X1 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91	/* X0 pipe ha() 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92	/* X1 pipe ha() 16-bit TLS LE offset */
+
+#define R_TILEPRO_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
+#define R_TILEPRO_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
+
+#define R_TILEPRO_NUM		130
+
+
+/* TILE-Gx relocations.  */
+#define R_TILEGX_NONE		0	/* No reloc */
+#define R_TILEGX_64		1	/* Direct 64 bit */
+#define R_TILEGX_32		2	/* Direct 32 bit */
+#define R_TILEGX_16		3	/* Direct 16 bit */
+#define R_TILEGX_8		4	/* Direct 8 bit */
+#define R_TILEGX_64_PCREL	5	/* PC relative 64 bit */
+#define R_TILEGX_32_PCREL	6	/* PC relative 32 bit */
+#define R_TILEGX_16_PCREL	7	/* PC relative 16 bit */
+#define R_TILEGX_8_PCREL	8	/* PC relative 8 bit */
+#define R_TILEGX_HW0		9	/* hword 0 16-bit */
+#define R_TILEGX_HW1		10	/* hword 1 16-bit */
+#define R_TILEGX_HW2		11	/* hword 2 16-bit */
+#define R_TILEGX_HW3		12	/* hword 3 16-bit */
+#define R_TILEGX_HW0_LAST	13	/* last hword 0 16-bit */
+#define R_TILEGX_HW1_LAST	14	/* last hword 1 16-bit */
+#define R_TILEGX_HW2_LAST	15	/* last hword 2 16-bit */
+#define R_TILEGX_COPY		16	/* Copy relocation */
+#define R_TILEGX_GLOB_DAT	17	/* Create GOT entry */
+#define R_TILEGX_JMP_SLOT	18	/* Create PLT entry */
+#define R_TILEGX_RELATIVE	19	/* Adjust by program base */
+#define R_TILEGX_BROFF_X1	20	/* X1 pipe branch offset */
+#define R_TILEGX_JUMPOFF_X1	21	/* X1 pipe jump offset */
+#define R_TILEGX_JUMPOFF_X1_PLT	22	/* X1 pipe jump offset to PLT */
+#define R_TILEGX_IMM8_X0	23	/* X0 pipe 8-bit */
+#define R_TILEGX_IMM8_Y0	24	/* Y0 pipe 8-bit */
+#define R_TILEGX_IMM8_X1	25	/* X1 pipe 8-bit */
+#define R_TILEGX_IMM8_Y1	26	/* Y1 pipe 8-bit */
+#define R_TILEGX_DEST_IMM8_X1	27	/* X1 pipe destination 8-bit */
+#define R_TILEGX_MT_IMM14_X1	28	/* X1 pipe mtspr */
+#define R_TILEGX_MF_IMM14_X1	29	/* X1 pipe mfspr */
+#define R_TILEGX_MMSTART_X0	30	/* X0 pipe mm "start" */
+#define R_TILEGX_MMEND_X0	31	/* X0 pipe mm "end" */
+#define R_TILEGX_SHAMT_X0	32	/* X0 pipe shift amount */
+#define R_TILEGX_SHAMT_X1	33	/* X1 pipe shift amount */
+#define R_TILEGX_SHAMT_Y0	34	/* Y0 pipe shift amount */
+#define R_TILEGX_SHAMT_Y1	35	/* Y1 pipe shift amount */
+#define R_TILEGX_IMM16_X0_HW0	36	/* X0 pipe hword 0 */
+#define R_TILEGX_IMM16_X1_HW0	37	/* X1 pipe hword 0 */
+#define R_TILEGX_IMM16_X0_HW1	38	/* X0 pipe hword 1 */
+#define R_TILEGX_IMM16_X1_HW1	39	/* X1 pipe hword 1 */
+#define R_TILEGX_IMM16_X0_HW2	40	/* X0 pipe hword 2 */
+#define R_TILEGX_IMM16_X1_HW2	41	/* X1 pipe hword 2 */
+#define R_TILEGX_IMM16_X0_HW3	42	/* X0 pipe hword 3 */
+#define R_TILEGX_IMM16_X1_HW3	43	/* X1 pipe hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST 44	/* X0 pipe last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST 45	/* X1 pipe last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST 46	/* X0 pipe last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST 47	/* X1 pipe last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST 48	/* X0 pipe last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST 49	/* X1 pipe last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_PCREL 50	/* X0 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PCREL 51	/* X1 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PCREL 52	/* X0 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PCREL 53	/* X1 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PCREL 54	/* X0 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PCREL 55	/* X1 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X0_HW3_PCREL 56	/* X0 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PCREL 57	/* X1 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_GOT 64	/* X0 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_GOT 65	/* X1 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78	/* X0 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79	/* X1 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80	/* X0 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81	/* X1 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
+/* Relocs 90-91 are currently not defined.  */
+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92	/* X0 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93	/* X1 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
+/* Relocs 104-105 are currently not defined.  */
+#define R_TILEGX_TLS_DTPMOD64	106	/* 64-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF64	107	/* 64-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF64	108	/* 64-bit offset in static TLS block */
+#define R_TILEGX_TLS_DTPMOD32	109	/* 32-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF32	110	/* 32-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF32	111	/* 32-bit offset in static TLS block */
+#define R_TILEGX_TLS_GD_CALL	112	/* "jal" for TLS GD */
+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113	/* X0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114	/* X1 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115	/* Y0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116	/* Y1 pipe "addi" for TLS GD */
+#define R_TILEGX_TLS_IE_LOAD	117	/* "ld_tls" for TLS IE */
+#define R_TILEGX_IMM8_X0_TLS_ADD 118	/* X0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_X1_TLS_ADD 119	/* X1 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y0_TLS_ADD 120	/* Y0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y1_TLS_ADD 121	/* Y1 pipe "addi" for TLS GD/IE */
+
+#define R_TILEGX_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
+#define R_TILEGX_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
+
+#define R_TILEGX_NUM		130
+
+/* BPF specific declarations.  */
+
+#define R_BPF_NONE		0	/* No reloc */
+#define R_BPF_MAP_FD		1	/* Map fd to pointer */
+
+/* Imagination Meta specific relocations. */
+
+#define R_METAG_HIADDR16	0
+#define R_METAG_LOADDR16	1
+#define R_METAG_ADDR32		2	/* 32bit absolute address */
+#define R_METAG_NONE		3	/* No reloc */
+#define R_METAG_RELBRANCH	4
+#define R_METAG_GETSETOFF	5
+
+/* Backward compatability */
+#define R_METAG_REG32OP1	6
+#define R_METAG_REG32OP2	7
+#define R_METAG_REG32OP3	8
+#define R_METAG_REG16OP1	9
+#define R_METAG_REG16OP2	10
+#define R_METAG_REG16OP3	11
+#define R_METAG_REG32OP4	12
+
+#define R_METAG_HIOG		13
+#define R_METAG_LOOG		14
+
+#define R_METAG_REL8		15
+#define R_METAG_REL16		16
+
+/* GNU */
+#define R_METAG_GNU_VTINHERIT	30
+#define R_METAG_GNU_VTENTRY	31
+
+/* PIC relocations */
+#define R_METAG_HI16_GOTOFF	32
+#define R_METAG_LO16_GOTOFF	33
+#define R_METAG_GETSET_GOTOFF	34
+#define R_METAG_GETSET_GOT	35
+#define R_METAG_HI16_GOTPC	36
+#define R_METAG_LO16_GOTPC	37
+#define R_METAG_HI16_PLT	38
+#define R_METAG_LO16_PLT	39
+#define R_METAG_RELBRANCH_PLT	40
+#define R_METAG_GOTOFF		41
+#define R_METAG_PLT		42
+#define R_METAG_COPY		43
+#define R_METAG_JMP_SLOT	44
+#define R_METAG_RELATIVE	45
+#define R_METAG_GLOB_DAT	46
+
+/* TLS relocations */
+#define R_METAG_TLS_GD		47
+#define R_METAG_TLS_LDM		48
+#define R_METAG_TLS_LDO_HI16	49
+#define R_METAG_TLS_LDO_LO16	50
+#define R_METAG_TLS_LDO		51
+#define R_METAG_TLS_IE		52
+#define R_METAG_TLS_IENONPIC	53
+#define R_METAG_TLS_IENONPIC_HI16 54
+#define R_METAG_TLS_IENONPIC_LO16 55
+#define R_METAG_TLS_TPOFF	56
+#define R_METAG_TLS_DTPMOD	57
+#define R_METAG_TLS_DTPOFF	58
+#define R_METAG_TLS_LE		59
+#define R_METAG_TLS_LE_HI16	60
+#define R_METAG_TLS_LE_LO16	61
+
+__END_DECLS
+
+#endif	/* elf.h */
diff --git a/third_party/elfutils/libelf/elf32_checksum.c b/third_party/elfutils/libelf/elf32_checksum.c
new file mode 100644
index 0000000..f9dfccb
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_checksum.c
@@ -0,0 +1,168 @@
+/* Compute simple checksum from permanent parts of the ELF file.
+   Copyright (C) 2002, 2003, 2004, 2005, 2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "gelf.h"
+#include "libelfP.h"
+#include "elf-knowledge.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+#define process_block(crc, data) \
+  __libelf_crc32 (crc, data->d_buf, data->d_size)
+
+
+long int
+elfw2(LIBELFBITS,checksum) (Elf *elf)
+{
+  size_t shstrndx;
+  Elf_Scn *scn;
+  long int result = 0;
+  unsigned char *ident;
+  bool same_byte_order;
+
+  if (elf == NULL)
+    return -1l;
+
+  /* Find the section header string table.  */
+  if  (INTUSE(elf_getshdrstrndx) (elf, &shstrndx) < 0)
+    {
+      /* This can only happen if the ELF handle is not for real.  */
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1l;
+    }
+
+  /* Determine whether the byte order of the file and that of the host
+     is the same.  */
+  ident = elf->state.ELFW(elf,LIBELFBITS).ehdr->e_ident;
+  same_byte_order = ((ident[EI_DATA] == ELFDATA2LSB
+		      && __BYTE_ORDER == __LITTLE_ENDIAN)
+		     || (ident[EI_DATA] == ELFDATA2MSB
+			 && __BYTE_ORDER == __BIG_ENDIAN));
+
+  /* If we don't have native byte order, we will likely need to
+     convert the data with xlate functions.  We do it upfront instead
+     of relocking mid-iteration. */
+  if (!likely (same_byte_order))
+    rwlock_wrlock (elf->lock);
+  else
+    rwlock_rdlock (elf->lock);
+
+  /* Iterate over all sections to find those which are not strippable.  */
+  scn = NULL;
+  while ((scn = INTUSE(elf_nextscn) (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr;
+      Elf_Data *data;
+
+      /* Get the section header.  */
+      shdr = INTUSE(gelf_getshdr) (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+	  result = -1l;
+	  goto out;
+	}
+
+      if (SECTION_STRIP_P (shdr,
+			   INTUSE(elf_strptr) (elf, shstrndx, shdr->sh_name),
+			   true))
+	/* The section can be stripped.  Don't use it.  */
+	continue;
+
+      /* Do not look at NOBITS sections.  */
+      if (shdr->sh_type == SHT_NOBITS)
+	continue;
+
+      /* To compute the checksum we need to get to the data.  For
+	 repeatable results we must use the external format.  The data
+	 we get with 'elf'getdata' might be changed for endianess
+	 reasons.  Therefore we use 'elf_rawdata' if possible.  But
+	 this function can fail if the data was constructed by the
+	 program.  In this case we have to use 'elf_getdata' and
+	 eventually convert the data to the external format.  */
+      data = INTUSE(elf_rawdata) (scn, NULL);
+      if (data != NULL)
+	{
+	  /* The raw data is available.  */
+	  result = process_block (result, data);
+
+	  /* Maybe the user added more data.  These blocks cannot be
+	     read using 'elf_rawdata'.  Simply proceed with looking
+	     for more data block with 'elf_getdata'.  */
+	}
+
+      /* Iterate through the list of data blocks.  */
+      while ((data = INTUSE(elf_getdata) (scn, data)) != NULL)
+	/* If the file byte order is the same as the host byte order
+	   process the buffer directly.  If the data is just a stream
+	   of bytes which the library will not convert we can use it
+	   as well.  */
+	if (likely (same_byte_order) || data->d_type == ELF_T_BYTE)
+	  result = process_block (result, data);
+	else
+	  {
+	    /* Convert the data to file byte order.  */
+	    if (INTUSE(elfw2(LIBELFBITS,xlatetof)) (data, data, ident[EI_DATA])
+		== NULL)
+	      {
+		result = -1l;
+		goto out;
+	      }
+
+	    result = process_block (result, data);
+
+	    /* And convert it back.  */
+	    if (INTUSE(elfw2(LIBELFBITS,xlatetom)) (data, data, ident[EI_DATA])
+		== NULL)
+	      {
+		result = -1l;
+		goto out;
+	      }
+	  }
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,checksum))
diff --git a/third_party/elfutils/libelf/elf32_fsize.c b/third_party/elfutils/libelf/elf32_fsize.c
new file mode 100644
index 0000000..fddae91
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_fsize.c
@@ -0,0 +1,68 @@
+/* Return the size of an object file type.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+size_t
+elfw2(LIBELFBITS, fsize) (Elf_Type type, size_t count, unsigned int version)
+{
+  /* We do not have differences between file and memory sizes.  Better
+     not since otherwise `mmap' would not work.  */
+  if (unlikely (version == EV_NONE) || unlikely (version >= EV_NUM))
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+      return 0;
+    }
+
+  if (unlikely (type >= ELF_T_NUM))
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
+      return 0;
+    }
+
+#if EV_NUM != 2
+  return (count
+	  * __libelf_type_sizes[version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][type]);
+#else
+  return (count
+	  * __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][type]);
+#endif
+}
+#define local_strong_alias(n1, n2) strong_alias (n1, n2)
+local_strong_alias (elfw2(LIBELFBITS, fsize), __elfw2(LIBELFBITS, msize))
diff --git a/third_party/elfutils/libelf/elf32_getchdr.c b/third_party/elfutils/libelf/elf32_getchdr.c
new file mode 100644
index 0000000..982a614
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_getchdr.c
@@ -0,0 +1,83 @@
+/* Return section compression header.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include "libelfP.h"
+#include "common.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Chdr) *
+elfw2(LIBELFBITS,getchdr) (Elf_Scn *scn)
+{
+  ElfW2(LIBELFBITS,Shdr) *shdr = elfw2(LIBELFBITS,getshdr) (scn);
+  if (shdr == NULL)
+    return NULL;
+
+  /* Must have SHF_COMPRESSED flag set.  Allocated or no bits sections
+     can never be compressed.  */
+  if ((shdr->sh_flags & SHF_ALLOC) != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS);
+      return NULL;
+    }
+
+  if (shdr->sh_type == SHT_NULL
+      || shdr->sh_type == SHT_NOBITS)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE);
+      return NULL;
+    }
+
+  if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+    {
+      __libelf_seterrno (ELF_E_NOT_COMPRESSED);
+      return NULL;
+    }
+
+  /* This makes sure the data is in the correct format, so we don't
+     need to swap fields. */
+  Elf_Data *d  = elf_getdata (scn, NULL);
+  if (d == NULL)
+    return NULL;
+
+  if (d->d_size < sizeof (ElfW2(LIBELFBITS,Chdr)) || d->d_buf == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_DATA);
+      return NULL;
+    }
+
+  return (ElfW2(LIBELFBITS,Chdr) *) d->d_buf;
+}
diff --git a/third_party/elfutils/libelf/elf32_getehdr.c b/third_party/elfutils/libelf/elf32_getehdr.c
new file mode 100644
index 0000000..89e3c40
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_getehdr.c
@@ -0,0 +1,96 @@
+/* Get ELF header.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+static ElfW2(LIBELFBITS,Ehdr) *
+getehdr_impl (Elf *elf, int wrlock)
+{
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+ again:
+  if (elf->class == 0)
+    {
+      if (!wrlock)
+	{
+	  rwlock_unlock (elf->lock);
+	  rwlock_wrlock (elf->lock);
+	  wrlock = 1;
+	  goto again;
+	}
+      elf->class = ELFW(ELFCLASS,LIBELFBITS);
+    }
+  else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      return NULL;
+    }
+
+  return elf->state.ELFW(elf,LIBELFBITS).ehdr;
+}
+
+ElfW2(LIBELFBITS,Ehdr) *
+internal_function
+__elfw2(LIBELFBITS,getehdr_wrlock) (Elf *elf)
+{
+  return getehdr_impl (elf, 1);
+}
+
+ElfW2(LIBELFBITS,Ehdr) *
+elfw2(LIBELFBITS,getehdr) (Elf *elf)
+{
+  ElfW2(LIBELFBITS,Ehdr) *result;
+  if (elf == NULL)
+    return NULL;
+
+  rwlock_rdlock (elf->lock);
+  result = getehdr_impl (elf, 0);
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf32_getphdr.c b/third_party/elfutils/libelf/elf32_getphdr.c
new file mode 100644
index 0000000..99b4ac0
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_getphdr.c
@@ -0,0 +1,265 @@
+/* Get ELF program header table.
+   Copyright (C) 1998-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+ElfW2(LIBELFBITS,Phdr) *
+__elfw2(LIBELFBITS,getphdr_wrlock) (Elf *elf)
+{
+  ElfW2(LIBELFBITS,Phdr) *result;
+
+  /* If the program header entry has already been filled in the code
+     below must already have been run.  So the class is set, too.  No
+     need to waste any more time here.  */
+  result = elf->state.ELFW(elf,LIBELFBITS).phdr;
+  if (likely (result != NULL))
+    return result;
+
+  if (elf->class == 0)
+    elf->class = ELFW(ELFCLASS,LIBELFBITS);
+  else if (elf->class != ELFW(ELFCLASS,LIBELFBITS))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      result = NULL;
+      goto out;
+    }
+
+  if (likely (result == NULL))
+    {
+      /* Read the section header table.  */
+      ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+      /* If no program header exists return NULL.  */
+      size_t phnum;
+      if (__elf_getphdrnum_rdlock (elf, &phnum) != 0)
+	goto out;
+      if (phnum == 0 || ehdr->e_phoff == 0)
+	{
+	  __libelf_seterrno (ELF_E_NO_PHDR);
+	  goto out;
+	}
+
+      /* Check this doesn't overflow.  */
+      size_t size = phnum * sizeof (ElfW2(LIBELFBITS,Phdr));
+
+      if (phnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))
+	  || ehdr->e_phoff > elf->maximum_size
+	  || elf->maximum_size - ehdr->e_phoff < size)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      if (elf->map_address != NULL)
+	{
+	  /* First see whether the information in the ELF header is
+	     valid and it does not ask for too much.  */
+	  if (unlikely (ehdr->e_phoff >= elf->maximum_size)
+	      || unlikely (elf->maximum_size - ehdr->e_phoff < size))
+	    {
+	      /* Something is wrong.  */
+	      __libelf_seterrno (ELF_E_INVALID_PHDR);
+	      goto out;
+	    }
+
+	  /* All the data is already mapped.  Use it.  */
+	  void *file_phdr = ((char *) elf->map_address
+			     + elf->start_offset + ehdr->e_phoff);
+	  if (ehdr->e_ident[EI_DATA] == MY_ELFDATA
+	      && (ALLOW_UNALIGNED
+		  || ((uintptr_t) file_phdr
+		      & (__alignof__ (ElfW2(LIBELFBITS,Phdr)) - 1)) == 0))
+	    /* Simply use the mapped data.  */
+	    elf->state.ELFW(elf,LIBELFBITS).phdr = file_phdr;
+	  else
+	    {
+	      ElfW2(LIBELFBITS,Phdr) *notcvt;
+	      ElfW2(LIBELFBITS,Phdr) *phdr;
+
+	      /* Allocate memory for the program headers.  We know the number
+		 of entries from the ELF header.  */
+	      phdr = elf->state.ELFW(elf,LIBELFBITS).phdr =
+		(ElfW2(LIBELFBITS,Phdr) *) malloc (size);
+	      if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
+		{
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  goto out;
+		}
+	      elf->state.ELFW(elf,LIBELFBITS).phdr_flags |=
+		ELF_F_MALLOCED | ELF_F_DIRTY;
+
+	      /* Now copy the data and at the same time convert the
+		 byte order.  */
+
+	      if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
+		{
+		  assert (! ALLOW_UNALIGNED);
+		  memcpy (phdr, file_phdr, size);
+		}
+	      else
+		{
+		  bool copy = ! (ALLOW_UNALIGNED
+				 || ((uintptr_t) file_phdr
+				     & (__alignof__ (ElfW2(LIBELFBITS,Phdr))
+					- 1)) == 0);
+		  if (! copy)
+		    notcvt = file_phdr;
+		  else
+		    {
+		      notcvt = (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
+		      if (unlikely (notcvt == NULL))
+			{
+			  __libelf_seterrno (ELF_E_NOMEM);
+			  goto out;
+			}
+		      memcpy (notcvt, file_phdr, size);
+		    }
+
+		  for (size_t cnt = 0; cnt < phnum; ++cnt)
+		    {
+		      CONVERT_TO (phdr[cnt].p_type, notcvt[cnt].p_type);
+		      CONVERT_TO (phdr[cnt].p_offset, notcvt[cnt].p_offset);
+		      CONVERT_TO (phdr[cnt].p_vaddr, notcvt[cnt].p_vaddr);
+		      CONVERT_TO (phdr[cnt].p_paddr, notcvt[cnt].p_paddr);
+		      CONVERT_TO (phdr[cnt].p_filesz, notcvt[cnt].p_filesz);
+		      CONVERT_TO (phdr[cnt].p_memsz, notcvt[cnt].p_memsz);
+		      CONVERT_TO (phdr[cnt].p_flags, notcvt[cnt].p_flags);
+		      CONVERT_TO (phdr[cnt].p_align, notcvt[cnt].p_align);
+		    }
+
+		  if (copy)
+		    free (notcvt);
+		}
+	    }
+	}
+      else if (likely (elf->fildes != -1))
+	{
+	  /* Allocate memory for the program headers.  We know the number
+	     of entries from the ELF header.  */
+	  elf->state.ELFW(elf,LIBELFBITS).phdr =
+	    (ElfW2(LIBELFBITS,Phdr) *) malloc (size);
+	  if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      goto out;
+	    }
+	  elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_MALLOCED;
+
+	  /* Read the header.  */
+	  ssize_t n = pread_retry (elf->fildes,
+				   elf->state.ELFW(elf,LIBELFBITS).phdr, size,
+				   elf->start_offset + ehdr->e_phoff);
+	  if (unlikely ((size_t) n != size))
+	    {
+	      /* Severe problems.  We cannot read the data.  */
+	      __libelf_seterrno (ELF_E_READ_ERROR);
+	      free (elf->state.ELFW(elf,LIBELFBITS).phdr);
+	      elf->state.ELFW(elf,LIBELFBITS).phdr = NULL;
+	      goto out;
+	    }
+
+	  /* If the byte order of the file is not the same as the one
+	     of the host convert the data now.  */
+	  if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
+	    {
+	      ElfW2(LIBELFBITS,Phdr) *phdr
+		= elf->state.ELFW(elf,LIBELFBITS).phdr;
+
+	      for (size_t cnt = 0; cnt < phnum; ++cnt)
+		{
+		  CONVERT (phdr[cnt].p_type);
+		  CONVERT (phdr[cnt].p_offset);
+		  CONVERT (phdr[cnt].p_vaddr);
+		  CONVERT (phdr[cnt].p_paddr);
+		  CONVERT (phdr[cnt].p_filesz);
+		  CONVERT (phdr[cnt].p_memsz);
+		  CONVERT (phdr[cnt].p_flags);
+		  CONVERT (phdr[cnt].p_align);
+		}
+	    }
+	}
+      else
+	{
+	  /* The file descriptor was already enabled and not all data was
+	     read.  */
+	  __libelf_seterrno (ELF_E_FD_DISABLED);
+	  goto out;
+	}
+
+      result = elf->state.ELFW(elf,LIBELFBITS).phdr;
+    }
+
+ out:
+  return result;
+}
+
+ElfW2(LIBELFBITS,Phdr) *
+elfw2(LIBELFBITS,getphdr) (Elf *elf)
+{
+  ElfW2(LIBELFBITS,Phdr) *result;
+
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* If the program header entry has already been filled in the code
+   * in getphdr_wrlock must already have been run.  So the class is
+   * set, too.  No need to waste any more time here.  */
+  result = elf->state.ELFW(elf,LIBELFBITS).phdr;
+  if (likely (result != NULL))
+    return result;
+
+  rwlock_wrlock (elf->lock);
+  result = __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,getphdr))
diff --git a/third_party/elfutils/libelf/elf32_getshdr.c b/third_party/elfutils/libelf/elf32_getshdr.c
new file mode 100644
index 0000000..237d912
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_getshdr.c
@@ -0,0 +1,299 @@
+/* Return section header.
+   Copyright (C) 1998-2002, 2005, 2007, 2009, 2012, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+static ElfW2(LIBELFBITS,Shdr) *
+load_shdr_wrlock (Elf_Scn *scn)
+{
+  ElfW2(LIBELFBITS,Shdr) *result;
+
+  /* Read the section header table.  */
+  Elf *elf = scn->elf;
+  ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+  /* Try again, maybe the data is there now.  */
+  result = scn->shdr.ELFW(e,LIBELFBITS);
+  if (result != NULL)
+    goto out;
+
+  size_t shnum;
+  if (__elf_getshdrnum_rdlock (elf, &shnum) != 0
+      || shnum > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Shdr)))
+    goto out;
+  size_t size = shnum * sizeof (ElfW2(LIBELFBITS,Shdr));
+
+  /* Allocate memory for the section headers.  We know the number
+     of entries from the ELF header.  */
+  ElfW2(LIBELFBITS,Shdr) *shdr = elf->state.ELFW(elf,LIBELFBITS).shdr =
+    (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
+  if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL)
+    {
+      __libelf_seterrno (ELF_E_NOMEM);
+      goto out;
+    }
+  elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 1;
+
+  if (elf->map_address != NULL)
+    {
+      /* First see whether the information in the ELF header is
+	 valid and it does not ask for too much.  */
+      if (unlikely (ehdr->e_shoff >= elf->maximum_size)
+	  || unlikely (elf->maximum_size - ehdr->e_shoff < size))
+	{
+	  /* Something is wrong.  */
+	  __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+	  goto free_and_out;
+	}
+
+      ElfW2(LIBELFBITS,Shdr) *notcvt;
+
+      /* All the data is already mapped.  If we could use it
+	 directly this would already have happened.  Unless
+	 we allocated the memory ourselves and the ELF_F_MALLOCED
+	 flag is set.  */
+      void *file_shdr = ((char *) elf->map_address
+			 + elf->start_offset + ehdr->e_shoff);
+
+      assert ((elf->flags & ELF_F_MALLOCED)
+	      || ehdr->e_ident[EI_DATA] != MY_ELFDATA
+	      || elf->cmd == ELF_C_READ_MMAP
+	      || (! ALLOW_UNALIGNED
+		  && ((uintptr_t) file_shdr
+		      & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1)) != 0));
+
+      /* Now copy the data and at the same time convert the byte order.  */
+      if (ehdr->e_ident[EI_DATA] == MY_ELFDATA)
+	{
+	  assert ((elf->flags & ELF_F_MALLOCED)
+		  || elf->cmd == ELF_C_READ_MMAP
+		  || ! ALLOW_UNALIGNED);
+	  memcpy (shdr, file_shdr, size);
+	}
+      else
+	{
+	  bool copy = ! (ALLOW_UNALIGNED
+			 || ((uintptr_t) file_shdr
+			     & (__alignof__ (ElfW2(LIBELFBITS,Shdr)) - 1))
+			     == 0);
+	  if (! copy)
+	    notcvt = (ElfW2(LIBELFBITS,Shdr) *)
+	      ((char *) elf->map_address
+	       + elf->start_offset + ehdr->e_shoff);
+	  else
+	    {
+	      notcvt = (ElfW2(LIBELFBITS,Shdr) *) malloc (size);
+	      if (unlikely (notcvt == NULL))
+		{
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  goto out;
+		}
+	      memcpy (notcvt, ((char *) elf->map_address
+			       + elf->start_offset + ehdr->e_shoff),
+		      size);
+	    }
+
+	  for (size_t cnt = 0; cnt < shnum; ++cnt)
+	    {
+	      CONVERT_TO (shdr[cnt].sh_name, notcvt[cnt].sh_name);
+	      CONVERT_TO (shdr[cnt].sh_type, notcvt[cnt].sh_type);
+	      CONVERT_TO (shdr[cnt].sh_flags, notcvt[cnt].sh_flags);
+	      CONVERT_TO (shdr[cnt].sh_addr, notcvt[cnt].sh_addr);
+	      CONVERT_TO (shdr[cnt].sh_offset, notcvt[cnt].sh_offset);
+	      CONVERT_TO (shdr[cnt].sh_size, notcvt[cnt].sh_size);
+	      CONVERT_TO (shdr[cnt].sh_link, notcvt[cnt].sh_link);
+	      CONVERT_TO (shdr[cnt].sh_info, notcvt[cnt].sh_info);
+	      CONVERT_TO (shdr[cnt].sh_addralign,
+			  notcvt[cnt].sh_addralign);
+	      CONVERT_TO (shdr[cnt].sh_entsize, notcvt[cnt].sh_entsize);
+
+	      /* If this is a section with an extended index add a
+		 reference in the section which uses the extended
+		 index.  */
+	      if (shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
+		  && shdr[cnt].sh_link < shnum)
+		elf->state.ELFW(elf,LIBELFBITS).scns.data[shdr[cnt].sh_link].shndx_index
+		  = cnt;
+
+	      /* Set the own shndx_index field in case it has not yet
+		 been set.  */
+	      if (elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index == 0)
+		elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shndx_index
+		  = -1;
+	    }
+
+	  if (copy)
+	    free (notcvt);
+	}
+    }
+  else if (likely (elf->fildes != -1))
+    {
+      /* Read the header.  */
+      ssize_t n = pread_retry (elf->fildes,
+			       elf->state.ELFW(elf,LIBELFBITS).shdr, size,
+			       elf->start_offset + ehdr->e_shoff);
+      if (unlikely ((size_t) n != size))
+	{
+	  /* Severe problems.  We cannot read the data.  */
+	  __libelf_seterrno (ELF_E_READ_ERROR);
+	  goto free_and_out;
+	}
+
+      /* If the byte order of the file is not the same as the one
+	 of the host convert the data now.  */
+      if (ehdr->e_ident[EI_DATA] != MY_ELFDATA)
+	for (size_t cnt = 0; cnt < shnum; ++cnt)
+	  {
+	    CONVERT (shdr[cnt].sh_name);
+	    CONVERT (shdr[cnt].sh_type);
+	    CONVERT (shdr[cnt].sh_flags);
+	    CONVERT (shdr[cnt].sh_addr);
+	    CONVERT (shdr[cnt].sh_offset);
+	    CONVERT (shdr[cnt].sh_size);
+	    CONVERT (shdr[cnt].sh_link);
+	    CONVERT (shdr[cnt].sh_info);
+	    CONVERT (shdr[cnt].sh_addralign);
+	    CONVERT (shdr[cnt].sh_entsize);
+	  }
+    }
+  else
+    {
+      /* The file descriptor was already enabled and not all data was
+	 read.  Undo the allocation.  */
+      __libelf_seterrno (ELF_E_FD_DISABLED);
+
+    free_and_out:
+      free (shdr);
+      elf->state.ELFW(elf,LIBELFBITS).shdr = NULL;
+      elf->state.ELFW(elf,LIBELFBITS).shdr_malloced = 0;
+
+      goto out;
+    }
+
+  /* Set the pointers in the `scn's.  */
+  for (size_t cnt = 0; cnt < shnum; ++cnt)
+    elf->state.ELFW(elf,LIBELFBITS).scns.data[cnt].shdr.ELFW(e,LIBELFBITS)
+      = &elf->state.ELFW(elf,LIBELFBITS).shdr[cnt];
+
+  result = scn->shdr.ELFW(e,LIBELFBITS);
+  assert (result != NULL);
+
+out:
+  return result;
+}
+
+static bool
+scn_valid (Elf_Scn *scn)
+{
+  if (scn == NULL)
+    return false;
+
+  if (unlikely (scn->elf->state.elf.ehdr == NULL))
+    {
+      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+      return false;
+    }
+
+  if (unlikely (scn->elf->class != ELFW(ELFCLASS,LIBELFBITS)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      return false;
+    }
+
+  return true;
+}
+
+ElfW2(LIBELFBITS,Shdr) *
+internal_function
+__elfw2(LIBELFBITS,getshdr_rdlock) (Elf_Scn *scn)
+{
+  ElfW2(LIBELFBITS,Shdr) *result;
+
+  if (!scn_valid (scn))
+    return NULL;
+
+  result = scn->shdr.ELFW(e,LIBELFBITS);
+  if (result == NULL)
+    {
+      rwlock_unlock (scn->elf->lock);
+      rwlock_wrlock (scn->elf->lock);
+      result = scn->shdr.ELFW(e,LIBELFBITS);
+      if (result == NULL)
+	result = load_shdr_wrlock (scn);
+    }
+
+  return result;
+}
+
+ElfW2(LIBELFBITS,Shdr) *
+internal_function
+__elfw2(LIBELFBITS,getshdr_wrlock) (Elf_Scn *scn)
+{
+  ElfW2(LIBELFBITS,Shdr) *result;
+
+  if (!scn_valid (scn))
+    return NULL;
+
+  result = scn->shdr.ELFW(e,LIBELFBITS);
+  if (result == NULL)
+    result = load_shdr_wrlock (scn);
+
+  return result;
+}
+
+ElfW2(LIBELFBITS,Shdr) *
+elfw2(LIBELFBITS,getshdr) (Elf_Scn *scn)
+{
+  ElfW2(LIBELFBITS,Shdr) *result;
+
+  if (!scn_valid (scn))
+    return NULL;
+
+  rwlock_rdlock (scn->elf->lock);
+  result = __elfw2(LIBELFBITS,getshdr_rdlock) (scn);
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf32_newehdr.c b/third_party/elfutils/libelf/elf32_newehdr.c
new file mode 100644
index 0000000..775d115
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_newehdr.c
@@ -0,0 +1,91 @@
+/* Create new ELF header.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Ehdr) *
+elfw2(LIBELFBITS,newehdr) (Elf *elf)
+{
+  ElfW2(LIBELFBITS,Ehdr) *result;
+
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  if (elf->class == 0)
+    elf->class = ELFW(ELFCLASS,LIBELFBITS);
+  else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      result = NULL;
+      goto out;
+    }
+
+  /* Don't create an ELF header if one already exists.  */
+  if (elf->state.ELFW(elf,LIBELFBITS).ehdr == NULL)
+    {
+      /* We use the memory in the ELF descriptor.  */
+      elf->state.ELFW(elf,LIBELFBITS).ehdr =
+	&elf->state.ELFW(elf,LIBELFBITS).ehdr_mem;
+
+      /* We clear this memory.  */
+      memset (elf->state.ELFW(elf,LIBELFBITS).ehdr, '\0',
+	      sizeof (ElfW2(LIBELFBITS,Ehdr)));
+
+      /* Mark the ELF header has modified.  */
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+
+  result = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,newehdr))
diff --git a/third_party/elfutils/libelf/elf32_newphdr.c b/third_party/elfutils/libelf/elf32_newphdr.c
new file mode 100644
index 0000000..4aa7213
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_newphdr.c
@@ -0,0 +1,190 @@
+/* Create new ELF program header table.
+   Copyright (C) 1999-2010, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+ElfW2(LIBELFBITS,Phdr) *
+elfw2(LIBELFBITS,newphdr) (Elf *elf, size_t count)
+{
+  ElfW2(LIBELFBITS,Phdr) *result;
+
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  if (unlikely ((ElfW2(LIBELFBITS,Word)) count != count))
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return NULL;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  if (elf->class == 0)
+    elf->class = ELFW(ELFCLASS,LIBELFBITS);
+  else if (unlikely (elf->class != ELFW(ELFCLASS,LIBELFBITS)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CLASS);
+      result = NULL;
+      goto out;
+    }
+
+  if (unlikely (elf->state.ELFW(elf,LIBELFBITS).ehdr == NULL))
+    {
+      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+      result = NULL;
+      goto out;
+    }
+
+  /* A COUNT of zero means remove existing table.  */
+  if (count == 0)
+    {
+      /* Free the old program header.  */
+      if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
+	{
+	  if (elf->state.ELFW(elf,LIBELFBITS).phdr_flags & ELF_F_MALLOCED)
+	    free (elf->state.ELFW(elf,LIBELFBITS).phdr);
+
+	  /* Set the pointer to NULL.  */
+	  elf->state.ELFW(elf,LIBELFBITS).phdr = NULL;
+	  /* Set the `e_phnum' member to the new value.  */
+	  elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = 0;
+	  /* Also clear any old PN_XNUM extended value.  */
+	  if (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0)
+	    elf->state.ELFW(elf,LIBELFBITS).scns.data[0]
+	      .shdr.ELFW(e,LIBELFBITS)->sh_info = 0;
+	  /* Also set the size.  */
+	  elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize =
+	    sizeof (ElfW2(LIBELFBITS,Phdr));
+
+	  elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_DIRTY;
+	  elf->flags |= ELF_F_DIRTY;
+	  __libelf_seterrno (ELF_E_NOERROR);
+	}
+
+      result = NULL;
+    }
+  else if (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum != count
+	   || count == PN_XNUM
+	   || elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
+    {
+      if (unlikely (count > SIZE_MAX / sizeof (ElfW2(LIBELFBITS,Phdr))))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  result = NULL;
+	  goto out;
+	}
+
+      Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
+      if (unlikely (count >= PN_XNUM && scn0->shdr.ELFW(e,LIBELFBITS) == NULL))
+	{
+	  /* Something is wrong with section zero, but we need it to write
+	     the extended phdr count.  */
+	  __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+	  result = NULL;
+	  goto out;
+	}
+
+      /* Allocate a new program header with the appropriate number of
+	 elements.  */
+      result = (ElfW2(LIBELFBITS,Phdr) *)
+	realloc (elf->state.ELFW(elf,LIBELFBITS).phdr,
+		 count * sizeof (ElfW2(LIBELFBITS,Phdr)));
+      if (result == NULL)
+	__libelf_seterrno (ELF_E_NOMEM);
+      else
+	{
+	  /* Now set the result.  */
+	  elf->state.ELFW(elf,LIBELFBITS).phdr = result;
+	  if (count >= PN_XNUM)
+	    {
+	      /* We have to write COUNT into the zeroth section's sh_info.  */
+	      if (elf->state.ELFW(elf,LIBELFBITS).scns.cnt == 0)
+		{
+		  assert (elf->state.ELFW(elf,LIBELFBITS).scns.max > 0);
+		  elf->state.ELFW(elf,LIBELFBITS).scns.cnt = 1;
+		}
+	      scn0->shdr.ELFW(e,LIBELFBITS)->sh_info = count;
+	      scn0->shdr_flags |= ELF_F_DIRTY;
+	      elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = PN_XNUM;
+	    }
+	  else
+	    /* Set the `e_phnum' member to the new value.  */
+	    elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phnum = count;
+	  /* Clear the whole memory.  */
+	  memset (result, '\0', count * sizeof (ElfW2(LIBELFBITS,Phdr)));
+	  /* Also set the size.  */
+	  elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize =
+	    elf_typesize (LIBELFBITS, ELF_T_PHDR, 1);
+	  /* Remember we allocated the array and mark the structure is
+	     modified.  */
+	  elf->state.ELFW(elf,LIBELFBITS).phdr_flags |=
+	    ELF_F_DIRTY | ELF_F_MALLOCED;
+	  /* We have to rewrite the entire file if the size of the
+	     program header is changed.  */
+	  elf->flags |= ELF_F_DIRTY;
+	}
+    }
+  else
+    {
+      /* We have the same number of entries.  Just clear the array.  */
+      assert (elf->state.ELFW(elf,LIBELFBITS).ehdr->e_phentsize
+	      == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1));
+
+      /* Mark the structure as modified.  */
+      elf->state.ELFW(elf,LIBELFBITS).phdr_flags |= ELF_F_DIRTY;
+
+      result = elf->state.ELFW(elf,LIBELFBITS).phdr;
+      memset (result, '\0', count * sizeof (ElfW2(LIBELFBITS,Phdr)));
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,newphdr))
diff --git a/third_party/elfutils/libelf/elf32_offscn.c b/third_party/elfutils/libelf/elf32_offscn.c
new file mode 100644
index 0000000..9e757c8
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_offscn.c
@@ -0,0 +1,99 @@
+/* Get section at specific index.
+   Copyright (C) 2005, 2008, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+Elf_Scn *
+elfw2(LIBELFBITS,offscn) (Elf *elf, ElfW2(LIBELFBITS,Off) offset)
+{
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  Elf_ScnList *runp = &elf->state.ELFW(elf,LIBELFBITS).scns;
+
+  /* If we have not looked at section headers before,
+     we might need to read them in first.  */
+  if (runp->cnt > 0
+      && unlikely (runp->data[0].shdr.ELFW(e,LIBELFBITS) == NULL)
+      && unlikely (elfw2(LIBELFBITS,getshdr) (&runp->data[0]) == NULL))
+    return NULL;
+
+  rwlock_rdlock (elf->lock);
+
+  Elf_Scn *result = NULL;
+
+  /* Find the section in the list.  */
+  while (1)
+    {
+      for (unsigned int i = 0; i < runp->cnt; ++i)
+	if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_offset == offset)
+	  {
+	    result = &runp->data[i];
+
+	    /* If this section is empty, the following one has the same
+	       sh_offset.  We presume the caller is looking for a nonempty
+	       section, so keep looking if this one is empty.  */
+	    if (runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_size != 0
+		&& runp->data[i].shdr.ELFW(e,LIBELFBITS)->sh_type != SHT_NOBITS)
+	      goto out;
+	  }
+
+      runp = runp->next;
+      if (runp == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OFFSET);
+	  break;
+	}
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elfw2(LIBELFBITS,offscn))
diff --git a/third_party/elfutils/libelf/elf32_updatefile.c b/third_party/elfutils/libelf/elf32_updatefile.c
new file mode 100644
index 0000000..7ac9951
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_updatefile.c
@@ -0,0 +1,850 @@
+/* Write changed data structures.
+   Copyright (C) 2000-2010, 2014, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <libelf.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include <system.h>
+#include "libelfP.h"
+
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+static int
+compare_sections (const void *a, const void *b)
+{
+  const Elf_Scn **scna = (const Elf_Scn **) a;
+  const Elf_Scn **scnb = (const Elf_Scn **) b;
+
+  if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_offset
+      < (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_offset)
+    return -1;
+
+  if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_offset
+      > (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_offset)
+    return 1;
+
+  if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_size
+      < (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_size)
+    return -1;
+
+  if ((*scna)->shdr.ELFW(e,LIBELFBITS)->sh_size
+      > (*scnb)->shdr.ELFW(e,LIBELFBITS)->sh_size)
+    return 1;
+
+  if ((*scna)->index < (*scnb)->index)
+    return -1;
+
+  if ((*scna)->index > (*scnb)->index)
+    return 1;
+
+  return 0;
+}
+
+
+/* Insert the sections in the list into the provided array and sort
+   them according to their start offsets.  For sections with equal
+   start offsets, the size is used; for sections with equal start
+   offsets and sizes, the section index is used.  Sorting by size
+   ensures that zero-length sections are processed first, which
+   is what we want since they do not advance our file writing position.  */
+static void
+sort_sections (Elf_Scn **scns, Elf_ScnList *list)
+{
+  Elf_Scn **scnp = scns;
+  do
+    for (size_t cnt = 0; cnt < list->cnt; ++cnt)
+      *scnp++ = &list->data[cnt];
+  while ((list = list->next) != NULL);
+
+  qsort (scns, scnp - scns, sizeof (*scns), compare_sections);
+}
+
+
+static inline void
+fill_mmap (size_t offset, char *last_position, char *scn_start,
+           char *const shdr_start, char *const shdr_end)
+{
+  size_t written = 0;
+
+  if (last_position < shdr_start)
+    {
+      written = MIN (scn_start + offset - last_position,
+                     shdr_start - last_position);
+
+      memset (last_position, __libelf_fill_byte, written);
+    }
+
+  if (last_position + written != scn_start + offset
+      && shdr_end < scn_start + offset)
+    {
+      char *fill_start = MAX (shdr_end, scn_start);
+      memset (fill_start, __libelf_fill_byte,
+              scn_start + offset - fill_start);
+    }
+}
+
+int
+internal_function
+__elfw2(LIBELFBITS,updatemmap) (Elf *elf, int change_bo, size_t shnum)
+{
+  bool previous_scn_changed = false;
+
+  /* We need the ELF header several times.  */
+  ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+  /* Write out the ELF header.  */
+  if ((elf->state.ELFW(elf,LIBELFBITS).ehdr_flags | elf->flags) & ELF_F_DIRTY)
+    {
+      /* If the type sizes should be different at some time we have to
+	 rewrite this code.  */
+      assert (sizeof (ElfW2(LIBELFBITS,Ehdr))
+	      == elf_typesize (LIBELFBITS, ELF_T_EHDR, 1));
+
+      if (unlikely (change_bo))
+	{
+	  /* Today there is only one version of the ELF header.  */
+#if EV_NUM != 2
+	  xfct_t fctp;
+	  fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]
+#endif
+
+	  /* Do the real work.  */
+	  (*fctp) ((char *) elf->map_address + elf->start_offset, ehdr,
+		   sizeof (ElfW2(LIBELFBITS,Ehdr)), 1);
+	}
+      else if (elf->map_address + elf->start_offset != ehdr)
+	memcpy (elf->map_address + elf->start_offset, ehdr,
+		sizeof (ElfW2(LIBELFBITS,Ehdr)));
+
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags &= ~ELF_F_DIRTY;
+
+      /* We start writing sections after the ELF header only if there is
+	 no program header.  */
+      previous_scn_changed = elf->state.ELFW(elf,LIBELFBITS).phdr == NULL;
+    }
+
+  size_t phnum;
+  if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
+    return -1;
+
+  /* Write out the program header table.  */
+  if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL
+      && ((elf->state.ELFW(elf,LIBELFBITS).phdr_flags | elf->flags)
+	  & ELF_F_DIRTY))
+    {
+      /* If the type sizes should be different at some time we have to
+	 rewrite this code.  */
+      assert (sizeof (ElfW2(LIBELFBITS,Phdr))
+	      == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1));
+
+      /* Maybe the user wants a gap between the ELF header and the program
+	 header.  */
+      if (ehdr->e_phoff > ehdr->e_ehsize)
+	memset (elf->map_address + elf->start_offset + ehdr->e_ehsize,
+		__libelf_fill_byte, ehdr->e_phoff - ehdr->e_ehsize);
+
+      if (unlikely (change_bo))
+	{
+	  /* Today there is only one version of the ELF header.  */
+#if EV_NUM != 2
+	  xfct_t fctp;
+	  fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]
+#endif
+
+	  /* Do the real work.  */
+	  (*fctp) (elf->map_address + elf->start_offset + ehdr->e_phoff,
+		   elf->state.ELFW(elf,LIBELFBITS).phdr,
+		   sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum, 1);
+	}
+      else
+	memcpy (elf->map_address + elf->start_offset + ehdr->e_phoff,
+		elf->state.ELFW(elf,LIBELFBITS).phdr,
+		sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum);
+
+      elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY;
+
+      /* We modified the program header.  Maybe this created a gap so
+	 we have to write fill bytes, if necessary.  */
+      previous_scn_changed = true;
+    }
+
+  /* From now on we have to keep track of the last position to eventually
+     fill the gaps with the prescribed fill byte.  */
+  char *last_position = ((char *) elf->map_address + elf->start_offset
+			 + MAX (elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
+				ehdr->e_phoff)
+			 + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum));
+
+  /* Write all the sections.  Well, only those which are modified.  */
+  if (shnum > 0)
+    {
+      if (unlikely (shnum > SIZE_MAX / sizeof (Elf_Scn *)))
+	return 1;
+
+      Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns;
+      Elf_Scn **scns = (Elf_Scn **) malloc (shnum * sizeof (Elf_Scn *));
+      if (unlikely (scns == NULL))
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  return -1;
+	}
+      char *const shdr_start = ((char *) elf->map_address + elf->start_offset
+				+ ehdr->e_shoff);
+      char *const shdr_end = shdr_start + ehdr->e_shnum * ehdr->e_shentsize;
+
+#if EV_NUM != 2
+      xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
+#else
+# undef shdr_fctp
+# define shdr_fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]
+#endif
+#define shdr_dest ((ElfW2(LIBELFBITS,Shdr) *) shdr_start)
+
+      /* Get all sections into the array and sort them.  */
+      sort_sections (scns, list);
+
+      /* We possibly have to copy the section header data because moving
+	 the sections might overwrite the data.  */
+      for (size_t cnt = 0; cnt < shnum; ++cnt)
+	{
+	  Elf_Scn *scn = scns[cnt];
+
+	  if (!elf->state.ELFW(elf,LIBELFBITS).shdr_malloced
+	      && (scn->shdr_flags & ELF_F_MALLOCED) == 0
+	      && scn->shdr.ELFW(e,LIBELFBITS) != &shdr_dest[scn->index])
+	    {
+	      assert ((char *) elf->map_address + elf->start_offset
+		      < (char *) scn->shdr.ELFW(e,LIBELFBITS));
+	      assert ((char *) scn->shdr.ELFW(e,LIBELFBITS)
+		      < ((char *) elf->map_address + elf->start_offset
+			 + elf->maximum_size));
+
+	      void *p = malloc (sizeof (ElfW2(LIBELFBITS,Shdr)));
+	      if (unlikely (p == NULL))
+		{
+		  free (scns);
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  return -1;
+		}
+	      scn->shdr.ELFW(e,LIBELFBITS)
+		= memcpy (p, scn->shdr.ELFW(e,LIBELFBITS),
+			  sizeof (ElfW2(LIBELFBITS,Shdr)));
+	    }
+
+	  /* If the file is mmaped and the original position of the
+	     section in the file is lower than the new position we
+	     need to save the section content since otherwise it is
+	     overwritten before it can be copied.  If there are
+	     multiple data segments in the list only the first can be
+	     from the file.  */
+	  if (((char *) elf->map_address + elf->start_offset
+	       <= (char  *) scn->data_list.data.d.d_buf)
+	      && ((char *) scn->data_list.data.d.d_buf
+		  < ((char *) elf->map_address + elf->start_offset
+		     + elf->maximum_size))
+	      && (((char *) elf->map_address + elf->start_offset
+		   + scn->shdr.ELFW(e,LIBELFBITS)->sh_offset)
+		  > (char *) scn->data_list.data.d.d_buf))
+	    {
+	      void *p = malloc (scn->data_list.data.d.d_size);
+	      if (unlikely (p == NULL))
+		{
+		  free (scns);
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  return -1;
+		}
+	      scn->data_list.data.d.d_buf = scn->data_base
+		= memcpy (p, scn->data_list.data.d.d_buf,
+			  scn->data_list.data.d.d_size);
+	    }
+	}
+
+      /* Iterate over all the section in the order in which they
+	 appear in the output file.  */
+      for (size_t cnt = 0; cnt < shnum; ++cnt)
+	{
+	  Elf_Scn *scn = scns[cnt];
+	  if (scn->index == 0)
+	    {
+	      /* The dummy section header entry.  It should not be
+		 possible to mark this "section" as dirty.  */
+	      assert ((scn->flags & ELF_F_DIRTY) == 0);
+	      continue;
+	    }
+
+	  ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
+	  if (shdr->sh_type == SHT_NOBITS)
+	    goto next;
+
+	  char *scn_start = ((char *) elf->map_address
+			     + elf->start_offset + shdr->sh_offset);
+	  Elf_Data_List *dl = &scn->data_list;
+	  bool scn_changed = false;
+
+	  if (scn->data_list_rear != NULL)
+	    do
+	      {
+		assert (dl->data.d.d_off >= 0);
+		assert ((GElf_Off) dl->data.d.d_off <= shdr->sh_size);
+		assert (dl->data.d.d_size <= (shdr->sh_size
+					      - (GElf_Off) dl->data.d.d_off));
+
+		/* If there is a gap, fill it.  */
+		if (scn_start + dl->data.d.d_off > last_position
+		    && (dl->data.d.d_off == 0
+			|| ((scn->flags | dl->flags | elf->flags)
+			    & ELF_F_DIRTY) != 0))
+		  {
+		    fill_mmap (dl->data.d.d_off, last_position, scn_start,
+		               shdr_start, shdr_end);
+		  }
+
+		last_position = scn_start + dl->data.d.d_off;
+
+		if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY)
+		  {
+		    /* Let it go backward if the sections use a bogus
+		       layout with overlaps.  We'll overwrite the stupid
+		       user's section data with the latest one, rather than
+		       crashing.  */
+
+		    if (unlikely (change_bo))
+		      {
+#if EV_NUM != 2
+			xfct_t fctp;
+			fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type]
+#endif
+
+			/* Do the real work.  */
+			(*fctp) (last_position, dl->data.d.d_buf,
+				 dl->data.d.d_size, 1);
+
+			last_position += dl->data.d.d_size;
+		      }
+		    else if (dl->data.d.d_size != 0)
+		      last_position = mempcpy (last_position,
+					       dl->data.d.d_buf,
+					       dl->data.d.d_size);
+
+		    scn_changed = true;
+		  }
+		else
+		  last_position += dl->data.d.d_size;
+
+		assert (scn_start + dl->data.d.d_off + dl->data.d.d_size
+			== last_position);
+
+		dl->flags &= ~ELF_F_DIRTY;
+
+		dl = dl->next;
+	      }
+	    while (dl != NULL);
+	  else
+	    {
+	      /* If the previous section (or the ELF/program
+		 header) changed we might have to fill the gap.  */
+	      if (scn_start > last_position && previous_scn_changed)
+		fill_mmap (0, last_position, scn_start,
+		           shdr_start, shdr_end);
+
+	      /* We have to trust the existing section header information.  */
+	      last_position = scn_start + shdr->sh_size;
+	    }
+
+
+	  previous_scn_changed = scn_changed;
+	next:
+	  scn->flags &= ~ELF_F_DIRTY;
+	}
+
+      /* Fill the gap between last section and section header table if
+	 necessary.  */
+      if ((elf->flags & ELF_F_DIRTY)
+	  && last_position < ((char *) elf->map_address + elf->start_offset
+			      + ehdr->e_shoff))
+	memset (last_position, __libelf_fill_byte,
+		(char *) elf->map_address + elf->start_offset + ehdr->e_shoff
+		- last_position);
+
+      /* Write the section header table entry if necessary.  */
+      for (size_t cnt = 0; cnt < shnum; ++cnt)
+	{
+	  Elf_Scn *scn = scns[cnt];
+
+	  if ((scn->shdr_flags | elf->flags) & ELF_F_DIRTY)
+	    {
+	      if (unlikely (change_bo))
+		(*shdr_fctp) (&shdr_dest[scn->index],
+			      scn->shdr.ELFW(e,LIBELFBITS),
+			      sizeof (ElfW2(LIBELFBITS,Shdr)), 1);
+	      else
+		memcpy (&shdr_dest[scn->index],
+			scn->shdr.ELFW(e,LIBELFBITS),
+			sizeof (ElfW2(LIBELFBITS,Shdr)));
+
+	      /* If we previously made a copy of the section header
+		 entry we now have to adjust the pointer again so
+		 point to new place in the mapping.  */
+	      if (!elf->state.ELFW(elf,LIBELFBITS).shdr_malloced
+		  && (scn->shdr_flags & ELF_F_MALLOCED) == 0
+		  && scn->shdr.ELFW(e,LIBELFBITS) != &shdr_dest[scn->index])
+		{
+		  free (scn->shdr.ELFW(e,LIBELFBITS));
+		  scn->shdr.ELFW(e,LIBELFBITS) = &shdr_dest[scn->index];
+		}
+
+	      scn->shdr_flags &= ~ELF_F_DIRTY;
+	    }
+	}
+      free (scns);
+    }
+
+  /* That was the last part.  Clear the overall flag.  */
+  elf->flags &= ~ELF_F_DIRTY;
+
+  /* Make sure the content hits the disk.  */
+  char *msync_start = ((char *) elf->map_address
+		       + (elf->start_offset & ~(sysconf (_SC_PAGESIZE) - 1)));
+  char *msync_end = ((char *) elf->map_address
+		     + elf->start_offset + ehdr->e_shoff
+		     + ehdr->e_shentsize * shnum);
+  (void) msync (msync_start, msync_end - msync_start, MS_SYNC);
+
+  return 0;
+}
+
+
+/* Size of the buffer we use to generate the blocks of fill bytes.  */
+#define FILLBUFSIZE	4096
+
+/* If we have to convert the section buffer contents we have to use
+   temporary buffer.  Only buffers up to MAX_TMPBUF bytes are allocated
+   on the stack.  */
+#define MAX_TMPBUF	32768
+
+
+/* Helper function to write out fill bytes.  */
+static int
+fill (int fd, off_t pos, size_t len, char *fillbuf, size_t *filledp)
+{
+  size_t filled = *filledp;
+  size_t fill_len = MIN (len, FILLBUFSIZE);
+
+  if (unlikely (fill_len > filled) && filled < FILLBUFSIZE)
+    {
+      /* Initialize a few more bytes.  */
+      memset (fillbuf + filled, __libelf_fill_byte, fill_len - filled);
+      *filledp = filled = fill_len;
+    }
+
+  do
+    {
+      /* This many bytes we want to write in this round.  */
+      size_t n = MIN (filled, len);
+
+      if (unlikely ((size_t) pwrite_retry (fd, fillbuf, n, pos) != n))
+	{
+	  __libelf_seterrno (ELF_E_WRITE_ERROR);
+	  return 1;
+	}
+
+      pos += n;
+      len -= n;
+    }
+  while (len > 0);
+
+  return 0;
+}
+
+
+int
+internal_function
+__elfw2(LIBELFBITS,updatefile) (Elf *elf, int change_bo, size_t shnum)
+{
+  char fillbuf[FILLBUFSIZE];
+  size_t filled = 0;
+  bool previous_scn_changed = false;
+
+  /* We need the ELF header several times.  */
+  ElfW2(LIBELFBITS,Ehdr) *ehdr = elf->state.ELFW(elf,LIBELFBITS).ehdr;
+
+  /* Write out the ELF header.  */
+  if ((elf->state.ELFW(elf,LIBELFBITS).ehdr_flags | elf->flags) & ELF_F_DIRTY)
+    {
+      ElfW2(LIBELFBITS,Ehdr) tmp_ehdr;
+      ElfW2(LIBELFBITS,Ehdr) *out_ehdr = ehdr;
+
+      /* If the type sizes should be different at some time we have to
+	 rewrite this code.  */
+      assert (sizeof (ElfW2(LIBELFBITS,Ehdr))
+	      == elf_typesize (LIBELFBITS, ELF_T_EHDR, 1));
+
+      if (unlikely (change_bo))
+	{
+	  /* Today there is only one version of the ELF header.  */
+#if EV_NUM != 2
+	  xfct_t fctp;
+	  fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_EHDR]
+#endif
+
+	  /* Write the converted ELF header in a temporary buffer.  */
+	  (*fctp) (&tmp_ehdr, ehdr, sizeof (ElfW2(LIBELFBITS,Ehdr)), 1);
+
+	  /* This is the buffer we want to write.  */
+	  out_ehdr = &tmp_ehdr;
+	}
+
+      /* Write out the ELF header.  */
+      if (unlikely (pwrite_retry (elf->fildes, out_ehdr,
+				  sizeof (ElfW2(LIBELFBITS,Ehdr)), 0)
+		    != sizeof (ElfW2(LIBELFBITS,Ehdr))))
+	{
+	  __libelf_seterrno (ELF_E_WRITE_ERROR);
+	  return 1;
+	}
+
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags &= ~ELF_F_DIRTY;
+
+      /* We start writing sections after the ELF header only if there is
+	 no program header.  */
+      previous_scn_changed = elf->state.ELFW(elf,LIBELFBITS).phdr == NULL;
+    }
+
+  /* If the type sizes should be different at some time we have to
+     rewrite this code.  */
+  assert (sizeof (ElfW2(LIBELFBITS,Phdr))
+	  == elf_typesize (LIBELFBITS, ELF_T_PHDR, 1));
+
+  size_t phnum;
+  if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
+    return -1;
+
+  /* Write out the program header table.  */
+  if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL
+      && ((elf->state.ELFW(elf,LIBELFBITS).phdr_flags | elf->flags)
+	  & ELF_F_DIRTY))
+    {
+      ElfW2(LIBELFBITS,Phdr) *tmp_phdr = NULL;
+      ElfW2(LIBELFBITS,Phdr) *out_phdr = elf->state.ELFW(elf,LIBELFBITS).phdr;
+
+      /* Maybe the user wants a gap between the ELF header and the program
+	 header.  */
+      if (ehdr->e_phoff > ehdr->e_ehsize
+	  && unlikely (fill (elf->fildes, ehdr->e_ehsize,
+			     ehdr->e_phoff - ehdr->e_ehsize, fillbuf, &filled)
+		       != 0))
+	return 1;
+
+      if (unlikely (change_bo))
+	{
+	  /* Today there is only one version of the ELF header.  */
+#if EV_NUM != 2
+	  xfct_t fctp;
+	  fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_PHDR]
+#endif
+
+	  /* Allocate sufficient memory.  */
+	  tmp_phdr = (ElfW2(LIBELFBITS,Phdr) *)
+	    malloc (sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum);
+	  if (unlikely (tmp_phdr == NULL))
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return 1;
+	    }
+
+	  /* Write the converted ELF header in a temporary buffer.  */
+	  (*fctp) (tmp_phdr, elf->state.ELFW(elf,LIBELFBITS).phdr,
+		   sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum, 1);
+
+	  /* This is the buffer we want to write.  */
+	  out_phdr = tmp_phdr;
+	}
+
+      /* Write out the ELF header.  */
+      size_t phdr_size = sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum;
+      if (unlikely ((size_t) pwrite_retry (elf->fildes, out_phdr,
+					   phdr_size, ehdr->e_phoff)
+		    != phdr_size))
+	{
+	  __libelf_seterrno (ELF_E_WRITE_ERROR);
+	  return 1;
+	}
+
+      /* This is a no-op we we have not allocated any memory.  */
+      free (tmp_phdr);
+
+      elf->state.ELFW(elf,LIBELFBITS).phdr_flags &= ~ELF_F_DIRTY;
+
+      /* We modified the program header.  Maybe this created a gap so
+	 we have to write fill bytes, if necessary.  */
+      previous_scn_changed = true;
+    }
+
+  /* From now on we have to keep track of the last position to eventually
+     fill the gaps with the prescribed fill byte.  */
+  off_t last_offset;
+  if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
+    last_offset = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
+  else
+    last_offset = (ehdr->e_phoff + sizeof (ElfW2(LIBELFBITS,Phdr)) * phnum);
+
+  /* Write all the sections.  Well, only those which are modified.  */
+  if (shnum > 0)
+    {
+      if (unlikely (shnum > SIZE_MAX / (sizeof (Elf_Scn *)
+					+ sizeof (ElfW2(LIBELFBITS,Shdr)))))
+	return 1;
+
+      off_t shdr_offset = elf->start_offset + ehdr->e_shoff;
+#if EV_NUM != 2
+      xfct_t shdr_fctp = __elf_xfctstom[__libelf_version - 1][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR];
+#else
+# undef shdr_fctp
+# define shdr_fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][ELF_T_SHDR]
+#endif
+
+      ElfW2(LIBELFBITS,Shdr) *shdr_data;
+      ElfW2(LIBELFBITS,Shdr) *shdr_data_mem = NULL;
+      if (change_bo || elf->state.ELFW(elf,LIBELFBITS).shdr == NULL
+	  || (elf->flags & ELF_F_DIRTY))
+	{
+	  shdr_data_mem = (ElfW2(LIBELFBITS,Shdr) *)
+	    malloc (shnum * sizeof (ElfW2(LIBELFBITS,Shdr)));
+	  if (unlikely (shdr_data_mem == NULL))
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return -1;
+	    }
+	  shdr_data = shdr_data_mem;
+	}
+      else
+	shdr_data = elf->state.ELFW(elf,LIBELFBITS).shdr;
+      int shdr_flags = elf->flags;
+
+      /* Get all sections into the array and sort them.  */
+      Elf_ScnList *list = &elf->state.ELFW(elf,LIBELFBITS).scns;
+      Elf_Scn **scns = (Elf_Scn **) malloc (shnum * sizeof (Elf_Scn *));
+      if (unlikely (scns == NULL))
+	{
+	  free (shdr_data_mem);
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  return -1;
+	}
+      sort_sections (scns, list);
+
+      for (size_t cnt = 0; cnt < shnum; ++cnt)
+	{
+	  Elf_Scn *scn = scns[cnt];
+	  if (scn->index == 0)
+	    {
+	      /* The dummy section header entry.  It should not be
+		 possible to mark this "section" as dirty.  */
+	      assert ((scn->flags & ELF_F_DIRTY) == 0);
+	      goto next;
+	    }
+
+	  ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
+	  if (shdr->sh_type == SHT_NOBITS)
+	    goto next;
+
+	  off_t scn_start = elf->start_offset + shdr->sh_offset;
+	  Elf_Data_List *dl = &scn->data_list;
+	  bool scn_changed = false;
+
+	  if (scn->data_list_rear != NULL)
+	    do
+	      {
+		/* If there is a gap, fill it.  */
+		if (scn_start + dl->data.d.d_off > last_offset
+		    && ((previous_scn_changed && dl->data.d.d_off == 0)
+			|| ((scn->flags | dl->flags | elf->flags)
+			    & ELF_F_DIRTY) != 0))
+		  {
+		    if (unlikely (fill (elf->fildes, last_offset,
+					(scn_start + dl->data.d.d_off)
+					- last_offset, fillbuf,
+					&filled) != 0))
+		      {
+		      fail_free:
+			free (shdr_data_mem);
+			free (scns);
+			return 1;
+		      }
+		  }
+
+		last_offset = scn_start + dl->data.d.d_off;
+
+		if ((scn->flags | dl->flags | elf->flags) & ELF_F_DIRTY)
+		  {
+		    char tmpbuf[MAX_TMPBUF];
+		    void *buf = dl->data.d.d_buf;
+
+		    /* Let it go backward if the sections use a bogus
+		       layout with overlaps.  We'll overwrite the stupid
+		       user's section data with the latest one, rather than
+		       crashing.  */
+
+		    if (unlikely (change_bo))
+		      {
+#if EV_NUM != 2
+			xfct_t fctp;
+			fctp = __elf_xfctstom[__libelf_version - 1][dl->data.d.d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type];
+#else
+# undef fctp
+# define fctp __elf_xfctstom[0][EV_CURRENT - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][dl->data.d.d_type]
+#endif
+
+			buf = tmpbuf;
+			if (dl->data.d.d_size > MAX_TMPBUF)
+			  {
+			    buf = malloc (dl->data.d.d_size);
+			    if (unlikely (buf == NULL))
+			      {
+				__libelf_seterrno (ELF_E_NOMEM);
+				goto fail_free;
+			      }
+			  }
+
+			/* Do the real work.  */
+			(*fctp) (buf, dl->data.d.d_buf, dl->data.d.d_size, 1);
+		      }
+
+		    ssize_t n = pwrite_retry (elf->fildes, buf,
+					      dl->data.d.d_size,
+					      last_offset);
+		    if (unlikely ((size_t) n != dl->data.d.d_size))
+		      {
+			if (buf != dl->data.d.d_buf && buf != tmpbuf)
+			  free (buf);
+
+			__libelf_seterrno (ELF_E_WRITE_ERROR);
+			goto fail_free;
+		      }
+
+		    if (buf != dl->data.d.d_buf && buf != tmpbuf)
+		      free (buf);
+
+		    scn_changed = true;
+		  }
+
+		last_offset += dl->data.d.d_size;
+
+		dl->flags &= ~ELF_F_DIRTY;
+
+		dl = dl->next;
+	      }
+	    while (dl != NULL);
+	  else
+	    {
+	      /* If the previous section (or the ELF/program
+		 header) changed we might have to fill the gap.  */
+	      if (scn_start > last_offset && previous_scn_changed)
+		{
+		  if (unlikely (fill (elf->fildes, last_offset,
+				      scn_start - last_offset, fillbuf,
+				      &filled) != 0))
+		    goto fail_free;
+		}
+
+	      last_offset = scn_start + shdr->sh_size;
+	    }
+
+	  previous_scn_changed = scn_changed;
+	next:
+	  /* Collect the section header table information.  */
+	  if (unlikely (change_bo))
+	    (*shdr_fctp) (&shdr_data[scn->index],
+			  scn->shdr.ELFW(e,LIBELFBITS),
+			  sizeof (ElfW2(LIBELFBITS,Shdr)), 1);
+	  else if (elf->state.ELFW(elf,LIBELFBITS).shdr == NULL
+		   || (elf->flags & ELF_F_DIRTY))
+	    memcpy (&shdr_data[scn->index], scn->shdr.ELFW(e,LIBELFBITS),
+		    sizeof (ElfW2(LIBELFBITS,Shdr)));
+
+	  shdr_flags |= scn->shdr_flags;
+	  scn->shdr_flags &= ~ELF_F_DIRTY;
+	}
+
+      /* Fill the gap between last section and section header table if
+	 necessary.  */
+      if ((elf->flags & ELF_F_DIRTY) && last_offset < shdr_offset
+	  && unlikely (fill (elf->fildes, last_offset,
+			     shdr_offset - last_offset,
+			     fillbuf, &filled) != 0))
+	goto fail_free;
+
+      /* Write out the section header table.  */
+      if (shdr_flags & ELF_F_DIRTY
+	  && unlikely ((size_t) pwrite_retry (elf->fildes, shdr_data,
+					      sizeof (ElfW2(LIBELFBITS,Shdr))
+					      * shnum, shdr_offset)
+		       != sizeof (ElfW2(LIBELFBITS,Shdr)) * shnum))
+	{
+	  __libelf_seterrno (ELF_E_WRITE_ERROR);
+	  goto fail_free;
+	}
+
+      free (shdr_data_mem);
+      free (scns);
+    }
+
+  /* That was the last part.  Clear the overall flag.  */
+  elf->flags &= ~ELF_F_DIRTY;
+
+  return 0;
+}
diff --git a/third_party/elfutils/libelf/elf32_updatenull.c b/third_party/elfutils/libelf/elf32_updatenull.c
new file mode 100644
index 0000000..3e9ef61
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_updatenull.c
@@ -0,0 +1,443 @@
+/* Update data structures for changes.
+   Copyright (C) 2000-2010, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <libelf.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "elf-knowledge.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS 32
+#endif
+
+
+
+static int
+ELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr,
+			       size_t shnum, int *change_bop)
+{
+  /* Always write the magic bytes.  */
+  if (memcmp (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0)
+    {
+      memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG);
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+
+  /* Always set the file class.  */
+  update_if_changed (ehdr->e_ident[EI_CLASS], ELFW(ELFCLASS,LIBELFBITS),
+		     elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
+
+  /* Set the data encoding if necessary.  */
+  if (unlikely (ehdr->e_ident[EI_DATA] == ELFDATANONE))
+    {
+      ehdr->e_ident[EI_DATA] =
+	BYTE_ORDER == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB;
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+  else if (unlikely (ehdr->e_ident[EI_DATA] >= ELFDATANUM))
+    {
+      __libelf_seterrno (ELF_E_DATA_ENCODING);
+      return 1;
+    }
+  else
+    *change_bop = ((BYTE_ORDER == LITTLE_ENDIAN
+		    && ehdr->e_ident[EI_DATA] != ELFDATA2LSB)
+		   || (BYTE_ORDER == BIG_ENDIAN
+		       && ehdr->e_ident[EI_DATA] != ELFDATA2MSB));
+
+  /* Unconditionally overwrite the ELF version.  */
+  update_if_changed (ehdr->e_ident[EI_VERSION], EV_CURRENT,
+		     elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
+
+  if (unlikely (ehdr->e_version == EV_NONE))
+    {
+      ehdr->e_version = EV_CURRENT;
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+  else if (unlikely (ehdr->e_version >= EV_NUM))
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+      return 1;
+    }
+
+  if (unlikely (shnum >= SHN_LORESERVE))
+    {
+      update_if_changed (ehdr->e_shnum, 0,
+			 elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
+    }
+  else
+    update_if_changed (ehdr->e_shnum, shnum,
+		       elf->state.ELFW(elf,LIBELFBITS).ehdr_flags);
+
+  if (unlikely (ehdr->e_ehsize != elf_typesize (LIBELFBITS, ELF_T_EHDR, 1)))
+    {
+      ehdr->e_ehsize = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+
+  /* If phnum is zero make sure e_phoff is also zero and not some random
+     value.  That would cause trouble in update_file.  */
+  if (ehdr->e_phnum == 0 && ehdr->e_phoff != 0)
+    {
+      ehdr->e_phoff = 0;
+      elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY;
+    }
+
+  return 0;
+}
+
+
+off_t
+internal_function
+__elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum)
+{
+  ElfW2(LIBELFBITS,Ehdr) *ehdr;
+  int changed = 0;
+  int ehdr_flags = 0;
+
+  ehdr = __elfw2(LIBELFBITS,getehdr_wrlock) (elf);
+
+  /* Set the default values.  */
+  if (ELFW(default_ehdr,LIBELFBITS) (elf, ehdr, shnum, change_bop) != 0)
+    return -1;
+
+  /* At least the ELF header is there.  */
+  off_t size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1);
+
+  /* Set the program header position.  */
+  if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL)
+    (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf);
+  if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL)
+    {
+      size_t phnum;
+      if (unlikely (__elf_getphdrnum_rdlock (elf, &phnum) != 0))
+	return -1;
+
+      if (elf->flags & ELF_F_LAYOUT)
+	{
+	  /* The user is supposed to fill out e_phoff.  Use it and
+	     e_phnum to determine the maximum extend.  */
+	  size = MAX ((size_t) size,
+		      ehdr->e_phoff
+		      + elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum));
+	}
+      else
+	{
+	  update_if_changed (ehdr->e_phoff,
+			     elf_typesize (LIBELFBITS, ELF_T_EHDR, 1),
+			     ehdr_flags);
+
+	  /* We need no alignment here.  */
+	  size += elf_typesize (LIBELFBITS, ELF_T_PHDR, phnum);
+	}
+    }
+
+  if (shnum > 0)
+    {
+      struct Elf_Scn *scn1 = NULL;
+      Elf_ScnList *list;
+      bool first = true;
+
+      assert (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0);
+
+      if (shnum >= SHN_LORESERVE)
+	{
+	  /* We have to  fill in the number of sections in the header
+	     of the zeroth section.  */
+	  Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0];
+
+	  update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size,
+			     shnum, scn0->shdr_flags);
+	}
+
+      /* Go over all sections and find out how large they are.  */
+      list = &elf->state.ELFW(elf,LIBELFBITS).scns;
+
+      /* Find the first section. */
+      if (list->cnt > 1)
+	scn1 = &list->data[1];
+      else if (list->next != NULL)
+	scn1 = &list->next->data[0];
+
+      /* Load the section headers if necessary.  This loads the
+	 headers for all sections.  */
+      if (scn1 != NULL && scn1->shdr.ELFW(e,LIBELFBITS) == NULL)
+	(void) __elfw2(LIBELFBITS,getshdr_wrlock) (scn1);
+
+      do
+	{
+	  for (size_t cnt = first == true; cnt < list->cnt; ++cnt)
+	    {
+	      Elf_Scn *scn = &list->data[cnt];
+	      ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS);
+	      off_t offset = 0;
+
+	      assert (shdr != NULL);
+	      ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize;
+	      ElfW2(LIBELFBITS,Word) sh_align = shdr->sh_addralign ?: 1;
+	      if (unlikely (! powerof2 (sh_align)))
+		{
+		  __libelf_seterrno (ELF_E_INVALID_ALIGN);
+		  return -1;
+		}
+
+	      /* Set the sh_entsize value if we can reliably detect it.  */
+	      switch (shdr->sh_type)
+		{
+		case SHT_SYMTAB:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
+		  break;
+		case SHT_RELA:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELA, 1);
+		  break;
+		case SHT_GROUP:
+		  /* Only relocatable files can contain section groups.  */
+		  if (ehdr->e_type != ET_REL)
+		    {
+		      __libelf_seterrno (ELF_E_GROUP_NOT_REL);
+		      return -1;
+		    }
+		  FALLTHROUGH;
+		case SHT_SYMTAB_SHNDX:
+		  sh_entsize = elf_typesize (32, ELF_T_WORD, 1);
+		  break;
+		case SHT_HASH:
+		  sh_entsize = SH_ENTSIZE_HASH (ehdr);
+		  break;
+		case SHT_DYNAMIC:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_DYN, 1);
+		  break;
+		case SHT_REL:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_REL, 1);
+		  break;
+		case SHT_DYNSYM:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1);
+		  break;
+		case SHT_SUNW_move:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_MOVE, 1);
+		  break;
+		case SHT_SUNW_syminfo:
+		  sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1);
+		  break;
+		default:
+		  break;
+		}
+
+	      /* If the section header contained the wrong entry size
+		 correct it and mark the header as modified.  */
+	      update_if_changed (shdr->sh_entsize, sh_entsize,
+				 scn->shdr_flags);
+
+	      if (scn->data_read == 0
+		  && __libelf_set_rawdata_wrlock (scn) != 0)
+		/* Something went wrong.  The error value is already set.  */
+		return -1;
+
+	      /* Iterate over all data blocks.  */
+	      if (list->data[cnt].data_list_rear != NULL)
+		{
+		  Elf_Data_List *dl = &scn->data_list;
+
+		  while (dl != NULL)
+		    {
+		      Elf_Data *data = &dl->data.d;
+		      if (dl == &scn->data_list && data->d_buf == NULL
+			  && scn->rawdata.d.d_buf != NULL)
+			data = &scn->rawdata.d;
+
+		      if (unlikely (data->d_version == EV_NONE)
+			  || unlikely (data->d_version >= EV_NUM))
+			{
+			  __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+			  return -1;
+			}
+
+		      if (unlikely (! powerof2 (data->d_align)))
+			{
+			  __libelf_seterrno (ELF_E_INVALID_ALIGN);
+			  return -1;
+			}
+
+		      sh_align = MAX (sh_align, data->d_align);
+
+		      if (elf->flags & ELF_F_LAYOUT)
+			{
+			  /* The user specified the offset and the size.
+			     All we have to do is check whether this block
+			     fits in the size specified for the section.  */
+			  if (unlikely ((GElf_Word) (data->d_off
+						     + data->d_size)
+					> shdr->sh_size))
+			    {
+			      __libelf_seterrno (ELF_E_SECTION_TOO_SMALL);
+			      return -1;
+			    }
+			}
+		      else
+			{
+			  /* Determine the padding.  */
+			  offset = ((offset + data->d_align - 1)
+				    & ~(data->d_align - 1));
+
+			  update_if_changed (data->d_off, offset, changed);
+
+			  offset += data->d_size;
+			}
+
+		      /* Next data block.  */
+		      dl = dl->next;
+		    }
+		}
+	      else
+		/* Get the size of the section from the raw data.  If
+		   none is available the value is zero.  */
+		offset += scn->rawdata.d.d_size;
+
+	      if (elf->flags & ELF_F_LAYOUT)
+		{
+		  size = MAX ((GElf_Word) size,
+			      (shdr->sh_type != SHT_NOBITS
+			       ? shdr->sh_offset + shdr->sh_size : 0));
+
+		  /* The alignment must be a power of two.  This is a
+		     requirement from the ELF specification.  Additionally
+		     we test for the alignment of the section being large
+		     enough for the largest alignment required by a data
+		     block.  */
+		  if (unlikely (! powerof2 (shdr->sh_addralign))
+		      || unlikely ((shdr->sh_addralign ?: 1) < sh_align))
+		    {
+		      __libelf_seterrno (ELF_E_INVALID_ALIGN);
+		      return -1;
+		    }
+		}
+	      else
+		{
+		  /* How much alignment do we need for this section.  */
+		  update_if_changed (shdr->sh_addralign, sh_align,
+				     scn->shdr_flags);
+
+		  size = (size + sh_align - 1) & ~(sh_align - 1);
+		  int offset_changed = 0;
+		  update_if_changed (shdr->sh_offset, (GElf_Word) size,
+				     offset_changed);
+		  changed |= offset_changed;
+
+		  if (offset_changed && scn->data_list_rear == NULL)
+		    {
+		      /* The position of the section in the file
+			 changed.  Create the section data list.  */
+		      if (__elf_getdata_rdlock (scn, NULL) == NULL)
+			return -1;
+		    }
+
+		  /* See whether the section size is correct.  */
+		  update_if_changed (shdr->sh_size, (GElf_Word) offset,
+				     changed);
+
+		  if (shdr->sh_type != SHT_NOBITS)
+		    size += offset;
+
+		  scn->flags |= changed;
+		}
+
+	      /* Check that the section size is actually a multiple of
+		 the entry size.  */
+	      if (shdr->sh_entsize != 0 && shdr->sh_entsize != 1
+		  && (elf->flags & ELF_F_PERMISSIVE) == 0)
+		{
+		  /* For compressed sections check the uncompressed size.  */
+		  ElfW2(LIBELFBITS,Word) sh_size;
+		  if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+		    sh_size = shdr->sh_size;
+		  else
+		    {
+		      ElfW2(LIBELFBITS,Chdr) *chdr;
+		      chdr = elfw2(LIBELFBITS,getchdr) (scn);
+		      if (unlikely (chdr == NULL))
+			return -1;
+		      sh_size = chdr->ch_size;
+		    }
+
+		  if (unlikely (sh_size % shdr->sh_entsize != 0))
+		    {
+		      __libelf_seterrno (ELF_E_INVALID_SHENTSIZE);
+		      return -1;
+		    }
+		}
+	    }
+
+	  assert (list->next == NULL || list->cnt == list->max);
+
+	  first = false;
+	}
+      while ((list = list->next) != NULL);
+
+      /* Store section information.  */
+      update_if_changed (ehdr->e_shentsize,
+			 elf_typesize (LIBELFBITS, ELF_T_SHDR, 1), ehdr_flags);
+      if (elf->flags & ELF_F_LAYOUT)
+	{
+	  /* The user is supposed to fill out e_shoff.  Use it and
+	     e_shnum (or sh_size of the dummy, first section header)
+	     to determine the maximum extend.  */
+	  size = MAX ((GElf_Word) size,
+		      (ehdr->e_shoff
+		       + (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum))));
+	}
+      else
+	{
+	  /* Align for section header table.
+
+	     Yes, we use `sizeof' and not `__alignof__' since we do not
+	     want to be surprised by architectures with less strict
+	     alignment rules.  */
+#define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off))
+	  size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1);
+
+	  update_if_changed (ehdr->e_shoff, (GElf_Word) size, elf->flags);
+
+	  /* Account for the section header size.  */
+	  size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum);
+	}
+    }
+
+  elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ehdr_flags;
+
+  return size;
+}
diff --git a/third_party/elfutils/libelf/elf32_xlatetof.c b/third_party/elfutils/libelf/elf32_xlatetof.c
new file mode 100644
index 0000000..ac4eaf4
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_xlatetof.c
@@ -0,0 +1,121 @@
+/* Convert from memory to file representation.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS	32
+#endif
+
+
+Elf_Data *
+elfw2(LIBELFBITS, xlatetof) (Elf_Data *dest, const Elf_Data *src,
+			     unsigned int encode)
+{
+  /* First test whether the input data is really suitable for this
+     type.  This means, whether there is an integer number of records.
+     Note that for this implementation the memory and file size of the
+     data types are identical.  */
+#if EV_NUM != 2
+  size_t recsize = __libelf_type_sizes[src->d_version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#else
+  size_t recsize = __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#endif
+
+  if (src->d_size % recsize != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_DATA);
+      return NULL;
+    }
+
+  /* Next see whether the converted data fits in the output buffer.  */
+  if (src->d_size > dest->d_size)
+    {
+      __libelf_seterrno (ELF_E_DEST_SIZE);
+      return NULL;
+    }
+
+  /* Test the encode parameter.  */
+  if (encode != ELFDATA2LSB && encode != ELFDATA2MSB)
+    {
+      __libelf_seterrno (ELF_E_INVALID_ENCODING);
+      return NULL;
+    }
+
+  /* Determine the translation function to use.
+
+     At this point we make an assumption which is valid for all
+     existing implementations so far: the memory and file sizes are
+     the same.  This has very important consequences:
+     a) The requirement that the source and destination buffer can
+	overlap can easily be fulfilled.
+     b) We need only one function to convert from and memory to file
+	and vice versa since the function only has to copy and/or
+	change the byte order.
+  */
+  if ((__BYTE_ORDER == __LITTLE_ENDIAN && encode == ELFDATA2LSB)
+      || (__BYTE_ORDER == __BIG_ENDIAN && encode == ELFDATA2MSB))
+    {
+      /* We simply have to copy since the byte order is the same.  */
+      if (src->d_buf != dest->d_buf)
+	memmove (dest->d_buf, src->d_buf, src->d_size);
+    }
+  else
+    {
+      xfct_t fctp;
+
+      /* Get a pointer to the transformation functions.  The `#ifdef' is
+	 a small optimization since we don't anticipate another ELF
+	 version and so would waste "precious" code.  */
+#if EV_NUM != 2
+      fctp = __elf_xfctstom[dest->d_version - 1][src->d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#else
+      fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#endif
+
+      /* Do the real work.  */
+      (*fctp) (dest->d_buf, src->d_buf, src->d_size, 1);
+    }
+
+  /* Now set the real destination type and length since the operation was
+     successful.  */
+  dest->d_type = src->d_type;
+  dest->d_size = src->d_size;
+
+  return dest;
+}
+INTDEF(elfw2(LIBELFBITS, xlatetof))
diff --git a/third_party/elfutils/libelf/elf32_xlatetom.c b/third_party/elfutils/libelf/elf32_xlatetom.c
new file mode 100644
index 0000000..13cd485
--- /dev/null
+++ b/third_party/elfutils/libelf/elf32_xlatetom.c
@@ -0,0 +1,126 @@
+/* Convert from file to memory representation.
+   Copyright (C) 1998, 1999, 2000, 2002, 2012, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS	32
+#endif
+
+
+Elf_Data *
+elfw2(LIBELFBITS, xlatetom) (Elf_Data *dest, const Elf_Data *src,
+			     unsigned int encode)
+{
+  /* First test whether the input data is really suitable for this
+     type.  This means, whether there is an integer number of records.
+     Note that for this implementation the memory and file size of the
+     data types are identical.  */
+#if EV_NUM != 2
+  size_t recsize = __libelf_type_sizes[src->d_version - 1][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#else
+  size_t recsize = __libelf_type_sizes[0][ELFW(ELFCLASS,LIBELFBITS) - 1][src->d_type];
+#endif
+
+
+  /* We shouldn't require integer number of records when processing
+     notes.  Payload bytes follow the header immediately, it's not an
+     array of records as is the case otherwise.  */
+  if (src->d_type != ELF_T_NHDR
+      && src->d_size % recsize != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_DATA);
+      return NULL;
+    }
+
+  /* Next see whether the converted data fits in the output buffer.  */
+  if (src->d_size > dest->d_size)
+    {
+      __libelf_seterrno (ELF_E_DEST_SIZE);
+      return NULL;
+    }
+
+  /* Test the encode parameter.  */
+  if (encode != ELFDATA2LSB && encode != ELFDATA2MSB)
+    {
+      __libelf_seterrno (ELF_E_INVALID_ENCODING);
+      return NULL;
+    }
+
+  /* Determine the translation function to use.
+
+     At this point we make an assumption which is valid for all
+     existing implementations so far: the memory and file sizes are
+     the same.  This has very important consequences:
+     a) The requirement that the source and destination buffer can
+	overlap can easily be fulfilled.
+     b) We need only one function to convert from and memory to file
+	and vice versa since the function only has to copy and/or
+	change the byte order.
+  */
+  if ((BYTE_ORDER == LITTLE_ENDIAN && encode == ELFDATA2LSB)
+      || (BYTE_ORDER == BIG_ENDIAN && encode == ELFDATA2MSB))
+    {
+      /* We simply have to copy since the byte order is the same.  */
+      if (src->d_buf != dest->d_buf)
+	memmove (dest->d_buf, src->d_buf, src->d_size);
+    }
+  else
+    {
+      xfct_t fctp;
+
+      /* Get a pointer to the transformation functions.  The `#ifdef' is
+	 a small optimization since we don't anticipate another ELF
+	 version and so would waste "precious" code.  */
+#if EV_NUM != 2
+      fctp = __elf_xfctstom[src->d_version - 1][dest->d_version - 1][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#else
+      fctp = __elf_xfctstom[0][0][ELFW(ELFCLASS, LIBELFBITS) - 1][src->d_type];
+#endif
+
+      /* Do the real work.  */
+      (*fctp) (dest->d_buf, src->d_buf, src->d_size, 0);
+    }
+
+  /* Now set the real destination type and length since the operation was
+     successful.  */
+  dest->d_type = src->d_type;
+  dest->d_size = src->d_size;
+
+  return dest;
+}
+INTDEF(elfw2(LIBELFBITS, xlatetom))
diff --git a/third_party/elfutils/libelf/elf64_checksum.c b/third_party/elfutils/libelf/elf64_checksum.c
new file mode 100644
index 0000000..1802240
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_checksum.c
@@ -0,0 +1,31 @@
+/* Compute simple checksum from permanent parts of the ELF file.
+   Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_checksum.c"
diff --git a/third_party/elfutils/libelf/elf64_fsize.c b/third_party/elfutils/libelf/elf64_fsize.c
new file mode 100644
index 0000000..1ee1067
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_fsize.c
@@ -0,0 +1,31 @@
+/* Return the size of an object file type.
+   Copyright (C) 1998, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_fsize.c"
diff --git a/third_party/elfutils/libelf/elf64_getchdr.c b/third_party/elfutils/libelf/elf64_getchdr.c
new file mode 100644
index 0000000..6588b79
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_getchdr.c
@@ -0,0 +1,30 @@
+/* Return section compression header.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_getchdr.c"
diff --git a/third_party/elfutils/libelf/elf64_getehdr.c b/third_party/elfutils/libelf/elf64_getehdr.c
new file mode 100644
index 0000000..b35e7f6
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_getehdr.c
@@ -0,0 +1,31 @@
+/* Return program header table.
+   Copyright (C) 1998, 1999, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_getehdr.c"
diff --git a/third_party/elfutils/libelf/elf64_getphdr.c b/third_party/elfutils/libelf/elf64_getphdr.c
new file mode 100644
index 0000000..c1ee60f
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_getphdr.c
@@ -0,0 +1,31 @@
+/* Return program header table.
+   Copyright (C) 1998, 1999, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_getphdr.c"
diff --git a/third_party/elfutils/libelf/elf64_getshdr.c b/third_party/elfutils/libelf/elf64_getshdr.c
new file mode 100644
index 0000000..c50cc71
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_getshdr.c
@@ -0,0 +1,31 @@
+/* Return section header.
+   Copyright (C) 1998, 1999, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_getshdr.c"
diff --git a/third_party/elfutils/libelf/elf64_newehdr.c b/third_party/elfutils/libelf/elf64_newehdr.c
new file mode 100644
index 0000000..65dd0f7
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_newehdr.c
@@ -0,0 +1,31 @@
+/* Create new program header table.
+   Copyright (C) 1999, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_newehdr.c"
diff --git a/third_party/elfutils/libelf/elf64_newphdr.c b/third_party/elfutils/libelf/elf64_newphdr.c
new file mode 100644
index 0000000..58bfc73
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_newphdr.c
@@ -0,0 +1,31 @@
+/* Create new program header table.
+   Copyright (C) 1999, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_newphdr.c"
diff --git a/third_party/elfutils/libelf/elf64_offscn.c b/third_party/elfutils/libelf/elf64_offscn.c
new file mode 100644
index 0000000..1b37b36
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_offscn.c
@@ -0,0 +1,31 @@
+/* Return program header table.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_offscn.c"
diff --git a/third_party/elfutils/libelf/elf64_updatefile.c b/third_party/elfutils/libelf/elf64_updatefile.c
new file mode 100644
index 0000000..6941fe9a
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_updatefile.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2000, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_updatefile.c"
diff --git a/third_party/elfutils/libelf/elf64_updatenull.c b/third_party/elfutils/libelf/elf64_updatenull.c
new file mode 100644
index 0000000..8333b5b
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_updatenull.c
@@ -0,0 +1,30 @@
+/* Copyright (C) 2000, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_updatenull.c"
diff --git a/third_party/elfutils/libelf/elf64_xlatetof.c b/third_party/elfutils/libelf/elf64_xlatetof.c
new file mode 100644
index 0000000..aacf5b0
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_xlatetof.c
@@ -0,0 +1,31 @@
+/* Convert from memory to file representation.
+   Copyright (C) 1998, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_xlatetof.c"
diff --git a/third_party/elfutils/libelf/elf64_xlatetom.c b/third_party/elfutils/libelf/elf64_xlatetom.c
new file mode 100644
index 0000000..034262c
--- /dev/null
+++ b/third_party/elfutils/libelf/elf64_xlatetom.c
@@ -0,0 +1,31 @@
+/* Convert from file to memory representation.
+   Copyright (C) 1998, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#define LIBELFBITS 64
+#include "elf32_xlatetom.c"
diff --git a/third_party/elfutils/libelf/elf_begin.c b/third_party/elfutils/libelf/elf_begin.c
new file mode 100644
index 0000000..b20ab4f
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_begin.c
@@ -0,0 +1,1180 @@
+/* Create descriptor for processing file.
+   Copyright (C) 1998-2010, 2012, 2014, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+
+/* Create descriptor for archive in memory.  */
+static inline Elf *
+file_read_ar (int fildes, void *map_address, off_t offset, size_t maxsize,
+	      Elf_Cmd cmd, Elf *parent)
+{
+  Elf *elf;
+
+  /* Create a descriptor.  */
+  elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
+                      ELF_K_AR, 0);
+  if (elf != NULL)
+    {
+      /* We don't read all the symbol tables in advance.  All this will
+	 happen on demand.  */
+      elf->state.ar.offset = offset + SARMAG;
+
+      elf->state.ar.elf_ar_hdr.ar_rawname = elf->state.ar.raw_name;
+    }
+
+  return elf;
+}
+
+
+static size_t
+get_shnum (void *map_address, unsigned char *e_ident, int fildes, off_t offset,
+	   size_t maxsize)
+{
+  size_t result;
+  union
+  {
+    Elf32_Ehdr *e32;
+    Elf64_Ehdr *e64;
+    void *p;
+  } ehdr;
+  union
+  {
+    Elf32_Ehdr e32;
+    Elf64_Ehdr e64;
+  } ehdr_mem;
+  bool is32 = e_ident[EI_CLASS] == ELFCLASS32;
+
+  /* Make the ELF header available.  */
+  if (e_ident[EI_DATA] == MY_ELFDATA
+      && (ALLOW_UNALIGNED
+	  || (((size_t) e_ident
+	       & ((is32 ? __alignof__ (Elf32_Ehdr) : __alignof__ (Elf64_Ehdr))
+		  - 1)) == 0)))
+    ehdr.p = e_ident;
+  else
+    {
+      /* We already read the ELF header.  We have to copy the header
+	 since we possibly modify the data here and the caller
+	 expects the memory it passes in to be preserved.  */
+      ehdr.p = &ehdr_mem;
+
+      if (is32)
+	{
+	  if (ALLOW_UNALIGNED)
+	    {
+	      ehdr_mem.e32.e_shnum = ((Elf32_Ehdr *) e_ident)->e_shnum;
+	      ehdr_mem.e32.e_shoff = ((Elf32_Ehdr *) e_ident)->e_shoff;
+	    }
+	  else
+	    memcpy (&ehdr_mem, e_ident, sizeof (Elf32_Ehdr));
+
+	  if (e_ident[EI_DATA] != MY_ELFDATA)
+	    {
+	      CONVERT (ehdr_mem.e32.e_shnum);
+	      CONVERT (ehdr_mem.e32.e_shoff);
+	    }
+	}
+      else
+	{
+	  if (ALLOW_UNALIGNED)
+	    {
+	      ehdr_mem.e64.e_shnum = ((Elf64_Ehdr *) e_ident)->e_shnum;
+	      ehdr_mem.e64.e_shoff = ((Elf64_Ehdr *) e_ident)->e_shoff;
+	    }
+	  else
+	    memcpy (&ehdr_mem, e_ident, sizeof (Elf64_Ehdr));
+
+	  if (e_ident[EI_DATA] != MY_ELFDATA)
+	    {
+	      CONVERT (ehdr_mem.e64.e_shnum);
+	      CONVERT (ehdr_mem.e64.e_shoff);
+	    }
+	}
+    }
+
+  if (is32)
+    {
+      /* Get the number of sections from the ELF header.  */
+      result = ehdr.e32->e_shnum;
+
+      if (unlikely (result == 0) && ehdr.e32->e_shoff != 0)
+	{
+	  if (unlikely (ehdr.e32->e_shoff >= maxsize)
+	      || unlikely (maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr)))
+	    /* Cannot read the first section header.  */
+	    return 0;
+
+	  if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
+	      && (ALLOW_UNALIGNED
+		  || (((size_t) ((char *) map_address + ehdr.e32->e_shoff))
+		      & (__alignof__ (Elf32_Shdr) - 1)) == 0))
+	    /* We can directly access the memory.  */
+	    result = ((Elf32_Shdr *) ((char *) map_address + ehdr.e32->e_shoff
+				      + offset))->sh_size;
+	  else
+	    {
+	      Elf32_Word size;
+	      ssize_t r;
+
+	      if (likely (map_address != NULL))
+		/* gcc will optimize the memcpy to a simple memory
+		   access while taking care of alignment issues.  */
+		memcpy (&size, &((Elf32_Shdr *) ((char *) map_address
+						 + ehdr.e32->e_shoff
+						 + offset))->sh_size,
+			sizeof (Elf32_Word));
+	      else
+		if (unlikely ((r = pread_retry (fildes, &size,
+						sizeof (Elf32_Word),
+						offset + ehdr.e32->e_shoff
+						+ offsetof (Elf32_Shdr,
+							    sh_size)))
+			      != sizeof (Elf32_Word)))
+		  {
+		    if (r < 0)
+		      __libelf_seterrno (ELF_E_INVALID_FILE);
+		    else
+		      __libelf_seterrno (ELF_E_INVALID_ELF);
+		    return (size_t) -1l;
+		  }
+
+	      if (e_ident[EI_DATA] != MY_ELFDATA)
+		CONVERT (size);
+
+	      result = size;
+	    }
+	}
+
+      /* If the section headers were truncated, pretend none were there.  */
+      if (ehdr.e32->e_shoff > maxsize
+	  || maxsize - ehdr.e32->e_shoff < sizeof (Elf32_Shdr) * result)
+	result = 0;
+    }
+  else
+    {
+      /* Get the number of sections from the ELF header.  */
+      result = ehdr.e64->e_shnum;
+
+      if (unlikely (result == 0) && ehdr.e64->e_shoff != 0)
+	{
+	  if (unlikely (ehdr.e64->e_shoff >= maxsize)
+	      || unlikely (ehdr.e64->e_shoff + sizeof (Elf64_Shdr) > maxsize))
+	    /* Cannot read the first section header.  */
+	    return 0;
+
+	  Elf64_Xword size;
+	  if (likely (map_address != NULL) && e_ident[EI_DATA] == MY_ELFDATA
+	      && (ALLOW_UNALIGNED
+		  || (((size_t) ((char *) map_address + ehdr.e64->e_shoff))
+		      & (__alignof__ (Elf64_Shdr) - 1)) == 0))
+	    /* We can directly access the memory.  */
+	    size = ((Elf64_Shdr *) ((char *) map_address + ehdr.e64->e_shoff
+				    + offset))->sh_size;
+	  else
+	    {
+	      ssize_t r;
+	      if (likely (map_address != NULL))
+		/* gcc will optimize the memcpy to a simple memory
+		   access while taking care of alignment issues.  */
+		memcpy (&size, &((Elf64_Shdr *) ((char *) map_address
+						 + ehdr.e64->e_shoff
+						 + offset))->sh_size,
+			sizeof (Elf64_Xword));
+	      else
+		if (unlikely ((r = pread_retry (fildes, &size,
+						sizeof (Elf64_Xword),
+						offset + ehdr.e64->e_shoff
+						+ offsetof (Elf64_Shdr,
+							    sh_size)))
+			      != sizeof (Elf64_Xword)))
+		  {
+		    if (r < 0)
+		      __libelf_seterrno (ELF_E_INVALID_FILE);
+		    else
+		      __libelf_seterrno (ELF_E_INVALID_ELF);
+		    return (size_t) -1l;
+		  }
+
+	      if (e_ident[EI_DATA] != MY_ELFDATA)
+		CONVERT (size);
+	    }
+
+	  if (size > ~((GElf_Word) 0))
+	    {
+	      /* Invalid value, it is too large.  */
+	      __libelf_seterrno (ELF_E_INVALID_ELF);
+	      return (size_t) -1l;
+	    }
+
+	  result = size;
+	}
+
+      /* If the section headers were truncated, pretend none were there.  */
+      if (ehdr.e64->e_shoff > maxsize
+	  || maxsize - ehdr.e64->e_shoff < sizeof (Elf64_Shdr) * result)
+	result = 0;
+    }
+
+  return result;
+}
+
+
+/* Create descriptor for ELF file in memory.  */
+static Elf *
+file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
+	       off_t offset, size_t maxsize, Elf_Cmd cmd, Elf *parent)
+{
+  /* Verify the binary is of the class we can handle.  */
+  if (unlikely ((e_ident[EI_CLASS] != ELFCLASS32
+		 && e_ident[EI_CLASS] != ELFCLASS64)
+		/* We also can only handle two encodings.  */
+		|| (e_ident[EI_DATA] != ELFDATA2LSB
+		    && e_ident[EI_DATA] != ELFDATA2MSB)))
+    {
+      /* Cannot handle this.  */
+      __libelf_seterrno (ELF_E_INVALID_ELF);
+      return NULL;
+    }
+
+  /* Determine the number of sections.  Returns -1 and sets libelf errno
+     if the file handle or elf file is invalid.  Returns zero if there
+     are no section headers (or they cannot be read).  */
+  size_t scncnt = get_shnum (map_address, e_ident, fildes, offset, maxsize);
+  if (scncnt == (size_t) -1l)
+    /* Could not determine the number of sections.  */
+    return NULL;
+
+  /* Check for too many sections.  */
+  if (e_ident[EI_CLASS] == ELFCLASS32)
+    {
+      if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf32_Shdr)))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_ELF);
+	  return NULL;
+	}
+    }
+  else if (scncnt > SIZE_MAX / (sizeof (Elf_Scn) + sizeof (Elf64_Shdr)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_ELF);
+      return NULL;
+    }
+
+  /* We can now allocate the memory.  Even if there are no section headers,
+     we allocate space for a zeroth section in case we need it later.  */
+  const size_t scnmax = (scncnt ?: (cmd == ELF_C_RDWR || cmd == ELF_C_RDWR_MMAP)
+			 ? 1 : 0);
+  Elf *elf = allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
+			   ELF_K_ELF, scnmax * sizeof (Elf_Scn));
+  if (elf == NULL)
+    /* Not enough memory.  allocate_elf will have set libelf errno.  */
+    return NULL;
+
+  assert ((unsigned int) scncnt == scncnt);
+  assert (offsetof (struct Elf, state.elf32.scns)
+	  == offsetof (struct Elf, state.elf64.scns));
+  elf->state.elf32.scns.cnt = scncnt;
+  elf->state.elf32.scns.max = scnmax;
+
+  /* Some more or less arbitrary value.  */
+  elf->state.elf.scnincr = 10;
+
+  /* Make the class easily available.  */
+  elf->class = e_ident[EI_CLASS];
+
+  if (e_ident[EI_CLASS] == ELFCLASS32)
+    {
+      /* This pointer might not be directly usable if the alignment is
+	 not sufficient for the architecture.  */
+      Elf32_Ehdr *ehdr = (Elf32_Ehdr *) ((char *) map_address + offset);
+
+      /* This is a 32-bit binary.  */
+      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
+	  && (ALLOW_UNALIGNED
+	      || (((uintptr_t) ehdr) & (__alignof__ (Elf32_Ehdr) - 1)) == 0))
+	{
+	  /* We can use the mmapped memory.  */
+	  elf->state.elf32.ehdr = ehdr;
+	}
+      else
+	{
+	  /* Copy the ELF header.  */
+	  elf->state.elf32.ehdr = memcpy (&elf->state.elf32.ehdr_mem, e_ident,
+					  sizeof (Elf32_Ehdr));
+
+	  if (e_ident[EI_DATA] != MY_ELFDATA)
+	    {
+	      CONVERT (elf->state.elf32.ehdr_mem.e_type);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_machine);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_version);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_entry);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_phoff);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_shoff);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_flags);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_ehsize);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_phentsize);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_phnum);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_shentsize);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_shnum);
+	      CONVERT (elf->state.elf32.ehdr_mem.e_shstrndx);
+	    }
+	}
+
+      /* Don't precache the phdr pointer here.
+	 elf32_getphdr will validate it against the size when asked.  */
+
+      Elf32_Off e_shoff = elf->state.elf32.ehdr->e_shoff;
+      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
+	  && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write.  */
+	  && (ALLOW_UNALIGNED
+	      || (((uintptr_t) ((char *) ehdr + e_shoff)
+		   & (__alignof__ (Elf32_Shdr) - 1)) == 0)))
+	{
+	  if (unlikely (scncnt > 0 && e_shoff >= maxsize)
+	      || unlikely (maxsize - e_shoff
+			   < scncnt * sizeof (Elf32_Shdr)))
+	    {
+	    free_and_out:
+	      free (elf);
+	      __libelf_seterrno (ELF_E_INVALID_ELF);
+	      return NULL;
+	    }
+	  elf->state.elf32.shdr
+	    = (Elf32_Shdr *) ((char *) ehdr + e_shoff);
+
+	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
+	    {
+	      elf->state.elf32.scns.data[cnt].index = cnt;
+	      elf->state.elf32.scns.data[cnt].elf = elf;
+	      elf->state.elf32.scns.data[cnt].shdr.e32 =
+		&elf->state.elf32.shdr[cnt];
+	      if (likely (elf->state.elf32.shdr[cnt].sh_offset < maxsize)
+		  && likely (elf->state.elf32.shdr[cnt].sh_size
+			     <= maxsize - elf->state.elf32.shdr[cnt].sh_offset))
+		elf->state.elf32.scns.data[cnt].rawdata_base =
+		  elf->state.elf32.scns.data[cnt].data_base =
+		  ((char *) map_address + offset
+		   + elf->state.elf32.shdr[cnt].sh_offset);
+	      elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
+
+	      /* If this is a section with an extended index add a
+		 reference in the section which uses the extended
+		 index.  */
+	      if (elf->state.elf32.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
+		  && elf->state.elf32.shdr[cnt].sh_link < scncnt)
+		elf->state.elf32.scns.data[elf->state.elf32.shdr[cnt].sh_link].shndx_index
+		  = cnt;
+
+	      /* Set the own shndx_index field in case it has not yet
+		 been set.  */
+	      if (elf->state.elf32.scns.data[cnt].shndx_index == 0)
+		elf->state.elf32.scns.data[cnt].shndx_index = -1;
+	    }
+	}
+      else
+	{
+	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
+	    {
+	      elf->state.elf32.scns.data[cnt].index = cnt;
+	      elf->state.elf32.scns.data[cnt].elf = elf;
+	      elf->state.elf32.scns.data[cnt].list = &elf->state.elf32.scns;
+	    }
+	}
+
+      /* So far only one block with sections.  */
+      elf->state.elf32.scns_last = &elf->state.elf32.scns;
+    }
+  else
+    {
+      /* This pointer might not be directly usable if the alignment is
+	 not sufficient for the architecture.  */
+      Elf64_Ehdr *ehdr = (Elf64_Ehdr *) ((char *) map_address + offset);
+
+      /* This is a 64-bit binary.  */
+      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
+	  && (ALLOW_UNALIGNED
+	      || (((uintptr_t) ehdr) & (__alignof__ (Elf64_Ehdr) - 1)) == 0))
+	{
+	  /* We can use the mmapped memory.  */
+	  elf->state.elf64.ehdr = ehdr;
+	}
+      else
+	{
+	  /* Copy the ELF header.  */
+	  elf->state.elf64.ehdr = memcpy (&elf->state.elf64.ehdr_mem, e_ident,
+					  sizeof (Elf64_Ehdr));
+
+	  if (e_ident[EI_DATA] != MY_ELFDATA)
+	    {
+	      CONVERT (elf->state.elf64.ehdr_mem.e_type);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_machine);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_version);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_entry);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_phoff);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_shoff);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_flags);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_ehsize);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_phentsize);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_phnum);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_shentsize);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_shnum);
+	      CONVERT (elf->state.elf64.ehdr_mem.e_shstrndx);
+	    }
+	}
+
+      /* Don't precache the phdr pointer here.
+	 elf64_getphdr will validate it against the size when asked.  */
+
+      Elf64_Off e_shoff = elf->state.elf64.ehdr->e_shoff;
+      if (map_address != NULL && e_ident[EI_DATA] == MY_ELFDATA
+	  && cmd != ELF_C_READ_MMAP /* We need a copy to be able to write.  */
+	  && (ALLOW_UNALIGNED
+	      || (((uintptr_t) ((char *) ehdr + e_shoff)
+		   & (__alignof__ (Elf64_Shdr) - 1)) == 0)))
+	{
+	  if (unlikely (scncnt > 0 && e_shoff >= maxsize)
+	      || unlikely (maxsize - e_shoff
+			   < scncnt * sizeof (Elf64_Shdr)))
+	    goto free_and_out;
+	  elf->state.elf64.shdr
+	    = (Elf64_Shdr *) ((char *) ehdr + e_shoff);
+
+	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
+	    {
+	      elf->state.elf64.scns.data[cnt].index = cnt;
+	      elf->state.elf64.scns.data[cnt].elf = elf;
+	      elf->state.elf64.scns.data[cnt].shdr.e64 =
+		&elf->state.elf64.shdr[cnt];
+	      if (likely (elf->state.elf64.shdr[cnt].sh_offset < maxsize)
+		  && likely (elf->state.elf64.shdr[cnt].sh_size
+			     <= maxsize - elf->state.elf64.shdr[cnt].sh_offset))
+		elf->state.elf64.scns.data[cnt].rawdata_base =
+		  elf->state.elf64.scns.data[cnt].data_base =
+		  ((char *) map_address + offset
+		   + elf->state.elf64.shdr[cnt].sh_offset);
+	      elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
+
+	      /* If this is a section with an extended index add a
+		 reference in the section which uses the extended
+		 index.  */
+	      if (elf->state.elf64.shdr[cnt].sh_type == SHT_SYMTAB_SHNDX
+		  && elf->state.elf64.shdr[cnt].sh_link < scncnt)
+		elf->state.elf64.scns.data[elf->state.elf64.shdr[cnt].sh_link].shndx_index
+		  = cnt;
+
+	      /* Set the own shndx_index field in case it has not yet
+		 been set.  */
+	      if (elf->state.elf64.scns.data[cnt].shndx_index == 0)
+		elf->state.elf64.scns.data[cnt].shndx_index = -1;
+	    }
+	}
+      else
+	{
+	  for (size_t cnt = 0; cnt < scncnt; ++cnt)
+	    {
+	      elf->state.elf64.scns.data[cnt].index = cnt;
+	      elf->state.elf64.scns.data[cnt].elf = elf;
+	      elf->state.elf64.scns.data[cnt].list = &elf->state.elf64.scns;
+	    }
+	}
+
+      /* So far only one block with sections.  */
+      elf->state.elf64.scns_last = &elf->state.elf64.scns;
+    }
+
+  return elf;
+}
+
+
+Elf *
+internal_function
+__libelf_read_mmaped_file (int fildes, void *map_address,  off_t offset,
+			   size_t maxsize, Elf_Cmd cmd, Elf *parent)
+{
+  /* We have to find out what kind of file this is.  We handle ELF
+     files and archives.  To find out what we have we must look at the
+     header.  The header for an ELF file is EI_NIDENT bytes in size,
+     the header for an archive file SARMAG bytes long.  */
+  unsigned char *e_ident = (unsigned char *) map_address + offset;
+
+  /* See what kind of object we have here.  */
+  Elf_Kind kind = determine_kind (e_ident, maxsize);
+
+  switch (kind)
+    {
+    case ELF_K_ELF:
+      return file_read_elf (fildes, map_address, e_ident, offset, maxsize,
+			    cmd, parent);
+
+    case ELF_K_AR:
+      return file_read_ar (fildes, map_address, offset, maxsize, cmd, parent);
+
+    default:
+      break;
+    }
+
+  /* This case is easy.  Since we cannot do anything with this file
+     create a dummy descriptor.  */
+  return allocate_elf (fildes, map_address, offset, maxsize, cmd, parent,
+		       ELF_K_NONE, 0);
+}
+
+
+static Elf *
+read_unmmaped_file (int fildes, off_t offset, size_t maxsize, Elf_Cmd cmd,
+		    Elf *parent)
+{
+  /* We have to find out what kind of file this is.  We handle ELF
+     files and archives.  To find out what we have we must read the
+     header.  The identification header for an ELF file is EI_NIDENT
+     bytes in size, but we read the whole ELF header since we will
+     need it anyway later.  For archives the header in SARMAG bytes
+     long.  Read the maximum of these numbers.
+
+     XXX We have to change this for the extended `ar' format some day.
+
+     Use a union to ensure alignment.  We might later access the
+     memory as a ElfXX_Ehdr.  */
+  union
+  {
+    Elf64_Ehdr ehdr;
+    unsigned char header[MAX (sizeof (Elf64_Ehdr), SARMAG)];
+  } mem;
+
+  /* Read the head of the file.  */
+  ssize_t nread = pread_retry (fildes, mem.header,
+			       MIN (MAX (sizeof (Elf64_Ehdr), SARMAG),
+				    maxsize),
+			       offset);
+  if (unlikely (nread == -1))
+    {
+      /* We cannot even read the head of the file.  Maybe FILDES is associated
+	 with an unseekable device.  This is nothing we can handle.  */
+      __libelf_seterrno (ELF_E_INVALID_FILE);
+      return NULL;
+    }
+
+  /* See what kind of object we have here.  */
+  Elf_Kind kind = determine_kind (mem.header, nread);
+
+  switch (kind)
+    {
+    case ELF_K_AR:
+      return file_read_ar (fildes, NULL, offset, maxsize, cmd, parent);
+
+    case ELF_K_ELF:
+      /* Make sure at least the ELF header is contained in the file.  */
+      if ((size_t) nread >= (mem.header[EI_CLASS] == ELFCLASS32
+			     ? sizeof (Elf32_Ehdr) : sizeof (Elf64_Ehdr)))
+	return file_read_elf (fildes, NULL, mem.header, offset, maxsize, cmd,
+			      parent);
+      FALLTHROUGH;
+
+    default:
+      break;
+    }
+
+  /* This case is easy.  Since we cannot do anything with this file
+     create a dummy descriptor.  */
+  return allocate_elf (fildes, NULL, offset, maxsize, cmd, parent,
+		       ELF_K_NONE, 0);
+}
+
+
+/* Open a file for reading.  If possible we will try to mmap() the file.  */
+static struct Elf *
+read_file (int fildes, off_t offset, size_t maxsize,
+	   Elf_Cmd cmd, Elf *parent)
+{
+  void *map_address = NULL;
+  int use_mmap = (cmd == ELF_C_READ_MMAP || cmd == ELF_C_RDWR_MMAP
+		  || cmd == ELF_C_WRITE_MMAP
+		  || cmd == ELF_C_READ_MMAP_PRIVATE);
+
+  if (parent == NULL)
+    {
+      if (maxsize == ~((size_t) 0))
+	{
+	  /* We don't know in the moment how large the file is.
+	     Determine it now.  */
+	  struct stat st;
+
+	  if (fstat (fildes, &st) == 0
+	      && (sizeof (size_t) >= sizeof (st.st_size)
+		  || st.st_size <= ~((size_t) 0)))
+	    maxsize = (size_t) st.st_size;
+	}
+    }
+  else
+    {
+      /* The parent is already loaded.  Use it.  */
+      assert (maxsize != ~((size_t) 0));
+    }
+
+  if (use_mmap)
+    {
+      if (parent == NULL)
+	{
+	  /* We try to map the file ourself.  */
+	  map_address = mmap (NULL, maxsize, (cmd == ELF_C_READ_MMAP
+					      ? PROT_READ
+					      : PROT_READ|PROT_WRITE),
+			      cmd == ELF_C_READ_MMAP_PRIVATE
+			      || cmd == ELF_C_READ_MMAP
+			      ? MAP_PRIVATE : MAP_SHARED,
+			      fildes, offset);
+
+	  if (map_address == MAP_FAILED)
+	    map_address = NULL;
+	}
+      else
+	{
+	  map_address = parent->map_address;
+	}
+    }
+
+  /* If we have the file in memory optimize the access.  */
+  if (map_address != NULL)
+    {
+      assert (map_address != MAP_FAILED);
+
+      struct Elf *result = __libelf_read_mmaped_file (fildes, map_address,
+						      offset, maxsize, cmd,
+						      parent);
+
+      /* If something went wrong during the initialization unmap the
+	 memory if we mmaped here.  */
+      if (result == NULL
+	  && (parent == NULL
+	      || parent->map_address != map_address))
+	munmap (map_address, maxsize);
+      else if (parent == NULL)
+	/* Remember that we mmap()ed the memory.  */
+	result->flags |= ELF_F_MMAPPED;
+
+      return result;
+    }
+
+  /* Otherwise we have to do it the hard way.  We read as much as necessary
+     from the file whenever we need information which is not available.  */
+  return read_unmmaped_file (fildes, offset, maxsize, cmd, parent);
+}
+
+
+/* Find the entry with the long names for the content of this archive.  */
+static const char *
+read_long_names (Elf *elf)
+{
+  off_t offset = SARMAG;	/* This is the first entry.  */
+  struct ar_hdr hdrm;
+  struct ar_hdr *hdr;
+  char *newp;
+  size_t len;
+
+  while (1)
+    {
+      if (elf->map_address != NULL)
+	{
+	  if ((size_t) offset > elf->maximum_size
+	      || elf->maximum_size - offset < sizeof (struct ar_hdr))
+	    return NULL;
+
+	  /* The data is mapped.  */
+	  hdr = (struct ar_hdr *) (elf->map_address + offset);
+	}
+      else
+	{
+	  /* Read the header from the file.  */
+	  if (unlikely (pread_retry (elf->fildes, &hdrm, sizeof (hdrm),
+				     elf->start_offset + offset)
+			!= sizeof (hdrm)))
+	    return NULL;
+
+	  hdr = &hdrm;
+	}
+
+      len = atol (hdr->ar_size);
+
+      if (memcmp (hdr->ar_name, "//              ", 16) == 0)
+	break;
+
+      offset += sizeof (struct ar_hdr) + ((len + 1) & ~1l);
+    }
+
+  /* Due to the stupid format of the long name table entry (which are not
+     NUL terminted) we have to provide an appropriate representation anyhow.
+     Therefore we always make a copy which has the appropriate form.  */
+  newp = (char *) malloc (len);
+  if (newp != NULL)
+    {
+      char *runp;
+
+      if (elf->map_address != NULL)
+	{
+	  if (len > elf->maximum_size - offset - sizeof (struct ar_hdr))
+	    goto too_much;
+	  /* Simply copy it over.  */
+	  elf->state.ar.long_names = (char *) memcpy (newp,
+						      elf->map_address + offset
+						      + sizeof (struct ar_hdr),
+						      len);
+	}
+      else
+	{
+	  if (unlikely ((size_t) pread_retry (elf->fildes, newp, len,
+					      elf->start_offset + offset
+					      + sizeof (struct ar_hdr))
+			!= len))
+	    {
+	    too_much:
+	      /* We were not able to read all data.  */
+	      free (newp);
+	      elf->state.ar.long_names = NULL;
+	      return NULL;
+	    }
+	  elf->state.ar.long_names = newp;
+	}
+
+      elf->state.ar.long_names_len = len;
+
+      /* Now NUL-terminate the strings.  */
+      runp = newp;
+      while (1)
+        {
+	  char *startp = runp;
+	  runp = (char *) memchr (runp, '/', newp + len - runp);
+	  if (runp == NULL)
+	    {
+	      /* This was the last entry.  Clear any left overs.  */
+	      memset (startp, '\0', newp + len - startp);
+	      break;
+	    }
+
+	  /* NUL-terminate the string.  */
+	  *runp++ = '\0';
+
+	  /* A sanity check.  Somebody might have generated invalid
+	     archive.  */
+	  if (runp >= newp + len)
+	    break;
+	}
+    }
+
+  return newp;
+}
+
+
+/* Read the next archive header.  */
+int
+internal_function
+__libelf_next_arhdr_wrlock (Elf *elf)
+{
+  struct ar_hdr *ar_hdr;
+  Elf_Arhdr *elf_ar_hdr;
+
+  if (elf->map_address != NULL)
+    {
+      /* See whether this entry is in the file.  */
+      if (unlikely ((size_t) elf->state.ar.offset
+		    > elf->start_offset + elf->maximum_size
+		    || (elf->start_offset + elf->maximum_size
+			- elf->state.ar.offset) < sizeof (struct ar_hdr)))
+	{
+	  /* This record is not anymore in the file.  */
+	  __libelf_seterrno (ELF_E_RANGE);
+	  return -1;
+	}
+      ar_hdr = (struct ar_hdr *) (elf->map_address + elf->state.ar.offset);
+    }
+  else
+    {
+      ar_hdr = &elf->state.ar.ar_hdr;
+
+      if (unlikely (pread_retry (elf->fildes, ar_hdr, sizeof (struct ar_hdr),
+				 elf->state.ar.offset)
+		    != sizeof (struct ar_hdr)))
+	{
+	  /* Something went wrong while reading the file.  */
+	  __libelf_seterrno (ELF_E_RANGE);
+	  return -1;
+	}
+    }
+
+  /* One little consistency check.  */
+  if (unlikely (memcmp (ar_hdr->ar_fmag, ARFMAG, 2) != 0))
+    {
+      /* This is no valid archive.  */
+      __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
+      return -1;
+    }
+
+  /* Copy the raw name over to a NUL terminated buffer.  */
+  *((char *) mempcpy (elf->state.ar.raw_name, ar_hdr->ar_name, 16)) = '\0';
+
+  elf_ar_hdr = &elf->state.ar.elf_ar_hdr;
+
+  /* Now convert the `struct ar_hdr' into `Elf_Arhdr'.
+     Determine whether this is a special entry.  */
+  if (ar_hdr->ar_name[0] == '/')
+    {
+      if (ar_hdr->ar_name[1] == ' '
+	  && memcmp (ar_hdr->ar_name, "/               ", 16) == 0)
+	/* This is the index.  */
+	elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/", 2);
+      else if (ar_hdr->ar_name[1] == 'S'
+	       && memcmp (ar_hdr->ar_name, "/SYM64/         ", 16) == 0)
+	/* 64-bit index.  */
+	elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "/SYM64/", 8);
+      else if (ar_hdr->ar_name[1] == '/'
+	       && memcmp (ar_hdr->ar_name, "//              ", 16) == 0)
+	/* This is the array with the long names.  */
+	elf_ar_hdr->ar_name = memcpy (elf->state.ar.ar_name, "//", 3);
+      else if (likely  (isdigit (ar_hdr->ar_name[1])))
+	{
+	  size_t offset;
+
+	  /* This is a long name.  First we have to read the long name
+	     table, if this hasn't happened already.  */
+	  if (unlikely (elf->state.ar.long_names == NULL
+			&& read_long_names (elf) == NULL))
+	    {
+	      /* No long name table although it is reference.  The archive is
+		 broken.  */
+	      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
+	      return -1;
+	    }
+
+	  offset = atol (ar_hdr->ar_name + 1);
+	  if (unlikely (offset >= elf->state.ar.long_names_len))
+	    {
+	      /* The index in the long name table is larger than the table.  */
+	      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
+	      return -1;
+	    }
+	  elf_ar_hdr->ar_name = elf->state.ar.long_names + offset;
+	}
+      else
+	{
+	  /* This is none of the known special entries.  */
+	  __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
+	  return -1;
+	}
+    }
+  else
+    {
+      char *endp;
+
+      /* It is a normal entry.  Copy over the name.  */
+      endp = (char *) memccpy (elf->state.ar.ar_name, ar_hdr->ar_name,
+			       '/', 16);
+      if (endp != NULL)
+	endp[-1] = '\0';
+      else
+	{
+	  /* In the old BSD style of archive, there is no / terminator.
+	     Instead, there is space padding at the end of the name.  */
+	  size_t i = 15;
+	  do
+	    elf->state.ar.ar_name[i] = '\0';
+	  while (i > 0 && elf->state.ar.ar_name[--i] == ' ');
+	}
+
+      elf_ar_hdr->ar_name = elf->state.ar.ar_name;
+    }
+
+  if (unlikely (ar_hdr->ar_size[0] == ' '))
+    /* Something is really wrong.  We cannot live without a size for
+       the member since it will not be possible to find the next
+       archive member.  */
+    {
+      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
+      return -1;
+    }
+
+  /* Since there are no specialized functions to convert ASCII to
+     time_t, uid_t, gid_t, mode_t, and off_t we use either atol or
+     atoll depending on the size of the types.  We are also prepared
+     for the case where the whole field in the `struct ar_hdr' is
+     filled in which case we cannot simply use atol/l but instead have
+     to create a temporary copy.  */
+
+#define INT_FIELD(FIELD)						      \
+  do									      \
+    {									      \
+      char buf[sizeof (ar_hdr->FIELD) + 1];				      \
+      const char *string = ar_hdr->FIELD;				      \
+      if (ar_hdr->FIELD[sizeof (ar_hdr->FIELD) - 1] != ' ')		      \
+	{								      \
+	  *((char *) mempcpy (buf, ar_hdr->FIELD, sizeof (ar_hdr->FIELD)))  \
+	    = '\0';							      \
+	  string = buf;							      \
+	}								      \
+      if (sizeof (elf_ar_hdr->FIELD) <= sizeof (long int))		      \
+	elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atol (string);     \
+      else								      \
+	elf_ar_hdr->FIELD = (__typeof (elf_ar_hdr->FIELD)) atoll (string);    \
+    }									      \
+  while (0)
+
+  INT_FIELD (ar_date);
+  INT_FIELD (ar_uid);
+  INT_FIELD (ar_gid);
+  INT_FIELD (ar_mode);
+  INT_FIELD (ar_size);
+
+  if (elf_ar_hdr->ar_size < 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_ARCHIVE);
+      return -1;
+    }
+
+  /* Truncated file?  */
+  size_t maxsize;
+  maxsize = (elf->start_offset + elf->maximum_size
+	     - elf->state.ar.offset - sizeof (struct ar_hdr));
+  if ((size_t) elf_ar_hdr->ar_size > maxsize)
+    elf_ar_hdr->ar_size = maxsize;
+
+  return 0;
+}
+
+
+/* We were asked to return a clone of an existing descriptor.  This
+   function must be called with the lock on the parent descriptor
+   being held. */
+static Elf *
+dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
+{
+  struct Elf *result;
+
+  if (fildes == -1)
+    /* Allow the user to pass -1 as the file descriptor for the new file.  */
+    fildes = ref->fildes;
+  /* The file descriptor better should be the same.  If it was disconnected
+     already (using `elf_cntl') we do not test it.  */
+  else if (unlikely (ref->fildes != -1 && fildes != ref->fildes))
+    {
+      __libelf_seterrno (ELF_E_FD_MISMATCH);
+      return NULL;
+    }
+
+  /* The mode must allow reading.  I.e., a descriptor creating with a
+     command different then ELF_C_READ, ELF_C_WRITE and ELF_C_RDWR is
+     not allowed.  */
+  if (unlikely (ref->cmd != ELF_C_READ && ref->cmd != ELF_C_READ_MMAP
+		&& ref->cmd != ELF_C_WRITE && ref->cmd != ELF_C_WRITE_MMAP
+		&& ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
+		&& ref->cmd != ELF_C_READ_MMAP_PRIVATE))
+    {
+      __libelf_seterrno (ELF_E_INVALID_OP);
+      return NULL;
+    }
+
+  /* Now it is time to distinguish between reading normal files and
+     archives.  Normal files can easily be handled be incrementing the
+     reference counter and return the same descriptor.  */
+  if (ref->kind != ELF_K_AR)
+    {
+      ++ref->ref_count;
+      return ref;
+    }
+
+  /* This is an archive.  We must create a descriptor for the archive
+     member the internal pointer of the archive file desriptor is
+     pointing to.  First read the header of the next member if this
+     has not happened already.  */
+  if (ref->state.ar.elf_ar_hdr.ar_name == NULL
+      && __libelf_next_arhdr_wrlock (ref) != 0)
+    /* Something went wrong.  Maybe there is no member left.  */
+    return NULL;
+
+  /* We have all the information we need about the next archive member.
+     Now create a descriptor for it.  */
+  result = read_file (fildes, ref->state.ar.offset + sizeof (struct ar_hdr),
+		      ref->state.ar.elf_ar_hdr.ar_size, cmd, ref);
+
+  /* Enlist this new descriptor in the list of children.  */
+  if (result != NULL)
+    {
+      result->next = ref->state.ar.children;
+      ref->state.ar.children = result;
+    }
+
+  return result;
+}
+
+
+/* Return desriptor for empty file ready for writing.  */
+static struct Elf *
+write_file (int fd, Elf_Cmd cmd)
+{
+  /* We simply create an empty `Elf' structure.  */
+#define NSCNSALLOC	10
+  Elf *result = allocate_elf (fd, NULL, 0, 0, cmd, NULL, ELF_K_ELF,
+			      NSCNSALLOC * sizeof (Elf_Scn));
+
+  if (result != NULL)
+    {
+      /* We have to write to the file in any case.  */
+      result->flags = ELF_F_DIRTY;
+
+      /* Some more or less arbitrary value.  */
+      result->state.elf.scnincr = NSCNSALLOC;
+
+      /* We have allocated room for some sections.  */
+      assert (offsetof (struct Elf, state.elf32.scns)
+	      == offsetof (struct Elf, state.elf64.scns));
+      result->state.elf.scns_last = &result->state.elf32.scns;
+      result->state.elf32.scns.max = NSCNSALLOC;
+    }
+
+  return result;
+}
+
+/* Lock if necessary before dup an archive.  */
+static inline Elf *
+lock_dup_elf (int fildes, Elf_Cmd cmd, Elf *ref)
+{
+  /* We need wrlock to dup an archive.  */
+  if (ref->kind == ELF_K_AR)
+    {
+      rwlock_unlock (ref->lock);
+      rwlock_wrlock (ref->lock);
+    }
+    /* Duplicate the descriptor.  */
+  return dup_elf (fildes, cmd, ref);
+}
+
+/* Return a descriptor for the file belonging to FILDES.  */
+Elf *
+elf_begin (int fildes, Elf_Cmd cmd, Elf *ref)
+{
+  Elf *retval;
+
+  if (unlikely (! __libelf_version_initialized))
+    {
+      /* Version wasn't set so far.  */
+      __libelf_seterrno (ELF_E_NO_VERSION);
+      return NULL;
+    }
+
+  if (ref != NULL)
+    /* Make sure the descriptor is not suddenly going away.  */
+    rwlock_rdlock (ref->lock);
+  else if (unlikely (fcntl (fildes, F_GETFD) == -1 && errno == EBADF))
+    {
+      /* We cannot do anything productive without a file descriptor.  */
+      __libelf_seterrno (ELF_E_INVALID_FILE);
+      return NULL;
+    }
+
+  switch (cmd)
+    {
+    case ELF_C_NULL:
+      /* We simply return a NULL pointer.  */
+      retval = NULL;
+      break;
+
+    case ELF_C_READ_MMAP_PRIVATE:
+      /* If we have a reference it must also be opened this way.  */
+      if (unlikely (ref != NULL && ref->cmd != ELF_C_READ_MMAP_PRIVATE))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_CMD);
+	  retval = NULL;
+	  break;
+	}
+      FALLTHROUGH;
+
+    case ELF_C_READ:
+    case ELF_C_READ_MMAP:
+      if (ref != NULL)
+	retval = lock_dup_elf (fildes, cmd, ref);
+      else
+	/* Create descriptor for existing file.  */
+	retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
+      break;
+
+    case ELF_C_RDWR:
+    case ELF_C_RDWR_MMAP:
+      /* If we have a REF object it must also be opened using this
+	 command.  */
+      if (ref != NULL)
+	{
+	  if (unlikely (ref->cmd != ELF_C_RDWR && ref->cmd != ELF_C_RDWR_MMAP
+			&& ref->cmd != ELF_C_WRITE
+			&& ref->cmd != ELF_C_WRITE_MMAP))
+	    {
+	      /* This is not ok.  REF must also be opened for writing.  */
+	      __libelf_seterrno (ELF_E_INVALID_CMD);
+	      retval = NULL;
+	    }
+	  else
+	    retval = lock_dup_elf (fildes, cmd, ref);
+	}
+      else
+	/* Create descriptor for existing file.  */
+	retval = read_file (fildes, 0, ~((size_t) 0), cmd, NULL);
+      break;
+
+    case ELF_C_WRITE:
+    case ELF_C_WRITE_MMAP:
+      /* We ignore REF and prepare a descriptor to write a new file.  */
+      retval = write_file (fildes, cmd);
+      break;
+
+    default:
+      __libelf_seterrno (ELF_E_INVALID_CMD);
+      retval = NULL;
+      break;
+    }
+
+  /* Release the lock.  */
+  if (ref != NULL)
+    rwlock_unlock (ref->lock);
+
+  return retval;
+}
+INTDEF(elf_begin)
diff --git a/third_party/elfutils/libelf/elf_clone.c b/third_party/elfutils/libelf/elf_clone.c
new file mode 100644
index 0000000..e6fe472
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_clone.c
@@ -0,0 +1,81 @@
+/* Create clone of a given descriptor.
+   Copyright (C) 2003, 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include "libelfP.h"
+#include "common.h"
+
+
+Elf *
+elf_clone (Elf *elf, Elf_Cmd cmd)
+{
+  Elf *retval = NULL;
+
+  if (elf == NULL)
+    /* Some earlier mistake.  */
+    return NULL;
+
+  /* Make sure the descriptor is not suddenly going away.  */
+  rwlock_rdlock (elf->lock);
+
+  if (cmd != ELF_C_EMPTY)
+    // XXX TODO handle ELF_C_READ/WRITE etc
+    goto out;
+
+  retval = allocate_elf (elf->fildes, elf->map_address, elf->start_offset,
+			 elf->maximum_size, elf->cmd, elf->parent, elf->kind,
+			 elf->state.elf32.scns.max * sizeof (Elf_Scn));
+  if (retval != NULL)
+    {
+      /* We have to write to the file in any case.  */
+      retval->flags = ELF_F_DIRTY;
+
+      /* Some more or less arbitrary value.  */
+      retval->state.elf.scnincr = 10;
+
+      /* We have allocated room for some sections.  */
+      assert (offsetof (struct Elf, state.elf32.scns)
+	      == offsetof (struct Elf, state.elf64.scns));
+      retval->state.elf.scns_last = &retval->state.elf32.scns;
+      retval->state.elf32.scns.max = elf->state.elf32.scns.max;
+
+      retval->class = elf->class;
+    }
+
+  /* Release the lock.  */
+ out:
+  rwlock_unlock (elf->lock);
+
+  return retval;
+}
diff --git a/third_party/elfutils/libelf/elf_cntl.c b/third_party/elfutils/libelf/elf_cntl.c
new file mode 100644
index 0000000..fd68178
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_cntl.c
@@ -0,0 +1,81 @@
+/* Control an ELF file desrciptor.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <unistd.h>
+
+#include "libelfP.h"
+
+
+int
+elf_cntl (Elf *elf, Elf_Cmd cmd)
+{
+  int result = 0;
+
+  if (elf == NULL)
+    return -1;
+
+  if (elf->fildes == -1)
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  switch (cmd)
+    {
+    case ELF_C_FDREAD:
+      /* If not all of the file is in the memory read it now.  */
+      if (elf->map_address == NULL && __libelf_readall (elf) == NULL)
+	{
+	  /* We were not able to read everything.  */
+	  result = -1;
+	  break;
+	}
+      FALLTHROUGH;
+
+    case ELF_C_FDDONE:
+      /* Mark the file descriptor as not usable.  */
+      elf->fildes = -1;
+      break;
+
+    default:
+      __libelf_seterrno (ELF_E_INVALID_CMD);
+      result = -1;
+      break;
+    }
+
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_compress.c b/third_party/elfutils/libelf/elf_compress.c
new file mode 100644
index 0000000..711be59
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_compress.c
@@ -0,0 +1,525 @@
+/* Compress or decompress a section.
+   Copyright (C) 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <zlib.h>
+
+/* Cleanup and return result.  Don't leak memory.  */
+static void *
+do_deflate_cleanup (void *result, z_stream *z, void *out_buf,
+                    int ei_data, Elf_Data *cdatap)
+{
+  deflateEnd (z);
+  free (out_buf);
+  if (ei_data != MY_ELFDATA)
+    free (cdatap->d_buf);
+  return result;
+}
+
+#define deflate_cleanup(result) \
+    do_deflate_cleanup(result, &z, out_buf, ei_data, &cdata)
+
+/* Given a section, uses the (in-memory) Elf_Data to extract the
+   original data size (including the given header size) and data
+   alignment.  Returns a buffer that has at least hsize bytes (for the
+   caller to fill in with a header) plus zlib compressed date.  Also
+   returns the new buffer size in new_size (hsize + compressed data
+   size).  Returns (void *) -1 when FORCE is false and the compressed
+   data would be bigger than the original data.  */
+void *
+internal_function
+__libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
+		   size_t *orig_size, size_t *orig_addralign,
+		   size_t *new_size, bool force)
+{
+  /* The compressed data is the on-disk data.  We simplify the
+     implementation a bit by asking for the (converted) in-memory
+     data (which might be all there is if the user created it with
+     elf_newdata) and then convert back to raw if needed before
+     compressing.  Should be made a bit more clever to directly
+     use raw if that is directly available.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return NULL;
+
+  /* When not forced and we immediately know we would use more data by
+     compressing, because of the header plus zlib overhead (five bytes
+     per 16 KB block, plus a one-time overhead of six bytes for the
+     entire stream), don't do anything.  */
+  Elf_Data *next_data = elf_getdata (scn, data);
+  if (next_data == NULL && !force
+      && data->d_size <= hsize + 5 + 6)
+    return (void *) -1;
+
+  *orig_addralign = data->d_align;
+  *orig_size = data->d_size;
+
+  /* Guess an output block size. 1/8th of the original Elf_Data plus
+     hsize.  Make the first chunk twice that size (25%), then increase
+     by a block (12.5%) when necessary.  */
+  size_t block = (data->d_size / 8) + hsize;
+  size_t out_size = 2 * block;
+  void *out_buf = malloc (out_size);
+  if (out_buf == NULL)
+    {
+      __libelf_seterrno (ELF_E_NOMEM);
+      return NULL;
+    }
+
+  /* Caller gets to fill in the header at the start.  Just skip it here.  */
+  size_t used = hsize;
+
+  z_stream z;
+  z.zalloc = Z_NULL;
+  z.zfree = Z_NULL;
+  z.opaque = Z_NULL;
+  int zrc = deflateInit (&z, Z_BEST_COMPRESSION);
+  if (zrc != Z_OK)
+    {
+      free (out_buf);
+      __libelf_seterrno (ELF_E_COMPRESS_ERROR);
+      return NULL;
+    }
+
+  Elf_Data cdata;
+  cdata.d_buf = NULL;
+
+  /* Loop over data buffers.  */
+  int flush = Z_NO_FLUSH;
+  do
+    {
+      /* Convert to raw if different endianess.  */
+      cdata = *data;
+      if (ei_data != MY_ELFDATA)
+	{
+	  /* Don't do this conversion in place, we might want to keep
+	     the original data around, caller decides.  */
+	  cdata.d_buf = malloc (data->d_size);
+	  if (cdata.d_buf == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return deflate_cleanup (NULL);
+	    }
+	  if (gelf_xlatetof (scn->elf, &cdata, data, ei_data) == NULL)
+	    return deflate_cleanup (NULL);
+	}
+
+      z.avail_in = cdata.d_size;
+      z.next_in = cdata.d_buf;
+
+      /* Get next buffer to see if this is the last one.  */
+      data = next_data;
+      if (data != NULL)
+	{
+	  *orig_addralign = MAX (*orig_addralign, data->d_align);
+	  *orig_size += data->d_size;
+	  next_data = elf_getdata (scn, data);
+	}
+      else
+	flush = Z_FINISH;
+
+      /* Flush one data buffer.  */
+      do
+	{
+	  z.avail_out = out_size - used;
+	  z.next_out = out_buf + used;
+	  zrc = deflate (&z, flush);
+	  if (zrc == Z_STREAM_ERROR)
+	    {
+	      __libelf_seterrno (ELF_E_COMPRESS_ERROR);
+	      return deflate_cleanup (NULL);
+	    }
+	  used += (out_size - used) - z.avail_out;
+
+	  /* Bail out if we are sure the user doesn't want the
+	     compression forced and we are using more compressed data
+	     than original data.  */
+	  if (!force && flush == Z_FINISH && used >= *orig_size)
+	    return deflate_cleanup ((void *) -1);
+
+	  if (z.avail_out == 0)
+	    {
+	      void *bigger = realloc (out_buf, out_size + block);
+	      if (bigger == NULL)
+		{
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  return deflate_cleanup (NULL);
+		}
+	      out_buf = bigger;
+	      out_size += block;
+	    }
+	}
+      while (z.avail_out == 0); /* Need more output buffer.  */
+
+      if (ei_data != MY_ELFDATA)
+	{
+	  free (cdata.d_buf);
+	  cdata.d_buf = NULL;
+	}
+    }
+  while (flush != Z_FINISH); /* More data blocks.  */
+
+  zrc = deflateEnd (&z);
+  if (zrc != Z_OK)
+    {
+      __libelf_seterrno (ELF_E_COMPRESS_ERROR);
+      return deflate_cleanup (NULL);
+    }
+
+  *new_size = used;
+  return out_buf;
+}
+
+void *
+internal_function
+__libelf_decompress (void *buf_in, size_t size_in, size_t size_out)
+{
+  /* Catch highly unlikely compression ratios so we don't allocate
+     some giant amount of memory for nothing. The max compression
+     factor 1032:1 comes from http://www.zlib.net/zlib_tech.html  */
+  if (unlikely (size_out / 1032 > size_in))
+    {
+      __libelf_seterrno (ELF_E_INVALID_DATA);
+      return NULL;
+    }
+
+  void *buf_out = malloc (size_out);
+  if (unlikely (buf_out == NULL))
+    {
+      __libelf_seterrno (ELF_E_NOMEM);
+      return NULL;
+    }
+
+  z_stream z =
+    {
+      .next_in = buf_in,
+      .avail_in = size_in,
+      .next_out = buf_out,
+      .avail_out = size_out
+    };
+  int zrc = inflateInit (&z);
+  while (z.avail_in > 0 && likely (zrc == Z_OK))
+    {
+      z.next_out = buf_out + (size_out - z.avail_out);
+      zrc = inflate (&z, Z_FINISH);
+      if (unlikely (zrc != Z_STREAM_END))
+	{
+	  zrc = Z_DATA_ERROR;
+	  break;
+	}
+      zrc = inflateReset (&z);
+    }
+  if (likely (zrc == Z_OK))
+    zrc = inflateEnd (&z);
+
+  if (unlikely (zrc != Z_OK) || unlikely (z.avail_out != 0))
+    {
+      free (buf_out);
+      __libelf_seterrno (ELF_E_DECOMPRESS_ERROR);
+      return NULL;
+    }
+
+  return buf_out;
+}
+
+void *
+internal_function
+__libelf_decompress_elf (Elf_Scn *scn, size_t *size_out, size_t *addralign)
+{
+  GElf_Chdr chdr;
+  if (gelf_getchdr (scn, &chdr) == NULL)
+    return NULL;
+
+  if (chdr.ch_type != ELFCOMPRESS_ZLIB)
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE);
+      return NULL;
+    }
+
+  if (! powerof2 (chdr.ch_addralign))
+    {
+      __libelf_seterrno (ELF_E_INVALID_ALIGN);
+      return NULL;
+    }
+
+  /* Take the in-memory representation, so we can even handle a
+     section that has just been constructed (maybe it was copied
+     over from some other ELF file first with elf_newdata).  This
+     is slightly inefficient when the raw data needs to be
+     converted since then we'll be converting the whole buffer and
+     not just Chdr.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return NULL;
+
+  int elfclass = scn->elf->class;
+  size_t hsize = (elfclass == ELFCLASS32
+		  ? sizeof (Elf32_Chdr) : sizeof (Elf64_Chdr));
+  size_t size_in = data->d_size - hsize;
+  void *buf_in = data->d_buf + hsize;
+  void *buf_out = __libelf_decompress (buf_in, size_in, chdr.ch_size);
+  *size_out = chdr.ch_size;
+  *addralign = chdr.ch_addralign;
+  return buf_out;
+}
+
+/* Assumes buf is a malloced buffer.  */
+void
+internal_function
+__libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size, size_t align,
+			Elf_Type type)
+{
+  /* This is the new raw data, replace and possibly free old data.  */
+  scn->rawdata.d.d_off = 0;
+  scn->rawdata.d.d_version = __libelf_version;
+  scn->rawdata.d.d_buf = buf;
+  scn->rawdata.d.d_size = size;
+  scn->rawdata.d.d_align = align;
+  scn->rawdata.d.d_type = type;
+
+  /* Existing existing data is no longer valid.  */
+  scn->data_list_rear = NULL;
+  if (scn->data_base != scn->rawdata_base)
+    free (scn->data_base);
+  scn->data_base = NULL;
+  if (scn->elf->map_address == NULL
+      || scn->rawdata_base == scn->zdata_base
+      || (scn->flags & ELF_F_MALLOCED) != 0)
+    free (scn->rawdata_base);
+
+  scn->rawdata_base = buf;
+  scn->flags |= ELF_F_MALLOCED;
+}
+
+int
+elf_compress (Elf_Scn *scn, int type, unsigned int flags)
+{
+  if (scn == NULL)
+    return -1;
+
+  if ((flags & ~ELF_CHF_FORCE) != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return -1;
+    }
+
+  bool force = (flags & ELF_CHF_FORCE) != 0;
+
+  Elf *elf = scn->elf;
+  GElf_Ehdr ehdr;
+  if (gelf_getehdr (elf, &ehdr) == NULL)
+    return -1;
+
+  int elfclass = elf->class;
+  int elfdata = ehdr.e_ident[EI_DATA];
+
+  Elf64_Xword sh_flags;
+  Elf64_Word sh_type;
+  Elf64_Xword sh_addralign;
+  if (elfclass == ELFCLASS32)
+    {
+      Elf32_Shdr *shdr = elf32_getshdr (scn);
+      if (shdr == NULL)
+	return -1;
+
+      sh_flags = shdr->sh_flags;
+      sh_type = shdr->sh_type;
+      sh_addralign = shdr->sh_addralign;
+    }
+  else
+    {
+      Elf64_Shdr *shdr = elf64_getshdr (scn);
+      if (shdr == NULL)
+	return -1;
+
+      sh_flags = shdr->sh_flags;
+      sh_type = shdr->sh_type;
+      sh_addralign = shdr->sh_addralign;
+    }
+
+  if ((sh_flags & SHF_ALLOC) != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS);
+      return -1;
+    }
+
+  if (sh_type == SHT_NULL || sh_type == SHT_NOBITS)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE);
+      return -1;
+    }
+
+  int compressed = (sh_flags & SHF_COMPRESSED);
+  if (type == ELFCOMPRESS_ZLIB)
+    {
+      /* Compress/Deflate.  */
+      if (compressed == 1)
+	{
+	  __libelf_seterrno (ELF_E_ALREADY_COMPRESSED);
+	  return -1;
+	}
+
+      size_t hsize = (elfclass == ELFCLASS32
+		      ? sizeof (Elf32_Chdr) : sizeof (Elf64_Chdr));
+      size_t orig_size, orig_addralign, new_size;
+      void *out_buf = __libelf_compress (scn, hsize, elfdata,
+					 &orig_size, &orig_addralign,
+					 &new_size, force);
+
+      /* Compression would make section larger, don't change anything.  */
+      if (out_buf == (void *) -1)
+	return 0;
+
+      /* Compression failed, return error.  */
+      if (out_buf == NULL)
+	return -1;
+
+      /* Put the header in front of the data.  */
+      if (elfclass == ELFCLASS32)
+	{
+	  Elf32_Chdr chdr;
+	  chdr.ch_type = ELFCOMPRESS_ZLIB;
+	  chdr.ch_size = orig_size;
+	  chdr.ch_addralign = orig_addralign;
+	  if (elfdata != MY_ELFDATA)
+	    {
+	      CONVERT (chdr.ch_type);
+	      CONVERT (chdr.ch_size);
+	      CONVERT (chdr.ch_addralign);
+	    }
+	  memcpy (out_buf, &chdr, sizeof (Elf32_Chdr));
+	}
+      else
+	{
+	  Elf64_Chdr chdr;
+	  chdr.ch_type = ELFCOMPRESS_ZLIB;
+	  chdr.ch_reserved = 0;
+	  chdr.ch_size = orig_size;
+	  chdr.ch_addralign = sh_addralign;
+	  if (elfdata != MY_ELFDATA)
+	    {
+	      CONVERT (chdr.ch_type);
+	      CONVERT (chdr.ch_reserved);
+	      CONVERT (chdr.ch_size);
+	      CONVERT (chdr.ch_addralign);
+	    }
+	  memcpy (out_buf, &chdr, sizeof (Elf64_Chdr));
+	}
+
+      /* Note we keep the sh_entsize as is, we assume it is setup
+	 correctly and ignored when SHF_COMPRESSED is set.  */
+      if (elfclass == ELFCLASS32)
+	{
+	  Elf32_Shdr *shdr = elf32_getshdr (scn);
+	  shdr->sh_size = new_size;
+	  shdr->sh_addralign = 1;
+	  shdr->sh_flags |= SHF_COMPRESSED;
+	}
+      else
+	{
+	  Elf64_Shdr *shdr = elf64_getshdr (scn);
+	  shdr->sh_size = new_size;
+	  shdr->sh_addralign = 1;
+	  shdr->sh_flags |= SHF_COMPRESSED;
+	}
+
+      __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_CHDR);
+
+      /* The section is now compressed, we could keep the uncompressed
+	 data around, but since that might have been multiple Elf_Data
+	 buffers let the user uncompress it explicitly again if they
+	 want it to simplify bookkeeping.  */
+      scn->zdata_base = NULL;
+
+      return 1;
+    }
+  else if (type == 0)
+    {
+      /* Decompress/Inflate.  */
+      if (compressed == 0)
+	{
+	  __libelf_seterrno (ELF_E_NOT_COMPRESSED);
+	  return -1;
+	}
+
+      /* If the data is already decompressed (by elf_strptr), then we
+	 only need to setup the rawdata and section header. XXX what
+	 about elf_newdata?  */
+      if (scn->zdata_base == NULL)
+	{
+	  size_t size_out, addralign;
+	  void *buf_out = __libelf_decompress_elf (scn, &size_out, &addralign);
+	  if (buf_out == NULL)
+	    return -1;
+
+	  scn->zdata_base = buf_out;
+	  scn->zdata_size = size_out;
+	  scn->zdata_align = addralign;
+	}
+
+      /* Note we keep the sh_entsize as is, we assume it is setup
+	 correctly and ignored when SHF_COMPRESSED is set.  */
+      if (elfclass == ELFCLASS32)
+	{
+	  Elf32_Shdr *shdr = elf32_getshdr (scn);
+	  shdr->sh_size = scn->zdata_size;
+	  shdr->sh_addralign = scn->zdata_align;
+	  shdr->sh_flags &= ~SHF_COMPRESSED;
+	}
+      else
+	{
+	  Elf64_Shdr *shdr = elf64_getshdr (scn);
+	  shdr->sh_size = scn->zdata_size;
+	  shdr->sh_addralign = scn->zdata_align;
+	  shdr->sh_flags &= ~SHF_COMPRESSED;
+	}
+
+      __libelf_reset_rawdata (scn, scn->zdata_base,
+			      scn->zdata_size, scn->zdata_align,
+			      __libelf_data_type (elf, sh_type));
+
+      return 1;
+    }
+  else
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE);
+      return -1;
+    }
+}
diff --git a/third_party/elfutils/libelf/elf_compress_gnu.c b/third_party/elfutils/libelf/elf_compress_gnu.c
new file mode 100644
index 0000000..c35dc39
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_compress_gnu.c
@@ -0,0 +1,208 @@
+/* Compress or decompress a section.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include "libelfP.h"
+#include "common.h"
+
+int
+elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags)
+{
+  if (scn == NULL)
+    return -1;
+
+  if ((flags & ~ELF_CHF_FORCE) != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return -1;
+    }
+
+  bool force = (flags & ELF_CHF_FORCE) != 0;
+
+  Elf *elf = scn->elf;
+  GElf_Ehdr ehdr;
+  if (gelf_getehdr (elf, &ehdr) == NULL)
+    return -1;
+
+  int elfclass = elf->class;
+  int elfdata = ehdr.e_ident[EI_DATA];
+
+  Elf64_Xword sh_flags;
+  Elf64_Word sh_type;
+  Elf64_Xword sh_addralign;
+  if (elfclass == ELFCLASS32)
+    {
+      Elf32_Shdr *shdr = elf32_getshdr (scn);
+      if (shdr == NULL)
+	return -1;
+
+      sh_flags = shdr->sh_flags;
+      sh_type = shdr->sh_type;
+      sh_addralign = shdr->sh_addralign;
+    }
+  else
+    {
+      Elf64_Shdr *shdr = elf64_getshdr (scn);
+      if (shdr == NULL)
+	return -1;
+
+      sh_flags = shdr->sh_flags;
+      sh_type = shdr->sh_type;
+      sh_addralign = shdr->sh_addralign;
+    }
+
+  if ((sh_flags & SHF_ALLOC) != 0)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_FLAGS);
+      return -1;
+    }
+
+  if (sh_type == SHT_NULL || sh_type == SHT_NOBITS)
+    {
+      __libelf_seterrno (ELF_E_INVALID_SECTION_TYPE);
+      return -1;
+    }
+
+  /* For GNU compression we cannot really know whether the section is
+     already compressed or not.  Just try and see what happens...  */
+  // int compressed = (sh_flags & SHF_COMPRESSED);
+  if (inflate == 1)
+    {
+      size_t hsize = 4 + 8; /* GNU "ZLIB" + 8 byte size.  */
+      size_t orig_size, new_size, orig_addralign;
+      void *out_buf = __libelf_compress (scn, hsize, elfdata,
+					 &orig_size, &orig_addralign,
+					 &new_size, force);
+
+      /* Compression would make section larger, don't change anything.  */
+      if (out_buf == (void *) -1)
+	return 0;
+
+      /* Compression failed, return error.  */
+      if (out_buf == NULL)
+	return -1;
+
+      uint64_t be64_size = htobe64 (orig_size);
+      memmove (out_buf, "ZLIB", 4);
+      memmove (out_buf + 4, &be64_size, sizeof (be64_size));
+
+      /* We don't know anything about sh_entsize, sh_addralign and
+	 sh_flags won't have a SHF_COMPRESSED hint in the GNU format.
+	 Just adjust the sh_size.  */
+      if (elfclass == ELFCLASS32)
+	{
+	  Elf32_Shdr *shdr = elf32_getshdr (scn);
+	  shdr->sh_size = new_size;
+	}
+      else
+	{
+	  Elf64_Shdr *shdr = elf64_getshdr (scn);
+	  shdr->sh_size = new_size;
+	}
+
+      __libelf_reset_rawdata (scn, out_buf, new_size, 1, ELF_T_BYTE);
+
+      /* The section is now compressed, we could keep the uncompressed
+	 data around, but since that might have been multiple Elf_Data
+	 buffers let the user uncompress it explicitly again if they
+	 want it to simplify bookkeeping.  */
+      scn->zdata_base = NULL;
+
+      return 1;
+    }
+  else if (inflate == 0)
+    {
+      /* In theory the user could have constucted a compressed section
+	 by hand.  But we always just take the rawdata directly and
+	 decompress that.  */
+      Elf_Data *data = elf_rawdata (scn, NULL);
+      if (data == NULL)
+	return -1;
+
+      size_t hsize = 4 + 8; /* GNU "ZLIB" + 8 byte size.  */
+      if (data->d_size < hsize || memcmp (data->d_buf, "ZLIB", 4) != 0)
+	{
+          __libelf_seterrno (ELF_E_NOT_COMPRESSED);
+	  return -1;
+	}
+
+      /* There is a 12-byte header of "ZLIB" followed by
+	 an 8-byte big-endian size.  There is only one type and
+	 Alignment isn't preserved separately.  */
+      uint64_t gsize;
+      memcpy (&gsize, data->d_buf + 4, sizeof gsize);
+      gsize = be64toh (gsize);
+
+      /* One more sanity check, size should be bigger than original
+	 data size plus some overhead (4 chars ZLIB + 8 bytes size + 6
+	 bytes zlib stream overhead + 5 bytes overhead max for one 16K
+	 block) and should fit into a size_t.  */
+      if (gsize + 4 + 8 + 6 + 5 < data->d_size || gsize > SIZE_MAX)
+	{
+	  __libelf_seterrno (ELF_E_NOT_COMPRESSED);
+	  return -1;
+	}
+
+      size_t size = gsize;
+      size_t size_in = data->d_size - hsize;
+      void *buf_in = data->d_buf + hsize;
+      void *buf_out = __libelf_decompress (buf_in, size_in, size);
+      if (buf_out == NULL)
+	return -1;
+
+      /* We don't know anything about sh_entsize, sh_addralign and
+	 sh_flags won't have a SHF_COMPRESSED hint in the GNU format.
+	 Just adjust the sh_size.  */
+      if (elfclass == ELFCLASS32)
+	{
+	  Elf32_Shdr *shdr = elf32_getshdr (scn);
+	  shdr->sh_size = size;
+	}
+      else
+	{
+	  Elf64_Shdr *shdr = elf64_getshdr (scn);
+	  shdr->sh_size = size;
+	}
+
+      __libelf_reset_rawdata (scn, buf_out, size, sh_addralign,
+			      __libelf_data_type (elf, sh_type));
+
+      scn->zdata_base = buf_out;
+
+      return 1;
+    }
+  else
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_COMPRESSION_TYPE);
+      return -1;
+    }
+}
diff --git a/third_party/elfutils/libelf/elf_end.c b/third_party/elfutils/libelf/elf_end.c
new file mode 100644
index 0000000..160f0b8
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_end.c
@@ -0,0 +1,239 @@
+/* Free resources associated with Elf descriptor.
+   Copyright (C) 1998,1999,2000,2001,2002,2004,2005,2007,2015,2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include "libelfP.h"
+
+
+int
+elf_end (Elf *elf)
+{
+  Elf *parent;
+
+  if (elf == NULL)
+    /* This is allowed and is a no-op.  */
+    return 0;
+
+  /* Make sure we are alone.  */
+  rwlock_wrlock (elf->lock);
+
+  if (elf->ref_count != 0 && --elf->ref_count != 0)
+    {
+      /* Not yet the last activation.  */
+      int result = elf->ref_count;
+      rwlock_unlock (elf->lock);
+      return result;
+    }
+
+  if (elf->kind == ELF_K_AR)
+    {
+      /* We cannot remove the descriptor now since we still have some
+	 descriptors which depend on it.  But we can free the archive
+	 symbol table since this is only available via the archive ELF
+	 descriptor.  The long name table cannot be freed yet since
+	 the archive headers for the ELF files in the archive point
+	 into this array.  */
+      if (elf->state.ar.ar_sym != (Elf_Arsym *) -1l)
+	free (elf->state.ar.ar_sym);
+      elf->state.ar.ar_sym = NULL;
+
+      if (elf->state.ar.children != NULL)
+	return 0;
+    }
+
+  /* Remove this structure from the children list.  */
+  parent = elf->parent;
+  if (parent != NULL)
+    {
+      /* This is tricky.  Lock must be acquire from the father to
+	 the child but here we already have the child lock.  We
+	 solve this problem by giving free the child lock.  The
+	 state of REF_COUNT==0 is handled all over the library, so
+	 this should be ok.  */
+      rwlock_unlock (elf->lock);
+      rwlock_rdlock (parent->lock);
+      rwlock_wrlock (elf->lock);
+
+      if (parent->state.ar.children == elf)
+	parent->state.ar.children = elf->next;
+      else
+	{
+	  struct Elf *child = parent->state.ar.children;
+
+	  while (child->next != elf)
+	    child = child->next;
+
+	  child->next = elf->next;
+	}
+
+      rwlock_unlock (parent->lock);
+    }
+
+  /* This was the last activation.  Free all resources.  */
+  switch (elf->kind)
+    {
+    case ELF_K_AR:
+      if (elf->state.ar.long_names != NULL)
+	free (elf->state.ar.long_names);
+      break;
+
+    case ELF_K_ELF:
+      {
+	Elf_Data_Chunk *rawchunks
+	  = (elf->class == ELFCLASS32
+	     || (offsetof (struct Elf, state.elf32.rawchunks)
+		 == offsetof (struct Elf, state.elf64.rawchunks))
+	     ? elf->state.elf32.rawchunks
+	     : elf->state.elf64.rawchunks);
+	while (rawchunks != NULL)
+	  {
+	    Elf_Data_Chunk *next = rawchunks->next;
+	    if (rawchunks->dummy_scn.flags & ELF_F_MALLOCED)
+	      free (rawchunks->data.d.d_buf);
+	    free (rawchunks);
+	    rawchunks = next;
+	  }
+
+	Elf_ScnList *list = (elf->class == ELFCLASS32
+			     || (offsetof (struct Elf, state.elf32.scns)
+				 == offsetof (struct Elf, state.elf64.scns))
+			     ? &elf->state.elf32.scns
+			     : &elf->state.elf64.scns);
+
+	do
+	  {
+	    /* Free all separately allocated section headers.  */
+	    size_t cnt = list->max;
+
+	    while (cnt-- > 0)
+	      {
+		/* These pointers can be NULL; it's safe to use
+		   'free' since it will check for this.  */
+		Elf_Scn *scn = &list->data[cnt];
+		Elf_Data_List *runp;
+
+		if ((scn->shdr_flags & ELF_F_MALLOCED) != 0)
+		  /* It doesn't matter which pointer.  */
+		  free (scn->shdr.e32);
+
+		/* Free zdata if uncompressed, but not yet used as
+		   rawdata_base.  If it is already used it will be
+		   freed below.  */
+		if (scn->zdata_base != scn->rawdata_base)
+		  free (scn->zdata_base);
+
+		/* If the file has the same byte order and the
+		   architecture doesn't require overly stringent
+		   alignment the raw data buffer is the same as the
+		   one used for presenting to the caller.  */
+		if (scn->data_base != scn->rawdata_base)
+		  free (scn->data_base);
+
+		/* The section data is allocated if we couldn't mmap
+		   the file.  Or if we had to decompress.  */
+		if (elf->map_address == NULL
+		    || scn->rawdata_base == scn->zdata_base
+		    || (scn->flags & ELF_F_MALLOCED) != 0)
+		  free (scn->rawdata_base);
+
+		/* Free the list of data buffers for the section.
+		   We don't free the buffers themselves since this
+		   is the users job.  */
+		runp = scn->data_list.next;
+		while (runp != NULL)
+		  {
+		    Elf_Data_List *oldp = runp;
+		    runp = runp->next;
+		    if ((oldp->flags & ELF_F_MALLOCED) != 0)
+		      free (oldp);
+		  }
+	      }
+
+	    /* Free the memory for the array.  */
+	    Elf_ScnList *oldp = list;
+	    list = list->next;
+	    assert (list == NULL || oldp->cnt == oldp->max);
+	    if (oldp != (elf->class == ELFCLASS32
+			 || (offsetof (struct Elf, state.elf32.scns)
+			     == offsetof (struct Elf, state.elf64.scns))
+			 ? &elf->state.elf32.scns
+			 : &elf->state.elf64.scns))
+	      free (oldp);
+	  }
+	while (list != NULL);
+      }
+
+      /* Free the section header.  */
+      if (elf->state.elf.shdr_malloced  != 0)
+	free (elf->class == ELFCLASS32
+	      || (offsetof (struct Elf, state.elf32.shdr)
+		  == offsetof (struct Elf, state.elf64.shdr))
+	      ? (void *) elf->state.elf32.shdr
+	      : (void *) elf->state.elf64.shdr);
+
+      /* Free the program header.  */
+      if ((elf->state.elf.phdr_flags & ELF_F_MALLOCED) != 0)
+	free (elf->class == ELFCLASS32
+	      || (offsetof (struct Elf, state.elf32.phdr)
+		  == offsetof (struct Elf, state.elf64.phdr))
+	      ? (void *) elf->state.elf32.phdr
+	      : (void *) elf->state.elf64.phdr);
+      break;
+
+    default:
+      break;
+    }
+
+  if (elf->map_address != NULL && parent == NULL)
+    {
+      /* The file was read or mapped for this descriptor.  */
+      if ((elf->flags & ELF_F_MALLOCED) != 0)
+	free (elf->map_address);
+      else if ((elf->flags & ELF_F_MMAPPED) != 0)
+	munmap (elf->map_address, elf->maximum_size);
+    }
+
+  rwlock_unlock (elf->lock);
+  rwlock_fini (elf->lock);
+
+  /* Finally the descriptor itself.  */
+  free (elf);
+
+  return (parent != NULL && parent->ref_count == 0
+	  ? INTUSE(elf_end) (parent) : 0);
+}
+INTDEF(elf_end)
diff --git a/third_party/elfutils/libelf/elf_error.c b/third_party/elfutils/libelf/elf_error.c
new file mode 100644
index 0000000..5364e68
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_error.c
@@ -0,0 +1,355 @@
+/* Error handling in libelf.
+   Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+/* The error number.  */
+static __thread int global_error;
+
+
+int
+elf_errno (void)
+{
+  int result = global_error;
+  global_error = ELF_E_NOERROR;
+  return result;
+}
+
+
+/* Return the appropriate message for the error.  */
+static const char msgstr[] =
+{
+#define ELF_E_NOERROR_IDX 0
+  N_("no error")
+  "\0"
+#define ELF_E_UNKNOWN_ERROR_IDX (ELF_E_NOERROR_IDX + sizeof "no error")
+  N_("unknown error")
+  "\0"
+#define ELF_E_UNKNOWN_VERSION_IDX \
+  (ELF_E_UNKNOWN_ERROR_IDX + sizeof "unknown error")
+  N_("unknown version")
+  "\0"
+#define ELF_E_UNKNOWN_TYPE_IDX \
+  (ELF_E_UNKNOWN_VERSION_IDX + sizeof "unknown version")
+  N_("unknown type")
+  "\0"
+#define ELF_E_INVALID_HANDLE_IDX \
+  (ELF_E_UNKNOWN_TYPE_IDX + sizeof "unknown type")
+  N_("invalid `Elf' handle")
+  "\0"
+#define ELF_E_SOURCE_SIZE_IDX \
+  (ELF_E_INVALID_HANDLE_IDX + sizeof "invalid `Elf' handle")
+  N_("invalid size of source operand")
+  "\0"
+#define ELF_E_DEST_SIZE_IDX \
+  (ELF_E_SOURCE_SIZE_IDX + sizeof "invalid size of source operand")
+  N_("invalid size of destination operand")
+  "\0"
+#define ELF_E_INVALID_ENCODING_IDX \
+  (ELF_E_DEST_SIZE_IDX + sizeof "invalid size of destination operand")
+  N_("invalid encoding")
+  "\0"
+#define ELF_E_NOMEM_IDX \
+  (ELF_E_INVALID_ENCODING_IDX + sizeof "invalid encoding")
+  N_("out of memory")
+  "\0"
+#define ELF_E_INVALID_FILE_IDX \
+  (ELF_E_NOMEM_IDX + sizeof "out of memory")
+  N_("invalid file descriptor")
+  "\0"
+#define ELF_E_INVALID_ELF_IDX \
+  (ELF_E_INVALID_FILE_IDX + sizeof "invalid file descriptor")
+  N_("invalid ELF file data")
+  "\0"
+#define ELF_E_INVALID_OP_IDX \
+  (ELF_E_INVALID_ELF_IDX + sizeof "invalid ELF file data")
+  N_("invalid operation")
+  "\0"
+#define ELF_E_NO_VERSION_IDX \
+  (ELF_E_INVALID_OP_IDX + sizeof "invalid operation")
+  N_("ELF version not set")
+  "\0"
+#define ELF_E_INVALID_CMD_IDX \
+  (ELF_E_NO_VERSION_IDX + sizeof "ELF version not set")
+  N_("invalid command")
+  "\0"
+#define ELF_E_RANGE_IDX \
+  (ELF_E_INVALID_CMD_IDX + sizeof "invalid command")
+  N_("offset out of range")
+  "\0"
+#define ELF_E_ARCHIVE_FMAG_IDX \
+  (ELF_E_RANGE_IDX + sizeof "offset out of range")
+  N_("invalid fmag field in archive header")
+  "\0"
+#define ELF_E_INVALID_ARCHIVE_IDX \
+  (ELF_E_ARCHIVE_FMAG_IDX + sizeof "invalid fmag field in archive header")
+  N_("invalid archive file")
+  "\0"
+#define ELF_E_NO_ARCHIVE_IDX \
+  (ELF_E_INVALID_ARCHIVE_IDX + sizeof "invalid archive file")
+  N_("descriptor is not for an archive")
+  "\0"
+#define ELF_E_NO_INDEX_IDX \
+  (ELF_E_NO_ARCHIVE_IDX + sizeof "descriptor is not for an archive")
+  N_("no index available")
+  "\0"
+#define ELF_E_READ_ERROR_IDX \
+  (ELF_E_NO_INDEX_IDX + sizeof "no index available")
+  N_("cannot read data from file")
+  "\0"
+#define ELF_E_WRITE_ERROR_IDX \
+  (ELF_E_READ_ERROR_IDX + sizeof "cannot read data from file")
+  N_("cannot write data to file")
+  "\0"
+#define ELF_E_INVALID_CLASS_IDX \
+  (ELF_E_WRITE_ERROR_IDX + sizeof "cannot write data to file")
+  N_("invalid binary class")
+  "\0"
+#define ELF_E_INVALID_INDEX_IDX \
+  (ELF_E_INVALID_CLASS_IDX + sizeof "invalid binary class")
+  N_("invalid section index")
+  "\0"
+#define ELF_E_INVALID_OPERAND_IDX \
+  (ELF_E_INVALID_INDEX_IDX + sizeof "invalid section index")
+  N_("invalid operand")
+  "\0"
+#define ELF_E_INVALID_SECTION_IDX \
+  (ELF_E_INVALID_OPERAND_IDX + sizeof "invalid operand")
+  N_("invalid section")
+  "\0"
+#define ELF_E_INVALID_COMMAND_IDX \
+  (ELF_E_INVALID_SECTION_IDX + sizeof "invalid section")
+  N_("invalid command")
+  "\0"
+#define ELF_E_WRONG_ORDER_EHDR_IDX \
+  (ELF_E_INVALID_COMMAND_IDX + sizeof "invalid command")
+  N_("executable header not created first")
+  "\0"
+#define ELF_E_FD_DISABLED_IDX \
+  (ELF_E_WRONG_ORDER_EHDR_IDX + sizeof "executable header not created first")
+  N_("file descriptor disabled")
+  "\0"
+#define ELF_E_FD_MISMATCH_IDX \
+  (ELF_E_FD_DISABLED_IDX + sizeof "file descriptor disabled")
+  N_("archive/member file descriptor mismatch")
+  "\0"
+#define ELF_E_OFFSET_RANGE_IDX \
+  (ELF_E_FD_MISMATCH_IDX + sizeof "archive/member file descriptor mismatch")
+  N_("offset out of range")
+  "\0"
+#define ELF_E_NOT_NUL_SECTION_IDX \
+  (ELF_E_OFFSET_RANGE_IDX + sizeof "offset out of range")
+  N_("cannot manipulate null section")
+  "\0"
+#define ELF_E_DATA_MISMATCH_IDX \
+  (ELF_E_NOT_NUL_SECTION_IDX + sizeof "cannot manipulate null section")
+  N_("data/scn mismatch")
+  "\0"
+#define ELF_E_INVALID_SECTION_HEADER_IDX \
+  (ELF_E_DATA_MISMATCH_IDX + sizeof "data/scn mismatch")
+  N_("invalid section header")
+  "\0"
+#define ELF_E_INVALID_DATA_IDX \
+  (ELF_E_INVALID_SECTION_HEADER_IDX + sizeof "invalid section header")
+  N_("invalid data")
+  "\0"
+#define ELF_E_DATA_ENCODING_IDX \
+  (ELF_E_INVALID_DATA_IDX + sizeof "invalid data")
+  N_("unknown data encoding")
+  "\0"
+#define ELF_E_SECTION_TOO_SMALL_IDX \
+  (ELF_E_DATA_ENCODING_IDX + sizeof "unknown data encoding")
+  N_("section `sh_size' too small for data")
+  "\0"
+#define ELF_E_INVALID_ALIGN_IDX \
+  (ELF_E_SECTION_TOO_SMALL_IDX + sizeof "section `sh_size' too small for data")
+  N_("invalid section alignment")
+  "\0"
+#define ELF_E_INVALID_SHENTSIZE_IDX \
+  (ELF_E_INVALID_ALIGN_IDX + sizeof "invalid section alignment")
+  N_("invalid section entry size")
+  "\0"
+#define ELF_E_UPDATE_RO_IDX \
+  (ELF_E_INVALID_SHENTSIZE_IDX + sizeof "invalid section entry size")
+  N_("update() for write on read-only file")
+  "\0"
+#define ELF_E_NOFILE_IDX \
+  (ELF_E_UPDATE_RO_IDX + sizeof "update() for write on read-only file")
+  N_("no such file")
+  "\0"
+#define ELF_E_GROUP_NOT_REL_IDX \
+  (ELF_E_NOFILE_IDX + sizeof "no such file")
+  N_("only relocatable files can contain section groups")
+  "\0"
+#define ELF_E_INVALID_PHDR_IDX \
+  (ELF_E_GROUP_NOT_REL_IDX \
+   + sizeof "only relocatable files can contain section groups")
+  N_("program header only allowed in executables, shared objects, and \
+core files")
+  "\0"
+#define ELF_E_NO_PHDR_IDX \
+  (ELF_E_INVALID_PHDR_IDX \
+   + sizeof "program header only allowed in executables, shared objects, and \
+core files")
+  N_("file has no program header")
+  "\0"
+#define ELF_E_INVALID_OFFSET_IDX \
+  (ELF_E_NO_PHDR_IDX \
+   + sizeof "file has no program header")
+  N_("invalid offset")
+  "\0"
+#define ELF_E_INVALID_SECTION_TYPE_IDX \
+  (ELF_E_INVALID_OFFSET_IDX \
+   + sizeof "invalid offset")
+  N_("invalid section type")
+  "\0"
+#define ELF_E_INVALID_SECTION_FLAGS_IDX \
+  (ELF_E_INVALID_SECTION_TYPE_IDX \
+   + sizeof "invalid section type")
+  N_("invalid section flags")
+  "\0"
+#define ELF_E_NOT_COMPRESSED_IDX		\
+  (ELF_E_INVALID_SECTION_FLAGS_IDX			\
+   + sizeof "invalid section flags")
+  N_("section does not contain compressed data")
+  "\0"
+#define ELF_E_ALREADY_COMPRESSED_IDX \
+  (ELF_E_NOT_COMPRESSED_IDX \
+   + sizeof "section does not contain compressed data")
+  N_("section contains compressed data")
+  "\0"
+#define ELF_E_UNKNOWN_COMPRESSION_TYPE_IDX \
+  (ELF_E_ALREADY_COMPRESSED_IDX \
+   + sizeof "section contains compressed data")
+  N_("unknown compression type")
+  "\0"
+#define ELF_E_COMPRESS_ERROR_IDX \
+  (ELF_E_UNKNOWN_COMPRESSION_TYPE_IDX \
+   + sizeof "unknown compression type")
+  N_("cannot compress data")
+  "\0"
+#define ELF_E_DECOMPRESS_ERROR_IDX \
+  (ELF_E_COMPRESS_ERROR_IDX \
+   + sizeof "cannot compress data")
+  N_("cannot decompress data")
+};
+
+
+static const uint_fast16_t msgidx[ELF_E_NUM] =
+{
+  [ELF_E_NOERROR] = ELF_E_NOERROR_IDX,
+  [ELF_E_UNKNOWN_ERROR] = ELF_E_UNKNOWN_ERROR_IDX,
+  [ELF_E_UNKNOWN_VERSION] = ELF_E_UNKNOWN_VERSION_IDX,
+  [ELF_E_UNKNOWN_TYPE] = ELF_E_UNKNOWN_TYPE_IDX,
+  [ELF_E_INVALID_HANDLE] = ELF_E_INVALID_HANDLE_IDX,
+  [ELF_E_SOURCE_SIZE] = ELF_E_SOURCE_SIZE_IDX,
+  [ELF_E_DEST_SIZE] = ELF_E_DEST_SIZE_IDX,
+  [ELF_E_INVALID_ENCODING] = ELF_E_INVALID_ENCODING_IDX,
+  [ELF_E_NOMEM] = ELF_E_NOMEM_IDX,
+  [ELF_E_INVALID_FILE] = ELF_E_INVALID_FILE_IDX,
+  [ELF_E_INVALID_ELF] = ELF_E_INVALID_ELF_IDX,
+  [ELF_E_INVALID_OP] = ELF_E_INVALID_OP_IDX,
+  [ELF_E_NO_VERSION] = ELF_E_NO_VERSION_IDX,
+  [ELF_E_INVALID_CMD] = ELF_E_INVALID_CMD_IDX,
+  [ELF_E_RANGE] = ELF_E_RANGE_IDX,
+  [ELF_E_ARCHIVE_FMAG] = ELF_E_ARCHIVE_FMAG_IDX,
+  [ELF_E_INVALID_ARCHIVE] = ELF_E_INVALID_ARCHIVE_IDX,
+  [ELF_E_NO_ARCHIVE] = ELF_E_NO_ARCHIVE_IDX,
+  [ELF_E_NO_INDEX] = ELF_E_NO_INDEX_IDX,
+  [ELF_E_READ_ERROR] = ELF_E_READ_ERROR_IDX,
+  [ELF_E_WRITE_ERROR] = ELF_E_WRITE_ERROR_IDX,
+  [ELF_E_INVALID_CLASS] = ELF_E_INVALID_CLASS_IDX,
+  [ELF_E_INVALID_INDEX] = ELF_E_INVALID_INDEX_IDX,
+  [ELF_E_INVALID_OPERAND] = ELF_E_INVALID_OPERAND_IDX,
+  [ELF_E_INVALID_SECTION] = ELF_E_INVALID_SECTION_IDX,
+  [ELF_E_INVALID_COMMAND] = ELF_E_INVALID_COMMAND_IDX,
+  [ELF_E_WRONG_ORDER_EHDR] = ELF_E_WRONG_ORDER_EHDR_IDX,
+  [ELF_E_FD_DISABLED] = ELF_E_FD_DISABLED_IDX,
+  [ELF_E_FD_MISMATCH] = ELF_E_FD_MISMATCH_IDX,
+  [ELF_E_OFFSET_RANGE] = ELF_E_OFFSET_RANGE_IDX,
+  [ELF_E_NOT_NUL_SECTION] = ELF_E_NOT_NUL_SECTION_IDX,
+  [ELF_E_DATA_MISMATCH] = ELF_E_DATA_MISMATCH_IDX,
+  [ELF_E_INVALID_SECTION_HEADER] = ELF_E_INVALID_SECTION_HEADER_IDX,
+  [ELF_E_INVALID_DATA] = ELF_E_INVALID_DATA_IDX,
+  [ELF_E_DATA_ENCODING] = ELF_E_DATA_ENCODING_IDX,
+  [ELF_E_SECTION_TOO_SMALL] = ELF_E_SECTION_TOO_SMALL_IDX,
+  [ELF_E_INVALID_ALIGN] = ELF_E_INVALID_ALIGN_IDX,
+  [ELF_E_INVALID_SHENTSIZE] = ELF_E_INVALID_SHENTSIZE_IDX,
+  [ELF_E_UPDATE_RO] = ELF_E_UPDATE_RO_IDX,
+  [ELF_E_NOFILE] = ELF_E_NOFILE_IDX,
+  [ELF_E_GROUP_NOT_REL] = ELF_E_GROUP_NOT_REL_IDX,
+  [ELF_E_INVALID_PHDR] = ELF_E_INVALID_PHDR_IDX,
+  [ELF_E_NO_PHDR] = ELF_E_NO_PHDR_IDX,
+  [ELF_E_INVALID_OFFSET] = ELF_E_INVALID_OFFSET_IDX,
+  [ELF_E_INVALID_SECTION_TYPE] = ELF_E_INVALID_SECTION_TYPE_IDX,
+  [ELF_E_INVALID_SECTION_FLAGS] = ELF_E_INVALID_SECTION_FLAGS_IDX,
+  [ELF_E_NOT_COMPRESSED] = ELF_E_NOT_COMPRESSED_IDX,
+  [ELF_E_ALREADY_COMPRESSED] = ELF_E_ALREADY_COMPRESSED_IDX,
+  [ELF_E_UNKNOWN_COMPRESSION_TYPE] = ELF_E_UNKNOWN_COMPRESSION_TYPE_IDX,
+  [ELF_E_COMPRESS_ERROR] = ELF_E_COMPRESS_ERROR_IDX,
+  [ELF_E_DECOMPRESS_ERROR] = ELF_E_DECOMPRESS_ERROR_IDX
+};
+#define nmsgidx ((int) (sizeof (msgidx) / sizeof (msgidx[0])))
+
+
+void
+internal_function
+__libelf_seterrno (int value)
+{
+  global_error = value >= 0 && value < nmsgidx ? value : ELF_E_UNKNOWN_ERROR;
+}
+
+
+const char *
+elf_errmsg (int error)
+{
+  int last_error = global_error;
+
+  if (error == 0)
+    {
+      assert (msgidx[last_error] < sizeof (msgstr));
+      return last_error != 0 ? _(msgstr + msgidx[last_error]) : NULL;
+    }
+  else if (error < -1 || error >= nmsgidx)
+    return _(msgstr + ELF_E_UNKNOWN_ERROR_IDX);
+
+  assert (msgidx[error == -1 ? last_error : error] < sizeof (msgstr));
+  return _(msgstr + msgidx[error == -1 ? last_error : error]);
+}
diff --git a/third_party/elfutils/libelf/elf_fill.c b/third_party/elfutils/libelf/elf_fill.c
new file mode 100644
index 0000000..6ebdf63
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_fill.c
@@ -0,0 +1,46 @@
+/* Set fill byte used when constructing ELF objects.
+   Copyright (C) 1998, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+
+#include "libelfP.h"
+
+
+int __libelf_fill_byte;
+
+
+void
+elf_fill (int fill)
+{
+  __libelf_fill_byte = fill;
+}
diff --git a/third_party/elfutils/libelf/elf_flagdata.c b/third_party/elfutils/libelf/elf_flagdata.c
new file mode 100644
index 0000000..cd2b123
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_flagdata.c
@@ -0,0 +1,68 @@
+/* Manipulate ELF data flag.
+   Copyright (C) 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagdata (Elf_Data *data, Elf_Cmd cmd, unsigned int flags)
+{
+  Elf_Data_Scn *data_scn;
+  unsigned int result;
+
+  if (data == NULL)
+    return 0;
+
+  data_scn = (Elf_Data_Scn *) data;
+
+  if (data_scn == NULL || unlikely (data_scn->s->elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (data_scn->s->flags |= (flags & ELF_F_DIRTY));
+  else if (likely (cmd == ELF_C_CLR))
+    result = (data_scn->s->flags &= ~(flags & ELF_F_DIRTY));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_flagehdr.c b/third_party/elfutils/libelf/elf_flagehdr.c
new file mode 100644
index 0000000..a98276d5
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_flagehdr.c
@@ -0,0 +1,65 @@
+/* Manipulate ELF header flags.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagehdr (Elf *elf, Elf_Cmd cmd, unsigned int flags)
+{
+  unsigned int result;
+
+  if (elf == NULL)
+    return 0;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (elf->state.elf.ehdr_flags |= (flags & ELF_F_DIRTY));
+  else if (cmd == ELF_C_CLR)
+    result = (elf->state.elf.ehdr_flags &= ~(flags & ELF_F_DIRTY));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_flagelf.c b/third_party/elfutils/libelf/elf_flagelf.c
new file mode 100644
index 0000000..bd90a21
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_flagelf.c
@@ -0,0 +1,67 @@
+/* Manipulate ELF file flags.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagelf (Elf *elf, Elf_Cmd cmd, unsigned int flags)
+{
+  unsigned int result;
+
+  if (elf == NULL)
+    return 0;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (elf->flags
+	      |= (flags & (ELF_F_DIRTY | ELF_F_LAYOUT | ELF_F_PERMISSIVE)));
+  else if (likely (cmd == ELF_C_CLR))
+    result = (elf->flags
+	      &= ~(flags & (ELF_F_DIRTY | ELF_F_LAYOUT | ELF_F_PERMISSIVE)));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_flagphdr.c b/third_party/elfutils/libelf/elf_flagphdr.c
new file mode 100644
index 0000000..0682d1f
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_flagphdr.c
@@ -0,0 +1,65 @@
+/* Manipulate ELF program header flags.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagphdr (Elf *elf, Elf_Cmd cmd, unsigned int flags)
+{
+  unsigned int result;
+
+  if (elf == NULL)
+    return 0;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (elf->state.elf.phdr_flags |= (flags & ELF_F_DIRTY));
+  else if (likely (cmd == ELF_C_CLR))
+    result = (elf->state.elf.phdr_flags &= ~(flags & ELF_F_DIRTY));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_flagscn.c b/third_party/elfutils/libelf/elf_flagscn.c
new file mode 100644
index 0000000..2164a8c
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_flagscn.c
@@ -0,0 +1,65 @@
+/* Manipulate ELF section flags.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagscn (Elf_Scn *scn, Elf_Cmd cmd, unsigned int flags)
+{
+  unsigned int result;
+
+  if (scn == NULL)
+    return 0;
+
+  if (unlikely (scn->elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (scn->flags |= (flags & ELF_F_DIRTY));
+  else if (likely (cmd == ELF_C_CLR))
+    result = (scn->flags &= ~(flags & ELF_F_DIRTY));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_flagshdr.c b/third_party/elfutils/libelf/elf_flagshdr.c
new file mode 100644
index 0000000..febf4ab
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_flagshdr.c
@@ -0,0 +1,65 @@
+/* Manipulate ELF section header flags.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+unsigned int
+elf_flagshdr (Elf_Scn *scn, Elf_Cmd cmd, unsigned int flags)
+{
+  unsigned int result;
+
+  if (scn == NULL)
+    return 0;
+
+  if (unlikely (scn->elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  if (likely (cmd == ELF_C_SET))
+    result = (scn->shdr_flags |= (flags & ELF_F_DIRTY));
+  else if (likely (cmd == ELF_C_CLR))
+    result = (scn->shdr_flags &= ~(flags & ELF_F_DIRTY));
+  else
+    {
+      __libelf_seterrno (ELF_E_INVALID_COMMAND);
+      return 0;
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_getarhdr.c b/third_party/elfutils/libelf/elf_getarhdr.c
new file mode 100644
index 0000000..509f1da
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_getarhdr.c
@@ -0,0 +1,73 @@
+/* Read header of next archive member.
+   Copyright (C) 1998, 1999, 2000, 2002, 2008, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Arhdr *
+elf_getarhdr (Elf *elf)
+{
+  if (elf == NULL)
+    return NULL;
+
+  Elf *parent = elf->parent;
+
+  /* Calling this function is not ok for any file type but archives.  */
+  if (parent == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OP);
+      return NULL;
+    }
+
+  /* Make sure we have read the archive header.  */
+  if (parent->state.ar.elf_ar_hdr.ar_name == NULL
+      && __libelf_next_arhdr_wrlock (parent) != 0)
+    {
+      rwlock_wrlock (parent->lock);
+      int st = __libelf_next_arhdr_wrlock (parent);
+      rwlock_unlock (parent->lock);
+
+      if (st != 0)
+	/* Something went wrong.  Maybe there is no member left.  */
+	return NULL;
+    }
+
+  /* We can be sure the parent is an archive.  */
+  assert (parent->kind == ELF_K_AR);
+
+  return &parent->state.ar.elf_ar_hdr;
+}
diff --git a/third_party/elfutils/libelf/elf_getaroff.c b/third_party/elfutils/libelf/elf_getaroff.c
new file mode 100644
index 0000000..5b59203
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_getaroff.c
@@ -0,0 +1,53 @@
+/* Return offset in archive for current file ELF.
+   Copyright (C) 2005, 2008, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+off_t
+elf_getaroff (Elf *elf)
+{
+  /* Be gratious, the specs demand it.  */
+  if (elf == NULL || elf->parent == NULL)
+    return ELF_C_NULL;
+
+  /* We can be sure the parent is an archive.  */
+  Elf *parent = elf->parent;
+  assert (parent->kind == ELF_K_AR);
+
+  return elf->start_offset - sizeof (struct ar_hdr) - parent->start_offset;
+}
diff --git a/third_party/elfutils/libelf/elf_getarsym.c b/third_party/elfutils/libelf/elf_getarsym.c
new file mode 100644
index 0000000..1f031fc
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_getarsym.c
@@ -0,0 +1,331 @@
+/* Return symbol table of archive.
+   Copyright (C) 1998-2000, 2002, 2005, 2009, 2012, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <system.h>
+#include <dl-hash.h>
+#include "libelfP.h"
+
+
+static int
+read_number_entries (uint64_t *nump, Elf *elf, size_t *offp, bool index64_p)
+{
+  union u
+  {
+    uint64_t ret64;
+    uint32_t ret32;
+  } u;
+
+  size_t w = index64_p ? 8 : 4;
+  if (elf->map_address != NULL)
+    /* Use memcpy instead of pointer dereference so as not to assume the
+       field is naturally aligned within the file.  */
+    memcpy (&u, elf->map_address + *offp, sizeof u);
+  else if ((size_t) pread_retry (elf->fildes, &u, w, *offp) != w)
+    return -1;
+
+  *offp += w;
+
+  if (__BYTE_ORDER == __LITTLE_ENDIAN)
+    *nump = index64_p ? bswap_64 (u.ret64) : bswap_32 (u.ret32);
+  else
+    *nump = index64_p ? u.ret64 : u.ret32;
+
+  return 0;
+}
+
+Elf_Arsym *
+elf_getarsym (Elf *elf, size_t *ptr)
+{
+  if (elf->kind != ELF_K_AR)
+    {
+      /* This is no archive.  */
+      __libelf_seterrno (ELF_E_NO_ARCHIVE);
+      return NULL;
+    }
+
+  if (ptr != NULL)
+    /* In case of an error or when we know the value store the expected
+       value now.  Doing this allows us easier exits in an error case.  */
+    *ptr = elf->state.ar.ar_sym_num;
+
+  if (elf->state.ar.ar_sym == (Elf_Arsym *) -1l)
+    {
+      /* There is no index.  */
+      __libelf_seterrno (ELF_E_NO_INDEX);
+      return NULL;
+    }
+
+  Elf_Arsym *result = elf->state.ar.ar_sym;
+  if (result == NULL)
+    {
+      /* We have not yet read the index.  */
+      rwlock_wrlock (elf->lock);
+
+      /* In case we find no index remember this for the next call.  */
+      elf->state.ar.ar_sym = (Elf_Arsym *) -1l;
+
+      /* We might have to allocate some temporary data for reading.  */
+      void *temp_data = NULL;
+
+      struct ar_hdr *index_hdr;
+      if (elf->map_address == NULL)
+	{
+	  /* We must read index from the file.  */
+	  assert (elf->fildes != -1);
+	  if (pread_retry (elf->fildes, &elf->state.ar.ar_hdr,
+			   sizeof (struct ar_hdr), elf->start_offset + SARMAG)
+	      != sizeof (struct ar_hdr))
+	    {
+	      /* It is not possible to read the index.  Maybe it does not
+		 exist.  */
+	      __libelf_seterrno (ELF_E_READ_ERROR);
+	      goto out;
+	    }
+
+	  index_hdr = &elf->state.ar.ar_hdr;
+	}
+      else
+	{
+	  if (SARMAG + sizeof (struct ar_hdr) > elf->maximum_size)
+	    {
+	      /* There is no room for the full archive.  */
+	      __libelf_seterrno (ELF_E_NO_INDEX);
+	      goto out;
+	    }
+
+	  index_hdr = (struct ar_hdr *) (elf->map_address
+					 + elf->start_offset + SARMAG);
+	}
+
+      /* Now test whether this really is an archive.  */
+      if (memcmp (index_hdr->ar_fmag, ARFMAG, 2) != 0)
+	{
+	  /* Invalid magic bytes.  */
+	  __libelf_seterrno (ELF_E_ARCHIVE_FMAG);
+	  goto out;
+	}
+
+      bool index64_p;
+      /* Now test whether this is the index.  If the name is "/", this
+	 is 32-bit index, if it's "/SYM64/", it's 64-bit index.
+
+	 XXX This is not entirely true.  There are some more forms.
+	 Which of them shall we handle?  */
+      if (memcmp (index_hdr->ar_name, "/               ", 16) == 0)
+	index64_p = false;
+      else if (memcmp (index_hdr->ar_name, "/SYM64/         ", 16) == 0)
+	index64_p = true;
+      else
+	{
+	  /* If the index is not the first entry, there is no index.
+
+	     XXX Is this true?  */
+	  __libelf_seterrno (ELF_E_NO_INDEX);
+	  goto out;
+	}
+      int w = index64_p ? 8 : 4;
+
+      /* We have an archive.  The first word in there is the number of
+	 entries in the table.  */
+      uint64_t n = 0;
+      size_t off = elf->start_offset + SARMAG + sizeof (struct ar_hdr);
+      if (read_number_entries (&n, elf, &off, index64_p) < 0)
+	{
+	  /* Cannot read the number of entries.  */
+	  __libelf_seterrno (ELF_E_NO_INDEX);
+	  goto out;
+	}
+
+      /* Now we can perform some first tests on whether all the data
+	 needed for the index is available.  */
+      char tmpbuf[17];
+      memcpy (tmpbuf, index_hdr->ar_size, 10);
+      tmpbuf[10] = '\0';
+      size_t index_size = atol (tmpbuf);
+
+      if (index_size > elf->maximum_size
+	  || elf->maximum_size - index_size < SARMAG + sizeof (struct ar_hdr)
+#if SIZE_MAX <= 4294967295U
+	  || n >= SIZE_MAX / sizeof (Elf_Arsym)
+#endif
+	  || n > index_size / w)
+	{
+	  /* This index table cannot be right since it does not fit into
+	     the file.  */
+	  __libelf_seterrno (ELF_E_NO_INDEX);
+	  goto out;
+	}
+
+      /* Now we can allocate the arrays needed to store the index.  */
+      size_t ar_sym_len = (n + 1) * sizeof (Elf_Arsym);
+      elf->state.ar.ar_sym = (Elf_Arsym *) malloc (ar_sym_len);
+      if (elf->state.ar.ar_sym != NULL)
+	{
+	  void *file_data; /* unit32_t[n] or uint64_t[n] */
+	  char *str_data;
+	  size_t sz = n * w;
+
+	  if (elf->map_address == NULL)
+	    {
+	      temp_data = malloc (sz);
+	      if (unlikely (temp_data == NULL))
+		{
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  goto out;
+		}
+	      file_data = temp_data;
+
+	      ar_sym_len += index_size - n * w;
+	      Elf_Arsym *newp = (Elf_Arsym *) realloc (elf->state.ar.ar_sym,
+						       ar_sym_len);
+	      if (newp == NULL)
+		{
+		  free (elf->state.ar.ar_sym);
+		  elf->state.ar.ar_sym = NULL;
+		  __libelf_seterrno (ELF_E_NOMEM);
+		  goto out;
+		}
+	      elf->state.ar.ar_sym = newp;
+
+	      char *new_str = (char *) (elf->state.ar.ar_sym + n + 1);
+
+	      /* Now read the data from the file.  */
+	      if ((size_t) pread_retry (elf->fildes, file_data, sz, off) != sz
+		  || ((size_t) pread_retry (elf->fildes, new_str,
+					    index_size - sz, off + sz)
+		      != index_size - sz))
+		{
+		  /* We were not able to read the data.  */
+		  free (elf->state.ar.ar_sym);
+		  elf->state.ar.ar_sym = NULL;
+		  __libelf_seterrno (ELF_E_NO_INDEX);
+		  goto out;
+		}
+
+	      str_data = (char *) new_str;
+	    }
+	  else
+	    {
+	      file_data = (void *) (elf->map_address + off);
+	      if (!ALLOW_UNALIGNED
+		  && ((uintptr_t) file_data & -(uintptr_t) n) != 0)
+		{
+		  temp_data = malloc (sz);
+		  if (unlikely (temp_data == NULL))
+		    {
+		      __libelf_seterrno (ELF_E_NOMEM);
+		      goto out;
+		    }
+		  file_data = memcpy (temp_data, elf->map_address + off, sz);
+		}
+	      str_data = (char *) (elf->map_address + off + sz);
+	    }
+
+	  /* Now we can build the data structure.  */
+	  Elf_Arsym *arsym = elf->state.ar.ar_sym;
+	  uint64_t (*u64)[n] = file_data;
+	  uint32_t (*u32)[n] = file_data;
+	  for (size_t cnt = 0; cnt < n; ++cnt)
+	    {
+	      arsym[cnt].as_name = str_data;
+	      if (index64_p)
+		{
+		  uint64_t tmp = (*u64)[cnt];
+		  if (__BYTE_ORDER == __LITTLE_ENDIAN)
+		    tmp = bswap_64 (tmp);
+
+		  arsym[cnt].as_off = tmp;
+
+		  /* Check whether 64-bit offset fits into 32-bit
+		     size_t.  */
+		  if (sizeof (arsym[cnt].as_off) < 8
+		      && arsym[cnt].as_off != tmp)
+		    {
+		      if (elf->map_address == NULL)
+			{
+			  free (elf->state.ar.ar_sym);
+			  elf->state.ar.ar_sym = NULL;
+			}
+
+		      __libelf_seterrno (ELF_E_RANGE);
+		      goto out;
+		    }
+		}
+	      else if (__BYTE_ORDER == __LITTLE_ENDIAN)
+		arsym[cnt].as_off = bswap_32 ((*u32)[cnt]);
+	      else
+		arsym[cnt].as_off = (*u32)[cnt];
+
+	      arsym[cnt].as_hash = _dl_elf_hash (str_data);
+#if HAVE_DECL_RAWMEMCHR
+	      str_data = rawmemchr (str_data, '\0') + 1;
+#else
+	      char c;
+	      do {
+		c = *str_data;
+		str_data++;
+	      } while (c);
+#endif
+	    }
+
+	  /* At the end a special entry.  */
+	  arsym[n].as_name = NULL;
+	  arsym[n].as_off = 0;
+	  arsym[n].as_hash = ~0UL;
+
+	  /* Tell the caller how many entries we have.  */
+	  elf->state.ar.ar_sym_num = n + 1;
+	}
+
+      result = elf->state.ar.ar_sym;
+
+    out:
+      free (temp_data);
+      rwlock_unlock (elf->lock);
+    }
+
+  if (ptr != NULL)
+    *ptr = elf->state.ar.ar_sym_num;
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_getbase.c b/third_party/elfutils/libelf/elf_getbase.c
new file mode 100644
index 0000000..8ec5f87
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_getbase.c
@@ -0,0 +1,44 @@
+/* Return offset of first byte for the object.
+   Copyright (C) 1998, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+off_t
+elf_getbase (Elf *elf)
+{
+  return elf == NULL ? (off_t) -1 : elf->start_offset;
+}
diff --git a/third_party/elfutils/libelf/elf_getdata.c b/third_party/elfutils/libelf/elf_getdata.c
new file mode 100644
index 0000000..97c503b
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_getdata.c
@@ -0,0 +1,564 @@
+/* Return the next data element from the section after possibly converting it.
+   Copyright (C) 1998-2005, 2006, 2007, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libelfP.h"
+#include <system.h>
+#include "common.h"
+#include "elf-knowledge.h"
+
+
+#define TYPEIDX(Sh_Type) \
+  (Sh_Type >= SHT_NULL && Sh_Type < SHT_NUM				      \
+   ? Sh_Type								      \
+   : (Sh_Type >= SHT_GNU_HASH && Sh_Type <= SHT_HISUNW			      \
+      ? SHT_NUM + Sh_Type - SHT_GNU_HASH				      \
+      : 0))
+
+/* Associate section types with libelf types.  */
+static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
+  {
+    [EV_CURRENT - 1] =
+    {
+      [SHT_SYMTAB] = ELF_T_SYM,
+      [SHT_RELA] = ELF_T_RELA,
+      [SHT_HASH] = ELF_T_WORD,
+      [SHT_DYNAMIC] = ELF_T_DYN,
+      [SHT_REL] = ELF_T_REL,
+      [SHT_DYNSYM] = ELF_T_SYM,
+      [SHT_INIT_ARRAY] = ELF_T_ADDR,
+      [SHT_FINI_ARRAY] = ELF_T_ADDR,
+      [SHT_PREINIT_ARRAY] = ELF_T_ADDR,
+      [SHT_GROUP] = ELF_T_WORD,
+      [SHT_SYMTAB_SHNDX] = ELF_T_WORD,
+      [SHT_NOTE] = ELF_T_NHDR,
+      [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF,
+      [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED,
+      [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF,
+      [TYPEIDX (SHT_SUNW_syminfo)] = ELF_T_SYMINFO,
+      [TYPEIDX (SHT_SUNW_move)] = ELF_T_MOVE,
+      [TYPEIDX (SHT_GNU_LIBLIST)] = ELF_T_LIB,
+      [TYPEIDX (SHT_GNU_HASH)] = ELF_T_GNUHASH,
+    }
+  };
+
+#if !ALLOW_UNALIGNED
+/* Associate libelf types with their internal alignment requirements.  */
+const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+  {
+# define TYPE_ALIGNS(Bits)						      \
+    {									      \
+      [ELF_T_ADDR] = __alignof__ (ElfW2(Bits,Addr)),			      \
+      [ELF_T_EHDR] = __alignof__ (ElfW2(Bits,Ehdr)),			      \
+      [ELF_T_HALF] = __alignof__ (ElfW2(Bits,Half)),			      \
+      [ELF_T_OFF] = __alignof__ (ElfW2(Bits,Off)),			      \
+      [ELF_T_PHDR] = __alignof__ (ElfW2(Bits,Phdr)),			      \
+      [ELF_T_SHDR] = __alignof__ (ElfW2(Bits,Shdr)),			      \
+      [ELF_T_SWORD] = __alignof__ (ElfW2(Bits,Sword)),			      \
+      [ELF_T_WORD] = __alignof__ (ElfW2(Bits,Word)),			      \
+      [ELF_T_XWORD] = __alignof__ (ElfW2(Bits,Xword)),			      \
+      [ELF_T_SXWORD] = __alignof__ (ElfW2(Bits,Sxword)),		      \
+      [ELF_T_SYM] = __alignof__ (ElfW2(Bits,Sym)),			      \
+      [ELF_T_SYMINFO] = __alignof__ (ElfW2(Bits,Syminfo)),		      \
+      [ELF_T_REL] = __alignof__ (ElfW2(Bits,Rel)),			      \
+      [ELF_T_RELA] = __alignof__ (ElfW2(Bits,Rela)),			      \
+      [ELF_T_DYN] = __alignof__ (ElfW2(Bits,Dyn)),			      \
+      [ELF_T_VDEF] = __alignof__ (ElfW2(Bits,Verdef)),			      \
+      [ELF_T_VDAUX] = __alignof__ (ElfW2(Bits,Verdaux)),		      \
+      [ELF_T_VNEED] = __alignof__ (ElfW2(Bits,Verneed)),		      \
+      [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)),		      \
+      [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)),			      \
+      [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)),			      \
+      [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)),			      \
+      [ELF_T_GNUHASH] = __alignof__ (Elf32_Word),			      \
+      [ELF_T_AUXV] = __alignof__ (ElfW2(Bits,auxv_t)),			      \
+      [ELF_T_CHDR] = __alignof__ (ElfW2(Bits,Chdr)),			      \
+    }
+    [EV_CURRENT - 1] =
+    {
+      [ELFCLASS32 - 1] = TYPE_ALIGNS (32),
+      [ELFCLASS64 - 1] = TYPE_ALIGNS (64),
+    }
+# undef TYPE_ALIGNS
+  };
+#endif
+
+
+Elf_Type
+internal_function
+__libelf_data_type (Elf *elf, int sh_type)
+{
+  /* Some broken ELF ABI for 64-bit machines use the wrong hash table
+     entry size.  See elf-knowledge.h for more information.  */
+  if (sh_type == SHT_HASH && elf->class == ELFCLASS64)
+    {
+      GElf_Ehdr ehdr_mem;
+      GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
+      return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
+    }
+  else
+    return shtype_map[LIBELF_EV_IDX][TYPEIDX (sh_type)];
+}
+
+/* Convert the data in the current section.  */
+static void
+convert_data (Elf_Scn *scn, int version __attribute__ ((unused)), int eclass,
+	      int data, size_t size, Elf_Type type)
+{
+  const size_t align = __libelf_type_align (eclass, type);
+
+  if (data == MY_ELFDATA)
+    {
+      if (((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
+	/* No need to copy, we can use the raw data.  */
+	scn->data_base = scn->rawdata_base;
+      else
+	{
+	  scn->data_base = (char *) malloc (size);
+	  if (scn->data_base == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return;
+	    }
+
+	  /* The copy will be appropriately aligned for direct access.  */
+	  memcpy (scn->data_base, scn->rawdata_base, size);
+	}
+    }
+  else
+    {
+      xfct_t fp;
+
+      scn->data_base = (char *) malloc (size);
+      if (scn->data_base == NULL)
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  return;
+	}
+
+      /* Make sure the source is correctly aligned for the conversion
+	 function to directly access the data elements.  */
+      char *rawdata_source;
+      if (ALLOW_UNALIGNED ||
+	  ((((size_t) (char *) scn->rawdata_base)) & (align - 1)) == 0)
+	rawdata_source = scn->rawdata_base;
+      else
+	{
+	  rawdata_source = (char *) malloc (size);
+	  if (rawdata_source == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return;
+	    }
+
+	  /* The copy will be appropriately aligned for direct access.  */
+	  memcpy (rawdata_source, scn->rawdata_base, size);
+	}
+
+      /* Get the conversion function.  */
+#if EV_NUM != 2
+      fp = __elf_xfctstom[version - 1][__libelf_version - 1][eclass - 1][type];
+#else
+      fp = __elf_xfctstom[0][0][eclass - 1][type];
+#endif
+
+      fp (scn->data_base, rawdata_source, size, 0);
+
+      if (rawdata_source != scn->rawdata_base)
+	free (rawdata_source);
+    }
+
+  scn->data_list.data.d.d_buf = scn->data_base;
+  scn->data_list.data.d.d_size = size;
+  scn->data_list.data.d.d_type = type;
+  scn->data_list.data.d.d_off = scn->rawdata.d.d_off;
+  scn->data_list.data.d.d_align = scn->rawdata.d.d_align;
+  scn->data_list.data.d.d_version = scn->rawdata.d.d_version;
+
+  scn->data_list.data.s = scn;
+}
+
+
+/* Store the information for the raw data in the `rawdata' element.  */
+int
+internal_function
+__libelf_set_rawdata_wrlock (Elf_Scn *scn)
+{
+  Elf64_Off offset;
+  Elf64_Xword size;
+  Elf64_Xword align;
+  Elf64_Xword flags;
+  int type;
+  Elf *elf = scn->elf;
+
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Shdr *shdr
+	= scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
+
+      if (shdr == NULL)
+	/* Something went terribly wrong.  */
+	return 1;
+
+      offset = shdr->sh_offset;
+      size = shdr->sh_size;
+      type = shdr->sh_type;
+      align = shdr->sh_addralign;
+      flags = shdr->sh_flags;
+    }
+  else
+    {
+      Elf64_Shdr *shdr
+	= scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
+
+      if (shdr == NULL)
+	/* Something went terribly wrong.  */
+	return 1;
+
+      offset = shdr->sh_offset;
+      size = shdr->sh_size;
+      type = shdr->sh_type;
+      align = shdr->sh_addralign;
+      flags = shdr->sh_flags;
+    }
+
+  /* If the section has no data (for whatever reason), leave the `d_buf'
+     pointer NULL.  */
+  if (size != 0 && type != SHT_NOBITS)
+    {
+      /* First a test whether the section is valid at all.  */
+      size_t entsize;
+
+      /* Compressed data has a header, but then compressed data.  */
+      if ((flags & SHF_COMPRESSED) != 0)
+	entsize = 1;
+      else if (type == SHT_HASH)
+	{
+	  GElf_Ehdr ehdr_mem;
+	  GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
+	  entsize = SH_ENTSIZE_HASH (ehdr);
+	}
+      else
+	{
+	  Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
+	  if (t == ELF_T_VDEF || t == ELF_T_NHDR
+	      || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
+	    entsize = 1;
+	  else
+	    entsize = __libelf_type_sizes[LIBELF_EV_IDX][elf->class - 1][t];
+	}
+
+      /* We assume it is an array of bytes if it is none of the structured
+	 sections we know of.  */
+      if (entsize == 0)
+	entsize = 1;
+
+      if (unlikely (size % entsize != 0))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  return 1;
+	}
+
+      /* We can use the mapped or loaded data if available.  */
+      if (elf->map_address != NULL)
+	{
+	  /* First see whether the information in the section header is
+	     valid and it does not ask for too much.  Check for unsigned
+	     overflow.  */
+	  if (unlikely (offset > elf->maximum_size
+	      || elf->maximum_size - offset < size))
+	    {
+	      /* Something is wrong.  */
+	      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+	      return 1;
+	    }
+
+	  scn->rawdata_base = scn->rawdata.d.d_buf
+	    = (char *) elf->map_address + elf->start_offset + offset;
+	}
+      else if (likely (elf->fildes != -1))
+	{
+	  /* First see whether the information in the section header is
+	     valid and it does not ask for too much.  Check for unsigned
+	     overflow.  */
+	  if (unlikely (offset > elf->maximum_size
+			|| elf->maximum_size - offset < size))
+	    {
+	      /* Something is wrong.  */
+	      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+	      return 1;
+	    }
+
+	  /* We have to read the data from the file.  Allocate the needed
+	     memory.  */
+	  scn->rawdata_base = scn->rawdata.d.d_buf
+	    = (char *) malloc (size);
+	  if (scn->rawdata.d.d_buf == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_NOMEM);
+	      return 1;
+	    }
+
+	  ssize_t n = pread_retry (elf->fildes, scn->rawdata.d.d_buf, size,
+				   elf->start_offset + offset);
+	  if (unlikely ((size_t) n != size))
+	    {
+	      /* Cannot read the data.  */
+	      free (scn->rawdata.d.d_buf);
+	      scn->rawdata_base = scn->rawdata.d.d_buf = NULL;
+	      __libelf_seterrno (ELF_E_READ_ERROR);
+	      return 1;
+	    }
+	}
+      else
+	{
+	  /* The file descriptor is already closed, we cannot get the data
+	     anymore.  */
+	  __libelf_seterrno (ELF_E_FD_DISABLED);
+	  return 1;
+	}
+    }
+
+  scn->rawdata.d.d_size = size;
+
+  /* Compressed data always has type ELF_T_CHDR regardless of the
+     section type.  */
+  if ((flags & SHF_COMPRESSED) != 0)
+    scn->rawdata.d.d_type = ELF_T_CHDR;
+  else
+    scn->rawdata.d.d_type = __libelf_data_type (elf, type);
+  scn->rawdata.d.d_off = 0;
+
+  /* Make sure the alignment makes sense.  d_align should be aligned both
+     in the section (trivially true since d_off is zero) and in the file.
+     Unfortunately we cannot be too strict because there are ELF files
+     out there that fail this requirement.  We will try to fix those up
+     in elf_update when writing out the image.  But for very large
+     alignment values this can bloat the image considerably.  So here
+     just check and clamp the alignment value to not be bigger than the
+     actual offset of the data in the file.  Given that there is always
+     at least an ehdr this will only trigger for alignment values > 64
+     which should be uncommon.  */
+  align = align ?: 1;
+  if (type != SHT_NOBITS && align > offset)
+    align = offset;
+  scn->rawdata.d.d_align = align;
+  if (elf->class == ELFCLASS32
+      || (offsetof (struct Elf, state.elf32.ehdr)
+	  == offsetof (struct Elf, state.elf64.ehdr)))
+    scn->rawdata.d.d_version =
+      elf->state.elf32.ehdr->e_ident[EI_VERSION];
+  else
+    scn->rawdata.d.d_version =
+      elf->state.elf64.ehdr->e_ident[EI_VERSION];
+
+  scn->rawdata.s = scn;
+
+  scn->data_read = 1;
+
+  /* We actually read data from the file.  At least we tried.  */
+  scn->flags |= ELF_F_FILEDATA;
+
+  return 0;
+}
+
+int
+internal_function
+__libelf_set_rawdata (Elf_Scn *scn)
+{
+  int result;
+
+  if (scn == NULL)
+    return 1;
+
+  rwlock_wrlock (scn->elf->lock);
+  result = __libelf_set_rawdata_wrlock (scn);
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
+
+void
+internal_function
+__libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
+{
+  if (scn->rawdata.d.d_buf != NULL && scn->rawdata.d.d_size > 0)
+    {
+      Elf *elf = scn->elf;
+
+      /* Upgrade the lock to a write lock if necessary and check
+	 nobody else already did the work.  */
+      if (!wrlocked)
+	{
+	  rwlock_unlock (elf->lock);
+	  rwlock_wrlock (elf->lock);
+	  if (scn->data_list_rear != NULL)
+	    return;
+	}
+
+      /* Convert according to the version and the type.   */
+      convert_data (scn, __libelf_version, elf->class,
+		    (elf->class == ELFCLASS32
+		     || (offsetof (struct Elf, state.elf32.ehdr)
+			 == offsetof (struct Elf, state.elf64.ehdr))
+		     ? elf->state.elf32.ehdr->e_ident[EI_DATA]
+		     : elf->state.elf64.ehdr->e_ident[EI_DATA]),
+		    scn->rawdata.d.d_size, scn->rawdata.d.d_type);
+    }
+  else
+    {
+      /* This is an empty or NOBITS section.  There is no buffer but
+	 the size information etc is important.  */
+      scn->data_list.data.d = scn->rawdata.d;
+      scn->data_list.data.s = scn;
+    }
+
+  scn->data_list_rear = &scn->data_list;
+}
+
+Elf_Data *
+internal_function
+__elf_getdata_rdlock (Elf_Scn *scn, Elf_Data *data)
+{
+  Elf_Data *result = NULL;
+  Elf *elf;
+  int locked = 0;
+
+  if (scn == NULL)
+    return NULL;
+
+  if (unlikely (scn->elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* We will need this multiple times later on.  */
+  elf = scn->elf;
+
+  /* If `data' is not NULL this means we are not addressing the initial
+     data in the file.  But this also means this data is already read
+     (since otherwise it is not possible to have a valid `data' pointer)
+     and all the data structures are initialized as well.  In this case
+     we can simply walk the list of data records.  */
+  if (data != NULL)
+    {
+      Elf_Data_List *runp;
+
+      /* It is not possible that if DATA is not NULL the first entry is
+	 returned.  But this also means that there must be a first data
+	 entry.  */
+      if (scn->data_list_rear == NULL
+	  /* The section the reference data is for must match the section
+	     parameter.  */
+	  || unlikely (((Elf_Data_Scn *) data)->s != scn))
+	{
+	  __libelf_seterrno (ELF_E_DATA_MISMATCH);
+	  goto out;
+	}
+
+      /* We start searching with the first entry.  */
+      runp = &scn->data_list;
+
+      while (1)
+	{
+	  /* If `data' does not match any known record punt.  */
+	  if (runp == NULL)
+	    {
+	      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+	      goto out;
+	    }
+
+	  if (&runp->data.d == data)
+	    /* Found the entry.  */
+	    break;
+
+	  runp = runp->next;
+	}
+
+      /* Return the data for the next data record.  */
+      result = runp->next ? &runp->next->data.d : NULL;
+      goto out;
+    }
+
+  /* If the data for this section was not yet initialized do it now.  */
+  if (scn->data_read == 0)
+    {
+      /* We cannot acquire a write lock while we are holding a read
+         lock.  Therefore give up the read lock and then get the write
+         lock.  But this means that the data could meanwhile be
+         modified, therefore start the tests again.  */
+      rwlock_unlock (elf->lock);
+      rwlock_wrlock (elf->lock);
+      locked = 1;
+
+      /* Read the data from the file.  There is always a file (or
+	 memory region) associated with this descriptor since
+	 otherwise the `data_read' flag would be set.  */
+      if (scn->data_read == 0 && __libelf_set_rawdata_wrlock (scn) != 0)
+	/* Something went wrong.  The error value is already set.  */
+	goto out;
+    }
+
+  /* At this point we know the raw data is available.  But it might be
+     empty in case the section has size zero (for whatever reason).
+     Now create the converted data in case this is necessary.  */
+  if (scn->data_list_rear == NULL)
+    __libelf_set_data_list_rdlock (scn, locked);
+
+  /* Return the first data element in the list.  */
+  result = &scn->data_list.data.d;
+
+ out:
+  return result;
+}
+
+Elf_Data *
+elf_getdata (Elf_Scn *scn, Elf_Data *data)
+{
+  Elf_Data *result;
+
+  if (scn == NULL)
+    return NULL;
+
+  rwlock_rdlock (scn->elf->lock);
+  result = __elf_getdata_rdlock (scn, data);
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
+INTDEF(elf_getdata)
diff --git a/third_party/elfutils/libelf/elf_getdata_rawchunk.c b/third_party/elfutils/libelf/elf_getdata_rawchunk.c
new file mode 100644
index 0000000..31b2fe7
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_getdata_rawchunk.c
@@ -0,0 +1,187 @@
+/* Return converted data from raw chunk of ELF file.
+   Copyright (C) 2007, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+Elf_Data *
+elf_getdata_rawchunk (Elf *elf, off_t offset, size_t size, Elf_Type type)
+{
+  if (unlikely (elf == NULL))
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      /* No valid descriptor.  */
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  if (unlikely (offset < 0 || (uint64_t) offset > elf->maximum_size
+		|| elf->maximum_size - (uint64_t) offset < size))
+
+    {
+      /* Invalid request.  */
+      __libelf_seterrno (ELF_E_INVALID_OP);
+      return NULL;
+    }
+
+  if (type >= ELF_T_NUM)
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
+      return NULL;
+    }
+
+  /* Get the raw bytes from the file.  */
+  void *rawchunk;
+  int flags = 0;
+  Elf_Data *result = NULL;
+
+  rwlock_rdlock (elf->lock);
+
+  size_t align = __libelf_type_align (elf->class, type);
+  if (elf->map_address != NULL)
+    {
+    /* If the file is mmap'ed we can use it directly, if aligned for type.  */
+      char *rawdata = elf->map_address + elf->start_offset + offset;
+      if (ALLOW_UNALIGNED ||
+	  ((uintptr_t) rawdata & (align - 1)) == 0)
+	rawchunk = rawdata;
+      else
+	{
+	  /* We allocate the memory and memcpy it to get aligned data. */
+	  rawchunk = malloc (size);
+	  if (rawchunk == NULL)
+	    goto nomem;
+	  memcpy (rawchunk, rawdata, size);
+	  flags = ELF_F_MALLOCED;
+	}
+    }
+  else
+    {
+      /* We allocate the memory and read the data from the file.  */
+      rawchunk = malloc (size);
+      if (rawchunk == NULL)
+	{
+	nomem:
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  goto out;
+	}
+
+      /* Read the file content.  */
+      if (unlikely ((size_t) pread_retry (elf->fildes, rawchunk, size,
+					  elf->start_offset + offset)
+		    != size))
+	{
+	  /* Something went wrong.  */
+	  free (rawchunk);
+	  __libelf_seterrno (ELF_E_READ_ERROR);
+	  goto out;
+	}
+
+      flags = ELF_F_MALLOCED;
+    }
+
+  /* Copy and/or convert the data as needed for aligned native-order access.  */
+  void *buffer;
+  if (elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA)
+    {
+      if (((uintptr_t) rawchunk & (align - 1)) == 0)
+	/* No need to copy, we can use the raw data.  */
+	buffer = rawchunk;
+      else
+	{
+	  /* A malloc'd block is always sufficiently aligned.  */
+	  assert (flags == 0);
+
+	  buffer = malloc (size);
+	  if (unlikely (buffer == NULL))
+	    goto nomem;
+	  flags = ELF_F_MALLOCED;
+
+	  /* The copy will be appropriately aligned for direct access.  */
+	  memcpy (buffer, rawchunk, size);
+	}
+    }
+  else
+    {
+      if (flags)
+	buffer = rawchunk;
+      else
+	{
+	  buffer = malloc (size);
+	  if (unlikely (buffer == NULL))
+	    goto nomem;
+	  flags = ELF_F_MALLOCED;
+	}
+
+      /* Call the conversion function.  */
+      (*__elf_xfctstom[LIBELF_EV_IDX][LIBELF_EV_IDX][elf->class - 1][type])
+	(buffer, rawchunk, size, 0);
+    }
+
+  /* Allocate the dummy container to point at this buffer.  */
+  Elf_Data_Chunk *chunk = calloc (1, sizeof *chunk);
+  if (chunk == NULL)
+    {
+      if (flags)
+	free (buffer);
+      goto nomem;
+    }
+
+  chunk->dummy_scn.elf = elf;
+  chunk->dummy_scn.flags = flags;
+  chunk->data.s = &chunk->dummy_scn;
+  chunk->data.d.d_buf = buffer;
+  chunk->data.d.d_size = size;
+  chunk->data.d.d_type = type;
+  chunk->data.d.d_align = align;
+  chunk->data.d.d_version = __libelf_version;
+
+  rwlock_unlock (elf->lock);
+  rwlock_wrlock (elf->lock);
+
+  chunk->next = elf->state.elf.rawchunks;
+  elf->state.elf.rawchunks = chunk;
+  result = &chunk->data.d;
+
+ out:
+  rwlock_unlock (elf->lock);
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_getident.c b/third_party/elfutils/libelf/elf_getident.c
new file mode 100644
index 0000000..5abf8c9
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_getident.c
@@ -0,0 +1,61 @@
+/* Retrieve file identification data.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+char *
+elf_getident (Elf *elf, size_t *ptr)
+{
+  /* In case this is no ELF file, the handle is invalid and we return
+     NULL.  */
+  if (elf == NULL || elf->kind != ELF_K_ELF)
+    {
+      if (ptr != NULL)
+	*ptr = 0;
+      return NULL;
+    }
+
+  /* We already read the ELF header.  Return a pointer to it and store
+     the length in *PTR.  */
+  if (ptr != NULL)
+    *ptr = EI_NIDENT;
+
+  return (char *) (elf->class == ELFCLASS32
+		   || (offsetof (struct Elf, state.elf32.ehdr)
+		       == offsetof (struct Elf, state.elf64.ehdr))
+		   ? elf->state.elf32.ehdr->e_ident
+		   : elf->state.elf64.ehdr->e_ident);
+}
diff --git a/third_party/elfutils/libelf/elf_getphdrnum.c b/third_party/elfutils/libelf/elf_getphdrnum.c
new file mode 100644
index 0000000..f91cba9
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_getphdrnum.c
@@ -0,0 +1,142 @@
+/* Return number of program headers in the ELF file.
+   Copyright (C) 2010, 2014, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+int
+internal_function
+__elf_getphdrnum_rdlock (Elf *elf, size_t *dst)
+{
+ if (unlikely (elf->state.elf64.ehdr == NULL))
+   {
+     /* Maybe no ELF header was created yet.  */
+     __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+     return -1;
+   }
+
+ *dst = (elf->class == ELFCLASS32
+	 ? elf->state.elf32.ehdr->e_phnum
+	 : elf->state.elf64.ehdr->e_phnum);
+
+ if (*dst == PN_XNUM)
+   {
+     const Elf_ScnList *const scns = (elf->class == ELFCLASS32
+				      ? &elf->state.elf32.scns
+				      : &elf->state.elf64.scns);
+
+     /* If there are no section headers, perhaps this is really just 65536
+	written without PN_XNUM support.  Either that or it's bad data.  */
+
+     if (elf->class == ELFCLASS32)
+       {
+	 if (likely (scns->cnt > 0
+		     && elf->state.elf32.scns.data[0].shdr.e32 != NULL))
+	   *dst = scns->data[0].shdr.e32->sh_info;
+       }
+     else
+       {
+	 if (likely (scns->cnt > 0
+		     && elf->state.elf64.scns.data[0].shdr.e64 != NULL))
+	   *dst = scns->data[0].shdr.e64->sh_info;
+       }
+   }
+
+ return 0;
+}
+
+int
+internal_function
+__elf_getphdrnum_chk_rdlock (Elf *elf, size_t *dst)
+{
+  int result = __elf_getphdrnum_rdlock (elf, dst);
+
+  /* If the phdrs haven't been created or read in yet then do some
+     sanity checking to make sure phnum and phoff are consistent.  */
+  if (elf->state.elf.phdr == NULL)
+    {
+      Elf64_Off off = (elf->class == ELFCLASS32
+		       ? elf->state.elf32.ehdr->e_phoff
+		       : elf->state.elf64.ehdr->e_phoff);
+      if (unlikely (off == 0))
+	{
+	  *dst = 0;
+	  return result;
+	}
+
+      if (unlikely (off >= elf->maximum_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  return -1;
+	}
+
+      /* Check for too many sections.  */
+      size_t phdr_size = (elf->class == ELFCLASS32
+			  ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr));
+      if (unlikely (*dst > SIZE_MAX / phdr_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  return -1;
+	}
+
+      /* Truncated file?  Don't return more than can be indexed.  */
+      if (unlikely (elf->maximum_size - off < *dst * phdr_size))
+	*dst = (elf->maximum_size - off) / phdr_size;
+    }
+
+  return result;
+}
+
+int
+elf_getphdrnum (Elf *elf, size_t *dst)
+{
+  int result;
+
+  if (elf == NULL)
+    return -1;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1;
+    }
+
+  rwlock_rdlock (elf->lock);
+  result = __elf_getphdrnum_chk_rdlock (elf, dst);
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_getscn.c b/third_party/elfutils/libelf/elf_getscn.c
new file mode 100644
index 0000000..9f7213b
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_getscn.c
@@ -0,0 +1,87 @@
+/* Get section at specific index.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+elf_getscn (Elf *elf, size_t idx)
+{
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_rdlock (elf->lock);
+
+  Elf_Scn *result = NULL;
+
+  /* Find the section in the list.  */
+  Elf_ScnList *runp = (elf->class == ELFCLASS32
+		       || (offsetof (struct Elf, state.elf32.scns)
+			   == offsetof (struct Elf, state.elf64.scns))
+		       ? &elf->state.elf32.scns : &elf->state.elf64.scns);
+  while (1)
+    {
+      if (idx < runp->max)
+	{
+	  if (idx < runp->cnt)
+	    result = &runp->data[idx];
+	  else
+	    __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  break;
+	}
+
+      idx -= runp->max;
+
+      runp = runp->next;
+      if (runp == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  break;
+	}
+    }
+
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elf_getscn)
diff --git a/third_party/elfutils/libelf/elf_getshdrnum.c b/third_party/elfutils/libelf/elf_getshdrnum.c
new file mode 100644
index 0000000..18e5d14
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_getshdrnum.c
@@ -0,0 +1,87 @@
+/* Return number of sections in the ELF file.
+   Copyright (C) 2002, 2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+int
+internal_function
+__elf_getshdrnum_rdlock (Elf *elf, size_t *dst)
+{
+  int result = 0;
+  int idx;
+
+  if (elf == NULL)
+    return -1;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1;
+    }
+
+  idx = elf->state.elf.scns_last->cnt;
+  if (idx != 0
+      || (elf->state.elf.scns_last
+	  != (elf->class == ELFCLASS32
+	      || (offsetof (Elf, state.elf32.scns)
+		  == offsetof (Elf, state.elf64.scns))
+	      ? &elf->state.elf32.scns : &elf->state.elf64.scns)))
+    /* There is at least one section.  */
+    *dst = 1 + elf->state.elf.scns_last->data[idx - 1].index;
+  else
+    *dst = 0;
+
+  return result;
+}
+
+int
+elf_getshdrnum (Elf *elf, size_t *dst)
+{
+  int result;
+
+  if (elf == NULL)
+    return -1;
+
+  rwlock_rdlock (elf->lock);
+  result = __elf_getshdrnum_rdlock (elf, dst);
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+/* Alias for the deprecated name.  */
+strong_alias (elf_getshdrnum, elf_getshnum)
diff --git a/third_party/elfutils/libelf/elf_getshdrstrndx.c b/third_party/elfutils/libelf/elf_getshdrstrndx.c
new file mode 100644
index 0000000..ad884fd
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_getshdrstrndx.c
@@ -0,0 +1,235 @@
+/* Return section index of section header string table.
+   Copyright (C) 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <gelf.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+
+int
+elf_getshdrstrndx (Elf *elf, size_t *dst)
+{
+  int result = 0;
+
+  if (elf == NULL)
+    return -1;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1;
+    }
+
+  rwlock_rdlock (elf->lock);
+
+  /* We rely here on the fact that the `elf' element is a common prefix
+     of `elf32' and `elf64'.  */
+  assert (offsetof (struct Elf, state.elf.ehdr)
+	  == offsetof (struct Elf, state.elf32.ehdr));
+  assert (sizeof (elf->state.elf.ehdr)
+	  == sizeof (elf->state.elf32.ehdr));
+  assert (offsetof (struct Elf, state.elf.ehdr)
+	  == offsetof (struct Elf, state.elf64.ehdr));
+  assert (sizeof (elf->state.elf.ehdr)
+	  == sizeof (elf->state.elf64.ehdr));
+
+  if (unlikely (elf->state.elf.ehdr == NULL))
+    {
+      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+      result = -1;
+    }
+  else
+    {
+      Elf32_Word num;
+
+      num = (elf->class == ELFCLASS32
+	     ? elf->state.elf32.ehdr->e_shstrndx
+	     : elf->state.elf64.ehdr->e_shstrndx);
+
+      /* Determine whether the index is too big to fit in the ELF
+	 header.  */
+      if (unlikely (num == SHN_XINDEX))
+	{
+	  /* Yes.  Search the zeroth section header.  */
+	  if (elf->class == ELFCLASS32)
+	    {
+	      size_t offset;
+	      if (unlikely (elf->state.elf32.scns.cnt == 0))
+		{
+		  /* Cannot use SHN_XINDEX without section headers.  */
+		  __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+		  result = -1;
+		  goto out;
+		}
+
+	      if (elf->state.elf32.scns.data[0].shdr.e32 != NULL)
+		{
+		  num = elf->state.elf32.scns.data[0].shdr.e32->sh_link;
+		  goto success;
+		}
+
+	      offset = elf->state.elf32.ehdr->e_shoff;
+
+	      if (elf->map_address != NULL
+		  && elf->state.elf32.ehdr->e_ident[EI_DATA] == MY_ELFDATA
+		  && (ALLOW_UNALIGNED
+		      || (((size_t) ((char *) elf->map_address
+			   + elf->start_offset + offset))
+			  & (__alignof__ (Elf32_Shdr) - 1)) == 0))
+		{
+		  /* First see whether the information in the ELF header is
+		     valid and it does not ask for too much.  */
+		  if (unlikely (elf->maximum_size - offset
+				< sizeof (Elf32_Shdr)))
+		    {
+		      /* Something is wrong.  */
+		      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+		      result = -1;
+		      goto out;
+		    }
+
+		  /* We can directly access the memory.  */
+		  num = ((Elf32_Shdr *) (elf->map_address + elf->start_offset
+					 + offset))->sh_link;
+		}
+	      else
+		{
+		  /* We avoid reading in all the section headers.  Just read
+		     the first one.  */
+		  Elf32_Shdr shdr_mem;
+		  ssize_t r;
+
+		  if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem,
+						  sizeof (Elf32_Shdr), offset))
+				!= sizeof (Elf32_Shdr)))
+		    {
+		      /* We must be able to read this ELF section header.  */
+		      if (r < 0)
+			__libelf_seterrno (ELF_E_INVALID_FILE);
+		      else
+			__libelf_seterrno (ELF_E_INVALID_ELF);
+		      result = -1;
+		      goto out;
+		    }
+
+		  if (elf->state.elf32.ehdr->e_ident[EI_DATA] != MY_ELFDATA)
+		    CONVERT (shdr_mem.sh_link);
+		  num = shdr_mem.sh_link;
+		}
+	    }
+	  else
+	    {
+	      if (unlikely (elf->state.elf64.scns.cnt == 0))
+		{
+		  /* Cannot use SHN_XINDEX without section headers.  */
+		  __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+		  result = -1;
+		  goto out;
+		}
+
+	      if (elf->state.elf64.scns.data[0].shdr.e64 != NULL)
+		{
+		  num = elf->state.elf64.scns.data[0].shdr.e64->sh_link;
+		  goto success;
+		}
+
+	      size_t offset = elf->state.elf64.ehdr->e_shoff;
+
+	      if (elf->map_address != NULL
+		  && elf->state.elf64.ehdr->e_ident[EI_DATA] == MY_ELFDATA
+		  && (ALLOW_UNALIGNED
+		      || (((size_t) ((char *) elf->map_address
+			   + elf->start_offset + offset))
+			  & (__alignof__ (Elf64_Shdr) - 1)) == 0))
+		{
+		  /* First see whether the information in the ELF header is
+		     valid and it does not ask for too much.  */
+		  if (unlikely (elf->maximum_size - offset
+				< sizeof (Elf64_Shdr)))
+		    {
+		      /* Something is wrong.  */
+		      __libelf_seterrno (ELF_E_INVALID_SECTION_HEADER);
+		      result = -1;
+		      goto out;
+		    }
+
+		  /* We can directly access the memory.  */
+		  num = ((Elf64_Shdr *) (elf->map_address + elf->start_offset
+					 + offset))->sh_link;
+		}
+	      else
+		{
+		  /* We avoid reading in all the section headers.  Just read
+		     the first one.  */
+		  Elf64_Shdr shdr_mem;
+		  ssize_t r;
+
+		  if (unlikely ((r = pread_retry (elf->fildes, &shdr_mem,
+						  sizeof (Elf64_Shdr), offset))
+				!= sizeof (Elf64_Shdr)))
+		    {
+		      /* We must be able to read this ELF section header.  */
+		      if (r < 0)
+			__libelf_seterrno (ELF_E_INVALID_FILE);
+		      else
+			__libelf_seterrno (ELF_E_INVALID_ELF);
+		      result = -1;
+		      goto out;
+		    }
+
+		  if (elf->state.elf64.ehdr->e_ident[EI_DATA] != MY_ELFDATA)
+		    CONVERT (shdr_mem.sh_link);
+		  num = shdr_mem.sh_link;
+		}
+	    }
+	}
+
+      /* Store the result.  */
+    success:
+      *dst = num;
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elf_getshdrstrndx)
+/* Alias for the deprecated name.  */
+strong_alias (elf_getshdrstrndx, elf_getshstrndx)
diff --git a/third_party/elfutils/libelf/elf_gnu_hash.c b/third_party/elfutils/libelf/elf_gnu_hash.c
new file mode 100644
index 0000000..5a1b852
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_gnu_hash.c
@@ -0,0 +1,46 @@
+/* GNU-style Hash function used in ELF implementations.
+   Copyright (C) 2006, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelfP.h>
+
+/* Get the implementation.  */
+#include <dl-hash.h>
+
+unsigned long int
+elf_gnu_hash (const char *string)
+{
+  uint_fast32_t h = 5381;
+  for (unsigned char c = *string; c != '\0'; c = *++string)
+    h = h * 33 + c;
+  return h & 0xffffffff;
+}
diff --git a/third_party/elfutils/libelf/elf_hash.c b/third_party/elfutils/libelf/elf_hash.c
new file mode 100644
index 0000000..345697e
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_hash.c
@@ -0,0 +1,44 @@
+/* Hash function used in ELF implementations.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelfP.h>
+
+/* Get the implementation.  */
+#include <dl-hash.h>
+
+unsigned long int
+elf_hash (const char *string)
+{
+  return _dl_elf_hash (string);
+}
+INTDEF(elf_hash)
diff --git a/third_party/elfutils/libelf/elf_kind.c b/third_party/elfutils/libelf/elf_kind.c
new file mode 100644
index 0000000..0fb3f0c
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_kind.c
@@ -0,0 +1,44 @@
+/* Return the kind of file associated with the descriptor.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Kind
+elf_kind (Elf *elf)
+{
+  return elf == NULL ? ELF_K_NONE : elf->kind;
+}
diff --git a/third_party/elfutils/libelf/elf_memory.c b/third_party/elfutils/libelf/elf_memory.c
new file mode 100644
index 0000000..a47f1d2
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_memory.c
@@ -0,0 +1,50 @@
+/* Create descriptor for memory region.
+   Copyright (C) 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf *
+elf_memory (char *image, size_t size)
+{
+  if (image == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return NULL;
+    }
+
+  return __libelf_read_mmaped_file (-1, image, 0, size, ELF_C_READ, NULL);
+}
diff --git a/third_party/elfutils/libelf/elf_ndxscn.c b/third_party/elfutils/libelf/elf_ndxscn.c
new file mode 100644
index 0000000..488c4e5
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_ndxscn.c
@@ -0,0 +1,47 @@
+/* Get index of section.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+size_t
+elf_ndxscn (Elf_Scn *scn)
+{
+  if (scn == NULL)
+    return SHN_UNDEF;
+
+  return scn->index;
+}
diff --git a/third_party/elfutils/libelf/elf_newdata.c b/third_party/elfutils/libelf/elf_newdata.c
new file mode 100644
index 0000000..f6609a8
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_newdata.c
@@ -0,0 +1,136 @@
+/* Create new, empty section data.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+elf_newdata (Elf_Scn *scn)
+{
+  Elf_Data_List *result = NULL;
+
+  if (scn == NULL)
+    return NULL;
+
+  if (unlikely (scn->index == 0))
+    {
+      /* It is not allowed to add something to the 0th section.  */
+      __libelf_seterrno (ELF_E_NOT_NUL_SECTION);
+      return NULL;
+    }
+
+  if (scn->elf->class == ELFCLASS32
+      || (offsetof (struct Elf, state.elf32.ehdr)
+	  == offsetof (struct Elf, state.elf64.ehdr))
+      ? scn->elf->state.elf32.ehdr == NULL
+      : scn->elf->state.elf64.ehdr == NULL)
+    {
+      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+      return NULL;
+    }
+
+  rwlock_wrlock (scn->elf->lock);
+
+  /* data_read is set when data has been read from the ELF image or
+     when a new section has been created by elf_newscn.  If data has
+     been read from the ELF image, then rawdata_base will point to raw
+     data.  If data_read has been set by elf_newscn, then rawdata_base
+     will be NULL.  data_list_rear will be set by elf_getdata if the
+     data has been converted, or by this function, elf_newdata, when
+     new data has been added.
+
+     Currently elf_getdata and elf_update rely on the fact that when
+     data_list_read is not NULL all they have to do is walk the data
+     list. They will ignore any (unread) raw data in that case.
+
+     So we need to make sure the data list is setup if there is
+     already data available.  */
+  if (scn->data_read
+      && scn->rawdata_base != NULL
+      && scn->data_list_rear == NULL)
+    __libelf_set_data_list_rdlock (scn, 1);
+
+  if (scn->data_read && scn->data_list_rear == NULL)
+    {
+      /* This means the section was created by the user and this is the
+	 first data.  */
+      result = &scn->data_list;
+      result->flags = ELF_F_DIRTY;
+    }
+  else
+    {
+      /* It would be more efficient to create new data without
+	 reading/converting the data from the file.  But then we
+	 have to remember this.  Currently elf_getdata and
+	 elf_update rely on the fact that they don't have to
+	 load/convert any data if data_list_rear is set.  */
+      if (scn->data_read == 0)
+	{
+	  if (__libelf_set_rawdata_wrlock (scn) != 0)
+	    /* Something went wrong.  The error value is already set.  */
+	    goto out;
+	  __libelf_set_data_list_rdlock (scn, 1);
+	}
+
+      /* Create a new, empty data descriptor.  */
+      result = (Elf_Data_List *) calloc (1, sizeof (Elf_Data_List));
+      if (result == NULL)
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  goto out;
+	}
+
+      result->flags = ELF_F_DIRTY | ELF_F_MALLOCED;
+    }
+
+  /* Set the predefined values.  */
+  result->data.d.d_version = __libelf_version;
+
+  result->data.s = scn;
+
+  /* Add to the end of the list.  */
+  if (scn->data_list_rear != NULL)
+    scn->data_list_rear->next = result;
+
+  scn->data_list_rear = result;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  /* Please note that the following is thread safe and is also defined
+     for RESULT == NULL since it still return NULL.  */
+  return &result->data.d;
+}
diff --git a/third_party/elfutils/libelf/elf_newscn.c b/third_party/elfutils/libelf/elf_newscn.c
new file mode 100644
index 0000000..d15a642
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_newscn.c
@@ -0,0 +1,162 @@
+/* Append new section.
+   Copyright (C) 1998,1999,2000,2001,2002,2005,2009,2014,2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+elf_newscn (Elf *elf)
+{
+  Elf_Scn *result = NULL;
+  bool first = false;
+
+  if (elf == NULL)
+    return NULL;
+
+  /* We rely on the prefix of the `elf', `elf32', and `elf64' element
+     being the same.  */
+  assert (offsetof (Elf, state.elf.scns_last)
+	  == offsetof (Elf, state.elf32.scns_last));
+  assert (offsetof (Elf, state.elf.scns_last)
+	  == offsetof (Elf, state.elf64.scns_last));
+  assert (offsetof (Elf, state.elf32.scns)
+	  == offsetof (Elf, state.elf64.scns));
+
+  rwlock_wrlock (elf->lock);
+
+ again:
+  if (elf->state.elf.scns_last->cnt < elf->state.elf.scns_last->max)
+    {
+      result = &elf->state.elf.scns_last->data[elf->state.elf.scns_last->cnt];
+
+      if (++elf->state.elf.scns_last->cnt == 1
+	  && (elf->state.elf.scns_last
+	      == (elf->class == ELFCLASS32
+		  || (offsetof (Elf, state.elf32.scns)
+		      == offsetof (Elf, state.elf64.scns))
+		  ? &elf->state.elf32.scns : &elf->state.elf64.scns)))
+	/* This is zeroth section.  */
+	first = true;
+      else
+	{
+	  assert (elf->state.elf.scns_last->cnt > 1);
+	  result->index = result[-1].index + 1;
+	}
+    }
+  else
+    {
+      /* We must allocate a new element.  */
+      Elf_ScnList *newp = NULL;
+
+      assert (elf->state.elf.scnincr > 0);
+
+      if (
+#if SIZE_MAX <= 4294967295U
+	  likely (elf->state.elf.scnincr
+		  < SIZE_MAX / 2 / sizeof (Elf_Scn) - sizeof (Elf_ScnList))
+#else
+	  1
+#endif
+	  )
+      newp = (Elf_ScnList *) calloc (sizeof (Elf_ScnList)
+				     + ((elf->state.elf.scnincr *= 2)
+					* sizeof (Elf_Scn)), 1);
+      if (newp == NULL)
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  goto out;
+	}
+
+      result = &newp->data[0];
+
+      /* One section used.  */
+      ++newp->cnt;
+
+      /* This is the number of sections we allocated.  */
+      newp->max = elf->state.elf.scnincr;
+
+      /* Remember the index for the first section in this block.  */
+      newp->data[0].index
+	= 1 + elf->state.elf.scns_last->data[elf->state.elf.scns_last->max - 1].index;
+
+      /* Enqueue the new list element.  */
+      elf->state.elf.scns_last = elf->state.elf.scns_last->next = newp;
+    }
+
+  /* Create a section header for this section.  */
+  if (elf->class == ELFCLASS32)
+    {
+      result->shdr.e32 = (Elf32_Shdr *) calloc (1, sizeof (Elf32_Shdr));
+      if (result->shdr.e32 == NULL)
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  goto out;
+	}
+    }
+  else
+    {
+      result->shdr.e64 = (Elf64_Shdr *) calloc (1, sizeof (Elf64_Shdr));
+      if (result->shdr.e64 == NULL)
+	{
+	  __libelf_seterrno (ELF_E_NOMEM);
+	  goto out;
+	}
+    }
+
+  result->elf = elf;
+  result->shdr_flags = ELF_F_DIRTY | ELF_F_MALLOCED;
+  result->list = elf->state.elf.scns_last;
+
+  /* Initialize the data part.  */
+  result->data_read = 1;
+  if (unlikely (first))
+    {
+      /* For the first section we mark the data as already available.  */
+      //result->data_list_rear = &result->data_list;
+      first = false;
+      goto again;
+    }
+
+  result->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_next.c b/third_party/elfutils/libelf/elf_next.c
new file mode 100644
index 0000000..6edafd2
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_next.c
@@ -0,0 +1,72 @@
+/* Advance in archive to next element.
+   Copyright (C) 1998-2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Cmd
+elf_next (Elf *elf)
+{
+  Elf *parent;
+  Elf_Cmd ret;
+
+  /* Be gratious, the specs demand it.  */
+  if (elf == NULL || elf->parent == NULL)
+    return ELF_C_NULL;
+
+  /* We can be sure the parent is an archive.  */
+  parent = elf->parent;
+  assert (parent->kind == ELF_K_AR);
+
+  rwlock_wrlock (parent->lock);
+
+  /* Now advance the offset.  */
+  parent->state.ar.offset += (sizeof (struct ar_hdr)
+			      + ((parent->state.ar.elf_ar_hdr.ar_size + 1)
+				 & ~1l));
+
+  /* Get the next archive header.  */
+  ret = __libelf_next_arhdr_wrlock (parent) != 0 ? ELF_C_NULL : elf->cmd;
+
+  /* If necessary, mark the archive header as unusable.  */
+  if (ret == ELF_C_NULL)
+    parent->state.ar.elf_ar_hdr.ar_name = NULL;
+
+  rwlock_unlock (parent->lock);
+
+  return ret;
+}
diff --git a/third_party/elfutils/libelf/elf_nextscn.c b/third_party/elfutils/libelf/elf_nextscn.c
new file mode 100644
index 0000000..d2f3e7c
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_nextscn.c
@@ -0,0 +1,83 @@
+/* Get next section.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+elf_nextscn (Elf *elf, Elf_Scn *scn)
+{
+  Elf_ScnList *list;
+  Elf_Scn *result = NULL;
+
+  if (elf == NULL)
+    return NULL;
+
+  rwlock_rdlock (elf->lock);
+
+  if (scn == NULL)
+    {
+      /* If no section handle is given return the first (not 0th) section.
+	 Set scn to the 0th section and perform nextscn.  */
+      if (elf->class == ELFCLASS32
+	   || (offsetof (Elf, state.elf32.scns)
+	       == offsetof (Elf, state.elf64.scns)))
+	list = &elf->state.elf32.scns;
+      else
+	list = &elf->state.elf64.scns;
+
+      scn = &list->data[0];
+    }
+  else
+    list = scn->list;
+
+  if (scn + 1 < &list->data[list->cnt])
+    result = scn + 1;
+  else if (scn + 1 == &list->data[list->max]
+	   && (list = list->next) != NULL)
+    {
+      /* If there is another element in the section list it must
+         have at least one entry.  */
+      assert (list->cnt > 0);
+      result = &list->data[0];
+    }
+
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elf_nextscn)
diff --git a/third_party/elfutils/libelf/elf_rand.c b/third_party/elfutils/libelf/elf_rand.c
new file mode 100644
index 0000000..f1850e7
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_rand.c
@@ -0,0 +1,63 @@
+/* Select specific element in archive.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+size_t
+elf_rand (Elf *elf, size_t offset)
+{
+  /* Be gratious, the specs demand it.  */
+  if (elf == NULL || elf->kind != ELF_K_AR)
+    return 0;
+
+  rwlock_wrlock (elf->lock);
+
+  /* Save the old offset and set the offset.  */
+  elf->state.ar.offset = elf->start_offset + offset;
+
+  /* Get the next archive header.  */
+  if (__libelf_next_arhdr_wrlock (elf) != 0)
+    {
+      /* Mark the archive header as unusable.  */
+      elf->state.ar.elf_ar_hdr.ar_name = NULL;
+      return 0;
+    }
+
+  rwlock_unlock (elf->lock);
+
+  return offset;
+}
diff --git a/third_party/elfutils/libelf/elf_rawdata.c b/third_party/elfutils/libelf/elf_rawdata.c
new file mode 100644
index 0000000..db28f5d
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_rawdata.c
@@ -0,0 +1,76 @@
+/* Return raw section content.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+elf_rawdata (Elf_Scn *scn, Elf_Data *data)
+{
+  if (scn == NULL || scn->elf->kind != ELF_K_ELF)
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* If `data' is not NULL this means we are not addressing the initial
+     data in the file.  But this also means this data is already read
+     (since otherwise it is not possible to have a valid `data' pointer)
+     and all the data structures are initialized as well.  In this case
+     we can simply walk the list of data records.  */
+  if (data != NULL
+      || (scn->data_read != 0 && (scn->flags & ELF_F_FILEDATA) == 0))
+    {
+      /* We don't allow accessing any but the data read from the file
+	 as raw.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return NULL;
+    }
+
+  /* If the data for this section was not yet initialized do it now.  */
+  if (scn->data_read == 0)
+    {
+      /* First thing we do is to read the data from the file.  There is
+	 always a file (or memory region) associated with this descriptor
+	 since otherwise the `data_read' flag would be set.  */
+      if (__libelf_set_rawdata (scn) != 0)
+	/* Something went wrong.  The error value is already set.  */
+	return NULL;
+    }
+
+  /* Return the first data element in the list.  */
+  return &scn->rawdata.d;
+}
+INTDEF(elf_rawdata)
diff --git a/third_party/elfutils/libelf/elf_rawfile.c b/third_party/elfutils/libelf/elf_rawfile.c
new file mode 100644
index 0000000..b3837f4
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_rawfile.c
@@ -0,0 +1,67 @@
+/* Retrieve uninterpreted file contents.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+char *
+elf_rawfile (Elf *elf, size_t *ptr)
+{
+  char *result;
+
+  if (elf == NULL)
+    {
+      /* No valid descriptor.  */
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+    error_out:
+      if (ptr != NULL)
+	*ptr = 0;
+      return NULL;
+    }
+
+  /* If the file is not mmap'ed and not previously loaded, do it now.  */
+  if (elf->map_address == NULL && __libelf_readall (elf) == NULL)
+    goto error_out;
+
+  rwlock_rdlock (elf->lock);
+  if (ptr != NULL)
+    *ptr = elf->maximum_size;
+
+  result = (char *) elf->map_address + elf->start_offset;
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/elf_readall.c b/third_party/elfutils/libelf/elf_readall.c
new file mode 100644
index 0000000..384d251
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_readall.c
@@ -0,0 +1,152 @@
+/* Read all of the file associated with the descriptor.
+   Copyright (C) 1998-2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <system.h>
+#include "libelfP.h"
+#include "common.h"
+
+
+static void
+set_address (Elf *elf, size_t offset)
+{
+  if (elf->kind == ELF_K_AR)
+    {
+      Elf *child = elf->state.ar.children;
+
+      while (child != NULL)
+	{
+	  if (child->map_address == NULL)
+	    {
+	      child->map_address = elf->map_address;
+	      child->start_offset -= offset;
+	      if (child->kind == ELF_K_AR)
+		child->state.ar.offset -= offset;
+
+	      set_address (child, offset);
+	    }
+
+	  child = child->next;
+	}
+    }
+}
+
+
+char *
+internal_function
+__libelf_readall (Elf *elf)
+{
+  /* Get the file.  */
+  rwlock_wrlock (elf->lock);
+
+  if (elf->map_address == NULL && unlikely (elf->fildes == -1))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      rwlock_unlock (elf->lock);
+      return NULL;
+    }
+
+  /* If the file is not mmap'ed and not previously loaded, do it now.  */
+  if (elf->map_address == NULL)
+    {
+      char *mem = NULL;
+
+      /* If this is an archive and we have derived descriptors get the
+	 locks for all of them.  */
+      libelf_acquire_all (elf);
+
+      if (elf->maximum_size == ~((size_t) 0))
+	{
+	  /* We don't yet know how large the file is.   Determine that now.  */
+	  struct stat st;
+
+	  if (fstat (elf->fildes, &st) < 0)
+	    goto read_error;
+
+	  if (sizeof (size_t) >= sizeof (st.st_size)
+	      || st.st_size <= ~((size_t) 0))
+	    elf->maximum_size = (size_t) st.st_size;
+	  else
+	    {
+	      errno = EOVERFLOW;
+	      goto read_error;
+	    }
+	}
+
+      /* Allocate all the memory we need.  */
+      mem = (char *) malloc (elf->maximum_size);
+      if (mem != NULL)
+	{
+	  /* Read the file content.  */
+	  if (unlikely ((size_t) pread_retry (elf->fildes, mem,
+					      elf->maximum_size,
+					      elf->start_offset)
+			!= elf->maximum_size))
+	    {
+	      /* Something went wrong.  */
+	    read_error:
+	      __libelf_seterrno (ELF_E_READ_ERROR);
+	      free (mem);
+	    }
+	  else
+	    {
+	      /* Remember the address.  */
+	      elf->map_address = mem;
+
+	      /* Also remember that we allocated the memory.  */
+	      elf->flags |= ELF_F_MALLOCED;
+
+	      /* Propagate the information down to all children and
+		 their children.  */
+	      set_address (elf, elf->start_offset);
+
+	      /* Correct the own offsets.  */
+	      if (elf->kind == ELF_K_AR)
+		elf->state.ar.offset -= elf->start_offset;
+	      elf->start_offset = 0;
+	    }
+	}
+      else
+	__libelf_seterrno (ELF_E_NOMEM);
+
+      /* Free the locks on the children.  */
+      libelf_release_all (elf);
+    }
+
+  rwlock_unlock (elf->lock);
+
+  return (char *) elf->map_address;
+}
diff --git a/third_party/elfutils/libelf/elf_scnshndx.c b/third_party/elfutils/libelf/elf_scnshndx.c
new file mode 100644
index 0000000..5b783fa
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_scnshndx.c
@@ -0,0 +1,50 @@
+/* Get the section index of the extended section index table.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libelfP.h"
+
+
+int
+elf_scnshndx (Elf_Scn *scn)
+{
+  if (unlikely (scn->shndx_index == 0))
+    {
+      /* We do not have the value yet.  We get it as a side effect of
+	 getting a section header.  */
+      GElf_Shdr shdr_mem;
+      (void) INTUSE(gelf_getshdr) (scn, &shdr_mem);
+    }
+
+  return scn->shndx_index;
+}
+INTDEF(elf_scnshndx)
diff --git a/third_party/elfutils/libelf/elf_strptr.c b/third_party/elfutils/libelf/elf_strptr.c
new file mode 100644
index 0000000..e72a3a3
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_strptr.c
@@ -0,0 +1,240 @@
+/* Return string pointer from string section.
+   Copyright (C) 1998-2002, 2004, 2008, 2009, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+static void *
+get_zdata (Elf_Scn *strscn)
+{
+  size_t zsize, zalign;
+  void *zdata = __libelf_decompress_elf (strscn, &zsize, &zalign);
+  if (zdata == NULL)
+    return NULL;
+
+  strscn->zdata_base = zdata;
+  strscn->zdata_size = zsize;
+  strscn->zdata_align = zalign;
+
+  return zdata;
+}
+
+static bool validate_str (const char *str, size_t from, size_t to)
+{
+#if HAVE_DECL_MEMRCHR
+  return memrchr (&str[from], '\0', to - from) != NULL;
+#else
+  do {
+    if (to <= from)
+      return false;
+
+    to--;
+  } while (str[to]);
+
+  return true;
+#endif
+}
+
+char *
+elf_strptr (Elf *elf, size_t idx, size_t offset)
+{
+  if (elf == NULL)
+    return NULL;
+
+  if (elf->kind != ELF_K_ELF)
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_rdlock (elf->lock);
+
+  char *result = NULL;
+  Elf_Scn *strscn;
+
+  /* Find the section in the list.  */
+  Elf_ScnList *runp = (elf->class == ELFCLASS32
+		       || (offsetof (struct Elf, state.elf32.scns)
+			   == offsetof (struct Elf, state.elf64.scns))
+		       ? &elf->state.elf32.scns : &elf->state.elf64.scns);
+  while (1)
+    {
+      if (idx < runp->max)
+	{
+	  if (idx < runp->cnt)
+	    strscn = &runp->data[idx];
+	  else
+	    {
+	      __libelf_seterrno (ELF_E_INVALID_INDEX);
+	      goto out;
+	    }
+	  break;
+	}
+
+      idx -= runp->max;
+
+      runp = runp->next;
+      if (runp == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+    }
+
+  size_t sh_size = 0;
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Shdr *shdr = strscn->shdr.e32 ?: __elf32_getshdr_rdlock (strscn);
+      if (unlikely (shdr->sh_type != SHT_STRTAB))
+	{
+	  /* This is no string section.  */
+	  __libelf_seterrno (ELF_E_INVALID_SECTION);
+	  goto out;
+	}
+
+      if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+	sh_size = shdr->sh_size;
+      else
+	{
+	  if (strscn->zdata_base == NULL && get_zdata (strscn) == NULL)
+	    goto out;
+	  sh_size = strscn->zdata_size;
+	}
+
+      if (unlikely (offset >= sh_size))
+	{
+	  /* The given offset is too big, it is beyond this section.  */
+	  __libelf_seterrno (ELF_E_OFFSET_RANGE);
+	  goto out;
+	}
+    }
+  else
+    {
+      Elf64_Shdr *shdr = strscn->shdr.e64 ?: __elf64_getshdr_rdlock (strscn);
+      if (unlikely (shdr->sh_type != SHT_STRTAB))
+	{
+	  /* This is no string section.  */
+	  __libelf_seterrno (ELF_E_INVALID_SECTION);
+	  goto out;
+	}
+
+      if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+	sh_size = shdr->sh_size;
+      else
+	{
+	  if (strscn->zdata_base == NULL && get_zdata (strscn) == NULL)
+	    goto out;
+	  sh_size = strscn->zdata_size;
+	}
+
+      if (unlikely (offset >= sh_size))
+	{
+	  /* The given offset is too big, it is beyond this section.  */
+	  __libelf_seterrno (ELF_E_OFFSET_RANGE);
+	  goto out;
+	}
+    }
+
+  if (strscn->rawdata_base == NULL && ! strscn->data_read)
+    {
+      rwlock_unlock (elf->lock);
+      rwlock_wrlock (elf->lock);
+      if (strscn->rawdata_base == NULL && ! strscn->data_read
+	/* Read the section data.  */
+	  && __libelf_set_rawdata_wrlock (strscn) != 0)
+	goto out;
+    }
+
+  if (unlikely (strscn->zdata_base != NULL))
+    {
+      /* Make sure the string is NUL terminated.  Start from the end,
+         which very likely is a NUL char.  */
+      if (likely (validate_str (strscn->zdata_base, offset, sh_size)))
+        result = &strscn->zdata_base[offset];
+      else
+        __libelf_seterrno (ELF_E_INVALID_INDEX);
+    }
+  else if (likely (strscn->data_list_rear == NULL))
+    {
+      // XXX The above is currently correct since elf_newdata will
+      // make sure to convert the rawdata into the datalist if
+      // necessary. But it would be more efficient to keep the rawdata
+      // unconverted and only then iterate over the rest of the (newly
+      // added data) list.  Note that when the ELF file is mmapped
+      // rawdata_base can be set while rawdata.d hasn't been
+      // initialized yet (when data_read is zero). So we cannot just
+      // look at the rawdata.d.d_size.
+
+      /* Make sure the string is NUL terminated.  Start from the end,
+	 which very likely is a NUL char.  */
+      if (likely (validate_str (strscn->rawdata_base, offset, sh_size)))
+	result = &strscn->rawdata_base[offset];
+      else
+	__libelf_seterrno (ELF_E_INVALID_INDEX);
+    }
+  else
+    {
+      /* This is a file which is currently created.  Use the list of
+	 data blocks.  */
+      struct Elf_Data_List *dl = &strscn->data_list;
+      while (dl != NULL)
+	{
+	  if (offset >= (size_t) dl->data.d.d_off
+	      && offset < dl->data.d.d_off + dl->data.d.d_size)
+	    {
+	      /* Make sure the string is NUL terminated.  Start from
+		 the end, which very likely is a NUL char.  */
+	      if (likely (validate_str ((char *) dl->data.d.d_buf,
+					offset - dl->data.d.d_off,
+					dl->data.d.d_size)))
+		result = ((char *) dl->data.d.d_buf
+			  + (offset - dl->data.d.d_off));
+	      else
+		__libelf_seterrno (ELF_E_INVALID_INDEX);
+	      break;
+	    }
+
+	  dl = dl->next;
+	}
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
+INTDEF(elf_strptr)
diff --git a/third_party/elfutils/libelf/elf_update.c b/third_party/elfutils/libelf/elf_update.c
new file mode 100644
index 0000000..8ce0782
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_update.c
@@ -0,0 +1,222 @@
+/* Update data structures for changes and write them out.
+   Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include "libelfP.h"
+
+
+static off_t
+write_file (Elf *elf, off_t size, int change_bo, size_t shnum)
+{
+  int class = elf->class;
+
+  /* Check the mode bits now, before modification might change them.  */
+  struct stat st;
+  if (unlikely (fstat (elf->fildes, &st) != 0))
+    {
+      __libelf_seterrno (ELF_E_WRITE_ERROR);
+      return -1;
+    }
+
+  /* Adjust the size in any case.  We do this even if we use `write'.
+     We cannot do this if this file is in an archive.  We also don't
+     do it *now* if we are shortening the file since this would
+     prevent programs to use the data of the file in generating the
+     new file.  We truncate the file later in this case.  */
+  if (elf->parent == NULL
+      && (elf->maximum_size == ~((size_t) 0)
+	  || (size_t) size > elf->maximum_size)
+      && unlikely (ftruncate (elf->fildes, size) != 0))
+    {
+      __libelf_seterrno (ELF_E_WRITE_ERROR);
+      return -1;
+    }
+
+  /* Try to map the file if this isn't done yet.  */
+  if (elf->map_address == NULL && elf->cmd == ELF_C_WRITE_MMAP)
+    {
+      elf->map_address = mmap (NULL, size, PROT_READ | PROT_WRITE,
+			       MAP_SHARED, elf->fildes, 0);
+      if (unlikely (elf->map_address == MAP_FAILED))
+	elf->map_address = NULL;
+      else
+	elf->flags |= ELF_F_MMAPPED;
+    }
+
+  if (elf->map_address != NULL)
+    {
+      /* When using mmap we want to make sure the file content is
+	 really there. Only using ftruncate might mean the file is
+	 extended, but space isn't allocated yet.  This might cause a
+	 SIGBUS once we write into the mmapped space and the disk is
+	 full.  In glibc posix_fallocate is required to extend the
+	 file and allocate enough space even if the underlying
+	 filesystem would normally return EOPNOTSUPP.  But other
+	 implementations might not work as expected.  And the glibc
+	 fallback case might fail (with unexpected errnos) in some cases.
+	 So we only report an error when the call fails and errno is
+	 ENOSPC. Otherwise we ignore the error and treat it as just hint.  */
+      if (elf->parent == NULL
+	  && (elf->maximum_size == ~((size_t) 0)
+	      || (size_t) size > elf->maximum_size)
+	  && unlikely (posix_fallocate (elf->fildes, 0, size) != 0))
+	if (errno == ENOSPC)
+	  {
+	    __libelf_seterrno (ELF_E_WRITE_ERROR);
+	    return -1;
+	  }
+
+      /* The file is mmaped.  */
+      if ((class == ELFCLASS32
+	   ? __elf32_updatemmap (elf, change_bo, shnum)
+	   : __elf64_updatemmap (elf, change_bo, shnum)) != 0)
+	/* Some problem while writing.  */
+	size = -1;
+    }
+  else
+    {
+      /* The file is not mmaped.  */
+      if ((class == ELFCLASS32
+	   ? __elf32_updatefile (elf, change_bo, shnum)
+	   : __elf64_updatefile (elf, change_bo, shnum)) != 0)
+	/* Some problem while writing.  */
+	size = -1;
+    }
+
+  /* Reduce the file size if necessary.  */
+  if (size != -1
+      && elf->parent == NULL
+      && elf->maximum_size != ~((size_t) 0)
+      && (size_t) size < elf->maximum_size
+      && unlikely (ftruncate (elf->fildes, size) != 0))
+    {
+      __libelf_seterrno (ELF_E_WRITE_ERROR);
+      size = -1;
+    }
+
+  /* POSIX says that ftruncate and write may clear the S_ISUID and S_ISGID
+     mode bits.  So make sure we restore them afterwards if they were set.
+     This is not atomic if someone else chmod's the file while we operate.  */
+  if (size != -1
+      && unlikely (st.st_mode & (S_ISUID | S_ISGID))
+      /* fchmod ignores the bits we cannot change.  */
+      && unlikely (fchmod (elf->fildes, st.st_mode) != 0))
+    {
+      __libelf_seterrno (ELF_E_WRITE_ERROR);
+      size = -1;
+    }
+
+  if (size != -1 && elf->parent == NULL)
+    elf->maximum_size = size;
+
+  return size;
+}
+
+
+off_t
+elf_update (Elf *elf, Elf_Cmd cmd)
+{
+  size_t shnum;
+  off_t size;
+  int change_bo = 0;
+
+  if (cmd != ELF_C_NULL
+      && cmd != ELF_C_WRITE
+      && unlikely (cmd != ELF_C_WRITE_MMAP))
+    {
+      __libelf_seterrno (ELF_E_INVALID_CMD);
+      return -1;
+    }
+
+  if (elf == NULL)
+    return -1;
+
+  if (elf->kind != ELF_K_ELF)
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return -1;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  /* Make sure we have an ELF header.  */
+  if (elf->state.elf.ehdr == NULL)
+    {
+      __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+      size = -1;
+      goto out;
+    }
+
+  /* Determine the number of sections.  */
+  shnum = (elf->state.elf.scns_last->cnt == 0
+	   ? 0
+	   : 1 + elf->state.elf.scns_last->data[elf->state.elf.scns_last->cnt - 1].index);
+
+  /* Update the ELF descriptor.  First, place the program header.  It
+     will come right after the ELF header.  The count the size of all
+     sections and finally place the section table.  */
+  size = (elf->class == ELFCLASS32
+	  ? __elf32_updatenull_wrlock (elf, &change_bo, shnum)
+	  : __elf64_updatenull_wrlock (elf, &change_bo, shnum));
+  if (likely (size != -1)
+      /* See whether we actually have to write out the data.  */
+      && (cmd == ELF_C_WRITE || cmd == ELF_C_WRITE_MMAP))
+    {
+      if (elf->cmd != ELF_C_RDWR
+	  && elf->cmd != ELF_C_RDWR_MMAP
+	  && elf->cmd != ELF_C_WRITE
+	  && unlikely (elf->cmd != ELF_C_WRITE_MMAP))
+	{
+	  __libelf_seterrno (ELF_E_UPDATE_RO);
+	  size = -1;
+	}
+      else if (unlikely (elf->fildes == -1))
+	{
+	  /* We closed the file already.  */
+	  __libelf_seterrno (ELF_E_FD_DISABLED);
+	  size = -1;
+	}
+      else
+	size = write_file (elf, size, change_bo, shnum);
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return size;
+}
diff --git a/third_party/elfutils/libelf/elf_version.c b/third_party/elfutils/libelf/elf_version.c
new file mode 100644
index 0000000..7c336ff
--- /dev/null
+++ b/third_party/elfutils/libelf/elf_version.c
@@ -0,0 +1,69 @@
+/* Coordinate ELF library and application versions.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelfP.h>
+
+
+/* Is the version initialized?  */
+int __libelf_version_initialized;
+
+/* Currently selected version.  */
+unsigned int __libelf_version = EV_CURRENT;
+
+
+unsigned int
+elf_version (unsigned int version)
+{
+  if (version == EV_NONE)
+    return __libelf_version;
+
+  if (likely (version < EV_NUM))
+    {
+      /* Phew, we know this version.  */
+      unsigned int last_version = __libelf_version;
+
+      /* Store the new version.  */
+      __libelf_version = version;
+
+      /* Signal that the version is now initialized.  */
+      __libelf_version_initialized = 1;
+
+      /* And return the last version.  */
+      return last_version;
+    }
+
+  /* We cannot handle this version.  */
+  __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+  return EV_NONE;
+}
+INTDEF(elf_version)
diff --git a/third_party/elfutils/libelf/exttypes.h b/third_party/elfutils/libelf/exttypes.h
new file mode 100644
index 0000000..7bacd65
--- /dev/null
+++ b/third_party/elfutils/libelf/exttypes.h
@@ -0,0 +1,104 @@
+/* External ELF types.
+   Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _EXTTYPES_H
+#define	_EXTTYPES_H 1
+
+/* Integral types.  */
+typedef char Elf32_Ext_Addr[ELF32_FSZ_ADDR];
+typedef char Elf32_Ext_Off[ELF32_FSZ_OFF];
+typedef char Elf32_Ext_Half[ELF32_FSZ_HALF];
+typedef char Elf32_Ext_Sword[ELF32_FSZ_SWORD];
+typedef char Elf32_Ext_Word[ELF32_FSZ_WORD];
+typedef char Elf32_Ext_Sxword[ELF32_FSZ_SXWORD];
+typedef char Elf32_Ext_Xword[ELF32_FSZ_XWORD];
+
+typedef char Elf64_Ext_Addr[ELF64_FSZ_ADDR];
+typedef char Elf64_Ext_Off[ELF64_FSZ_OFF];
+typedef char Elf64_Ext_Half[ELF64_FSZ_HALF];
+typedef char Elf64_Ext_Sword[ELF64_FSZ_SWORD];
+typedef char Elf64_Ext_Word[ELF64_FSZ_WORD];
+typedef char Elf64_Ext_Sxword[ELF64_FSZ_SXWORD];
+typedef char Elf64_Ext_Xword[ELF64_FSZ_XWORD];
+
+
+/* Define the composed types.  */
+#define START(Bits, Name, EName) typedef struct {
+#define END(Bits, Name) } ElfW2(Bits, Name)
+#define TYPE_NAME(Type, Name) Type Name;
+#define TYPE_EXTRA(Text) Text
+#define TYPE_XLATE(Text)
+
+/* Get the abstract definitions. */
+#include "abstract.h"
+
+/* And define the types.  */
+Ehdr32 (Ext_);
+Phdr32 (Ext_);
+Shdr32 (Ext_);
+Sym32 (Ext_);
+Rel32 (Ext_);
+Rela32 (Ext_);
+Note32 (Ext_);
+Dyn32 (Ext_);
+Verdef32 (Ext_);
+Verdaux32 (Ext_);
+Verneed32 (Ext_);
+Vernaux32 (Ext_);
+Syminfo32 (Ext_);
+Move32 (Ext_);
+Lib32 (Ext_);
+auxv_t32 (Ext_);
+Chdr32 (Ext_);
+
+Ehdr64 (Ext_);
+Phdr64 (Ext_);
+Shdr64 (Ext_);
+Sym64 (Ext_);
+Rel64 (Ext_);
+Rela64 (Ext_);
+Note64 (Ext_);
+Dyn64 (Ext_);
+Verdef64 (Ext_);
+Verdaux64 (Ext_);
+Verneed64 (Ext_);
+Vernaux64 (Ext_);
+Syminfo64 (Ext_);
+Move64 (Ext_);
+Lib64 (Ext_);
+auxv_t64 (Ext_);
+Chdr64 (Ext_);
+
+#undef START
+#undef END
+#undef TYPE_NAME
+#undef TYPE_EXTRA
+#undef TYPE_XLATE
+
+#endif	/* exttypes.h */
diff --git a/third_party/elfutils/libelf/gelf.h b/third_party/elfutils/libelf/gelf.h
new file mode 100644
index 0000000..0619880
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf.h
@@ -0,0 +1,342 @@
+/* This file defines generic ELF types, structures, and macros.
+   Copyright (C) 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GELF_H
+#define	_GELF_H 1
+
+#include <libelf.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Class independent type definitions.  Correctly speaking this is not
+   true.  We assume that 64-bit binaries are the largest class and
+   therefore all other classes can be represented without loss.  */
+
+/* Type for a 16-bit quantity.  */
+typedef Elf64_Half GElf_Half;
+
+/* Types for signed and unsigned 32-bit quantities.  */
+typedef Elf64_Word GElf_Word;
+typedef	Elf64_Sword GElf_Sword;
+
+/* Types for signed and unsigned 64-bit quantities.  */
+typedef Elf64_Xword GElf_Xword;
+typedef	Elf64_Sxword GElf_Sxword;
+
+/* Type of addresses.  */
+typedef Elf64_Addr GElf_Addr;
+
+/* Type of file offsets.  */
+typedef Elf64_Off GElf_Off;
+
+
+/* The ELF file header.  This appears at the start of every ELF file.  */
+typedef Elf64_Ehdr GElf_Ehdr;
+
+/* Section header.  */
+typedef Elf64_Shdr GElf_Shdr;
+
+/* Section index.  */
+/* XXX This should probably be a larger type in preparation of times when
+   regular section indices can be larger.  */
+typedef Elf64_Section GElf_Section;
+
+/* Symbol table entry.  */
+typedef Elf64_Sym GElf_Sym;
+
+/* The syminfo section if available contains additional information about
+   every dynamic symbol.  */
+typedef Elf64_Syminfo GElf_Syminfo;
+
+/* Relocation table entry without addend (in section of type SHT_REL).  */
+typedef Elf64_Rel GElf_Rel;
+
+/* Relocation table entry with addend (in section of type SHT_RELA).  */
+typedef Elf64_Rela GElf_Rela;
+
+/* Program segment header.  */
+typedef Elf64_Phdr GElf_Phdr;
+
+/* Header of a compressed section.  */
+typedef Elf64_Chdr GElf_Chdr;
+
+/* Dynamic section entry.  */
+typedef Elf64_Dyn GElf_Dyn;
+
+
+/* Version definition sections.  */
+typedef Elf64_Verdef GElf_Verdef;
+
+/* Auxialiary version information.  */
+typedef Elf64_Verdaux GElf_Verdaux;
+
+/* Version dependency section.  */
+typedef Elf64_Verneed GElf_Verneed;
+
+/* Auxiliary needed version information.  */
+typedef Elf64_Vernaux GElf_Vernaux;
+
+
+/* Type for version symbol information.  */
+typedef Elf64_Versym GElf_Versym;
+
+
+/* Auxiliary vector.  */
+typedef Elf64_auxv_t GElf_auxv_t;
+
+
+/* Note section contents.  */
+typedef Elf64_Nhdr GElf_Nhdr;
+
+
+/* Move structure.  */
+typedef Elf64_Move GElf_Move;
+
+
+/* Library list structure.  */
+typedef Elf64_Lib GElf_Lib;
+
+
+/* How to extract and insert information held in the st_info field.  */
+
+#define GELF_ST_BIND(val)		ELF64_ST_BIND (val)
+#define GELF_ST_TYPE(val)		ELF64_ST_TYPE (val)
+#define GELF_ST_INFO(bind, type)	ELF64_ST_INFO (bind, type)
+
+/* How to extract information held in the st_other field.  */
+
+#define GELF_ST_VISIBILITY(val)		ELF64_ST_VISIBILITY (val)
+
+
+/* How to extract and insert information held in the r_info field.  */
+
+#define GELF_R_SYM(info)		ELF64_R_SYM (info)
+#define GELF_R_TYPE(info)		ELF64_R_TYPE (info)
+#define GELF_R_INFO(sym, type)		ELF64_R_INFO (sym, type)
+
+
+/* How to extract and insert information held in the m_info field.  */
+#define GELF_M_SYM(info)		ELF64_M_SYM (info)
+#define GELF_M_SIZE(info)		ELF64_M_SIZE (info)
+#define GELF_M_INFO(sym, size)		ELF64_M_INFO (sym, size)
+
+
+/* Get class of the file associated with ELF.  */
+extern int gelf_getclass (Elf *__elf);
+
+
+/* Return size of array of COUNT elements of the type denoted by TYPE
+   in the external representation.  The binary class is taken from ELF.
+   The result is based on version VERSION of the ELF standard.  */
+extern size_t gelf_fsize (Elf *__elf, Elf_Type __type, size_t __count,
+			  unsigned int __version);
+
+/* Retrieve object file header.  */
+extern GElf_Ehdr *gelf_getehdr (Elf *__elf, GElf_Ehdr *__dest);
+
+/* Update the ELF header.  */
+extern int gelf_update_ehdr (Elf *__elf, GElf_Ehdr *__src);
+
+/* Create new ELF header if none exists.  Creates an Elf32_Ehdr if CLASS
+   is ELFCLASS32 or an Elf64_Ehdr if CLASS is ELFCLASS64.  Returns NULL
+   on error.  */
+extern void *gelf_newehdr (Elf *__elf, int __class);
+
+/* Get section at OFFSET.  */
+extern Elf_Scn *gelf_offscn (Elf *__elf, GElf_Off __offset);
+
+/* Retrieve section header.  */
+extern GElf_Shdr *gelf_getshdr (Elf_Scn *__scn, GElf_Shdr *__dst);
+
+/* Update section header.  */
+extern int gelf_update_shdr (Elf_Scn *__scn, GElf_Shdr *__src);
+
+/* Retrieve program header table entry.  */
+extern GElf_Phdr *gelf_getphdr (Elf *__elf, int __ndx, GElf_Phdr *__dst);
+
+/* Update the program header.  */
+extern int gelf_update_phdr (Elf *__elf, int __ndx, GElf_Phdr *__src);
+
+/* Create new program header with PHNUM entries.  Creates either an
+   Elf32_Phdr or an Elf64_Phdr depending on whether the given ELF is
+   ELFCLASS32 or ELFCLASS64.  Returns NULL on error.  */
+extern void *gelf_newphdr (Elf *__elf, size_t __phnum);
+
+/* Get compression header of section if any.  Returns NULL and sets
+   elf_errno if the section isn't compressed or an error occurred.  */
+extern GElf_Chdr *gelf_getchdr (Elf_Scn *__scn, GElf_Chdr *__dst);
+
+/* Convert data structure from the representation in the file represented
+   by ELF to their memory representation.  */
+extern Elf_Data *gelf_xlatetom (Elf *__elf, Elf_Data *__dest,
+				const Elf_Data *__src, unsigned int __encode);
+
+/* Convert data structure from to the representation in memory
+   represented by ELF file representation.  */
+extern Elf_Data *gelf_xlatetof (Elf *__elf, Elf_Data *__dest,
+				const Elf_Data *__src, unsigned int __encode);
+
+
+/* Retrieve REL relocation info at the given index.  */
+extern GElf_Rel *gelf_getrel (Elf_Data *__data, int __ndx, GElf_Rel *__dst);
+
+/* Retrieve RELA relocation info at the given index.  */
+extern GElf_Rela *gelf_getrela (Elf_Data *__data, int __ndx, GElf_Rela *__dst);
+
+/* Update REL relocation information at given index.  */
+extern int gelf_update_rel (Elf_Data *__dst, int __ndx, GElf_Rel *__src);
+
+/* Update RELA relocation information at given index.  */
+extern int gelf_update_rela (Elf_Data *__dst, int __ndx, GElf_Rela *__src);
+
+
+/* Retrieve symbol information from the symbol table at the given index.  */
+extern GElf_Sym *gelf_getsym (Elf_Data *__data, int __ndx, GElf_Sym *__dst);
+
+/* Update symbol information in the symbol table at the given index.  */
+extern int gelf_update_sym (Elf_Data *__data, int __ndx, GElf_Sym *__src);
+
+
+/* Retrieve symbol information and separate section index from the
+   symbol table at the given index.  */
+extern GElf_Sym *gelf_getsymshndx (Elf_Data *__symdata, Elf_Data *__shndxdata,
+				   int __ndx, GElf_Sym *__sym,
+				   Elf32_Word *__xshndx);
+
+/* Update symbol information and separate section index in the symbol
+   table at the given index.  */
+extern int gelf_update_symshndx (Elf_Data *__symdata, Elf_Data *__shndxdata,
+				 int __ndx, GElf_Sym *__sym,
+				 Elf32_Word __xshndx);
+
+
+/* Retrieve additional symbol information from the symbol table at the
+   given index.  */
+extern GElf_Syminfo *gelf_getsyminfo (Elf_Data *__data, int __ndx,
+				      GElf_Syminfo *__dst);
+
+/* Update additional symbol information in the symbol table at the
+   given index.  */
+extern int gelf_update_syminfo (Elf_Data *__data, int __ndx,
+				GElf_Syminfo *__src);
+
+
+/* Get information from dynamic table at the given index.  */
+extern GElf_Dyn *gelf_getdyn (Elf_Data *__data, int __ndx, GElf_Dyn *__dst);
+
+/* Update information in dynamic table at the given index.  */
+extern int gelf_update_dyn (Elf_Data *__dst, int __ndx, GElf_Dyn *__src);
+
+
+/* Get move structure at the given index.  */
+extern GElf_Move *gelf_getmove (Elf_Data *__data, int __ndx, GElf_Move *__dst);
+
+/* Update move structure at the given index.  */
+extern int gelf_update_move (Elf_Data *__data, int __ndx,
+			     GElf_Move *__src);
+
+
+/* Get library from table at the given index.  */
+extern GElf_Lib *gelf_getlib (Elf_Data *__data, int __ndx, GElf_Lib *__dst);
+
+/* Update library in table at the given index.  */
+extern int gelf_update_lib (Elf_Data *__data, int __ndx, GElf_Lib *__src);
+
+
+
+/* Retrieve symbol version information at given index.  */
+extern GElf_Versym *gelf_getversym (Elf_Data *__data, int __ndx,
+				    GElf_Versym *__dst);
+
+/* Update symbol version information.  */
+extern int gelf_update_versym (Elf_Data *__data, int __ndx,
+			       GElf_Versym *__src);
+
+
+/* Retrieve required symbol version information at given offset.  */
+extern GElf_Verneed *gelf_getverneed (Elf_Data *__data, int __offset,
+				      GElf_Verneed *__dst);
+
+/* Update required symbol version information.  */
+extern int gelf_update_verneed (Elf_Data *__data, int __offset,
+				GElf_Verneed *__src);
+
+/* Retrieve additional required symbol version information at given offset.  */
+extern GElf_Vernaux *gelf_getvernaux (Elf_Data *__data, int __offset,
+				      GElf_Vernaux *__dst);
+
+/* Update additional required symbol version information.  */
+extern int gelf_update_vernaux (Elf_Data *__data, int __offset,
+				GElf_Vernaux *__src);
+
+
+/* Retrieve symbol version definition information at given offset.  */
+extern GElf_Verdef *gelf_getverdef (Elf_Data *__data, int __offset,
+				    GElf_Verdef *__dst);
+
+/* Update symbol version definition information.  */
+extern int gelf_update_verdef (Elf_Data *__data, int __offset,
+			       GElf_Verdef *__src);
+
+/* Retrieve additional symbol version definition information at given
+   offset.  */
+extern GElf_Verdaux *gelf_getverdaux (Elf_Data *__data, int __offset,
+				      GElf_Verdaux *__dst);
+
+/* Update additional symbol version definition information.  */
+extern int gelf_update_verdaux (Elf_Data *__data, int __offset,
+				GElf_Verdaux *__src);
+
+
+/* Get auxv entry at the given index.  */
+extern GElf_auxv_t *gelf_getauxv (Elf_Data *__data, int __ndx,
+				  GElf_auxv_t *__dst);
+
+/* Update auxv entry at the given index.  */
+extern int gelf_update_auxv (Elf_Data *__data, int __ndx, GElf_auxv_t *__src);
+
+
+/* Get note header at the given offset into the data, and the offsets of
+   the note's name and descriptor data.  Returns the offset of the next
+   note header, or 0 for an invalid offset or corrupt note header.  */
+extern size_t gelf_getnote (Elf_Data *__data, size_t __offset,
+			    GElf_Nhdr *__result,
+			    size_t *__name_offset, size_t *__desc_offset);
+
+
+/* Compute simple checksum from permanent parts of the ELF file.  */
+extern long int gelf_checksum (Elf *__elf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* gelf.h */
diff --git a/third_party/elfutils/libelf/gelf_checksum.c b/third_party/elfutils/libelf/gelf_checksum.c
new file mode 100644
index 0000000..831c54c
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_checksum.c
@@ -0,0 +1,48 @@
+/* Convert from file to memory representation.  Generic ELF version.
+   Copyright (C) 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+long int
+gelf_checksum (Elf *elf)
+{
+  if (elf == NULL)
+    return -1l;
+
+  return (elf->class == ELFCLASS32
+	  ? INTUSE(elf32_checksum) (elf) : INTUSE(elf64_checksum) (elf));
+}
diff --git a/third_party/elfutils/libelf/gelf_fsize.c b/third_party/elfutils/libelf/gelf_fsize.c
new file mode 100644
index 0000000..0c50926
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_fsize.c
@@ -0,0 +1,108 @@
+/* Return the size of an object file type.
+   Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+/* These are the sizes for all the known types.  */
+const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+{
+  /* We have no entry for EV_NONE since we have to set an error.  */
+  [EV_CURRENT - 1] = {
+    [ELFCLASS32 - 1] = {
+#define TYPE_SIZES(LIBELFBITS) \
+      [ELF_T_ADDR]	= ELFW2(LIBELFBITS, FSZ_ADDR),			      \
+      [ELF_T_OFF]	= ELFW2(LIBELFBITS, FSZ_OFF),			      \
+      [ELF_T_BYTE]	= 1,						      \
+      [ELF_T_HALF]	= ELFW2(LIBELFBITS, FSZ_HALF),			      \
+      [ELF_T_WORD]	= ELFW2(LIBELFBITS, FSZ_WORD),			      \
+      [ELF_T_SWORD]	= ELFW2(LIBELFBITS, FSZ_SWORD),			      \
+      [ELF_T_XWORD]	= ELFW2(LIBELFBITS, FSZ_XWORD),			      \
+      [ELF_T_SXWORD]	= ELFW2(LIBELFBITS, FSZ_SXWORD),		      \
+      [ELF_T_EHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Ehdr)),		      \
+      [ELF_T_SHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Shdr)),		      \
+      [ELF_T_SYM]	= sizeof (ElfW2(LIBELFBITS, Ext_Sym)),		      \
+      [ELF_T_REL]	= sizeof (ElfW2(LIBELFBITS, Ext_Rel)),		      \
+      [ELF_T_RELA]	= sizeof (ElfW2(LIBELFBITS, Ext_Rela)),		      \
+      [ELF_T_PHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Phdr)),		      \
+      [ELF_T_DYN]	= sizeof (ElfW2(LIBELFBITS, Ext_Dyn)),		      \
+      [ELF_T_VDEF]	= sizeof (ElfW2(LIBELFBITS, Ext_Verdef)),	      \
+      [ELF_T_VDAUX]	= sizeof (ElfW2(LIBELFBITS, Ext_Verdaux)),	      \
+      [ELF_T_VNEED]	= sizeof (ElfW2(LIBELFBITS, Ext_Verneed)),	      \
+      [ELF_T_VNAUX]	= sizeof (ElfW2(LIBELFBITS, Ext_Vernaux)),	      \
+      [ELF_T_NHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Nhdr)),		      \
+      [ELF_T_SYMINFO]	= sizeof (ElfW2(LIBELFBITS, Ext_Syminfo)),	      \
+      [ELF_T_MOVE]	= sizeof (ElfW2(LIBELFBITS, Ext_Move)),		      \
+      [ELF_T_LIB]	= sizeof (ElfW2(LIBELFBITS, Ext_Lib)),		      \
+      [ELF_T_AUXV]	= sizeof (ElfW2(LIBELFBITS, Ext_auxv_t)),	      \
+      [ELF_T_CHDR]	= sizeof (ElfW2(LIBELFBITS, Ext_Chdr)),		      \
+      [ELF_T_GNUHASH]	= ELFW2(LIBELFBITS, FSZ_WORD)
+      TYPE_SIZES (32)
+    },
+    [ELFCLASS64 - 1] = {
+      TYPE_SIZES (64)
+    }
+  }
+};
+
+
+size_t
+gelf_fsize (Elf *elf, Elf_Type type, size_t count, unsigned int version)
+{
+  /* We do not have differences between file and memory sizes.  Better
+     not since otherwise `mmap' would not work.  */
+  if (elf == NULL)
+    return 0;
+
+  if (version == EV_NONE || version >= EV_NUM)
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_VERSION);
+      return 0;
+    }
+
+  if (type >= ELF_T_NUM)
+    {
+      __libelf_seterrno (ELF_E_UNKNOWN_TYPE);
+      return 0;
+    }
+
+#if EV_NUM != 2
+  return count * __libelf_type_sizes[version - 1][elf->class - 1][type];
+#else
+  return count * __libelf_type_sizes[0][elf->class - 1][type];
+#endif
+}
+INTDEF(gelf_fsize)
diff --git a/third_party/elfutils/libelf/gelf_getauxv.c b/third_party/elfutils/libelf/gelf_getauxv.c
new file mode 100644
index 0000000..1591be2
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getauxv.c
@@ -0,0 +1,107 @@
+/* Get information from auxiliary vector at the given index.
+   Copyright (C) 2007, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_auxv_t *
+gelf_getauxv (Elf_Data *data, int ndx, GElf_auxv_t *dst)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  GElf_auxv_t *result = NULL;
+  Elf *elf;
+
+  if (data_scn == NULL)
+    return NULL;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_AUXV))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  elf = data_scn->s->elf;
+
+  rwlock_rdlock (elf->lock);
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_auxv_t *src;
+
+      /* Here it gets a bit more complicated.  The format of the vector
+	 entries has to be converted.  The user better have provided a
+	 buffer where we can store the information.  While copying the data
+	 we convert the format.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      src = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx];
+
+      /* This might look like a simple copy operation but it's
+	 not.  There are zero- and sign-extensions going on.  */
+      dst->a_type = src->a_type;
+      dst->a_un.a_val = src->a_un.a_val;
+    }
+  else
+    {
+      /* If this is a 64 bit object it's easy.  */
+      assert (sizeof (GElf_auxv_t) == sizeof (Elf64_auxv_t));
+
+      /* The data is already in the correct form.  Just make sure the
+	 index is OK.  */
+      if (unlikely ((ndx + 1) * sizeof (GElf_auxv_t) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      memcpy (dst, data_scn->d.d_buf + ndx * sizeof (GElf_auxv_t),
+	      sizeof (GElf_auxv_t));
+    }
+
+  result = dst;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getchdr.c b/third_party/elfutils/libelf/gelf_getchdr.c
new file mode 100644
index 0000000..394bf4b
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getchdr.c
@@ -0,0 +1,69 @@
+/* Return section compression header.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libelfP.h"
+#include <gelf.h>
+#include <stddef.h>
+
+
+GElf_Chdr *
+gelf_getchdr (Elf_Scn *scn, GElf_Chdr *dest)
+{
+  if (scn == NULL)
+    return NULL;
+
+  if (dest == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return NULL;
+    }
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Chdr *chdr = elf32_getchdr (scn);
+      if (chdr == NULL)
+	return NULL;
+      dest->ch_type = chdr->ch_type;
+      dest->ch_size = chdr->ch_size;
+      dest->ch_addralign = chdr->ch_addralign;
+    }
+  else
+    {
+      Elf64_Chdr *chdr = elf64_getchdr (scn);
+      if (chdr == NULL)
+	return NULL;
+      *dest = *chdr;
+    }
+
+  return dest;
+}
+INTDEF(gelf_getchdr)
diff --git a/third_party/elfutils/libelf/gelf_getclass.c b/third_party/elfutils/libelf/gelf_getclass.c
new file mode 100644
index 0000000..7d0924b
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getclass.c
@@ -0,0 +1,44 @@
+/* Return the class of file associated with the descriptor.
+   Copyright (C) 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_getclass (Elf *elf)
+{
+  return elf == NULL || elf->kind != ELF_K_ELF ? ELFCLASSNONE : elf->class;
+}
diff --git a/third_party/elfutils/libelf/gelf_getdyn.c b/third_party/elfutils/libelf/gelf_getdyn.c
new file mode 100644
index 0000000..a0090e1
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getdyn.c
@@ -0,0 +1,108 @@
+/* Get information from dynamic table at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Dyn *
+gelf_getdyn (Elf_Data *data, int ndx, GElf_Dyn *dst)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  GElf_Dyn *result = NULL;
+  Elf *elf;
+
+  if (data_scn == NULL)
+    return NULL;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_DYN))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  elf = data_scn->s->elf;
+
+  rwlock_rdlock (elf->lock);
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Dyn *src;
+
+      /* Here it gets a bit more complicated.  The format of the symbol
+	 table entries has to be adopted.  The user better has provided
+	 a buffer where we can store the information.  While copying the
+	 data we are converting the format.  */
+      if (INVALID_NDX (ndx, Elf32_Dyn, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      src = &((Elf32_Dyn *) data_scn->d.d_buf)[ndx];
+
+      /* This might look like a simple copy operation but it's
+	 not.  There are zero- and sign-extensions going on.  */
+      dst->d_tag = src->d_tag;
+      /* It OK to copy `d_val' since `d_ptr' has the same size.  */
+      dst->d_un.d_val = src->d_un.d_val;
+    }
+  else
+    {
+      /* If this is a 64 bit object it's easy.  */
+      assert (sizeof (GElf_Dyn) == sizeof (Elf64_Dyn));
+
+      /* The data is already in the correct form.  Just make sure the
+	 index is OK.  */
+      if (INVALID_NDX (ndx, GElf_Dyn, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      *dst = ((GElf_Dyn *) data_scn->d.d_buf)[ndx];
+    }
+
+  result = dst;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getehdr.c b/third_party/elfutils/libelf/gelf_getehdr.c
new file mode 100644
index 0000000..abeb70c
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getehdr.c
@@ -0,0 +1,108 @@
+/* Get ELF header.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Ehdr *
+internal_function
+__gelf_getehdr_rdlock (Elf *elf, GElf_Ehdr *dest)
+{
+  GElf_Ehdr *result = NULL;
+
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* The following is an optimization: the ehdr element is at the same
+     position in both the elf32 and elf64 structure.  */
+  if (offsetof (struct Elf, state.elf32.ehdr)
+      != offsetof (struct Elf, state.elf64.ehdr))
+    abort ();
+  /* Just pick one of the values.  */
+ if (unlikely (elf->state.elf64.ehdr == NULL))
+    /* Maybe no ELF header was created yet.  */
+    __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+  else if (elf->class == ELFCLASS32)
+    {
+      Elf32_Ehdr *ehdr = elf->state.elf32.ehdr;
+
+      /* Convert the 32-bit struct to an 64-bit one.  */
+      memcpy (dest->e_ident, ehdr->e_ident, EI_NIDENT);
+#define COPY(name) \
+      dest->name = ehdr->name
+      COPY (e_type);
+      COPY (e_machine);
+      COPY (e_version);
+      COPY (e_entry);
+      COPY (e_phoff);
+      COPY (e_shoff);
+      COPY (e_flags);
+      COPY (e_ehsize);
+      COPY (e_phentsize);
+      COPY (e_phnum);
+      COPY (e_shentsize);
+      COPY (e_shnum);
+      COPY (e_shstrndx);
+
+      result = dest;
+    }
+  else
+    result = memcpy (dest, elf->state.elf64.ehdr, sizeof (*dest));
+
+  return result;
+}
+
+GElf_Ehdr *
+gelf_getehdr (Elf *elf, GElf_Ehdr *dest)
+{
+  GElf_Ehdr *result;
+  if (elf == NULL)
+    return NULL;
+
+  rwlock_rdlock (elf->lock);
+  result = __gelf_getehdr_rdlock (elf, dest);
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getlib.c b/third_party/elfutils/libelf/gelf_getlib.c
new file mode 100644
index 0000000..a8ac478
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getlib.c
@@ -0,0 +1,77 @@
+/* Get library from table at the given index.
+   Copyright (C) 2004, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Lib *
+gelf_getlib (Elf_Data *data, int ndx, GElf_Lib *dst)
+{
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_LIB))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  rwlock_rdlock (data_scn->s->elf->lock);
+
+  /* The on disk format of Elf32_Lib and Elf64_Lib is identical.  So
+     we can simplify things significantly.  */
+  assert (sizeof (GElf_Lib) == sizeof (Elf32_Lib));
+  assert (sizeof (GElf_Lib) == sizeof (Elf64_Lib));
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  GElf_Lib *result = NULL;
+  if (INVALID_NDX (ndx, GElf_Lib, data))
+    __libelf_seterrno (ELF_E_INVALID_INDEX);
+  else
+    {
+      *dst = ((GElf_Lib *) data->d_buf)[ndx];
+
+      result = dst;
+    }
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getmove.c b/third_party/elfutils/libelf/gelf_getmove.c
new file mode 100644
index 0000000..18efedc
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getmove.c
@@ -0,0 +1,79 @@
+/* Get move structure at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+GElf_Move *
+gelf_getmove (Elf_Data *data, int ndx, GElf_Move *dst)
+{
+  GElf_Move *result = NULL;
+  Elf *elf;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_MOVE))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Move) == sizeof (Elf32_Move));
+  assert (sizeof (GElf_Move) == sizeof (Elf64_Move));
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (INVALID_NDX (ndx, GElf_Move, data))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      goto out;
+    }
+
+  elf = ((Elf_Data_Scn *) data)->s->elf;
+  rwlock_rdlock (elf->lock);
+
+  *dst = ((GElf_Move *) data->d_buf)[ndx];
+
+  rwlock_unlock (elf->lock);
+
+  result = dst;
+
+ out:
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getnote.c b/third_party/elfutils/libelf/gelf_getnote.c
new file mode 100644
index 0000000..c75edda
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getnote.c
@@ -0,0 +1,100 @@
+/* Get note information at the supplied offset.
+   Copyright (C) 2007, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+size_t
+gelf_getnote (Elf_Data *data, size_t offset, GElf_Nhdr *result,
+	      size_t *name_offset, size_t *desc_offset)
+{
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (data->d_type != ELF_T_NHDR))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  */
+  assert (sizeof (GElf_Nhdr) == sizeof (Elf32_Nhdr));
+  assert (sizeof (GElf_Nhdr) == sizeof (Elf64_Nhdr));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     offset is OK.  */
+  if (unlikely (offset > data->d_size
+		|| data->d_size - offset < sizeof (GElf_Nhdr)))
+    {
+      __libelf_seterrno (ELF_E_OFFSET_RANGE);
+      offset = 0;
+    }
+  else
+    {
+      const GElf_Nhdr *n = data->d_buf + offset;
+      offset += sizeof *n;
+
+      /* Include padding.  Check below for overflow.  */
+      GElf_Word namesz = NOTE_ALIGN (n->n_namesz);
+      GElf_Word descsz = NOTE_ALIGN (n->n_descsz);
+
+      if (unlikely (offset > data->d_size
+		    || data->d_size - offset < namesz
+		    || (namesz == 0 && n->n_namesz != 0)))
+	offset = 0;
+      else
+	{
+	  *name_offset = offset;
+	  offset += namesz;
+	  if (unlikely (offset > data->d_size
+			|| data->d_size - offset < descsz
+			|| (descsz == 0 && n->n_descsz != 0)))
+	    offset = 0;
+	  else
+	    {
+	      *desc_offset = offset;
+	      offset += descsz;
+	      *result = *n;
+	    }
+	}
+    }
+
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return offset;
+}
diff --git a/third_party/elfutils/libelf/gelf_getphdr.c b/third_party/elfutils/libelf/gelf_getphdr.c
new file mode 100644
index 0000000..c719e4b
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getphdr.c
@@ -0,0 +1,135 @@
+/* Return program header table entry.
+   Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "libelfP.h"
+
+
+GElf_Phdr *
+gelf_getphdr (Elf *elf, int ndx, GElf_Phdr *dst)
+{
+  GElf_Phdr *result = NULL;
+
+  if (elf == NULL)
+    return NULL;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  if (dst == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return NULL;
+    }
+
+  rwlock_rdlock (elf->lock);
+
+  if (elf->class == ELFCLASS32)
+    {
+      /* Copy the elements one-by-one.  */
+      Elf32_Phdr *phdr = elf->state.elf32.phdr;
+
+      if (phdr == NULL)
+	{
+	  rwlock_unlock (elf->lock);
+	  phdr = INTUSE(elf32_getphdr) (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    return NULL;
+	  rwlock_rdlock (elf->lock);
+	}
+
+      /* Test whether the index is ok.  */
+      size_t phnum;
+      if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0
+	  || (size_t) ndx >= phnum)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      /* We know the result now.  */
+      result = dst;
+
+      /* Now correct the pointer to point to the correct element.  */
+      phdr += ndx;
+
+#define COPY(Name) result->Name = phdr->Name
+      COPY (p_type);
+      COPY (p_offset);
+      COPY (p_vaddr);
+      COPY (p_paddr);
+      COPY (p_filesz);
+      COPY (p_memsz);
+      COPY (p_flags);
+      COPY (p_align);
+    }
+  else
+    {
+      /* Copy the elements one-by-one.  */
+      Elf64_Phdr *phdr = elf->state.elf64.phdr;
+
+      if (phdr == NULL)
+	{
+	  rwlock_unlock (elf->lock);
+	  phdr = INTUSE(elf64_getphdr) (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    return NULL;
+	  rwlock_rdlock (elf->lock);
+	}
+
+      /* Test whether the index is ok.  */
+      size_t phnum;
+      if (__elf_getphdrnum_chk_rdlock (elf, &phnum) != 0
+	  || (size_t) ndx >= phnum)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      /* We only have to copy the data.  */
+      result = memcpy (dst, phdr + ndx, sizeof (GElf_Phdr));
+    }
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getrel.c b/third_party/elfutils/libelf/gelf_getrel.c
new file mode 100644
index 0000000..309e3d3
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getrel.c
@@ -0,0 +1,99 @@
+/* Get REL relocation information at given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Rel *
+gelf_getrel (Elf_Data *data, int ndx, GElf_Rel *dst)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  GElf_Rel *result;
+
+  if (data_scn == NULL)
+    return NULL;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_REL))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  scn = data_scn->s;
+
+  rwlock_rdlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      /* We have to convert the data.  */
+      if (INVALID_NDX (ndx, Elf32_Rel, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  result = NULL;
+	}
+      else
+	{
+	  Elf32_Rel *src = &((Elf32_Rel *) data_scn->d.d_buf)[ndx];
+
+	  dst->r_offset = src->r_offset;
+	  dst->r_info = GELF_R_INFO (ELF32_R_SYM (src->r_info),
+				     ELF32_R_TYPE (src->r_info));
+
+	  result = dst;
+	}
+    }
+  else
+    {
+      /* Simply copy the data after we made sure we are actually getting
+	 correct data.  */
+      if (INVALID_NDX (ndx, Elf64_Rel, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  result = NULL;
+	}
+      else
+	result = memcpy (dst, &((Elf64_Rel *) data_scn->d.d_buf)[ndx],
+			 sizeof (Elf64_Rel));
+    }
+
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getrela.c b/third_party/elfutils/libelf/gelf_getrela.c
new file mode 100644
index 0000000..d695f65
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getrela.c
@@ -0,0 +1,100 @@
+/* Get RELA relocation information at given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Rela *
+gelf_getrela (Elf_Data *data, int ndx, GElf_Rela *dst)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  GElf_Rela *result;
+
+  if (data_scn == NULL)
+    return NULL;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_RELA))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  scn = data_scn->s;
+
+  rwlock_rdlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      /* We have to convert the data.  */
+      if (INVALID_NDX (ndx, Elf32_Rela, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  result = NULL;
+	}
+      else
+	{
+	  Elf32_Rela *src = &((Elf32_Rela *) data_scn->d.d_buf)[ndx];
+
+	  dst->r_offset = src->r_offset;
+	  dst->r_info = GELF_R_INFO (ELF32_R_SYM (src->r_info),
+				     ELF32_R_TYPE (src->r_info));
+	  dst->r_addend = src->r_addend;
+
+	  result = dst;
+	}
+    }
+  else
+    {
+      /* Simply copy the data after we made sure we are actually getting
+	 correct data.  */
+      if (INVALID_NDX (ndx, Elf64_Rela, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  result = NULL;
+	}
+      else
+	result = memcpy (dst, &((Elf64_Rela *) data_scn->d.d_buf)[ndx],
+			 sizeof (Elf64_Rela));
+    }
+
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getshdr.c b/third_party/elfutils/libelf/gelf_getshdr.c
new file mode 100644
index 0000000..3858c8e
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getshdr.c
@@ -0,0 +1,103 @@
+/* Return section header.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Shdr *
+gelf_getshdr (Elf_Scn *scn, GElf_Shdr *dst)
+{
+  GElf_Shdr *result = NULL;
+
+  if (scn == NULL)
+    return NULL;
+
+  if (dst == NULL)
+    {
+      __libelf_seterrno (ELF_E_INVALID_OPERAND);
+      return NULL;
+    }
+
+  rwlock_rdlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      /* Copy the elements one-by-one.  */
+      Elf32_Shdr *shdr
+	= scn->shdr.e32 ?: __elf32_getshdr_rdlock (scn);
+
+      if (shdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
+	  goto out;
+	}
+
+#define COPY(name) \
+      dst->name = shdr->name
+      COPY (sh_name);
+      COPY (sh_type);
+      COPY (sh_flags);
+      COPY (sh_addr);
+      COPY (sh_offset);
+      COPY (sh_size);
+      COPY (sh_link);
+      COPY (sh_info);
+      COPY (sh_addralign);
+      COPY (sh_entsize);
+
+      result = dst;
+    }
+  else
+    {
+      Elf64_Shdr *shdr
+	= scn->shdr.e64 ?: __elf64_getshdr_rdlock (scn);
+
+      if (shdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
+	  goto out;
+	}
+
+      /* We only have to copy the data.  */
+      result = memcpy (dst, shdr, sizeof (GElf_Shdr));
+    }
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
+INTDEF(gelf_getshdr)
diff --git a/third_party/elfutils/libelf/gelf_getsym.c b/third_party/elfutils/libelf/gelf_getsym.c
new file mode 100644
index 0000000..01534d2
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getsym.c
@@ -0,0 +1,114 @@
+/* Get symbol information from symbol table at the given index.
+   Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Sym *
+gelf_getsym (Elf_Data *data, int ndx, GElf_Sym *dst)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  GElf_Sym *result = NULL;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_SYM))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_rdlock (data_scn->s->elf->lock);
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  if (data_scn->s->elf->class == ELFCLASS32)
+    {
+      Elf32_Sym *src;
+
+      /* Here it gets a bit more complicated.  The format of the symbol
+	 table entries has to be adopted.  The user better has provided
+	 a buffer where we can store the information.  While copying the
+	 data we are converting the format.  */
+      if (INVALID_NDX (ndx, Elf32_Sym, data))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      src = &((Elf32_Sym *) data->d_buf)[ndx];
+
+      /* This might look like a simple copy operation but it's
+	 not.  There are zero- and sign-extensions going on.  */
+#define COPY(name) \
+      dst->name = src->name
+      COPY (st_name);
+      /* Please note that we can simply copy the `st_info' element since
+	 the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same
+	 for the 64 bit variant.  */
+      COPY (st_info);
+      COPY (st_other);
+      COPY (st_shndx);
+      COPY (st_value);
+      COPY (st_size);
+    }
+  else
+    {
+      /* If this is a 64 bit object it's easy.  */
+      assert (sizeof (GElf_Sym) == sizeof (Elf64_Sym));
+
+      /* The data is already in the correct form.  Just make sure the
+	 index is OK.  */
+      if (INVALID_NDX (ndx, GElf_Sym, data))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      *dst = ((GElf_Sym *) data->d_buf)[ndx];
+    }
+
+  result = dst;
+
+ out:
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return result;
+}
+INTDEF(gelf_getsym)
diff --git a/third_party/elfutils/libelf/gelf_getsyminfo.c b/third_party/elfutils/libelf/gelf_getsyminfo.c
new file mode 100644
index 0000000..8360ed3
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getsyminfo.c
@@ -0,0 +1,77 @@
+/* Get additional symbol information from symbol table at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Syminfo *
+gelf_getsyminfo (Elf_Data *data, int ndx, GElf_Syminfo *dst)
+{
+  GElf_Syminfo *result = NULL;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_SYMINFO))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Syminfo) == sizeof (Elf32_Syminfo));
+  assert (sizeof (GElf_Syminfo) == sizeof (Elf64_Syminfo));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (INVALID_NDX (ndx, GElf_Syminfo, data))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      goto out;
+    }
+
+  *dst = ((GElf_Syminfo *) data->d_buf)[ndx];
+
+  result = dst;
+
+ out:
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getsymshndx.c b/third_party/elfutils/libelf/gelf_getsymshndx.c
new file mode 100644
index 0000000..17c90fc
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getsymshndx.c
@@ -0,0 +1,136 @@
+/* Get symbol information and separate section index from symbol table
+   at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Sym *
+gelf_getsymshndx (Elf_Data *symdata, Elf_Data *shndxdata, int ndx,
+		  GElf_Sym *dst, Elf32_Word *dstshndx)
+{
+  Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata;
+  Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata;
+  GElf_Sym *result = NULL;
+  Elf32_Word shndx = 0;
+
+  if (symdata == NULL)
+    return NULL;
+
+  if (unlikely (symdata->d_type != ELF_T_SYM)
+      || (likely (shndxdata_scn != NULL)
+	  && unlikely (shndxdata->d_type != ELF_T_WORD)))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  rwlock_rdlock (symdata_scn->s->elf->lock);
+
+  /* The user is not required to pass a data descriptor for an extended
+     section index table.  */
+  if (likely (shndxdata_scn != NULL))
+    {
+      if (INVALID_NDX (ndx, Elf32_Word, &shndxdata_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      shndx = ((Elf32_Word *) shndxdata_scn->d.d_buf)[ndx];
+    }
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  if (symdata_scn->s->elf->class == ELFCLASS32)
+    {
+      Elf32_Sym *src;
+
+      /* Here it gets a bit more complicated.  The format of the symbol
+	 table entries has to be adopted.  The user better has provided
+	 a buffer where we can store the information.  While copying the
+	 data we are converting the format.  */
+      if (INVALID_NDX (ndx, Elf32_Sym, symdata))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      src = &((Elf32_Sym *) symdata->d_buf)[ndx];
+
+      /* This might look like a simple copy operation but it's
+	 not.  There are zero- and sign-extensions going on.  */
+#define COPY(name) \
+      dst->name = src->name
+      COPY (st_name);
+      /* Please note that we can simply copy the `st_info' element since
+	 the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same
+	 for the 64 bit variant.  */
+      COPY (st_info);
+      COPY (st_other);
+      COPY (st_shndx);
+      COPY (st_value);
+      COPY (st_size);
+    }
+  else
+    {
+      /* If this is a 64 bit object it's easy.  */
+      assert (sizeof (GElf_Sym) == sizeof (Elf64_Sym));
+
+      /* The data is already in the correct form.  Just make sure the
+	 index is OK.  */
+      if (INVALID_NDX (ndx, GElf_Sym, symdata))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      *dst = ((GElf_Sym *) symdata->d_buf)[ndx];
+    }
+
+  /* Now we can store the section index.  */
+  if (dstshndx != NULL)
+    *dstshndx = shndx;
+
+  result = dst;
+
+ out:
+  rwlock_unlock (symdata_scn->s->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getverdaux.c b/third_party/elfutils/libelf/gelf_getverdaux.c
new file mode 100644
index 0000000..739a765
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getverdaux.c
@@ -0,0 +1,79 @@
+/* Get additional symbol version definition information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verdaux *
+gelf_getverdaux (Elf_Data *data, int offset, GElf_Verdaux *dst)
+{
+  GElf_Verdaux *result;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_VDEF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  */
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux));
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (unlikely (offset < 0)
+      || unlikely (offset + sizeof (GElf_Verdaux) > data->d_size)
+      || unlikely (offset % __alignof__ (GElf_Verdaux) != 0))
+    {
+      __libelf_seterrno (ELF_E_OFFSET_RANGE);
+      result = NULL;
+    }
+  else
+    result = (GElf_Verdaux *) memcpy (dst, (char *) data->d_buf + offset,
+				      sizeof (GElf_Verdaux));
+
+
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getverdef.c b/third_party/elfutils/libelf/gelf_getverdef.c
new file mode 100644
index 0000000..651f4fa
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getverdef.c
@@ -0,0 +1,78 @@
+/* Get symbol version definition information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verdef *
+gelf_getverdef (Elf_Data *data, int offset, GElf_Verdef *dst)
+{
+  GElf_Verdef *result;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_VDEF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  */
+  assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef));
+  assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (unlikely (offset < 0)
+      || unlikely (offset + sizeof (GElf_Verdef) > data->d_size)
+      || unlikely (offset % __alignof__ (GElf_Verdef) != 0))
+    {
+      __libelf_seterrno (ELF_E_OFFSET_RANGE);
+      result = NULL;
+    }
+  else
+    result = (GElf_Verdef *) memcpy (dst, (char *) data->d_buf + offset,
+				     sizeof (GElf_Verdef));
+
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getvernaux.c b/third_party/elfutils/libelf/gelf_getvernaux.c
new file mode 100644
index 0000000..e47fb0a
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getvernaux.c
@@ -0,0 +1,81 @@
+/* Get additional required symbol version information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Vernaux *
+gelf_getvernaux (Elf_Data *data, int offset, GElf_Vernaux *dst)
+{
+  GElf_Vernaux *result;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_VNEED))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  And fortunately the `ElfXXX_Vernaux' records
+     also have the same size.  */
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Verneed));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Verneed));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (unlikely (offset < 0)
+      || unlikely (offset + sizeof (GElf_Vernaux) > data->d_size)
+      || unlikely (offset % sizeof (GElf_Vernaux) != 0))
+    {
+      __libelf_seterrno (ELF_E_OFFSET_RANGE);
+      result = NULL;
+    }
+  else
+    result = (GElf_Vernaux *) memcpy (dst, (char *) data->d_buf + offset,
+				      sizeof (GElf_Verneed));
+
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getverneed.c b/third_party/elfutils/libelf/gelf_getverneed.c
new file mode 100644
index 0000000..c1f5d34
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getverneed.c
@@ -0,0 +1,81 @@
+/* Get required symbol version information at the given offset.
+   Copyright (C) 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Verneed *
+gelf_getverneed (Elf_Data *data, int offset, GElf_Verneed *dst)
+{
+  GElf_Verneed *result;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_VNEED))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  And fortunately the `ElfXXX_Vernaux' records
+     also have the same size.  */
+  assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed));
+  assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed));
+  assert (sizeof (GElf_Verneed) == sizeof (Elf32_Vernaux));
+  assert (sizeof (GElf_Verneed) == sizeof (Elf64_Vernaux));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (unlikely (offset < 0)
+      || unlikely (offset + sizeof (GElf_Verneed) > data->d_size)
+      || unlikely (offset % sizeof (GElf_Verneed) != 0))
+    {
+      __libelf_seterrno (ELF_E_OFFSET_RANGE);
+      result = NULL;
+    }
+  else
+    result = (GElf_Verneed *) memcpy (dst, (char *) data->d_buf + offset,
+				      sizeof (GElf_Verneed));
+
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_getversym.c b/third_party/elfutils/libelf/gelf_getversym.c
new file mode 100644
index 0000000..68d23c7
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_getversym.c
@@ -0,0 +1,86 @@
+/* Get symbol version information at the given index.
+   Copyright (C) 1999, 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+GElf_Versym *
+gelf_getversym (Elf_Data *data, int ndx, GElf_Versym *dst)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  GElf_Versym *result;
+
+  if (data == NULL)
+    return NULL;
+
+  if (unlikely (data->d_type != ELF_T_HALF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return NULL;
+    }
+
+  /* This is the one place where we have to take advantage of the fact
+     that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'.
+     The interface is broken so that it requires this hack.  */
+  scn = data_scn->s;
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  */
+  assert (sizeof (GElf_Versym) == sizeof (Elf32_Versym));
+  assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym));
+
+  rwlock_rdlock (scn->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     index is OK.  */
+  if (INVALID_NDX (ndx, GElf_Versym, data))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      result = NULL;
+    }
+  else
+    {
+      *dst = ((GElf_Versym *) data->d_buf)[ndx];
+
+      result = dst;
+    }
+
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_newehdr.c b/third_party/elfutils/libelf/gelf_newehdr.c
new file mode 100644
index 0000000..2788906
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_newehdr.c
@@ -0,0 +1,46 @@
+/* Create new ELF header.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+void *
+gelf_newehdr (Elf *elf, int class)
+{
+  return (class == ELFCLASS32
+	  ? (void *) INTUSE(elf32_newehdr) (elf)
+	  : (void *) INTUSE(elf64_newehdr) (elf));
+}
diff --git a/third_party/elfutils/libelf/gelf_newphdr.c b/third_party/elfutils/libelf/gelf_newphdr.c
new file mode 100644
index 0000000..84aad78
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_newphdr.c
@@ -0,0 +1,46 @@
+/* Create new ELF program header.
+   Copyright (C) 1998, 1999, 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+void *
+gelf_newphdr ( Elf *elf, size_t phnum)
+{
+  return (elf->class == ELFCLASS32
+	  ? (void *) INTUSE(elf32_newphdr) (elf, phnum)
+	  : (void *) INTUSE(elf64_newphdr) (elf, phnum));
+}
diff --git a/third_party/elfutils/libelf/gelf_offscn.c b/third_party/elfutils/libelf/gelf_offscn.c
new file mode 100644
index 0000000..cf206f5
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_offscn.c
@@ -0,0 +1,55 @@
+/* Create new ELF header.
+   Copyright (C) 2005, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+Elf_Scn *
+gelf_offscn (Elf *elf, GElf_Off offset)
+{
+  if (elf->class == ELFCLASS32)
+    {
+      if ((Elf32_Off) offset != offset)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OFFSET);
+	  return NULL;
+	}
+
+      return INTUSE(elf32_offscn) (elf, (Elf32_Off) offset);
+    }
+
+  return INTUSE(elf64_offscn) (elf, offset);
+}
diff --git a/third_party/elfutils/libelf/gelf_update_auxv.c b/third_party/elfutils/libelf/gelf_update_auxv.c
new file mode 100644
index 0000000..e4e5229
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_auxv.c
@@ -0,0 +1,111 @@
+/* Update information in dynamic table at the given index.
+   Copyright (C) 2007, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_auxv (Elf_Data *data, int ndx, GElf_auxv_t *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (ndx < 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_AUXV))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_auxv_t *auxv;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->a_type > 0xffffffffll)
+	  || unlikely (src->a_un.a_val > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      auxv = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx];
+
+      auxv->a_type = src->a_type;
+      auxv->a_un.a_val = src->a_un.a_val;
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (unlikely ((ndx + 1) * sizeof (Elf64_auxv_t) > data_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_auxv_t *) data_scn->d.d_buf)[ndx] = *src;
+    }
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_dyn.c b/third_party/elfutils/libelf/gelf_update_dyn.c
new file mode 100644
index 0000000..5c515d2
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_dyn.c
@@ -0,0 +1,107 @@
+/* Update information in dynamic table at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_dyn (Elf_Data *data, int ndx, GElf_Dyn *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_DYN))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Dyn *dyn;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->d_tag < -0x80000000ll)
+	  || unlikely (src->d_tag > 0x7fffffffll)
+	  || unlikely (src->d_un.d_val > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Check whether we have to resize the data buffer.  */
+      if (INVALID_NDX (ndx, Elf32_Dyn, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      dyn = &((Elf32_Dyn *) data_scn->d.d_buf)[ndx];
+
+      dyn->d_tag = src->d_tag;
+      dyn->d_un.d_val = src->d_un.d_val;
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (INVALID_NDX (ndx, Elf64_Dyn, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_Dyn *) data_scn->d.d_buf)[ndx] = *src;
+    }
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_ehdr.c b/third_party/elfutils/libelf/gelf_update_ehdr.c
new file mode 100644
index 0000000..73d5af7
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_ehdr.c
@@ -0,0 +1,118 @@
+/* Update ELF header.
+   Copyright (C) 2000, 2001, 2002, 2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_ehdr (Elf *elf, GElf_Ehdr *src)
+{
+  int result = 0;
+
+  if (elf == NULL)
+    return 0;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Ehdr *ehdr = elf->state.elf32.ehdr;
+
+      if (ehdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+	  goto out;
+	}
+
+      /* We have to convert the data to the 32 bit format.  This might
+	 overflow some fields so we have to test for this case before
+	 copying.  */
+      if (unlikely (src->e_entry > 0xffffffffull)
+	  || unlikely (src->e_phoff > 0xffffffffull)
+	  || unlikely (src->e_shoff > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Copy the data.  */
+      memcpy (ehdr->e_ident, src->e_ident, EI_NIDENT);
+#define COPY(name) \
+      ehdr->name = src->name
+      COPY (e_type);
+      COPY (e_machine);
+      COPY (e_version);
+      COPY (e_entry);
+      COPY (e_phoff);
+      COPY (e_shoff);
+      COPY (e_flags);
+      COPY (e_ehsize);
+      COPY (e_phentsize);
+      COPY (e_phnum);
+      COPY (e_shentsize);
+      COPY (e_shnum);
+      COPY (e_shstrndx);
+    }
+  else
+    {
+      Elf64_Ehdr *ehdr = elf->state.elf64.ehdr;
+
+      if (ehdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_WRONG_ORDER_EHDR);
+	  goto out;
+	}
+
+      /* Just copy the data.  */
+      memcpy (ehdr, src, sizeof (Elf64_Ehdr));
+    }
+
+  /* Mark the ELF header as modified.  */
+  elf->state.elf.ehdr_flags |= ELF_F_DIRTY;
+
+  result = 1;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_lib.c b/third_party/elfutils/libelf/gelf_update_lib.c
new file mode 100644
index 0000000..d0f235e
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_lib.c
@@ -0,0 +1,75 @@
+/* Update library in table at the given index.
+   Copyright (C) 2004, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_lib (Elf_Data *data, int ndx, GElf_Lib *src)
+{
+  if (data == NULL)
+    return 0;
+
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  if (unlikely (data_scn->d.d_type != ELF_T_LIB))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  Elf_Scn *scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  /* Check whether we have to resize the data buffer.  */
+  int result = 0;
+  if (INVALID_NDX (ndx, Elf64_Lib, &data_scn->d))
+    __libelf_seterrno (ELF_E_INVALID_INDEX);
+  else
+    {
+      ((Elf64_Lib *) data_scn->d.d_buf)[ndx] = *src;
+
+      result = 1;
+
+      /* Mark the section as modified.  */
+      scn->flags |= ELF_F_DIRTY;
+    }
+
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_move.c b/third_party/elfutils/libelf/gelf_update_move.c
new file mode 100644
index 0000000..4190ee3
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_move.c
@@ -0,0 +1,77 @@
+/* Update move structure at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_move (Elf_Data *data, int ndx, GElf_Move *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Move) == sizeof (Elf32_Move));
+  assert (sizeof (GElf_Move) == sizeof (Elf64_Move));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (INVALID_NDX (ndx, GElf_Move, &data_scn->d))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_MOVE))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  ((GElf_Move *) data_scn->d.d_buf)[ndx] = *src;
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_phdr.c b/third_party/elfutils/libelf/gelf_update_phdr.c
new file mode 100644
index 0000000..a848677
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_phdr.c
@@ -0,0 +1,143 @@
+/* Update program header program header table entry.
+   Copyright (C) 2000-2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_phdr (Elf *elf, int ndx, GElf_Phdr *src)
+{
+  int result = 0;
+
+  if (elf == NULL)
+    return 0;
+
+  if (unlikely (elf->kind != ELF_K_ELF))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  rwlock_wrlock (elf->lock);
+
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Phdr *phdr = elf->state.elf32.phdr;
+
+      /* We have to convert the data to the 32 bit format.  This might
+	 overflow some fields so we have to test for this case before
+	 copying.  */
+      if (unlikely (src->p_offset > 0xffffffffull)
+	  || unlikely (src->p_vaddr > 0xffffffffull)
+	  || unlikely (src->p_paddr > 0xffffffffull)
+	  || unlikely (src->p_filesz > 0xffffffffull)
+	  || unlikely (src->p_memsz > 0xffffffffull)
+	  || unlikely (src->p_align > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      if (phdr == NULL)
+	{
+	  phdr = __elf32_getphdr_wrlock (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    goto out;
+	}
+
+      /* Test whether the index is ok.  */
+      size_t phnum;
+      if (ndx >= elf->state.elf32.ehdr->e_phnum
+	  && (elf->state.elf32.ehdr->e_phnum != PN_XNUM
+	      || __elf_getphdrnum_rdlock (elf, &phnum) != 0
+	      || (size_t) ndx >= phnum))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      /* Now correct the pointer to point to the correct element.  */
+      phdr += ndx;
+
+#define COPY(name) \
+      phdr->name = src->name
+      COPY (p_type);
+      COPY (p_offset);
+      COPY (p_vaddr);
+      COPY (p_paddr);
+      COPY (p_filesz);
+      COPY (p_memsz);
+      COPY (p_flags);
+      COPY (p_align);
+    }
+  else
+    {
+      Elf64_Phdr *phdr = elf->state.elf64.phdr;
+
+      if (phdr == NULL)
+	{
+	  phdr = __elf64_getphdr_wrlock (elf);
+	  if (phdr == NULL)
+	    /* The error number is already set.  */
+	    goto out;
+	}
+
+      /* Test whether the index is ok.  */
+      size_t phnum;
+      if (ndx >= elf->state.elf64.ehdr->e_phnum
+	  && (elf->state.elf64.ehdr->e_phnum != PN_XNUM
+	      || __elf_getphdrnum_rdlock (elf, &phnum) != 0
+	      || (size_t) ndx >= phnum))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      /* Just copy the data.  */
+      memcpy (phdr + ndx, src, sizeof (Elf64_Phdr));
+    }
+
+  /* Mark the program header as modified.  */
+  elf->state.elf.phdr_flags |= ELF_F_DIRTY;
+
+  result = 1;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_rel.c b/third_party/elfutils/libelf/gelf_update_rel.c
new file mode 100644
index 0000000..14f62e9
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_rel.c
@@ -0,0 +1,108 @@
+/* Update REL relocation information at given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_rel (Elf_Data *dst, int ndx, GElf_Rel *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) dst;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (dst == NULL)
+    return 0;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_REL))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Rel *rel;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->r_offset > 0xffffffffull)
+	  || unlikely (GELF_R_SYM (src->r_info) > 0xffffff)
+	  || unlikely (GELF_R_TYPE (src->r_info) > 0xff))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Check whether we have to resize the data buffer.  */
+      if (INVALID_NDX (ndx, Elf32_Rel, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      rel = &((Elf32_Rel *) data_scn->d.d_buf)[ndx];
+
+      rel->r_offset = src->r_offset;
+      rel->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info),
+				  GELF_R_TYPE (src->r_info));
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (INVALID_NDX (ndx, Elf64_Rel, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_Rel *) data_scn->d.d_buf)[ndx] = *src;
+    }
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_rela.c b/third_party/elfutils/libelf/gelf_update_rela.c
new file mode 100644
index 0000000..8825270
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_rela.c
@@ -0,0 +1,111 @@
+/* Update RELA relocation information at given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_rela (Elf_Data *dst, int ndx, GElf_Rela *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) dst;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (dst == NULL)
+    return 0;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_RELA))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Rela *rel;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->r_offset > 0xffffffffull)
+	  || unlikely (GELF_R_SYM (src->r_info) > 0xffffff)
+	  || unlikely (GELF_R_TYPE (src->r_info) > 0xff)
+	  || unlikely (src->r_addend < -0x80000000ll)
+	  || unlikely (src->r_addend > 0x7fffffffll))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Check whether we have to resize the data buffer.  */
+      if (INVALID_NDX (ndx, Elf32_Rela, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      rel = &((Elf32_Rela *) data_scn->d.d_buf)[ndx];
+
+      rel->r_offset = src->r_offset;
+      rel->r_info = ELF32_R_INFO (GELF_R_SYM (src->r_info),
+				  GELF_R_TYPE (src->r_info));
+      rel->r_addend = src->r_addend;
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (INVALID_NDX (ndx, Elf64_Rela, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_Rela *) data_scn->d.d_buf)[ndx] = *src;
+    }
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_shdr.c b/third_party/elfutils/libelf/gelf_update_shdr.c
new file mode 100644
index 0000000..c93c6ec
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_shdr.c
@@ -0,0 +1,111 @@
+/* Update section header.
+   Copyright (C) 2000, 2001, 2002, 2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_shdr (Elf_Scn *scn, GElf_Shdr *src)
+{
+  int result = 0;
+  Elf *elf;
+
+  if (scn == NULL || src == NULL)
+    return 0;
+
+  elf = scn->elf;
+  rwlock_wrlock (elf->lock);
+
+  if (elf->class == ELFCLASS32)
+    {
+      Elf32_Shdr *shdr
+	= scn->shdr.e32 ?: __elf32_getshdr_wrlock (scn);
+
+      if (shdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
+	  goto out;
+	}
+
+      if (unlikely (src->sh_flags > 0xffffffffull)
+	  || unlikely (src->sh_addr > 0xffffffffull)
+	  || unlikely (src->sh_offset > 0xffffffffull)
+	  || unlikely (src->sh_size > 0xffffffffull)
+	  || unlikely (src->sh_addralign > 0xffffffffull)
+	  || unlikely (src->sh_entsize > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+#define COPY(name) \
+      shdr->name = src->name
+      COPY (sh_name);
+      COPY (sh_type);
+      COPY (sh_flags);
+      COPY (sh_addr);
+      COPY (sh_offset);
+      COPY (sh_size);
+      COPY (sh_link);
+      COPY (sh_info);
+      COPY (sh_addralign);
+      COPY (sh_entsize);
+    }
+  else
+    {
+      Elf64_Shdr *shdr
+	= scn->shdr.e64 ?: __elf64_getshdr_wrlock (scn);
+
+      if (shdr == NULL)
+	{
+	  __libelf_seterrno (ELF_E_INVALID_OPERAND);
+	  goto out;
+	}
+
+      /* We only have to copy the data.  */
+      (void) memcpy (shdr, src, sizeof (GElf_Shdr));
+    }
+
+  /* Mark the section header as modified.  */
+  scn->shdr_flags |= ELF_F_DIRTY;
+
+  result = 1;
+
+ out:
+  rwlock_unlock (elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_sym.c b/third_party/elfutils/libelf/gelf_update_sym.c
new file mode 100644
index 0000000..0f47885
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_sym.c
@@ -0,0 +1,116 @@
+/* Update symbol information in symbol table at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_sym (Elf_Data *data, int ndx, GElf_Sym *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_SYM))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Sym *sym;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->st_value > 0xffffffffull)
+	  || unlikely (src->st_size > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Check whether we have to resize the data buffer.  */
+      if (INVALID_NDX (ndx, Elf32_Sym, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      sym = &((Elf32_Sym *) data_scn->d.d_buf)[ndx];
+
+#define COPY(name) \
+      sym->name = src->name
+      COPY (st_name);
+      COPY (st_value);
+      COPY (st_size);
+      /* Please note that we can simply copy the `st_info' element since
+	 the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same
+	 for the 64 bit variant.  */
+      COPY (st_info);
+      COPY (st_other);
+      COPY (st_shndx);
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (INVALID_NDX (ndx, Elf64_Sym, &data_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_Sym *) data_scn->d.d_buf)[ndx] = *src;
+    }
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_syminfo.c b/third_party/elfutils/libelf/gelf_update_syminfo.c
new file mode 100644
index 0000000..6f7f302
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_syminfo.c
@@ -0,0 +1,83 @@
+/* Update additional symbol information in symbol table at the given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_syminfo (Elf_Data *data, int ndx, GElf_Syminfo *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+  Elf_Scn *scn;
+  int result = 0;
+
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (data_scn->d.d_type != ELF_T_SYMINFO))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Syminfo) == sizeof (Elf32_Syminfo));
+  assert (sizeof (GElf_Syminfo) == sizeof (Elf64_Syminfo));
+
+  scn = data_scn->s;
+  rwlock_wrlock (scn->elf->lock);
+
+  /* Check whether we have to resize the data buffer.  */
+  if (INVALID_NDX (ndx, GElf_Syminfo, &data_scn->d))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      goto out;
+    }
+
+  ((GElf_Syminfo *) data_scn->d.d_buf)[ndx] = *src;
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_symshndx.c b/third_party/elfutils/libelf/gelf_update_symshndx.c
new file mode 100644
index 0000000..eb80afa
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_symshndx.c
@@ -0,0 +1,145 @@
+/* Update symbol information and section index in symbol table at the
+   given index.
+   Copyright (C) 2000, 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_symshndx (Elf_Data *symdata, Elf_Data *shndxdata, int ndx,
+		      GElf_Sym *src, Elf32_Word srcshndx)
+{
+  Elf_Data_Scn *symdata_scn = (Elf_Data_Scn *) symdata;
+  Elf_Data_Scn *shndxdata_scn = (Elf_Data_Scn *) shndxdata;
+  Elf_Scn *scn;
+  Elf32_Word *shndx = NULL;
+  int result = 0;
+
+  if (symdata == NULL)
+    return 0;
+
+  if (unlikely (symdata_scn->d.d_type != ELF_T_SYM))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  scn = symdata_scn->s;
+  /* We simply have to believe the user that the two sections belong to
+     the same ELF file.  */
+  rwlock_wrlock (scn->elf->lock);
+
+  /* The user is not required to pass a data descriptor for an extended
+     section index table.  */
+  if (shndxdata_scn != NULL)
+    {
+      if (unlikely ((ndx + 1) * sizeof (Elf32_Word) > shndxdata_scn->d.d_size))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      shndx = &((Elf32_Word *) shndxdata_scn->d.d_buf)[ndx];
+    }
+  /* But if s/he does not the extended sectio index must be zero.  */
+  else if (unlikely (srcshndx != 0))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      goto out;
+    }
+
+  if (scn->elf->class == ELFCLASS32)
+    {
+      Elf32_Sym *sym;
+
+      /* There is the possibility that the values in the input are
+	 too large.  */
+      if (unlikely (src->st_value > 0xffffffffull)
+	  || unlikely (src->st_size > 0xffffffffull))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_DATA);
+	  goto out;
+	}
+
+      /* Check whether we have to resize the data buffer.  */
+      if (INVALID_NDX (ndx, Elf32_Sym, &symdata_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      sym = &((Elf32_Sym *) symdata_scn->d.d_buf)[ndx];
+
+#define COPY(name) \
+      sym->name = src->name
+      COPY (st_name);
+      COPY (st_value);
+      COPY (st_size);
+      /* Please note that we can simply copy the `st_info' element since
+	 the definitions of ELFxx_ST_BIND and ELFxx_ST_TYPE are the same
+	 for the 64 bit variant.  */
+      COPY (st_info);
+      COPY (st_other);
+      COPY (st_shndx);
+    }
+  else
+    {
+      /* Check whether we have to resize the data buffer.  */
+      if (INVALID_NDX (ndx, Elf64_Sym, &symdata_scn->d))
+	{
+	  __libelf_seterrno (ELF_E_INVALID_INDEX);
+	  goto out;
+	}
+
+      ((Elf64_Sym *) symdata_scn->d.d_buf)[ndx] = *src;
+    }
+
+  /* Now we can store the section index.  */
+  if (shndx != NULL)
+    *shndx = srcshndx;
+
+  result = 1;
+
+  /* Mark the section as modified.  */
+  scn->flags |= ELF_F_DIRTY;
+
+ out:
+  rwlock_unlock (scn->elf->lock);
+
+  return result;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_verdaux.c b/third_party/elfutils/libelf/gelf_update_verdaux.c
new file mode 100644
index 0000000..f3554fd
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_verdaux.c
@@ -0,0 +1,78 @@
+/* Update additional symbol version definition information.
+   Copyright (C) 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verdaux (Elf_Data *data, int offset, GElf_Verdaux *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux));
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (unlikely (offset < 0)
+      || unlikely ((offset + sizeof (GElf_Verdaux)) > data_scn->d.d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_VDEF))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verdaux));
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_verdef.c b/third_party/elfutils/libelf/gelf_update_verdef.c
new file mode 100644
index 0000000..adb5db1
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_verdef.c
@@ -0,0 +1,78 @@
+/* Update symbol version definition information.
+   Copyright (C) 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verdef (Elf_Data *data, int offset, GElf_Verdef *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef));
+  assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (unlikely (offset < 0)
+      || unlikely ((offset + sizeof (GElf_Verdef)) > data_scn->d.d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_VDEF))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verdef));
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_vernaux.c b/third_party/elfutils/libelf/gelf_update_vernaux.c
new file mode 100644
index 0000000..854afab
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_vernaux.c
@@ -0,0 +1,78 @@
+/* Update additional required symbol version information.
+   Copyright (C) 2001, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_vernaux (Elf_Data *data, int offset, GElf_Vernaux *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (unlikely (offset < 0)
+      || unlikely ((offset + sizeof (GElf_Vernaux)) > data_scn->d.d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_VNEED))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Vernaux));
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_verneed.c b/third_party/elfutils/libelf/gelf_update_verneed.c
new file mode 100644
index 0000000..bf5af5a
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_verneed.c
@@ -0,0 +1,78 @@
+/* Update required symbol version information.
+   Copyright (C) 2001, 2002, 201r Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_verneed (Elf_Data *data, int offset, GElf_Verneed *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed));
+  assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (unlikely (offset < 0)
+      || unlikely ((offset + sizeof (GElf_Verneed)) > data_scn->d.d_size))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_VNEED))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  memcpy ((char *) data_scn->d.d_buf + offset, src, sizeof (GElf_Verneed));
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/third_party/elfutils/libelf/gelf_update_versym.c b/third_party/elfutils/libelf/gelf_update_versym.c
new file mode 100644
index 0000000..9949dff
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_update_versym.c
@@ -0,0 +1,77 @@
+/* Update symbol version information.
+   Copyright (C) 2001, 2002, 2005, 2009, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+
+int
+gelf_update_versym (Elf_Data *data, int ndx, GElf_Versym *src)
+{
+  Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data;
+
+  if (data == NULL)
+    return 0;
+
+  /* The types for 32 and 64 bit are the same.  Lucky us.  */
+  assert (sizeof (GElf_Versym) == sizeof (Elf32_Versym));
+  assert (sizeof (GElf_Versym) == sizeof (Elf64_Versym));
+
+  /* Check whether we have to resize the data buffer.  */
+  if (INVALID_NDX (ndx, GElf_Versym, &data_scn->d))
+    {
+      __libelf_seterrno (ELF_E_INVALID_INDEX);
+      return 0;
+    }
+
+  if (unlikely (data_scn->d.d_type != ELF_T_HALF))
+    {
+      /* The type of the data better should match.  */
+      __libelf_seterrno (ELF_E_DATA_MISMATCH);
+      return 0;
+    }
+
+  rwlock_wrlock (data_scn->s->elf->lock);
+
+  ((GElf_Versym *) data_scn->d.d_buf)[ndx] = *src;
+
+  /* Mark the section as modified.  */
+  data_scn->s->flags |= ELF_F_DIRTY;
+
+  rwlock_unlock (data_scn->s->elf->lock);
+
+  return 1;
+}
diff --git a/third_party/elfutils/libelf/gelf_xlate.c b/third_party/elfutils/libelf/gelf_xlate.c
new file mode 100644
index 0000000..479f143
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_xlate.c
@@ -0,0 +1,217 @@
+/* Transformation functions for ELF data types.
+   Copyright (C) 1998,1999,2000,2002,2004,2005,2006,2007,2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <byteswap.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "libelfP.h"
+
+#ifndef LIBELFBITS
+# define LIBELFBITS	32
+#endif
+
+
+/* Well, what shall I say.  Nothing to do here.  */
+#define elf_cvt_Byte(dest, src, n) \
+  (__builtin_constant_p (n) && (n) == 1					      \
+   ? (void) (*((char *) (dest)) = *((char *) (src)))			      \
+   : Elf32_cvt_Byte (dest, src, n))
+static void
+(elf_cvt_Byte) (void *dest, const void *src, size_t n,
+		int encode __attribute__ ((unused)))
+{
+  if (n != 0)
+    memmove (dest, src, n);
+}
+
+
+/* We'll optimize the definition of the conversion functions here a
+   bit.  We need only functions for 16, 32, and 64 bits.  The
+   functions referenced in the table will be aliases for one of these
+   functions.  Which one is decided by the ELFxx_FSZ_type.  */
+
+#if ALLOW_UNALIGNED
+
+#define FETCH(Bits, ptr)	(*(const uint##Bits##_t *) ptr)
+#define STORE(Bits, ptr, val)	(*(uint##Bits##_t *) ptr = val)
+
+#else
+
+union unaligned
+  {
+    uint16_t u16;
+    uint32_t u32;
+    uint64_t u64;
+  } attribute_packed;
+
+#define FETCH(Bits, ptr)	(((const union unaligned *) ptr)->u##Bits)
+#define STORE(Bits, ptr, val)	(((union unaligned *) ptr)->u##Bits = val)
+
+#endif
+
+/* Now define the conversion functions for the basic types.  We use here
+   the fact that file and memory types are the same and that we have the
+   ELFxx_FSZ_* macros.
+
+   At the same time we define inline functions which we will use to
+   convert the complex types.  */
+#define FUNDAMENTAL(NAME, Name, Bits) \
+  INLINE2 (ELFW2(Bits,FSZ_##NAME), ElfW2(Bits,cvt_##Name), ElfW2(Bits,Name))
+#define INLINE2(Bytes, FName, TName) \
+  INLINE3 (Bytes, FName, TName)
+#define INLINE3(Bytes, FName, TName)					      \
+  static inline void FName##1 (void *dest, const void *ptr)		      \
+  {									      \
+    switch (Bytes)							      \
+      {									      \
+      case 2: STORE (16, dest, bswap_16 (FETCH (16, ptr))); break;	      \
+      case 4: STORE (32, dest, bswap_32 (FETCH (32, ptr))); break;	      \
+      case 8: STORE (64, dest, bswap_64 (FETCH (64, ptr))); break;	      \
+      default:								      \
+	abort ();							      \
+      }									      \
+  }									      \
+									      \
+  static void FName (void *dest, const void *ptr, size_t len,		      \
+		     int encode __attribute__ ((unused)))		      \
+  {									      \
+    size_t n = len / sizeof (TName);					      \
+    if (dest < ptr)							      \
+      while (n-- > 0)							      \
+	{								      \
+	  FName##1 (dest, ptr);						      \
+	  dest += Bytes;						      \
+	  ptr += Bytes;							      \
+	}								      \
+    else								      \
+      {									      \
+	dest += len;							      \
+	ptr += len;							      \
+	while (n-- > 0)							      \
+	  {								      \
+	    ptr -= Bytes;						      \
+	    dest -= Bytes;						      \
+	    FName##1 (dest, ptr);					      \
+	  }								      \
+      }									      \
+  }
+
+
+/* Now the tricky part: define the transformation functions for the
+   complex types.  We will use the definitions of the types in
+   abstract.h.  */
+#define START(Bits, Name, EName) \
+  static void								      \
+  ElfW2 (Bits, cvt_##Name) (void *dest, const void *src, size_t len,	      \
+			    int encode __attribute__ ((unused)))	      \
+  { ElfW2(Bits, Name) *tdest = (ElfW2(Bits, Name) *) dest;		      \
+    ElfW2(Bits, Name) *tsrc = (ElfW2(Bits, Name) *) src;		      \
+    size_t n;								      \
+    for (n = len / sizeof (ElfW2(Bits, Name)); n > 0; ++tdest, ++tsrc, --n) {
+#define END(Bits, Name) } }
+#define TYPE_EXTRA(Code)
+#define TYPE_XLATE(Code) Code
+#define TYPE_NAME(Type, Name) TYPE_NAME2 (Type, Name)
+#define TYPE_NAME2(Type, Name) Type##1 (&tdest->Name, &tsrc->Name);
+#define TYPE(Name, Bits) TYPE2 (Name, Bits)
+#define TYPE2(Name, Bits) TYPE3 (Name##Bits)
+#define TYPE3(Name) Name (cvt_)
+
+/* Signal that we are generating conversion functions.  */
+#define GENERATE_CONVERSION
+
+/* First generate the 32-bit conversion functions.  */
+#define LIBELFBITS 32
+#include "gelf_xlate.h"
+
+/* Now generate the 64-bit conversion functions.  */
+#define LIBELFBITS 64
+#include "gelf_xlate.h"
+
+
+/* We have a few functions which we must create by hand since the sections
+   do not contain records of only one type.  */
+#include "version_xlate.h"
+#include "gnuhash_xlate.h"
+#include "note_xlate.h"
+#include "chdr_xlate.h"
+
+
+/* Now the externally visible table with the function pointers.  */
+const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] =
+{
+  [EV_CURRENT - 1] = {
+    [EV_CURRENT - 1] = {
+      [ELFCLASS32 - 1] = {
+#define define_xfcts(Bits) \
+	[ELF_T_BYTE]	= elf_cvt_Byte,					      \
+	[ELF_T_ADDR]	= ElfW2(Bits, cvt_Addr),			      \
+	[ELF_T_DYN]	= ElfW2(Bits, cvt_Dyn),				      \
+	[ELF_T_EHDR]	= ElfW2(Bits, cvt_Ehdr),			      \
+	[ELF_T_HALF]	= ElfW2(Bits, cvt_Half),			      \
+	[ELF_T_OFF]	= ElfW2(Bits, cvt_Off),				      \
+	[ELF_T_PHDR]	= ElfW2(Bits, cvt_Phdr),			      \
+	[ELF_T_RELA]	= ElfW2(Bits, cvt_Rela),			      \
+	[ELF_T_REL]	= ElfW2(Bits, cvt_Rel),				      \
+	[ELF_T_SHDR]	= ElfW2(Bits, cvt_Shdr),			      \
+	[ELF_T_SWORD]	= ElfW2(Bits, cvt_Sword),			      \
+	[ELF_T_SYM]	= ElfW2(Bits, cvt_Sym),				      \
+	[ELF_T_WORD]	= ElfW2(Bits, cvt_Word),			      \
+	[ELF_T_XWORD]	= ElfW2(Bits, cvt_Xword),			      \
+	[ELF_T_SXWORD]	= ElfW2(Bits, cvt_Sxword),			      \
+	[ELF_T_VDEF]	= elf_cvt_Verdef,				      \
+	[ELF_T_VDAUX]	= elf_cvt_Verdef,				      \
+	[ELF_T_VNEED]	= elf_cvt_Verneed,				      \
+	[ELF_T_VNAUX]	= elf_cvt_Verneed,				      \
+	[ELF_T_NHDR]	= elf_cvt_note,					      \
+	[ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo),			      \
+	[ELF_T_MOVE]	= ElfW2(Bits, cvt_Move),			      \
+	[ELF_T_LIB]	= ElfW2(Bits, cvt_Lib),				      \
+	[ELF_T_AUXV]	= ElfW2(Bits, cvt_auxv_t),			      \
+	[ELF_T_CHDR]	= ElfW2(Bits, cvt_chdr)
+        define_xfcts (32),
+	[ELF_T_GNUHASH] = Elf32_cvt_Word
+      },
+      [ELFCLASS64 - 1] = {
+	define_xfcts (64),
+	[ELF_T_GNUHASH] = elf_cvt_gnuhash
+      }
+    }
+  }
+};
+/* For now we only handle the case where the memory representation is the
+   same as the file representation.  Should this change we have to define
+   separate functions.  For now reuse them.  */
+strong_alias (__elf_xfctstom, __elf_xfctstof)
diff --git a/third_party/elfutils/libelf/gelf_xlate.h b/third_party/elfutils/libelf/gelf_xlate.h
new file mode 100644
index 0000000..3c0e4bf
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_xlate.h
@@ -0,0 +1,57 @@
+/* Helper file for type conversion function generation.
+   Copyright (C) 1998, 1999, 2000, 2002, 2004, 2007 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+
+/* Simple types.  */
+FUNDAMENTAL (ADDR, Addr, LIBELFBITS);
+FUNDAMENTAL (OFF, Off, LIBELFBITS);
+FUNDAMENTAL (HALF, Half, LIBELFBITS);
+FUNDAMENTAL (WORD, Word, LIBELFBITS);
+FUNDAMENTAL (SWORD, Sword, LIBELFBITS);
+FUNDAMENTAL (XWORD, Xword, LIBELFBITS);
+FUNDAMENTAL (SXWORD, Sxword, LIBELFBITS);
+
+/* The structured types.  */
+TYPE (Ehdr, LIBELFBITS)
+TYPE (Phdr, LIBELFBITS)
+TYPE (Shdr, LIBELFBITS)
+TYPE (Sym, LIBELFBITS)
+TYPE (Rel, LIBELFBITS)
+TYPE (Rela, LIBELFBITS)
+TYPE (Note, LIBELFBITS)
+TYPE (Dyn, LIBELFBITS)
+TYPE (Syminfo, LIBELFBITS)
+TYPE (Move, LIBELFBITS)
+TYPE (Lib, LIBELFBITS)
+TYPE (auxv_t, LIBELFBITS)
+TYPE (Chdr, LIBELFBITS)
+
+
+/* Prepare for the next round.  */
+#undef LIBELFBITS
diff --git a/third_party/elfutils/libelf/gelf_xlatetof.c b/third_party/elfutils/libelf/gelf_xlatetof.c
new file mode 100644
index 0000000..e266180
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_xlatetof.c
@@ -0,0 +1,50 @@
+/* Convert from memory to file representation.  Generic ELF version.
+   Copyright (C) 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+gelf_xlatetof (Elf *elf, Elf_Data *dest, const Elf_Data * src,
+	       unsigned int encode)
+{
+  if (elf == NULL)
+    return NULL;
+
+  return (elf->class == ELFCLASS32
+	  ? INTUSE(elf32_xlatetof) (dest, src, encode)
+	  : INTUSE(elf64_xlatetof) (dest, src, encode));
+}
diff --git a/third_party/elfutils/libelf/gelf_xlatetom.c b/third_party/elfutils/libelf/gelf_xlatetom.c
new file mode 100644
index 0000000..8499c71
--- /dev/null
+++ b/third_party/elfutils/libelf/gelf_xlatetom.c
@@ -0,0 +1,50 @@
+/* Convert from file to memory representation.  Generic ELF version.
+   Copyright (C) 2000, 2002, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gelf.h>
+#include <stddef.h>
+
+#include "libelfP.h"
+
+
+Elf_Data *
+gelf_xlatetom (Elf *elf, Elf_Data *dest, const Elf_Data * src,
+	       unsigned int encode)
+{
+  if (elf == NULL)
+    return NULL;
+
+  return (elf->class == ELFCLASS32
+	  ? INTUSE(elf32_xlatetom) (dest, src, encode)
+	  : INTUSE(elf64_xlatetom) (dest, src, encode));
+}
diff --git a/third_party/elfutils/libelf/gnuhash_xlate.h b/third_party/elfutils/libelf/gnuhash_xlate.h
new file mode 100644
index 0000000..6faf113
--- /dev/null
+++ b/third_party/elfutils/libelf/gnuhash_xlate.h
@@ -0,0 +1,74 @@
+/* Conversion functions for versioning information.
+   Copyright (C) 2006, 2007 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2006.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <gelf.h>
+
+#include "libelfP.h"
+
+
+static void
+elf_cvt_gnuhash (void *dest, const void *src, size_t len, int encode)
+{
+  /* The GNU hash table format on 64 bit machines mixes 32 bit and 64 bit
+     words.  We must detangle them here.   */
+  Elf32_Word *dest32 = dest;
+  const Elf32_Word *src32 = src;
+
+  /* First four control words, 32 bits.  */
+  for (unsigned int cnt = 0; cnt < 4; ++cnt)
+    {
+      if (len < 4)
+	return;
+      dest32[cnt] = bswap_32 (src32[cnt]);
+      len -= 4;
+    }
+
+  Elf32_Word bitmask_words = encode ? src32[2] : dest32[2];
+
+  /* Now the 64 bit words.  */
+  Elf64_Xword *dest64 = (Elf64_Xword *) &dest32[4];
+  const Elf64_Xword *src64 = (const Elf64_Xword *) &src32[4];
+  for (unsigned int cnt = 0; cnt < bitmask_words; ++cnt)
+    {
+      if (len < 8)
+	return;
+      dest64[cnt] = bswap_64 (src64[cnt]);
+      len -= 8;
+    }
+
+  /* The rest are 32 bit words again.  */
+  src32 = (const Elf32_Word *) &src64[bitmask_words];
+  dest32 = (Elf32_Word *) &dest64[bitmask_words];
+  while (len >= 4)
+    {
+      *dest32++ = bswap_32 (*src32++);
+      len -= 4;
+    }
+}
diff --git a/third_party/elfutils/libelf/libelf.h b/third_party/elfutils/libelf/libelf.h
new file mode 100644
index 0000000..547c0f5
--- /dev/null
+++ b/third_party/elfutils/libelf/libelf.h
@@ -0,0 +1,515 @@
+/* Interface for libelf.
+   Copyright (C) 1998-2010, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBELF_H
+#define _LIBELF_H 1
+
+#include <stdint.h>
+#include <sys/types.h>
+
+/* Get the ELF types.  */
+#include <elf.h>
+
+#ifndef SHF_COMPRESSED
+ /* Older glibc elf.h might not yet define the ELF compression types.  */
+ #define SHF_COMPRESSED      (1 << 11)  /* Section with compressed data. */
+
+ /* Section compression header.  Used when SHF_COMPRESSED is set.  */
+
+ typedef struct
+ {
+   Elf32_Word   ch_type;        /* Compression format.  */
+   Elf32_Word   ch_size;        /* Uncompressed data size.  */
+   Elf32_Word   ch_addralign;   /* Uncompressed data alignment.  */
+ } Elf32_Chdr;
+
+ typedef struct
+ {
+   Elf64_Word   ch_type;        /* Compression format.  */
+   Elf64_Word   ch_reserved;
+   Elf64_Xword  ch_size;        /* Uncompressed data size.  */
+   Elf64_Xword  ch_addralign;   /* Uncompressed data alignment.  */
+ } Elf64_Chdr;
+
+ /* Legal values for ch_type (compression algorithm).  */
+ #define ELFCOMPRESS_ZLIB       1          /* ZLIB/DEFLATE algorithm.  */
+ #define ELFCOMPRESS_LOOS       0x60000000 /* Start of OS-specific.  */
+ #define ELFCOMPRESS_HIOS       0x6fffffff /* End of OS-specific.  */
+ #define ELFCOMPRESS_LOPROC     0x70000000 /* Start of processor-specific.  */
+ #define ELFCOMPRESS_HIPROC     0x7fffffff /* End of processor-specific.  */
+#endif
+
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+# define __nonnull_attribute__(...) __attribute__ ((__nonnull__ (__VA_ARGS__)))
+# define __deprecated_attribute__ __attribute__ ((__deprecated__))
+# define __pure_attribute__ __attribute__ ((__pure__))
+# define __const_attribute__ __attribute__ ((__const__))
+#else
+# define __nonnull_attribute__(...)
+# define __deprecated_attribute__
+# define __pure_attribute__
+# define __const_attribute__
+#endif
+
+#if __GNUC__ < 4
+#define __noreturn_attribute__
+#else
+#define __noreturn_attribute__ __attribute__ ((noreturn))
+#endif
+
+#ifdef __GNUC_STDC_INLINE__
+# define __libdw_extern_inline extern __inline __attribute__ ((__gnu_inline__))
+#else
+# define __libdw_extern_inline extern __inline
+#endif
+
+/* Known translation types.  */
+typedef enum
+{
+  ELF_T_BYTE,                   /* unsigned char */
+  ELF_T_ADDR,                   /* Elf32_Addr, Elf64_Addr, ... */
+  ELF_T_DYN,                    /* Dynamic section record.  */
+  ELF_T_EHDR,                   /* ELF header.  */
+  ELF_T_HALF,                   /* Elf32_Half, Elf64_Half, ... */
+  ELF_T_OFF,                    /* Elf32_Off, Elf64_Off, ... */
+  ELF_T_PHDR,                   /* Program header.  */
+  ELF_T_RELA,                   /* Relocation entry with addend.  */
+  ELF_T_REL,                    /* Relocation entry.  */
+  ELF_T_SHDR,                   /* Section header.  */
+  ELF_T_SWORD,                  /* Elf32_Sword, Elf64_Sword, ... */
+  ELF_T_SYM,                    /* Symbol record.  */
+  ELF_T_WORD,                   /* Elf32_Word, Elf64_Word, ... */
+  ELF_T_XWORD,                  /* Elf32_Xword, Elf64_Xword, ... */
+  ELF_T_SXWORD,                 /* Elf32_Sxword, Elf64_Sxword, ... */
+  ELF_T_VDEF,                   /* Elf32_Verdef, Elf64_Verdef, ... */
+  ELF_T_VDAUX,                  /* Elf32_Verdaux, Elf64_Verdaux, ... */
+  ELF_T_VNEED,                  /* Elf32_Verneed, Elf64_Verneed, ... */
+  ELF_T_VNAUX,                  /* Elf32_Vernaux, Elf64_Vernaux, ... */
+  ELF_T_NHDR,                   /* Elf32_Nhdr, Elf64_Nhdr, ... */
+  ELF_T_SYMINFO,		/* Elf32_Syminfo, Elf64_Syminfo, ... */
+  ELF_T_MOVE,			/* Elf32_Move, Elf64_Move, ... */
+  ELF_T_LIB,			/* Elf32_Lib, Elf64_Lib, ... */
+  ELF_T_GNUHASH,		/* GNU-style hash section.  */
+  ELF_T_AUXV,			/* Elf32_auxv_t, Elf64_auxv_t, ... */
+  ELF_T_CHDR,			/* Compressed, Elf32_Chdr, Elf64_Chdr, ... */
+  /* Keep this the last entry.  */
+  ELF_T_NUM
+} Elf_Type;
+
+/* Descriptor for data to be converted to or from memory format.  */
+typedef struct
+{
+  void *d_buf;			/* Pointer to the actual data.  */
+  Elf_Type d_type;		/* Type of this piece of data.  */
+  unsigned int d_version;	/* ELF version.  */
+  size_t d_size;		/* Size in bytes.  */
+  int64_t d_off;		/* Offset into section.  */
+  size_t d_align;		/* Alignment in section.  */
+} Elf_Data;
+
+
+/* Commands for `...'.  */
+typedef enum
+{
+  ELF_C_NULL,			/* Nothing, terminate, or compute only.  */
+  ELF_C_READ,			/* Read .. */
+  ELF_C_RDWR,			/* Read and write .. */
+  ELF_C_WRITE,			/* Write .. */
+  ELF_C_CLR,			/* Clear flag.  */
+  ELF_C_SET,			/* Set flag.  */
+  ELF_C_FDDONE,			/* Signal that file descriptor will not be
+				   used anymore.  */
+  ELF_C_FDREAD,			/* Read rest of data so that file descriptor
+				   is not used anymore.  */
+  /* The following are extensions.  */
+  ELF_C_READ_MMAP,		/* Read, but mmap the file if possible.  */
+  ELF_C_RDWR_MMAP,		/* Read and write, with mmap.  */
+  ELF_C_WRITE_MMAP,		/* Write, with mmap.  */
+  ELF_C_READ_MMAP_PRIVATE,	/* Read, but memory is writable, results are
+				   not written to the file.  */
+  ELF_C_EMPTY,			/* Copy basic file data but not the content. */
+  /* Keep this the last entry.  */
+  ELF_C_NUM
+} Elf_Cmd;
+
+
+/* Flags for the ELF structures.  */
+enum
+{
+  ELF_F_DIRTY = 0x1,
+#define ELF_F_DIRTY		ELF_F_DIRTY
+  ELF_F_LAYOUT = 0x4,
+#define ELF_F_LAYOUT		ELF_F_LAYOUT
+  ELF_F_PERMISSIVE = 0x8
+#define ELF_F_PERMISSIVE	ELF_F_PERMISSIVE
+};
+
+/* Flags for elf_compress[_gnu].  */
+enum
+{
+  ELF_CHF_FORCE = 0x1
+#define ELF_CHF_FORCE ELF_CHF_FORCE
+};
+
+/* Identification values for recognized object files.  */
+typedef enum
+{
+  ELF_K_NONE,			/* Unknown.  */
+  ELF_K_AR,			/* Archive.  */
+  ELF_K_COFF,			/* Stupid old COFF.  */
+  ELF_K_ELF,			/* ELF file.  */
+  /* Keep this the last entry.  */
+  ELF_K_NUM
+} Elf_Kind;
+
+
+/* Archive member header.  */
+typedef struct
+{
+  char *ar_name;		/* Name of archive member.  */
+  time_t ar_date;		/* File date.  */
+  uid_t ar_uid;			/* User ID.  */
+  gid_t ar_gid;			/* Group ID.  */
+  mode_t ar_mode;		/* File mode.  */
+  int64_t ar_size;		/* File size.  */
+  char *ar_rawname;		/* Original name of archive member.  */
+} Elf_Arhdr;
+
+
+/* Archive symbol table entry.  */
+typedef struct
+{
+  char *as_name;		/* Symbol name.  */
+  size_t as_off;		/* Offset for this file in the archive.  */
+  unsigned long int as_hash;	/* Hash value of the name.  */
+} Elf_Arsym;
+
+
+/* Descriptor for the ELF file.  */
+typedef struct Elf Elf;
+
+/* Descriptor for ELF file section.  */
+typedef struct Elf_Scn Elf_Scn;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Return descriptor for ELF file to work according to CMD.  */
+extern Elf *elf_begin (int __fildes, Elf_Cmd __cmd, Elf *__ref);
+
+/* Create a clone of an existing ELF descriptor.  */
+  extern Elf *elf_clone (Elf *__elf, Elf_Cmd __cmd);
+
+/* Create descriptor for memory region.  */
+extern Elf *elf_memory (char *__image, size_t __size);
+
+/* Advance archive descriptor to next element.  */
+extern Elf_Cmd elf_next (Elf *__elf);
+
+/* Free resources allocated for ELF.  */
+extern int elf_end (Elf *__elf);
+
+/* Update ELF descriptor and write file to disk.  */
+extern int64_t elf_update (Elf *__elf, Elf_Cmd __cmd);
+
+/* Determine what kind of file is associated with ELF.  */
+extern Elf_Kind elf_kind (Elf *__elf) __pure_attribute__;
+
+/* Get the base offset for an object file.  */
+extern int64_t elf_getbase (Elf *__elf);
+
+
+/* Retrieve file identification data.  */
+extern char *elf_getident (Elf *__elf, size_t *__nbytes);
+
+/* Retrieve class-dependent object file header.  */
+extern Elf32_Ehdr *elf32_getehdr (Elf *__elf);
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern Elf64_Ehdr *elf64_getehdr (Elf *__elf);
+
+/* Create ELF header if none exists.  */
+extern Elf32_Ehdr *elf32_newehdr (Elf *__elf);
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern Elf64_Ehdr *elf64_newehdr (Elf *__elf);
+
+/* Get the number of program headers in the ELF file.  If the file uses
+   more headers than can be represented in the e_phnum field of the ELF
+   header the information from the sh_info field in the zeroth section
+   header is used.  */
+extern int elf_getphdrnum (Elf *__elf, size_t *__dst);
+
+/* Retrieve class-dependent program header table.  */
+extern Elf32_Phdr *elf32_getphdr (Elf *__elf);
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern Elf64_Phdr *elf64_getphdr (Elf *__elf);
+
+/* Create ELF program header.  */
+extern Elf32_Phdr *elf32_newphdr (Elf *__elf, size_t __cnt);
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern Elf64_Phdr *elf64_newphdr (Elf *__elf, size_t __cnt);
+
+
+/* Get section at INDEX.  */
+extern Elf_Scn *elf_getscn (Elf *__elf, size_t __index);
+
+/* Get section at OFFSET.  */
+extern Elf_Scn *elf32_offscn (Elf *__elf, Elf32_Off __offset);
+/* Similar bug this time the binary calls is ELFCLASS64.  */
+extern Elf_Scn *elf64_offscn (Elf *__elf, Elf64_Off __offset);
+
+/* Get index of section.  */
+extern size_t elf_ndxscn (Elf_Scn *__scn);
+
+/* Get section with next section index.  */
+extern Elf_Scn *elf_nextscn (Elf *__elf, Elf_Scn *__scn);
+
+/* Create a new section and append it at the end of the table.  */
+extern Elf_Scn *elf_newscn (Elf *__elf);
+
+/* Get the section index of the extended section index table for the
+   given symbol table.  */
+extern int elf_scnshndx (Elf_Scn *__scn);
+
+/* Get the number of sections in the ELF file.  If the file uses more
+   sections than can be represented in the e_shnum field of the ELF
+   header the information from the sh_size field in the zeroth section
+   header is used.  */
+extern int elf_getshdrnum (Elf *__elf, size_t *__dst);
+/* Sun messed up the implementation of 'elf_getshnum' in their implementation.
+   It was agreed to make the same functionality available under a different
+   name and obsolete the old name.  */
+extern int elf_getshnum (Elf *__elf, size_t *__dst)
+     __deprecated_attribute__;
+
+
+/* Get the section index of the section header string table in the ELF
+   file.  If the index cannot be represented in the e_shnum field of
+   the ELF header the information from the sh_link field in the zeroth
+   section header is used.  */
+extern int elf_getshdrstrndx (Elf *__elf, size_t *__dst);
+/* Sun messed up the implementation of 'elf_getshnum' in their implementation.
+   It was agreed to make the same functionality available under a different
+   name and obsolete the old name.  */
+extern int elf_getshstrndx (Elf *__elf, size_t *__dst)
+     __deprecated_attribute__;
+
+
+/* Retrieve section header of ELFCLASS32 binary.  */
+extern Elf32_Shdr *elf32_getshdr (Elf_Scn *__scn);
+/* Similar for ELFCLASS64.  */
+extern Elf64_Shdr *elf64_getshdr (Elf_Scn *__scn);
+
+/* Returns compression header for a section if section data is
+   compressed.  Returns NULL and sets elf_errno if the section isn't
+   compressed or an error occurred.  */
+extern Elf32_Chdr *elf32_getchdr (Elf_Scn *__scn);
+extern Elf64_Chdr *elf64_getchdr (Elf_Scn *__scn);
+
+/* Compress or decompress the data of a section and adjust the section
+   header.
+
+   elf_compress works by setting or clearing the SHF_COMPRESS flag
+   from the section Shdr and will encode or decode a Elf32_Chdr or
+   Elf64_Chdr at the start of the section data.  elf_compress_gnu will
+   encode or decode any section, but is traditionally only used for
+   sections that have a name starting with ".debug" when
+   uncompressed or ".zdebug" when compressed and stores just the
+   uncompressed size.  The GNU compression method is deprecated and
+   should only be used for legacy support.
+
+   elf_compress takes a compression type that should be either zero to
+   decompress or an ELFCOMPRESS algorithm to use for compression.
+   Currently only ELFCOMPRESS_ZLIB is supported.  elf_compress_gnu
+   will compress in the traditional GNU compression format when
+   compress is one and decompress the section data when compress is
+   zero.
+
+   The FLAGS argument can be zero or ELF_CHF_FORCE.  If FLAGS contains
+   ELF_CHF_FORCE then it will always compress the section, even if
+   that would not reduce the size of the data section (including the
+   header).  Otherwise elf_compress and elf_compress_gnu will compress
+   the section only if the total data size is reduced.
+
+   On successful compression or decompression the function returns
+   one.  If (not forced) compression is requested and the data section
+   would not actually reduce in size, the section is not actually
+   compressed and zero is returned.  Otherwise -1 is returned and
+   elf_errno is set.
+
+   It is an error to request compression for a section that already
+   has SHF_COMPRESSED set, or (for elf_compress) to request
+   decompression for an section that doesn't have SHF_COMPRESSED set.
+   It is always an error to call these functions on SHT_NOBITS
+   sections or if the section has the SHF_ALLOC flag set.
+   elf_compress_gnu will not check whether the section name starts
+   with ".debug" or .zdebug".  It is the responsibilty of the caller
+   to make sure the deprecated GNU compression method is only called
+   on correctly named sections (and to change the name of the section
+   when using elf_compress_gnu).
+
+   All previous returned Shdrs and Elf_Data buffers are invalidated by
+   this call and should no longer be accessed.
+
+   Note that although this changes the header and data returned it
+   doesn't mark the section as dirty.  To keep the changes when
+   calling elf_update the section has to be flagged ELF_F_DIRTY.  */
+extern int elf_compress (Elf_Scn *scn, int type, unsigned int flags);
+extern int elf_compress_gnu (Elf_Scn *scn, int compress, unsigned int flags);
+
+/* Set or clear flags for ELF file.  */
+extern unsigned int elf_flagelf (Elf *__elf, Elf_Cmd __cmd,
+				 unsigned int __flags);
+/* Similarly for the ELF header.  */
+extern unsigned int elf_flagehdr (Elf *__elf, Elf_Cmd __cmd,
+				  unsigned int __flags);
+/* Similarly for the ELF program header.  */
+extern unsigned int elf_flagphdr (Elf *__elf, Elf_Cmd __cmd,
+				  unsigned int __flags);
+/* Similarly for the given ELF section.  */
+extern unsigned int elf_flagscn (Elf_Scn *__scn, Elf_Cmd __cmd,
+				 unsigned int __flags);
+/* Similarly for the given ELF data.  */
+extern unsigned int elf_flagdata (Elf_Data *__data, Elf_Cmd __cmd,
+				  unsigned int __flags);
+/* Similarly for the given ELF section header.  */
+extern unsigned int elf_flagshdr (Elf_Scn *__scn, Elf_Cmd __cmd,
+				  unsigned int __flags);
+
+
+/* Get data from section while translating from file representation to
+   memory representation.  The Elf_Data d_type is set based on the
+   section type if known.  Otherwise d_type is set to ELF_T_BYTE.  If
+   the section contains compressed data then d_type is always set to
+   ELF_T_CHDR.  */
+extern Elf_Data *elf_getdata (Elf_Scn *__scn, Elf_Data *__data);
+
+/* Get uninterpreted section content.  */
+extern Elf_Data *elf_rawdata (Elf_Scn *__scn, Elf_Data *__data);
+
+/* Create new data descriptor for section SCN.  */
+extern Elf_Data *elf_newdata (Elf_Scn *__scn);
+
+/* Get data translated from a chunk of the file contents as section data
+   would be for TYPE.  The resulting Elf_Data pointer is valid until
+   elf_end (ELF) is called.  */
+extern Elf_Data *elf_getdata_rawchunk (Elf *__elf,
+				       int64_t __offset, size_t __size,
+				       Elf_Type __type);
+
+
+/* Return pointer to string at OFFSET in section INDEX.  */
+extern char *elf_strptr (Elf *__elf, size_t __index, size_t __offset);
+
+
+/* Return header of archive.  */
+extern Elf_Arhdr *elf_getarhdr (Elf *__elf);
+
+/* Return offset in archive for current file ELF.  */
+extern int64_t elf_getaroff (Elf *__elf);
+
+/* Select archive element at OFFSET.  */
+extern size_t elf_rand (Elf *__elf, size_t __offset);
+
+/* Get symbol table of archive.  */
+extern Elf_Arsym *elf_getarsym (Elf *__elf, size_t *__narsyms);
+
+
+/* Control ELF descriptor.  */
+extern int elf_cntl (Elf *__elf, Elf_Cmd __cmd);
+
+/* Retrieve uninterpreted file contents.  */
+extern char *elf_rawfile (Elf *__elf, size_t *__nbytes);
+
+
+/* Return size of array of COUNT elements of the type denoted by TYPE
+   in the external representation.  The binary class is taken from ELF.
+   The result is based on version VERSION of the ELF standard.  */
+extern size_t elf32_fsize (Elf_Type __type, size_t __count,
+			   unsigned int __version)
+       __const_attribute__;
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern size_t elf64_fsize (Elf_Type __type, size_t __count,
+			   unsigned int __version)
+       __const_attribute__;
+
+
+/* Convert data structure from the representation in the file represented
+   by ELF to their memory representation.  */
+extern Elf_Data *elf32_xlatetom (Elf_Data *__dest, const Elf_Data *__src,
+				 unsigned int __encode);
+/* Same for 64 bit class.  */
+extern Elf_Data *elf64_xlatetom (Elf_Data *__dest, const Elf_Data *__src,
+				 unsigned int __encode);
+
+/* Convert data structure from to the representation in memory
+   represented by ELF file representation.  */
+extern Elf_Data *elf32_xlatetof (Elf_Data *__dest, const Elf_Data *__src,
+				 unsigned int __encode);
+/* Same for 64 bit class.  */
+extern Elf_Data *elf64_xlatetof (Elf_Data *__dest, const Elf_Data *__src,
+				 unsigned int __encode);
+
+
+/* Return error code of last failing function call.  This value is kept
+   separately for each thread.  */
+extern int elf_errno (void);
+
+/* Return error string for ERROR.  If ERROR is zero, return error string
+   for most recent error or NULL is none occurred.  If ERROR is -1 the
+   behaviour is similar to the last case except that not NULL but a legal
+   string is returned.  */
+extern const char *elf_errmsg (int __error);
+
+
+/* Coordinate ELF library and application versions.  */
+extern unsigned int elf_version (unsigned int __version);
+
+/* Set fill bytes used to fill holes in data structures.  */
+extern void elf_fill (int __fill);
+
+/* Compute hash value.  */
+extern unsigned long int elf_hash (const char *__string)
+       __pure_attribute__;
+
+/* Compute hash value using the GNU-specific hash function.  */
+extern unsigned long int elf_gnu_hash (const char *__string)
+       __pure_attribute__;
+
+
+/* Compute simple checksum from permanent parts of the ELF file.  */
+extern long int elf32_checksum (Elf *__elf);
+/* Similar but this time the binary calls is ELFCLASS64.  */
+extern long int elf64_checksum (Elf *__elf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* libelf.h */
diff --git a/third_party/elfutils/libelf/libelf.map b/third_party/elfutils/libelf/libelf.map
new file mode 100644
index 0000000..10dc505
--- /dev/null
+++ b/third_party/elfutils/libelf/libelf.map
@@ -0,0 +1,150 @@
+ELFUTILS_1.0 {
+  global:
+    elf32_checksum;
+    elf32_fsize;
+    elf32_getehdr;
+    elf32_getphdr;
+    elf32_getshdr;
+    elf32_newehdr;
+    elf32_newphdr;
+    elf32_xlatetof;
+    elf32_xlatetom;
+    elf64_checksum;
+    elf64_fsize;
+    elf64_getehdr;
+    elf64_getphdr;
+    elf64_getshdr;
+    elf64_newehdr;
+    elf64_newphdr;
+    elf64_xlatetof;
+    elf64_xlatetom;
+    elf_begin;
+    elf_clone;
+    elf_cntl;
+    elf_end;
+    elf_errmsg;
+    elf_errno;
+    elf_fill;
+    elf_flagdata;
+    elf_flagehdr;
+    elf_flagelf;
+    elf_flagphdr;
+    elf_flagscn;
+    elf_flagshdr;
+    elf_getarhdr;
+    elf_getarsym;
+    elf_getbase;
+    elf_getdata;
+    elf_getident;
+    elf_getscn;
+    elf_getshnum;
+    elf_getshstrndx;
+    elf_hash;
+    elf_kind;
+    elf_memory;
+    elf_ndxscn;
+    elf_newdata;
+    elf_newscn;
+    elf_next;
+    elf_nextscn;
+    elf_rand;
+    elf_rawdata;
+    elf_rawfile;
+    elf_scncnt;
+    elf_strptr;
+    elf_update;
+    elf_version;
+    gelf_checksum;
+    gelf_fsize;
+    gelf_getclass;
+    gelf_getdyn;
+    gelf_getehdr;
+    gelf_getmove;
+    gelf_getphdr;
+    gelf_getrel;
+    gelf_getrela;
+    gelf_getshdr;
+    gelf_getsym;
+    gelf_getsyminfo;
+    gelf_getsymshndx;
+    gelf_getverdaux;
+    gelf_getverdef;
+    gelf_getvernaux;
+    gelf_getverneed;
+    gelf_getversym;
+    gelf_newehdr;
+    gelf_newphdr;
+    gelf_update_dyn;
+    gelf_update_ehdr;
+    gelf_update_move;
+    gelf_update_phdr;
+    gelf_update_rel;
+    gelf_update_rela;
+    gelf_update_shdr;
+    gelf_update_sym;
+    gelf_update_syminfo;
+    gelf_update_symshndx;
+    gelf_update_verdaux;
+    gelf_update_verdef;
+    gelf_update_vernaux;
+    gelf_update_verneed;
+    gelf_update_versym;
+    gelf_xlatetof;
+    gelf_xlatetom;
+    nlist;
+
+  local:
+    *;
+};
+
+ELFUTILS_1.1 {
+  global:
+    gelf_getlib;
+    gelf_update_lib;
+} ELFUTILS_1.0;
+
+ELFUTILS_1.1.1 {
+  global:
+    elf32_offscn;
+    elf64_offscn;
+    gelf_offscn;
+    elf_getaroff;
+} ELFUTILS_1.1;
+
+ELFUTILS_1.2 {
+  global:
+    elf_gnu_hash;
+} ELFUTILS_1.1.1;
+
+ELFUTILS_1.3 {
+  global:
+    elf_getdata_rawchunk;
+    gelf_getauxv;
+    gelf_update_auxv;
+    gelf_getnote;
+} ELFUTILS_1.2;
+
+ELFUTILS_1.4 {
+  global:
+    elf_scnshndx;
+} ELFUTILS_1.3;
+
+ELFUTILS_1.5 {
+  global:
+    elf_getshdrnum; elf_getshdrstrndx;
+} ELFUTILS_1.4;
+
+ELFUTILS_1.6 {
+  global:
+    elf_getphdrnum;
+} ELFUTILS_1.5;
+
+ELFUTILS_1.7 {
+  global:
+    elf32_getchdr;
+    elf64_getchdr;
+    gelf_getchdr;
+
+    elf_compress;
+    elf_compress_gnu;
+} ELFUTILS_1.6;
diff --git a/third_party/elfutils/libelf/libelfP.h b/third_party/elfutils/libelf/libelfP.h
new file mode 100644
index 0000000..ca805ac
--- /dev/null
+++ b/third_party/elfutils/libelf/libelfP.h
@@ -0,0 +1,638 @@
+/* Internal interfaces for libelf.
+   Copyright (C) 1998-2010, 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LIBELFP_H
+#define _LIBELFP_H 1
+
+#include <ar.h>
+#include <gelf.h>
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+/* gettext helper macros.  */
+#define _(Str) dgettext ("elfutils", Str)
+
+
+/* Helper Macros to write 32 bit and 64 bit functions.  */
+#define __elfw2_(Bits, Name) __elf##Bits##_##Name
+#define elfw2_(Bits, Name) elf##Bits##_##Name
+#define ElfW2_(Bits, Name) Elf##Bits##_##Name
+#define ELFW2_(Bits, Name) ELF##Bits##_##Name
+#define ELFW_(Name, Bits) Name##Bits
+#define __elfw2(Bits, Name) __elfw2_(Bits, Name)
+#define elfw2(Bits, Name) elfw2_(Bits, Name)
+#define ElfW2(Bits, Name) ElfW2_(Bits, Name)
+#define ELFW2(Bits, Name) ELFW2_(Bits, Name)
+#define ELFW(Name, Bits)  ELFW_(Name, Bits)
+
+
+/* Sizes of the external types, for 32 bits objects.  */
+#define ELF32_FSZ_ADDR   4
+#define ELF32_FSZ_OFF    4
+#define ELF32_FSZ_HALF   2
+#define ELF32_FSZ_WORD   4
+#define ELF32_FSZ_SWORD  4
+#define ELF32_FSZ_XWORD  8
+#define ELF32_FSZ_SXWORD 8
+
+/* Same for 64 bits objects.  */
+#define ELF64_FSZ_ADDR   8
+#define ELF64_FSZ_OFF    8
+#define ELF64_FSZ_HALF   2
+#define ELF64_FSZ_WORD   4
+#define ELF64_FSZ_SWORD  4
+#define ELF64_FSZ_XWORD  8
+#define ELF64_FSZ_SXWORD 8
+
+
+/* This is an extension of the ELF_F_* enumeration.  The values here are
+   not part of the library interface, they are only used internally.  */
+enum
+{
+  ELF_F_MMAPPED = 0x40,
+  ELF_F_MALLOCED = 0x80,
+  ELF_F_FILEDATA = 0x100
+};
+
+
+/* Get definition of all the external types.  */
+#include "exttypes.h"
+
+
+/* Error values.  */
+enum
+{
+  ELF_E_NOERROR = 0,
+  ELF_E_UNKNOWN_ERROR,
+  ELF_E_UNKNOWN_VERSION,
+  ELF_E_UNKNOWN_TYPE,
+  ELF_E_INVALID_HANDLE,
+  ELF_E_SOURCE_SIZE,
+  ELF_E_DEST_SIZE,
+  ELF_E_INVALID_ENCODING,
+  ELF_E_NOMEM,
+  ELF_E_INVALID_FILE,
+  ELF_E_INVALID_ELF,
+  ELF_E_INVALID_OP,
+  ELF_E_NO_VERSION,
+  ELF_E_INVALID_CMD,
+  ELF_E_RANGE,
+  ELF_E_ARCHIVE_FMAG,
+  ELF_E_INVALID_ARCHIVE,
+  ELF_E_NO_ARCHIVE,
+  ELF_E_NO_INDEX,
+  ELF_E_READ_ERROR,
+  ELF_E_WRITE_ERROR,
+  ELF_E_INVALID_CLASS,
+  ELF_E_INVALID_INDEX,
+  ELF_E_INVALID_OPERAND,
+  ELF_E_INVALID_SECTION,
+  ELF_E_INVALID_COMMAND,
+  ELF_E_WRONG_ORDER_EHDR,
+  ELF_E_FD_DISABLED,
+  ELF_E_FD_MISMATCH,
+  ELF_E_OFFSET_RANGE,
+  ELF_E_NOT_NUL_SECTION,
+  ELF_E_DATA_MISMATCH,
+  ELF_E_INVALID_SECTION_HEADER,
+  ELF_E_INVALID_DATA,
+  ELF_E_DATA_ENCODING,
+  ELF_E_SECTION_TOO_SMALL,
+  ELF_E_INVALID_ALIGN,
+  ELF_E_INVALID_SHENTSIZE,
+  ELF_E_UPDATE_RO,
+  ELF_E_NOFILE,
+  ELF_E_GROUP_NOT_REL,
+  ELF_E_INVALID_PHDR,
+  ELF_E_NO_PHDR,
+  ELF_E_INVALID_OFFSET,
+  ELF_E_INVALID_SECTION_TYPE,
+  ELF_E_INVALID_SECTION_FLAGS,
+  ELF_E_NOT_COMPRESSED,
+  ELF_E_ALREADY_COMPRESSED,
+  ELF_E_UNKNOWN_COMPRESSION_TYPE,
+  ELF_E_COMPRESS_ERROR,
+  ELF_E_DECOMPRESS_ERROR,
+  /* Keep this as the last entry.  */
+  ELF_E_NUM
+};
+
+
+/* The visible `Elf_Data' type is not sufficent for some operations due
+   to a misdesigned interface.  Extend it for internal purposes.  */
+typedef struct
+{
+  Elf_Data d;
+  Elf_Scn *s;
+} Elf_Data_Scn;
+
+
+/* List of `Elf_Data' descriptors.  This is what makes up the section
+   contents.  */
+typedef struct Elf_Data_List
+{
+  /* `data' *must* be the first element in the struct.  */
+  Elf_Data_Scn data;
+  struct Elf_Data_List *next;
+  int flags;
+} Elf_Data_List;
+
+
+/* Descriptor for ELF section.  */
+struct Elf_Scn
+{
+  /* We have to distinguish several different situations:
+
+     1. the section is user created.  Therefore there is no file or memory
+        region to read the data from.  Here we have two different subcases:
+
+        a) data was not yet added (before the first `elf_newdata' call)
+
+        b) at least one data set is available
+
+     2. this is a section from a file/memory region.  We have to read the
+        current content in one data block if we have to.  But we don't
+        read the data until it is necessary.  So we have the subcases:
+
+        a) the section in the file has size zero (for whatever reason)
+
+        b) the data of the file is not (yet) read
+
+        c) the data is read and available.
+
+     In addition to this we have different data sets, the raw and the converted
+     data.  This distinction only exists for the data read from the file.
+     All user-added data set (all but the first when read from the file or
+     all of them for user-create sections) are the same in both formats.
+     We don't create the converted data before it is necessary.
+
+     The `data_read' element signals whether data is available in the
+     raw format.
+
+     If there is data from the file/memory region or if read one data
+     set is added the `rawdata_list_read' pointer in non-NULL and points
+     to the last filled data set.  `raw_datalist_rear' is therefore NULL
+     only if there is no data set at all.
+
+     This so far allows to distinguish all but two cases (given that the
+     `rawdata_list' and `data_list' entries are initialized to zero) is
+     between not yet loaded data from the file/memory region and a section
+     with zero size and type ELF_T_BYTE.   */
+  Elf_Data_List data_list;	/* List of data buffers.  */
+  Elf_Data_List *data_list_rear; /* Pointer to the rear of the data list. */
+
+  Elf_Data_Scn rawdata;		/* Uninterpreted data of the section.  */
+
+  int data_read;		/* Nonzero if the section was created by the
+				   user or if the data from the file/memory
+				   is read.  */
+  int shndx_index;		/* Index of the extended section index
+				   table for this symbol table (if this
+				   section is a symbol table).  */
+
+  size_t index;			/* Index of this section.  */
+  struct Elf *elf;		/* The underlying ELF file.  */
+
+  union
+  {
+    Elf32_Shdr *e32;		/* Pointer to 32bit section header.  */
+    Elf64_Shdr *e64;		/* Pointer to 64bit section header.  */
+  } shdr;
+
+  unsigned int shdr_flags;	/* Section header modified?  */
+  unsigned int flags;		/* Section changed in size?
+				   ELF_F_MALLOCED for a Elf_Data_Chunk
+				   dummy_scn means the rawchunks
+				   data.d.d_buf was malloced. For normal
+				   sections it means rawdata_base was
+				   malloced (by elf_compress) even if
+				   the Elf was mmapped.  */
+
+  char *rawdata_base;		/* The unmodified data of the section.  */
+  char *data_base;		/* The converted data of the section.  */
+
+  char *zdata_base;		/* The uncompressed data of the section.  */
+  size_t zdata_size;		/* If zdata_base != NULL, the size of data.  */
+  size_t zdata_align;		/* If zdata_base != NULL, the addralign.  */
+
+  struct Elf_ScnList *list;	/* Pointer to the section list element the
+				   data is in.  */
+};
+
+
+/* List of section.  */
+typedef struct Elf_ScnList
+{
+  unsigned int cnt;		/* Number of elements of 'data' used.  */
+  unsigned int max;		/* Number of elements of 'data' allocated.  */
+  struct Elf_ScnList *next;	/* Next block of sections.  */
+  struct Elf_Scn data[0];	/* Section data.  */
+} Elf_ScnList;
+
+
+/* elf_getdata_rawchunk result.  */
+typedef struct Elf_Data_Chunk
+{
+  Elf_Data_Scn data;
+  union
+  {
+    Elf_Scn dummy_scn;
+    struct Elf_Data_Chunk *next;
+  };
+} Elf_Data_Chunk;
+
+
+/* The ELF descriptor.  */
+struct Elf
+{
+  /* Address to which the file was mapped.  NULL if not mapped.  */
+  void *map_address;
+
+  /* When created for an archive member this points to the descriptor
+     for the archive. */
+  Elf *parent;
+  Elf *next;             /* Used in list of archive descriptors.  */
+
+  /* What kind of file is underneath (ELF file, archive...).  */
+  Elf_Kind kind;
+
+  /* Command used to create this descriptor.  */
+  Elf_Cmd cmd;
+
+  /* The binary class.  */
+  unsigned int class;
+
+  /* The used file descriptor.  -1 if not available anymore.  */
+  int fildes;
+
+  /* Offset in the archive this file starts or zero.  */
+  off_t start_offset;
+
+  /* Size of the file in the archive or the entire file size, or ~0
+     for an (yet) unknown size.  */
+  size_t maximum_size;
+
+  /* Describes the way the memory was allocated and if the dirty bit is
+     signalled it means that the whole file has to be rewritten since
+     the layout changed.  */
+  int flags;
+
+  /* Reference counting for the descriptor.  */
+  int ref_count;
+
+  /* Lock to handle multithreaded programs.  */
+  rwlock_define (,lock);
+
+  union
+  {
+    struct
+    {
+      /* The next fields are only useful when testing for ==/!= NULL.  */
+      void *ehdr;
+      void *shdr;
+      void *phdr;
+
+      Elf_ScnList *scns_last;	/* Last element in the section list.
+				   If NULL the data has not yet been
+				   read from the file.  */
+      Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results.  */
+      unsigned int scnincr;	/* Number of sections allocate the last
+				   time.  */
+      int ehdr_flags;		/* Flags (dirty) for ELF header.  */
+      int phdr_flags;		/* Flags (dirty|malloc) for program header.  */
+      int shdr_malloced;	/* Nonzero if shdr array was allocated.  */
+      off_t sizestr_offset;	/* Offset of the size string in the parent
+				   if this is an archive member.  */
+    } elf;
+
+    struct
+    {
+      Elf32_Ehdr *ehdr;		/* Pointer to the ELF header.  This is
+				   never malloced.  */
+      Elf32_Shdr *shdr;		/* Used when reading from a file.  */
+      Elf32_Phdr *phdr;		/* Pointer to the program header array.  */
+      Elf_ScnList *scns_last;	/* Last element in the section list.
+				   If NULL the data has not yet been
+				   read from the file.  */
+      Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results.  */
+      unsigned int scnincr;	/* Number of sections allocate the last
+				   time.  */
+      int ehdr_flags;		/* Flags (dirty) for ELF header.  */
+      int phdr_flags;		/* Flags (dirty|malloc) for program header.  */
+      int shdr_malloced;	/* Nonzero if shdr array was allocated.  */
+      off_t sizestr_offset;	/* Offset of the size string in the parent
+				   if this is an archive member.  */
+      Elf32_Ehdr ehdr_mem;	/* Memory used for ELF header when not
+				   mmaped.  */
+      char __e32scnspad[sizeof (Elf64_Ehdr) - sizeof (Elf32_Ehdr)];
+
+      /* The section array.  */
+      Elf_ScnList scns;
+    } elf32;
+
+    struct
+    {
+      Elf64_Ehdr *ehdr;		/* Pointer to the ELF header.  This is
+				   never malloced.  */
+      Elf64_Shdr *shdr;		/* Used when reading from a file.  */
+      Elf64_Phdr *phdr;		/* Pointer to the program header array.  */
+      Elf_ScnList *scns_last;	/* Last element in the section list.
+				   If NULL the data has not yet been
+				   read from the file.  */
+      Elf_Data_Chunk *rawchunks; /* List of elf_getdata_rawchunk results.  */
+      unsigned int scnincr;	/* Number of sections allocate the last
+				   time.  */
+      int ehdr_flags;		/* Flags (dirty) for ELF header.  */
+      int phdr_flags;		/* Flags (dirty|malloc) for program header.  */
+      int shdr_malloced;	/* Nonzero if shdr array was allocated.  */
+      off_t sizestr_offset;	/* Offset of the size string in the parent
+				   if this is an archive member.  */
+      Elf64_Ehdr ehdr_mem;	/* Memory used for ELF header when not
+				   mmaped.  */
+
+      /* The section array.  */
+      Elf_ScnList scns;
+    } elf64;
+
+    struct
+    {
+      Elf *children;		/* List of all descriptors for this archive. */
+      Elf_Arsym *ar_sym;	/* Symbol table returned by elf_getarsym.  */
+      size_t ar_sym_num;	/* Number of entries in `ar_sym'.  */
+      char *long_names;		/* If no index is available but long names
+				   are used this elements points to the data.*/
+      size_t long_names_len;	/* Length of the long name table.  */
+      off_t offset;		/* Offset in file we are currently at.
+				   elf_next() advances this to the next
+				   member of the archive.  */
+      Elf_Arhdr elf_ar_hdr;	/* Structure returned by 'elf_getarhdr'.  */
+      struct ar_hdr ar_hdr;	/* Header read from file.  */
+      char ar_name[16];		/* NUL terminated ar_name of elf_ar_hdr.  */
+      char raw_name[17];	/* This is a buffer for the NUL terminated
+				   named raw_name used in the elf_ar_hdr.  */
+    } ar;
+  } state;
+
+  /* There absolutely never must be anything following the union.  */
+};
+
+/* Type of the conversion functions.  These functions will convert the
+   byte order.  */
+typedef void (*xfct_t) (void *, const void *, size_t, int);
+
+/* The table with the function pointers.  */
+extern const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+extern const xfct_t __elf_xfctstof[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+
+
+/* Array with sizes of the external types indexed by ELF version, binary
+   class, and type. */
+extern const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+/* We often have to access the size for a type in the current version.  */
+#if EV_NUM != 2
+# define elf_typesize(class,type,n) \
+  elfw2(class,fsize) (type, n, __libelf_version)
+#else
+# define elf_typesize(class,type,n) \
+  (__libelf_type_sizes[EV_CURRENT - 1][ELFW(ELFCLASS,class) - 1][type] * n)
+#endif
+
+/* Currently selected version of the ELF specification.  */
+extern unsigned int __libelf_version attribute_hidden;
+
+/* The byte value used for filling gaps.  */
+extern int __libelf_fill_byte attribute_hidden;
+
+/* Nonzero if the version was set.  */
+extern int __libelf_version_initialized attribute_hidden;
+
+/* Index for __libelf_type_sizes et al.  */
+#if EV_NUM == 2
+# define LIBELF_EV_IDX	0
+#else
+# define LIBELF_EV_IDX	(__libelf_version - 1)
+#endif
+
+#if !ALLOW_UNALIGNED
+/* Array with alignment requirements of the internal types indexed by ELF
+   version, binary class, and type. */
+extern const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
+# define __libelf_type_align(class, type)	\
+    (__libelf_type_aligns[LIBELF_EV_IDX][class - 1][type] ?: 1)
+#else
+# define __libelf_type_align(class, type)	1
+#endif
+
+/* Given an Elf handle and a section type returns the Elf_Data d_type.
+   Should not be called when SHF_COMPRESSED is set, the d_type should
+   be ELF_T_BYTE.  */
+extern Elf_Type __libelf_data_type (Elf *elf, int sh_type) internal_function;
+
+/* The libelf API does not have such a function but it is still useful.
+   Get the memory size for the given type.
+
+   These functions cannot be marked internal since they are aliases
+   of the export elfXX_fsize functions.*/
+extern size_t __elf32_msize (Elf_Type __type, size_t __count,
+			     unsigned int __version);
+extern size_t __elf64_msize (Elf_Type __type, size_t __count,
+			     unsigned int __version);
+
+
+/* Create Elf descriptor from memory image.  */
+extern Elf *__libelf_read_mmaped_file (int fildes, void *map_address,
+				       off_t offset, size_t maxsize,
+				       Elf_Cmd cmd, Elf *parent)
+     internal_function;
+
+/* Set error value.  */
+extern void __libelf_seterrno (int value) internal_function;
+
+/* Get the next archive header.  */
+extern int __libelf_next_arhdr_wrlock (Elf *elf) internal_function;
+
+/* Read all of the file associated with the descriptor.  */
+extern char *__libelf_readall (Elf *elf) internal_function;
+
+/* Read the complete section table and convert the byte order if necessary.  */
+extern int __libelf_readsections (Elf *elf) internal_function;
+
+/* Store the information for the raw data in the `rawdata_list' element.  */
+extern int __libelf_set_rawdata (Elf_Scn *scn) internal_function;
+extern int __libelf_set_rawdata_wrlock (Elf_Scn *scn) internal_function;
+
+
+/* Helper functions for elf_update.  */
+extern off_t __elf32_updatenull_wrlock (Elf *elf, int *change_bop,
+					size_t shnum) internal_function;
+extern off_t __elf64_updatenull_wrlock (Elf *elf, int *change_bop,
+					size_t shnum) internal_function;
+
+extern int __elf32_updatemmap (Elf *elf, int change_bo, size_t shnum)
+     internal_function;
+extern int __elf64_updatemmap (Elf *elf, int change_bo, size_t shnum)
+     internal_function;
+extern int __elf32_updatefile (Elf *elf, int change_bo, size_t shnum)
+     internal_function;
+extern int __elf64_updatefile (Elf *elf, int change_bo, size_t shnum)
+     internal_function;
+
+
+/* Alias for exported functions to avoid PLT entries, and
+   rdlock/wrlock variants of these functions.  */
+extern int __elf_end_internal (Elf *__elf) attribute_hidden;
+extern Elf *__elf_begin_internal (int __fildes, Elf_Cmd __cmd, Elf *__ref)
+     attribute_hidden;
+extern Elf32_Ehdr *__elf32_getehdr_wrlock (Elf *__elf) internal_function;
+extern Elf64_Ehdr *__elf64_getehdr_wrlock (Elf *__elf) internal_function;
+extern Elf32_Ehdr *__elf32_newehdr_internal (Elf *__elf) attribute_hidden;
+extern Elf64_Ehdr *__elf64_newehdr_internal (Elf *__elf) attribute_hidden;
+extern Elf32_Phdr *__elf32_getphdr_internal (Elf *__elf) attribute_hidden;
+extern Elf64_Phdr *__elf64_getphdr_internal (Elf *__elf) attribute_hidden;
+extern Elf32_Phdr *__elf32_getphdr_wrlock (Elf *__elf) attribute_hidden;
+extern Elf64_Phdr *__elf64_getphdr_wrlock (Elf *__elf) attribute_hidden;
+extern Elf32_Phdr *__elf32_newphdr_internal (Elf *__elf, size_t __cnt)
+     attribute_hidden;
+extern Elf64_Phdr *__elf64_newphdr_internal (Elf *__elf, size_t __cnt)
+     attribute_hidden;
+extern Elf_Scn *__elf32_offscn_internal (Elf *__elf, Elf32_Off __offset)
+     attribute_hidden;
+extern Elf_Scn *__elf64_offscn_internal (Elf *__elf, Elf64_Off __offset)
+     attribute_hidden;
+extern int __elf_getphdrnum_rdlock (Elf *__elf, size_t *__dst)
+     internal_function;
+extern int __elf_getphdrnum_chk_rdlock (Elf *__elf, size_t *__dst)
+     internal_function;
+extern int __elf_getshdrnum_rdlock (Elf *__elf, size_t *__dst)
+     internal_function;
+extern int __elf_getshdrstrndx_internal (Elf *__elf, size_t *__dst)
+     attribute_hidden;
+extern Elf32_Shdr *__elf32_getshdr_rdlock (Elf_Scn *__scn) internal_function;
+extern Elf64_Shdr *__elf64_getshdr_rdlock (Elf_Scn *__scn) internal_function;
+extern Elf32_Shdr *__elf32_getshdr_wrlock (Elf_Scn *__scn) internal_function;
+extern Elf64_Shdr *__elf64_getshdr_wrlock (Elf_Scn *__scn) internal_function;
+extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index)
+     attribute_hidden;
+extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn)
+     attribute_hidden;
+extern int __elf_scnshndx_internal (Elf_Scn *__scn) attribute_hidden;
+extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data)
+     attribute_hidden;
+extern Elf_Data *__elf_getdata_rdlock (Elf_Scn *__scn, Elf_Data *__data)
+     internal_function;
+extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data)
+     attribute_hidden;
+/* Should be called to setup first section data element if
+   data_list_rear is NULL and we know data_read is set and there is
+   raw data available.  Might upgrade the ELF lock from a read to a
+   write lock.  If the lock is already a write lock set wrlocked.  */
+extern void __libelf_set_data_list_rdlock (Elf_Scn *scn, int wrlocked)
+     internal_function;
+extern char *__elf_strptr_internal (Elf *__elf, size_t __index,
+				    size_t __offset) attribute_hidden;
+extern Elf_Data *__elf32_xlatetom_internal (Elf_Data *__dest,
+					    const Elf_Data *__src,
+					    unsigned int __encode)
+     attribute_hidden;
+extern Elf_Data *__elf64_xlatetom_internal (Elf_Data *__dest,
+					    const Elf_Data *__src,
+					    unsigned int __encode)
+     attribute_hidden;
+extern Elf_Data *__elf32_xlatetof_internal (Elf_Data *__dest,
+					    const Elf_Data *__src,
+					    unsigned int __encode)
+     attribute_hidden;
+extern Elf_Data *__elf64_xlatetof_internal (Elf_Data *__dest,
+					    const Elf_Data *__src,
+					    unsigned int __encode)
+     attribute_hidden;
+extern unsigned int __elf_version_internal (unsigned int __version)
+     attribute_hidden;
+extern unsigned long int __elf_hash_internal (const char *__string)
+       __attribute__ ((__pure__)) attribute_hidden;
+extern long int __elf32_checksum_internal (Elf *__elf) attribute_hidden;
+extern long int __elf64_checksum_internal (Elf *__elf) attribute_hidden;
+
+
+extern GElf_Ehdr *__gelf_getehdr_rdlock (Elf *__elf, GElf_Ehdr *__dest)
+     internal_function;
+extern size_t __gelf_fsize_internal (Elf *__elf, Elf_Type __type,
+				     size_t __count, unsigned int __version)
+     attribute_hidden;
+extern GElf_Shdr *__gelf_getshdr_internal (Elf_Scn *__scn, GElf_Shdr *__dst)
+     attribute_hidden;
+extern GElf_Sym *__gelf_getsym_internal (Elf_Data *__data, int __ndx,
+					 GElf_Sym *__dst) attribute_hidden;
+
+
+extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len)
+     attribute_hidden;
+
+extern void * __libelf_compress (Elf_Scn *scn, size_t hsize, int ei_data,
+				 size_t *orig_size, size_t *orig_addralign,
+				 size_t *size, bool force)
+     internal_function;
+
+extern void * __libelf_decompress (void *buf_in, size_t size_in,
+				   size_t size_out) internal_function;
+extern void * __libelf_decompress_elf (Elf_Scn *scn,
+				       size_t *size_out, size_t *addralign)
+     internal_function;
+
+
+extern void __libelf_reset_rawdata (Elf_Scn *scn, void *buf, size_t size,
+				    size_t align, Elf_Type type)
+     internal_function;
+
+
+/* We often have to update a flag iff a value changed.  Make this
+   convenient.  */
+#define update_if_changed(var, exp, flag) \
+  do {									      \
+    __typeof__ (var) *_var = &(var);					      \
+    __typeof__ (exp) _exp = (exp);					      \
+    if (*_var != _exp)							      \
+      {									      \
+	*_var = _exp;							      \
+	(flag) |= ELF_F_DIRTY;						      \
+      }									      \
+  } while (0)
+
+/* Align offset to 4 bytes as needed for note name and descriptor data.  */
+#define NOTE_ALIGN(n)	(((n) + 3) & -4U)
+
+/* Convenience macro.  */
+#define INVALID_NDX(ndx, type, data) \
+  unlikely ((data)->d_size / sizeof (type) <= (unsigned int) (ndx))
+
+#endif  /* libelfP.h */
diff --git a/third_party/elfutils/libelf/libelf_crc32.c b/third_party/elfutils/libelf/libelf_crc32.c
new file mode 100644
index 0000000..1426faf
--- /dev/null
+++ b/third_party/elfutils/libelf/libelf_crc32.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define crc32 attribute_hidden __libelf_crc32
+#define LIB_SYSTEM_H	1
+#include <libelf.h>
+#include "../lib/crc32.c"
diff --git a/third_party/elfutils/libelf/libelf_next_prime.c b/third_party/elfutils/libelf/libelf_next_prime.c
new file mode 100644
index 0000000..05229c3
--- /dev/null
+++ b/third_party/elfutils/libelf/libelf_next_prime.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define next_prime attribute_hidden __libelf_next_prime
+#include "../lib/next_prime.c"
diff --git a/third_party/elfutils/libelf/nlist.c b/third_party/elfutils/libelf/nlist.c
new file mode 100644
index 0000000..c7b32fd
--- /dev/null
+++ b/third_party/elfutils/libelf/nlist.c
@@ -0,0 +1,247 @@
+/* Extract symbol list from binary.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005, 2007, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <nlist.h>
+#include <unistd.h>
+
+#include "libelfP.h"
+
+
+struct hashentry
+{
+  const char *str;
+  GElf_Sym sym;
+};
+#define TYPE struct hashentry
+/* XXX Use a better hash function some day.  */
+#define HASHFCT(str, len) INTUSE(elf_hash) (str)
+#define COMPARE(p1, p2) strcmp ((p1)->str, (p2)->str)
+#define CLASS static
+#define PREFIX nlist_
+#define xcalloc(n, m) calloc (n, m)
+#define next_prime(s) __libelf_next_prime (s)
+#include <fixedsizehash.h>
+
+
+int
+nlist (const char *filename, struct nlist *nl)
+{
+  int fd;
+  Elf *elf;
+  Elf_Scn *scn = NULL;
+  Elf_Scn *symscn = NULL;
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = NULL;
+  Elf_Data *data;
+  struct nlist_fshash *table;
+  size_t nsyms;
+  size_t cnt;
+
+  /* Open the file.  */
+  fd = open (filename, O_RDONLY);
+  if (fd == -1)
+    {
+      __libelf_seterrno (ELF_E_NOFILE);
+      goto fail;
+    }
+
+  /* For compatibility reasons (`nlist' existed before ELF and libelf)
+     we don't expect the caller to set the ELF version.  Do this here
+     if it hasn't happened yet.  */
+  if (__libelf_version_initialized == 0)
+    INTUSE(elf_version) (EV_CURRENT);
+
+  /* Now get an ELF descriptor.  */
+  elf = INTUSE(elf_begin) (fd, ELF_C_READ_MMAP, NULL);
+  if (elf == NULL)
+    goto fail_fd;
+
+  /* Find a symbol table.  We prefer the real symbol table but if it
+     does not exist use the dynamic symbol table.  */
+  while ((scn = INTUSE(elf_nextscn) (elf, scn)) != NULL)
+    {
+      shdr = INTUSE(gelf_getshdr) (scn, &shdr_mem);
+      if (shdr == NULL)
+	goto fail_close;
+
+      /* That is what we are looking for.  */
+      if (shdr->sh_type == SHT_SYMTAB)
+	{
+	  symscn = scn;
+	  break;
+	}
+
+      /* Better than nothing.  Remember this section.  */
+      if (shdr->sh_type == SHT_DYNSYM)
+	symscn = scn;
+    }
+
+  if (symscn == NULL)
+    /* We haven't found anything.  Fail.  */
+    goto fail_close;
+
+  /* Re-get the section header in case we found only the dynamic symbol
+     table.  */
+  if (scn == NULL)
+    {
+      shdr = INTUSE(gelf_getshdr) (symscn, &shdr_mem);
+      if (unlikely (shdr == NULL))
+	goto fail_close;
+    }
+  /* SHDR->SH_LINK now contains the index of the string section.  */
+
+  /* Get the data for the symbol section.  */
+  data = INTUSE(elf_getdata) (symscn, NULL);
+  if (data == NULL)
+    goto fail_close;
+
+  /* How many symbols are there?  */
+  nsyms = (shdr->sh_size
+	   / INTUSE(gelf_fsize) (elf, ELF_T_SYM, 1, EV_CURRENT));
+
+  /* Create the hash table.  */
+  table = nlist_fshash_init (nsyms);
+  if (table == NULL)
+    {
+      __libelf_seterrno (ELF_E_NOMEM);
+      goto fail_close;
+    }
+
+  /* Iterate over all the symbols in the section.  */
+  for (cnt = 0; cnt < nsyms; ++cnt)
+    {
+      struct hashentry mem;
+      GElf_Sym *sym;
+
+      /* Get the symbol.  */
+      sym = INTUSE(gelf_getsym) (data, cnt, &mem.sym);
+      if (sym == NULL)
+	goto fail_dealloc;
+
+      /* Get the name of the symbol.  */
+      mem.str = INTUSE(elf_strptr) (elf, shdr->sh_link, sym->st_name);
+      if (mem.str == NULL)
+	goto fail_dealloc;
+
+      /* Don't allow zero-length strings.  */
+      if (mem.str[0] == '\0')
+	continue;
+
+      /* And add it to the hash table.  Note that we are using the
+         overwrite version.  This will ensure that
+	 a) global symbols are preferred over local symbols since
+	    they are all located at the end
+	 b) if there are multiple local symbols with the same name
+	    the last one is used.
+      */
+      (void) nlist_fshash_overwrite (table, mem.str, 0, &mem);
+    }
+
+  /* Now it is time to look for the symbols the user asked for.
+     XXX What is a `null name/null string'?  This is what the
+     standard says terminates the list.  Is it a null pointer
+     or a zero-length string?  We test for both...  */
+  while (nl->n_name != NULL && nl->n_name[0] != '\0')
+    {
+      struct hashentry search;
+      const struct hashentry *found;
+
+      /* Search for a matching entry in the hash table.  */
+      search.str = nl->n_name;
+      found = nlist_fshash_find (table, nl->n_name, 0, &search);
+
+      if (found != NULL)
+	{
+	  /* Found it.  */
+	  nl->n_value = found->sym.st_value;
+	  nl->n_scnum = found->sym.st_shndx;
+	  nl->n_type = GELF_ST_TYPE (found->sym.st_info);
+	  /* XXX What shall we fill in the next fields?  */
+	  nl->n_sclass = 0;
+	  nl->n_numaux = 0;
+	}
+      else
+	{
+	  /* Not there.  */
+	  nl->n_value = 0;
+	  nl->n_scnum = 0;
+	  nl->n_type = 0;
+	  nl->n_sclass = 0;
+	  nl->n_numaux = 0;
+	}
+
+      /* Next search request.  */
+      ++nl;
+    }
+
+  /* Free the resources.  */
+  nlist_fshash_fini (table);
+
+  /* We do not need the ELF descriptor anymore.  */
+  (void) INTUSE(elf_end) (elf);
+
+  /* Neither the file descriptor.  */
+  (void) close (fd);
+
+  return 0;
+
+ fail_dealloc:
+  nlist_fshash_fini (table);
+
+ fail_close:
+  /* We do not need the ELF descriptor anymore.  */
+  (void) INTUSE(elf_end) (elf);
+
+ fail_fd:
+  /* Neither the file descriptor.  */
+  (void) close (fd);
+
+ fail:
+  /* We have to set all entries to zero.  */
+  while (nl->n_name != NULL && nl->n_name[0] != '\0')
+    {
+      nl->n_value = 0;
+      nl->n_scnum = 0;
+      nl->n_type = 0;
+      nl->n_sclass = 0;
+      nl->n_numaux = 0;
+
+      /* Next entry.  */
+      ++nl;
+    }
+
+  return -1;
+}
diff --git a/third_party/elfutils/libelf/nlist.h b/third_party/elfutils/libelf/nlist.h
new file mode 100644
index 0000000..5990918
--- /dev/null
+++ b/third_party/elfutils/libelf/nlist.h
@@ -0,0 +1,56 @@
+/* Interface for nlist.
+   Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _NLIST_H
+#define _NLIST_H 1
+
+
+/* Symbol list type.  */
+struct nlist
+{
+  char *n_name;			/* Symbol name.  */
+  long int n_value;		/* Value of symbol.  */
+  short int n_scnum;		/* Section number found in.  */
+  unsigned short int n_type;	/* Type of symbol.  */
+  char n_sclass;		/* Storage class.  */
+  char n_numaux;		/* Number of auxiliary entries.  */
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Get specified entries from file.  */
+extern int nlist (__const char *__filename, struct nlist *__nl);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* nlist.h */
diff --git a/third_party/elfutils/libelf/note_xlate.h b/third_party/elfutils/libelf/note_xlate.h
new file mode 100644
index 0000000..62c6f63
--- /dev/null
+++ b/third_party/elfutils/libelf/note_xlate.h
@@ -0,0 +1,64 @@
+/* Conversion functions for notes.
+   Copyright (C) 2007, 2009, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+static void
+elf_cvt_note (void *dest, const void *src, size_t len, int encode)
+{
+  assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
+
+  while (len >= sizeof (Elf32_Nhdr))
+    {
+      (1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr),
+					     encode);
+      const Elf32_Nhdr *n = encode ? src : dest;
+      Elf32_Word namesz = NOTE_ALIGN (n->n_namesz);
+      Elf32_Word descsz = NOTE_ALIGN (n->n_descsz);
+
+      len -= sizeof *n;
+      src += sizeof *n;
+      dest += sizeof *n;
+
+      if (namesz > len)
+	break;
+      len -= namesz;
+      if (descsz > len)
+	break;
+      len -= descsz;
+
+      if (src != dest)
+	memcpy (dest, src, namesz + descsz);
+
+      src += namesz + descsz;
+      dest += namesz + descsz;
+    }
+
+    /* Copy opver any leftover data unconcerted.  Probably part of
+       truncated name/desc data.  */
+    if (unlikely (len > 0) && src != dest)
+      memcpy (dest, src, len);
+}
diff --git a/third_party/elfutils/libelf/version_xlate.h b/third_party/elfutils/libelf/version_xlate.h
new file mode 100644
index 0000000..9fe01c6
--- /dev/null
+++ b/third_party/elfutils/libelf/version_xlate.h
@@ -0,0 +1,230 @@
+/* Conversion functions for versioning information.
+   Copyright (C) 1998, 1999, 2000, 2002, 2003, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * 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
+
+   or both in parallel, as here.
+
+   elfutils 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.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#include <assert.h>
+#include <gelf.h>
+
+#include "libelfP.h"
+
+
+static void
+elf_cvt_Verdef (void *dest, const void *src, size_t len, int encode)
+{
+  /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux.
+     To recognize them we have to walk the data structure and convert
+     them one after the other.  The ENCODE parameter specifies whether
+     we are encoding or decoding.  When we are encoding we can immediately
+     use the data in the buffer; if not, we have to decode the data before
+     using it.  */
+  size_t def_offset = 0;
+  GElf_Verdef *ddest;
+  GElf_Verdef *dsrc;
+
+  /* We rely on the types being all the same size.  */
+  assert (sizeof (GElf_Verdef) == sizeof (Elf32_Verdef));
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf32_Verdaux));
+  assert (sizeof (GElf_Verdef) == sizeof (Elf64_Verdef));
+  assert (sizeof (GElf_Verdaux) == sizeof (Elf64_Verdaux));
+
+  if (len == 0)
+    return;
+
+  /* Below we rely on the next field offsets to be correct, start by
+     copying over all data as is in case some data isn't translated.
+     We don't want to leave (undefined) garbage in the dest buffer.  */
+  memmove (dest, src, len);
+
+  do
+    {
+      size_t aux_offset;
+      GElf_Verdaux *asrc;
+
+      /* Test for correct offset.  */
+      if (def_offset > len || len - def_offset < sizeof (GElf_Verdef))
+	return;
+
+      /* Work the tree from the first record.  */
+      ddest = (GElf_Verdef *) ((char *) dest + def_offset);
+      dsrc = (GElf_Verdef *) ((char *) src + def_offset);
+
+      /* Decode first if necessary.  */
+      if (! encode)
+	{
+	  ddest->vd_version = bswap_16 (dsrc->vd_version);
+	  ddest->vd_flags = bswap_16 (dsrc->vd_flags);
+	  ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
+	  ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
+	  ddest->vd_hash = bswap_32 (dsrc->vd_hash);
+	  ddest->vd_aux = bswap_32 (dsrc->vd_aux);
+	  ddest->vd_next = bswap_32 (dsrc->vd_next);
+
+	  aux_offset = def_offset + ddest->vd_aux;
+	}
+      else
+	aux_offset = def_offset + dsrc->vd_aux;
+
+      /* Handle all the auxiliary records belonging to this definition.  */
+      do
+	{
+	  GElf_Verdaux *adest;
+
+	  /* Test for correct offset.  */
+	  if (aux_offset > len || len - aux_offset < sizeof (GElf_Verdaux))
+	    return;
+
+	  adest = (GElf_Verdaux *) ((char *) dest + aux_offset);
+	  asrc = (GElf_Verdaux *) ((char *) src + aux_offset);
+
+	  if (encode)
+	    aux_offset += asrc->vda_next;
+
+	  adest->vda_name = bswap_32 (asrc->vda_name);
+	  adest->vda_next = bswap_32 (asrc->vda_next);
+
+	  if (! encode)
+	    aux_offset += adest->vda_next;
+	}
+      while (asrc->vda_next != 0);
+
+      /* Encode now if necessary.  */
+      if (encode)
+	{
+	  def_offset += dsrc->vd_next;
+
+	  ddest->vd_version = bswap_16 (dsrc->vd_version);
+	  ddest->vd_flags = bswap_16 (dsrc->vd_flags);
+	  ddest->vd_ndx = bswap_16 (dsrc->vd_ndx);
+	  ddest->vd_cnt = bswap_16 (dsrc->vd_cnt);
+	  ddest->vd_hash = bswap_32 (dsrc->vd_hash);
+	  ddest->vd_aux = bswap_32 (dsrc->vd_aux);
+	  ddest->vd_next = bswap_32 (dsrc->vd_next);
+	}
+      else
+	def_offset += ddest->vd_next;
+    }
+  while (dsrc->vd_next != 0);
+}
+
+
+static void
+elf_cvt_Verneed (void *dest, const void *src, size_t len, int encode)
+{
+  /* We have two different record types: ElfXX_Verndef and ElfXX_Verdaux.
+     To recognize them we have to walk the data structure and convert
+     them one after the other.  The ENCODE parameter specifies whether
+     we are encoding or decoding.  When we are encoding we can immediately
+     use the data in the buffer; if not, we have to decode the data before
+     using it.  */
+  size_t need_offset = 0;
+  GElf_Verneed *ndest;
+  GElf_Verneed *nsrc;
+
+  /* We rely on the types being all the same size.  */
+  assert (sizeof (GElf_Verneed) == sizeof (Elf32_Verneed));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf32_Vernaux));
+  assert (sizeof (GElf_Verneed) == sizeof (Elf64_Verneed));
+  assert (sizeof (GElf_Vernaux) == sizeof (Elf64_Vernaux));
+
+  if (len == 0)
+    return;
+
+  /* Below we rely on the next field offsets to be correct, start by
+     copying over all data as is in case some data isn't translated.
+     We don't want to leave (undefined) garbage in the dest buffer.  */
+  memmove (dest, src, len);
+
+  do
+    {
+      size_t aux_offset;
+      GElf_Vernaux *asrc;
+
+      /* Test for correct offset.  */
+      if (need_offset > len || len - need_offset < sizeof (GElf_Verneed))
+	return;
+
+      /* Work the tree from the first record.  */
+      ndest = (GElf_Verneed *) ((char *) dest + need_offset);
+      nsrc = (GElf_Verneed *) ((char *) src + need_offset);
+
+      /* Decode first if necessary.  */
+      if (! encode)
+	{
+	  ndest->vn_version = bswap_16 (nsrc->vn_version);
+	  ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
+	  ndest->vn_file = bswap_32 (nsrc->vn_file);
+	  ndest->vn_aux = bswap_32 (nsrc->vn_aux);
+	  ndest->vn_next = bswap_32 (nsrc->vn_next);
+
+	  aux_offset = need_offset + ndest->vn_aux;
+	}
+      else
+	aux_offset = need_offset + nsrc->vn_aux;
+
+      /* Handle all the auxiliary records belonging to this requirement.  */
+      do
+	{
+	  GElf_Vernaux *adest;
+
+	  /* Test for correct offset.  */
+	  if (aux_offset > len || len - aux_offset < sizeof (GElf_Vernaux))
+	    return;
+
+	  adest = (GElf_Vernaux *) ((char *) dest + aux_offset);
+	  asrc = (GElf_Vernaux *) ((char *) src + aux_offset);
+
+	  if (encode)
+	    aux_offset += asrc->vna_next;
+
+	  adest->vna_hash = bswap_32 (asrc->vna_hash);
+	  adest->vna_flags = bswap_16 (asrc->vna_flags);
+	  adest->vna_other = bswap_16 (asrc->vna_other);
+	  adest->vna_name = bswap_32 (asrc->vna_name);
+	  adest->vna_next = bswap_32 (asrc->vna_next);
+
+	  if (! encode)
+	    aux_offset += adest->vna_next;
+	}
+      while (asrc->vna_next != 0);
+
+      /* Encode now if necessary.  */
+      if (encode)
+	{
+	  need_offset += nsrc->vn_next;
+
+	  ndest->vn_version = bswap_16 (nsrc->vn_version);
+	  ndest->vn_cnt = bswap_16 (nsrc->vn_cnt);
+	  ndest->vn_file = bswap_32 (nsrc->vn_file);
+	  ndest->vn_aux = bswap_32 (nsrc->vn_aux);
+	  ndest->vn_next = bswap_32 (nsrc->vn_next);
+	}
+      else
+	need_offset += ndest->vn_next;
+    }
+  while (nsrc->vn_next != 0);
+}
diff --git a/third_party/elfutils/m4/ChangeLog b/third_party/elfutils/m4/ChangeLog
new file mode 100644
index 0000000..9ee06d7
--- /dev/null
+++ b/third_party/elfutils/m4/ChangeLog
@@ -0,0 +1,82 @@
+2015-05-01  Mark Wielaard  <mjw@redhat.com>
+
+	* zip.m4: Explicitly set with_ to no, if not yes.
+
+2014-07-14  Mark Wielaard  <mjw@redhat.com>
+
+	* biarch.m4 (utrace_BIARCH): Set biarch-no for cross-compile using
+	AC_RUN_IFELSE extra argument.
+
+2013-12-02  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* biarch.m4 (utrace_BIARCH): Call AC_MSG_WARN if !BIARCH.
+
+2013-11-07  Roland McGrath  <roland@redhat.com>
+	    Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* biarch.m4: New file.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* gettext.m4: Upgrade to gettext-0.18.2.
+	* iconv.m4: Upgrade to gettext-0.18.2.
+	* po.m4: Upgrade to gettext-0.18.2.
+
+2010-04-14  Roland McGrath  <roland@redhat.com>
+
+	* gettext.m4: Upgrade to gettext-0.17.
+	* iconv.m4: Upgrade to gettext-0.17.
+	* po.m4: Upgrade to gettext-0.17.
+
+2009-08-26  Roland McGrath  <roland@redhat.com>
+
+	* zip.m4 (eu_ZIPLIB): Don't apply lib/LIB suffix to args.
+
+2009-02-01  Roland McGrath  <roland@redhat.com>
+
+	* zip.m4: Fix --with/--without argument handling.
+
+2009-01-08  Roland McGrath  <roland@redhat.com>
+
+	* zip.am: New file.
+	* Makefile.am (EXTRA_DIST): Add it.
+
+2007-06-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* gettext.m4: Update from gettext 0.16.1.
+	* iconv.m4: Likewise.
+	* progtest.m4: Likewise.
+	* nls.m4: New file.
+	* po.m4: New file.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Remove glibc21.m4, intdiv0.m4,
+	inttypes.m4, inttypes_h.m4, inttypes-pri.m4, isc-posix.m4,
+	lib-ld.m4, lib-link.m4, lib-prefix.m4, stdint_h.m4, uintmax_t.m4,
+	and ulonglong.m4.
+	* glibc21.m4: Removed.
+	* inttypes_h.m4: Removed.
+	* inttypes.m4: Removed.
+	* inttypes-pri.m4: Removed.
+	* isc-posix.m4: Removed.
+	* lib-ld.m4: Removed.
+	* lib-link.m4: Removed.
+	* lib-prefix.m4: Removed.
+	* stdint_h.m4: Removed.
+	* uintmax_t.m4: Removed.
+	* ulonglong.m4: Removed.
+
+2002-03-22  gettextize  <bug-gnu-gettext@gnu.org>
+
+	* codeset.m4: Upgrade to gettext-0.11.
+	* gettext.m4: Upgrade to gettext-0.11.
+	* glibc21.m4: Upgrade to gettext-0.11.
+	* iconv.m4: Upgrade to gettext-0.11.
+	* isc-posix.m4: New file, from gettext-0.11.
+	* lcmessage.m4: Upgrade to gettext-0.11.
+	* lib-ld.m4: Upgrade to gettext-0.11.
+	* lib-link.m4: Upgrade to gettext-0.11.
+	* lib-prefix.m4: Upgrade to gettext-0.11.
+	* progtest.m4: Upgrade to gettext-0.11.
+	* Makefile.am (EXTRA_DIST): Add the new files.
diff --git a/third_party/elfutils/m4/Makefile.am b/third_party/elfutils/m4/Makefile.am
new file mode 100644
index 0000000..3b0e114
--- /dev/null
+++ b/third_party/elfutils/m4/Makefile.am
@@ -0,0 +1,21 @@
+## Process this file with automake to produce Makefile.in -*-Makefile-*-
+##
+## Copyright (C) 2000-2009 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file 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 3 of the License, or
+## (at your option) any later version.
+##
+## elfutils 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.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program.  If not, see <http://www.gnu.org/licenses/>.
+##
+
+##m4-files-begin
+EXTRA_DIST = codeset.m4 gettext.m4 iconv.m4 lcmessage.m4 progtest.m4 zip.m4
diff --git a/third_party/elfutils/m4/biarch.m4 b/third_party/elfutils/m4/biarch.m4
new file mode 100644
index 0000000..c238d8d
--- /dev/null
+++ b/third_party/elfutils/m4/biarch.m4
@@ -0,0 +1,47 @@
+AC_DEFUN([utrace_CC_m32], [dnl
+AC_CACHE_CHECK([$CC option for 32-bit word size], utrace_cv_CC_m32, [dnl
+save_CC="$CC"
+utrace_cv_CC_m32=none
+for ut_try in -m32 -m31; do
+  [CC=`echo "$save_CC" | sed 's/ -m[36][241]//'`" $ut_try"]
+  AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int foo (void) { return 1; }]])],
+		    [utrace_cv_CC_m32=$ut_try])
+  test x$utrace_cv_CC_m32 = xnone || break
+done
+CC="$save_CC"])])
+
+AC_DEFUN([utrace_HOST64], [AC_REQUIRE([utrace_CC_m32])
+AS_IF([test x$utrace_cv_CC_m32 != xnone], [dnl
+AC_CACHE_CHECK([for 64-bit host], utrace_cv_host64, [dnl
+AC_EGREP_CPP([@utrace_host64@], [#include <stdint.h>
+#if (UINTPTR_MAX > 0xffffffffUL)
+@utrace_host64@
+#endif],
+             utrace_cv_host64=yes, utrace_cv_host64=no)])
+AS_IF([test $utrace_cv_host64 = no],
+      [utrace_biarch=-m64 utrace_thisarch=$utrace_cv_CC_m32],
+      [utrace_biarch=$utrace_cv_CC_m32 utrace_thisarch=-m64])
+
+biarch_CC=`echo "$CC" | sed "s/ *${utrace_thisarch}//"`
+biarch_CC="$biarch_CC $utrace_biarch"])])
+
+AC_DEFUN([utrace_BIARCH], [AC_REQUIRE([utrace_HOST64])
+utrace_biarch_forced=no
+AC_ARG_WITH([biarch],
+	    AC_HELP_STRING([--with-biarch],
+			   [enable biarch tests despite build problems]),
+	    [AS_IF([test "x$with_biarch" != xno], [utrace_biarch_forced=yes])])
+AS_IF([test $utrace_biarch_forced = yes], [dnl
+utrace_cv_cc_biarch=yes
+AC_MSG_NOTICE([enabling biarch tests regardless using $biarch_CC])], [dnl
+AS_IF([test x$utrace_cv_CC_m32 != xnone], [dnl
+AC_CACHE_CHECK([whether $biarch_CC makes executables we can run],
+	       utrace_cv_cc_biarch, [dnl
+save_CC="$CC"
+CC="$biarch_CC"
+AC_RUN_IFELSE([AC_LANG_PROGRAM([], [])],
+	      utrace_cv_cc_biarch=yes, utrace_cv_cc_biarch=no, utrace_cv_cc_biarch=no)
+CC="$save_CC"])], [utrace_cv_cc_biarch=no])
+AS_IF([test $utrace_cv_cc_biarch != yes], [dnl
+AC_MSG_WARN([not running biarch tests, $biarch_CC does not work])])])
+AM_CONDITIONAL(BIARCH, [test $utrace_cv_cc_biarch = yes])])
diff --git a/third_party/elfutils/m4/codeset.m4 b/third_party/elfutils/m4/codeset.m4
new file mode 100644
index 0000000..59535eb
--- /dev/null
+++ b/third_party/elfutils/m4/codeset.m4
@@ -0,0 +1,23 @@
+# codeset.m4 serial AM1 (gettext-0.10.40)
+dnl Copyright (C) 2000-2002 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License.  As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_LANGINFO_CODESET],
+[
+  AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset,
+    [AC_TRY_LINK([#include <langinfo.h>],
+      [char* cs = nl_langinfo(CODESET);],
+      am_cv_langinfo_codeset=yes,
+      am_cv_langinfo_codeset=no)
+    ])
+  if test $am_cv_langinfo_codeset = yes; then
+    AC_DEFINE(HAVE_LANGINFO_CODESET, 1,
+      [Define if you have <langinfo.h> and nl_langinfo(CODESET).])
+  fi
+])
diff --git a/third_party/elfutils/m4/gettext.m4 b/third_party/elfutils/m4/gettext.m4
new file mode 100644
index 0000000..8d1f066
--- /dev/null
+++ b/third_party/elfutils/m4/gettext.m4
@@ -0,0 +1,401 @@
+# gettext.m4 serial 66 (gettext-0.18.2)
+dnl Copyright (C) 1995-2013 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2006, 2008-2010.
+
+dnl Macro to add for using GNU gettext.
+
+dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
+dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The
+dnl    default (if it is not specified or empty) is 'no-libtool'.
+dnl    INTLSYMBOL should be 'external' for packages with no intl directory,
+dnl    and 'no-libtool' or 'use-libtool' for packages with an intl directory.
+dnl    If INTLSYMBOL is 'use-libtool', then a libtool library
+dnl    $(top_builddir)/intl/libintl.la will be created (shared and/or static,
+dnl    depending on --{enable,disable}-{shared,static} and on the presence of
+dnl    AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
+dnl    $(top_builddir)/intl/libintl.a will be created.
+dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
+dnl    implementations (in libc or libintl) without the ngettext() function
+dnl    will be ignored.  If NEEDSYMBOL is specified and is
+dnl    'need-formatstring-macros', then GNU gettext implementations that don't
+dnl    support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
+dnl INTLDIR is used to find the intl libraries.  If empty,
+dnl    the value '$(top_builddir)/intl/' is used.
+dnl
+dnl The result of the configuration is one of three cases:
+dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
+dnl    and used.
+dnl    Catalog format: GNU --> install in $(datadir)
+dnl    Catalog extension: .mo after installation, .gmo in source tree
+dnl 2) GNU gettext has been found in the system's C library.
+dnl    Catalog format: GNU --> install in $(datadir)
+dnl    Catalog extension: .mo after installation, .gmo in source tree
+dnl 3) No internationalization, always use English msgid.
+dnl    Catalog format: none
+dnl    Catalog extension: none
+dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
+dnl The use of .gmo is historical (it was needed to avoid overwriting the
+dnl GNU format catalogs when building on a platform with an X/Open gettext),
+dnl but we keep it in order not to force irrelevant filename changes on the
+dnl maintainers.
+dnl
+AC_DEFUN([AM_GNU_GETTEXT],
+[
+  dnl Argument checking.
+  ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
+    [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
+])])])])])
+  ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
+    [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])])
+  ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
+    [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
+])])])])
+  define([gt_included_intl],
+    ifelse([$1], [external],
+      ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]),
+      [yes]))
+  define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
+  gt_NEEDS_INIT
+  AM_GNU_GETTEXT_NEED([$2])
+
+  AC_REQUIRE([AM_PO_SUBDIRS])dnl
+  ifelse(gt_included_intl, yes, [
+    AC_REQUIRE([AM_INTL_SUBDIR])dnl
+  ])
+
+  dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+  AC_REQUIRE([AC_LIB_RPATH])
+
+  dnl Sometimes libintl requires libiconv, so first search for libiconv.
+  dnl Ideally we would do this search only after the
+  dnl      if test "$USE_NLS" = "yes"; then
+  dnl        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
+  dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
+  dnl the configure script would need to contain the same shell code
+  dnl again, outside any 'if'. There are two solutions:
+  dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
+  dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
+  dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
+  dnl documented, we avoid it.
+  ifelse(gt_included_intl, yes, , [
+    AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+  ])
+
+  dnl Sometimes, on Mac OS X, libintl requires linking with CoreFoundation.
+  gt_INTL_MACOSX
+
+  dnl Set USE_NLS.
+  AC_REQUIRE([AM_NLS])
+
+  ifelse(gt_included_intl, yes, [
+    BUILD_INCLUDED_LIBINTL=no
+    USE_INCLUDED_LIBINTL=no
+  ])
+  LIBINTL=
+  LTLIBINTL=
+  POSUB=
+
+  dnl Add a version number to the cache macros.
+  case " $gt_needs " in
+    *" need-formatstring-macros "*) gt_api_version=3 ;;
+    *" need-ngettext "*) gt_api_version=2 ;;
+    *) gt_api_version=1 ;;
+  esac
+  gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
+  gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
+
+  dnl If we use NLS figure out what method
+  if test "$USE_NLS" = "yes"; then
+    gt_use_preinstalled_gnugettext=no
+    ifelse(gt_included_intl, yes, [
+      AC_MSG_CHECKING([whether included gettext is requested])
+      AC_ARG_WITH([included-gettext],
+        [  --with-included-gettext use the GNU gettext library included here],
+        nls_cv_force_use_gnu_gettext=$withval,
+        nls_cv_force_use_gnu_gettext=no)
+      AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext])
+
+      nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+      if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+    ])
+        dnl User does not insist on using GNU NLS library.  Figure out what
+        dnl to use.  If GNU gettext is available we use this.  Else we have
+        dnl to fall back to GNU NLS library.
+
+        if test $gt_api_version -ge 3; then
+          gt_revision_test_code='
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
+#endif
+changequote(,)dnl
+typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
+changequote([,])dnl
+'
+        else
+          gt_revision_test_code=
+        fi
+        if test $gt_api_version -ge 2; then
+          gt_expression_test_code=' + * ngettext ("", "", 0)'
+        else
+          gt_expression_test_code=
+        fi
+
+        AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
+         [AC_LINK_IFELSE(
+            [AC_LANG_PROGRAM(
+               [[
+#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern int *_nl_domain_bindings;
+               ]],
+               [[
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings
+               ]])],
+            [eval "$gt_func_gnugettext_libc=yes"],
+            [eval "$gt_func_gnugettext_libc=no"])])
+
+        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
+          dnl Sometimes libintl requires libiconv, so first search for libiconv.
+          ifelse(gt_included_intl, yes, , [
+            AM_ICONV_LINK
+          ])
+          dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
+          dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
+          dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
+          dnl even if libiconv doesn't exist.
+          AC_LIB_LINKFLAGS_BODY([intl])
+          AC_CACHE_CHECK([for GNU gettext in libintl],
+            [$gt_func_gnugettext_libintl],
+           [gt_save_CPPFLAGS="$CPPFLAGS"
+            CPPFLAGS="$CPPFLAGS $INCINTL"
+            gt_save_LIBS="$LIBS"
+            LIBS="$LIBS $LIBINTL"
+            dnl Now see whether libintl exists and does not depend on libiconv.
+            AC_LINK_IFELSE(
+              [AC_LANG_PROGRAM(
+                 [[
+#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);
+                 ]],
+                 [[
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+                 ]])],
+              [eval "$gt_func_gnugettext_libintl=yes"],
+              [eval "$gt_func_gnugettext_libintl=no"])
+            dnl Now see whether libintl exists and depends on libiconv.
+            if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
+              LIBS="$LIBS $LIBICONV"
+              AC_LINK_IFELSE(
+                [AC_LANG_PROGRAM(
+                   [[
+#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);
+                   ]],
+                   [[
+bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+                   ]])],
+                [LIBINTL="$LIBINTL $LIBICONV"
+                 LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+                 eval "$gt_func_gnugettext_libintl=yes"
+                ])
+            fi
+            CPPFLAGS="$gt_save_CPPFLAGS"
+            LIBS="$gt_save_LIBS"])
+        fi
+
+        dnl If an already present or preinstalled GNU gettext() is found,
+        dnl use it.  But if this macro is used in GNU gettext, and GNU
+        dnl gettext is already preinstalled in libintl, we update this
+        dnl libintl.  (Cf. the install rule in intl/Makefile.in.)
+        if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
+           || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \
+                && test "$PACKAGE" != gettext-runtime \
+                && test "$PACKAGE" != gettext-tools; }; then
+          gt_use_preinstalled_gnugettext=yes
+        else
+          dnl Reset the values set by searching for libintl.
+          LIBINTL=
+          LTLIBINTL=
+          INCINTL=
+        fi
+
+    ifelse(gt_included_intl, yes, [
+        if test "$gt_use_preinstalled_gnugettext" != "yes"; then
+          dnl GNU gettext is not found in the C library.
+          dnl Fall back on included GNU gettext library.
+          nls_cv_use_gnu_gettext=yes
+        fi
+      fi
+
+      if test "$nls_cv_use_gnu_gettext" = "yes"; then
+        dnl Mark actions used to generate GNU NLS library.
+        BUILD_INCLUDED_LIBINTL=yes
+        USE_INCLUDED_LIBINTL=yes
+        LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD"
+        LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD"
+        LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
+      fi
+
+      CATOBJEXT=
+      if test "$gt_use_preinstalled_gnugettext" = "yes" \
+         || test "$nls_cv_use_gnu_gettext" = "yes"; then
+        dnl Mark actions to use GNU gettext tools.
+        CATOBJEXT=.gmo
+      fi
+    ])
+
+    if test -n "$INTL_MACOSX_LIBS"; then
+      if test "$gt_use_preinstalled_gnugettext" = "yes" \
+         || test "$nls_cv_use_gnu_gettext" = "yes"; then
+        dnl Some extra flags are needed during linking.
+        LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
+        LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
+      fi
+    fi
+
+    if test "$gt_use_preinstalled_gnugettext" = "yes" \
+       || test "$nls_cv_use_gnu_gettext" = "yes"; then
+      AC_DEFINE([ENABLE_NLS], [1],
+        [Define to 1 if translation of program messages to the user's native language
+   is requested.])
+    else
+      USE_NLS=no
+    fi
+  fi
+
+  AC_MSG_CHECKING([whether to use NLS])
+  AC_MSG_RESULT([$USE_NLS])
+  if test "$USE_NLS" = "yes"; then
+    AC_MSG_CHECKING([where the gettext function comes from])
+    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+        gt_source="external libintl"
+      else
+        gt_source="libc"
+      fi
+    else
+      gt_source="included intl directory"
+    fi
+    AC_MSG_RESULT([$gt_source])
+  fi
+
+  if test "$USE_NLS" = "yes"; then
+
+    if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+      if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+        AC_MSG_CHECKING([how to link with libintl])
+        AC_MSG_RESULT([$LIBINTL])
+        AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
+      fi
+
+      dnl For backward compatibility. Some packages may be using this.
+      AC_DEFINE([HAVE_GETTEXT], [1],
+       [Define if the GNU gettext() function is already present or preinstalled.])
+      AC_DEFINE([HAVE_DCGETTEXT], [1],
+       [Define if the GNU dcgettext() function is already present or preinstalled.])
+    fi
+
+    dnl We need to process the po/ directory.
+    POSUB=po
+  fi
+
+  ifelse(gt_included_intl, yes, [
+    dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
+    dnl to 'yes' because some of the testsuite requires it.
+    if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then
+      BUILD_INCLUDED_LIBINTL=yes
+    fi
+
+    dnl Make all variables we use known to autoconf.
+    AC_SUBST([BUILD_INCLUDED_LIBINTL])
+    AC_SUBST([USE_INCLUDED_LIBINTL])
+    AC_SUBST([CATOBJEXT])
+
+    dnl For backward compatibility. Some configure.ins may be using this.
+    nls_cv_header_intl=
+    nls_cv_header_libgt=
+
+    dnl For backward compatibility. Some Makefiles may be using this.
+    DATADIRNAME=share
+    AC_SUBST([DATADIRNAME])
+
+    dnl For backward compatibility. Some Makefiles may be using this.
+    INSTOBJEXT=.mo
+    AC_SUBST([INSTOBJEXT])
+
+    dnl For backward compatibility. Some Makefiles may be using this.
+    GENCAT=gencat
+    AC_SUBST([GENCAT])
+
+    dnl For backward compatibility. Some Makefiles may be using this.
+    INTLOBJS=
+    if test "$USE_INCLUDED_LIBINTL" = yes; then
+      INTLOBJS="\$(GETTOBJS)"
+    fi
+    AC_SUBST([INTLOBJS])
+
+    dnl Enable libtool support if the surrounding package wishes it.
+    INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
+    AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX])
+  ])
+
+  dnl For backward compatibility. Some Makefiles may be using this.
+  INTLLIBS="$LIBINTL"
+  AC_SUBST([INTLLIBS])
+
+  dnl Make all documented variables known to autoconf.
+  AC_SUBST([LIBINTL])
+  AC_SUBST([LTLIBINTL])
+  AC_SUBST([POSUB])
+])
+
+
+dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized.
+m4_define([gt_NEEDS_INIT],
+[
+  m4_divert_text([DEFAULTS], [gt_needs=])
+  m4_define([gt_NEEDS_INIT], [])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL])
+AC_DEFUN([AM_GNU_GETTEXT_NEED],
+[
+  m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
+AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
diff --git a/third_party/elfutils/m4/iconv.m4 b/third_party/elfutils/m4/iconv.m4
new file mode 100644
index 0000000..a503646
--- /dev/null
+++ b/third_party/elfutils/m4/iconv.m4
@@ -0,0 +1,268 @@
+# iconv.m4 serial 18 (gettext-0.18.2)
+dnl Copyright (C) 2000-2002, 2007-2013 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
+[
+  dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+  AC_REQUIRE([AC_LIB_RPATH])
+
+  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+  dnl accordingly.
+  AC_LIB_LINKFLAGS_BODY([iconv])
+])
+
+AC_DEFUN([AM_ICONV_LINK],
+[
+  dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
+  dnl those with the standalone portable GNU libiconv installed).
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+  dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+  dnl accordingly.
+  AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+
+  dnl Add $INCICONV to CPPFLAGS before performing the following checks,
+  dnl because if the user has installed libiconv and not disabled its use
+  dnl via --without-libiconv-prefix, he wants to use it. The first
+  dnl AC_LINK_IFELSE will then fail, the second AC_LINK_IFELSE will succeed.
+  am_save_CPPFLAGS="$CPPFLAGS"
+  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
+
+  AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
+    am_cv_func_iconv="no, consider installing GNU libiconv"
+    am_cv_lib_iconv=no
+    AC_LINK_IFELSE(
+      [AC_LANG_PROGRAM(
+         [[
+#include <stdlib.h>
+#include <iconv.h>
+         ]],
+         [[iconv_t cd = iconv_open("","");
+           iconv(cd,NULL,NULL,NULL,NULL);
+           iconv_close(cd);]])],
+      [am_cv_func_iconv=yes])
+    if test "$am_cv_func_iconv" != yes; then
+      am_save_LIBS="$LIBS"
+      LIBS="$LIBS $LIBICONV"
+      AC_LINK_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[
+#include <stdlib.h>
+#include <iconv.h>
+           ]],
+           [[iconv_t cd = iconv_open("","");
+             iconv(cd,NULL,NULL,NULL,NULL);
+             iconv_close(cd);]])],
+        [am_cv_lib_iconv=yes]
+        [am_cv_func_iconv=yes])
+      LIBS="$am_save_LIBS"
+    fi
+  ])
+  if test "$am_cv_func_iconv" = yes; then
+    AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
+      dnl This tests against bugs in AIX 5.1, AIX 6.1..7.1, HP-UX 11.11,
+      dnl Solaris 10.
+      am_save_LIBS="$LIBS"
+      if test $am_cv_lib_iconv = yes; then
+        LIBS="$LIBS $LIBICONV"
+      fi
+      AC_RUN_IFELSE(
+        [AC_LANG_SOURCE([[
+#include <iconv.h>
+#include <string.h>
+int main ()
+{
+  int result = 0;
+  /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
+     returns.  */
+  {
+    iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
+    if (cd_utf8_to_88591 != (iconv_t)(-1))
+      {
+        static const char input[] = "\342\202\254"; /* EURO SIGN */
+        char buf[10];
+        const char *inptr = input;
+        size_t inbytesleft = strlen (input);
+        char *outptr = buf;
+        size_t outbytesleft = sizeof (buf);
+        size_t res = iconv (cd_utf8_to_88591,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if (res == 0)
+          result |= 1;
+        iconv_close (cd_utf8_to_88591);
+      }
+  }
+  /* Test against Solaris 10 bug: Failures are not distinguishable from
+     successful returns.  */
+  {
+    iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
+    if (cd_ascii_to_88591 != (iconv_t)(-1))
+      {
+        static const char input[] = "\263";
+        char buf[10];
+        const char *inptr = input;
+        size_t inbytesleft = strlen (input);
+        char *outptr = buf;
+        size_t outbytesleft = sizeof (buf);
+        size_t res = iconv (cd_ascii_to_88591,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if (res == 0)
+          result |= 2;
+        iconv_close (cd_ascii_to_88591);
+      }
+  }
+  /* Test against AIX 6.1..7.1 bug: Buffer overrun.  */
+  {
+    iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
+    if (cd_88591_to_utf8 != (iconv_t)(-1))
+      {
+        static const char input[] = "\304";
+        static char buf[2] = { (char)0xDE, (char)0xAD };
+        const char *inptr = input;
+        size_t inbytesleft = 1;
+        char *outptr = buf;
+        size_t outbytesleft = 1;
+        size_t res = iconv (cd_88591_to_utf8,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
+          result |= 4;
+        iconv_close (cd_88591_to_utf8);
+      }
+  }
+#if 0 /* This bug could be worked around by the caller.  */
+  /* Test against HP-UX 11.11 bug: Positive return value instead of 0.  */
+  {
+    iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
+    if (cd_88591_to_utf8 != (iconv_t)(-1))
+      {
+        static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+        char buf[50];
+        const char *inptr = input;
+        size_t inbytesleft = strlen (input);
+        char *outptr = buf;
+        size_t outbytesleft = sizeof (buf);
+        size_t res = iconv (cd_88591_to_utf8,
+                            (char **) &inptr, &inbytesleft,
+                            &outptr, &outbytesleft);
+        if ((int)res > 0)
+          result |= 8;
+        iconv_close (cd_88591_to_utf8);
+      }
+  }
+#endif
+  /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
+     provided.  */
+  if (/* Try standardized names.  */
+      iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
+      /* Try IRIX, OSF/1 names.  */
+      && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
+      /* Try AIX names.  */
+      && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
+      /* Try HP-UX names.  */
+      && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
+    result |= 16;
+  return result;
+}]])],
+        [am_cv_func_iconv_works=yes],
+        [am_cv_func_iconv_works=no],
+        [
+changequote(,)dnl
+         case "$host_os" in
+           aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+           *)            am_cv_func_iconv_works="guessing yes" ;;
+         esac
+changequote([,])dnl
+        ])
+      LIBS="$am_save_LIBS"
+    ])
+    case "$am_cv_func_iconv_works" in
+      *no) am_func_iconv=no am_cv_lib_iconv=no ;;
+      *)   am_func_iconv=yes ;;
+    esac
+  else
+    am_func_iconv=no am_cv_lib_iconv=no
+  fi
+  if test "$am_func_iconv" = yes; then
+    AC_DEFINE([HAVE_ICONV], [1],
+      [Define if you have the iconv() function and it works.])
+  fi
+  if test "$am_cv_lib_iconv" = yes; then
+    AC_MSG_CHECKING([how to link with libiconv])
+    AC_MSG_RESULT([$LIBICONV])
+  else
+    dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
+    dnl either.
+    CPPFLAGS="$am_save_CPPFLAGS"
+    LIBICONV=
+    LTLIBICONV=
+  fi
+  AC_SUBST([LIBICONV])
+  AC_SUBST([LTLIBICONV])
+])
+
+dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
+dnl avoid warnings like
+dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
+dnl This is tricky because of the way 'aclocal' is implemented:
+dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
+dnl   Otherwise aclocal's initial scan pass would miss the macro definition.
+dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
+dnl   Otherwise aclocal would emit many "Use of uninitialized value $1"
+dnl   warnings.
+m4_define([gl_iconv_AC_DEFUN],
+  m4_version_prereq([2.64],
+    [[AC_DEFUN_ONCE(
+        [$1], [$2])]],
+    [m4_ifdef([gl_00GNULIB],
+       [[AC_DEFUN_ONCE(
+           [$1], [$2])]],
+       [[AC_DEFUN(
+           [$1], [$2])]])]))
+gl_iconv_AC_DEFUN([AM_ICONV],
+[
+  AM_ICONV_LINK
+  if test "$am_cv_func_iconv" = yes; then
+    AC_MSG_CHECKING([for iconv declaration])
+    AC_CACHE_VAL([am_cv_proto_iconv], [
+      AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[
+#include <stdlib.h>
+#include <iconv.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus)
+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
+#else
+size_t iconv();
+#endif
+           ]],
+           [[]])],
+        [am_cv_proto_iconv_arg1=""],
+        [am_cv_proto_iconv_arg1="const"])
+      am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
+    am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
+    AC_MSG_RESULT([
+         $am_cv_proto_iconv])
+    AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
+      [Define as const if the declaration of iconv() needs const.])
+    dnl Also substitute ICONV_CONST in the gnulib generated <iconv.h>.
+    m4_ifdef([gl_ICONV_H_DEFAULTS],
+      [AC_REQUIRE([gl_ICONV_H_DEFAULTS])
+       if test -n "$am_cv_proto_iconv_arg1"; then
+         ICONV_CONST="const"
+       fi
+      ])
+  fi
+])
diff --git a/third_party/elfutils/m4/lcmessage.m4 b/third_party/elfutils/m4/lcmessage.m4
new file mode 100644
index 0000000..ffbf915
--- /dev/null
+++ b/third_party/elfutils/m4/lcmessage.m4
@@ -0,0 +1,32 @@
+# lcmessage.m4 serial 2 (gettext-0.10.40)
+dnl Copyright (C) 1995-2002 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License.  As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl   Ulrich Drepper <drepper@cygnus.com>, 1995.
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+
+AC_DEFUN([AM_LC_MESSAGES],
+  [if test $ac_cv_header_locale_h = yes; then
+    AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+      [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+       am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+    if test $am_cv_val_LC_MESSAGES = yes; then
+      AC_DEFINE(HAVE_LC_MESSAGES, 1,
+        [Define if your <locale.h> file defines LC_MESSAGES.])
+    fi
+  fi])
diff --git a/third_party/elfutils/m4/nls.m4 b/third_party/elfutils/m4/nls.m4
new file mode 100644
index 0000000..7967cc2
--- /dev/null
+++ b/third_party/elfutils/m4/nls.m4
@@ -0,0 +1,31 @@
+# nls.m4 serial 3 (gettext-0.15)
+dnl Copyright (C) 1995-2003, 2005-2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
+
+AC_PREREQ(2.50)
+
+AC_DEFUN([AM_NLS],
+[
+  AC_MSG_CHECKING([whether NLS is requested])
+  dnl Default is enabled NLS
+  AC_ARG_ENABLE(nls,
+    [  --disable-nls           do not use Native Language Support],
+    USE_NLS=$enableval, USE_NLS=yes)
+  AC_MSG_RESULT($USE_NLS)
+  AC_SUBST(USE_NLS)
+])
diff --git a/third_party/elfutils/m4/po.m4 b/third_party/elfutils/m4/po.m4
new file mode 100644
index 0000000..f395723
--- /dev/null
+++ b/third_party/elfutils/m4/po.m4
@@ -0,0 +1,452 @@
+# po.m4 serial 20 (gettext-0.18.2)
+dnl Copyright (C) 1995-2013 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl   Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
+dnl   Bruno Haible <haible@clisp.cons.org>, 2000-2003.
+
+AC_PREREQ([2.60])
+
+dnl Checks for all prerequisites of the po subdirectory.
+AC_DEFUN([AM_PO_SUBDIRS],
+[
+  AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+  AC_REQUIRE([AC_PROG_INSTALL])dnl
+  AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+  AC_REQUIRE([AM_NLS])dnl
+
+  dnl Release version of the gettext macros. This is used to ensure that
+  dnl the gettext macros and po/Makefile.in.in are in sync.
+  AC_SUBST([GETTEXT_MACRO_VERSION], [0.18])
+
+  dnl Perform the following tests also if --disable-nls has been given,
+  dnl because they are needed for "make dist" to work.
+
+  dnl Search for GNU msgfmt in the PATH.
+  dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
+  dnl The second test excludes FreeBSD msgfmt.
+  AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+    [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
+     (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+    :)
+  AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT])
+
+  dnl Test whether it is GNU msgfmt >= 0.15.
+changequote(,)dnl
+  case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
+    *) MSGFMT_015=$MSGFMT ;;
+  esac
+changequote([,])dnl
+  AC_SUBST([MSGFMT_015])
+changequote(,)dnl
+  case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
+    *) GMSGFMT_015=$GMSGFMT ;;
+  esac
+changequote([,])dnl
+  AC_SUBST([GMSGFMT_015])
+
+  dnl Search for GNU xgettext 0.12 or newer in the PATH.
+  dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
+  dnl The second test excludes FreeBSD xgettext.
+  AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+    [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
+     (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+    :)
+  dnl Remove leftover from FreeBSD xgettext call.
+  rm -f messages.po
+
+  dnl Test whether it is GNU xgettext >= 0.15.
+changequote(,)dnl
+  case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+    '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
+    *) XGETTEXT_015=$XGETTEXT ;;
+  esac
+changequote([,])dnl
+  AC_SUBST([XGETTEXT_015])
+
+  dnl Search for GNU msgmerge 0.11 or newer in the PATH.
+  AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
+    [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :)
+
+  dnl Installation directories.
+  dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
+  dnl have to define it here, so that it can be used in po/Makefile.
+  test -n "$localedir" || localedir='${datadir}/locale'
+  AC_SUBST([localedir])
+
+  dnl Support for AM_XGETTEXT_OPTION.
+  test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
+  AC_SUBST([XGETTEXT_EXTRA_OPTIONS])
+
+  AC_CONFIG_COMMANDS([po-directories], [[
+    for ac_file in $CONFIG_FILES; do
+      # Support "outfile[:infile[:infile...]]"
+      case "$ac_file" in
+        *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+      esac
+      # PO directories have a Makefile.in generated from Makefile.in.in.
+      case "$ac_file" in */Makefile.in)
+        # Adjust a relative srcdir.
+        ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+        ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'`
+        ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+        # In autoconf-2.13 it is called $ac_given_srcdir.
+        # In autoconf-2.50 it is called $srcdir.
+        test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+        case "$ac_given_srcdir" in
+          .)  top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+          /*) top_srcdir="$ac_given_srcdir" ;;
+          *)  top_srcdir="$ac_dots$ac_given_srcdir" ;;
+        esac
+        # Treat a directory as a PO directory if and only if it has a
+        # POTFILES.in file. This allows packages to have multiple PO
+        # directories under different names or in different locations.
+        if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
+          rm -f "$ac_dir/POTFILES"
+          test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
+          gt_tab=`printf '\t'`
+          cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*,     $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
+          POMAKEFILEDEPS="POTFILES.in"
+          # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
+          # on $ac_dir but don't depend on user-specified configuration
+          # parameters.
+          if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+            # The LINGUAS file contains the set of available languages.
+            if test -n "$OBSOLETE_ALL_LINGUAS"; then
+              test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+            fi
+            ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+            # Hide the ALL_LINGUAS assignment from automake < 1.5.
+            eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+            POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+          else
+            # The set of available languages was given in configure.in.
+            # Hide the ALL_LINGUAS assignment from automake < 1.5.
+            eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
+          fi
+          # Compute POFILES
+          # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+          # Compute UPDATEPOFILES
+          # as      $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+          # Compute DUMMYPOFILES
+          # as      $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+          # Compute GMOFILES
+          # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+          case "$ac_given_srcdir" in
+            .) srcdirpre= ;;
+            *) srcdirpre='$(srcdir)/' ;;
+          esac
+          POFILES=
+          UPDATEPOFILES=
+          DUMMYPOFILES=
+          GMOFILES=
+          for lang in $ALL_LINGUAS; do
+            POFILES="$POFILES $srcdirpre$lang.po"
+            UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+            DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+            GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+          done
+          # CATALOGS depends on both $ac_dir and the user's LINGUAS
+          # environment variable.
+          INST_LINGUAS=
+          if test -n "$ALL_LINGUAS"; then
+            for presentlang in $ALL_LINGUAS; do
+              useit=no
+              if test "%UNSET%" != "$LINGUAS"; then
+                desiredlanguages="$LINGUAS"
+              else
+                desiredlanguages="$ALL_LINGUAS"
+              fi
+              for desiredlang in $desiredlanguages; do
+                # Use the presentlang catalog if desiredlang is
+                #   a. equal to presentlang, or
+                #   b. a variant of presentlang (because in this case,
+                #      presentlang can be used as a fallback for messages
+                #      which are not translated in the desiredlang catalog).
+                case "$desiredlang" in
+                  "$presentlang"*) useit=yes;;
+                esac
+              done
+              if test $useit = yes; then
+                INST_LINGUAS="$INST_LINGUAS $presentlang"
+              fi
+            done
+          fi
+          CATALOGS=
+          if test -n "$INST_LINGUAS"; then
+            for lang in $INST_LINGUAS; do
+              CATALOGS="$CATALOGS $lang.gmo"
+            done
+          fi
+          test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
+          sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
+          for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
+            if test -f "$f"; then
+              case "$f" in
+                *.orig | *.bak | *~) ;;
+                *) cat "$f" >> "$ac_dir/Makefile" ;;
+              esac
+            fi
+          done
+        fi
+        ;;
+      esac
+    done]],
+   [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
+    # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
+    # from automake < 1.5.
+    eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
+    # Capture the value of LINGUAS because we need it to compute CATALOGS.
+    LINGUAS="${LINGUAS-%UNSET%}"
+   ])
+])
+
+dnl Postprocesses a Makefile in a directory containing PO files.
+AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
+[
+  # When this code is run, in config.status, two variables have already been
+  # set:
+  # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in,
+  # - LINGUAS is the value of the environment variable LINGUAS at configure
+  #   time.
+
+changequote(,)dnl
+  # Adjust a relative srcdir.
+  ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+  ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'`
+  ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+  # In autoconf-2.13 it is called $ac_given_srcdir.
+  # In autoconf-2.50 it is called $srcdir.
+  test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+  case "$ac_given_srcdir" in
+    .)  top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+    /*) top_srcdir="$ac_given_srcdir" ;;
+    *)  top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  # Find a way to echo strings without interpreting backslash.
+  if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then
+    gt_echo='echo'
+  else
+    if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then
+      gt_echo='printf %s\n'
+    else
+      echo_func () {
+        cat <<EOT
+$*
+EOT
+      }
+      gt_echo='echo_func'
+    fi
+  fi
+
+  # A sed script that extracts the value of VARIABLE from a Makefile.
+  tab=`printf '\t'`
+  sed_x_variable='
+# Test if the hold space is empty.
+x
+s/P/P/
+x
+ta
+# Yes it was empty. Look if we have the expected variable definition.
+/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=/{
+  # Seen the first line of the variable definition.
+  s/^['"${tab}"' ]*VARIABLE['"${tab}"' ]*=//
+  ba
+}
+bd
+:a
+# Here we are processing a line from the variable definition.
+# Remove comment, more precisely replace it with a space.
+s/#.*$/ /
+# See if the line ends in a backslash.
+tb
+:b
+s/\\$//
+# Print the line, without the trailing backslash.
+p
+tc
+# There was no trailing backslash. The end of the variable definition is
+# reached. Clear the hold space.
+s/^.*$//
+x
+bd
+:c
+# A trailing backslash means that the variable definition continues in the
+# next line. Put a nonempty string into the hold space to indicate this.
+s/^.*$/P/
+x
+:d
+'
+changequote([,])dnl
+
+  # Set POTFILES to the value of the Makefile variable POTFILES.
+  sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'`
+  POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"`
+  # Compute POTFILES_DEPS as
+  #   $(foreach file, $(POTFILES), $(top_srcdir)/$(file))
+  POTFILES_DEPS=
+  for file in $POTFILES; do
+    POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file"
+  done
+  POMAKEFILEDEPS=""
+
+  if test -n "$OBSOLETE_ALL_LINGUAS"; then
+    test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+  fi
+  if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+    # The LINGUAS file contains the set of available languages.
+    ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+    POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+  else
+    # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
+    sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'`
+    ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
+  fi
+  # Hide the ALL_LINGUAS assignment from automake < 1.5.
+  eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+  # Compute POFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+  # Compute UPDATEPOFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+  # Compute DUMMYPOFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+  # Compute GMOFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+  # Compute PROPERTIESFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
+  # Compute CLASSFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
+  # Compute QMFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
+  # Compute MSGFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg)
+  # Compute RESOURCESDLLFILES
+  # as      $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll)
+  case "$ac_given_srcdir" in
+    .) srcdirpre= ;;
+    *) srcdirpre='$(srcdir)/' ;;
+  esac
+  POFILES=
+  UPDATEPOFILES=
+  DUMMYPOFILES=
+  GMOFILES=
+  PROPERTIESFILES=
+  CLASSFILES=
+  QMFILES=
+  MSGFILES=
+  RESOURCESDLLFILES=
+  for lang in $ALL_LINGUAS; do
+    POFILES="$POFILES $srcdirpre$lang.po"
+    UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+    DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+    GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+    PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties"
+    CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
+    QMFILES="$QMFILES $srcdirpre$lang.qm"
+    frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+    MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
+    frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+    RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll"
+  done
+  # CATALOGS depends on both $ac_dir and the user's LINGUAS
+  # environment variable.
+  INST_LINGUAS=
+  if test -n "$ALL_LINGUAS"; then
+    for presentlang in $ALL_LINGUAS; do
+      useit=no
+      if test "%UNSET%" != "$LINGUAS"; then
+        desiredlanguages="$LINGUAS"
+      else
+        desiredlanguages="$ALL_LINGUAS"
+      fi
+      for desiredlang in $desiredlanguages; do
+        # Use the presentlang catalog if desiredlang is
+        #   a. equal to presentlang, or
+        #   b. a variant of presentlang (because in this case,
+        #      presentlang can be used as a fallback for messages
+        #      which are not translated in the desiredlang catalog).
+        case "$desiredlang" in
+          "$presentlang"*) useit=yes;;
+        esac
+      done
+      if test $useit = yes; then
+        INST_LINGUAS="$INST_LINGUAS $presentlang"
+      fi
+    done
+  fi
+  CATALOGS=
+  JAVACATALOGS=
+  QTCATALOGS=
+  TCLCATALOGS=
+  CSHARPCATALOGS=
+  if test -n "$INST_LINGUAS"; then
+    for lang in $INST_LINGUAS; do
+      CATALOGS="$CATALOGS $lang.gmo"
+      JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties"
+      QTCATALOGS="$QTCATALOGS $lang.qm"
+      frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+      TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg"
+      frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+      CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll"
+    done
+  fi
+
+  sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp"
+  tab=`printf '\t'`
+  if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
+    # Add dependencies that cannot be formulated as a simple suffix rule.
+    for lang in $ALL_LINGUAS; do
+      frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+      cat >> "$ac_file.tmp" <<EOF
+$frobbedlang.msg: $lang.po
+${tab}@echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
+${tab}\$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+    done
+  fi
+  if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then
+    # Add dependencies that cannot be formulated as a simple suffix rule.
+    for lang in $ALL_LINGUAS; do
+      frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+      cat >> "$ac_file.tmp" <<EOF
+$frobbedlang/\$(DOMAIN).resources.dll: $lang.po
+${tab}@echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
+${tab}\$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+    done
+  fi
+  if test -n "$POMAKEFILEDEPS"; then
+    cat >> "$ac_file.tmp" <<EOF
+Makefile: $POMAKEFILEDEPS
+EOF
+  fi
+  mv "$ac_file.tmp" "$ac_file"
+])
+
+dnl Initializes the accumulator used by AM_XGETTEXT_OPTION.
+AC_DEFUN([AM_XGETTEXT_OPTION_INIT],
+[
+  XGETTEXT_EXTRA_OPTIONS=
+])
+
+dnl Registers an option to be passed to xgettext in the po subdirectory.
+AC_DEFUN([AM_XGETTEXT_OPTION],
+[
+  AC_REQUIRE([AM_XGETTEXT_OPTION_INIT])
+  XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1"
+])
diff --git a/third_party/elfutils/m4/progtest.m4 b/third_party/elfutils/m4/progtest.m4
new file mode 100644
index 0000000..a56365c
--- /dev/null
+++ b/third_party/elfutils/m4/progtest.m4
@@ -0,0 +1,92 @@
+# progtest.m4 serial 4 (gettext-0.14.2)
+dnl Copyright (C) 1996-2003, 2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl   Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+AC_PREREQ(2.50)
+
+# Search path for a program which passes the given test.
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl   TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN([AM_PATH_PROG_WITH_TEST],
+[
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+  ac_executable_p="test -x"
+else
+  ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+  [[\\/]]* | ?:[[\\/]]*)
+    ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+    ;;
+  *)
+    ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in ifelse([$5], , $PATH, [$5]); do
+      IFS="$ac_save_IFS"
+      test -z "$ac_dir" && ac_dir=.
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+          echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
+          if [$3]; then
+            ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
+            break 2
+          fi
+        fi
+      done
+    done
+    IFS="$ac_save_IFS"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [  test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+    ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
+  AC_MSG_RESULT([$]$1)
+else
+  AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
diff --git a/third_party/elfutils/m4/zip.m4 b/third_party/elfutils/m4/zip.m4
new file mode 100644
index 0000000..ab6fd57
--- /dev/null
+++ b/third_party/elfutils/m4/zip.m4
@@ -0,0 +1,20 @@
+dnl -*- Autoconf -*- test for either zlib or bzlib.
+dnl Defines --with-$1 argument, $2 automake conditional,
+dnl and sets AC_DEFINE(USE_$2) and LIBS.
+
+AC_DEFUN([eu_ZIPLIB], [dnl
+AC_ARG_WITH([[$1]],
+AC_HELP_STRING([--with-[$1]], [support [$1] compression in libdwfl]),,
+	    [with_[$1]=default])
+if test $with_[$1] != no; then
+  AC_SEARCH_LIBS([$4], [$3], [with_[$1]=yes],
+  	         [test $with_[$1] = default ||
+		  AC_MSG_ERROR([missing -l[$3] for --with-[$1]])])
+fi
+AM_CONDITIONAL([$2], test $with_[$1] = yes)
+if test $with_[$1] = yes; then
+  AC_DEFINE(USE_[$2])
+else
+  with_[$1]=no
+fi
+AH_TEMPLATE(USE_[$2], [Support $5 decompression via -l$3.])])
diff --git a/third_party/elfutils/po/ChangeLog b/third_party/elfutils/po/ChangeLog
new file mode 100644
index 0000000..2c27e64
--- /dev/null
+++ b/third_party/elfutils/po/ChangeLog
@@ -0,0 +1,183 @@
+2017-09-01  Mark Wielaard  <mark@klomp.org>
+
+	* *.po: Regenerated. Replace \v with \n\n.
+
+2017-08-02  Mark Wielaard  <mark@klomp.org>
+
+	* *.po: Update for 0.170.
+
+2017-05-05  Mark Wielaard  <mark@klomp.org>
+
+	* *.po: Update for 0.169.
+
+2017-02-16  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* po/POTFILES.in: Removed lib/version.c, added lib/printversion.c.
+
+2016-12-27  Mark Wielaard  <mark@klomp.org>
+
+	* *.po: Update for 0.168.
+
+2016-12-24  Mark Wielaard  <mark@klomp.org>
+
+	* Makevars (COPYRIGHT_HOLDER): Set to the elfutils developers.
+	(MSGID_BUGS_ADDRESS): Set to http://sourceware.org/bugzilla/
+
+2016-08-24  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Regenerate.
+
+2016-08-04  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.167.
+
+2016-07-06  Mark Wielaard  <mjw@redhat.com>
+
+	* po/POTFILES.in: Removed libebl/eblobjecttypename.c,
+	src/i386_ld.c, src/ld.c, src/ldgeneric.c and src/ldscript.y.
+
+2016-03-31  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.166.
+
+2016-01-11  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Regenerate.
+
+2016-01-08  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.165.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Regenerate.
+
+2015-10-15  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.164.
+
+2015-06-19  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.163.
+
+2015-06-15  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Regenerate.
+
+2015-06-10  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.162.
+
+2014-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.161.
+
+2014-08-25  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.160.
+
+2014-05-20  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Regenerated.
+
+2014-05-17  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.159.
+
+2014-01-03  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.158.
+
+2013-07-30  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.157.
+
+2013-07-25  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* *.po: Update for 0.156.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.in.in: Upgrade to gettext-0.18.2.
+
+2012-08-27  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.155.
+
+2012-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.154.
+
+2012-02-23  Mark Wielaard  <mjw@redhat.com>
+
+	* *.po: Update for 0.153.
+
+2010-04-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* LINGUAS: Remove fr.po, it.po, nl.po, ru.po, zh_CN.  The files
+	contain no translations at all.
+
+2010-04-14  Roland McGrath  <roland@redhat.com>
+
+	* POTFILES.in: Add libdwfl/libdwflP.h.
+
+	* LINGUAS: New file.
+	* Makefile.in.in: Upgrade to gettext-0.17.
+
+2009-01-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makevars (XGETTEXT_OPTIONS): Add --flag option for argp_error.
+
+	* POTFILES.in: Add more files with translatable strings.
+
+2007-06-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.in.in: Update from gettext 0.16.1.
+	* Rules-quot: Likewise.
+	* Makevars: Add more XGGETEXT_OPTIONS.
+
+	* remove-potcdata.sin: New file.
+
+	* POTFILES.in: Also include messages from libelf.
+
+2007-04-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.in.in: Remove MKINSTALLDIRS.
+	Define mkinstalldirs to mkdir -p.
+
+2006-04-04  Roland McGrath  <roland@redhat.com>
+
+	* POTFILES.in: Comment out lib/xstrdup.c, not distributed any more.
+
+2005-08-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* POTFILES.in: Add src/strings.c.
+
+2005-08-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* POTFILES.in: Add src/ranlib.c.
+
+2005-08-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.in.in (XGETTEXT_OPTIONS): Move adding of --flag options
+	after magic Makevars line.  Also look for ERROR from elflint.
+
+2005-07-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.in.in: Add src/elfcmp.
+
+2005-05-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.in.in (XGETTEXT_OPTIONS): Define.
+
+2005-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* POTFILES.in: Remove unnecessary entries.
+
+2004-01-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* POTFILES.in: Add files from libdw, libebl, and libasm.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* Moved to CVS archive.
diff --git a/third_party/elfutils/po/LINGUAS b/third_party/elfutils/po/LINGUAS
new file mode 100644
index 0000000..4adcc52
--- /dev/null
+++ b/third_party/elfutils/po/LINGUAS
@@ -0,0 +1,5 @@
+# List of translations, i.e. .po files supplied by translators.
+de es ja pl uk
+
+# These are automagically created, not real translations.
+en@quot en@boldquot
diff --git a/third_party/elfutils/po/Makefile.in.in b/third_party/elfutils/po/Makefile.in.in
new file mode 100644
index 0000000..fce63a6
--- /dev/null
+++ b/third_party/elfutils/po/Makefile.in.in
@@ -0,0 +1,453 @@
+# Makefile for PO directory in any package using GNU gettext.
+# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+#
+# This file can be copied and used freely without restrictions.  It can
+# be used in projects which are not available under the GNU General Public
+# License but which still want to provide support for the GNU gettext
+# functionality.
+# Please note that the actual code of GNU gettext is covered by the GNU
+# General Public License and is *not* in the public domain.
+#
+# Origin: gettext-0.18.2
+GETTEXT_MACRO_VERSION = 0.18
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datarootdir = @datarootdir@
+datadir = @datadir@
+localedir = @localedir@
+gettextsrcdir = $(datadir)/gettext/po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+
+# We use $(mkdir_p).
+# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as
+# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions,
+# @install_sh@ does not start with $(SHELL), so we add it.
+# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined
+# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake
+# versions, $(mkinstalldirs) and $(install_sh) are unused.
+mkinstalldirs = $(SHELL) @install_sh@ -d
+install_sh = $(SHELL) @install_sh@
+MKDIR_P = @MKDIR_P@
+mkdir_p = @mkdir_p@
+
+GMSGFMT_ = @GMSGFMT@
+GMSGFMT_no = @GMSGFMT@
+GMSGFMT_yes = @GMSGFMT_015@
+GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
+MSGFMT_ = @MSGFMT@
+MSGFMT_no = @MSGFMT@
+MSGFMT_yes = @MSGFMT_015@
+MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
+XGETTEXT_ = @XGETTEXT@
+XGETTEXT_no = @XGETTEXT@
+XGETTEXT_yes = @XGETTEXT_015@
+XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
+MSGMERGE = msgmerge
+MSGMERGE_UPDATE = @MSGMERGE@ --update
+MSGINIT = msginit
+MSGCONV = msgconv
+MSGFILTER = msgfilter
+
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+UPDATEPOFILES = @UPDATEPOFILES@
+DUMMYPOFILES = @DUMMYPOFILES@
+DISTFILES.common = Makefile.in.in remove-potcdate.sin \
+$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
+DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \
+$(POFILES) $(GMOFILES) \
+$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+
+# Makevars gets inserted here. (Don't remove this line!)
+
+.SUFFIXES:
+.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
+
+.po.mo:
+	@echo "$(MSGFMT) -c -o $@ $<"; \
+	$(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
+
+.po.gmo:
+	@lang=`echo $* | sed -e 's,.*/,,'`; \
+	test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+	echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \
+	cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
+
+.sin.sed:
+	sed -e '/^#/d' $< > t-$@
+	mv t-$@ $@
+
+
+all: all-@USE_NLS@
+
+all-yes: stamp-po
+all-no:
+
+# Ensure that the gettext macros and this Makefile.in.in are in sync.
+CHECK_MACRO_VERSION = \
+	test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
+	  || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \
+	       exit 1; \
+	     }
+
+# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
+# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
+# we don't want to bother translators with empty POT files). We assume that
+# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
+# In this case, stamp-po is a nop (i.e. a phony target).
+
+# stamp-po is a timestamp denoting the last time at which the CATALOGS have
+# been loosely updated. Its purpose is that when a developer or translator
+# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
+# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
+# invocations of "make" will do nothing. This timestamp would not be necessary
+# if updating the $(CATALOGS) would always touch them; however, the rule for
+# $(POFILES) has been designed to not touch files that don't need to be
+# changed.
+stamp-po: $(srcdir)/$(DOMAIN).pot
+	@$(CHECK_MACRO_VERSION)
+	test ! -f $(srcdir)/$(DOMAIN).pot || \
+	  test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
+	@test ! -f $(srcdir)/$(DOMAIN).pot || { \
+	  echo "touch stamp-po" && \
+	  echo timestamp > stamp-poT && \
+	  mv stamp-poT stamp-po; \
+	}
+
+# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
+# otherwise packages like GCC can not be built if only parts of the source
+# have been downloaded.
+
+# This target rebuilds $(DOMAIN).pot; it is an expensive operation.
+# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed.
+# The determination of whether the package xyz is a GNU one is based on the
+# heuristic whether some file in the top level directory mentions "GNU xyz".
+# If GNU 'find' is available, we avoid grepping through monster files.
+$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed
+	if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \
+	       LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f -size -10000000c -exec grep 'GNU @PACKAGE@' /dev/null '{}' ';' 2>/dev/null; \
+	     else \
+	       LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null; \
+	     fi; \
+	   } | grep -v 'libtool:' >/dev/null; then \
+	  package_gnu='GNU '; \
+	else \
+	  package_gnu=''; \
+	fi; \
+	if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \
+	  msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \
+	else \
+	  msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \
+	fi; \
+	case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
+	  '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \
+	    $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
+	      --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
+	      --files-from=$(srcdir)/POTFILES.in \
+	      --copyright-holder='$(COPYRIGHT_HOLDER)' \
+	      --msgid-bugs-address="$$msgid_bugs_address" \
+	    ;; \
+	  *) \
+	    $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \
+	      --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \
+	      --files-from=$(srcdir)/POTFILES.in \
+	      --copyright-holder='$(COPYRIGHT_HOLDER)' \
+	      --package-name="$${package_gnu}@PACKAGE@" \
+	      --package-version='@VERSION@' \
+	      --msgid-bugs-address="$$msgid_bugs_address" \
+	    ;; \
+	esac
+	test ! -f $(DOMAIN).po || { \
+	  if test -f $(srcdir)/$(DOMAIN).pot; then \
+	    sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \
+	    sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \
+	    if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \
+	      rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \
+	    else \
+	      rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \
+	      mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
+	    fi; \
+	  else \
+	    mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \
+	  fi; \
+	}
+
+# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
+# every "make" invocation, only create it when it is missing.
+# Only "make $(DOMAIN).pot-update" or "make dist" will force an update.
+$(srcdir)/$(DOMAIN).pot:
+	$(MAKE) $(DOMAIN).pot-update
+
+# This target rebuilds a PO file if $(DOMAIN).pot has changed.
+# Note that a PO file is not touched if it doesn't need to be changed.
+$(POFILES): $(srcdir)/$(DOMAIN).pot
+	@lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
+	if test -f "$(srcdir)/$${lang}.po"; then \
+	  test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+	  echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \
+	  cd $(srcdir) \
+	    && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
+	           '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+	             $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
+	           *) \
+	             $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \
+	         esac; \
+	       }; \
+	else \
+	  $(MAKE) $${lang}.po-create; \
+	fi
+
+
+install: install-exec install-data
+install-exec:
+install-data: install-data-@USE_NLS@
+	if test "$(PACKAGE)" = "gettext-tools"; then \
+	  $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \
+	  for file in $(DISTFILES.common) Makevars.template; do \
+	    $(INSTALL_DATA) $(srcdir)/$$file \
+			    $(DESTDIR)$(gettextsrcdir)/$$file; \
+	  done; \
+	  for file in Makevars; do \
+	    rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+	  done; \
+	else \
+	  : ; \
+	fi
+install-data-no: all
+install-data-yes: all
+	@catalogs='$(CATALOGS)'; \
+	for cat in $$catalogs; do \
+	  cat=`basename $$cat`; \
+	  lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+	  dir=$(localedir)/$$lang/LC_MESSAGES; \
+	  $(mkdir_p) $(DESTDIR)$$dir; \
+	  if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
+	  $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
+	  echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
+	  for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+	    if test -n "$$lc"; then \
+	      if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
+	        link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
+	        mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+	        mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+	        (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+	         for file in *; do \
+	           if test -f $$file; then \
+	             ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+	           fi; \
+	         done); \
+	        rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+	      else \
+	        if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+	          :; \
+	        else \
+	          rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+	          mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+	        fi; \
+	      fi; \
+	      rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+	      ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
+	      ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
+	      cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+	      echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
+	    fi; \
+	  done; \
+	done
+
+install-strip: install
+
+installdirs: installdirs-exec installdirs-data
+installdirs-exec:
+installdirs-data: installdirs-data-@USE_NLS@
+	if test "$(PACKAGE)" = "gettext-tools"; then \
+	  $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \
+	else \
+	  : ; \
+	fi
+installdirs-data-no:
+installdirs-data-yes:
+	@catalogs='$(CATALOGS)'; \
+	for cat in $$catalogs; do \
+	  cat=`basename $$cat`; \
+	  lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+	  dir=$(localedir)/$$lang/LC_MESSAGES; \
+	  $(mkdir_p) $(DESTDIR)$$dir; \
+	  for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+	    if test -n "$$lc"; then \
+	      if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
+	        link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
+	        mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+	        mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+	        (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+	         for file in *; do \
+	           if test -f $$file; then \
+	             ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+	           fi; \
+	         done); \
+	        rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+	      else \
+	        if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+	          :; \
+	        else \
+	          rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+	          mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+	        fi; \
+	      fi; \
+	    fi; \
+	  done; \
+	done
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall: uninstall-exec uninstall-data
+uninstall-exec:
+uninstall-data: uninstall-data-@USE_NLS@
+	if test "$(PACKAGE)" = "gettext-tools"; then \
+	  for file in $(DISTFILES.common) Makevars.template; do \
+	    rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+	  done; \
+	else \
+	  : ; \
+	fi
+uninstall-data-no:
+uninstall-data-yes:
+	catalogs='$(CATALOGS)'; \
+	for cat in $$catalogs; do \
+	  cat=`basename $$cat`; \
+	  lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+	  for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
+	    rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+	  done; \
+	done
+
+check: all
+
+info dvi ps pdf html tags TAGS ctags CTAGS ID:
+
+mostlyclean:
+	rm -f remove-potcdate.sed
+	rm -f stamp-poT
+	rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
+	rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+	rm -f Makefile Makefile.in POTFILES *.mo
+
+maintainer-clean: distclean
+	@echo "This command is intended for maintainers to use;"
+	@echo "it deletes files that may require special tools to rebuild."
+	rm -f stamp-po $(GMOFILES)
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir:
+	$(MAKE) update-po
+	@$(MAKE) dist2
+# This is a separate target because 'update-po' must be executed before.
+dist2: stamp-po $(DISTFILES)
+	dists="$(DISTFILES)"; \
+	if test "$(PACKAGE)" = "gettext-tools"; then \
+	  dists="$$dists Makevars.template"; \
+	fi; \
+	if test -f $(srcdir)/$(DOMAIN).pot; then \
+	  dists="$$dists $(DOMAIN).pot stamp-po"; \
+	fi; \
+	if test -f $(srcdir)/ChangeLog; then \
+	  dists="$$dists ChangeLog"; \
+	fi; \
+	for i in 0 1 2 3 4 5 6 7 8 9; do \
+	  if test -f $(srcdir)/ChangeLog.$$i; then \
+	    dists="$$dists ChangeLog.$$i"; \
+	  fi; \
+	done; \
+	if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
+	for file in $$dists; do \
+	  if test -f $$file; then \
+	    cp -p $$file $(distdir) || exit 1; \
+	  else \
+	    cp -p $(srcdir)/$$file $(distdir) || exit 1; \
+	  fi; \
+	done
+
+update-po: Makefile
+	$(MAKE) $(DOMAIN).pot-update
+	test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
+	$(MAKE) update-gmo
+
+# General rule for creating PO files.
+
+.nop.po-create:
+	@lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
+	echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \
+	exit 1
+
+# General rule for updating PO files.
+
+.nop.po-update:
+	@lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
+	if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \
+	tmpdir=`pwd`; \
+	echo "$$lang:"; \
+	test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+	echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
+	cd $(srcdir); \
+	if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
+	       '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+	         $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
+	       *) \
+	         $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
+	     esac; \
+	   }; then \
+	  if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+	    rm -f $$tmpdir/$$lang.new.po; \
+	  else \
+	    if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+	      :; \
+	    else \
+	      echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
+	      exit 1; \
+	    fi; \
+	  fi; \
+	else \
+	  echo "msgmerge for $$lang.po failed!" 1>&2; \
+	  rm -f $$tmpdir/$$lang.new.po; \
+	fi
+
+$(DUMMYPOFILES):
+
+update-gmo: Makefile $(GMOFILES)
+	@:
+
+# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
+# because execution permission bits may not work on the current file system.
+# Use @SHELL@, which is the shell determined by autoconf for the use by its
+# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
+Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
+	cd $(top_builddir) \
+	  && @SHELL@ ./config.status $(subdir)/$@.in po-directories
+
+force:
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/third_party/elfutils/po/Makevars b/third_party/elfutils/po/Makevars
new file mode 100644
index 0000000..0afcf4e
--- /dev/null
+++ b/third_party/elfutils/po/Makevars
@@ -0,0 +1,43 @@
+# Makefile variables for PO directory in any package using GNU gettext.
+
+# Usually the message domain is the same as the package name.
+DOMAIN = $(PACKAGE)
+
+# These two variables depend on the location of this directory.
+subdir = po
+top_builddir = ..
+
+# These options get passed to xgettext.
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_  --flag=error:3:c-format \
+		   --flag=ERROR:1:c-format --flag=argp_error:2:c-format \
+		   --add-comments
+
+# This is the copyright holder that gets inserted into the header of the
+# $(DOMAIN).pot file.  Set this to the copyright holder of the surrounding
+# package.  (Note that the msgstr strings, extracted from the package's
+# sources, belong to the copyright holder of the package.)  Translators are
+# expected to transfer the copyright for their translations to this person
+# or entity, or to disclaim their copyright.  The empty string stands for
+# the public domain; in this case the translators are expected to disclaim
+# their copyright.
+COPYRIGHT_HOLDER = The elfutils developers
+
+# This is the email address or URL to which the translators shall report
+# bugs in the untranslated strings:
+# - Strings which are not entire sentences, see the maintainer guidelines
+#   in the GNU gettext documentation, section 'Preparing Strings'.
+# - Strings which use unclear terms or require additional context to be
+#   understood.
+# - Strings which make invalid assumptions about notation of date, time or
+#   money.
+# - Pluralisation problems.
+# - Incorrect English spelling.
+# - Incorrect formatting.
+# It can be your email address, or a mailing list address where translators
+# can write to without being subscribed, or the URL of a web page through
+# which the translators can contact you.
+MSGID_BUGS_ADDRESS = https://sourceware.org/bugzilla/
+
+# This is the list of locale categories, beyond LC_MESSAGES, for which the
+# message catalogs shall be used.  It is usually empty.
+EXTRA_LOCALE_CATEGORIES =
diff --git a/third_party/elfutils/po/POTFILES.in b/third_party/elfutils/po/POTFILES.in
new file mode 100644
index 0000000..4eac6d0
--- /dev/null
+++ b/third_party/elfutils/po/POTFILES.in
@@ -0,0 +1,48 @@
+# List of files which containing translatable strings.
+# Copyright (C) 2000-2010 Red Hat, Inc.
+
+# Files from the compatibility library
+lib/color.c
+lib/printversion.c
+lib/xmalloc.c
+
+# Library sources
+libasm/asm_error.c
+libdw/dwarf_error.c
+libdwfl/argp-std.c
+libdwfl/libdwflP.h
+libebl/eblbackendname.c
+libebl/eblcorenotetypename.c
+libebl/ebldynamictagname.c
+libebl/eblobjnote.c
+libebl/eblobjnotetypename.c
+libebl/eblosabiname.c
+libebl/eblsectionname.c
+libebl/eblsectiontypename.c
+libebl/eblsegmenttypename.c
+libebl/eblsymbolbindingname.c
+libebl/eblsymboltypename.c
+libelf/elf_error.c
+
+# Program sources
+src/addr2line.c
+src/ar.c
+src/arlib-argp.c
+src/arlib.c
+src/elfcmp.c
+src/elfcompress.c
+src/elflint.c
+src/findtextrel.c
+src/nm.c
+src/objdump.c
+src/ranlib.c
+src/readelf.c
+src/size.c
+src/stack.c
+src/strings.c
+src/strip.c
+src/unstrip.c
+
+# Tests
+tests/backtrace.c
+tests/dwflmodtest.c
diff --git a/third_party/elfutils/po/Rules-quot b/third_party/elfutils/po/Rules-quot
new file mode 100644
index 0000000..9c2a995
--- /dev/null
+++ b/third_party/elfutils/po/Rules-quot
@@ -0,0 +1,47 @@
+# Special Makefile rules for English message catalogs with quotation marks.
+
+DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot
+
+.SUFFIXES: .insert-header .po-update-en
+
+en@quot.po-create:
+	$(MAKE) en@quot.po-update
+en@boldquot.po-create:
+	$(MAKE) en@boldquot.po-update
+
+en@quot.po-update: en@quot.po-update-en
+en@boldquot.po-update: en@boldquot.po-update-en
+
+.insert-header.po-update-en:
+	@lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \
+	if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \
+	tmpdir=`pwd`; \
+	echo "$$lang:"; \
+	ll=`echo $$lang | sed -e 's/@.*//'`; \
+	LC_ALL=C; export LC_ALL; \
+	cd $(srcdir); \
+	if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$ll -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \
+	  if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+	    rm -f $$tmpdir/$$lang.new.po; \
+	  else \
+	    if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+	      :; \
+	    else \
+	      echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
+	      exit 1; \
+	    fi; \
+	  fi; \
+	else \
+	  echo "creation of $$lang.po failed!" 1>&2; \
+	  rm -f $$tmpdir/$$lang.new.po; \
+	fi
+
+en@quot.insert-header: insert-header.sin
+	sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header
+
+en@boldquot.insert-header: insert-header.sin
+	sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header
+
+mostlyclean: mostlyclean-quot
+mostlyclean-quot:
+	rm -f *.insert-header
diff --git a/third_party/elfutils/po/boldquot.sed b/third_party/elfutils/po/boldquot.sed
new file mode 100644
index 0000000..4b937aa
--- /dev/null
+++ b/third_party/elfutils/po/boldquot.sed
@@ -0,0 +1,10 @@
+s/"\([^"]*\)"/“\1”/g
+s/`\([^`']*\)'/‘\1’/g
+s/ '\([^`']*\)' / ‘\1’ /g
+s/ '\([^`']*\)'$/ ‘\1’/g
+s/^'\([^`']*\)' /‘\1’ /g
+s/“”/""/g
+s/“/“/g
+s/”/”/g
+s/‘/‘/g
+s/’/’/g
diff --git a/third_party/elfutils/po/de.po b/third_party/elfutils/po/de.po
new file mode 100644
index 0000000..fd01ff8
--- /dev/null
+++ b/third_party/elfutils/po/de.po
@@ -0,0 +1,6245 @@
+# German translation of elfutils.
+# Copyright (C) 2009 THE elfutils'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the elfutils package.
+# , fuzzy
+#
+#
+# Thomas Spura <tomspur@fedoraproject.org>, 2009.
+# Cornelius Neckenig <tbull@fedoraproject.org>, 2009.
+# Michael Münch <micm@fedoraproject.org>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: elfutils VERSION\n"
+"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n"
+"POT-Creation-Date: 2017-09-01 12:27+0200\n"
+"PO-Revision-Date: 2009-06-29 15:15+0200\n"
+"Last-Translator: Michael Münch <micm@fedoraproject.org>\n"
+"Language-Team: German\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Lokalize 0.3\n"
+
+#: lib/color.c:53
+msgid ""
+"colorize the output.  WHEN defaults to 'always' or can be 'auto' or 'never'"
+msgstr ""
+
+#: lib/color.c:127
+#, c-format
+msgid ""
+"%s: invalid argument '%s' for '--color'\n"
+"valid arguments are:\n"
+"  - 'always', 'yes', 'force'\n"
+"  - 'never', 'no', 'none'\n"
+"  - 'auto', 'tty', 'if-tty'\n"
+msgstr ""
+
+#: lib/color.c:190 src/objdump.c:727
+#, fuzzy, c-format
+msgid "cannot allocate memory"
+msgstr "konnte Verzeichnis nicht erstellen: %s"
+
+#: lib/printversion.c:40
+#, fuzzy, c-format
+msgid ""
+"Copyright (C) %s The elfutils developers <%s>.\n"
+"This is free software; see the source for copying conditions.  There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+"Copyright (C) %s Red Hat, Inc.\n"
+"Dies ist freie Software, siehe Quellcode für Kopierbedingungen. KEINE "
+"GARANTIE,\n"
+"auch nicht für Marktgängigkeit oder Eignung für einen Bestimmten Zweck.\n"
+
+#: lib/xmalloc.c:53 lib/xmalloc.c:66 lib/xmalloc.c:78 src/readelf.c:3310
+#: src/readelf.c:3701 src/readelf.c:8540 src/unstrip.c:2227 src/unstrip.c:2433
+#, c-format
+msgid "memory exhausted"
+msgstr "Kein Speicher mehr verfügbar"
+
+#: libasm/asm_error.c:65 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:50
+#: libelf/elf_error.c:60
+msgid "no error"
+msgstr "kein Fehler"
+
+#: libasm/asm_error.c:66 libdw/dwarf_error.c:68 libdwfl/libdwflP.h:52
+#: libelf/elf_error.c:91
+msgid "out of memory"
+msgstr "nicht genügend Speicher"
+
+#: libasm/asm_error.c:67
+msgid "cannot create output file"
+msgstr "Ausgangsdatei konnte nicht erstellt werden"
+
+#: libasm/asm_error.c:68
+msgid "invalid parameter"
+msgstr "ungültiger Parameter"
+
+#: libasm/asm_error.c:69
+msgid "cannot change mode of output file"
+msgstr "konnte Modus der Ausgabedatei nicht ändern"
+
+#: libasm/asm_error.c:70
+msgid "cannot rename output file"
+msgstr "Ausgangsdatei konnte nicht umbenannt werden"
+
+#: libasm/asm_error.c:71
+msgid "duplicate symbol"
+msgstr "Symbol doppelt vorhanden"
+
+#: libasm/asm_error.c:72
+msgid "invalid section type for operation"
+msgstr "ungültiger Abschnittstyp für Operation"
+
+#: libasm/asm_error.c:73
+msgid "error during output of data"
+msgstr "Fehler bei Datenausgabe"
+
+#: libasm/asm_error.c:74
+msgid "no backend support available"
+msgstr "keine Backend-Unterstützung verfügbar"
+
+#: libasm/asm_error.c:83 libdw/dwarf_error.c:59 libdwfl/libdwflP.h:51
+#: libelf/elf_error.c:63
+msgid "unknown error"
+msgstr "unbekannter Fehler"
+
+#: libdw/dwarf_error.c:60
+msgid "invalid access"
+msgstr "Ungültiger Zugriff"
+
+#: libdw/dwarf_error.c:61
+msgid "no regular file"
+msgstr "Keine reguläre Date"
+
+#: libdw/dwarf_error.c:62
+msgid "I/O error"
+msgstr "I/O Fehler"
+
+#: libdw/dwarf_error.c:63
+msgid "invalid ELF file"
+msgstr "Ungültige ELF Datei"
+
+#: libdw/dwarf_error.c:64
+msgid "no DWARF information"
+msgstr "keine DWARF Information"
+
+#: libdw/dwarf_error.c:65
+msgid "cannot decompress DWARF"
+msgstr ""
+
+#: libdw/dwarf_error.c:66
+msgid "no ELF file"
+msgstr "keine ELF Datei"
+
+#: libdw/dwarf_error.c:67
+msgid "cannot get ELF header"
+msgstr "ELF Kopf konnte nicht ausgelesen werden"
+
+#: libdw/dwarf_error.c:69
+msgid "not implemented"
+msgstr "Nicht implementiert"
+
+#: libdw/dwarf_error.c:70 libelf/elf_error.c:107 libelf/elf_error.c:155
+msgid "invalid command"
+msgstr "Ungültiger Befehl"
+
+#: libdw/dwarf_error.c:71
+msgid "invalid version"
+msgstr "Ungültige Version"
+
+#: libdw/dwarf_error.c:72
+msgid "invalid file"
+msgstr "Ungültige Datei"
+
+#: libdw/dwarf_error.c:73
+msgid "no entries found"
+msgstr "Keine Einträge gefunden"
+
+#: libdw/dwarf_error.c:74
+msgid "invalid DWARF"
+msgstr "DWARF ungültig"
+
+#: libdw/dwarf_error.c:75
+msgid "no string data"
+msgstr ""
+
+#: libdw/dwarf_error.c:76
+msgid "no address value"
+msgstr "Kein Adress-Wert"
+
+#: libdw/dwarf_error.c:77
+msgid "no constant value"
+msgstr "Kein Konstanten-Wert"
+
+#: libdw/dwarf_error.c:78
+msgid "no reference value"
+msgstr "Kein Referenz-Wert"
+
+#: libdw/dwarf_error.c:79
+msgid "invalid reference value"
+msgstr "Ungültiger Referenz-Wert"
+
+#: libdw/dwarf_error.c:80
+msgid ".debug_line section missing"
+msgstr ".debug_line Sektion fehlt"
+
+#: libdw/dwarf_error.c:81
+msgid "invalid .debug_line section"
+msgstr "ungültige .debug_line Sektion"
+
+#: libdw/dwarf_error.c:82
+msgid "debug information too big"
+msgstr "Debug Information zu groß"
+
+#: libdw/dwarf_error.c:83
+msgid "invalid DWARF version"
+msgstr "Ungültige DWARF Version"
+
+#: libdw/dwarf_error.c:84
+msgid "invalid directory index"
+msgstr "ungültiger Verzeichnisindex"
+
+#: libdw/dwarf_error.c:85 libdwfl/libdwflP.h:71
+msgid "address out of range"
+msgstr "Außerhalb des Adressbereiches"
+
+#: libdw/dwarf_error.c:86
+msgid "no location list value"
+msgstr ""
+
+#: libdw/dwarf_error.c:87
+msgid "no block data"
+msgstr ""
+
+#: libdw/dwarf_error.c:88
+msgid "invalid line index"
+msgstr "Ungültiger Zeilenindex"
+
+#: libdw/dwarf_error.c:89
+msgid "invalid address range index"
+msgstr "Ungültiger Adressbereichs Index"
+
+#: libdw/dwarf_error.c:90 libdwfl/libdwflP.h:72
+msgid "no matching address range"
+msgstr "Kein passender Adressbereich"
+
+#: libdw/dwarf_error.c:91
+msgid "no flag value"
+msgstr ""
+
+#: libdw/dwarf_error.c:92 libelf/elf_error.c:232
+msgid "invalid offset"
+msgstr "ungültiger Offset"
+
+#: libdw/dwarf_error.c:93
+msgid ".debug_ranges section missing"
+msgstr ""
+
+#: libdw/dwarf_error.c:94
+#, fuzzy
+msgid "invalid CFI section"
+msgstr "ungültiger Abschnitt"
+
+#: libdw/dwarf_error.c:95
+msgid "no alternative debug link found"
+msgstr ""
+
+#: libdw/dwarf_error.c:96
+#, fuzzy
+msgid "invalid opcode"
+msgstr "ungültiger Operand"
+
+#: libdw/dwarf_error.c:97
+msgid "not a CU (unit) DIE"
+msgstr ""
+
+#: libdw/dwarf_error.c:98
+#, fuzzy
+msgid "unknown language code"
+msgstr "unbekannter Typ"
+
+#: libdwfl/argp-std.c:50 src/stack.c:639 src/unstrip.c:2374
+msgid "Input selection options:"
+msgstr "Eingabeauswahloptionen:"
+
+#: libdwfl/argp-std.c:51
+msgid "Find addresses in FILE"
+msgstr "Finde Adressen in FILE"
+
+#: libdwfl/argp-std.c:53
+msgid "Find addresses from signatures found in COREFILE"
+msgstr "Finde Adressen von Signatur aus COREFILE"
+
+#: libdwfl/argp-std.c:55
+msgid "Find addresses in files mapped into process PID"
+msgstr ""
+
+#: libdwfl/argp-std.c:57
+msgid ""
+"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps "
+"format"
+msgstr ""
+
+#: libdwfl/argp-std.c:59
+msgid "Find addresses in the running kernel"
+msgstr "Finde Adressen im laufenden Kernel"
+
+#: libdwfl/argp-std.c:61
+msgid "Kernel with all modules"
+msgstr "Kernel mit allen Modulen"
+
+#: libdwfl/argp-std.c:63 src/stack.c:646
+msgid "Search path for separate debuginfo files"
+msgstr "Dateisuchpfad für separate Debug-Informationen"
+
+#: libdwfl/argp-std.c:164
+msgid "only one of -e, -p, -k, -K, or --core allowed"
+msgstr "Nur eine Option von -e, -p, -k, -K, oder --core erlaubt"
+
+#: libdwfl/argp-std.c:237
+msgid "cannot load kernel symbols"
+msgstr "Konnte Kernel Symbole nicht laden"
+
+#. Non-fatal to have no modules since we do have the kernel.
+#: libdwfl/argp-std.c:241
+msgid "cannot find kernel modules"
+msgstr "Konnte Kernel Module nicht finden"
+
+#: libdwfl/argp-std.c:258
+msgid "cannot find kernel or modules"
+msgstr "Konnte Kernel oder Module nicht finden"
+
+#: libdwfl/argp-std.c:297
+#, c-format
+msgid "cannot read ELF core file: %s"
+msgstr "Konnte ELF Kerndatei %s nicht lesen"
+
+#: libdwfl/argp-std.c:320
+#, fuzzy
+msgid "Not enough memory"
+msgstr "nicht genügend Speicher"
+
+#: libdwfl/argp-std.c:330
+msgid "No modules recognized in core file"
+msgstr "Keine Module in der Kerndatei gefunden"
+
+#: libdwfl/libdwflP.h:53
+msgid "See errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:54
+msgid "See elf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:55
+msgid "See dwarf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:56
+msgid "See ebl_errno (XXX missing)"
+msgstr ""
+
+#: libdwfl/libdwflP.h:57
+msgid "gzip decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:58
+msgid "bzip2 decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:59
+msgid "LZMA decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:60
+msgid "no support library found for machine"
+msgstr ""
+
+#: libdwfl/libdwflP.h:61
+msgid "Callbacks missing for ET_REL file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:62
+msgid "Unsupported relocation type"
+msgstr ""
+
+#: libdwfl/libdwflP.h:63
+msgid "r_offset is bogus"
+msgstr ""
+
+#: libdwfl/libdwflP.h:64 libelf/elf_error.c:111 libelf/elf_error.c:171
+msgid "offset out of range"
+msgstr "Offset ausserhalb des Bereichs"
+
+#: libdwfl/libdwflP.h:65
+#, fuzzy
+msgid "relocation refers to undefined symbol"
+msgstr "Zeige Grösse der definierten Symbole"
+
+#: libdwfl/libdwflP.h:66
+msgid "Callback returned failure"
+msgstr ""
+
+#: libdwfl/libdwflP.h:67
+#, fuzzy
+msgid "No DWARF information found"
+msgstr "keine DWARF Information"
+
+#: libdwfl/libdwflP.h:68
+msgid "No symbol table found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:69
+#, fuzzy
+msgid "No ELF program headers"
+msgstr "Programm-Köpfe anzeigen"
+
+#: libdwfl/libdwflP.h:70
+msgid "address range overlaps an existing module"
+msgstr ""
+
+#: libdwfl/libdwflP.h:73
+msgid "image truncated"
+msgstr ""
+
+#: libdwfl/libdwflP.h:74
+#, fuzzy
+msgid "ELF file opened"
+msgstr "keine ELF Datei"
+
+#: libdwfl/libdwflP.h:75
+#, fuzzy
+msgid "not a valid ELF file"
+msgstr "Ungültige ELF Datei"
+
+#: libdwfl/libdwflP.h:76
+#, fuzzy
+msgid "cannot handle DWARF type description"
+msgstr "konnte Elf-Deskriptor nicht erzeugen: %s"
+
+#: libdwfl/libdwflP.h:77
+msgid "ELF file does not match build ID"
+msgstr ""
+
+#: libdwfl/libdwflP.h:78
+#, fuzzy
+msgid "corrupt .gnu.prelink_undo section data"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: libdwfl/libdwflP.h:79
+msgid "Internal error due to ebl"
+msgstr ""
+
+#: libdwfl/libdwflP.h:80
+msgid "Missing data in core file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:81
+#, fuzzy
+msgid "Invalid register"
+msgstr "ungültiger Parameter"
+
+#: libdwfl/libdwflP.h:82
+msgid "Error reading process memory"
+msgstr ""
+
+#: libdwfl/libdwflP.h:83
+msgid "Couldn't find architecture of any ELF"
+msgstr ""
+
+#: libdwfl/libdwflP.h:84
+msgid "Error parsing /proc filesystem"
+msgstr ""
+
+#: libdwfl/libdwflP.h:85
+#, fuzzy
+msgid "Invalid DWARF"
+msgstr "DWARF ungültig"
+
+#: libdwfl/libdwflP.h:86
+msgid "Unsupported DWARF"
+msgstr ""
+
+#: libdwfl/libdwflP.h:87
+msgid "Unable to find more threads"
+msgstr ""
+
+#: libdwfl/libdwflP.h:88
+msgid "Dwfl already has attached state"
+msgstr ""
+
+#: libdwfl/libdwflP.h:89
+msgid "Dwfl has no attached state"
+msgstr ""
+
+#: libdwfl/libdwflP.h:90
+msgid "Unwinding not supported for this architecture"
+msgstr ""
+
+#: libdwfl/libdwflP.h:91
+#, fuzzy
+msgid "Invalid argument"
+msgstr "ungültiger Parameter"
+
+#: libdwfl/libdwflP.h:92
+#, fuzzy
+msgid "Not an ET_CORE ELF file"
+msgstr "Ungültige ELF Datei"
+
+#: libebl/eblbackendname.c:41
+msgid "No backend"
+msgstr "Kein Backend"
+
+#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:76
+#: libebl/eblobjnotetypename.c:83 libebl/eblobjnotetypename.c:102
+#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83
+#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:79
+msgid "<unknown>"
+msgstr "<Unbekannt>"
+
+#: libebl/ebldynamictagname.c:101
+#, c-format
+msgid "<unknown>: %#<PRIx64>"
+msgstr "<Unbekannt>: %#<PRIx64>"
+
+#: libebl/eblobjnote.c:53
+#, fuzzy, c-format
+msgid "unknown SDT version %u\n"
+msgstr "unbekannte Version"
+
+#: libebl/eblobjnote.c:71
+#, fuzzy, c-format
+msgid "invalid SDT probe descriptor\n"
+msgstr "ungültiger Datei-Deskriptor"
+
+#: libebl/eblobjnote.c:121
+#, c-format
+msgid "    PC: "
+msgstr ""
+
+#: libebl/eblobjnote.c:123
+#, c-format
+msgid " Base: "
+msgstr ""
+
+#: libebl/eblobjnote.c:125
+#, c-format
+msgid " Semaphore: "
+msgstr ""
+
+#: libebl/eblobjnote.c:127
+#, c-format
+msgid "    Provider: "
+msgstr ""
+
+#: libebl/eblobjnote.c:129
+#, c-format
+msgid " Name: "
+msgstr ""
+
+#: libebl/eblobjnote.c:131
+#, c-format
+msgid " Args: "
+msgstr ""
+
+#: libebl/eblobjnote.c:141
+#, c-format
+msgid "    Build ID: "
+msgstr "    Build ID: "
+
+#. A non-null terminated version string.
+#: libebl/eblobjnote.c:152
+#, c-format
+msgid "    Linker version: %.*s\n"
+msgstr ""
+
+#: libebl/eblobjnote.c:213
+#, c-format
+msgid "    OS: %s, ABI: "
+msgstr "    OS: %s, ABI: "
+
+#: libebl/eblosabiname.c:70
+msgid "Stand alone"
+msgstr ""
+
+#: libebl/eblsymbolbindingname.c:67 libebl/eblsymboltypename.c:73
+#, c-format
+msgid "<unknown>: %d"
+msgstr "<unbekannt>: %d"
+
+#: libelf/elf_error.c:67
+msgid "unknown version"
+msgstr "unbekannte Version"
+
+#: libelf/elf_error.c:71
+msgid "unknown type"
+msgstr "unbekannter Typ"
+
+#: libelf/elf_error.c:75
+msgid "invalid `Elf' handle"
+msgstr "ungültiges `Elf'-Handle"
+
+#: libelf/elf_error.c:79
+msgid "invalid size of source operand"
+msgstr "ungültige Grösse des Quell-Operanden"
+
+#: libelf/elf_error.c:83
+msgid "invalid size of destination operand"
+msgstr "ungültige Grösse des Ziel-Operanden"
+
+#: libelf/elf_error.c:87 src/readelf.c:5153
+#, c-format
+msgid "invalid encoding"
+msgstr "ungültige Kodierung"
+
+#: libelf/elf_error.c:95
+msgid "invalid file descriptor"
+msgstr "ungültiger Datei-Deskriptor"
+
+#: libelf/elf_error.c:99
+msgid "invalid operation"
+msgstr "ungültige Operation"
+
+#: libelf/elf_error.c:103
+msgid "ELF version not set"
+msgstr "ELF-Version nicht gesetzt"
+
+#: libelf/elf_error.c:115
+msgid "invalid fmag field in archive header"
+msgstr "ungültiges fmag-Feld im Archivheader"
+
+#: libelf/elf_error.c:119
+msgid "invalid archive file"
+msgstr "Ungültige Archiv-Datei"
+
+#: libelf/elf_error.c:123
+msgid "descriptor is not for an archive"
+msgstr ""
+
+#: libelf/elf_error.c:127
+msgid "no index available"
+msgstr "kein Index verfügbar"
+
+#: libelf/elf_error.c:131
+msgid "cannot read data from file"
+msgstr "Daten aus der Datei konnten nicht gelesen werden"
+
+#: libelf/elf_error.c:135
+msgid "cannot write data to file"
+msgstr "Daten konnten nicht in die Datei geschrieben werden"
+
+#: libelf/elf_error.c:139
+msgid "invalid binary class"
+msgstr "ungültige Binärklasse"
+
+#: libelf/elf_error.c:143
+msgid "invalid section index"
+msgstr "ungültiger Abschnittsindex"
+
+#: libelf/elf_error.c:147
+msgid "invalid operand"
+msgstr "ungültiger Operand"
+
+#: libelf/elf_error.c:151
+msgid "invalid section"
+msgstr "ungültiger Abschnitt"
+
+#: libelf/elf_error.c:159
+msgid "executable header not created first"
+msgstr "ausführbarer Header wurde nicht zuerst erstellt"
+
+#: libelf/elf_error.c:163
+msgid "file descriptor disabled"
+msgstr "Datei-Deskriptor deaktiviert"
+
+#: libelf/elf_error.c:167
+#, fuzzy
+msgid "archive/member file descriptor mismatch"
+msgstr "Datei-Deskriptor deaktiviert"
+
+#: libelf/elf_error.c:175
+msgid "cannot manipulate null section"
+msgstr ""
+
+#: libelf/elf_error.c:179
+#, fuzzy
+msgid "data/scn mismatch"
+msgstr "data/scn Unterschied"
+
+#: libelf/elf_error.c:183
+msgid "invalid section header"
+msgstr "ungültiger Abschnitts-Header"
+
+#: libelf/elf_error.c:187 src/readelf.c:7403 src/readelf.c:7914
+#: src/readelf.c:8015 src/readelf.c:8196
+#, c-format
+msgid "invalid data"
+msgstr "Ungültige Daten"
+
+#: libelf/elf_error.c:191
+msgid "unknown data encoding"
+msgstr "Unbekannte Datenkodierung"
+
+#: libelf/elf_error.c:195
+msgid "section `sh_size' too small for data"
+msgstr "Abschnitt `sh_size' zu klein für Daten"
+
+#: libelf/elf_error.c:199
+msgid "invalid section alignment"
+msgstr "ungültige Abschnittsausrichtung"
+
+#: libelf/elf_error.c:203
+msgid "invalid section entry size"
+msgstr ""
+
+#: libelf/elf_error.c:207
+msgid "update() for write on read-only file"
+msgstr ""
+
+#: libelf/elf_error.c:211
+msgid "no such file"
+msgstr "Datei nicht gefunden"
+
+#: libelf/elf_error.c:215
+msgid "only relocatable files can contain section groups"
+msgstr ""
+
+#: libelf/elf_error.c:220
+msgid ""
+"program header only allowed in executables, shared objects, and core files"
+msgstr ""
+
+#: libelf/elf_error.c:227
+msgid "file has no program header"
+msgstr "Datei hat keinen Programm-Kopf"
+
+#: libelf/elf_error.c:237
+#, fuzzy
+msgid "invalid section type"
+msgstr "ungültiger Abschnitt"
+
+#: libelf/elf_error.c:242
+#, fuzzy
+msgid "invalid section flags"
+msgstr "ungültiger Abschnitt"
+
+#: libelf/elf_error.c:247
+msgid "section does not contain compressed data"
+msgstr ""
+
+#: libelf/elf_error.c:252
+msgid "section contains compressed data"
+msgstr ""
+
+#: libelf/elf_error.c:257
+#, fuzzy
+msgid "unknown compression type"
+msgstr "unbekannter Typ"
+
+#: libelf/elf_error.c:262
+#, fuzzy
+msgid "cannot compress data"
+msgstr "konnte Abschnittsdaten nicht kopieren: %s"
+
+#: libelf/elf_error.c:267
+#, fuzzy
+msgid "cannot decompress data"
+msgstr "konnte Abschnittsdaten nicht kopieren: %s"
+
+#: src/addr2line.c:58
+#, fuzzy
+msgid "Input format options:"
+msgstr "Eingabeauswahloptionen:"
+
+#: src/addr2line.c:60
+msgid "Treat addresses as offsets relative to NAME section."
+msgstr ""
+
+#: src/addr2line.c:62
+#, fuzzy
+msgid "Output format options:"
+msgstr "Ausgabeformat:"
+
+#: src/addr2line.c:63
+msgid "Print address before each entry"
+msgstr ""
+
+#: src/addr2line.c:64
+msgid "Show only base names of source files"
+msgstr ""
+
+#: src/addr2line.c:66
+msgid "Show absolute file names using compilation directory"
+msgstr ""
+
+#: src/addr2line.c:67
+msgid "Also show function names"
+msgstr ""
+
+#: src/addr2line.c:68
+msgid "Also show symbol or section names"
+msgstr ""
+
+#: src/addr2line.c:69
+msgid "Also show symbol and the section names"
+msgstr ""
+
+#: src/addr2line.c:70
+msgid "Also show line table flags"
+msgstr ""
+
+#: src/addr2line.c:72
+msgid ""
+"Show all source locations that caused inline expansion of subroutines at the "
+"address."
+msgstr ""
+
+#: src/addr2line.c:75
+msgid "Show demangled symbols (ARG is always ignored)"
+msgstr ""
+
+#: src/addr2line.c:77
+msgid "Print all information on one line, and indent inlines"
+msgstr ""
+
+#: src/addr2line.c:79 src/elfcmp.c:71 src/findtextrel.c:66 src/nm.c:101
+#: src/strings.c:79
+msgid "Miscellaneous:"
+msgstr "Verschiedenes:"
+
+#. Short description of program.
+#: src/addr2line.c:87
+msgid ""
+"Locate source files and line information for ADDRs (in a.out by default)."
+msgstr ""
+
+#. Strings for arguments in help texts.
+#: src/addr2line.c:91
+msgid "[ADDR...]"
+msgstr ""
+
+#: src/addr2line.c:519
+#, fuzzy, c-format
+msgid "Section syntax requires exactly one module"
+msgstr "Abschnitt syntax benötigt genau ein Modul"
+
+#: src/addr2line.c:542
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside section '%s'"
+msgstr ""
+
+#: src/addr2line.c:632
+#, c-format
+msgid "cannot find symbol '%s'"
+msgstr "Konnte Symbol '%s' nicht finden"
+
+#: src/addr2line.c:637
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside contents of '%s'"
+msgstr ""
+
+#: src/ar.c:68
+msgid "Commands:"
+msgstr "Befehle:"
+
+#: src/ar.c:69
+msgid "Delete files from archive."
+msgstr "Dateien aus dem Archiv löschen."
+
+#: src/ar.c:70
+msgid "Move files in archive."
+msgstr "Dateien zum Archiv hinzufügen."
+
+#: src/ar.c:71
+msgid "Print files in archive."
+msgstr "Packe Dateien in Archiv"
+
+#: src/ar.c:72
+msgid "Quick append files to archive."
+msgstr "Hänge Dateien an ein Archiv"
+
+#: src/ar.c:74
+msgid "Replace existing or insert new file into archive."
+msgstr "Ersetze existierende oder füge neue Datei in das Archiv ein."
+
+#: src/ar.c:75
+msgid "Display content of archive."
+msgstr "Zeige Archivinhalt an."
+
+#: src/ar.c:76
+msgid "Extract files from archive."
+msgstr "Entpacke Dateien aus dem Archiv"
+
+#: src/ar.c:78
+msgid "Command Modifiers:"
+msgstr ""
+
+#: src/ar.c:79
+msgid "Preserve original dates."
+msgstr "Erhalte ursprüngliche Daten."
+
+#: src/ar.c:80
+msgid "Use instance [COUNT] of name."
+msgstr ""
+
+#: src/ar.c:82
+msgid "Do not replace existing files with extracted files."
+msgstr "Ersetze existierende Dateien nicht mit entpackten Dateien"
+
+#: src/ar.c:83
+msgid "Allow filename to be truncated if necessary."
+msgstr "Erlaube angehängte Dateinamen, wenn nötig"
+
+#: src/ar.c:85
+msgid "Provide verbose output."
+msgstr "Zeige detaillierte Ausgabe."
+
+#: src/ar.c:86
+msgid "Force regeneration of symbol table."
+msgstr "Erzwinge Regenerierung der Symboltabelle."
+
+#: src/ar.c:87
+msgid "Insert file after [MEMBER]."
+msgstr "Füge Datei nach [MEMBER] ein."
+
+#: src/ar.c:88
+msgid "Insert file before [MEMBER]."
+msgstr "Füge Datei vor [MEMBER] ein."
+
+#: src/ar.c:89
+msgid "Same as -b."
+msgstr "Genau wie -b."
+
+#: src/ar.c:90
+msgid "Suppress message when library has to be created."
+msgstr "Unterdrücke Nachricht wenn Bibliothek erstellt werden muss."
+
+#: src/ar.c:92
+#, fuzzy
+msgid "Use full path for file matching."
+msgstr "Vollständigen Pfad für Dateiabgleich verwenden."
+
+#: src/ar.c:93
+msgid "Update only older files in archive."
+msgstr "Nur ältere Datein im Archiv aktualisieren"
+
+#. Short description of program.
+#: src/ar.c:99
+msgid "Create, modify, and extract from archives."
+msgstr "Erstelle, ändere, extrahiere von Archiven"
+
+#. Strings for arguments in help texts.
+#: src/ar.c:102
+msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]"
+msgstr "[MEMBER] [COUNT] ARCHIVE [FILE...]"
+
+#: src/ar.c:181
+#, c-format
+msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options"
+msgstr "'a', 'b', und 'i' nur zusammen mit 'm' and 'r Optionen"
+
+#: src/ar.c:186
+#, c-format
+msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers"
+msgstr ""
+
+#: src/ar.c:202
+#, c-format
+msgid "'N' is only meaningful with the 'x' and 'd' options"
+msgstr "'N' ist nur mit den Optionen 'x' und 'd' von Bedeutung."
+
+#: src/ar.c:207
+#, c-format
+msgid "COUNT parameter required"
+msgstr "COUNT Parameter erforderlich"
+
+#: src/ar.c:219
+#, c-format
+msgid "invalid COUNT parameter %s"
+msgstr "Ungültiger COUNT Parameter %s"
+
+#: src/ar.c:226
+#, fuzzy, c-format
+msgid "'%c' is only meaningful with the 'x' option"
+msgstr "'%' ist nur mit der Option 'x' von Bedeutung"
+
+#: src/ar.c:232
+#, c-format
+msgid "archive name required"
+msgstr "Archivname erforderlich"
+
+#: src/ar.c:245
+#, c-format
+msgid "command option required"
+msgstr ""
+
+#: src/ar.c:296
+#, c-format
+msgid "More than one operation specified"
+msgstr "Mehr als eine Operation angegeben"
+
+#: src/ar.c:390
+#, c-format
+msgid "cannot open archive '%s'"
+msgstr "Konnte Archiv '%s' nicht öffnen"
+
+#: src/ar.c:400
+#, c-format
+msgid "cannot open archive '%s': %s"
+msgstr "Konnte Archiv '%s': %s nicht öffnen"
+
+#: src/ar.c:404
+#, c-format
+msgid "%s: not an archive file"
+msgstr "%s: Keine Archiv-Datei"
+
+#: src/ar.c:408
+#, c-format
+msgid "cannot stat archive '%s'"
+msgstr ""
+
+#: src/ar.c:420
+#, c-format
+msgid "no entry %s in archive\n"
+msgstr "Kein Eintrag %s in Archiv\n"
+
+#: src/ar.c:473 src/ar.c:918 src/ar.c:1118
+#, c-format
+msgid "cannot create hash table"
+msgstr "Konnte Hash-Tabelle nicht erstellen"
+
+#: src/ar.c:480 src/ar.c:925 src/ar.c:1127
+#, c-format
+msgid "cannot insert into hash table"
+msgstr "Konnte nicht in Hash-Tabelle einfügen"
+
+#: src/ar.c:488 src/ranlib.c:149
+#, c-format
+msgid "cannot stat '%s'"
+msgstr ""
+
+#: src/ar.c:584
+#, c-format
+msgid "cannot read content of %s: %s"
+msgstr "Konnte Inhalt von %s: %s nicht lesen"
+
+#: src/ar.c:627
+#, c-format
+msgid "cannot open %.*s"
+msgstr "Konnte %.*s nicht öffnen"
+
+#: src/ar.c:649
+#, c-format
+msgid "failed to write %s"
+msgstr "Konnte %s nicht schreiben"
+
+#: src/ar.c:661
+#, c-format
+msgid "cannot change mode of %s"
+msgstr ""
+
+#: src/ar.c:677
+#, c-format
+msgid "cannot change modification time of %s"
+msgstr "Konnte Bearbeitungszeit von %s nicht ändern"
+
+#: src/ar.c:723
+#, c-format
+msgid "cannot rename temporary file to %.*s"
+msgstr "Konnte temporäre Datei nicht in %.*s umbenennen"
+
+#: src/ar.c:759 src/ar.c:1010 src/ar.c:1409 src/ranlib.c:223
+#, c-format
+msgid "cannot create new file"
+msgstr "neue Datei konnte nicht angelegt werden"
+
+#: src/ar.c:1209
+#, c-format
+msgid "position member %s not found"
+msgstr ""
+
+#: src/ar.c:1219
+#, c-format
+msgid "%s: no entry %s in archive!\n"
+msgstr "%s: Kein Eintrag %s in dem Archiv!\n"
+
+#: src/ar.c:1248 src/objdump.c:242
+#, c-format
+msgid "cannot open %s"
+msgstr "Konnte %s nicht öffnen"
+
+#: src/ar.c:1253
+#, c-format
+msgid "cannot stat %s"
+msgstr ""
+
+#: src/ar.c:1259
+#, c-format
+msgid "%s is no regular file"
+msgstr "%s ist keine reguläre Datei"
+
+#: src/ar.c:1272
+#, c-format
+msgid "cannot get ELF descriptor for %s: %s\n"
+msgstr ""
+
+#: src/ar.c:1292
+#, c-format
+msgid "cannot read %s: %s"
+msgstr "Konnte %s: %s nicht lesen"
+
+#: src/arlib-argp.c:32
+msgid "Use zero for uid, gid, and date in archive members."
+msgstr ""
+
+#: src/arlib-argp.c:34
+msgid "Use actual uid, gid, and date in archive members."
+msgstr ""
+
+#: src/arlib-argp.c:65
+#, c-format
+msgid "%s (default)"
+msgstr ""
+
+#. The archive is too big.
+#: src/arlib.c:213
+#, c-format
+msgid "the archive '%s' is too large"
+msgstr "Das Archiv '%s' ist zu groß"
+
+#: src/arlib.c:226
+#, c-format
+msgid "cannot read ELF header of %s(%s): %s"
+msgstr "\"Konnte ELF-Kopf von %s(%s): %s nicht lesen"
+
+#: src/elfcmp.c:61
+msgid "Control options:"
+msgstr ""
+
+#: src/elfcmp.c:63
+msgid "Output all differences, not just the first"
+msgstr ""
+
+#: src/elfcmp.c:64
+msgid ""
+"Control treatment of gaps in loadable segments [ignore|match] (default: "
+"ignore)"
+msgstr ""
+
+#: src/elfcmp.c:66
+msgid "Ignore permutation of buckets in SHT_HASH section"
+msgstr ""
+
+#: src/elfcmp.c:68
+msgid "Ignore differences in build ID"
+msgstr ""
+
+#: src/elfcmp.c:69
+msgid "Output nothing; yield exit status only"
+msgstr ""
+
+#. Short description of program.
+#: src/elfcmp.c:76
+msgid "Compare relevant parts of two ELF files for equality."
+msgstr ""
+
+#. Strings for arguments in help texts.
+#: src/elfcmp.c:80
+#, fuzzy
+msgid "FILE1 FILE2"
+msgstr "DATEI1 DATEI2"
+
+#: src/elfcmp.c:142
+msgid "Invalid number of parameters.\n"
+msgstr "Ungültige Anzahl von Parametern.\n"
+
+#: src/elfcmp.c:173 src/elfcmp.c:178
+#, c-format
+msgid "cannot get ELF header of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:204
+#, c-format
+msgid "%s %s diff: ELF header"
+msgstr ""
+
+#: src/elfcmp.c:211 src/elfcmp.c:214
+#, fuzzy, c-format
+msgid "cannot get section count of '%s': %s"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/elfcmp.c:219
+#, c-format
+msgid "%s %s diff: section count"
+msgstr ""
+
+#: src/elfcmp.c:226 src/elfcmp.c:229
+#, fuzzy, c-format
+msgid "cannot get program header count of '%s': %s"
+msgstr "konnte Programm-Kopf nicht erstellen: %s"
+
+#: src/elfcmp.c:234
+#, fuzzy, c-format
+msgid "%s %s diff: program header count"
+msgstr "Datei hat keinen Programm-Kopf"
+
+#: src/elfcmp.c:292
+#, c-format
+msgid "%s %s differ: section [%zu], [%zu] name"
+msgstr ""
+
+#: src/elfcmp.c:315
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' header"
+msgstr ""
+
+#: src/elfcmp.c:323 src/elfcmp.c:329
+#, c-format
+msgid "cannot get content of section %zu in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:338
+#, c-format
+msgid "symbol table [%zu] in '%s' has zero sh_entsize"
+msgstr ""
+
+#: src/elfcmp.c:350 src/elfcmp.c:356
+#, c-format
+msgid "cannot get symbol in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:378
+#, c-format
+msgid "%s %s differ: symbol table [%zu]"
+msgstr ""
+
+#: src/elfcmp.c:381
+#, c-format
+msgid "%s %s differ: symbol table [%zu,%zu]"
+msgstr ""
+
+#: src/elfcmp.c:428 src/elfcmp.c:498
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' number of notes"
+msgstr ""
+
+#: src/elfcmp.c:436
+#, fuzzy, c-format
+msgid "cannot read note section [%zu] '%s' in '%s': %s"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/elfcmp.c:447
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note name"
+msgstr ""
+
+#: src/elfcmp.c:455
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note '%s' type"
+msgstr ""
+
+#: src/elfcmp.c:470
+#, c-format
+msgid "%s %s differ: build ID length"
+msgstr ""
+
+#: src/elfcmp.c:478
+#, c-format
+msgid "%s %s differ: build ID content"
+msgstr ""
+
+#: src/elfcmp.c:487
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:528
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:532
+#, c-format
+msgid "%s %s differ: section [%zu,%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:547
+#, c-format
+msgid "%s %s differ: unequal amount of important sections"
+msgstr ""
+
+#: src/elfcmp.c:580 src/elfcmp.c:585
+#, c-format
+msgid "cannot load data of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:604 src/elfcmp.c:610
+#, c-format
+msgid "cannot get program header entry %d of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:616
+#, c-format
+msgid "%s %s differ: program header %d"
+msgstr ""
+
+#: src/elfcmp.c:640
+#, c-format
+msgid "%s %s differ: gap"
+msgstr ""
+
+#: src/elfcmp.c:691
+#, c-format
+msgid "Invalid value '%s' for --gaps parameter."
+msgstr ""
+
+#: src/elfcmp.c:719 src/findtextrel.c:206 src/nm.c:365 src/ranlib.c:142
+#: src/size.c:273 src/strings.c:186 src/strip.c:518 src/strip.c:555
+#: src/unstrip.c:2023 src/unstrip.c:2052
+#, c-format
+msgid "cannot open '%s'"
+msgstr "'%s' kann nicht geöffnet werden"
+
+#: src/elfcmp.c:723 src/findtextrel.c:213 src/ranlib.c:159
+#, c-format
+msgid "cannot create ELF descriptor for '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:728
+#, c-format
+msgid "cannot create EBL descriptor for '%s'"
+msgstr ""
+
+#: src/elfcmp.c:746 src/findtextrel.c:394
+#, c-format
+msgid "cannot get section header of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:756
+#, c-format
+msgid "cannot get content of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:766 src/elfcmp.c:780
+#, c-format
+msgid "cannot get relocation: %s"
+msgstr ""
+
+#: src/elfcompress.c:115 src/strip.c:297 src/unstrip.c:121
+#, c-format
+msgid "-o option specified twice"
+msgstr ""
+
+#: src/elfcompress.c:122
+#, fuzzy, c-format
+msgid "-t option specified twice"
+msgstr "Option -d zweimal angegeben"
+
+#: src/elfcompress.c:131
+#, fuzzy, c-format
+msgid "unknown compression type '%s'"
+msgstr "unbekannter Typ"
+
+#. We need at least one input file.
+#: src/elfcompress.c:143 src/elfcompress.c:1305
+#, fuzzy, c-format
+msgid "No input file given"
+msgstr "Eingabedatei '%s' ignoriert"
+
+#: src/elfcompress.c:149 src/elfcompress.c:1310
+#, c-format
+msgid "Only one input file allowed together with '-o'"
+msgstr ""
+
+#: src/elfcompress.c:1267
+msgid "Place (de)compressed output into FILE"
+msgstr ""
+
+#: src/elfcompress.c:1270
+msgid ""
+"What type of compression to apply. TYPE can be 'none' (decompress), "
+"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-"
+"gnu' (.zdebug GNU style compression, 'gnu' is an alias)"
+msgstr ""
+
+#: src/elfcompress.c:1273
+msgid ""
+"SECTION name to (de)compress, SECTION is an extended wildcard pattern "
+"(defaults to '.?(z)debug*')"
+msgstr ""
+
+#: src/elfcompress.c:1276
+msgid "Print a message for each section being (de)compressed"
+msgstr ""
+
+#: src/elfcompress.c:1279
+msgid "Force compression of section even if it would become larger"
+msgstr ""
+
+#: src/elfcompress.c:1282 src/strip.c:91
+msgid "Relax a few rules to handle slightly broken ELF files"
+msgstr ""
+
+#: src/elfcompress.c:1285
+#, fuzzy
+msgid "Be silent when a section cannot be compressed"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#. Strings for arguments in help texts.
+#: src/elfcompress.c:1294 src/elflint.c:78 src/readelf.c:142
+msgid "FILE..."
+msgstr "DATEI..."
+
+#: src/elfcompress.c:1295
+msgid "Compress or decompress sections in an ELF file."
+msgstr ""
+
+#: src/elflint.c:64
+msgid "Be extremely strict, flag level 2 features."
+msgstr ""
+
+#: src/elflint.c:65
+msgid "Do not print anything if successful"
+msgstr "Gebe nichts aus, wenn erfolgreich"
+
+#: src/elflint.c:66
+msgid "Binary is a separate debuginfo file"
+msgstr ""
+
+#: src/elflint.c:68
+msgid ""
+"Binary has been created with GNU ld and is therefore known to be broken in "
+"certain ways"
+msgstr ""
+
+#. Short description of program.
+#: src/elflint.c:74
+msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
+msgstr ""
+
+#: src/elflint.c:155 src/readelf.c:317
+#, c-format
+msgid "cannot open input file"
+msgstr "Kann Eingabedatei nicht öffnen"
+
+#: src/elflint.c:162
+#, c-format
+msgid "cannot generate Elf descriptor: %s\n"
+msgstr "kann Elf-Deskriptor nicht erzeugen: %s\n"
+
+#: src/elflint.c:181
+#, c-format
+msgid "error while closing Elf descriptor: %s\n"
+msgstr "Fehler beim Schliessen des Elf-Desktriptor: %s\n"
+
+#: src/elflint.c:185
+msgid "No errors"
+msgstr "Keine Fehler"
+
+#: src/elflint.c:220 src/readelf.c:494
+msgid "Missing file name.\n"
+msgstr "Dateiname fehlt.\n"
+
+#: src/elflint.c:285
+#, c-format
+msgid " error while freeing sub-ELF descriptor: %s\n"
+msgstr ""
+
+#. We cannot do anything.
+#: src/elflint.c:293
+#, fuzzy, c-format
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr "Keine ELF-Datei - sie hat die falschen Magic Bytes am Anfang\n"
+
+#: src/elflint.c:358
+#, c-format
+msgid "e_ident[%d] == %d is no known class\n"
+msgstr ""
+
+#: src/elflint.c:363
+#, c-format
+msgid "e_ident[%d] == %d is no known data encoding\n"
+msgstr ""
+
+#: src/elflint.c:367
+#, c-format
+msgid "unknown ELF header version number e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:375
+#, c-format
+msgid "unsupported OS ABI e_ident[%d] == '%s'\n"
+msgstr ""
+
+#: src/elflint.c:381
+#, c-format
+msgid "unsupport ABI version e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:386
+#, c-format
+msgid "e_ident[%zu] is not zero\n"
+msgstr "e_ident[%zu] ist nicht null\n"
+
+#: src/elflint.c:391
+#, c-format
+msgid "unknown object file type %d\n"
+msgstr ""
+
+#: src/elflint.c:398
+#, c-format
+msgid "unknown machine type %d\n"
+msgstr ""
+
+#: src/elflint.c:402
+#, c-format
+msgid "unknown object file version\n"
+msgstr ""
+
+#: src/elflint.c:408
+#, c-format
+msgid "invalid program header offset\n"
+msgstr ""
+
+#: src/elflint.c:410
+#, c-format
+msgid "executables and DSOs cannot have zero program header offset\n"
+msgstr ""
+
+#: src/elflint.c:414
+#, c-format
+msgid "invalid number of program header entries\n"
+msgstr ""
+
+#: src/elflint.c:422
+#, c-format
+msgid "invalid section header table offset\n"
+msgstr ""
+
+#: src/elflint.c:425
+#, c-format
+msgid "section header table must be present\n"
+msgstr ""
+
+#: src/elflint.c:439
+#, c-format
+msgid "invalid number of section header table entries\n"
+msgstr ""
+
+#: src/elflint.c:456
+#, c-format
+msgid "invalid section header index\n"
+msgstr ""
+
+#: src/elflint.c:474
+#, c-format
+msgid "Can only check %u headers, shnum was %u\n"
+msgstr ""
+
+#: src/elflint.c:488
+#, fuzzy, c-format
+msgid "invalid number of program header table entries\n"
+msgstr "Ungültige Anzahl von Parametern.\n"
+
+#: src/elflint.c:505
+#, c-format
+msgid "Can only check %u headers, phnum was %u\n"
+msgstr ""
+
+#: src/elflint.c:510
+#, c-format
+msgid "invalid machine flags: %s\n"
+msgstr ""
+
+#: src/elflint.c:517 src/elflint.c:534
+#, c-format
+msgid "invalid ELF header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:520 src/elflint.c:537
+#, c-format
+msgid "invalid program header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:523 src/elflint.c:540
+#, c-format
+msgid "invalid program header position or size\n"
+msgstr ""
+
+#: src/elflint.c:526 src/elflint.c:543
+#, c-format
+msgid "invalid section header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:529 src/elflint.c:546
+#, c-format
+msgid "invalid section header position or size\n"
+msgstr ""
+
+#: src/elflint.c:591
+#, c-format
+msgid ""
+"section [%2d] '%s': section with SHF_GROUP flag set not part of a section "
+"group\n"
+msgstr ""
+
+#: src/elflint.c:595
+#, c-format
+msgid ""
+"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"
+msgstr ""
+
+#: src/elflint.c:611 src/elflint.c:1495 src/elflint.c:1546 src/elflint.c:1652
+#: src/elflint.c:1988 src/elflint.c:2311 src/elflint.c:2930 src/elflint.c:3093
+#: src/elflint.c:3241 src/elflint.c:3431 src/elflint.c:4399
+#, c-format
+msgid "section [%2d] '%s': cannot get section data\n"
+msgstr ""
+
+#: src/elflint.c:624 src/elflint.c:1659
+#, c-format
+msgid ""
+"section [%2d] '%s': referenced as string table for section [%2d] '%s' but "
+"type is not SHT_STRTAB\n"
+msgstr ""
+
+#: src/elflint.c:647
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol table cannot have more than one extended index "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:659
+#, c-format
+msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n"
+msgstr ""
+
+#: src/elflint.c:668
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:673 src/elflint.c:676 src/elflint.c:679 src/elflint.c:682
+#: src/elflint.c:685 src/elflint.c:688
+#, c-format
+msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:691
+#, c-format
+msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:701
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:710
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid name value\n"
+msgstr ""
+
+#: src/elflint.c:725
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: too large section index but no extended "
+"section index section\n"
+msgstr ""
+
+#: src/elflint.c:731
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in "
+"st_shndx (%<PRIu32>)\n"
+msgstr ""
+
+#. || sym->st_shndx > SHN_HIRESERVE  always false
+#: src/elflint.c:743
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid section index\n"
+msgstr ""
+
+#: src/elflint.c:751
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown type\n"
+msgstr ""
+
+#: src/elflint.c:757
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown symbol binding\n"
+msgstr ""
+
+#: src/elflint.c:762
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unique symbol not of object type\n"
+msgstr ""
+
+#: src/elflint.c:770
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"
+msgstr ""
+
+#: src/elflint.c:774
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"
+msgstr ""
+
+#: src/elflint.c:778
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"
+msgstr ""
+
+#: src/elflint.c:829
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: st_value out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:835 src/elflint.c:860 src/elflint.c:909
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu does not fit completely in referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:844
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have "
+"SHF_TLS flag set\n"
+msgstr ""
+
+#: src/elflint.c:854 src/elflint.c:902
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:881
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"
+msgstr ""
+
+#: src/elflint.c:887
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but couldn't get TLS program "
+"header entry\n"
+msgstr ""
+
+#: src/elflint.c:895
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] "
+"'%s'\n"
+msgstr ""
+
+#: src/elflint.c:922
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:929
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: non-local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:936
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: non-local section symbol\n"
+msgstr ""
+
+#: src/elflint.c:986
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section "
+"[%2d]\n"
+msgstr ""
+
+#: src/elflint.c:993
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] "
+"'%s'\n"
+msgstr ""
+
+#. This test is more strict than the psABIs which
+#. usually allow the symbol to be in the middle of
+#. the .got section, allowing negative offsets.
+#: src/elflint.c:1009
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#<PRIx64> does not "
+"match %s section address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:1016
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %<PRIu64> does not "
+"match %s section size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:1024
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:1040
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC_ symbol value %#<PRIx64> does not match dynamic "
+"segment address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:1047
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC symbol size %<PRIu64> does not match dynamic "
+"segment size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:1060
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-"
+"default visibility\n"
+msgstr ""
+
+#: src/elflint.c:1064
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"
+msgstr ""
+
+#: src/elflint.c:1102
+#, fuzzy, c-format
+msgid "section [%2d] '%s': cannot get section data.\n"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/elflint.c:1118
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"
+msgstr ""
+
+#: src/elflint.c:1129 src/elflint.c:1182
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"
+msgstr ""
+
+#: src/elflint.c:1154 src/elflint.c:1207
+#, c-format
+msgid ""
+"section [%2d] '%s': relative relocations after index %d as specified by "
+"DT_RELCOUNT\n"
+msgstr ""
+
+#: src/elflint.c:1160 src/elflint.c:1213
+#, c-format
+msgid ""
+"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT "
+"specified %d relative relocations\n"
+msgstr ""
+
+#: src/elflint.c:1172
+#, c-format
+msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n"
+msgstr ""
+
+#: src/elflint.c:1255
+#, c-format
+msgid "section [%2d] '%s': invalid destination section index\n"
+msgstr ""
+
+#: src/elflint.c:1267
+#, c-format
+msgid "section [%2d] '%s': invalid destination section type\n"
+msgstr ""
+
+#: src/elflint.c:1275
+#, c-format
+msgid "section [%2d] '%s': sh_info should be zero\n"
+msgstr ""
+
+#: src/elflint.c:1283
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': no relocations for merge-able string sections possible\n"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/elflint.c:1291
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n"
+msgstr ""
+
+#: src/elflint.c:1351
+#, c-format
+msgid "text relocation flag set but there is no read-only segment\n"
+msgstr ""
+
+#: src/elflint.c:1378
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid type\n"
+msgstr ""
+
+#: src/elflint.c:1386
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: relocation type invalid for the file "
+"type\n"
+msgstr ""
+
+#: src/elflint.c:1394
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n"
+msgstr ""
+
+#: src/elflint.c:1412
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can "
+"be used with %s\n"
+msgstr ""
+
+#: src/elflint.c:1429
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:1444
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: copy relocation against symbol of type "
+"%s\n"
+msgstr ""
+
+#: src/elflint.c:1465
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: read-only section modified but text "
+"relocation flag not set\n"
+msgstr ""
+
+#: src/elflint.c:1480
+#, c-format
+msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n"
+msgstr ""
+
+#: src/elflint.c:1520 src/elflint.c:1571
+#, c-format
+msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1647
+#, c-format
+msgid "more than one dynamic section present\n"
+msgstr ""
+
+#: src/elflint.c:1665
+#, c-format
+msgid ""
+"section [%2d]: referenced as string table for section [%2d] '%s' but section "
+"link value is invalid\n"
+msgstr ""
+
+#: src/elflint.c:1673
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"
+msgstr ""
+
+#: src/elflint.c:1678 src/elflint.c:1967
+#, c-format
+msgid "section [%2d] '%s': sh_info not zero\n"
+msgstr ""
+
+#: src/elflint.c:1688
+#, c-format
+msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1696
+#, c-format
+msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"
+msgstr ""
+
+#: src/elflint.c:1703
+#, c-format
+msgid "section [%2d] '%s': entry %zu: unknown tag\n"
+msgstr ""
+
+#: src/elflint.c:1714
+#, c-format
+msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n"
+msgstr ""
+
+#: src/elflint.c:1724
+#, c-format
+msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n"
+msgstr ""
+
+#: src/elflint.c:1742
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"
+msgstr ""
+
+#: src/elflint.c:1755
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: pointer does not match address of section "
+"[%2d] '%s' referenced by sh_link\n"
+msgstr ""
+
+#: src/elflint.c:1798
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:1813
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must be valid offset in section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:1833 src/elflint.c:1861
+#, c-format
+msgid "section [%2d] '%s': contains %s entry but not %s\n"
+msgstr ""
+
+#: src/elflint.c:1845
+#, c-format
+msgid "section [%2d] '%s': mandatory tag %s not present\n"
+msgstr ""
+
+#: src/elflint.c:1854
+#, c-format
+msgid "section [%2d] '%s': no hash section present\n"
+msgstr ""
+
+#: src/elflint.c:1869 src/elflint.c:1876
+#, c-format
+msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n"
+msgstr ""
+
+#: src/elflint.c:1886 src/elflint.c:1890
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"
+msgstr ""
+
+#: src/elflint.c:1896
+#, c-format
+msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n"
+msgstr ""
+
+#: src/elflint.c:1907 src/elflint.c:1911 src/elflint.c:1915 src/elflint.c:1919
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in prelinked executable\n"
+msgstr ""
+
+#: src/elflint.c:1931
+#, c-format
+msgid ""
+"section [%2d] '%s': only relocatable files can have extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1941
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index section not for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1945
+#, c-format
+msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n"
+msgstr ""
+
+#: src/elflint.c:1950
+#, c-format
+msgid "cannot get data for symbol section\n"
+msgstr ""
+
+#: src/elflint.c:1953
+#, c-format
+msgid "section [%2d] '%s': entry size does not match Elf32_Word\n"
+msgstr ""
+
+#: src/elflint.c:1962
+#, c-format
+msgid "section [%2d] '%s': extended index table too small for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1977
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to "
+"same symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1995
+#, c-format
+msgid "symbol 0 should have zero extended section index\n"
+msgstr ""
+
+#: src/elflint.c:2007
+#, c-format
+msgid "cannot get data for symbol %zu\n"
+msgstr ""
+
+#: src/elflint.c:2012
+#, c-format
+msgid "extended section index is %<PRIu32> but symbol index is not XINDEX\n"
+msgstr ""
+
+#: src/elflint.c:2029 src/elflint.c:2083
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"
+msgstr ""
+
+#: src/elflint.c:2043 src/elflint.c:2097
+#, c-format
+msgid "section [%2d] '%s': chain array too large\n"
+msgstr ""
+
+#: src/elflint.c:2057 src/elflint.c:2111
+#, c-format
+msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2067
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2121
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %<PRIu64> out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2134
+#, c-format
+msgid "section [%2d] '%s': not enough data\n"
+msgstr ""
+
+#: src/elflint.c:2146
+#, c-format
+msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n"
+msgstr ""
+
+#: src/elflint.c:2162
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected at "
+"least %ld)\n"
+msgstr ""
+
+#: src/elflint.c:2171
+#, c-format
+msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n"
+msgstr ""
+
+#: src/elflint.c:2205
+#, c-format
+msgid ""
+"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"
+msgstr ""
+
+#: src/elflint.c:2226
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is "
+"undefined\n"
+msgstr ""
+
+#: src/elflint.c:2239
+#, c-format
+msgid ""
+"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+
+#: src/elflint.c:2248
+#, c-format
+msgid ""
+"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+
+#: src/elflint.c:2278
+#, c-format
+msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2283
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2289
+#, c-format
+msgid "section [%2d] '%s': bitmask does not match names in the hash table\n"
+msgstr ""
+
+#: src/elflint.c:2302
+#, c-format
+msgid "section [%2d] '%s': relocatable files cannot have hash tables\n"
+msgstr ""
+
+#: src/elflint.c:2320
+#, c-format
+msgid "section [%2d] '%s': hash table not for dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2324
+#, c-format
+msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n"
+msgstr ""
+
+#: src/elflint.c:2334
+#, c-format
+msgid "section [%2d] '%s': hash table entry size incorrect\n"
+msgstr ""
+
+#: src/elflint.c:2339
+#, c-format
+msgid "section [%2d] '%s': not marked to be allocated\n"
+msgstr ""
+
+#: src/elflint.c:2344
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table has not even room for initial administrative "
+"entries\n"
+msgstr ""
+
+#: src/elflint.c:2393
+#, c-format
+msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"
+msgstr ""
+
+#: src/elflint.c:2417 src/elflint.c:2482 src/elflint.c:2517
+#, c-format
+msgid "hash section [%2zu] '%s' does not contain enough data\n"
+msgstr ""
+
+#: src/elflint.c:2438
+#, c-format
+msgid "hash section [%2zu] '%s' has zero bit mask words\n"
+msgstr ""
+
+#: src/elflint.c:2449 src/elflint.c:2493 src/elflint.c:2530
+#, c-format
+msgid "hash section [%2zu] '%s' uses too much data\n"
+msgstr ""
+
+#: src/elflint.c:2464
+#, c-format
+msgid ""
+"hash section [%2zu] '%s' invalid symbol index %<PRIu32> (max_nsyms: "
+"%<PRIu32>, nentries: %<PRIu32>\n"
+msgstr ""
+
+#: src/elflint.c:2551
+#, c-format
+msgid "hash section [%2zu] '%s' invalid sh_entsize\n"
+msgstr ""
+
+#: src/elflint.c:2561 src/elflint.c:2565
+#, c-format
+msgid "section [%2zu] '%s': reference to symbol index 0\n"
+msgstr ""
+
+#: src/elflint.c:2572
+#, c-format
+msgid ""
+"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2584
+#, c-format
+msgid ""
+"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2600
+#, c-format
+msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n"
+msgstr ""
+
+#: src/elflint.c:2620
+#, c-format
+msgid ""
+"section [%2d] '%s': section groups only allowed in relocatable object files\n"
+msgstr ""
+
+#: src/elflint.c:2631
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol table: %s\n"
+msgstr ""
+
+#: src/elflint.c:2636
+#, c-format
+msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2642
+#, c-format
+msgid "section [%2d] '%s': invalid symbol index in sh_info\n"
+msgstr ""
+
+#: src/elflint.c:2647
+#, c-format
+msgid "section [%2d] '%s': sh_flags not zero\n"
+msgstr ""
+
+#: src/elflint.c:2654
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol for signature\n"
+msgstr ""
+
+#: src/elflint.c:2658
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol name for signature\n"
+msgstr ""
+
+#: src/elflint.c:2663
+#, c-format
+msgid "section [%2d] '%s': signature symbol cannot be empty string\n"
+msgstr ""
+
+#: src/elflint.c:2669
+#, c-format
+msgid "section [%2d] '%s': sh_flags not set correctly\n"
+msgstr ""
+
+#: src/elflint.c:2675
+#, c-format
+msgid "section [%2d] '%s': cannot get data: %s\n"
+msgstr ""
+
+#: src/elflint.c:2684
+#, c-format
+msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"
+msgstr ""
+
+#: src/elflint.c:2690
+#, c-format
+msgid "section [%2d] '%s': section group without flags word\n"
+msgstr ""
+
+#: src/elflint.c:2698
+#, c-format
+msgid "section [%2d] '%s': section group without member\n"
+msgstr ""
+
+#: src/elflint.c:2702
+#, c-format
+msgid "section [%2d] '%s': section group with only one member\n"
+msgstr ""
+
+#: src/elflint.c:2713
+#, c-format
+msgid "section [%2d] '%s': unknown section group flags\n"
+msgstr ""
+
+#: src/elflint.c:2725
+#, fuzzy, c-format
+msgid "section [%2d] '%s': section index %zu out of range\n"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/elflint.c:2734
+#, c-format
+msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:2741
+#, c-format
+msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2747
+#, c-format
+msgid ""
+"section [%2d] '%s': element %zu references section [%2d] '%s' without "
+"SHF_GROUP flag set\n"
+msgstr ""
+
+#: src/elflint.c:2754
+#, c-format
+msgid "section [%2d] '%s' is contained in more than one section group\n"
+msgstr ""
+
+#: src/elflint.c:2944
+#, c-format
+msgid ""
+"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no "
+"dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2956
+#, c-format
+msgid ""
+"section [%2d] '%s' has different number of entries than symbol table [%2d] "
+"'%s'\n"
+msgstr ""
+
+#: src/elflint.c:2972
+#, c-format
+msgid "section [%2d] '%s': symbol %d: cannot read version data\n"
+msgstr ""
+
+#: src/elflint.c:2988
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n"
+msgstr ""
+
+#: src/elflint.c:2996
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with version\n"
+msgstr ""
+
+#: src/elflint.c:3010
+#, c-format
+msgid "section [%2d] '%s': symbol %d: invalid version index %d\n"
+msgstr ""
+
+#: src/elflint.c:3015
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for defined version\n"
+msgstr ""
+
+#: src/elflint.c:3025
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for requested version\n"
+msgstr ""
+
+#: src/elflint.c:3078
+#, c-format
+msgid "more than one version reference section present\n"
+msgstr ""
+
+#: src/elflint.c:3086 src/elflint.c:3233
+#, c-format
+msgid "section [%2d] '%s': sh_link does not link to string table\n"
+msgstr ""
+
+#: src/elflint.c:3111 src/elflint.c:3287
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong version %d\n"
+msgstr ""
+
+#: src/elflint.c:3118 src/elflint.c:3294
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3128
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid file reference\n"
+msgstr ""
+
+#: src/elflint.c:3136
+#, c-format
+msgid "section [%2d] '%s': entry %d references unknown dependency\n"
+msgstr ""
+
+#: src/elflint.c:3148
+#, c-format
+msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:3156
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name "
+"reference\n"
+msgstr ""
+
+#: src/elflint.c:3165
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: "
+"%#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:3174
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version "
+"name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3185
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"
+msgstr ""
+
+#: src/elflint.c:3202 src/elflint.c:3378
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n"
+msgstr ""
+
+#: src/elflint.c:3210 src/elflint.c:3386
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says "
+"there are more entries\n"
+msgstr ""
+
+#: src/elflint.c:3225
+#, c-format
+msgid "more than one version definition section present\n"
+msgstr ""
+
+#: src/elflint.c:3272
+#, c-format
+msgid "section [%2d] '%s': more than one BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3276
+#, c-format
+msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"
+msgstr ""
+
+#: src/elflint.c:3282
+#, c-format
+msgid "section [%2d] '%s': entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:3309
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid name reference\n"
+msgstr ""
+
+#: src/elflint.c:3316
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:3324
+#, c-format
+msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3344
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3361
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3394
+#, c-format
+msgid "section [%2d] '%s': no BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3410
+#, c-format
+msgid "section [%2d] '%s': unknown parent version '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3423
+#, c-format
+msgid "section [%2d] '%s': empty object attributes section\n"
+msgstr ""
+
+#: src/elflint.c:3444
+#, c-format
+msgid "section [%2d] '%s': unrecognized attribute format\n"
+msgstr ""
+
+#: src/elflint.c:3460
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3469
+#, c-format
+msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3481
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n"
+msgstr ""
+
+#: src/elflint.c:3498
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"
+msgstr ""
+
+#: src/elflint.c:3507
+#, c-format
+msgid "section [%2d] '%s': offset %zu: truncated attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3516
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3531
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"
+msgstr ""
+
+#. Tag_File
+#: src/elflint.c:3542
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3560
+#, c-format
+msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"
+msgstr ""
+
+#: src/elflint.c:3571
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n"
+msgstr ""
+
+#: src/elflint.c:3584
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3588
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: unrecognized %s attribute value %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3598
+#, c-format
+msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n"
+msgstr ""
+
+#: src/elflint.c:3604
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3693
+#, c-format
+msgid "cannot get section header of zeroth section\n"
+msgstr ""
+
+#: src/elflint.c:3697
+#, c-format
+msgid "zeroth section has nonzero name\n"
+msgstr ""
+
+#: src/elflint.c:3699
+#, c-format
+msgid "zeroth section has nonzero type\n"
+msgstr ""
+
+#: src/elflint.c:3701
+#, c-format
+msgid "zeroth section has nonzero flags\n"
+msgstr ""
+
+#: src/elflint.c:3703
+#, c-format
+msgid "zeroth section has nonzero address\n"
+msgstr ""
+
+#: src/elflint.c:3705
+#, c-format
+msgid "zeroth section has nonzero offset\n"
+msgstr ""
+
+#: src/elflint.c:3707
+#, c-format
+msgid "zeroth section has nonzero align value\n"
+msgstr ""
+
+#: src/elflint.c:3709
+#, c-format
+msgid "zeroth section has nonzero entry size value\n"
+msgstr ""
+
+#: src/elflint.c:3712
+#, c-format
+msgid ""
+"zeroth section has nonzero size value while ELF header has nonzero shnum "
+"value\n"
+msgstr ""
+
+#: src/elflint.c:3716
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in shstrndx\n"
+msgstr ""
+
+#: src/elflint.c:3720
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in phnum\n"
+msgstr ""
+
+#: src/elflint.c:3738
+#, c-format
+msgid "cannot get section header for section [%2zu] '%s': %s\n"
+msgstr ""
+
+#: src/elflint.c:3747
+#, c-format
+msgid "section [%2zu]: invalid name\n"
+msgstr ""
+
+#: src/elflint.c:3774
+#, c-format
+msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3792
+#, c-format
+msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3810
+#, c-format
+msgid ""
+"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3828
+#, c-format
+msgid "section [%2zu] '%s' present in object file\n"
+msgstr ""
+
+#: src/elflint.c:3834 src/elflint.c:3866
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"
+msgstr ""
+
+#: src/elflint.c:3839 src/elflint.c:3871
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable "
+"segments\n"
+msgstr ""
+
+#: src/elflint.c:3847
+#, c-format
+msgid ""
+"section [%2zu] '%s' is extension section index table in non-object file\n"
+msgstr ""
+
+#: src/elflint.c:3890
+#, c-format
+msgid "section [%2zu] '%s': size not multiple of entry size\n"
+msgstr ""
+
+#: src/elflint.c:3895
+#, c-format
+msgid "cannot get section header\n"
+msgstr ""
+
+#: src/elflint.c:3905
+#, c-format
+msgid "section [%2zu] '%s' has unsupported type %d\n"
+msgstr ""
+
+#: src/elflint.c:3920
+#, c-format
+msgid ""
+"section [%2zu] '%s' contains invalid processor-specific flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3927
+#, c-format
+msgid "section [%2zu] '%s' contains unknown flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3935
+#, c-format
+msgid "section [%2zu] '%s': thread-local data sections address not zero\n"
+msgstr ""
+
+#: src/elflint.c:3945
+#, fuzzy, c-format
+msgid "section [%2zu] '%s': allocated section cannot be compressed\n"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/elflint.c:3950
+#, fuzzy, c-format
+msgid "section [%2zu] '%s': nobits section cannot be compressed\n"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/elflint.c:3956
+#, c-format
+msgid ""
+"section [%2zu] '%s': compressed section with no compression header: %s\n"
+msgstr ""
+
+#: src/elflint.c:3962
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in link value\n"
+msgstr ""
+
+#: src/elflint.c:3967
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in info value\n"
+msgstr ""
+
+#: src/elflint.c:3974
+#, c-format
+msgid "section [%2zu] '%s': strings flag set without merge flag\n"
+msgstr ""
+
+#: src/elflint.c:3979
+#, c-format
+msgid "section [%2zu] '%s': merge flag set but entry size is zero\n"
+msgstr ""
+
+#: src/elflint.c:3998
+#, c-format
+msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n"
+msgstr ""
+
+#: src/elflint.c:4007
+#, c-format
+msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n"
+msgstr ""
+
+#: src/elflint.c:4014
+#, c-format
+msgid "section [%2zu] '%s' is both executable and writable\n"
+msgstr ""
+
+#: src/elflint.c:4045
+#, c-format
+msgid ""
+"section [%2zu] '%s' not fully contained in segment of program header entry "
+"%d\n"
+msgstr ""
+
+#: src/elflint.c:4055
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:4081
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d and file contents is non-zero\n"
+msgstr ""
+
+#: src/elflint.c:4092
+#, c-format
+msgid ""
+"section [%2zu] '%s' has not type NOBITS but is not read from the file in "
+"segment of program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:4103
+#, c-format
+msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:4113
+#, c-format
+msgid "section [%2zu] '%s' is writable in unwritable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:4123
+#, c-format
+msgid ""
+"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:4129
+#, c-format
+msgid ""
+"section [%2zu] '%s': ELF header says this is the section header string table "
+"but type is not SHT_TYPE\n"
+msgstr ""
+
+#: src/elflint.c:4137
+#, c-format
+msgid ""
+"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"
+msgstr ""
+
+#: src/elflint.c:4188
+#, c-format
+msgid "more than one version symbol table present\n"
+msgstr ""
+
+#: src/elflint.c:4211
+#, c-format
+msgid "INTERP program header entry but no .interp section\n"
+msgstr ""
+
+#: src/elflint.c:4222
+#, c-format
+msgid ""
+"loadable segment [%u] is executable but contains no executable sections\n"
+msgstr ""
+
+#: src/elflint.c:4228
+#, c-format
+msgid "loadable segment [%u] is writable but contains no writable sections\n"
+msgstr ""
+
+#: src/elflint.c:4239
+#, c-format
+msgid ""
+"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section "
+"exist\n"
+msgstr ""
+
+#: src/elflint.c:4252
+#, c-format
+msgid "duplicate version index %d\n"
+msgstr ""
+
+#: src/elflint.c:4266
+#, c-format
+msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"
+msgstr ""
+
+#: src/elflint.c:4315
+#, c-format
+msgid "phdr[%d]: unknown core file note type %<PRIu32> at offset %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:4319
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown core file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+
+#: src/elflint.c:4342
+#, c-format
+msgid "phdr[%d]: unknown object file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+
+#: src/elflint.c:4346
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown object file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+
+#: src/elflint.c:4363
+#, c-format
+msgid "phdr[%d]: no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4382
+#, c-format
+msgid "phdr[%d]: cannot get content of note section: %s\n"
+msgstr ""
+
+#: src/elflint.c:4385
+#, c-format
+msgid "phdr[%d]: extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4406
+#, c-format
+msgid "section [%2d] '%s': no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4413
+#, c-format
+msgid "section [%2d] '%s': cannot get content of note section\n"
+msgstr ""
+
+#: src/elflint.c:4416
+#, c-format
+msgid "section [%2d] '%s': extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4434
+#, c-format
+msgid ""
+"only executables, shared objects, and core files can have program headers\n"
+msgstr ""
+
+#: src/elflint.c:4449
+#, c-format
+msgid "cannot get program header entry %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:4458
+#, c-format
+msgid "program header entry %d: unknown program header entry type %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:4469
+#, c-format
+msgid "more than one INTERP entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4477
+#, c-format
+msgid "more than one TLS entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4484
+#, c-format
+msgid "static executable cannot have dynamic sections\n"
+msgstr ""
+
+#: src/elflint.c:4498
+#, c-format
+msgid "dynamic section reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4501
+#, c-format
+msgid "dynamic section size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4511
+#, c-format
+msgid "more than one GNU_RELRO entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4532
+#, c-format
+msgid "loadable segment GNU_RELRO applies to is not writable\n"
+msgstr ""
+
+#: src/elflint.c:4543
+#, c-format
+msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"
+msgstr ""
+
+#: src/elflint.c:4550
+#, c-format
+msgid ""
+"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n"
+msgstr ""
+
+#: src/elflint.c:4559 src/elflint.c:4582
+#, c-format
+msgid "%s segment not contained in a loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:4588
+#, c-format
+msgid "program header offset in ELF header and PHDR entry do not match"
+msgstr ""
+
+#: src/elflint.c:4613
+#, c-format
+msgid "call frame search table reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4616
+#, c-format
+msgid "call frame search table size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4629
+#, c-format
+msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"
+msgstr ""
+
+#: src/elflint.c:4637
+#, c-format
+msgid "call frame search table must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4640
+#, c-format
+msgid "section [%2zu] '%s' must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4644
+#, c-format
+msgid "call frame search table must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4647
+#, c-format
+msgid "section [%2zu] '%s' must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4652
+#, c-format
+msgid "call frame search table must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4655
+#, c-format
+msgid "section [%2zu] '%s' must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4666
+#, c-format
+msgid "program header entry %d: file size greater than memory size\n"
+msgstr ""
+
+#: src/elflint.c:4673
+#, c-format
+msgid "program header entry %d: alignment not a power of 2\n"
+msgstr ""
+
+#: src/elflint.c:4676
+#, c-format
+msgid ""
+"program header entry %d: file offset and virtual address not module of "
+"alignment\n"
+msgstr ""
+
+#: src/elflint.c:4689
+#, c-format
+msgid ""
+"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME "
+"program header entry"
+msgstr ""
+
+#: src/elflint.c:4723
+#, c-format
+msgid "cannot read ELF header: %s\n"
+msgstr ""
+
+#: src/elflint.c:4749
+#, c-format
+msgid "text relocation flag set but not needed\n"
+msgstr ""
+
+#: src/findtextrel.c:61
+msgid "Input Selection:"
+msgstr ""
+
+#: src/findtextrel.c:62
+msgid "Prepend PATH to all file names"
+msgstr ""
+
+#: src/findtextrel.c:64
+msgid "Use PATH as root of debuginfo hierarchy"
+msgstr ""
+
+#. Short description of program.
+#: src/findtextrel.c:71
+msgid "Locate source of text relocations in FILEs (a.out by default)."
+msgstr ""
+
+#. Strings for arguments in help texts.
+#: src/findtextrel.c:75 src/nm.c:109 src/objdump.c:72 src/size.c:81
+#: src/strings.c:88 src/strip.c:99
+msgid "[FILE...]"
+msgstr ""
+
+#: src/findtextrel.c:223
+#, c-format
+msgid "cannot get ELF header '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:234
+#, c-format
+msgid "'%s' is not a DSO or PIE"
+msgstr ""
+
+#: src/findtextrel.c:254
+#, c-format
+msgid "getting get section header of section %zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:277
+#, c-format
+msgid "cannot read dynamic section: %s"
+msgstr ""
+
+#: src/findtextrel.c:298
+#, c-format
+msgid "no text relocations reported in '%s'"
+msgstr ""
+
+#: src/findtextrel.c:310
+#, c-format
+msgid "while reading ELF file"
+msgstr ""
+
+#: src/findtextrel.c:314
+#, fuzzy, c-format
+msgid "cannot get program header count: %s"
+msgstr "konnte Programm-Kopf nicht erstellen: %s"
+
+#: src/findtextrel.c:325 src/findtextrel.c:342
+#, fuzzy, c-format
+msgid "cannot get program header index at offset %zd: %s"
+msgstr "konnte Programm-Kopf nicht erstellen: %s"
+
+#: src/findtextrel.c:406
+#, c-format
+msgid "cannot get symbol table section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:426 src/findtextrel.c:449
+#, c-format
+msgid "cannot get relocation at index %d in section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:515
+#, c-format
+msgid "%s not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:568
+#, c-format
+msgid ""
+"the file containing the function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:575 src/findtextrel.c:595
+#, c-format
+msgid ""
+"the file containing the function '%s' might not be compiled with -fpic/-"
+"fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:583
+#, c-format
+msgid ""
+"either the file containing the function '%s' or the file containing the "
+"function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:603
+#, c-format
+msgid ""
+"a relocation modifies memory at offset %llu in a write-protected segment\n"
+msgstr ""
+
+#: src/nm.c:67 src/strip.c:70
+msgid "Output selection:"
+msgstr ""
+
+#: src/nm.c:68
+msgid "Display debugger-only symbols"
+msgstr ""
+
+#: src/nm.c:69
+msgid "Display only defined symbols"
+msgstr "Zeige nur definierte Symbole"
+
+#: src/nm.c:72
+msgid "Display dynamic symbols instead of normal symbols"
+msgstr "Zeige dynamische Symbole anstelle normaler Symbole"
+
+#: src/nm.c:73
+msgid "Display only external symbols"
+msgstr "Zeige nur externe Symbole"
+
+#: src/nm.c:74
+msgid "Display only undefined symbols"
+msgstr "Zeige nur undefinierte Symbole"
+
+#: src/nm.c:76
+msgid "Include index for symbols from archive members"
+msgstr ""
+
+#: src/nm.c:78 src/size.c:55
+msgid "Output format:"
+msgstr "Ausgabeformat:"
+
+#: src/nm.c:80
+#, fuzzy
+msgid "Print name of the input file before every symbol"
+msgstr "Zeige Name der Eingabedatei vor jedem Symbol"
+
+#: src/nm.c:83
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd', `sysv' or `posix'.  The "
+"default is `sysv'"
+msgstr ""
+"Benutze das Ausgabeformat FORMAT. FORMAT kann `bsd', `sysv' or `posix' sein. "
+"Der Standard ist `sysv'"
+
+#: src/nm.c:85
+msgid "Same as --format=bsd"
+msgstr "Genau wie --format=bsd"
+
+#: src/nm.c:86
+msgid "Same as --format=posix"
+msgstr "Genau wie --format=posix"
+
+#: src/nm.c:87 src/size.c:61
+msgid "Use RADIX for printing symbol values"
+msgstr "Benutze RADIX zur Ausgabe von Symbolwerten"
+
+#: src/nm.c:88
+#, fuzzy
+msgid "Mark special symbols"
+msgstr "Kennzeichne schwache Symbole"
+
+#: src/nm.c:90
+#, fuzzy
+msgid "Print size of defined symbols"
+msgstr "Zeige Grösse der definierten Symbole"
+
+#: src/nm.c:92 src/size.c:69 src/strip.c:75 src/unstrip.c:73
+msgid "Output options:"
+msgstr "Ausgabeoptionen:"
+
+#: src/nm.c:93
+msgid "Sort symbols numerically by address"
+msgstr "Symbole anhand der Adresse numerisch sortieren"
+
+#: src/nm.c:95
+msgid "Do not sort the symbols"
+msgstr "Symbole nicht sortieren"
+
+#: src/nm.c:96
+msgid "Reverse the sense of the sort"
+msgstr "Sortierreihenfolge umkehren"
+
+#: src/nm.c:99
+msgid "Decode low-level symbol names into source code names"
+msgstr ""
+
+#. Short description of program.
+#: src/nm.c:106
+msgid "List symbols from FILEs (a.out by default)."
+msgstr ""
+
+#: src/nm.c:117 src/objdump.c:80
+#, fuzzy
+msgid "Output formatting"
+msgstr "Ausgabeformat:"
+
+#: src/nm.c:141 src/objdump.c:104 src/size.c:106 src/strip.c:131
+#, fuzzy, c-format
+msgid "%s: INTERNAL ERROR %d (%s): %s"
+msgstr "%s: INTERNER FEHLER %d (%s-%s): %s"
+
+#: src/nm.c:382 src/nm.c:394 src/size.c:289 src/size.c:298 src/size.c:309
+#: src/strip.c:2421
+#, c-format
+msgid "while closing '%s'"
+msgstr "beim Schliessen von '%s'"
+
+#: src/nm.c:404 src/objdump.c:281 src/strip.c:443
+#, c-format
+msgid "%s: File format not recognized"
+msgstr "%s: Dateiformat nicht erkannt"
+
+#. Note: 0 is no valid offset.
+#: src/nm.c:444
+#, fuzzy
+msgid ""
+"\n"
+"Archive index:\n"
+msgstr ""
+"\n"
+"Archiv-Index:"
+
+#: src/nm.c:453
+#, c-format
+msgid "invalid offset %zu for symbol %s"
+msgstr "ungültiger Offset %zu für Symbol %s"
+
+#: src/nm.c:458
+#, c-format
+msgid "%s in %s\n"
+msgstr ""
+
+#: src/nm.c:466
+#, c-format
+msgid "cannot reset archive offset to beginning"
+msgstr ""
+
+#: src/nm.c:491 src/objdump.c:329
+#, c-format
+msgid "%s%s%s: file format not recognized"
+msgstr "%s%s%s: Dateiformat nicht erkannt"
+
+#: src/nm.c:706
+#, c-format
+msgid "cannot create search tree"
+msgstr "Kann Suchbaum nicht erstellen"
+
+#: src/nm.c:747 src/nm.c:1208 src/objdump.c:778 src/readelf.c:551
+#: src/readelf.c:1129 src/readelf.c:1329 src/readelf.c:1477 src/readelf.c:1678
+#: src/readelf.c:1884 src/readelf.c:2074 src/readelf.c:2252 src/readelf.c:2328
+#: src/readelf.c:2586 src/readelf.c:2662 src/readelf.c:2749 src/readelf.c:3329
+#: src/readelf.c:3379 src/readelf.c:3442 src/readelf.c:8444 src/readelf.c:9544
+#: src/readelf.c:9747 src/readelf.c:9815 src/size.c:397 src/size.c:466
+#: src/strip.c:572
+#, c-format
+msgid "cannot get section header string table index"
+msgstr ""
+
+#. We always print this prolog.
+#: src/nm.c:774
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s:\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Symbole aus %s:\n"
+"\n"
+
+#. The header line.
+#: src/nm.c:777
+#, c-format
+msgid ""
+"%*s%-*s %-*s Class  Type     %-*s %*s Section\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:1219
+#, fuzzy, c-format
+msgid "%s: entry size in section %zd `%s' is not what we expect"
+msgstr "%s: entry size in section `%s' is not what we expect"
+
+#: src/nm.c:1224
+#, fuzzy, c-format
+msgid "%s: size of section %zd `%s' is not multiple of entry size"
+msgstr "%s: entry size in section `%s' is not what we expect"
+
+#: src/nm.c:1303
+#, fuzzy, c-format
+msgid "%s: entries (%zd) in section %zd `%s' is too large"
+msgstr "%s: entry size in section `%s' is not what we expect"
+
+#. XXX Add machine specific object file types.
+#: src/nm.c:1529
+#, c-format
+msgid "%s%s%s%s: Invalid operation"
+msgstr "%s%s%s%s: Ungültige Operation"
+
+#: src/nm.c:1586
+#, c-format
+msgid "%s%s%s: no symbols"
+msgstr "%s%s%s: keine Symbole"
+
+#: src/objdump.c:53
+msgid "Mode selection:"
+msgstr ""
+
+#: src/objdump.c:54
+msgid "Display relocation information."
+msgstr ""
+
+#: src/objdump.c:56
+msgid "Display the full contents of all sections requested"
+msgstr ""
+
+#: src/objdump.c:58
+msgid "Display assembler code of executable sections"
+msgstr ""
+
+#: src/objdump.c:60
+#, fuzzy
+msgid "Output content selection:"
+msgstr "Eingabeauswahloptionen:"
+
+#: src/objdump.c:62
+msgid "Only display information for section NAME."
+msgstr ""
+
+#. Short description of program.
+#: src/objdump.c:68
+msgid "Show information from FILEs (a.out by default)."
+msgstr ""
+
+#: src/objdump.c:219 src/readelf.c:499
+msgid "No operation specified.\n"
+msgstr "Keine Operation angegeben.\n"
+
+#: src/objdump.c:259 src/objdump.c:271
+#, c-format
+msgid "while close `%s'"
+msgstr ""
+
+#: src/objdump.c:364 src/readelf.c:1979 src/readelf.c:2171
+msgid "INVALID SYMBOL"
+msgstr ""
+
+#: src/objdump.c:379 src/readelf.c:2013 src/readelf.c:2207
+msgid "INVALID SECTION"
+msgstr ""
+
+#: src/objdump.c:499
+#, c-format
+msgid ""
+"\n"
+"RELOCATION RECORDS FOR [%s]:\n"
+"%-*s TYPE                 VALUE\n"
+msgstr ""
+
+#: src/objdump.c:502
+msgid "OFFSET"
+msgstr "OFFSET"
+
+#: src/objdump.c:567
+#, c-format
+msgid "Contents of section %s:\n"
+msgstr "Inhalt des Abschnitts %s:\n"
+
+#: src/objdump.c:688
+#, c-format
+msgid "cannot disassemble"
+msgstr "Disassemblieren nicht möglich"
+
+#. Short description of program.
+#: src/ranlib.c:64
+msgid "Generate an index to speed access to archives."
+msgstr "Erstelle einen Index zur Beschleunigung des Zugriffs auf Archive."
+
+#. Strings for arguments in help texts.
+#: src/ranlib.c:67
+msgid "ARCHIVE"
+msgstr "ARCHIV"
+
+#: src/ranlib.c:103
+#, c-format
+msgid "Archive name required"
+msgstr "Archivname benötigt"
+
+#: src/ranlib.c:167
+#, c-format
+msgid "'%s' is no archive"
+msgstr "'%s' ist kein Archiv"
+
+#: src/ranlib.c:202
+#, c-format
+msgid "error while freeing sub-ELF descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:87
+#, fuzzy
+msgid "ELF input selection:"
+msgstr "Eingabeauswahloptionen:"
+
+#: src/readelf.c:89
+msgid ""
+"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data"
+msgstr ""
+
+#: src/readelf.c:91
+#, fuzzy
+msgid "ELF output selection:"
+msgstr "Eingabeauswahloptionen:"
+
+#: src/readelf.c:93
+msgid "All these plus -p .strtab -p .dynstr -p .comment"
+msgstr ""
+
+#: src/readelf.c:94
+msgid "Display the dynamic segment"
+msgstr ""
+
+#: src/readelf.c:95
+msgid "Display the ELF file header"
+msgstr ""
+
+#: src/readelf.c:97
+msgid "Display histogram of bucket list lengths"
+msgstr ""
+
+#: src/readelf.c:98
+msgid "Display the program headers"
+msgstr "Programm-Köpfe anzeigen"
+
+#: src/readelf.c:100
+msgid "Display relocations"
+msgstr "Relocations anzeigen"
+
+#: src/readelf.c:101
+#, fuzzy
+msgid "Display the sections' headers"
+msgstr "Programm-Köpfe anzeigen"
+
+#: src/readelf.c:104
+#, fuzzy
+msgid "Display the symbol table sections"
+msgstr "Symboltabelle anzeigen"
+
+#: src/readelf.c:105
+msgid "Display versioning information"
+msgstr "Versionierungsinformationen anzeigen"
+
+#: src/readelf.c:106
+#, fuzzy
+msgid "Display the ELF notes"
+msgstr "Kernnotizen anzeigen"
+
+#: src/readelf.c:108
+#, fuzzy
+msgid "Display architecture specific information, if any"
+msgstr "Architekturspezifische Informationen anzeigen (falls vorhanden)"
+
+#: src/readelf.c:110
+msgid "Display sections for exception handling"
+msgstr "Abschnitte für Ausnahmebehandlung anzeigen"
+
+#: src/readelf.c:112
+msgid "Additional output selection:"
+msgstr ""
+
+#: src/readelf.c:114
+msgid ""
+"Display DWARF section content.  SECTION can be one of abbrev, aranges, "
+"decodedaranges, frame, gdb_index, info, loc, line, decodedline, ranges, "
+"pubnames, str, macinfo, macro or exception"
+msgstr ""
+
+#: src/readelf.c:118
+msgid "Dump the uninterpreted contents of SECTION, by number or name"
+msgstr ""
+
+#: src/readelf.c:120
+msgid "Print string contents of sections"
+msgstr ""
+
+#: src/readelf.c:123
+msgid "Display the symbol index of an archive"
+msgstr "Symbolindex des Archivs anzeigen"
+
+#: src/readelf.c:125
+msgid "Output control:"
+msgstr "Ausgabekontrolle:"
+
+#: src/readelf.c:127
+msgid "Do not find symbol names for addresses in DWARF data"
+msgstr "Keine symbolischen Namen für Adressen in DWARF-Daten suchen"
+
+#: src/readelf.c:129
+#, fuzzy
+msgid ""
+"Display just offsets instead of resolving values to addresses in DWARF data"
+msgstr "Keine symbolischen Namen für Adressen in DWARF-Daten suchen"
+
+#: src/readelf.c:131
+msgid "Ignored for compatibility (lines always wide)"
+msgstr ""
+
+#: src/readelf.c:133
+msgid ""
+"Show compression information for compressed sections (when used with -S); "
+"decompress section before dumping data (when used with -p or -x)"
+msgstr ""
+
+#. Short description of program.
+#: src/readelf.c:138
+msgid "Print information from ELF file in human-readable form."
+msgstr "Informationen aus der ELF-Datei in menschenlesbarer Form ausgeben."
+
+#: src/readelf.c:467
+#, c-format
+msgid "Unknown DWARF debug section `%s'.\n"
+msgstr ""
+
+#: src/readelf.c:535 src/readelf.c:646
+#, c-format
+msgid "cannot generate Elf descriptor: %s"
+msgstr "konnte Elf-Deskriptor nicht erzeugen: %s"
+
+#: src/readelf.c:542 src/readelf.c:858 src/strip.c:641
+#, c-format
+msgid "cannot determine number of sections: %s"
+msgstr ""
+
+#: src/readelf.c:560 src/readelf.c:1151 src/readelf.c:1353
+#, c-format
+msgid "cannot get section: %s"
+msgstr ""
+
+#: src/readelf.c:569 src/readelf.c:1158 src/readelf.c:1361 src/readelf.c:9767
+#: src/unstrip.c:375 src/unstrip.c:406 src/unstrip.c:455 src/unstrip.c:565
+#: src/unstrip.c:582 src/unstrip.c:619 src/unstrip.c:817 src/unstrip.c:1109
+#: src/unstrip.c:1301 src/unstrip.c:1362 src/unstrip.c:1535 src/unstrip.c:1650
+#: src/unstrip.c:1790 src/unstrip.c:1885
+#, c-format
+msgid "cannot get section header: %s"
+msgstr ""
+
+#: src/readelf.c:577
+#, fuzzy, c-format
+msgid "cannot get section name"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/readelf.c:586 src/readelf.c:5562 src/readelf.c:7902 src/readelf.c:8004
+#: src/readelf.c:8181
+#, c-format
+msgid "cannot get %s content: %s"
+msgstr ""
+
+#: src/readelf.c:602
+#, fuzzy, c-format
+msgid "cannot create temp file '%s'"
+msgstr "neue Datei konnte nicht angelegt werden"
+
+#: src/readelf.c:611
+#, fuzzy, c-format
+msgid "cannot write section data"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/readelf.c:617 src/readelf.c:634 src/readelf.c:663
+#, c-format
+msgid "error while closing Elf descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:624
+#, fuzzy, c-format
+msgid "error while rewinding file descriptor"
+msgstr "Fehler beim Schliessen des Elf-Desktriptor: %s\n"
+
+#: src/readelf.c:658
+#, c-format
+msgid "'%s' is not an archive, cannot print archive index"
+msgstr ""
+
+#: src/readelf.c:757
+#, fuzzy, c-format
+msgid "No such section '%s' in '%s'"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/readelf.c:784
+#, c-format
+msgid "cannot stat input file"
+msgstr ""
+
+#: src/readelf.c:786
+#, c-format
+msgid "input file is empty"
+msgstr ""
+
+#: src/readelf.c:788
+#, c-format
+msgid "failed reading '%s': %s"
+msgstr "Konnte '%s' nicht lesen: %s"
+
+#: src/readelf.c:843
+#, c-format
+msgid "cannot read ELF header: %s"
+msgstr ""
+
+#: src/readelf.c:851
+#, c-format
+msgid "cannot create EBL handle"
+msgstr ""
+
+#: src/readelf.c:864
+#, fuzzy, c-format
+msgid "cannot determine number of program headers: %s"
+msgstr "konnte Programm-Kopf nicht erstellen: %s"
+
+#: src/readelf.c:954
+msgid "NONE (None)"
+msgstr ""
+
+#: src/readelf.c:955
+msgid "REL (Relocatable file)"
+msgstr ""
+
+#: src/readelf.c:956
+msgid "EXEC (Executable file)"
+msgstr ""
+
+#: src/readelf.c:957
+msgid "DYN (Shared object file)"
+msgstr ""
+
+#: src/readelf.c:958
+msgid "CORE (Core file)"
+msgstr ""
+
+#: src/readelf.c:963
+#, c-format
+msgid "OS Specific: (%x)\n"
+msgstr ""
+
+#. && e_type <= ET_HIPROC always true
+#: src/readelf.c:965
+#, c-format
+msgid "Processor Specific: (%x)\n"
+msgstr ""
+
+#: src/readelf.c:975
+msgid ""
+"ELF Header:\n"
+"  Magic:  "
+msgstr ""
+
+#: src/readelf.c:979
+#, c-format
+msgid ""
+"\n"
+"  Class:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:984
+#, fuzzy, c-format
+msgid "  Data:                              %s\n"
+msgstr "  Daten:                             %s\n"
+
+#: src/readelf.c:990
+#, c-format
+msgid "  Ident Version:                     %hhd %s\n"
+msgstr ""
+
+#: src/readelf.c:992 src/readelf.c:1009
+msgid "(current)"
+msgstr "(aktuell)"
+
+#: src/readelf.c:996
+#, c-format
+msgid "  OS/ABI:                            %s\n"
+msgstr ""
+
+#: src/readelf.c:999
+#, c-format
+msgid "  ABI Version:                       %hhd\n"
+msgstr ""
+
+#: src/readelf.c:1002
+msgid "  Type:                              "
+msgstr "  Typ:                               "
+
+#: src/readelf.c:1005
+#, c-format
+msgid "  Machine:                           %s\n"
+msgstr ""
+
+#: src/readelf.c:1007
+#, c-format
+msgid "  Version:                           %d %s\n"
+msgstr ""
+
+#: src/readelf.c:1011
+#, c-format
+msgid "  Entry point address:               %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:1014
+#, c-format
+msgid "  Start of program headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:1015 src/readelf.c:1018
+msgid "(bytes into file)"
+msgstr ""
+
+#: src/readelf.c:1017
+#, c-format
+msgid "  Start of section headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:1020
+#, c-format
+msgid "  Flags:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:1023
+#, c-format
+msgid "  Size of this header:               %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:1024 src/readelf.c:1027 src/readelf.c:1044
+msgid "(bytes)"
+msgstr "(Bytes)"
+
+#: src/readelf.c:1026
+#, c-format
+msgid "  Size of program header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:1029
+#, c-format
+msgid "  Number of program headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:1036
+#, c-format
+msgid " (%<PRIu32> in [0].sh_info)"
+msgstr ""
+
+#: src/readelf.c:1039 src/readelf.c:1056 src/readelf.c:1070
+msgid " ([0] not available)"
+msgstr ""
+
+#: src/readelf.c:1043
+#, c-format
+msgid "  Size of section header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:1046
+#, c-format
+msgid "  Number of section headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:1053
+#, c-format
+msgid " (%<PRIu32> in [0].sh_size)"
+msgstr ""
+
+#. We managed to get the zeroth section.
+#: src/readelf.c:1066
+#, c-format
+msgid " (%<PRIu32> in [0].sh_link)"
+msgstr ""
+
+#: src/readelf.c:1074
+#, c-format
+msgid ""
+"  Section header string table index: XINDEX%s\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:1078
+#, c-format
+msgid ""
+"  Section header string table index: %<PRId16>\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:1121
+#, c-format
+msgid ""
+"There are %d section headers, starting at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:1131
+msgid "Section Headers:"
+msgstr ""
+
+#: src/readelf.c:1134
+msgid ""
+"[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
+"Inf Al"
+msgstr ""
+
+#: src/readelf.c:1136
+msgid ""
+"[Nr] Name                 Type         Addr             Off      Size     ES "
+"Flags Lk Inf Al"
+msgstr ""
+
+#: src/readelf.c:1141
+msgid "     [Compression  Size   Al]"
+msgstr ""
+
+#: src/readelf.c:1143
+msgid "     [Compression  Size     Al]"
+msgstr ""
+
+#: src/readelf.c:1219
+#, c-format
+msgid "bad compression header for section %zd: %s"
+msgstr ""
+
+#: src/readelf.c:1230
+#, c-format
+msgid "bad gnu compressed size for section %zd: %s"
+msgstr ""
+
+#: src/readelf.c:1248
+msgid "Program Headers:"
+msgstr "Programm-Köpfe:"
+
+#: src/readelf.c:1250
+msgid ""
+"  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:1253
+msgid ""
+"  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
+"MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:1310
+#, c-format
+msgid "\t[Requesting program interpreter: %s]\n"
+msgstr ""
+
+#: src/readelf.c:1331
+msgid ""
+"\n"
+" Section to Segment mapping:\n"
+"  Segment Sections..."
+msgstr ""
+
+#: src/readelf.c:1342 src/unstrip.c:1944 src/unstrip.c:1986 src/unstrip.c:1993
+#, c-format
+msgid "cannot get program header: %s"
+msgstr ""
+
+#: src/readelf.c:1485
+#, c-format
+msgid ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1490
+#, c-format
+msgid ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1498
+msgid "<INVALID SYMBOL>"
+msgstr ""
+
+#: src/readelf.c:1512
+msgid "<INVALID SECTION>"
+msgstr ""
+
+#: src/readelf.c:1535 src/readelf.c:2262 src/readelf.c:3345 src/readelf.c:9638
+#: src/readelf.c:9645 src/readelf.c:9689 src/readelf.c:9696
+msgid "Couldn't uncompress section"
+msgstr ""
+
+#: src/readelf.c:1540 src/readelf.c:2267 src/readelf.c:3350
+#, fuzzy, c-format
+msgid "cannot get section [%zd] header: %s"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/readelf.c:1684 src/readelf.c:2334 src/readelf.c:2592 src/readelf.c:2668
+#: src/readelf.c:2972 src/readelf.c:3046 src/readelf.c:4773
+#, fuzzy, c-format
+msgid "invalid sh_link value in section %zu"
+msgstr "ungültige .debug_line Sektion"
+
+#: src/readelf.c:1687
+#, c-format
+msgid ""
+"\n"
+"Dynamic segment contains %lu entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Dynamic segment contains %lu entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1697
+msgid "  Type              Value\n"
+msgstr ""
+
+#: src/readelf.c:1721
+#, c-format
+msgid "Shared library: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1726
+#, c-format
+msgid "Library soname: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1731
+#, c-format
+msgid "Library rpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1736
+#, c-format
+msgid "Library runpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1756
+#, c-format
+msgid "%<PRId64> (bytes)\n"
+msgstr ""
+
+#: src/readelf.c:1869 src/readelf.c:2059
+#, c-format
+msgid ""
+"\n"
+"Invalid symbol table at offset %#0<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:1887 src/readelf.c:2077
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#. The .rel.dyn section does not refer to a specific section but
+#. instead of section index zero.  Do not try to print a section
+#. name.
+#. The .rela.dyn section does not refer to a specific section but
+#. instead of section index zero.  Do not try to print a section
+#. name.
+#: src/readelf.c:1902 src/readelf.c:2092
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1912
+msgid "  Offset      Type                 Value       Name\n"
+msgstr ""
+
+#: src/readelf.c:1914
+msgid "  Offset              Type                 Value               Name\n"
+msgstr ""
+
+#: src/readelf.c:1967 src/readelf.c:1978 src/readelf.c:1991 src/readelf.c:2012
+#: src/readelf.c:2024 src/readelf.c:2158 src/readelf.c:2170 src/readelf.c:2184
+#: src/readelf.c:2206 src/readelf.c:2219
+msgid "<INVALID RELOC>"
+msgstr ""
+
+#: src/readelf.c:2102
+msgid "  Offset      Type            Value       Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:2104
+msgid "  Offset              Type            Value               Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:2342
+#, c-format
+msgid ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entry:\n"
+msgid_plural ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2347
+#, c-format
+msgid " %lu local symbol  String table: [%2u] '%s'\n"
+msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2355
+msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:2357
+msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:2377
+#, c-format
+msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+msgstr ""
+
+#: src/readelf.c:2465
+#, c-format
+msgid "bad dynamic symbol"
+msgstr ""
+
+#: src/readelf.c:2547
+msgid "none"
+msgstr "keine"
+
+#: src/readelf.c:2564
+msgid "| <unknown>"
+msgstr "| <unbekannt>"
+
+#: src/readelf.c:2595
+#, c-format
+msgid ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2616
+#, fuzzy, c-format
+msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
+msgstr "  %#06x: Version: %hu  Datei: %s  Cnt: %hu\n"
+
+#: src/readelf.c:2629
+#, c-format
+msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
+msgstr "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
+
+#: src/readelf.c:2672
+#, c-format
+msgid ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2700
+#, c-format
+msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
+msgstr ""
+
+#: src/readelf.c:2715
+#, c-format
+msgid "  %#06x: Parent %d: %s\n"
+msgstr ""
+
+#. Print the header.
+#: src/readelf.c:2976
+#, c-format
+msgid ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgid_plural ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:3004
+msgid "   0 *local*                     "
+msgstr "   0 *lokal*                     "
+
+#: src/readelf.c:3009
+msgid "   1 *global*                    "
+msgstr "   1 *global*                    "
+
+#: src/readelf.c:3051
+#, c-format
+msgid ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"bucket):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"buckets):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:3073
+#, no-c-format
+msgid " Length  Number  % of total  Coverage\n"
+msgstr ""
+
+#: src/readelf.c:3075
+#, c-format
+msgid "      0  %6<PRIu32>      %5.1f%%\n"
+msgstr "      0  %6<PRIu32>      %5.1f%%\n"
+
+#: src/readelf.c:3082
+#, c-format
+msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+msgstr "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+
+#: src/readelf.c:3095
+#, c-format
+msgid ""
+" Average number of tests:   successful lookup: %f\n"
+"\t\t\t  unsuccessful lookup: %f\n"
+msgstr ""
+
+#: src/readelf.c:3113 src/readelf.c:3168 src/readelf.c:3225
+#, c-format
+msgid "cannot get data for section %d: %s"
+msgstr ""
+
+#: src/readelf.c:3121
+#, fuzzy, c-format
+msgid "invalid data in sysv.hash section %d"
+msgstr "ungültige .debug_line Sektion"
+
+#: src/readelf.c:3176
+#, fuzzy, c-format
+msgid "invalid data in sysv.hash64 section %d"
+msgstr "ungültige .debug_line Sektion"
+
+#: src/readelf.c:3234
+#, fuzzy, c-format
+msgid "invalid data in gnu.hash section %d"
+msgstr "ungültige .debug_line Sektion"
+
+#: src/readelf.c:3301
+#, c-format
+msgid ""
+" Symbol Bias: %u\n"
+" Bitmask Size: %zu bytes  %<PRIuFAST32>%% bits set  2nd hash shift: %u\n"
+msgstr ""
+
+#: src/readelf.c:3390
+#, c-format
+msgid ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:3404
+msgid ""
+"       Library                       Time Stamp          Checksum Version "
+"Flags"
+msgstr ""
+
+#: src/readelf.c:3454
+#, c-format
+msgid ""
+"\n"
+"Object attributes section [%2zu] '%s' of %<PRIu64> bytes at offset "
+"%#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:3471
+msgid "  Owner          Size\n"
+msgstr ""
+
+#: src/readelf.c:3500
+#, c-format
+msgid "  %-13s  %4<PRIu32>\n"
+msgstr "  %-13s  %4<PRIu32>\n"
+
+#. Unknown subsection, print and skip.
+#: src/readelf.c:3539
+#, c-format
+msgid "    %-4u %12<PRIu32>\n"
+msgstr "    %-4u %12<PRIu32>\n"
+
+#. Tag_File
+#: src/readelf.c:3544
+#, c-format
+msgid "    File: %11<PRIu32>\n"
+msgstr "    File: %11<PRIu32>\n"
+
+#: src/readelf.c:3593
+#, c-format
+msgid "      %s: %<PRId64>, %s\n"
+msgstr "      %s: %<PRId64>, %s\n"
+
+#: src/readelf.c:3596
+#, c-format
+msgid "      %s: %<PRId64>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:3599
+#, c-format
+msgid "      %s: %s\n"
+msgstr "      %s: %s\n"
+
+#: src/readelf.c:3609
+#, c-format
+msgid "      %u: %<PRId64>\n"
+msgstr "      %u: %<PRId64>\n"
+
+#: src/readelf.c:3612
+#, c-format
+msgid "      %u: %s\n"
+msgstr "      %u: %s\n"
+
+#: src/readelf.c:3657
+#, c-format
+msgid "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3660
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3665
+#, c-format
+msgid "%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%#<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3668
+#, c-format
+msgid "%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%#0*<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3674
+#, c-format
+msgid "%s+%#<PRIx64> <%s>"
+msgstr "%s+%#<PRIx64> <%s>"
+
+#: src/readelf.c:3677
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s>"
+msgstr "%s+%#0*<PRIx64> <%s>"
+
+#: src/readelf.c:3681
+#, c-format
+msgid "%#<PRIx64> <%s>"
+msgstr "%#<PRIx64> <%s>"
+
+#: src/readelf.c:3684
+#, c-format
+msgid "%#0*<PRIx64> <%s>"
+msgstr "%#0*<PRIx64> <%s>"
+
+#: src/readelf.c:3689
+#, c-format
+msgid "%s+%#<PRIx64>"
+msgstr "%s+%#<PRIx64>"
+
+#: src/readelf.c:3692
+#, c-format
+msgid "%s+%#0*<PRIx64>"
+msgstr "%s+%#0*<PRIx64>"
+
+#: src/readelf.c:4095
+msgid "empty block"
+msgstr ""
+
+#: src/readelf.c:4098
+#, c-format
+msgid "%zu byte block:"
+msgstr ""
+
+#: src/readelf.c:4495
+#, c-format
+msgid "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+msgstr ""
+
+#: src/readelf.c:4552
+#, c-format
+msgid "%s %#<PRIx64> used with different address sizes"
+msgstr ""
+
+#: src/readelf.c:4559
+#, c-format
+msgid "%s %#<PRIx64> used with different offset sizes"
+msgstr ""
+
+#: src/readelf.c:4566
+#, c-format
+msgid "%s %#<PRIx64> used with different base addresses"
+msgstr ""
+
+#: src/readelf.c:4655
+#, c-format
+msgid " [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"
+msgstr ""
+
+#: src/readelf.c:4663
+#, c-format
+msgid " [%6tx]  <UNUSED GARBAGE> ... %<PRIu64> bytes ...\n"
+msgstr ""
+
+#: src/readelf.c:4689
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [ Code]\n"
+msgstr ""
+
+#: src/readelf.c:4697
+#, c-format
+msgid ""
+"\n"
+"Abbreviation section at offset %<PRIu64>:\n"
+msgstr ""
+
+#: src/readelf.c:4710
+#, c-format
+msgid " *** error while reading abbreviation: %s\n"
+msgstr ""
+
+#: src/readelf.c:4726
+#, c-format
+msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
+msgstr ""
+
+#: src/readelf.c:4729 src/readelf.c:6178 src/readelf.c:6186 src/readelf.c:7759
+msgid "yes"
+msgstr "ja"
+
+#: src/readelf.c:4729 src/readelf.c:6178 src/readelf.c:7759
+msgid "no"
+msgstr "nein"
+
+#: src/readelf.c:4763 src/readelf.c:4836
+#, c-format
+msgid "cannot get .debug_aranges content: %s"
+msgstr ""
+
+#: src/readelf.c:4778
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:4809
+#, c-format
+msgid " [%*zu] ???\n"
+msgstr " [%*zu] ???\n"
+
+#: src/readelf.c:4811
+#, c-format
+msgid ""
+" [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:4841 src/readelf.c:4995 src/readelf.c:5572 src/readelf.c:6529
+#: src/readelf.c:7061 src/readelf.c:7181 src/readelf.c:7345 src/readelf.c:7833
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:4854 src/readelf.c:6555
+#, c-format
+msgid ""
+"\n"
+"Table at offset %zu:\n"
+msgstr ""
+
+#: src/readelf.c:4858 src/readelf.c:5596 src/readelf.c:6566
+#, c-format
+msgid "invalid data in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:4874
+#, fuzzy, c-format
+msgid ""
+"\n"
+" Length:        %6<PRIu64>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:4886
+#, fuzzy, c-format
+msgid " DWARF version: %6<PRIuFAST16>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:4890
+#, c-format
+msgid "unsupported aranges version"
+msgstr ""
+
+#: src/readelf.c:4901
+#, fuzzy, c-format
+msgid " CU offset:     %6<PRIx64>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:4907
+#, c-format
+msgid " Address size:  %6<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:4911
+#, fuzzy, c-format
+msgid "unsupported address size"
+msgstr "Kein Adress-Wert"
+
+#: src/readelf.c:4916
+#, c-format
+msgid ""
+" Segment size:  %6<PRIu64>\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:4920
+#, c-format
+msgid "unsupported segment size"
+msgstr ""
+
+#: src/readelf.c:4960
+#, fuzzy, c-format
+msgid "   %s..%s (%<PRIx64>)\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:4963
+#, fuzzy, c-format
+msgid "   %s..%s\n"
+msgstr " [%6tx]  %s..%s\n"
+
+#: src/readelf.c:4972
+#, c-format
+msgid "   %zu padding bytes\n"
+msgstr ""
+
+#: src/readelf.c:4990
+#, c-format
+msgid "cannot get .debug_ranges content: %s"
+msgstr ""
+
+#: src/readelf.c:5020 src/readelf.c:7088
+#, c-format
+msgid " [%6tx]  <INVALID DATA>\n"
+msgstr ""
+
+#: src/readelf.c:5042 src/readelf.c:7110
+#, c-format
+msgid " [%6tx]  base address %s\n"
+msgstr ""
+
+#: src/readelf.c:5049 src/readelf.c:7117
+#, fuzzy, c-format
+msgid " [%6tx]  empty list\n"
+msgstr " [%6tx]  %s..%s\n"
+
+#. We have an address range entry.
+#. First address range entry in a list.
+#: src/readelf.c:5060
+#, c-format
+msgid " [%6tx]  %s..%s\n"
+msgstr " [%6tx]  %s..%s\n"
+
+#: src/readelf.c:5062
+#, c-format
+msgid "           %s..%s\n"
+msgstr "           %s..%s\n"
+
+#: src/readelf.c:5298
+msgid "         <INVALID DATA>\n"
+msgstr ""
+
+#: src/readelf.c:5551
+#, fuzzy, c-format
+msgid "cannot get ELF: %s"
+msgstr "ELF Kopf konnte nicht ausgelesen werden"
+
+#: src/readelf.c:5568
+#, c-format
+msgid ""
+"\n"
+"Call frame information section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:5618
+#, c-format
+msgid ""
+"\n"
+" [%6tx] Zero terminator\n"
+msgstr ""
+
+#: src/readelf.c:5711 src/readelf.c:5866
+#, fuzzy, c-format
+msgid "invalid augmentation length"
+msgstr "ungültige Abschnittsausrichtung"
+
+#: src/readelf.c:5726
+msgid "FDE address encoding: "
+msgstr ""
+
+#: src/readelf.c:5732
+msgid "LSDA pointer encoding: "
+msgstr ""
+
+#: src/readelf.c:5843
+#, c-format
+msgid " (offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5850
+#, c-format
+msgid " (end offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5887
+#, c-format
+msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:5942
+#, c-format
+msgid "cannot get attribute code: %s"
+msgstr ""
+
+#: src/readelf.c:5951
+#, c-format
+msgid "cannot get attribute form: %s"
+msgstr ""
+
+#: src/readelf.c:5966
+#, c-format
+msgid "cannot get attribute value: %s"
+msgstr ""
+
+#: src/readelf.c:6268
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [Offset]\n"
+msgstr ""
+
+#: src/readelf.c:6300
+#, c-format
+msgid ""
+" Type unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: "
+"%<PRIu8>, Offset size: %<PRIu8>\n"
+" Type signature: %#<PRIx64>, Type offset: %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:6309
+#, c-format
+msgid ""
+" Compilation unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: "
+"%<PRIu8>, Offset size: %<PRIu8>\n"
+msgstr ""
+
+#: src/readelf.c:6334
+#, c-format
+msgid "cannot get DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:6348
+#, c-format
+msgid "cannot get DIE offset: %s"
+msgstr ""
+
+#: src/readelf.c:6357
+#, c-format
+msgid "cannot get tag of DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:6389
+#, c-format
+msgid "cannot get next DIE: %s\n"
+msgstr ""
+
+#: src/readelf.c:6397
+#, c-format
+msgid "cannot get next DIE: %s"
+msgstr ""
+
+#: src/readelf.c:6433
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:6542
+#, c-format
+msgid "cannot get line data section data: %s"
+msgstr ""
+
+#. Print what we got so far.
+#: src/readelf.c:6612
+#, c-format
+msgid ""
+"\n"
+" Length:                     %<PRIu64>\n"
+" DWARF version:              %<PRIuFAST16>\n"
+" Prologue length:            %<PRIu64>\n"
+" Minimum instruction length: %<PRIuFAST8>\n"
+" Maximum operations per instruction: %<PRIuFAST8>\n"
+" Initial value if '%s': %<PRIuFAST8>\n"
+" Line base:                  %<PRIdFAST8>\n"
+" Line range:                 %<PRIuFAST8>\n"
+" Opcode base:                %<PRIuFAST8>\n"
+"\n"
+"Opcodes:\n"
+msgstr ""
+
+#: src/readelf.c:6633
+#, c-format
+msgid "invalid data at offset %tu in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:6648
+#, c-format
+msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
+msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:6656
+msgid ""
+"\n"
+"Directory table:"
+msgstr ""
+
+#: src/readelf.c:6672
+msgid ""
+"\n"
+"File name table:\n"
+" Entry Dir   Time      Size      Name"
+msgstr ""
+
+#: src/readelf.c:6707
+msgid ""
+"\n"
+"Line number statements:"
+msgstr ""
+
+#: src/readelf.c:6758
+#, c-format
+msgid "invalid maximum operations per instruction is zero"
+msgstr ""
+
+#: src/readelf.c:6794
+#, c-format
+msgid " special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"
+msgstr ""
+
+#: src/readelf.c:6799
+#, c-format
+msgid " special opcode %u: address+%u = %s, line%+d = %zu\n"
+msgstr ""
+
+#: src/readelf.c:6819
+#, c-format
+msgid " extended opcode %u: "
+msgstr ""
+
+#: src/readelf.c:6824
+msgid " end of sequence"
+msgstr ""
+
+#: src/readelf.c:6843
+#, c-format
+msgid " set address to %s\n"
+msgstr ""
+
+#: src/readelf.c:6870
+#, c-format
+msgid " define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
+msgstr ""
+
+#: src/readelf.c:6883
+#, c-format
+msgid " set discriminator to %u\n"
+msgstr ""
+
+#. Unknown, ignore it.
+#: src/readelf.c:6888
+#, fuzzy
+msgid " unknown opcode"
+msgstr "unbekannter Typ"
+
+#. Takes no argument.
+#: src/readelf.c:6900
+msgid " copy"
+msgstr ""
+
+#: src/readelf.c:6911
+#, c-format
+msgid " advance address by %u to %s, op_index to %u\n"
+msgstr ""
+
+#: src/readelf.c:6915
+#, c-format
+msgid " advance address by %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:6926
+#, c-format
+msgid " advance line by constant %d to %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:6934
+#, c-format
+msgid " set file to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:6944
+#, c-format
+msgid " set column to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:6951
+#, c-format
+msgid " set '%s' to %<PRIuFAST8>\n"
+msgstr ""
+
+#. Takes no argument.
+#: src/readelf.c:6957
+msgid " set basic block flag"
+msgstr ""
+
+#: src/readelf.c:6970
+#, c-format
+msgid " advance address by constant %u to %s, op_index to %u\n"
+msgstr ""
+
+#: src/readelf.c:6974
+#, c-format
+msgid " advance address by constant %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:6992
+#, c-format
+msgid " advance address by fixed value %u to %s\n"
+msgstr ""
+
+#. Takes no argument.
+#: src/readelf.c:7001
+msgid " set prologue end flag"
+msgstr ""
+
+#. Takes no argument.
+#: src/readelf.c:7006
+msgid " set epilogue begin flag"
+msgstr ""
+
+#: src/readelf.c:7015
+#, c-format
+msgid " set isa to %u\n"
+msgstr ""
+
+#. This is a new opcode the generator but not we know about.
+#. Read the parameters associated with it but then discard
+#. everything.  Read all the parameters for this opcode.
+#: src/readelf.c:7024
+#, c-format
+msgid " unknown opcode with %<PRIu8> parameter:"
+msgid_plural " unknown opcode with %<PRIu8> parameters:"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:7056
+#, c-format
+msgid "cannot get .debug_loc content: %s"
+msgstr ""
+
+#. First entry in a list.
+#: src/readelf.c:7131
+#, c-format
+msgid " [%6tx]  %s..%s"
+msgstr " [%6tx]  %s..%s"
+
+#: src/readelf.c:7133
+#, c-format
+msgid "           %s..%s"
+msgstr "           %s..%s"
+
+#: src/readelf.c:7140 src/readelf.c:8091
+msgid "   <INVALID DATA>\n"
+msgstr ""
+
+#: src/readelf.c:7192 src/readelf.c:7354
+#, c-format
+msgid "cannot get macro information section data: %s"
+msgstr ""
+
+#: src/readelf.c:7272
+#, c-format
+msgid "%*s*** non-terminated string at end of section"
+msgstr ""
+
+#: src/readelf.c:7295
+#, c-format
+msgid "%*s*** missing DW_MACINFO_start_file argument at end of section"
+msgstr ""
+
+#: src/readelf.c:7395
+#, fuzzy, c-format
+msgid " Offset:             0x%<PRIx64>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:7407
+#, fuzzy, c-format
+msgid " Version:            %<PRIu16>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:7413 src/readelf.c:8210
+#, c-format
+msgid "  unknown version, cannot parse section\n"
+msgstr ""
+
+#: src/readelf.c:7420
+#, fuzzy, c-format
+msgid " Flag:               0x%<PRIx8>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:7423
+#, c-format
+msgid " Offset length:      %<PRIu8>\n"
+msgstr ""
+
+#: src/readelf.c:7431
+#, c-format
+msgid " .debug_line offset: 0x%<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:7444
+#, c-format
+msgid "  extension opcode table, %<PRIu8> items:\n"
+msgstr ""
+
+#: src/readelf.c:7451
+#, c-format
+msgid "    [%<PRIx8>]"
+msgstr ""
+
+#: src/readelf.c:7463
+#, c-format
+msgid " %<PRIu8> arguments:"
+msgstr ""
+
+#: src/readelf.c:7491
+#, c-format
+msgid " no arguments."
+msgstr ""
+
+#: src/readelf.c:7791
+#, c-format
+msgid "vendor opcode not verified?"
+msgstr ""
+
+#: src/readelf.c:7819
+#, c-format
+msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
+msgstr ""
+
+#: src/readelf.c:7860
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" %*s  String\n"
+msgstr ""
+
+#: src/readelf.c:7874
+#, c-format
+msgid " *** error while reading strings: %s\n"
+msgstr ""
+
+#: src/readelf.c:7894
+#, c-format
+msgid ""
+"\n"
+"Call frame search table section [%2zu] '.eh_frame_hdr':\n"
+msgstr ""
+
+#: src/readelf.c:7996
+#, c-format
+msgid ""
+"\n"
+"Exception handling table section [%2zu] '.gcc_except_table':\n"
+msgstr ""
+
+#: src/readelf.c:8019
+#, c-format
+msgid " LPStart encoding:    %#x "
+msgstr ""
+
+#: src/readelf.c:8031
+#, c-format
+msgid " TType encoding:      %#x "
+msgstr ""
+
+#: src/readelf.c:8046
+#, c-format
+msgid " Call site encoding:  %#x "
+msgstr ""
+
+#: src/readelf.c:8059
+msgid ""
+"\n"
+" Call site table:"
+msgstr ""
+
+#: src/readelf.c:8073
+#, c-format
+msgid ""
+" [%4u] Call site start:   %#<PRIx64>\n"
+"        Call site length:  %<PRIu64>\n"
+"        Landing pad:       %#<PRIx64>\n"
+"        Action:            %u\n"
+msgstr ""
+
+#: src/readelf.c:8146
+#, c-format
+msgid "invalid TType encoding"
+msgstr ""
+
+#: src/readelf.c:8172
+#, c-format
+msgid ""
+"\n"
+"GDB section [%2zu] '%s' at offset %#<PRIx64> contains %<PRId64> bytes :\n"
+msgstr ""
+
+#: src/readelf.c:8201
+#, fuzzy, c-format
+msgid " Version:         %<PRId32>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:8219
+#, c-format
+msgid " CU offset:       %#<PRIx32>\n"
+msgstr ""
+
+#: src/readelf.c:8226
+#, c-format
+msgid " TU offset:       %#<PRIx32>\n"
+msgstr ""
+
+#: src/readelf.c:8233
+#, c-format
+msgid " address offset:  %#<PRIx32>\n"
+msgstr ""
+
+#: src/readelf.c:8240
+#, c-format
+msgid " symbol offset:   %#<PRIx32>\n"
+msgstr ""
+
+#: src/readelf.c:8247
+#, c-format
+msgid " constant offset: %#<PRIx32>\n"
+msgstr ""
+
+#: src/readelf.c:8261
+#, c-format
+msgid ""
+"\n"
+" CU list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+
+#: src/readelf.c:8286
+#, c-format
+msgid ""
+"\n"
+" TU list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+
+#: src/readelf.c:8315
+#, c-format
+msgid ""
+"\n"
+" Address list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+
+#: src/readelf.c:8348
+#, c-format
+msgid ""
+"\n"
+" Symbol table at offset %#<PRIx32> contains %zu slots:\n"
+msgstr ""
+
+#: src/readelf.c:8435
+#, c-format
+msgid "cannot get debug context descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:8591 src/readelf.c:9213 src/readelf.c:9324 src/readelf.c:9382
+#, c-format
+msgid "cannot convert core note data: %s"
+msgstr ""
+
+#: src/readelf.c:8954
+#, c-format
+msgid ""
+"\n"
+"%*s... <repeats %u more times> ..."
+msgstr ""
+
+#: src/readelf.c:9461
+msgid "  Owner          Data size  Type\n"
+msgstr ""
+
+#: src/readelf.c:9479
+#, c-format
+msgid "  %-13.*s  %9<PRId32>  %s\n"
+msgstr ""
+
+#: src/readelf.c:9529
+#, c-format
+msgid "cannot get content of note section: %s"
+msgstr ""
+
+#: src/readelf.c:9556
+#, c-format
+msgid ""
+"\n"
+"Note section [%2zu] '%s' of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:9579
+#, c-format
+msgid ""
+"\n"
+"Note segment of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:9625
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Section [%zu] '%s' has no data to dump.\n"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/readelf.c:9652 src/readelf.c:9703
+#, fuzzy, c-format
+msgid "cannot get data for section [%zu] '%s': %s"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/readelf.c:9657
+#, c-format
+msgid ""
+"\n"
+"Hex dump of section [%zu] '%s', %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:9662
+#, c-format
+msgid ""
+"\n"
+"Hex dump of section [%zu] '%s', %<PRIu64> bytes (%zd uncompressed) at offset "
+"%#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:9676
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Section [%zu] '%s' has no strings to dump.\n"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/readelf.c:9708
+#, c-format
+msgid ""
+"\n"
+"String section [%zu] '%s' contains %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:9713
+#, c-format
+msgid ""
+"\n"
+"String section [%zu] '%s' contains %<PRIu64> bytes (%zd uncompressed) at "
+"offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:9762
+#, c-format
+msgid ""
+"\n"
+"section [%lu] does not exist"
+msgstr ""
+
+#: src/readelf.c:9791
+#, c-format
+msgid ""
+"\n"
+"section '%s' does not exist"
+msgstr ""
+
+#: src/readelf.c:9848
+#, c-format
+msgid "cannot get symbol index of archive '%s': %s"
+msgstr ""
+
+#: src/readelf.c:9851
+#, c-format
+msgid ""
+"\n"
+"Archive '%s' has no symbol index\n"
+msgstr ""
+
+#: src/readelf.c:9855
+#, c-format
+msgid ""
+"\n"
+"Index of archive '%s' has %zu entries:\n"
+msgstr ""
+
+#: src/readelf.c:9873
+#, fuzzy, c-format
+msgid "cannot extract member at offset %zu in '%s': %s"
+msgstr "konnte Programm-Kopf nicht erstellen: %s"
+
+#: src/readelf.c:9878
+#, c-format
+msgid "Archive member '%s' contains:\n"
+msgstr ""
+
+#: src/size.c:57
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd' or `sysv'.  The default "
+"is `bsd'"
+msgstr ""
+
+#: src/size.c:59
+msgid "Same as `--format=sysv'"
+msgstr "Genau wie `--format=sysv'"
+
+#: src/size.c:60
+msgid "Same as `--format=bsd'"
+msgstr "Genau wie `--format=bsd'"
+
+#: src/size.c:63
+msgid "Same as `--radix=10'"
+msgstr "Genau wie `--radix=10'"
+
+#: src/size.c:64
+msgid "Same as `--radix=8'"
+msgstr "Genau wie `--radix=8'"
+
+#: src/size.c:65
+msgid "Same as `--radix=16'"
+msgstr "Genau wie `--radix=16'"
+
+#: src/size.c:67
+msgid "Similar to `--format=sysv' output but in one line"
+msgstr ""
+
+#: src/size.c:71
+msgid "Print size and permission flags for loadable segments"
+msgstr ""
+
+#: src/size.c:72
+msgid "Display the total sizes (bsd only)"
+msgstr ""
+
+#. Short description of program.
+#: src/size.c:77
+msgid "List section sizes of FILEs (a.out by default)."
+msgstr ""
+
+#: src/size.c:241
+#, c-format
+msgid "Invalid format: %s"
+msgstr "Ungültiges Format: %s"
+
+#: src/size.c:252
+#, c-format
+msgid "Invalid radix: %s"
+msgstr ""
+
+#: src/size.c:311
+#, c-format
+msgid "%s: file format not recognized"
+msgstr ""
+
+#: src/size.c:417 src/size.c:550
+#, c-format
+msgid " (ex %s)"
+msgstr ""
+
+#: src/size.c:575
+msgid "(TOTALS)\n"
+msgstr ""
+
+#: src/stack.c:483
+#, c-format
+msgid "-p PID should be a positive process id."
+msgstr ""
+
+#: src/stack.c:489
+#, fuzzy, c-format
+msgid "Cannot open core file '%s'"
+msgstr "Konnte Archiv '%s' nicht öffnen"
+
+#: src/stack.c:549
+#, c-format
+msgid "-n MAXFRAMES should be 0 or higher."
+msgstr ""
+
+#: src/stack.c:561
+#, c-format
+msgid "-e EXEC needs a core given by --core."
+msgstr ""
+
+#: src/stack.c:565
+#, c-format
+msgid "-1 needs a thread id given by -p."
+msgstr ""
+
+#: src/stack.c:569
+#, c-format
+msgid "One of -p PID or --core COREFILE should be given."
+msgstr ""
+
+#: src/stack.c:641
+#, fuzzy
+msgid "Show stack of process PID"
+msgstr "Kann Suchbaum nicht erstellen"
+
+#: src/stack.c:643
+msgid "Show stack found in COREFILE"
+msgstr ""
+
+#: src/stack.c:644
+msgid "(optional) EXECUTABLE that produced COREFILE"
+msgstr ""
+
+#: src/stack.c:648
+#, fuzzy
+msgid "Output selection options:"
+msgstr "Eingabeauswahloptionen:"
+
+#: src/stack.c:650
+msgid "Additionally show frame activation"
+msgstr ""
+
+#: src/stack.c:652
+msgid "Additionally try to lookup DWARF debuginfo name for frame address"
+msgstr ""
+
+#: src/stack.c:655
+msgid ""
+"Additionally show inlined function frames using DWARF debuginfo if available "
+"(implies -d)"
+msgstr ""
+
+#: src/stack.c:657
+msgid "Additionally show module file information"
+msgstr ""
+
+#: src/stack.c:659
+msgid "Additionally show source file information"
+msgstr ""
+
+#: src/stack.c:661
+msgid ""
+"Show all additional information (activation, debugname, inlines, module and "
+"source)"
+msgstr ""
+
+#: src/stack.c:663
+msgid "Do not resolve address to function symbol name"
+msgstr ""
+
+#: src/stack.c:665
+msgid "Show raw function symbol names, do not try to demangle names"
+msgstr ""
+
+#: src/stack.c:667
+msgid "Show module build-id, load address and pc offset"
+msgstr ""
+
+#: src/stack.c:669
+msgid "Show the backtrace of only one thread"
+msgstr ""
+
+#: src/stack.c:671
+msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)"
+msgstr ""
+
+#: src/stack.c:673
+msgid "Show module memory map with build-id, elf and debug files detected"
+msgstr ""
+
+#: src/stack.c:681
+msgid ""
+"Print a stack for each thread in a process or core file.\n"
+"\n"
+"Program exits with return code 0 if all frames were shown without any "
+"errors.  If some frames were shown, but there were some non-fatal errors, "
+"possibly causing an incomplete backtrace, the program exits with return code "
+"1.  If no frames could be shown, or a fatal error occured the program exits "
+"with return code 2.  If the program was invoked with bad or missing "
+"arguments it will exit with return code 64."
+msgstr ""
+
+#: src/stack.c:756
+#, c-format
+msgid "Couldn't show any frames."
+msgstr ""
+
+#: src/strings.c:66
+msgid "Output Selection:"
+msgstr ""
+
+#: src/strings.c:67
+msgid "Scan entire file, not only loaded sections"
+msgstr ""
+
+#: src/strings.c:69
+msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed"
+msgstr ""
+
+#: src/strings.c:70
+msgid ""
+"Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, "
+"{B,L} = 32-bit"
+msgstr ""
+
+#: src/strings.c:74
+msgid "Print name of the file before each string."
+msgstr ""
+
+#: src/strings.c:76
+msgid "Print location of the string in base 8, 10, or 16 respectively."
+msgstr ""
+
+#: src/strings.c:77
+msgid "Alias for --radix=o"
+msgstr "Alias für --radix=o"
+
+#. Short description of program.
+#: src/strings.c:84
+msgid "Print the strings of printable characters in files."
+msgstr ""
+
+#: src/strings.c:257 src/strings.c:292
+#, c-format
+msgid "invalid value '%s' for %s parameter"
+msgstr ""
+
+#: src/strings.c:303
+#, c-format
+msgid "invalid minimum length of matched string size"
+msgstr ""
+
+#: src/strings.c:586
+#, fuzzy, c-format
+msgid "lseek failed"
+msgstr "lseek64 fehlgeschlagen"
+
+#: src/strings.c:603 src/strings.c:667
+#, c-format
+msgid "re-mmap failed"
+msgstr "re-mmap fehlgeschlagen"
+
+#: src/strings.c:640
+#, c-format
+msgid "mprotect failed"
+msgstr "mprotect fehlgeschlagen"
+
+#: src/strings.c:729
+#, c-format
+msgid "Skipping section %zd '%s' data outside file"
+msgstr ""
+
+#: src/strip.c:71
+msgid "Place stripped output into FILE"
+msgstr ""
+
+#: src/strip.c:72
+msgid "Extract the removed sections into FILE"
+msgstr ""
+
+#: src/strip.c:73
+msgid "Embed name FILE instead of -f argument"
+msgstr ""
+
+#: src/strip.c:77
+msgid "Remove all debugging symbols"
+msgstr ""
+
+#: src/strip.c:81
+msgid "Remove section headers (not recommended)"
+msgstr ""
+
+#: src/strip.c:83
+msgid "Copy modified/access timestamps to the output"
+msgstr ""
+
+#: src/strip.c:85
+msgid ""
+"Resolve all trivial relocations between debug sections if the removed "
+"sections are placed in a debug file (only relevant for ET_REL files, "
+"operation is not reversable, needs -f)"
+msgstr ""
+
+#: src/strip.c:87
+msgid "Remove .comment section"
+msgstr ""
+
+#: src/strip.c:88
+msgid ""
+"Remove the named section.  SECTION is an extended wildcard pattern.  May be "
+"given more than once.  Only non-allocated sections can be removed."
+msgstr ""
+
+#: src/strip.c:89
+msgid ""
+"Keep the named section.  SECTION is an extended wildcard pattern.  May be "
+"given more than once."
+msgstr ""
+
+#. Short description of program.
+#: src/strip.c:96
+msgid "Discard symbols from object files."
+msgstr ""
+
+#: src/strip.c:242
+#, c-format
+msgid "--reloc-debug-sections used without -f"
+msgstr ""
+
+#: src/strip.c:256
+#, c-format
+msgid "Only one input file allowed together with '-o' and '-f'"
+msgstr ""
+
+#: src/strip.c:279
+#, c-format
+msgid "-f option specified twice"
+msgstr ""
+
+#: src/strip.c:288
+#, c-format
+msgid "-F option specified twice"
+msgstr ""
+
+#: src/strip.c:347
+#, c-format
+msgid "cannot both keep and remove .comment section"
+msgstr ""
+
+#: src/strip.c:372 src/strip.c:396
+#, c-format
+msgid "cannot stat input file '%s'"
+msgstr ""
+
+#: src/strip.c:386
+#, c-format
+msgid "while opening '%s'"
+msgstr ""
+
+#: src/strip.c:424
+#, c-format
+msgid "%s: cannot use -o or -f when stripping archive"
+msgstr ""
+
+#. We would like to support ar archives, but currently it just
+#. doesn't work at all since we call elf_clone on the members
+#. which doesn't really support ar members.
+#. result = handle_ar (fd, elf, NULL, fname,
+#. preserve_dates ? tv : NULL);
+#.
+#: src/strip.c:436
+#, fuzzy, c-format
+msgid "%s: no support for stripping archive"
+msgstr "%s: Kein Eintrag %s in dem Archiv!\n"
+
+#: src/strip.c:535
+#, c-format
+msgid "cannot open EBL backend"
+msgstr ""
+
+#: src/strip.c:580
+#, fuzzy, c-format
+msgid "cannot get number of phdrs"
+msgstr "konnte Programm-Kopf nicht erstellen: %s"
+
+#: src/strip.c:596 src/strip.c:620
+#, c-format
+msgid "cannot create new file '%s': %s"
+msgstr ""
+
+#: src/strip.c:686
+#, c-format
+msgid "illformed file '%s'"
+msgstr ""
+
+#: src/strip.c:696
+#, fuzzy, c-format
+msgid "Cannot remove allocated section '%s'"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/strip.c:705
+#, fuzzy, c-format
+msgid "Cannot both keep and remove section '%s'"
+msgstr "Konnte Archiv '%s' nicht öffnen"
+
+#: src/strip.c:1061 src/strip.c:1160
+#, c-format
+msgid "while generating output file: %s"
+msgstr ""
+
+#: src/strip.c:1126 src/strip.c:2208
+#, c-format
+msgid "%s: error while creating ELF header: %s"
+msgstr ""
+
+#: src/strip.c:1143
+#, c-format
+msgid "while preparing output for '%s'"
+msgstr ""
+
+#: src/strip.c:1205 src/strip.c:1268
+#, c-format
+msgid "while create section header section: %s"
+msgstr ""
+
+#: src/strip.c:1214
+#, c-format
+msgid "cannot allocate section data: %s"
+msgstr ""
+
+#: src/strip.c:1280
+#, c-format
+msgid "while create section header string table: %s"
+msgstr ""
+
+#: src/strip.c:1287
+#, c-format
+msgid "no memory to create section header string table"
+msgstr ""
+
+#: src/strip.c:1497
+#, c-format
+msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]"
+msgstr ""
+
+#: src/strip.c:1994
+#, fuzzy, c-format
+msgid "bad relocation"
+msgstr "Relocations anzeigen"
+
+#: src/strip.c:2119 src/strip.c:2232
+#, c-format
+msgid "while writing '%s': %s"
+msgstr ""
+
+#: src/strip.c:2130
+#, c-format
+msgid "while creating '%s'"
+msgstr ""
+
+#: src/strip.c:2153
+#, c-format
+msgid "while computing checksum for debug information"
+msgstr ""
+
+#: src/strip.c:2217
+#, c-format
+msgid "%s: error while reading the file: %s"
+msgstr ""
+
+#: src/strip.c:2257 src/strip.c:2277
+#, fuzzy, c-format
+msgid "while writing '%s'"
+msgstr "beim Schliessen von '%s'"
+
+#: src/strip.c:2314 src/strip.c:2321
+#, c-format
+msgid "error while finishing '%s': %s"
+msgstr ""
+
+#: src/strip.c:2338 src/strip.c:2414
+#, c-format
+msgid "cannot set access and modification date of '%s'"
+msgstr ""
+
+#: src/unstrip.c:70
+msgid "Match MODULE against file names, not module names"
+msgstr ""
+
+#: src/unstrip.c:71
+msgid "Silently skip unfindable files"
+msgstr ""
+
+#: src/unstrip.c:74
+msgid "Place output into FILE"
+msgstr ""
+
+#: src/unstrip.c:76
+msgid "Create multiple output files under DIRECTORY"
+msgstr ""
+
+#: src/unstrip.c:77
+msgid "Use module rather than file names"
+msgstr ""
+
+#: src/unstrip.c:79
+msgid "Create output for modules that have no separate debug information"
+msgstr ""
+
+#: src/unstrip.c:82
+msgid "Apply relocations to section contents in ET_REL files"
+msgstr ""
+
+#: src/unstrip.c:84
+msgid "Only list module and file names, build IDs"
+msgstr ""
+
+#: src/unstrip.c:86
+msgid "Force combining files even if some ELF headers don't seem to match"
+msgstr ""
+
+#: src/unstrip.c:130
+#, c-format
+msgid "-d option specified twice"
+msgstr "Option -d zweimal angegeben"
+
+#: src/unstrip.c:165
+#, c-format
+msgid "only one of -o or -d allowed"
+msgstr "nur entweder -o oder -d erlaubt"
+
+#: src/unstrip.c:174
+#, c-format
+msgid "-n cannot be used with explicit files or -o or -d"
+msgstr "-n kann nicht mit expliziten Dateien oder -o oder -d verwendet werden"
+
+#: src/unstrip.c:189
+#, c-format
+msgid "output directory '%s'"
+msgstr "Ausgabeverzeichnis '%s'"
+
+#: src/unstrip.c:198
+#, c-format
+msgid "exactly two file arguments are required"
+msgstr "genau zwei Datei-Argumente werden benötigt"
+
+#: src/unstrip.c:204
+#, c-format
+msgid "-m, -a, -R, and -i options not allowed with explicit files"
+msgstr ""
+
+#: src/unstrip.c:217
+#, c-format
+msgid "-o or -d is required when using implicit files"
+msgstr ""
+
+#: src/unstrip.c:240
+#, c-format
+msgid "cannot create ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:245
+#, c-format
+msgid "cannot copy ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:249 src/unstrip.c:1933 src/unstrip.c:1976
+#, fuzzy, c-format
+msgid "cannot get number of program headers: %s"
+msgstr "konnte Programm-Kopf nicht erstellen: %s"
+
+#: src/unstrip.c:254 src/unstrip.c:1937
+#, c-format
+msgid "cannot create program headers: %s"
+msgstr "konnte Programm-Kopf nicht erstellen: %s"
+
+#: src/unstrip.c:260
+#, c-format
+msgid "cannot copy program header: %s"
+msgstr "konnte Programm-Kopf nicht kopieren: %s"
+
+#: src/unstrip.c:270
+#, c-format
+msgid "cannot copy section header: %s"
+msgstr ""
+
+#: src/unstrip.c:273 src/unstrip.c:1568
+#, c-format
+msgid "cannot get section data: %s"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/unstrip.c:275 src/unstrip.c:1570
+#, c-format
+msgid "cannot copy section data: %s"
+msgstr "konnte Abschnittsdaten nicht kopieren: %s"
+
+#: src/unstrip.c:299
+#, c-format
+msgid "cannot create directory '%s'"
+msgstr "konnte Verzeichnis nicht erstellen: %s"
+
+#: src/unstrip.c:371 src/unstrip.c:791 src/unstrip.c:1602
+#, c-format
+msgid "cannot get symbol table entry: %s"
+msgstr "konnte Eintrag aus der Symboltabelle nicht holen: %s"
+
+#: src/unstrip.c:387 src/unstrip.c:608 src/unstrip.c:629 src/unstrip.c:641
+#: src/unstrip.c:1623 src/unstrip.c:1799 src/unstrip.c:1823
+#, c-format
+msgid "cannot update symbol table: %s"
+msgstr "konnte Symboltabelle nicht aktualisieren: %s"
+
+#: src/unstrip.c:397
+#, c-format
+msgid "cannot update section header: %s"
+msgstr ""
+
+#: src/unstrip.c:436 src/unstrip.c:447
+#, c-format
+msgid "cannot update relocation: %s"
+msgstr ""
+
+#: src/unstrip.c:535
+#, c-format
+msgid "cannot get symbol version: %s"
+msgstr ""
+
+#: src/unstrip.c:548
+#, c-format
+msgid "unexpected section type in [%zu] with sh_link to symtab"
+msgstr ""
+
+#: src/unstrip.c:797
+#, fuzzy, c-format
+msgid "invalid string offset in symbol [%zu]"
+msgstr "ungültiger Offset %zu für Symbol %s"
+
+#: src/unstrip.c:955 src/unstrip.c:1305
+#, fuzzy, c-format
+msgid "cannot read section [%zu] name: %s"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/unstrip.c:996 src/unstrip.c:1015 src/unstrip.c:1053
+#, c-format
+msgid "cannot read '.gnu.prelink_undo' section: %s"
+msgstr ""
+
+#: src/unstrip.c:1033
+#, c-format
+msgid "overflow with shnum = %zu in '%s' section"
+msgstr ""
+
+#: src/unstrip.c:1044
+#, c-format
+msgid "invalid contents in '%s' section"
+msgstr ""
+
+#: src/unstrip.c:1099 src/unstrip.c:1427
+#, fuzzy, c-format
+msgid "cannot find matching section for [%zu] '%s'"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/unstrip.c:1224 src/unstrip.c:1239 src/unstrip.c:1506 src/unstrip.c:1758
+#, c-format
+msgid "cannot add section name to string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1248
+#, c-format
+msgid "cannot update section header string table data: %s"
+msgstr ""
+
+#: src/unstrip.c:1276 src/unstrip.c:1280
+#, c-format
+msgid "cannot get section header string table section index: %s"
+msgstr ""
+
+#: src/unstrip.c:1284 src/unstrip.c:1288 src/unstrip.c:1521
+#, c-format
+msgid "cannot get section count: %s"
+msgstr ""
+
+#: src/unstrip.c:1291
+#, c-format
+msgid "more sections in stripped file than debug file -- arguments reversed?"
+msgstr ""
+
+#: src/unstrip.c:1350 src/unstrip.c:1442
+#, c-format
+msgid "cannot read section header string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1500
+#, c-format
+msgid "cannot add new section: %s"
+msgstr ""
+
+#: src/unstrip.c:1610
+#, fuzzy, c-format
+msgid "symbol [%zu] has invalid section index"
+msgstr "ungültiger Abschnittsindex"
+
+#: src/unstrip.c:1894
+#, fuzzy, c-format
+msgid "cannot read section data: %s"
+msgstr "konnte Abschnittsdaten nicht holen: %s"
+
+#: src/unstrip.c:1915
+#, c-format
+msgid "cannot get ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:1923
+#, c-format
+msgid "cannot update ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:1947
+#, c-format
+msgid "cannot update program header: %s"
+msgstr "konnte Programm-Kopf nicht aktualisieren: %s"
+
+#: src/unstrip.c:1952 src/unstrip.c:2034
+#, c-format
+msgid "cannot write output file: %s"
+msgstr ""
+
+#: src/unstrip.c:2003
+#, c-format
+msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:2006
+#, c-format
+msgid ""
+"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:2025 src/unstrip.c:2076 src/unstrip.c:2088 src/unstrip.c:2174
+#, c-format
+msgid "cannot create ELF descriptor: %s"
+msgstr ""
+
+#: src/unstrip.c:2067
+msgid "WARNING: "
+msgstr ""
+
+#: src/unstrip.c:2069
+msgid ", use --force"
+msgstr ""
+
+#: src/unstrip.c:2092
+msgid "ELF header identification (e_ident) different"
+msgstr ""
+
+#: src/unstrip.c:2095
+msgid "ELF header type (e_type) different"
+msgstr ""
+
+#: src/unstrip.c:2098
+msgid "ELF header machine type (e_machine) different"
+msgstr ""
+
+#: src/unstrip.c:2101
+msgid "stripped program header (e_phnum) smaller than unstripped"
+msgstr ""
+
+#: src/unstrip.c:2131
+#, c-format
+msgid "cannot find stripped file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2135
+#, c-format
+msgid "cannot open stripped file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2150
+#, c-format
+msgid "cannot find debug file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2154
+#, c-format
+msgid "cannot open debug file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2167
+#, c-format
+msgid "module '%s' file '%s' is not stripped"
+msgstr ""
+
+#: src/unstrip.c:2198
+#, c-format
+msgid "cannot cache section addresses for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2331
+#, c-format
+msgid "no matching modules found"
+msgstr "kein passendes Modul gefunden"
+
+#: src/unstrip.c:2340
+#, c-format
+msgid "matched more than one module"
+msgstr "mehr als ein passendes Modul"
+
+#: src/unstrip.c:2384
+msgid ""
+"STRIPPED-FILE DEBUG-FILE\n"
+"[MODULE...]"
+msgstr ""
+
+#: src/unstrip.c:2385
+msgid ""
+"Combine stripped files with separate symbols and debug information.\n"
+"\n"
+"The first form puts the result in DEBUG-FILE if -o was not given.\n"
+"\n"
+"MODULE arguments give file name patterns matching modules to process.\n"
+"With -f these match the file name of the main (stripped) file (slashes are "
+"never special), otherwise they match the simple module names.  With no "
+"arguments, process all modules found.\n"
+"\n"
+"Multiple modules are written to files under OUTPUT-DIRECTORY, creating "
+"subdirectories as needed.  With -m these files have simple module names, "
+"otherwise they have the name of the main file complete with directory "
+"underneath OUTPUT-DIRECTORY.\n"
+"\n"
+"With -n no files are written, but one line to standard output for each "
+"module:\n"
+"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n"
+"START and SIZE are hexadecimal giving the address bounds of the module.  "
+"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the "
+"hexadecimal may be followed by @0xADDR giving the address where the ID "
+"resides if that is known.  FILE is the file name found for the module, or - "
+"if none was found, or . if an ELF image is available but not from any named "
+"file.  DEBUGFILE is the separate debuginfo file name, or - if no debuginfo "
+"was found, or . if FILE contains the debug information."
+msgstr ""
+
+#: tests/backtrace.c:442
+msgid "Run executable"
+msgstr ""
+
+#: tests/dwflmodtest.c:213
+msgid "Additionally show function names"
+msgstr ""
+
+#: tests/dwflmodtest.c:214
+msgid "Show instances of inlined functions"
+msgstr ""
+
+#~ msgid "Written by %s.\n"
+#~ msgstr "Geschrieben von %s.\n"
+
+#~ msgid "FILE"
+#~ msgstr "DATEI"
+
+#~ msgid "Start a group."
+#~ msgstr "Eine Gruppe starten."
+
+#~ msgid "End a group."
+#~ msgstr "Eine Gruppe beenden."
+
+#~ msgid "PATH"
+#~ msgstr "PFAD"
+
+#~ msgid "Same as --whole-archive."
+#~ msgstr "Genau wie --whole-archive."
+
+#~ msgid "ADDRESS"
+#~ msgstr "ADRESSE"
+
+#~ msgid "[FILE]..."
+#~ msgstr "[DATEI]..."
+
+#~ msgid "At least one input file needed"
+#~ msgstr "Mindestens eine Eingabedatei benötigt"
+
+#~ msgid "-( without matching -)"
+#~ msgstr "-( ohne Übereinstimmung -)"
+
+#~ msgid "only one option of -G and -r is allowed"
+#~ msgstr "nur eine Option aus -G und -r erlaubt"
+
+#~ msgid "More than one output file name given."
+#~ msgstr "Mehr als ein Name der Ausgabedatei angegeben."
+
+#~ msgid "-) without matching -("
+#~ msgstr "-) ohne Übereinstimmung -("
+
+#~ msgid "unknown option '-%c %s'"
+#~ msgstr "unbekannte Option '-%c %s'"
+
+#~ msgid "undefined symbol `%s' in %s"
+#~ msgstr "undefiniertes Symbol `%s' in %s"
+
+#~ msgid "cannot create versioning section: %s"
+#~ msgstr "konnte Versionierungsabschnitt nicht erstellen: %s"
+
+#~ msgid "cannot create versioning data: %s"
+#~ msgstr "konnte Versionierungsdaten nicht erstellen: %s"
+
+#~ msgid "cannot create program header: %s"
+#~ msgstr "konnte Programm-Kopf nicht erstellen: %s"
+
+#~ msgid "default visibility set as local and global"
+#~ msgstr "Standard-Sichtbarkeit auf lokal und global gesetzt"
+
+#, fuzzy
+#~ msgid "cannot attach to core"
+#~ msgstr "Kann Suchbaum nicht erstellen"
+
+#~ msgid "unknown tag %hx"
+#~ msgstr "unbekannter Tag %hx"
+
+#~ msgid "unknown user tag %hx"
+#~ msgstr "unbekannter Benutzer-Tag %hx"
+
+#~ msgid "unknown attribute %hx"
+#~ msgstr "unbekanntes Attribut %hx"
+
+#~ msgid "unknown user attribute %hx"
+#~ msgstr "unbekanntes Benutzer-Attribut %hx"
+
+#, fuzzy
+#~ msgid "unknown form %#<PRIx64>"
+#~ msgstr "unbekannte Form %<PRIx64>"
+
+#~ msgid ""
+#~ "\n"
+#~ "\n"
+#~ "Symbols from %s[%s]:\n"
+#~ "\n"
+#~ msgstr ""
+#~ "\n"
+#~ "\n"
+#~ "Symbole aus %s[%s]:\n"
+#~ "\n"
+
+#~ msgid "Equivalent to: -e -h -l"
+#~ msgstr "Entspricht: -e -h -l"
diff --git a/third_party/elfutils/po/en@boldquot.header b/third_party/elfutils/po/en@boldquot.header
new file mode 100644
index 0000000..fedb6a0
--- /dev/null
+++ b/third_party/elfutils/po/en@boldquot.header
@@ -0,0 +1,25 @@
+# All this catalog "translates" are quotation characters.
+# The msgids must be ASCII and therefore cannot contain real quotation
+# characters, only substitutes like grave accent (0x60), apostrophe (0x27)
+# and double quote (0x22). These substitutes look strange; see
+# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
+#
+# This catalog translates grave accent (0x60) and apostrophe (0x27) to
+# left single quotation mark (U+2018) and right single quotation mark (U+2019).
+# It also translates pairs of apostrophe (0x27) to
+# left single quotation mark (U+2018) and right single quotation mark (U+2019)
+# and pairs of quotation mark (0x22) to
+# left double quotation mark (U+201C) and right double quotation mark (U+201D).
+#
+# When output to an UTF-8 terminal, the quotation characters appear perfectly.
+# When output to an ISO-8859-1 terminal, the single quotation marks are
+# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to
+# grave/acute accent (by libiconv), and the double quotation marks are
+# transliterated to 0x22.
+# When output to an ASCII terminal, the single quotation marks are
+# transliterated to apostrophes, and the double quotation marks are
+# transliterated to 0x22.
+#
+# This catalog furthermore displays the text between the quotation marks in
+# bold face, assuming the VT100/XTerm escape sequences.
+#
diff --git a/third_party/elfutils/po/en@quot.header b/third_party/elfutils/po/en@quot.header
new file mode 100644
index 0000000..a9647fc
--- /dev/null
+++ b/third_party/elfutils/po/en@quot.header
@@ -0,0 +1,22 @@
+# All this catalog "translates" are quotation characters.
+# The msgids must be ASCII and therefore cannot contain real quotation
+# characters, only substitutes like grave accent (0x60), apostrophe (0x27)
+# and double quote (0x22). These substitutes look strange; see
+# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html
+#
+# This catalog translates grave accent (0x60) and apostrophe (0x27) to
+# left single quotation mark (U+2018) and right single quotation mark (U+2019).
+# It also translates pairs of apostrophe (0x27) to
+# left single quotation mark (U+2018) and right single quotation mark (U+2019)
+# and pairs of quotation mark (0x22) to
+# left double quotation mark (U+201C) and right double quotation mark (U+201D).
+#
+# When output to an UTF-8 terminal, the quotation characters appear perfectly.
+# When output to an ISO-8859-1 terminal, the single quotation marks are
+# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to
+# grave/acute accent (by libiconv), and the double quotation marks are
+# transliterated to 0x22.
+# When output to an ASCII terminal, the single quotation marks are
+# transliterated to apostrophes, and the double quotation marks are
+# transliterated to 0x22.
+#
diff --git a/third_party/elfutils/po/es.po b/third_party/elfutils/po/es.po
new file mode 100644
index 0000000..0aa9301
--- /dev/null
+++ b/third_party/elfutils/po/es.po
@@ -0,0 +1,7296 @@
+# Fedora Spanish Translation of elfutils.master.
+# This file is distributed under the same license as the elfutils.master package.
+#
+# Domingo Becker <domingobecker@gmail.com>, 2009.
+# Gladys Guerrero Lozano <gguerrer@redhat.com>, 2009.
+# Héctor Daniel Cabrera <logan@fedoraproject.org>, 2009, 2010.
+# Claudio Rodrigo Pereyra Diaz <claudio@pereyradiaz.com.ar>, 2010.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: elfutils.master.es\n"
+"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n"
+"POT-Creation-Date: 2017-09-01 12:27+0200\n"
+"PO-Revision-Date: 2011-01-10 15:17-0300\n"
+"Last-Translator: Claudio Rodrigo Pereyra Diaz <claudiorodrigo@pereyradiaz."
+"com.ar>\n"
+"Language-Team: Fedora Spanish <trans-es@lists.fedoraproject.org>\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Spanish\n"
+"X-Generator: Lokalize 1.0\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Poedit-Country: ARGENTINA\n"
+
+#: lib/color.c:53
+msgid ""
+"colorize the output.  WHEN defaults to 'always' or can be 'auto' or 'never'"
+msgstr ""
+
+#: lib/color.c:127
+#, c-format
+msgid ""
+"%s: invalid argument '%s' for '--color'\n"
+"valid arguments are:\n"
+"  - 'always', 'yes', 'force'\n"
+"  - 'never', 'no', 'none'\n"
+"  - 'auto', 'tty', 'if-tty'\n"
+msgstr ""
+
+#: lib/color.c:190 src/objdump.c:727
+#, fuzzy, c-format
+msgid "cannot allocate memory"
+msgstr "No se puede asignar sección PLT: %s"
+
+#: lib/printversion.c:40
+#, fuzzy, c-format
+msgid ""
+"Copyright (C) %s The elfutils developers <%s>.\n"
+"This is free software; see the source for copying conditions.  There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+"Copyright (C) %s Red Hat, Inc.\n"
+"El siguiente es un software libre; consulte el código para conocer las "
+"condiciones de copiado. NO tiene\n"
+"garantía, ni siquiera para SU COMERCIALIZACIÓN o PARA SER USADO CON UN FIN "
+"DETERMINADO.\n"
+
+#: lib/xmalloc.c:53 lib/xmalloc.c:66 lib/xmalloc.c:78 src/readelf.c:3310
+#: src/readelf.c:3701 src/readelf.c:8540 src/unstrip.c:2227 src/unstrip.c:2433
+#, c-format
+msgid "memory exhausted"
+msgstr "memoria agotada"
+
+#: libasm/asm_error.c:65 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:50
+#: libelf/elf_error.c:60
+msgid "no error"
+msgstr "ningún error"
+
+#: libasm/asm_error.c:66 libdw/dwarf_error.c:68 libdwfl/libdwflP.h:52
+#: libelf/elf_error.c:91
+msgid "out of memory"
+msgstr "memoria agotada"
+
+#: libasm/asm_error.c:67
+msgid "cannot create output file"
+msgstr "no se puede crear el archivo de salida"
+
+#: libasm/asm_error.c:68
+msgid "invalid parameter"
+msgstr "Parámetro inválido"
+
+#: libasm/asm_error.c:69
+msgid "cannot change mode of output file"
+msgstr "no sepuede cambiar modo de archivo de salida"
+
+#: libasm/asm_error.c:70
+msgid "cannot rename output file"
+msgstr "no se puede renombrar el archivo de salida"
+
+#: libasm/asm_error.c:71
+msgid "duplicate symbol"
+msgstr "Duplicar símbolo"
+
+#: libasm/asm_error.c:72
+msgid "invalid section type for operation"
+msgstr "tipo de sección inválido para operación"
+
+#: libasm/asm_error.c:73
+msgid "error during output of data"
+msgstr "error durante salida de datos"
+
+#: libasm/asm_error.c:74
+msgid "no backend support available"
+msgstr "No hay soporte de segundo plano"
+
+#: libasm/asm_error.c:83 libdw/dwarf_error.c:59 libdwfl/libdwflP.h:51
+#: libelf/elf_error.c:63
+msgid "unknown error"
+msgstr "error desconocido"
+
+#: libdw/dwarf_error.c:60
+msgid "invalid access"
+msgstr "Acceso inválido"
+
+#: libdw/dwarf_error.c:61
+msgid "no regular file"
+msgstr "no es un archivo regular"
+
+#: libdw/dwarf_error.c:62
+msgid "I/O error"
+msgstr "Error de E/S"
+
+#: libdw/dwarf_error.c:63
+msgid "invalid ELF file"
+msgstr "Archivo ELF inválido"
+
+#: libdw/dwarf_error.c:64
+msgid "no DWARF information"
+msgstr "Sin información de DWARF"
+
+#: libdw/dwarf_error.c:65
+msgid "cannot decompress DWARF"
+msgstr ""
+
+#: libdw/dwarf_error.c:66
+msgid "no ELF file"
+msgstr "No hay archivo ELF"
+
+#: libdw/dwarf_error.c:67
+msgid "cannot get ELF header"
+msgstr "no se puede obtener el encabezamiento ELF"
+
+#: libdw/dwarf_error.c:69
+msgid "not implemented"
+msgstr "sin implementar"
+
+#: libdw/dwarf_error.c:70 libelf/elf_error.c:107 libelf/elf_error.c:155
+msgid "invalid command"
+msgstr "comando inválido"
+
+#: libdw/dwarf_error.c:71
+msgid "invalid version"
+msgstr "versión inválida"
+
+#: libdw/dwarf_error.c:72
+msgid "invalid file"
+msgstr "Archivo inválido"
+
+#: libdw/dwarf_error.c:73
+msgid "no entries found"
+msgstr "No se hallaron entradas"
+
+#: libdw/dwarf_error.c:74
+msgid "invalid DWARF"
+msgstr "DWARF inválido"
+
+#: libdw/dwarf_error.c:75
+msgid "no string data"
+msgstr "no hay datos de cadena"
+
+#: libdw/dwarf_error.c:76
+msgid "no address value"
+msgstr "no hay valor de dirección"
+
+#: libdw/dwarf_error.c:77
+msgid "no constant value"
+msgstr "no hay valor constante"
+
+#: libdw/dwarf_error.c:78
+msgid "no reference value"
+msgstr "no hay valor de referencia"
+
+#: libdw/dwarf_error.c:79
+msgid "invalid reference value"
+msgstr "valor de la referencia inválido"
+
+#: libdw/dwarf_error.c:80
+msgid ".debug_line section missing"
+msgstr ".debug_line section faltante"
+
+#: libdw/dwarf_error.c:81
+msgid "invalid .debug_line section"
+msgstr ".debug_line section inválida"
+
+#: libdw/dwarf_error.c:82
+msgid "debug information too big"
+msgstr "información de depuración muy grande"
+
+#: libdw/dwarf_error.c:83
+msgid "invalid DWARF version"
+msgstr "versión DWARF inválida"
+
+#: libdw/dwarf_error.c:84
+msgid "invalid directory index"
+msgstr "Índice de directorio inválido"
+
+#: libdw/dwarf_error.c:85 libdwfl/libdwflP.h:71
+msgid "address out of range"
+msgstr "dirección fuera de rango"
+
+#: libdw/dwarf_error.c:86
+msgid "no location list value"
+msgstr "valor de lista sin ubicación"
+
+#: libdw/dwarf_error.c:87
+msgid "no block data"
+msgstr "sin datos de bloque "
+
+#: libdw/dwarf_error.c:88
+msgid "invalid line index"
+msgstr "Índice de línea inválido"
+
+#: libdw/dwarf_error.c:89
+msgid "invalid address range index"
+msgstr "Índice de dirección de rango inválido"
+
+#: libdw/dwarf_error.c:90 libdwfl/libdwflP.h:72
+msgid "no matching address range"
+msgstr "dirección de rango no coincidente"
+
+#: libdw/dwarf_error.c:91
+msgid "no flag value"
+msgstr "sin valor de bandera"
+
+#: libdw/dwarf_error.c:92 libelf/elf_error.c:232
+msgid "invalid offset"
+msgstr "desplazamiento inválido"
+
+#: libdw/dwarf_error.c:93
+msgid ".debug_ranges section missing"
+msgstr ".debug_ranges section faltante"
+
+#: libdw/dwarf_error.c:94
+msgid "invalid CFI section"
+msgstr "sección CFI inválida"
+
+#: libdw/dwarf_error.c:95
+msgid "no alternative debug link found"
+msgstr ""
+
+#: libdw/dwarf_error.c:96
+#, fuzzy
+msgid "invalid opcode"
+msgstr "operando inválido"
+
+#: libdw/dwarf_error.c:97
+msgid "not a CU (unit) DIE"
+msgstr ""
+
+#: libdw/dwarf_error.c:98
+#, fuzzy
+msgid "unknown language code"
+msgstr "código operativo desconocido "
+
+#: libdwfl/argp-std.c:50 src/stack.c:639 src/unstrip.c:2374
+msgid "Input selection options:"
+msgstr "Opciones de selección de entrada:"
+
+#: libdwfl/argp-std.c:51
+msgid "Find addresses in FILE"
+msgstr "Hallar direcciones en FICHERO"
+
+#: libdwfl/argp-std.c:53
+msgid "Find addresses from signatures found in COREFILE"
+msgstr "Buscar direcciones desde firmas encontradas en COREFILE"
+
+#: libdwfl/argp-std.c:55
+msgid "Find addresses in files mapped into process PID"
+msgstr "Busca direcciones en archivos mapeados sobre procesos PID"
+
+#: libdwfl/argp-std.c:57
+msgid ""
+"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps "
+"format"
+msgstr ""
+"Busca direcciones en archivos asignados como leídos desde FILE en formato "
+"Linux /proc/PID/maps"
+
+#: libdwfl/argp-std.c:59
+msgid "Find addresses in the running kernel"
+msgstr "Busca direcciones en el kernel que está ejecutándose"
+
+#: libdwfl/argp-std.c:61
+msgid "Kernel with all modules"
+msgstr "Kernel con todos los módulos"
+
+#: libdwfl/argp-std.c:63 src/stack.c:646
+msgid "Search path for separate debuginfo files"
+msgstr "Ruta de búsqueda para archivos debugingfo independientes"
+
+#: libdwfl/argp-std.c:164
+msgid "only one of -e, -p, -k, -K, or --core allowed"
+msgstr "Sólo uno de -e, -p, -k, -K, ó --core está permitido"
+
+#: libdwfl/argp-std.c:237
+msgid "cannot load kernel symbols"
+msgstr "No se pueden cargar símbolos de kernel"
+
+#. Non-fatal to have no modules since we do have the kernel.
+#: libdwfl/argp-std.c:241
+msgid "cannot find kernel modules"
+msgstr "no se pueden hallar módulos de kernel"
+
+#: libdwfl/argp-std.c:258
+msgid "cannot find kernel or modules"
+msgstr "imposible encontrar kernel o módulos"
+
+#: libdwfl/argp-std.c:297
+#, c-format
+msgid "cannot read ELF core file: %s"
+msgstr "No se puede leer archivo core ELF: %s"
+
+#: libdwfl/argp-std.c:320
+#, fuzzy
+msgid "Not enough memory"
+msgstr "memoria agotada"
+
+#: libdwfl/argp-std.c:330
+msgid "No modules recognized in core file"
+msgstr "No hay módulos reconocidos en el archivo core"
+
+#: libdwfl/libdwflP.h:53
+msgid "See errno"
+msgstr "Ve errno"
+
+#: libdwfl/libdwflP.h:54
+msgid "See elf_errno"
+msgstr "Ver elf_errno"
+
+#: libdwfl/libdwflP.h:55
+msgid "See dwarf_errno"
+msgstr "Ver dwarf_errno"
+
+#: libdwfl/libdwflP.h:56
+msgid "See ebl_errno (XXX missing)"
+msgstr "Ver ebl_errno (no se encuentra XXX)"
+
+#: libdwfl/libdwflP.h:57
+msgid "gzip decompression failed"
+msgstr "falló la descompresión gzip"
+
+#: libdwfl/libdwflP.h:58
+msgid "bzip2 decompression failed"
+msgstr "falló la descompresión bzip2"
+
+#: libdwfl/libdwflP.h:59
+msgid "LZMA decompression failed"
+msgstr "falló la descompresión LZMA"
+
+#: libdwfl/libdwflP.h:60
+msgid "no support library found for machine"
+msgstr "no se ha encontrado una biblioteca de soporte para la máquina"
+
+#: libdwfl/libdwflP.h:61
+msgid "Callbacks missing for ET_REL file"
+msgstr "No se encuentran rellamadas para el archivo ET_REL"
+
+#: libdwfl/libdwflP.h:62
+msgid "Unsupported relocation type"
+msgstr "Tipo de reubicación no soportada"
+
+#: libdwfl/libdwflP.h:63
+msgid "r_offset is bogus"
+msgstr "r_offset se encuentra inutilizable"
+
+#: libdwfl/libdwflP.h:64 libelf/elf_error.c:111 libelf/elf_error.c:171
+msgid "offset out of range"
+msgstr "desplazamiento fuera de rango"
+
+#: libdwfl/libdwflP.h:65
+msgid "relocation refers to undefined symbol"
+msgstr "la reubicación hace referencia a un símbolo no definido"
+
+#: libdwfl/libdwflP.h:66
+msgid "Callback returned failure"
+msgstr "La rellamada devolvió un fallo"
+
+#: libdwfl/libdwflP.h:67
+msgid "No DWARF information found"
+msgstr "No se ha encontrado una información DWARF"
+
+#: libdwfl/libdwflP.h:68
+msgid "No symbol table found"
+msgstr "No se ha encontrado una tabla simbólica"
+
+#: libdwfl/libdwflP.h:69
+msgid "No ELF program headers"
+msgstr "No existen encabezados de programa ELF"
+
+#: libdwfl/libdwflP.h:70
+msgid "address range overlaps an existing module"
+msgstr "el rango de dirección se superpone con un módulo existente"
+
+#: libdwfl/libdwflP.h:73
+msgid "image truncated"
+msgstr "imagen truncada"
+
+#: libdwfl/libdwflP.h:74
+msgid "ELF file opened"
+msgstr "Archivo ELF abierto"
+
+#: libdwfl/libdwflP.h:75
+msgid "not a valid ELF file"
+msgstr "no es un archivo ELF válido"
+
+#: libdwfl/libdwflP.h:76
+msgid "cannot handle DWARF type description"
+msgstr "no es posible manipular tipo de descripción DWARF"
+
+#: libdwfl/libdwflP.h:77
+msgid "ELF file does not match build ID"
+msgstr "El archivo ELF no coincide con el ID construido"
+
+#: libdwfl/libdwflP.h:78
+#, fuzzy
+msgid "corrupt .gnu.prelink_undo section data"
+msgstr "no se puede leer sección '.gnu.prelink_undo': %s"
+
+#: libdwfl/libdwflP.h:79
+msgid "Internal error due to ebl"
+msgstr ""
+
+#: libdwfl/libdwflP.h:80
+msgid "Missing data in core file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:81
+#, fuzzy
+msgid "Invalid register"
+msgstr "Parámetro inválido"
+
+#: libdwfl/libdwflP.h:82
+msgid "Error reading process memory"
+msgstr ""
+
+#: libdwfl/libdwflP.h:83
+msgid "Couldn't find architecture of any ELF"
+msgstr ""
+
+#: libdwfl/libdwflP.h:84
+msgid "Error parsing /proc filesystem"
+msgstr ""
+
+#: libdwfl/libdwflP.h:85
+#, fuzzy
+msgid "Invalid DWARF"
+msgstr "DWARF inválido"
+
+#: libdwfl/libdwflP.h:86
+msgid "Unsupported DWARF"
+msgstr ""
+
+#: libdwfl/libdwflP.h:87
+msgid "Unable to find more threads"
+msgstr ""
+
+#: libdwfl/libdwflP.h:88
+msgid "Dwfl already has attached state"
+msgstr ""
+
+#: libdwfl/libdwflP.h:89
+msgid "Dwfl has no attached state"
+msgstr ""
+
+#: libdwfl/libdwflP.h:90
+msgid "Unwinding not supported for this architecture"
+msgstr ""
+
+#: libdwfl/libdwflP.h:91
+#, fuzzy
+msgid "Invalid argument"
+msgstr "Parámetro inválido"
+
+#: libdwfl/libdwflP.h:92
+#, fuzzy
+msgid "Not an ET_CORE ELF file"
+msgstr "no es un archivo ELF válido"
+
+#: libebl/eblbackendname.c:41
+msgid "No backend"
+msgstr "No hay segundo plano (Backend)"
+
+#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:76
+#: libebl/eblobjnotetypename.c:83 libebl/eblobjnotetypename.c:102
+#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83
+#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:79
+msgid "<unknown>"
+msgstr "<desconocido>"
+
+#: libebl/ebldynamictagname.c:101
+#, c-format
+msgid "<unknown>: %#<PRIx64>"
+msgstr "<desconocido>: %#<PRIx64>"
+
+#: libebl/eblobjnote.c:53
+#, fuzzy, c-format
+msgid "unknown SDT version %u\n"
+msgstr "versión desconocida"
+
+#: libebl/eblobjnote.c:71
+#, fuzzy, c-format
+msgid "invalid SDT probe descriptor\n"
+msgstr "descriptor de archivo inválido"
+
+#: libebl/eblobjnote.c:121
+#, c-format
+msgid "    PC: "
+msgstr ""
+
+#: libebl/eblobjnote.c:123
+#, c-format
+msgid " Base: "
+msgstr ""
+
+#: libebl/eblobjnote.c:125
+#, c-format
+msgid " Semaphore: "
+msgstr ""
+
+#: libebl/eblobjnote.c:127
+#, c-format
+msgid "    Provider: "
+msgstr ""
+
+#: libebl/eblobjnote.c:129
+#, c-format
+msgid " Name: "
+msgstr ""
+
+#: libebl/eblobjnote.c:131
+#, c-format
+msgid " Args: "
+msgstr ""
+
+#: libebl/eblobjnote.c:141
+#, c-format
+msgid "    Build ID: "
+msgstr "    Build ID: "
+
+#. A non-null terminated version string.
+#: libebl/eblobjnote.c:152
+#, c-format
+msgid "    Linker version: %.*s\n"
+msgstr "    Versión del Enlazador: %.*s\n"
+
+#: libebl/eblobjnote.c:213
+#, c-format
+msgid "    OS: %s, ABI: "
+msgstr "    OS: %s, ABI: "
+
+#: libebl/eblosabiname.c:70
+msgid "Stand alone"
+msgstr "Autónomo"
+
+#: libebl/eblsymbolbindingname.c:67 libebl/eblsymboltypename.c:73
+#, c-format
+msgid "<unknown>: %d"
+msgstr "<desconocido>: %d"
+
+#: libelf/elf_error.c:67
+msgid "unknown version"
+msgstr "versión desconocida"
+
+#: libelf/elf_error.c:71
+msgid "unknown type"
+msgstr "tipo desconocido"
+
+#: libelf/elf_error.c:75
+msgid "invalid `Elf' handle"
+msgstr "manejo`ELF' inválido"
+
+#: libelf/elf_error.c:79
+msgid "invalid size of source operand"
+msgstr "tamaño inválido del operando fuente"
+
+#: libelf/elf_error.c:83
+msgid "invalid size of destination operand"
+msgstr "tamaño inválido del operando destino"
+
+#: libelf/elf_error.c:87 src/readelf.c:5153
+#, c-format
+msgid "invalid encoding"
+msgstr "codificación inválida"
+
+#: libelf/elf_error.c:95
+msgid "invalid file descriptor"
+msgstr "descriptor de archivo inválido"
+
+#: libelf/elf_error.c:99
+msgid "invalid operation"
+msgstr "operación inválida"
+
+#: libelf/elf_error.c:103
+msgid "ELF version not set"
+msgstr "no se estableció la versión de ELF"
+
+#: libelf/elf_error.c:115
+msgid "invalid fmag field in archive header"
+msgstr "campo fmag no válido en el encabezamiento del archivo"
+
+#: libelf/elf_error.c:119
+msgid "invalid archive file"
+msgstr "fichero de archivo inválido"
+
+#: libelf/elf_error.c:123
+msgid "descriptor is not for an archive"
+msgstr "el descriptor no es de un archivo"
+
+#: libelf/elf_error.c:127
+msgid "no index available"
+msgstr "no hay índice disponible"
+
+#: libelf/elf_error.c:131
+msgid "cannot read data from file"
+msgstr "no se pueden leer los datos del archivo"
+
+#: libelf/elf_error.c:135
+msgid "cannot write data to file"
+msgstr "no se puede escribir los datos al archivo"
+
+#: libelf/elf_error.c:139
+msgid "invalid binary class"
+msgstr "clase de binario inválida"
+
+#: libelf/elf_error.c:143
+msgid "invalid section index"
+msgstr "índice de sección inválido"
+
+#: libelf/elf_error.c:147
+msgid "invalid operand"
+msgstr "operando inválido"
+
+#: libelf/elf_error.c:151
+msgid "invalid section"
+msgstr "sección inválida"
+
+#: libelf/elf_error.c:159
+msgid "executable header not created first"
+msgstr "no se ha creado primero el encabezamiento ejecutable"
+
+#: libelf/elf_error.c:163
+msgid "file descriptor disabled"
+msgstr "descriptor de archivo inhabilitada"
+
+#: libelf/elf_error.c:167
+msgid "archive/member file descriptor mismatch"
+msgstr "archivo/miembro no coincide el descriptor de archivos"
+
+#: libelf/elf_error.c:175
+msgid "cannot manipulate null section"
+msgstr "no se pudo manipular una sección nula"
+
+#: libelf/elf_error.c:179
+msgid "data/scn mismatch"
+msgstr "no coinciden los datos/scn"
+
+#: libelf/elf_error.c:183
+msgid "invalid section header"
+msgstr "encabezamiento de sección inválida"
+
+#: libelf/elf_error.c:187 src/readelf.c:7403 src/readelf.c:7914
+#: src/readelf.c:8015 src/readelf.c:8196
+#, c-format
+msgid "invalid data"
+msgstr "datos inválidos"
+
+#: libelf/elf_error.c:191
+msgid "unknown data encoding"
+msgstr "codificación de caracteres desconocida"
+
+#: libelf/elf_error.c:195
+msgid "section `sh_size' too small for data"
+msgstr "el tamaño de la sección `sh_size' es demasiado pequeño para los datos "
+
+#: libelf/elf_error.c:199
+msgid "invalid section alignment"
+msgstr "alineación de la sección inválida"
+
+#: libelf/elf_error.c:203
+msgid "invalid section entry size"
+msgstr "tamaño de la entrada de la sección inválida"
+
+#: libelf/elf_error.c:207
+msgid "update() for write on read-only file"
+msgstr "update() para escribir sobre archivo de sólo lectura"
+
+#: libelf/elf_error.c:211
+msgid "no such file"
+msgstr "no hay tal archivo"
+
+#: libelf/elf_error.c:215
+msgid "only relocatable files can contain section groups"
+msgstr "solo los archivos reubicables pueden contener grupos de sección"
+
+#: libelf/elf_error.c:220
+msgid ""
+"program header only allowed in executables, shared objects, and core files"
+msgstr ""
+"los encabezamientos de los programas solo son permitidos en archivos "
+"ejecutables, archivos principales, u objetos compartidos"
+
+#: libelf/elf_error.c:227
+msgid "file has no program header"
+msgstr "el archivo no tiene encabezamiento de programa"
+
+#: libelf/elf_error.c:237
+#, fuzzy
+msgid "invalid section type"
+msgstr "sección inválida"
+
+#: libelf/elf_error.c:242
+#, fuzzy
+msgid "invalid section flags"
+msgstr "sección inválida"
+
+#: libelf/elf_error.c:247
+#, fuzzy
+msgid "section does not contain compressed data"
+msgstr "sección [%2zu] '%s' no debe ser ejecutable\n"
+
+#: libelf/elf_error.c:252
+msgid "section contains compressed data"
+msgstr ""
+
+#: libelf/elf_error.c:257
+#, fuzzy
+msgid "unknown compression type"
+msgstr "tipo desconocido"
+
+#: libelf/elf_error.c:262
+#, fuzzy
+msgid "cannot compress data"
+msgstr "no pueden copiar datos de sección: %s"
+
+#: libelf/elf_error.c:267
+#, fuzzy
+msgid "cannot decompress data"
+msgstr "no pueden copiar datos de sección: %s"
+
+#: src/addr2line.c:58
+#, fuzzy
+msgid "Input format options:"
+msgstr "Opciones de selección de entrada:"
+
+#: src/addr2line.c:60
+msgid "Treat addresses as offsets relative to NAME section."
+msgstr "Manejar direcciones como compensaciones relativas a sección de NOMBRE."
+
+#: src/addr2line.c:62
+#, fuzzy
+msgid "Output format options:"
+msgstr "Formato de salida:"
+
+#: src/addr2line.c:63
+#, fuzzy
+msgid "Print address before each entry"
+msgstr "Imprimir nombre de archivo antes de cada cadena."
+
+#: src/addr2line.c:64
+msgid "Show only base names of source files"
+msgstr "Mostrar sólo nombres de base de ficheros fuente"
+
+#: src/addr2line.c:66
+msgid "Show absolute file names using compilation directory"
+msgstr ""
+"Mostrar nombres de fichero absolutos mediante directorio de compilación"
+
+#: src/addr2line.c:67
+msgid "Also show function names"
+msgstr "También mostrar nombres de función"
+
+#: src/addr2line.c:68
+msgid "Also show symbol or section names"
+msgstr "También mostrar símbolo o nombres de sección"
+
+#: src/addr2line.c:69
+#, fuzzy
+msgid "Also show symbol and the section names"
+msgstr "También mostrar símbolo o nombres de sección"
+
+#: src/addr2line.c:70
+msgid "Also show line table flags"
+msgstr "También mostrar marcas de líneas de tabla"
+
+#: src/addr2line.c:72
+msgid ""
+"Show all source locations that caused inline expansion of subroutines at the "
+"address."
+msgstr ""
+
+#: src/addr2line.c:75
+msgid "Show demangled symbols (ARG is always ignored)"
+msgstr ""
+
+#: src/addr2line.c:77
+msgid "Print all information on one line, and indent inlines"
+msgstr ""
+
+#: src/addr2line.c:79 src/elfcmp.c:71 src/findtextrel.c:66 src/nm.c:101
+#: src/strings.c:79
+msgid "Miscellaneous:"
+msgstr "Misceláneos:"
+
+#. Short description of program.
+#: src/addr2line.c:87
+msgid ""
+"Locate source files and line information for ADDRs (in a.out by default)."
+msgstr ""
+"Localizar archivos fuente e información de línea para DIRECCIONES (en a.out "
+"por defecto)."
+
+#. Strings for arguments in help texts.
+#: src/addr2line.c:91
+msgid "[ADDR...]"
+msgstr "[DIREC...]"
+
+#: src/addr2line.c:519
+#, c-format
+msgid "Section syntax requires exactly one module"
+msgstr "Sintaxis de sección requiere exactamente un módulo"
+
+#: src/addr2line.c:542
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside section '%s'"
+msgstr "Compensación %#<PRIxMAX> se encuentra fuera de sección '%s'"
+
+#: src/addr2line.c:632
+#, c-format
+msgid "cannot find symbol '%s'"
+msgstr "no se puede encontrar símbolo '%s'"
+
+#: src/addr2line.c:637
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside contents of '%s'"
+msgstr "compensación %#<PRIxMAX> se encuentra fuera de contenido de '%s'"
+
+#: src/ar.c:68
+msgid "Commands:"
+msgstr "Comandos:"
+
+#: src/ar.c:69
+msgid "Delete files from archive."
+msgstr "Borrar archivos de un archivo"
+
+#: src/ar.c:70
+msgid "Move files in archive."
+msgstr "Desplazar ficheros en archivo."
+
+#: src/ar.c:71
+msgid "Print files in archive."
+msgstr "Imprimir ficheros en archivo."
+
+#: src/ar.c:72
+msgid "Quick append files to archive."
+msgstr "Adición rápida de ficheros para archivar"
+
+#: src/ar.c:74
+msgid "Replace existing or insert new file into archive."
+msgstr "Remplazar fichero existente o insertar uno nuevo en el archivo."
+
+#: src/ar.c:75
+msgid "Display content of archive."
+msgstr "Mostrar contenido de archivo"
+
+#: src/ar.c:76
+msgid "Extract files from archive."
+msgstr "extraer ficheros de un archivo"
+
+#: src/ar.c:78
+msgid "Command Modifiers:"
+msgstr "Modificadores de comandos:"
+
+#: src/ar.c:79
+msgid "Preserve original dates."
+msgstr "Preservar fechas originales."
+
+#: src/ar.c:80
+msgid "Use instance [COUNT] of name."
+msgstr "Usar instancia [COUNT] de nombre."
+
+#: src/ar.c:82
+msgid "Do not replace existing files with extracted files."
+msgstr "No remplazar los archivos existentes por los archivos extractados."
+
+#: src/ar.c:83
+msgid "Allow filename to be truncated if necessary."
+msgstr "Permitir truncamiento del nombre de archivo de ser necesario."
+
+#: src/ar.c:85
+msgid "Provide verbose output."
+msgstr "Proporcionar salida detallada"
+
+#: src/ar.c:86
+msgid "Force regeneration of symbol table."
+msgstr "Forzar regeneración de tabla de símbolos."
+
+#: src/ar.c:87
+msgid "Insert file after [MEMBER]."
+msgstr "Insertar archivo después de [MIEMBRO]."
+
+#: src/ar.c:88
+msgid "Insert file before [MEMBER]."
+msgstr "Introducir fichero antes de [MIEMBRO]."
+
+#: src/ar.c:89
+msgid "Same as -b."
+msgstr "Igual que -b."
+
+#: src/ar.c:90
+msgid "Suppress message when library has to be created."
+msgstr "Suprimir mensaje cuando se tenga que crear la biblioteca."
+
+#: src/ar.c:92
+msgid "Use full path for file matching."
+msgstr "Usar la ruta total para fichero coincidente."
+
+#: src/ar.c:93
+msgid "Update only older files in archive."
+msgstr "Actualizar sólo ficheros antiguos en archivo."
+
+#. Short description of program.
+#: src/ar.c:99
+msgid "Create, modify, and extract from archives."
+msgstr "Crear, modificar, y extraer de archivos."
+
+#. Strings for arguments in help texts.
+#: src/ar.c:102
+msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]"
+msgstr "[MIEMBRO] [CONTAR] ARCHIVO [FICHERO...]"
+
+#: src/ar.c:181
+#, c-format
+msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options"
+msgstr "'a', 'b', é 'i' sólo se permiten con las opciones 'm' y 'r'."
+
+#: src/ar.c:186
+#, c-format
+msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers"
+msgstr "Parámetro MIEMBRO requerido para modificadores 'a', 'b', e 'i'"
+
+#: src/ar.c:202
+#, c-format
+msgid "'N' is only meaningful with the 'x' and 'd' options"
+msgstr "'N' sólo es significativa con las opciones `x' y `d'."
+
+#: src/ar.c:207
+#, c-format
+msgid "COUNT parameter required"
+msgstr "Parámetro CONTAR requerido"
+
+#: src/ar.c:219
+#, c-format
+msgid "invalid COUNT parameter %s"
+msgstr "Parámetro CONTAR inválido %s"
+
+#: src/ar.c:226
+#, c-format
+msgid "'%c' is only meaningful with the 'x' option"
+msgstr "'%c' es sólo significativo con la opción 'x'"
+
+#: src/ar.c:232
+#, c-format
+msgid "archive name required"
+msgstr "nombre de archivo requerido"
+
+#: src/ar.c:245
+#, c-format
+msgid "command option required"
+msgstr ""
+
+#: src/ar.c:296
+#, c-format
+msgid "More than one operation specified"
+msgstr "Más de una operación especificada"
+
+#: src/ar.c:390
+#, c-format
+msgid "cannot open archive '%s'"
+msgstr "Imposible abrir el archivo '%s'"
+
+#: src/ar.c:400
+#, c-format
+msgid "cannot open archive '%s': %s"
+msgstr "Imposible abrir el archivo '%s': %s"
+
+#: src/ar.c:404
+#, c-format
+msgid "%s: not an archive file"
+msgstr "%s: no es un fichero de archivo"
+
+#: src/ar.c:408
+#, c-format
+msgid "cannot stat archive '%s'"
+msgstr "no sepuede stat el archivo '%s'"
+
+#: src/ar.c:420
+#, c-format
+msgid "no entry %s in archive\n"
+msgstr "no hay entrada %s en archivo\n"
+
+#: src/ar.c:473 src/ar.c:918 src/ar.c:1118
+#, c-format
+msgid "cannot create hash table"
+msgstr "Falló al crear la tabla de dispersión"
+
+#: src/ar.c:480 src/ar.c:925 src/ar.c:1127
+#, c-format
+msgid "cannot insert into hash table"
+msgstr "no sepuede insertar en tabla de dispersión"
+
+#: src/ar.c:488 src/ranlib.c:149
+#, c-format
+msgid "cannot stat '%s'"
+msgstr "no se puede stat '%s'"
+
+#: src/ar.c:584
+#, c-format
+msgid "cannot read content of %s: %s"
+msgstr "no se puede leer el contenido de %s: %s"
+
+#: src/ar.c:627
+#, c-format
+msgid "cannot open %.*s"
+msgstr " Imposible abrir %.*s"
+
+#: src/ar.c:649
+#, c-format
+msgid "failed to write %s"
+msgstr "Falló al escribir %s"
+
+#: src/ar.c:661
+#, c-format
+msgid "cannot change mode of %s"
+msgstr "No se puede cambiar el modo de %s"
+
+#: src/ar.c:677
+#, c-format
+msgid "cannot change modification time of %s"
+msgstr "No puede cambiar tiempo de modificación de %s"
+
+#: src/ar.c:723
+#, c-format
+msgid "cannot rename temporary file to %.*s"
+msgstr "no sepuede renombrar fichero temporal para %.*s"
+
+#: src/ar.c:759 src/ar.c:1010 src/ar.c:1409 src/ranlib.c:223
+#, c-format
+msgid "cannot create new file"
+msgstr "no sepuede crear fichero nuevo"
+
+#: src/ar.c:1209
+#, c-format
+msgid "position member %s not found"
+msgstr "no se encuentra miembro de posición %s "
+
+#: src/ar.c:1219
+#, c-format
+msgid "%s: no entry %s in archive!\n"
+msgstr "%s: ¡no hay entrada %s en archive!\n"
+
+#: src/ar.c:1248 src/objdump.c:242
+#, c-format
+msgid "cannot open %s"
+msgstr "no sepuede abrir %s"
+
+#: src/ar.c:1253
+#, c-format
+msgid "cannot stat %s"
+msgstr "no sepuede efectuar stat %s"
+
+#: src/ar.c:1259
+#, c-format
+msgid "%s is no regular file"
+msgstr " %s no es un fichero ordinario "
+
+#: src/ar.c:1272
+#, c-format
+msgid "cannot get ELF descriptor for %s: %s\n"
+msgstr "no sepuede obtener descriptor ELF para %s: %s\n"
+
+#: src/ar.c:1292
+#, c-format
+msgid "cannot read %s: %s"
+msgstr "no sepuede leer %s: %s"
+
+#: src/arlib-argp.c:32
+msgid "Use zero for uid, gid, and date in archive members."
+msgstr ""
+
+#: src/arlib-argp.c:34
+msgid "Use actual uid, gid, and date in archive members."
+msgstr ""
+
+#: src/arlib-argp.c:65
+#, c-format
+msgid "%s (default)"
+msgstr ""
+
+#. The archive is too big.
+#: src/arlib.c:213
+#, c-format
+msgid "the archive '%s' is too large"
+msgstr " El archivo '%s' es demasiado grande"
+
+#: src/arlib.c:226
+#, c-format
+msgid "cannot read ELF header of %s(%s): %s"
+msgstr "no se puede leer el encabezamiento ELF de %s(%s): %s"
+
+#: src/elfcmp.c:61
+msgid "Control options:"
+msgstr "Opciones de control:"
+
+#: src/elfcmp.c:63
+msgid "Output all differences, not just the first"
+msgstr ""
+
+#: src/elfcmp.c:64
+msgid ""
+"Control treatment of gaps in loadable segments [ignore|match] (default: "
+"ignore)"
+msgstr ""
+"Tratamiento de control de brechas en segmento cargables [ignorar|"
+"coincidencia] (por defecto: ignorar)"
+
+#: src/elfcmp.c:66
+msgid "Ignore permutation of buckets in SHT_HASH section"
+msgstr "Ignorar permutación de cubetas en sección SHT_HASH"
+
+#: src/elfcmp.c:68
+msgid "Ignore differences in build ID"
+msgstr ""
+
+#: src/elfcmp.c:69
+msgid "Output nothing; yield exit status only"
+msgstr "Nada de salida; producir estado de salida únicamente"
+
+#. Short description of program.
+#: src/elfcmp.c:76
+msgid "Compare relevant parts of two ELF files for equality."
+msgstr "Comparar partes relevantes de dos ficheros ELF para igualdad."
+
+#. Strings for arguments in help texts.
+#: src/elfcmp.c:80
+msgid "FILE1 FILE2"
+msgstr "FICHERO1 FICHERO2"
+
+#: src/elfcmp.c:142
+msgid "Invalid number of parameters.\n"
+msgstr "Número inválido de parámetros.\n"
+
+#: src/elfcmp.c:173 src/elfcmp.c:178
+#, c-format
+msgid "cannot get ELF header of '%s': %s"
+msgstr "no se puede obtener encabezamiento de '%s': %s"
+
+#: src/elfcmp.c:204
+#, c-format
+msgid "%s %s diff: ELF header"
+msgstr "%s %s diff: encabezamiento ELF"
+
+#: src/elfcmp.c:211 src/elfcmp.c:214
+#, c-format
+msgid "cannot get section count of '%s': %s"
+msgstr "no se puede obtener un conteo de sección en '%s': %s"
+
+#: src/elfcmp.c:219
+#, c-format
+msgid "%s %s diff: section count"
+msgstr "%s %s diff: conteo de sección"
+
+#: src/elfcmp.c:226 src/elfcmp.c:229
+#, c-format
+msgid "cannot get program header count of '%s': %s"
+msgstr "no se puede obtener un conteo de encabezado de programa de '%s': %s"
+
+#: src/elfcmp.c:234
+#, c-format
+msgid "%s %s diff: program header count"
+msgstr "%s %s diff: encabezado de programa"
+
+#: src/elfcmp.c:292
+#, fuzzy, c-format
+msgid "%s %s differ: section [%zu], [%zu] name"
+msgstr "%s %s differ: sección [%zu,%zu] contenido '%s'"
+
+#: src/elfcmp.c:315
+#, fuzzy, c-format
+msgid "%s %s differ: section [%zu] '%s' header"
+msgstr "%s %s differ: sección [%zu] contenido '%s'"
+
+#: src/elfcmp.c:323 src/elfcmp.c:329
+#, c-format
+msgid "cannot get content of section %zu in '%s': %s"
+msgstr "No se puede obtener contenido de sección %zu en '%s': %s"
+
+#: src/elfcmp.c:338
+#, fuzzy, c-format
+msgid "symbol table [%zu] in '%s' has zero sh_entsize"
+msgstr ""
+"\n"
+"La tabla de símbolos [%2u] '%s' contiene entrada %u:\n"
+
+#: src/elfcmp.c:350 src/elfcmp.c:356
+#, c-format
+msgid "cannot get symbol in '%s': %s"
+msgstr "No se puede obtener símbolo en '%s': %s"
+
+#: src/elfcmp.c:378
+#, c-format
+msgid "%s %s differ: symbol table [%zu]"
+msgstr "%s %s differ: tabla de símbolos [%zu]"
+
+#: src/elfcmp.c:381
+#, c-format
+msgid "%s %s differ: symbol table [%zu,%zu]"
+msgstr "%s %s differ: tabla de símbolos [%zu,%zu]"
+
+#: src/elfcmp.c:428 src/elfcmp.c:498
+#, fuzzy, c-format
+msgid "%s %s differ: section [%zu] '%s' number of notes"
+msgstr "%s %s differ: sección [%zu] contenido '%s'"
+
+#: src/elfcmp.c:436
+#, fuzzy, c-format
+msgid "cannot read note section [%zu] '%s' in '%s': %s"
+msgstr "No se puede obtener contenido de sección %zu en '%s': %s"
+
+#: src/elfcmp.c:447
+#, fuzzy, c-format
+msgid "%s %s differ: section [%zu] '%s' note name"
+msgstr "%s %s differ: sección [%zu] contenido '%s'"
+
+#: src/elfcmp.c:455
+#, fuzzy, c-format
+msgid "%s %s differ: section [%zu] '%s' note '%s' type"
+msgstr "%s %s differ: sección [%zu] contenido '%s'"
+
+#: src/elfcmp.c:470
+#, fuzzy, c-format
+msgid "%s %s differ: build ID length"
+msgstr "%s %s differ: brecha"
+
+#: src/elfcmp.c:478
+#, fuzzy, c-format
+msgid "%s %s differ: build ID content"
+msgstr "%s %s differ: sección [%zu] contenido '%s'"
+
+#: src/elfcmp.c:487
+#, fuzzy, c-format
+msgid "%s %s differ: section [%zu] '%s' note '%s' content"
+msgstr "%s %s differ: sección [%zu] contenido '%s'"
+
+#: src/elfcmp.c:528
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' content"
+msgstr "%s %s differ: sección [%zu] contenido '%s'"
+
+#: src/elfcmp.c:532
+#, c-format
+msgid "%s %s differ: section [%zu,%zu] '%s' content"
+msgstr "%s %s differ: sección [%zu,%zu] contenido '%s'"
+
+#: src/elfcmp.c:547
+#, c-format
+msgid "%s %s differ: unequal amount of important sections"
+msgstr "%s %s differ: cantidad desigual de secciones importantes"
+
+#: src/elfcmp.c:580 src/elfcmp.c:585
+#, c-format
+msgid "cannot load data of '%s': %s"
+msgstr "no se pueden cargar los datos de '%s': %s"
+
+#: src/elfcmp.c:604 src/elfcmp.c:610
+#, c-format
+msgid "cannot get program header entry %d of '%s': %s"
+msgstr ""
+"no se puede obtener entrada de encabezamiento de programa %d de '%s': %s"
+
+#: src/elfcmp.c:616
+#, c-format
+msgid "%s %s differ: program header %d"
+msgstr "%s %s differ: encabezamiento de programa %d"
+
+#: src/elfcmp.c:640
+#, c-format
+msgid "%s %s differ: gap"
+msgstr "%s %s differ: brecha"
+
+#: src/elfcmp.c:691
+#, c-format
+msgid "Invalid value '%s' for --gaps parameter."
+msgstr "Valor inválido '%s' para parámetro --gaps"
+
+#: src/elfcmp.c:719 src/findtextrel.c:206 src/nm.c:365 src/ranlib.c:142
+#: src/size.c:273 src/strings.c:186 src/strip.c:518 src/strip.c:555
+#: src/unstrip.c:2023 src/unstrip.c:2052
+#, c-format
+msgid "cannot open '%s'"
+msgstr "Imposible abrir '%s'"
+
+#: src/elfcmp.c:723 src/findtextrel.c:213 src/ranlib.c:159
+#, c-format
+msgid "cannot create ELF descriptor for '%s': %s"
+msgstr "No puede crear descriptor ELF para '%s': %s"
+
+#: src/elfcmp.c:728
+#, c-format
+msgid "cannot create EBL descriptor for '%s'"
+msgstr "no se puede crear el descriptor EBL para '%s'"
+
+#: src/elfcmp.c:746 src/findtextrel.c:394
+#, c-format
+msgid "cannot get section header of section %zu: %s"
+msgstr "No se puede obtener el encabezamiento de sección %zu: %s"
+
+#: src/elfcmp.c:756
+#, c-format
+msgid "cannot get content of section %zu: %s"
+msgstr "No se puede obtener contenido de sección %zu: %s"
+
+#: src/elfcmp.c:766 src/elfcmp.c:780
+#, c-format
+msgid "cannot get relocation: %s"
+msgstr "No se puede obtener reubicación: %s"
+
+#: src/elfcompress.c:115 src/strip.c:297 src/unstrip.c:121
+#, c-format
+msgid "-o option specified twice"
+msgstr "opción -o especificada dos veces"
+
+#: src/elfcompress.c:122
+#, fuzzy, c-format
+msgid "-t option specified twice"
+msgstr "opción -f especificada dos veces"
+
+#: src/elfcompress.c:131
+#, fuzzy, c-format
+msgid "unknown compression type '%s'"
+msgstr "tipo desconocido"
+
+#. We need at least one input file.
+#: src/elfcompress.c:143 src/elfcompress.c:1305
+#, fuzzy, c-format
+msgid "No input file given"
+msgstr "archivo de entrada vacío"
+
+#: src/elfcompress.c:149 src/elfcompress.c:1310
+#, fuzzy, c-format
+msgid "Only one input file allowed together with '-o'"
+msgstr "Sólo se permite ingresar un archivo junto con '-o' y '-f'"
+
+#: src/elfcompress.c:1267
+#, fuzzy
+msgid "Place (de)compressed output into FILE"
+msgstr "Colocar la salida obtenida en FICHERO"
+
+#: src/elfcompress.c:1270
+msgid ""
+"What type of compression to apply. TYPE can be 'none' (decompress), "
+"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-"
+"gnu' (.zdebug GNU style compression, 'gnu' is an alias)"
+msgstr ""
+
+#: src/elfcompress.c:1273
+msgid ""
+"SECTION name to (de)compress, SECTION is an extended wildcard pattern "
+"(defaults to '.?(z)debug*')"
+msgstr ""
+
+#: src/elfcompress.c:1276
+msgid "Print a message for each section being (de)compressed"
+msgstr ""
+
+#: src/elfcompress.c:1279
+msgid "Force compression of section even if it would become larger"
+msgstr ""
+
+#: src/elfcompress.c:1282 src/strip.c:91
+msgid "Relax a few rules to handle slightly broken ELF files"
+msgstr "Relaja algunas reglas para manejar ficheros ELF rotos"
+
+#: src/elfcompress.c:1285
+#, fuzzy
+msgid "Be silent when a section cannot be compressed"
+msgstr ""
+"Sección [%2zu] '%s': dirección de secciones de datos de hilo-local no cero\n"
+
+#. Strings for arguments in help texts.
+#: src/elfcompress.c:1294 src/elflint.c:78 src/readelf.c:142
+msgid "FILE..."
+msgstr "FICHERO..."
+
+#: src/elfcompress.c:1295
+msgid "Compress or decompress sections in an ELF file."
+msgstr ""
+
+#: src/elflint.c:64
+msgid "Be extremely strict, flag level 2 features."
+msgstr "Sea extremadamente estricto, característica de marca de nivel 2."
+
+#: src/elflint.c:65
+msgid "Do not print anything if successful"
+msgstr "No imprime nada si está correcto"
+
+#: src/elflint.c:66
+msgid "Binary is a separate debuginfo file"
+msgstr "Binario es un archivo debuginfo independiente"
+
+#: src/elflint.c:68
+msgid ""
+"Binary has been created with GNU ld and is therefore known to be broken in "
+"certain ways"
+msgstr ""
+"Binario ha sido creado con GNU Id y por lo tanto se sabe que puede estar "
+"roto de alguna forma"
+
+#. Short description of program.
+#: src/elflint.c:74
+msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
+msgstr "Chequeo minucioso de ficheros ELF de acuerdo con gABI/psABI "
+
+#: src/elflint.c:155 src/readelf.c:317
+#, c-format
+msgid "cannot open input file"
+msgstr "no se puede abrir el fichero de entrada"
+
+#: src/elflint.c:162
+#, c-format
+msgid "cannot generate Elf descriptor: %s\n"
+msgstr "no se puede crear descriptor ELF: %s\n"
+
+#: src/elflint.c:181
+#, c-format
+msgid "error while closing Elf descriptor: %s\n"
+msgstr "error al cerrar el descriptor ELF: %s\n"
+
+#: src/elflint.c:185
+msgid "No errors"
+msgstr "No hay errores"
+
+#: src/elflint.c:220 src/readelf.c:494
+msgid "Missing file name.\n"
+msgstr "Falta el nombre de archivo.\n"
+
+#: src/elflint.c:285
+#, c-format
+msgid " error while freeing sub-ELF descriptor: %s\n"
+msgstr " error al liberar descriptor sub-ELF: %s\n"
+
+#. We cannot do anything.
+#: src/elflint.c:293
+#, c-format
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr "No es un fichero ELF - tiene los bytes mágicos errados en el inicio\n"
+
+#: src/elflint.c:358
+#, c-format
+msgid "e_ident[%d] == %d is no known class\n"
+msgstr "e_ident[%d] == %d es una clase desconocida\n"
+
+#: src/elflint.c:363
+#, c-format
+msgid "e_ident[%d] == %d is no known data encoding\n"
+msgstr "e_ident[%d] == %d es una codificación de datos desconocida\n"
+
+#: src/elflint.c:367
+#, c-format
+msgid "unknown ELF header version number e_ident[%d] == %d\n"
+msgstr ""
+"número de versión de encabezamiento ELF desconocido e_ident[%d] == %d\n"
+
+#: src/elflint.c:375
+#, c-format
+msgid "unsupported OS ABI e_ident[%d] == '%s'\n"
+msgstr "Sistema operativo OS ABI e_ident[%d] == '%s' incompatible\n"
+
+#: src/elflint.c:381
+#, c-format
+msgid "unsupport ABI version e_ident[%d] == %d\n"
+msgstr "Versión incompatible ABI e_ident[%d] == %d\n"
+
+#: src/elflint.c:386
+#, c-format
+msgid "e_ident[%zu] is not zero\n"
+msgstr "e_ident[%zu] no es cero\n"
+
+#: src/elflint.c:391
+#, c-format
+msgid "unknown object file type %d\n"
+msgstr "tipo de fichero objeto desconocido %d\n"
+
+#: src/elflint.c:398
+#, c-format
+msgid "unknown machine type %d\n"
+msgstr "tipo de máquina desconocido %d\n"
+
+#: src/elflint.c:402
+#, c-format
+msgid "unknown object file version\n"
+msgstr "versión de fichero objeto desconocido\n"
+
+#: src/elflint.c:408
+#, c-format
+msgid "invalid program header offset\n"
+msgstr "Compensación de encabezamiento de programa inválida\n"
+
+#: src/elflint.c:410
+#, c-format
+msgid "executables and DSOs cannot have zero program header offset\n"
+msgstr ""
+"tanto los ejecutables como los DSO no pueden tener compensación de "
+"encabezamiento de programa cero\n"
+
+#: src/elflint.c:414
+#, c-format
+msgid "invalid number of program header entries\n"
+msgstr "cantidad no válida de entradas del encabezamiento del programa\n"
+
+#: src/elflint.c:422
+#, c-format
+msgid "invalid section header table offset\n"
+msgstr "compensación de sección de tabla de encabezamiento inválida\n"
+
+#: src/elflint.c:425
+#, c-format
+msgid "section header table must be present\n"
+msgstr "tabla de encabezamiento de sección debe estar presente\n"
+
+#: src/elflint.c:439
+#, c-format
+msgid "invalid number of section header table entries\n"
+msgstr ""
+"cantidad no válida de entradas en la tabla del encabezamiento de sección\n"
+
+#: src/elflint.c:456
+#, c-format
+msgid "invalid section header index\n"
+msgstr "Índice de sección de encabezamiento inválido\n"
+
+#: src/elflint.c:474
+#, c-format
+msgid "Can only check %u headers, shnum was %u\n"
+msgstr ""
+
+#: src/elflint.c:488
+#, c-format
+msgid "invalid number of program header table entries\n"
+msgstr "cantidad no válida de entradas de tabla de encabezado del programa\n"
+
+#: src/elflint.c:505
+#, c-format
+msgid "Can only check %u headers, phnum was %u\n"
+msgstr ""
+
+#: src/elflint.c:510
+#, c-format
+msgid "invalid machine flags: %s\n"
+msgstr "Indicadores de máquina inválidos: %s\n"
+
+#: src/elflint.c:517 src/elflint.c:534
+#, c-format
+msgid "invalid ELF header size: %hd\n"
+msgstr "tamaño inválido del encabezamiento ELF: %hd\n"
+
+#: src/elflint.c:520 src/elflint.c:537
+#, c-format
+msgid "invalid program header size: %hd\n"
+msgstr "tamaño inválido del encabezamiento del programa: %hd\n"
+
+#: src/elflint.c:523 src/elflint.c:540
+#, c-format
+msgid "invalid program header position or size\n"
+msgstr "tamaño o posición inválidos del encabezamiento del programa\n"
+
+#: src/elflint.c:526 src/elflint.c:543
+#, c-format
+msgid "invalid section header size: %hd\n"
+msgstr "tamaño inválido del encabezamiento de sección: %hd\n"
+
+#: src/elflint.c:529 src/elflint.c:546
+#, c-format
+msgid "invalid section header position or size\n"
+msgstr "tamaño o posición no válidos del encabezamiento de sección\n"
+
+#: src/elflint.c:591
+#, c-format
+msgid ""
+"section [%2d] '%s': section with SHF_GROUP flag set not part of a section "
+"group\n"
+msgstr ""
+"sección [%2d] '%s': sección con la bandera SHF_GROUP no es parte de una "
+"sección de grupo\n"
+
+#: src/elflint.c:595
+#, c-format
+msgid ""
+"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"
+msgstr ""
+"sección [%2d] '%s': el grupo de sección [%2zu] '%s' no precede al miembro de "
+"grupo\n"
+
+#: src/elflint.c:611 src/elflint.c:1495 src/elflint.c:1546 src/elflint.c:1652
+#: src/elflint.c:1988 src/elflint.c:2311 src/elflint.c:2930 src/elflint.c:3093
+#: src/elflint.c:3241 src/elflint.c:3431 src/elflint.c:4399
+#, c-format
+msgid "section [%2d] '%s': cannot get section data\n"
+msgstr "Sección [%2d] '%s': No se pueden obtener datos de sección\n"
+
+#: src/elflint.c:624 src/elflint.c:1659
+#, c-format
+msgid ""
+"section [%2d] '%s': referenced as string table for section [%2d] '%s' but "
+"type is not SHT_STRTAB\n"
+msgstr ""
+"sección [%2d] '%s': nombrado como una tabla de cadena para la sección [%2d] "
+"'%s' pero el tipo no es SHT_STRTAB\n"
+
+#: src/elflint.c:647
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol table cannot have more than one extended index "
+"section\n"
+msgstr ""
+"sección [%2d] '%s': la tabla de símbolo no puede tener más de una sección de "
+"índice extendido\n"
+
+#: src/elflint.c:659
+#, c-format
+msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n"
+msgstr ""
+"sección [%2u] '%s': el tamaño de la entrada no coincide con ElfXX_Sym\n"
+
+#: src/elflint.c:668
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %d: %s\n"
+msgstr "Sección [%2d] '%s': no se puede obtener símbolo %d: %s\n"
+
+#: src/elflint.c:673 src/elflint.c:676 src/elflint.c:679 src/elflint.c:682
+#: src/elflint.c:685 src/elflint.c:688
+#, c-format
+msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n"
+msgstr "Sección [%2d] '%s': '%s' en la entrada zeroth no es cero\n"
+
+#: src/elflint.c:691
+#, c-format
+msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n"
+msgstr "sección [%2d] '%s': XINDEX en la entrada zeroth no es cero\n"
+
+#: src/elflint.c:701
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %zu: %s\n"
+msgstr "sección [%2d] '%s': no es posible obtener el símbolo %zu: %s\n"
+
+#: src/elflint.c:710
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid name value\n"
+msgstr "sección [%2d] '%s': símbolo %zu: valor de nombre inválido\n"
+
+#: src/elflint.c:725
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: too large section index but no extended "
+"section index section\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: el índice de sección es demasiado extenso, "
+"pero no la sección extendida de la sección de índice\n"
+
+#: src/elflint.c:731
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in "
+"st_shndx (%<PRIu32>)\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: XINDEX es utilizado para índice que pueda "
+"caber en st_shndx (%<PRIu32>)\n"
+
+#. || sym->st_shndx > SHN_HIRESERVE  always false
+#: src/elflint.c:743
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid section index\n"
+msgstr "sección [%2d] '%s': símbolo %zu: índice de sección inválido\n"
+
+#: src/elflint.c:751
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown type\n"
+msgstr "sección [%2d] '%s': símbolo %zu: tipo desconocido\n"
+
+#: src/elflint.c:757
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown symbol binding\n"
+msgstr "sección [%2d] '%s': símbolo %zu: asociación de símbolo desconocida\n"
+
+#: src/elflint.c:762
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unique symbol not of object type\n"
+msgstr "Sección [%2d] '%s': símbolo %zu: símbolo único no de tipo de objeto\n"
+
+#: src/elflint.c:770
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"
+msgstr ""
+"sección [%2d] '%s': símbolo %zu: COMMON solo es permitido en archivos "
+"realojables\n"
+
+#: src/elflint.c:774
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: símbolos locales COMMON no tienen sentido\n"
+
+#: src/elflint.c:778
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: función en sección COMMON no tiene sentido\n"
+
+#: src/elflint.c:829
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: st_value out of bounds\n"
+msgstr "sección [%2d] '%s': símbolo %zu: st_value fuera de límites\n"
+
+#: src/elflint.c:835 src/elflint.c:860 src/elflint.c:909
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu does not fit completely in referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu no se ajusta totalmente en la sección [%2d] "
+"'%s'\n"
+
+#: src/elflint.c:844
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have "
+"SHF_TLS flag set\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: sección de referencia [%2d] '%s' no tiene "
+"establecida bandera SHF_TLS\n"
+
+#: src/elflint.c:854 src/elflint.c:902
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: st_value fuera de límites de sección de "
+"referencia [%2d] '%s'\n"
+
+#: src/elflint.c:881
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: símbolo TLS, pero no hay entrada de "
+"programa TLS\n"
+
+#: src/elflint.c:887
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but couldn't get TLS program "
+"header entry\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: símbolo TLS, pero no hay entrada de "
+"programa TLS\n"
+
+#: src/elflint.c:895
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] "
+"'%s'\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: st_value falta sección de referencia [%2d] "
+"'%s'\n"
+
+#: src/elflint.c:922
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: símbolo local fuera del rango descrito en "
+"sh_info\n"
+
+#: src/elflint.c:929
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: non-local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: símbolo non-local fuera del rango descrito "
+"en sh_info\n"
+
+#: src/elflint.c:936
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: non-local section symbol\n"
+msgstr "Sección [%2d] '%s': símbolo %zu: símbolo de sección non-local\n"
+
+#: src/elflint.c:986
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section "
+"[%2d]\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo _GLOBAL_OFFSET_TABLE_ se refiere a sección "
+"errada [%2d]\n"
+
+#: src/elflint.c:993
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] "
+"'%s'\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo _GLOBAL_OFFSET_TABLE_ se refiere a sección [%2d] "
+"'%s'\n"
+
+#. This test is more strict than the psABIs which
+#. usually allow the symbol to be in the middle of
+#. the .got section, allowing negative offsets.
+#: src/elflint.c:1009
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#<PRIx64> does not "
+"match %s section address %#<PRIx64>\n"
+msgstr ""
+"Sección [%2d] '%s': valor del símbolo _GLOBAL_OFFSET_TABLE_ %#<PRIx64> no "
+"coincide con dirección de sección %s %#<PRIx64>\n"
+
+#: src/elflint.c:1016
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %<PRIu64> does not "
+"match %s section size %<PRIu64>\n"
+msgstr ""
+"Sección [%2d] '%s': tamaño de símbolo _GLOBAL_OFFSET_TABLE_ %<PRIu64> no "
+"coincide con tamaño de sección %s %<PRIu64>\n"
+
+#: src/elflint.c:1024
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got "
+"section\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo _GLOBAL_OFFSET_TABLE_ presente, pero no. sección "
+"got\n"
+
+#: src/elflint.c:1040
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC_ symbol value %#<PRIx64> does not match dynamic "
+"segment address %#<PRIx64>\n"
+msgstr ""
+"sección [%2d] '%s': Valor de símbolo _DYNAMIC_ %#<PRIx64> no coincide con la "
+"dirección de segmento%#<PRIx64>\n"
+
+#: src/elflint.c:1047
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC symbol size %<PRIu64> does not match dynamic "
+"segment size %<PRIu64>\n"
+msgstr ""
+"Sección [%2d] '%s': tamaño de símbolo _DYNAMIC %<PRIu64> no coincide con "
+"tamaño de segmento %<PRIu64>\n"
+
+#: src/elflint.c:1060
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-"
+"default visibility\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: símbolo en tabla de símbolos dinámicos sin "
+"visibilidad predeterminada\n"
+
+#: src/elflint.c:1064
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %zu: bit desconocido establecido en st_other\n"
+
+#: src/elflint.c:1102
+#, fuzzy, c-format
+msgid "section [%2d] '%s': cannot get section data.\n"
+msgstr "Sección [%2d] '%s': No se pueden obtener datos de sección\n"
+
+#: src/elflint.c:1118
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"
+msgstr "Sección [%2d] '%s': DT_RELCOUNT utilizada para esta sección RELA\n"
+
+#: src/elflint.c:1129 src/elflint.c:1182
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"
+msgstr ""
+"Sección [%2d] '%s': valor DT_RELCOUNT %d demasiado alto para esta sección\n"
+
+#: src/elflint.c:1154 src/elflint.c:1207
+#, c-format
+msgid ""
+"section [%2d] '%s': relative relocations after index %d as specified by "
+"DT_RELCOUNT\n"
+msgstr ""
+"Sección [%2d] '%s': reubicaciones relativas después de que el %d de índice "
+"haya sido especificado por DT_RELCOUNT\n"
+
+#: src/elflint.c:1160 src/elflint.c:1213
+#, c-format
+msgid ""
+"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT "
+"specified %d relative relocations\n"
+msgstr ""
+"Sección [%2d] '%s': reubicación no-relativa en %zu de índice; DT_RELCOUNT "
+"especificado %d reubicaciones relativas\n"
+
+#: src/elflint.c:1172
+#, c-format
+msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n"
+msgstr "sección [%2d] '%s': DT_RELACOUNT utilizado para esta sección REL\n"
+
+#: src/elflint.c:1255
+#, c-format
+msgid "section [%2d] '%s': invalid destination section index\n"
+msgstr "Sección [%2d] '%s': índice de sección de destino inválido\n"
+
+#: src/elflint.c:1267
+#, c-format
+msgid "section [%2d] '%s': invalid destination section type\n"
+msgstr "Sección [%2d] '%s': tipo de sección de destino inválido\n"
+
+#: src/elflint.c:1275
+#, c-format
+msgid "section [%2d] '%s': sh_info should be zero\n"
+msgstr "Sección [%2d] '%s': sh_info debe ser cero\n"
+
+#: src/elflint.c:1283
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': no relocations for merge-able string sections possible\n"
+msgstr ""
+"Sección [%2d] '%s': no reubicaciones para secciones de fusión posibles\n"
+
+#: src/elflint.c:1291
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n"
+msgstr ""
+"Sección [%2d] '%s': tamaño de entrada de sección no coincide con ElfXX_Rela\n"
+
+#: src/elflint.c:1351
+#, c-format
+msgid "text relocation flag set but there is no read-only segment\n"
+msgstr "Reubicación de bandera pero no hay segmento de sólo lectura\n"
+
+#: src/elflint.c:1378
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid type\n"
+msgstr "Sección [%2d] '%s': reubicación %zu: tipo inválido\n"
+
+#: src/elflint.c:1386
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: relocation type invalid for the file "
+"type\n"
+msgstr ""
+"Sección [%2d] '%s': reubicación %zu: tipo de reubicación inválido para el "
+"tipo de archivo\n"
+
+#: src/elflint.c:1394
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n"
+msgstr "Sección [%2d] '%s': reubicación %zu: índice de símbolo inválido\n"
+
+#: src/elflint.c:1412
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can "
+"be used with %s\n"
+msgstr ""
+"Sección [%2d] '%s': reubicación %zu: sólo el símbolo '_GLOBAL_OFFSET_TABLE_' "
+"puede utilizarse con %s\n"
+
+#: src/elflint.c:1429
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n"
+msgstr "Sección [%2d] '%s': reubicación %zu: compensación fuera de límites\n"
+
+#: src/elflint.c:1444
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: copy relocation against symbol of type "
+"%s\n"
+msgstr ""
+"Sección [%2d] '%s': reubicación %zu: reubicación de copia con símbolo de "
+"tipo %s\n"
+
+#: src/elflint.c:1465
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: read-only section modified but text "
+"relocation flag not set\n"
+msgstr ""
+"Sección [%2d] '%s': reubicación %zu: sección de sólo-lectura modificada, "
+"pero no se estableció bandera de reubicación\n"
+
+#: src/elflint.c:1480
+#, c-format
+msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n"
+msgstr ""
+"Sección [%2d] '%s': las reubicaciones se hacen con datos cargados y "
+"descargados\n"
+
+#: src/elflint.c:1520 src/elflint.c:1571
+#, c-format
+msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
+msgstr "Sección [%2d] '%s': no puede obtener reubicación %zu: %s\n"
+
+#: src/elflint.c:1647
+#, c-format
+msgid "more than one dynamic section present\n"
+msgstr "más de una sección dinámica presente\n"
+
+#: src/elflint.c:1665
+#, fuzzy, c-format
+msgid ""
+"section [%2d]: referenced as string table for section [%2d] '%s' but section "
+"link value is invalid\n"
+msgstr ""
+"sección [%2d] '%s': nombrado como una tabla de cadena para la sección [%2d] "
+"'%s' pero el tipo no es SHT_STRTAB\n"
+
+#: src/elflint.c:1673
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"
+msgstr ""
+"Sección [%2d] '%s': tamaño de entrada de sección no coincide con ElfXX_Dyn\n"
+
+#: src/elflint.c:1678 src/elflint.c:1967
+#, c-format
+msgid "section [%2d] '%s': sh_info not zero\n"
+msgstr "Sección [%2d] '%s': sh_info no es cero\n"
+
+#: src/elflint.c:1688
+#, c-format
+msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"
+msgstr ""
+"Sección [%2d] '%s': no puede obtener entrada de sección dinámica %zu: %s\n"
+
+#: src/elflint.c:1696
+#, c-format
+msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"
+msgstr "Sección [%2d] '%s': entradas non-DT_NULL siguen a la entrada DT_NULL\n"
+
+#: src/elflint.c:1703
+#, c-format
+msgid "section [%2d] '%s': entry %zu: unknown tag\n"
+msgstr "Sección [%2d] '%s': entrada %zu: etiqueta desconocida\n"
+
+#: src/elflint.c:1714
+#, c-format
+msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n"
+msgstr "Sección [%2d] '%s': entrada %zu: más de una entrada con etiqueta %s\n"
+
+#: src/elflint.c:1724
+#, c-format
+msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n"
+msgstr "Sección [%2d] '%s': entrada %zu: nivel 2 etiqueta %s utilizada\n"
+
+#: src/elflint.c:1742
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"
+msgstr ""
+"Sección [%2d] '%s': entrada %zu: el valor DT_PLTREL debe ser DT_REL or "
+"DT_RELA\n"
+
+#: src/elflint.c:1755
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: pointer does not match address of section "
+"[%2d] '%s' referenced by sh_link\n"
+msgstr ""
+"Sección [%2d] '%s': entrada %zu: puntero no coincide con dirección de "
+"sección [%2d] '%s' al que hace referencia sh_link\n"
+
+#: src/elflint.c:1798
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"
+msgstr ""
+"Sección [%2d] '%s': entrada %zu: valor %s debe apuntar en segmento cargado\n"
+
+#: src/elflint.c:1813
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must be valid offset in section "
+"[%2d] '%s'\n"
+msgstr ""
+"sección [%2d] '%s': entrada %zu: valor %s debe ser compensación válida en "
+"sección [%2d] '%s'\n"
+
+#: src/elflint.c:1833 src/elflint.c:1861
+#, c-format
+msgid "section [%2d] '%s': contains %s entry but not %s\n"
+msgstr "Sección [%2d] '%s': contiene entrada %s pero no %s\n"
+
+#: src/elflint.c:1845
+#, c-format
+msgid "section [%2d] '%s': mandatory tag %s not present\n"
+msgstr "Sección [%2d] '%s': etiqueta obligatoria %s no está presente\n"
+
+#: src/elflint.c:1854
+#, c-format
+msgid "section [%2d] '%s': no hash section present\n"
+msgstr "Sección [%2d] '%s': no hay sección de dispersión presente\n"
+
+#: src/elflint.c:1869 src/elflint.c:1876
+#, c-format
+msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n"
+msgstr "Sección [%2d] '%s': no todas las %s, %s, y %s están presentes\n"
+
+#: src/elflint.c:1886 src/elflint.c:1890
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"
+msgstr ""
+"Sección [%2d] '%s': etiqueta %s faltante en DSO marcada durante el pre-"
+"enlace\n"
+
+#: src/elflint.c:1896
+#, c-format
+msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n"
+msgstr ""
+"Sección [%2d] '%s': archivo no-DSO marcado como dependencia durante el pre-"
+"enlace\n"
+
+#: src/elflint.c:1907 src/elflint.c:1911 src/elflint.c:1915 src/elflint.c:1919
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in prelinked executable\n"
+msgstr "Sección [%2d] '%s': etiqueta %s faltante en pre-enlace ejecutable\n"
+
+#: src/elflint.c:1931
+#, c-format
+msgid ""
+"section [%2d] '%s': only relocatable files can have extended section index\n"
+msgstr ""
+"Sección [%2d] '%s': sólo los archivos reubicables pueden tener índice de "
+"sección extendido\n"
+
+#: src/elflint.c:1941
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index section not for symbol table\n"
+msgstr ""
+"Sección [%2d] '%s': índice de sección extendido no para tabla de símbolos\n"
+
+#: src/elflint.c:1945
+#, fuzzy, c-format
+msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n"
+msgstr ""
+"Sección [%2d] '%s': índice de sección extendido no para tabla de símbolos\n"
+
+#: src/elflint.c:1950
+#, c-format
+msgid "cannot get data for symbol section\n"
+msgstr "no se puede obtener sección para símbolos\n"
+
+#: src/elflint.c:1953
+#, c-format
+msgid "section [%2d] '%s': entry size does not match Elf32_Word\n"
+msgstr "Sección [%2d] '%s': tamaño de entrada no coincide con Elf32_Word\n"
+
+#: src/elflint.c:1962
+#, c-format
+msgid "section [%2d] '%s': extended index table too small for symbol table\n"
+msgstr ""
+"Sección [%2d] '%s': tabla de índice extendida demasiado pequeña para tabla "
+"de símbolos\n"
+
+#: src/elflint.c:1977
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to "
+"same symbol table\n"
+msgstr ""
+"Sección [%2d] '%s': índice de sección extendida en sección [%2zu] '%s' se "
+"refiere a la misma tabla de símbolos\n"
+
+#: src/elflint.c:1995
+#, c-format
+msgid "symbol 0 should have zero extended section index\n"
+msgstr "símbolo 0 debe tener índice de sección extendida cero\n"
+
+#: src/elflint.c:2007
+#, c-format
+msgid "cannot get data for symbol %zu\n"
+msgstr "no puede obtener datos para símbolo %zu\n"
+
+#: src/elflint.c:2012
+#, c-format
+msgid "extended section index is %<PRIu32> but symbol index is not XINDEX\n"
+msgstr ""
+"índice de sección extendida es %<PRIu32> pero índice de símbolo no es "
+"XINDEX\n"
+
+#: src/elflint.c:2029 src/elflint.c:2083
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"
+msgstr ""
+"Sección [%2d] '%s': sección de tabla de dispersión es demasiado pequeña (es "
+"%ld, se espera %ld)\n"
+
+#: src/elflint.c:2043 src/elflint.c:2097
+#, c-format
+msgid "section [%2d] '%s': chain array too large\n"
+msgstr "Sección [%2d] '%s': índice de la cadena es demasiado grande\n"
+
+#: src/elflint.c:2057 src/elflint.c:2111
+#, c-format
+msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n"
+msgstr ""
+"Sección [%2d] '%s': referencia de cubetas de dispersión %zu fuera de "
+"límites\n"
+
+#: src/elflint.c:2067
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n"
+msgstr ""
+"Sección [%2d] '%s': referencia de cadena de dispersión %zu fuera de límites\n"
+
+#: src/elflint.c:2121
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %<PRIu64> out of bounds\n"
+msgstr ""
+"Sección [%2d] '%s': referencia de cadena de dispersión %<PRIu64> fuera de "
+"límites\n"
+
+#: src/elflint.c:2134
+#, fuzzy, c-format
+msgid "section [%2d] '%s': not enough data\n"
+msgstr "Sección [%2d] '%s': no puede obtener datos: %s\n"
+
+#: src/elflint.c:2146
+#, fuzzy, c-format
+msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n"
+msgstr "Sección [%2d] '%s': tamaño de bitmask no es potencia de 2: %u\n"
+
+#: src/elflint.c:2162
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected at "
+"least %ld)\n"
+msgstr ""
+"Sección [%2d] '%s': sección de tabla de dispersión es demasiado pequeña (es "
+"%ld, se espera al menos least%ld)\n"
+
+#: src/elflint.c:2171
+#, c-format
+msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n"
+msgstr ""
+"Sección [%2d] '%s': segundo cambio de función de dispersión demasiado "
+"grande: %u\n"
+
+#: src/elflint.c:2205
+#, c-format
+msgid ""
+"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"
+msgstr ""
+"Sección [%2d] '%s': cadena de dispersión para cubetas %zu inferior a "
+"polarización de índice de símbolo\n"
+
+#: src/elflint.c:2226
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is "
+"undefined\n"
+msgstr ""
+"Sección [%2d] '%s': el símbolo %u al que se hace referencia en cadena para "
+"cubeta %zu es indefinido\n"
+
+#: src/elflint.c:2239
+#, c-format
+msgid ""
+"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+"Sección [%2d] '%s': valor de dispersión para símbolo %u en cadena para "
+"cubeta %zu está errado\n"
+
+#: src/elflint.c:2248
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+"Sección [%2d] '%s': valor de dispersión para símbolo %u en cadena para "
+"cubeta %zu está errado\n"
+
+#: src/elflint.c:2278
+#, c-format
+msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n"
+msgstr ""
+"Sección [%2d] '%s': cadena de dispersión para cubeta %zu fuera de limites\n"
+
+#: src/elflint.c:2283
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"
+msgstr ""
+"Sección [%2d] '%s': referencia de símbolo en cadena para cubeta %zu fuera de "
+"límites\n"
+
+#: src/elflint.c:2289
+#, c-format
+msgid "section [%2d] '%s': bitmask does not match names in the hash table\n"
+msgstr ""
+"Sección [%2d] '%s': bitmask no coincide con nombres en la tabla de "
+"dispersión\n"
+
+#: src/elflint.c:2302
+#, c-format
+msgid "section [%2d] '%s': relocatable files cannot have hash tables\n"
+msgstr ""
+"Sección [%2d] '%s': archivos reubicables no pueden tener tablas de "
+"dispersión\n"
+
+#: src/elflint.c:2320
+#, c-format
+msgid "section [%2d] '%s': hash table not for dynamic symbol table\n"
+msgstr ""
+"Sección [%2d] '%s': tabla de dispersión no para tabla de símbolos dinámicos\n"
+
+#: src/elflint.c:2324
+#, fuzzy, c-format
+msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n"
+msgstr "Sección [%2d] '%s': índice de sección de destino inválido\n"
+
+#: src/elflint.c:2334
+#, c-format
+msgid "section [%2d] '%s': hash table entry size incorrect\n"
+msgstr ""
+"Sección [%2d] '%s': tamaño incorrecto de entrada de tabla de dispersión\n"
+
+#: src/elflint.c:2339
+#, c-format
+msgid "section [%2d] '%s': not marked to be allocated\n"
+msgstr "Sección [%2d] '%s': no marcada para ser asignada\n"
+
+#: src/elflint.c:2344
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table has not even room for initial administrative "
+"entries\n"
+msgstr ""
+"Sección [%2d] '%s': tabla de dispersión no tiene ni siquiera espacio para "
+"entradas administrativas iniciales\n"
+
+#: src/elflint.c:2393
+#, c-format
+msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"
+msgstr ""
+"sh_link en secciones de dispersión [%2zu] '%s' y [%2zu] '%s' no son "
+"idénticas\n"
+
+#: src/elflint.c:2417 src/elflint.c:2482 src/elflint.c:2517
+#, fuzzy, c-format
+msgid "hash section [%2zu] '%s' does not contain enough data\n"
+msgstr "sección [%2zu] '%s' no debe ser ejecutable\n"
+
+#: src/elflint.c:2438
+#, fuzzy, c-format
+msgid "hash section [%2zu] '%s' has zero bit mask words\n"
+msgstr "Sección [%2d] '%s': grupo de sección sin palabra de banderas\n"
+
+#: src/elflint.c:2449 src/elflint.c:2493 src/elflint.c:2530
+#, fuzzy, c-format
+msgid "hash section [%2zu] '%s' uses too much data\n"
+msgstr "sección [%2zu] '%s' debe ser asignada\n"
+
+#: src/elflint.c:2464
+#, c-format
+msgid ""
+"hash section [%2zu] '%s' invalid symbol index %<PRIu32> (max_nsyms: "
+"%<PRIu32>, nentries: %<PRIu32>\n"
+msgstr ""
+
+#: src/elflint.c:2551
+#, fuzzy, c-format
+msgid "hash section [%2zu] '%s' invalid sh_entsize\n"
+msgstr "Sección [%2zu]: nombre inválido\n"
+
+#: src/elflint.c:2561 src/elflint.c:2565
+#, c-format
+msgid "section [%2zu] '%s': reference to symbol index 0\n"
+msgstr "Sección [%2zu] '%s': referencia al índice de símbolo 0\n"
+
+#: src/elflint.c:2572
+#, c-format
+msgid ""
+"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+"Símbolo %d nombrado en nueva tabla de dispersión en [%2zu] '%s' pero no en "
+"la tabla de dispersión anterior en [%2zu] '%s'\n"
+
+#: src/elflint.c:2584
+#, c-format
+msgid ""
+"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+"Símbolo %d nombrado en la tabla de dispersión anterior en [%2zu] '%s' pero "
+"no en la nueva tabla de dispersión en [%2zu] '%s'\n"
+
+#: src/elflint.c:2600
+#, c-format
+msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n"
+msgstr "Sección [%2d] '%s': nonzero sh_%s para sección NULL\n"
+
+#: src/elflint.c:2620
+#, c-format
+msgid ""
+"section [%2d] '%s': section groups only allowed in relocatable object files\n"
+msgstr ""
+"Sección [%2d] '%s': grupos de sección sólo permitidos en archivos de objeto "
+"reubicables\n"
+
+#: src/elflint.c:2631
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol table: %s\n"
+msgstr "Sección [%2d] '%s': no puede obtener tabla de símbolos: %s\n"
+
+#: src/elflint.c:2636
+#, c-format
+msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n"
+msgstr ""
+"Sección [%2d] '%s': referencia de sección en sh_link no es una tabla de "
+"símbolos\n"
+
+#: src/elflint.c:2642
+#, c-format
+msgid "section [%2d] '%s': invalid symbol index in sh_info\n"
+msgstr "Sección [%2d] '%s': índice de símbolo inválido en sh_info\n"
+
+#: src/elflint.c:2647
+#, c-format
+msgid "section [%2d] '%s': sh_flags not zero\n"
+msgstr "Sección [%2d] '%s': sh_flags no cero\n"
+
+#: src/elflint.c:2654
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol for signature\n"
+msgstr "Sección [%2d] '%s': no puede obtener símbolo para firma\n"
+
+#: src/elflint.c:2658
+#, fuzzy, c-format
+msgid "section [%2d] '%s': cannot get symbol name for signature\n"
+msgstr "Sección [%2d] '%s': no puede obtener símbolo para firma\n"
+
+#: src/elflint.c:2663
+#, c-format
+msgid "section [%2d] '%s': signature symbol cannot be empty string\n"
+msgstr ""
+"sección [%2d] '%s': el símbolo de firma no puede ser una cadena vacía\n"
+
+#: src/elflint.c:2669
+#, c-format
+msgid "section [%2d] '%s': sh_flags not set correctly\n"
+msgstr "Sección [%2d] '%s': sh_flags no establecida correctamente\n"
+
+#: src/elflint.c:2675
+#, c-format
+msgid "section [%2d] '%s': cannot get data: %s\n"
+msgstr "Sección [%2d] '%s': no puede obtener datos: %s\n"
+
+#: src/elflint.c:2684
+#, c-format
+msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"
+msgstr ""
+"Sección [%2d] '%s': tamaño de sección no es múltiplo de tamaño de "
+"(Elf32_Word)\n"
+
+#: src/elflint.c:2690
+#, c-format
+msgid "section [%2d] '%s': section group without flags word\n"
+msgstr "Sección [%2d] '%s': grupo de sección sin palabra de banderas\n"
+
+#: src/elflint.c:2698
+#, c-format
+msgid "section [%2d] '%s': section group without member\n"
+msgstr "Sección [%2d] '%s': grupo de sección sin miembro\n"
+
+#: src/elflint.c:2702
+#, c-format
+msgid "section [%2d] '%s': section group with only one member\n"
+msgstr "Sección [%2d] '%s': grupo de sección con sólo un miembro\n"
+
+#: src/elflint.c:2713
+#, c-format
+msgid "section [%2d] '%s': unknown section group flags\n"
+msgstr "Sección [%2d] '%s': banderas de grupo de sección desconocido\n"
+
+#: src/elflint.c:2725
+#, fuzzy, c-format
+msgid "section [%2d] '%s': section index %zu out of range\n"
+msgstr "Sección [%2d] '%s': índice de sección %Zu fuera de rango\n"
+
+#: src/elflint.c:2734
+#, c-format
+msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n"
+msgstr ""
+"Sección [%2d] '%s': no se puede obtener encabezamiento de sección para "
+"elemento %zu: %s\n"
+
+#: src/elflint.c:2741
+#, c-format
+msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n"
+msgstr "Sección [%2d] '%s': grupo de sección contiene otro grupo [%2d] '%s'\n"
+
+#: src/elflint.c:2747
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': element %zu references section [%2d] '%s' without "
+"SHF_GROUP flag set\n"
+msgstr ""
+"Sección [%2d] '%s': elemento %Zu hace referencia a sección [%2d] '%s' sin "
+"establecer bandera SHF_GROUP\n"
+
+#: src/elflint.c:2754
+#, c-format
+msgid "section [%2d] '%s' is contained in more than one section group\n"
+msgstr "Sección [%2d] '%s' está contenida en más de un grupo de sección\n"
+
+#: src/elflint.c:2944
+#, c-format
+msgid ""
+"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no "
+"dynamic symbol table\n"
+msgstr ""
+"Sección [%2d] '%s' se refiere en sh_link a la sección [%2d] '%s' la cual no "
+"es una tabla de símbolos dinámicos\n"
+
+#: src/elflint.c:2956
+#, c-format
+msgid ""
+"section [%2d] '%s' has different number of entries than symbol table [%2d] "
+"'%s'\n"
+msgstr ""
+"Sección [%2d] '%s' tiene un número diferente de entradas a la de la tabla de "
+"símbolos [%2d] '%s'\n"
+
+#: src/elflint.c:2972
+#, c-format
+msgid "section [%2d] '%s': symbol %d: cannot read version data\n"
+msgstr ""
+"Sección [%2d] '%s': el símbolo %d: no se pueden leer datos de versión\n"
+
+#: src/elflint.c:2988
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n"
+msgstr ""
+"Sección [%2d] '%s': el símbolo %d: el símbolo local con alcance mundial\n"
+
+#: src/elflint.c:2996
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with version\n"
+msgstr "Sección [%2d] '%s': símbolo %d: símbolo local con versión\n"
+
+#: src/elflint.c:3010
+#, c-format
+msgid "section [%2d] '%s': symbol %d: invalid version index %d\n"
+msgstr "Sección [%2d] '%s': símbolo %d: índice de versión inválida %d\n"
+
+#: src/elflint.c:3015
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for defined version\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %d: índice de versión %d es para versión "
+"definida\n"
+
+#: src/elflint.c:3025
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for requested version\n"
+msgstr ""
+"Sección [%2d] '%s': símbolo %d: índice de versión %d es para la versión "
+"solicitada\n"
+
+#: src/elflint.c:3078
+#, c-format
+msgid "more than one version reference section present\n"
+msgstr "Más de una sección de referencia de versión presente\n"
+
+#: src/elflint.c:3086 src/elflint.c:3233
+#, c-format
+msgid "section [%2d] '%s': sh_link does not link to string table\n"
+msgstr "Sección [%2d] '%s': sh_link no se enlaza a la tabla de cadenas\n"
+
+#: src/elflint.c:3111 src/elflint.c:3287
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong version %d\n"
+msgstr "Sección [%2d] '%s': entrada %d tiene versión %d errada\n"
+
+#: src/elflint.c:3118 src/elflint.c:3294
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"
+msgstr ""
+"Sección [%2d] '%s': entrada %d tiene compensación errada de datos "
+"auxiliares\n"
+
+#: src/elflint.c:3128
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid file reference\n"
+msgstr "Sección [%2d] '%s': entrada %d tiene referencia de archivo inválida\n"
+
+#: src/elflint.c:3136
+#, c-format
+msgid "section [%2d] '%s': entry %d references unknown dependency\n"
+msgstr "Sección [%2d] '%s': %d hace referencia a dependencia desconocida\n"
+
+#: src/elflint.c:3148
+#, c-format
+msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"
+msgstr ""
+"sección [%2d] '%s': entrada auxiliar %d de entrada %d tiene bandera "
+"desconocida\n"
+
+#: src/elflint.c:3156
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name "
+"reference\n"
+msgstr ""
+"Sección [%2d] '%s': entrada auxiliar %d de entrada %d tiene referencia de "
+"nombre inválida\n"
+
+#: src/elflint.c:3165
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: "
+"%#x, expected %#x\n"
+msgstr ""
+"Sección [%2d] '%s': entrada auxiliar %d de entrada %d tiene valor de "
+"dispersión: %#x, esperado %#x\n"
+
+#: src/elflint.c:3174
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version "
+"name '%s'\n"
+msgstr ""
+"sección [%2d] '%s': entrada auxiliar %d de entrada %d tiene nombre duplicado "
+"'%s'\n"
+
+#: src/elflint.c:3185
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"
+msgstr ""
+"sección [%2d] '%s': entrada auxiliar %d de entrada %d tiene próximo campo "
+"errado\n"
+
+#: src/elflint.c:3202 src/elflint.c:3378
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n"
+msgstr ""
+"sección [%2d] '%s': entrada %d tiene compensación inválida para próxima "
+"entrada\n"
+
+#: src/elflint.c:3210 src/elflint.c:3386
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says "
+"there are more entries\n"
+msgstr ""
+"sección [%2d] '%s': entrada %d tiene compensación inválida para próxima "
+"entrada\n"
+
+#: src/elflint.c:3225
+#, c-format
+msgid "more than one version definition section present\n"
+msgstr "más de una definición de versión presente de sección\n"
+
+#: src/elflint.c:3272
+#, c-format
+msgid "section [%2d] '%s': more than one BASE definition\n"
+msgstr "Sección [%2d] '%s': más de una definición de BASE\n"
+
+#: src/elflint.c:3276
+#, c-format
+msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"
+msgstr ""
+"Sección [%2d] '%s': definición de BASE debe tener índice VER_NDX_GLOBAL\n"
+
+#: src/elflint.c:3282
+#, c-format
+msgid "section [%2d] '%s': entry %d has unknown flag\n"
+msgstr "Sección [%2d] '%s': entrada %d tiene bandera desconocida\n"
+
+#: src/elflint.c:3309
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid name reference\n"
+msgstr "Sección [%2d] '%s': entrada %d tiene referencia de nombre inválida\n"
+
+#: src/elflint.c:3316
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"
+msgstr ""
+"Sección [%2d] '%s': entrada %d tiene valor de dispersión errado: %#x, "
+"esperado %#x\n"
+
+#: src/elflint.c:3324
+#, c-format
+msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n"
+msgstr ""
+"Sección [%2d] '%s': entrada %d tiene nombre de versión duplicado '%s'\n"
+
+#: src/elflint.c:3344
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"
+msgstr ""
+"Sección [%2d] '%s': entrada %d tiene referencia de nombre inválida en datos "
+"auxiliares\n"
+
+#: src/elflint.c:3361
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"
+msgstr ""
+"Sección [%2d] '%s': entrada %d tiene próximo campo errado en datos "
+"auxiliares\n"
+
+#: src/elflint.c:3394
+#, c-format
+msgid "section [%2d] '%s': no BASE definition\n"
+msgstr "Sección [%2d] '%s': no hay definición de BASE\n"
+
+#: src/elflint.c:3410
+#, c-format
+msgid "section [%2d] '%s': unknown parent version '%s'\n"
+msgstr "Sección [%2d] '%s': desconocida versión principal '%s'\n"
+
+#: src/elflint.c:3423
+#, c-format
+msgid "section [%2d] '%s': empty object attributes section\n"
+msgstr "Sección [%2d] '%s': sección de atributos de objeto vacío\n"
+
+#: src/elflint.c:3444
+#, c-format
+msgid "section [%2d] '%s': unrecognized attribute format\n"
+msgstr "Sección[%2d] '%s': formato de atributo no reconocido\n"
+
+#: src/elflint.c:3460
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute section\n"
+msgstr ""
+"Sección[%2d] '%s': compensación %zu: campo de longitud cero en sección de "
+"atributo\n"
+
+#: src/elflint.c:3469
+#, c-format
+msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n"
+msgstr ""
+"Sección[%2d] '%s': compensación %zu: longitud inválida en sección de "
+"atributo\n"
+
+#: src/elflint.c:3481
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n"
+msgstr ""
+"Sección[%2d] '%s': compensación %zu: cadena de nombre de proveedor sin "
+"terminar\n"
+
+#: src/elflint.c:3498
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"
+msgstr ""
+"Sección [%2d] '%s': compensación %zu: sin fin ULEB128 en etiqueta de sub-"
+"sección de atributo\n"
+
+#: src/elflint.c:3507
+#, c-format
+msgid "section [%2d] '%s': offset %zu: truncated attribute section\n"
+msgstr "Sección [%2d] '%s': compensación %zu: sección de atributo truncado\n"
+
+#: src/elflint.c:3516
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"
+msgstr ""
+"Sección [%2d] '%s': compensación %zu: campo de longitud cero length en sub-"
+"sección de atributo\n"
+
+#: src/elflint.c:3531
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"
+msgstr ""
+"Sección [%2d] '%s': compensación %zu: longitud inválida en sub-sección de "
+"atributo\n"
+
+#. Tag_File
+#: src/elflint.c:3542
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"
+msgstr ""
+"Sección[%2d] '%s': compensación %zu: sub-sección de atributo tiene etiqueta "
+"inesperada %u\n"
+
+#: src/elflint.c:3560
+#, c-format
+msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"
+msgstr ""
+"Sección[%2d] '%s': compensación %zu: sin fin ULEB128 en etiqueta de "
+"atributo\n"
+
+#: src/elflint.c:3571
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n"
+msgstr ""
+"Sección [%2d] '%s': compensación %zu: cadena sin terminar en atributo\n"
+
+#: src/elflint.c:3584
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"
+msgstr ""
+"Sección [%2d] '%s': compensación %zu: etiqueta de atributo no reconocida %u\n"
+
+#: src/elflint.c:3588
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: unrecognized %s attribute value %<PRIu64>\n"
+msgstr ""
+"Sección [%2d] '%s': compensación %zu: no reconocido %s valor de atributo "
+"%<PRIu64>\n"
+
+#: src/elflint.c:3598
+#, c-format
+msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n"
+msgstr "Sección [%2d] '%s': compensación %zu: proveedor '%s' desconocido\n"
+
+#: src/elflint.c:3604
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"
+msgstr ""
+"Sección [%2d] '%s': compensación %zu: extra bytes después de la última "
+"sección de atributo\n"
+
+#: src/elflint.c:3693
+#, c-format
+msgid "cannot get section header of zeroth section\n"
+msgstr "no puede obtener encabezamiento de sección de sección zeroth\n"
+
+#: src/elflint.c:3697
+#, c-format
+msgid "zeroth section has nonzero name\n"
+msgstr "Sección zeroth tiene nombre nonzero\n"
+
+#: src/elflint.c:3699
+#, c-format
+msgid "zeroth section has nonzero type\n"
+msgstr "Sección zeroth tiene tipo nonzero\n"
+
+#: src/elflint.c:3701
+#, c-format
+msgid "zeroth section has nonzero flags\n"
+msgstr "Sección zeroth tiene banderas nonzero\n"
+
+#: src/elflint.c:3703
+#, c-format
+msgid "zeroth section has nonzero address\n"
+msgstr "Sección zeroth tiene dirección nonzero\n"
+
+#: src/elflint.c:3705
+#, c-format
+msgid "zeroth section has nonzero offset\n"
+msgstr "Sección zeroth tiene compensación nonzero\n"
+
+#: src/elflint.c:3707
+#, c-format
+msgid "zeroth section has nonzero align value\n"
+msgstr "Sección zeroth tiene valor de alineación nonzero\n"
+
+#: src/elflint.c:3709
+#, c-format
+msgid "zeroth section has nonzero entry size value\n"
+msgstr "Sección zeroth tiene valor de tamaño de entrada nonzero\n"
+
+#: src/elflint.c:3712
+#, c-format
+msgid ""
+"zeroth section has nonzero size value while ELF header has nonzero shnum "
+"value\n"
+msgstr ""
+"Sección zeroth tiene valor de tamaño nonzero mientras que el encabezamiento "
+"ELF tiene valor shnum nonzero\n"
+
+#: src/elflint.c:3716
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in shstrndx\n"
+msgstr ""
+"Sección zeroth tiene valor de enlace nonzero mientras que el encabezamiento "
+"ELF no señala sobreflujo en shstrndx\n"
+
+#: src/elflint.c:3720
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in phnum\n"
+msgstr ""
+"la sección zeroth tiene un valor de enlace distinto a cero mientras que el "
+"encabezamiento ELF no señala desbordamiento en phnum\n"
+
+#: src/elflint.c:3738
+#, c-format
+msgid "cannot get section header for section [%2zu] '%s': %s\n"
+msgstr "No se puede obtener encabezamiento para sección [%2zu] '%s': %s\n"
+
+#: src/elflint.c:3747
+#, c-format
+msgid "section [%2zu]: invalid name\n"
+msgstr "Sección [%2zu]: nombre inválido\n"
+
+#: src/elflint.c:3774
+#, c-format
+msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n"
+msgstr "Sección [%2d] '%s' tiene tipo errado: %s esperado, es %s\n"
+
+#: src/elflint.c:3792
+#, c-format
+msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n"
+msgstr "Sección [%2zu] '%s' tiene banderas erradas: %s esperado, es %s\n"
+
+#: src/elflint.c:3810
+#, c-format
+msgid ""
+"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"
+msgstr ""
+"Sección [%2zu] '%s' tiene banderas erradas: %s esperado y posiblemente %s, "
+"es %s\n"
+
+#: src/elflint.c:3828
+#, c-format
+msgid "section [%2zu] '%s' present in object file\n"
+msgstr "Sección [%2zu] '%s' presente en archivo objeto\n"
+
+#: src/elflint.c:3834 src/elflint.c:3866
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"
+msgstr ""
+"Sección [%2zu] '%s' tiene bandera SHF_ALLOC establecida pero no es un "
+"segmento cargable\n"
+
+#: src/elflint.c:3839 src/elflint.c:3871
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable "
+"segments\n"
+msgstr ""
+"Sección [%2zu] '%s' no tiene bandera SHF_ALLOC establecida pero hay "
+"segmentos cargables\n"
+
+#: src/elflint.c:3847
+#, c-format
+msgid ""
+"section [%2zu] '%s' is extension section index table in non-object file\n"
+msgstr ""
+"Sección [%2zu] '%s' es tabla de índice de sección de extensión en archivo no-"
+"objeto\n"
+
+#: src/elflint.c:3890
+#, c-format
+msgid "section [%2zu] '%s': size not multiple of entry size\n"
+msgstr "Sección [%2zu] '%s': tamaño no es múltiplo de tamaño de entrada\n"
+
+#: src/elflint.c:3895
+#, c-format
+msgid "cannot get section header\n"
+msgstr "no se puede obtener encabezamiento de sección\n"
+
+#: src/elflint.c:3905
+#, c-format
+msgid "section [%2zu] '%s' has unsupported type %d\n"
+msgstr "sección [%2zu] '%s' tiene tipo %d incompatible \n"
+
+#: src/elflint.c:3920
+#, c-format
+msgid ""
+"section [%2zu] '%s' contains invalid processor-specific flag(s) %#<PRIx64>\n"
+msgstr ""
+"Sección [%2zu] '%s' contiene bandera(s) de procesador-específico inválidas "
+"%#<PRIx64>\n"
+
+#: src/elflint.c:3927
+#, c-format
+msgid "section [%2zu] '%s' contains unknown flag(s) %#<PRIx64>\n"
+msgstr "Sección [%2zu] '%s' contiene bandera(s) desconocidas %#<PRIx64>\n"
+
+#: src/elflint.c:3935
+#, c-format
+msgid "section [%2zu] '%s': thread-local data sections address not zero\n"
+msgstr ""
+"Sección [%2zu] '%s': dirección de secciones de datos de hilo-local no cero\n"
+
+#: src/elflint.c:3945
+#, fuzzy, c-format
+msgid "section [%2zu] '%s': allocated section cannot be compressed\n"
+msgstr ""
+"Sección [%2zu] '%s': dirección de secciones de datos de hilo-local no cero\n"
+
+#: src/elflint.c:3950
+#, fuzzy, c-format
+msgid "section [%2zu] '%s': nobits section cannot be compressed\n"
+msgstr "Sección [%2d] '%s': no hay sección de dispersión presente\n"
+
+#: src/elflint.c:3956
+#, fuzzy, c-format
+msgid ""
+"section [%2zu] '%s': compressed section with no compression header: %s\n"
+msgstr "Sección [%2d] '%s': grupo de sección con sólo un miembro\n"
+
+#: src/elflint.c:3962
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in link value\n"
+msgstr ""
+"Sección [%2zu] '%s': referencia de sección inválida en valor de enlace\n"
+
+#: src/elflint.c:3967
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in info value\n"
+msgstr ""
+"Sección [%2zu] '%s': referencia de sección inválida en valor de información\n"
+
+#: src/elflint.c:3974
+#, c-format
+msgid "section [%2zu] '%s': strings flag set without merge flag\n"
+msgstr ""
+"Sección [%2zu] '%s': bandera de cadenas establecida sin bandera de fusión\n"
+
+#: src/elflint.c:3979
+#, c-format
+msgid "section [%2zu] '%s': merge flag set but entry size is zero\n"
+msgstr ""
+"Sección [%2zu] '%s': bandera de fusión establecida pero tamaño de entrada es "
+"cero\n"
+
+#: src/elflint.c:3998
+#, c-format
+msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n"
+msgstr ""
+"Sección [%2zu] '%s' tiene un tipo %d inesperado para una sección ejecutable\n"
+
+#: src/elflint.c:4007
+#, fuzzy, c-format
+msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n"
+msgstr "sección [%2zu] '%s' no debe tener permiso de escritura\n"
+
+#: src/elflint.c:4014
+#, c-format
+msgid "section [%2zu] '%s' is both executable and writable\n"
+msgstr "Sección [%2zu] '%s' es tanto de ejecución como de escritura\n"
+
+#: src/elflint.c:4045
+#, c-format
+msgid ""
+"section [%2zu] '%s' not fully contained in segment of program header entry "
+"%d\n"
+msgstr ""
+"Sección [%2zu] '%s' no contenida totalmente en segmento de entrada de "
+"encabezamiento de programa %d\n"
+
+#: src/elflint.c:4055
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d\n"
+msgstr ""
+"Sección [%2zu] '%s' no tiene tipo NOBITS pero es leída desde el archivo en "
+"segmento de entrada de encabezamiento de programa %d\n"
+
+#: src/elflint.c:4081
+#, fuzzy, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d and file contents is non-zero\n"
+msgstr ""
+"Sección [%2zu] '%s' no tiene tipo NOBITS pero es leída desde el archivo en "
+"segmento de entrada de encabezamiento de programa %d\n"
+
+#: src/elflint.c:4092
+#, c-format
+msgid ""
+"section [%2zu] '%s' has not type NOBITS but is not read from the file in "
+"segment of program header entry %d\n"
+msgstr ""
+"Sección [%2zu] '%s' no tiene tipo NOBITS pero no es leída desde el fichero "
+"en segmento de entrada de encabezamiento de programa %d\n"
+
+#: src/elflint.c:4103
+#, c-format
+msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n"
+msgstr "Sección [%2zu] '%s' es ejecutable en segmento no ejecutable %d\n"
+
+#: src/elflint.c:4113
+#, c-format
+msgid "section [%2zu] '%s' is writable in unwritable segment %d\n"
+msgstr ""
+"Sección [%2zu] '%s' es de escritura en segmento que no es de escritura %d\n"
+
+#: src/elflint.c:4123
+#, c-format
+msgid ""
+"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"
+msgstr ""
+"Sección [%2zu] '%s': asignación de bandera establecida pero sección no en "
+"ningún segmento cargado\n"
+
+#: src/elflint.c:4129
+#, c-format
+msgid ""
+"section [%2zu] '%s': ELF header says this is the section header string table "
+"but type is not SHT_TYPE\n"
+msgstr ""
+"Sección [%2zu] '%s': encabezamiento ELF dice esta es la tabla de cadena de "
+"encabezamiento de sección, pero el tipo no es SHT_TYPE\n"
+
+#: src/elflint.c:4137
+#, c-format
+msgid ""
+"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"
+msgstr ""
+"sección [%2zu] '%s': ficheros reubicables no pueden tener tablas de símbolos "
+"dinámicos\n"
+
+#: src/elflint.c:4188
+#, c-format
+msgid "more than one version symbol table present\n"
+msgstr "Más de una tabla de símbolos presente\n"
+
+#: src/elflint.c:4211
+#, c-format
+msgid "INTERP program header entry but no .interp section\n"
+msgstr ""
+"Entrada de encabezamiento de programa INTERP pero no la sección .interp\n"
+
+#: src/elflint.c:4222
+#, c-format
+msgid ""
+"loadable segment [%u] is executable but contains no executable sections\n"
+msgstr ""
+"segmento cargable [%u] es ejecutable pero no contiene secciones ejecutables\n"
+
+#: src/elflint.c:4228
+#, c-format
+msgid "loadable segment [%u] is writable but contains no writable sections\n"
+msgstr ""
+"segmento cargable [%u] es de escritura pero contiene secciones protegidas "
+"contra escritura\n"
+
+#: src/elflint.c:4239
+#, c-format
+msgid ""
+"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section "
+"exist\n"
+msgstr ""
+"Sección no .gnu.versym presente, pero la sección .gnu.versym_d o la sección ."
+"gnu.versym_r existen\n"
+
+#: src/elflint.c:4252
+#, c-format
+msgid "duplicate version index %d\n"
+msgstr "Duplicar índice de versión %d\n"
+
+#: src/elflint.c:4266
+#, c-format
+msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"
+msgstr ""
+"Sección .gnu.versym presente sin las secciones .gnu.versym_d o .gnu."
+"versym_r\n"
+
+#: src/elflint.c:4315
+#, c-format
+msgid "phdr[%d]: unknown core file note type %<PRIu32> at offset %<PRIu64>\n"
+msgstr ""
+"phdr[%d]: tipo de nota de fichero core desconocido %<PRIu32> en compensación "
+"%<PRIu64>\n"
+
+#: src/elflint.c:4319
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': unknown core file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+"Sección [%2d] '%s': tipo de nota de fichero core desconocido %<PRIu32> en "
+"compensación %Zu\n"
+
+#: src/elflint.c:4342
+#, fuzzy, c-format
+msgid "phdr[%d]: unknown object file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+"phdr[%d]: tipo de nota de fichero objeto desconocido %<PRIu32> en "
+"compensación %Zu\n"
+
+#: src/elflint.c:4346
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': unknown object file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+"Sección [%2d] '%s': tipo de nota de fichero objeto desconocido %<PRIu32> en "
+"compensación %Zu\n"
+
+#: src/elflint.c:4363
+#, c-format
+msgid "phdr[%d]: no note entries defined for the type of file\n"
+msgstr "phdr[%d]: no hay entradas de nota definidas para el tipo de archivo\n"
+
+#: src/elflint.c:4382
+#, c-format
+msgid "phdr[%d]: cannot get content of note section: %s\n"
+msgstr "phdr[%d]: no puede obtener contenido de sección de nota: %s\n"
+
+#: src/elflint.c:4385
+#, c-format
+msgid "phdr[%d]: extra %<PRIu64> bytes after last note\n"
+msgstr "phdr[%d]: extra %<PRIu64> bytes después de la última nota\n"
+
+#: src/elflint.c:4406
+#, c-format
+msgid "section [%2d] '%s': no note entries defined for the type of file\n"
+msgstr ""
+"Sección [%2d] '%s': no hay entradas de nota definidas para el tipo de "
+"archivo\n"
+
+#: src/elflint.c:4413
+#, c-format
+msgid "section [%2d] '%s': cannot get content of note section\n"
+msgstr ""
+"Sección[%2d] '%s': no se puede obtener el contenido de sección de nota\n"
+
+#: src/elflint.c:4416
+#, c-format
+msgid "section [%2d] '%s': extra %<PRIu64> bytes after last note\n"
+msgstr "Sección[%2d] '%s': extra %<PRIu64> bytes después de la última nota\n"
+
+#: src/elflint.c:4434
+#, c-format
+msgid ""
+"only executables, shared objects, and core files can have program headers\n"
+msgstr ""
+"Sólo ejecutables, objetos compartidos y ficheros core pueden tener "
+"encabezamientos de programas\n"
+
+#: src/elflint.c:4449
+#, c-format
+msgid "cannot get program header entry %d: %s\n"
+msgstr "no se puede obtener entrada de encabezamiento %d: %s\n"
+
+#: src/elflint.c:4458
+#, c-format
+msgid "program header entry %d: unknown program header entry type %#<PRIx64>\n"
+msgstr ""
+"entrada de encabezamiento de programa %d: tipo %#<PRIx64> de entrada de "
+"encabezamiento de programa desconocido\n"
+
+#: src/elflint.c:4469
+#, c-format
+msgid "more than one INTERP entry in program header\n"
+msgstr "Más de una entrada INTERP en encabezamiento de programa\n"
+
+#: src/elflint.c:4477
+#, c-format
+msgid "more than one TLS entry in program header\n"
+msgstr "más de una entrada TLS en encabezamiento de programa\n"
+
+#: src/elflint.c:4484
+#, c-format
+msgid "static executable cannot have dynamic sections\n"
+msgstr "ejecutable estático no puede tener secciones dinámicas\n"
+
+#: src/elflint.c:4498
+#, c-format
+msgid "dynamic section reference in program header has wrong offset\n"
+msgstr ""
+"Referencia de sección dinámica en encabezamiento de programa tiene "
+"compensación errada\n"
+
+#: src/elflint.c:4501
+#, c-format
+msgid "dynamic section size mismatch in program and section header\n"
+msgstr ""
+"No coinciden tamaño de sección dinámica en programa y encabezamiento de "
+"sección\n"
+
+#: src/elflint.c:4511
+#, c-format
+msgid "more than one GNU_RELRO entry in program header\n"
+msgstr "Más de una entrada GNU_RELRO en encabezamiento de programa\n"
+
+#: src/elflint.c:4532
+#, c-format
+msgid "loadable segment GNU_RELRO applies to is not writable\n"
+msgstr "Segmento cargable GNU_RELRO que se aplica no es de escritura\n"
+
+#: src/elflint.c:4543
+#, c-format
+msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"
+msgstr ""
+"Banderas de segmento cargable [%u] no coinciden con banderas GNU_RELRO [%u]\n"
+
+#: src/elflint.c:4550
+#, c-format
+msgid ""
+"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n"
+msgstr ""
+
+#: src/elflint.c:4559 src/elflint.c:4582
+#, c-format
+msgid "%s segment not contained in a loaded segment\n"
+msgstr "Segmento %s no contenido en un segmento cargable\n"
+
+#: src/elflint.c:4588
+#, c-format
+msgid "program header offset in ELF header and PHDR entry do not match"
+msgstr ""
+"Compensación de encabezamiento de programa en encabezamiento ELF y entrada "
+"PHDR no coinciden"
+
+#: src/elflint.c:4613
+#, c-format
+msgid "call frame search table reference in program header has wrong offset\n"
+msgstr ""
+"Referencia de tabla de búsqueda de marco de llamada en encabezamiento de "
+"programa tiene una compensación errada\n"
+
+#: src/elflint.c:4616
+#, c-format
+msgid "call frame search table size mismatch in program and section header\n"
+msgstr ""
+"Tamaño de tabla de búsqueda de marco de llamada no coincide con programa y "
+"encabezamiento de sección\n"
+
+#: src/elflint.c:4629
+#, c-format
+msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"
+msgstr "PT_GNU_EH_FRAME presente pero no la sección.eh_frame_hdr\n"
+
+#: src/elflint.c:4637
+#, c-format
+msgid "call frame search table must be allocated\n"
+msgstr "tabla de búsqueda de marco de llamada debe ser asignada\n"
+
+#: src/elflint.c:4640
+#, c-format
+msgid "section [%2zu] '%s' must be allocated\n"
+msgstr "sección [%2zu] '%s' debe ser asignada\n"
+
+#: src/elflint.c:4644
+#, c-format
+msgid "call frame search table must not be writable\n"
+msgstr ""
+"tabla de búsqueda de marco de llamada no debe tener permiso de escritura\n"
+
+#: src/elflint.c:4647
+#, c-format
+msgid "section [%2zu] '%s' must not be writable\n"
+msgstr "sección [%2zu] '%s' no debe tener permiso de escritura\n"
+
+#: src/elflint.c:4652
+#, c-format
+msgid "call frame search table must not be executable\n"
+msgstr "tabla de búsqueda de marco de llamada no debe ser ejecutable\n"
+
+#: src/elflint.c:4655
+#, c-format
+msgid "section [%2zu] '%s' must not be executable\n"
+msgstr "sección [%2zu] '%s' no debe ser ejecutable\n"
+
+#: src/elflint.c:4666
+#, c-format
+msgid "program header entry %d: file size greater than memory size\n"
+msgstr ""
+"entrada de encabezamiento de programa %d: tamaño de fichero mayor que el "
+"tamaño de memoria\n"
+
+#: src/elflint.c:4673
+#, c-format
+msgid "program header entry %d: alignment not a power of 2\n"
+msgstr ""
+"entrada de encabezamiento de programa %d: alineamiento no es potencia de 2\n"
+
+#: src/elflint.c:4676
+#, c-format
+msgid ""
+"program header entry %d: file offset and virtual address not module of "
+"alignment\n"
+msgstr ""
+"entrada de encabezamiento de programa %d: compensación de fichero y "
+"dirección virtual no módulo de alineación\n"
+
+#: src/elflint.c:4689
+#, c-format
+msgid ""
+"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME "
+"program header entry"
+msgstr ""
+"ejecutable/DSO con sección .eh_frame_hdr no tiene una entrada de "
+"encabezamiento de programa PT_GNU_EH_FRAME"
+
+#: src/elflint.c:4723
+#, c-format
+msgid "cannot read ELF header: %s\n"
+msgstr "No se puede leer encabezamiento ELF: %s\n"
+
+#: src/elflint.c:4749
+#, c-format
+msgid "text relocation flag set but not needed\n"
+msgstr "Bandera de reubicación de texto establecida pero no necesaria\n"
+
+#: src/findtextrel.c:61
+msgid "Input Selection:"
+msgstr "Selección de entrada:"
+
+#: src/findtextrel.c:62
+msgid "Prepend PATH to all file names"
+msgstr "Agregar RUTA a todos los nombres de ficheros"
+
+#: src/findtextrel.c:64
+msgid "Use PATH as root of debuginfo hierarchy"
+msgstr "Usar RUTA como root de jerarquía de debuginfo"
+
+#. Short description of program.
+#: src/findtextrel.c:71
+msgid "Locate source of text relocations in FILEs (a.out by default)."
+msgstr ""
+"Localizar origen de reubicaciones de texto en FICHEROS (a.out por defecto)."
+
+#. Strings for arguments in help texts.
+#: src/findtextrel.c:75 src/nm.c:109 src/objdump.c:72 src/size.c:81
+#: src/strings.c:88 src/strip.c:99
+msgid "[FILE...]"
+msgstr "[FICHERO...]"
+
+#: src/findtextrel.c:223
+#, c-format
+msgid "cannot get ELF header '%s': %s"
+msgstr "No se puede obtener encabezamiento ELF '%s': %s"
+
+#: src/findtextrel.c:234
+#, c-format
+msgid "'%s' is not a DSO or PIE"
+msgstr "'%s' es no un DSO o PIE"
+
+#: src/findtextrel.c:254
+#, c-format
+msgid "getting get section header of section %zu: %s"
+msgstr "obtener encabezamiento de sección get de sección %zu: %s"
+
+#: src/findtextrel.c:277
+#, c-format
+msgid "cannot read dynamic section: %s"
+msgstr "No se puede leer sección dinámica: %s"
+
+#: src/findtextrel.c:298
+#, c-format
+msgid "no text relocations reported in '%s'"
+msgstr "no hay reubicaciones de texto reportado en '%s'"
+
+#: src/findtextrel.c:310
+#, c-format
+msgid "while reading ELF file"
+msgstr "Error al leer fichero ELF"
+
+#: src/findtextrel.c:314
+#, fuzzy, c-format
+msgid "cannot get program header count: %s"
+msgstr "no se puede obtener memoria para encabezamiento del programa: %s"
+
+#: src/findtextrel.c:325 src/findtextrel.c:342
+#, fuzzy, c-format
+msgid "cannot get program header index at offset %zd: %s"
+msgstr ""
+"Nos se puede obtener el índice de encabezamiento de programa en compensación "
+"%d: %s"
+
+#: src/findtextrel.c:406
+#, c-format
+msgid "cannot get symbol table section %zu in '%s': %s"
+msgstr "No se puede obtener tabla de símbolos %zu en '%s': %s"
+
+#: src/findtextrel.c:426 src/findtextrel.c:449
+#, c-format
+msgid "cannot get relocation at index %d in section %zu in '%s': %s"
+msgstr ""
+"No se puede obtener reubicación en índice %d en sección %zu en '%s': %s"
+
+#: src/findtextrel.c:515
+#, c-format
+msgid "%s not compiled with -fpic/-fPIC\n"
+msgstr "%s no compilado con -fpic/-fPIC\n"
+
+#: src/findtextrel.c:568
+#, c-format
+msgid ""
+"the file containing the function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+"El archivo que contiene la función '%s' no está compilado con -fpic/-fPIC\n"
+
+#: src/findtextrel.c:575 src/findtextrel.c:595
+#, c-format
+msgid ""
+"the file containing the function '%s' might not be compiled with -fpic/-"
+"fPIC\n"
+msgstr ""
+"el fichero que contiene la función '%s' podría no estar compilado con -fpic/-"
+"fPIC\n"
+
+#: src/findtextrel.c:583
+#, c-format
+msgid ""
+"either the file containing the function '%s' or the file containing the "
+"function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+"Tanto el fichero que contiene la función '%s' como el fichero que contiene "
+"la función '%s' no están compilados con -fpic/-fPIC\n"
+
+#: src/findtextrel.c:603
+#, c-format
+msgid ""
+"a relocation modifies memory at offset %llu in a write-protected segment\n"
+msgstr ""
+"Una reubicación modifica memoria en compensación %llu en un segmento "
+"protegido contra escritura\n"
+
+#: src/nm.c:67 src/strip.c:70
+msgid "Output selection:"
+msgstr "Selección de salida:"
+
+#: src/nm.c:68
+msgid "Display debugger-only symbols"
+msgstr "Mostrar sólo símbolos del depurador"
+
+#: src/nm.c:69
+msgid "Display only defined symbols"
+msgstr "Mostrar sólo símbolos definidos"
+
+#: src/nm.c:72
+msgid "Display dynamic symbols instead of normal symbols"
+msgstr "Mostrar símbolos dinámicos en lugar de símbolos normales"
+
+#: src/nm.c:73
+msgid "Display only external symbols"
+msgstr "Mostrar sólo símbolos externos"
+
+#: src/nm.c:74
+msgid "Display only undefined symbols"
+msgstr "Mostrar sólo símbolos indefinidos"
+
+#: src/nm.c:76
+msgid "Include index for symbols from archive members"
+msgstr "Incluir índices para símbolos de miembros de archivo"
+
+#: src/nm.c:78 src/size.c:55
+msgid "Output format:"
+msgstr "Formato de salida:"
+
+#: src/nm.c:80
+msgid "Print name of the input file before every symbol"
+msgstr "Imprimir nombre de archivo de entrada antes de cada símbolo"
+
+#: src/nm.c:83
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd', `sysv' or `posix'.  The "
+"default is `sysv'"
+msgstr ""
+"Usar el formato de salida FORMATO.  FORMATO puede ser o bien `bsd', o "
+"`sysv', o `posix'. El establecido por defecto es `sysv'"
+
+#: src/nm.c:85
+msgid "Same as --format=bsd"
+msgstr "lo mismo que --format=bsd"
+
+#: src/nm.c:86
+msgid "Same as --format=posix"
+msgstr "lo mismo que --format=posix"
+
+#: src/nm.c:87 src/size.c:61
+msgid "Use RADIX for printing symbol values"
+msgstr "Utilizar RADIX para imprimir valores de símbolo"
+
+#: src/nm.c:88
+#, fuzzy
+msgid "Mark special symbols"
+msgstr "Marcar símbolos débiles"
+
+#: src/nm.c:90
+msgid "Print size of defined symbols"
+msgstr "Tamaño de impresión de símbolos definidos"
+
+#: src/nm.c:92 src/size.c:69 src/strip.c:75 src/unstrip.c:73
+msgid "Output options:"
+msgstr "Opciones de salida:"
+
+#: src/nm.c:93
+msgid "Sort symbols numerically by address"
+msgstr "Ordenar los símbolos numéricos por dirección"
+
+#: src/nm.c:95
+msgid "Do not sort the symbols"
+msgstr "No ordenar los símbolos"
+
+#: src/nm.c:96
+msgid "Reverse the sense of the sort"
+msgstr "Invertir el orden"
+
+#: src/nm.c:99
+msgid "Decode low-level symbol names into source code names"
+msgstr ""
+
+#. Short description of program.
+#: src/nm.c:106
+msgid "List symbols from FILEs (a.out by default)."
+msgstr "Listar símbolos de FICHEROS (a.out por defecto)."
+
+#: src/nm.c:117 src/objdump.c:80
+#, fuzzy
+msgid "Output formatting"
+msgstr "Formato de salida:"
+
+#: src/nm.c:141 src/objdump.c:104 src/size.c:106 src/strip.c:131
+#, fuzzy, c-format
+msgid "%s: INTERNAL ERROR %d (%s): %s"
+msgstr "%s: ERROR INTERNO %d (%s-%s): %s"
+
+#: src/nm.c:382 src/nm.c:394 src/size.c:289 src/size.c:298 src/size.c:309
+#: src/strip.c:2421
+#, c-format
+msgid "while closing '%s'"
+msgstr "error al cerrar '%s'"
+
+#: src/nm.c:404 src/objdump.c:281 src/strip.c:443
+#, c-format
+msgid "%s: File format not recognized"
+msgstr "%s: No se reconoce el formato del fichero"
+
+#. Note: 0 is no valid offset.
+#: src/nm.c:444
+#, fuzzy
+msgid ""
+"\n"
+"Archive index:\n"
+msgstr ""
+"\n"
+"Índice de archivo:"
+
+#: src/nm.c:453
+#, c-format
+msgid "invalid offset %zu for symbol %s"
+msgstr "Compensación %zu inválida para símbolo %s"
+
+#: src/nm.c:458
+#, c-format
+msgid "%s in %s\n"
+msgstr "%s en %s\n"
+
+#: src/nm.c:466
+#, c-format
+msgid "cannot reset archive offset to beginning"
+msgstr "imposible restablecer compensación de archivo al inicio"
+
+#: src/nm.c:491 src/objdump.c:329
+#, c-format
+msgid "%s%s%s: file format not recognized"
+msgstr "%s%s%s: no se reconoció el formato de fichero"
+
+#: src/nm.c:706
+#, c-format
+msgid "cannot create search tree"
+msgstr "No se puede crear el árbol de búsqueda"
+
+#: src/nm.c:747 src/nm.c:1208 src/objdump.c:778 src/readelf.c:551
+#: src/readelf.c:1129 src/readelf.c:1329 src/readelf.c:1477 src/readelf.c:1678
+#: src/readelf.c:1884 src/readelf.c:2074 src/readelf.c:2252 src/readelf.c:2328
+#: src/readelf.c:2586 src/readelf.c:2662 src/readelf.c:2749 src/readelf.c:3329
+#: src/readelf.c:3379 src/readelf.c:3442 src/readelf.c:8444 src/readelf.c:9544
+#: src/readelf.c:9747 src/readelf.c:9815 src/size.c:397 src/size.c:466
+#: src/strip.c:572
+#, c-format
+msgid "cannot get section header string table index"
+msgstr "no se puede obtener índice de cadena de encabezamiento de sección"
+
+#. We always print this prolog.
+#: src/nm.c:774
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s:\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Símbolos de %s:\n"
+"\n"
+
+#. The header line.
+#: src/nm.c:777
+#, c-format
+msgid ""
+"%*s%-*s %-*s Class  Type     %-*s %*s Section\n"
+"\n"
+msgstr ""
+"%*s%-*s %-*s Clase  Tipo     %-*s %*s Sección\n"
+"\n"
+
+#: src/nm.c:1219
+#, fuzzy, c-format
+msgid "%s: entry size in section %zd `%s' is not what we expect"
+msgstr ""
+"%s: el tamaño de la entrada en la sección `%s' no es el que esperábamos "
+
+#: src/nm.c:1224
+#, fuzzy, c-format
+msgid "%s: size of section %zd `%s' is not multiple of entry size"
+msgstr "%s: Tamaño de sección `%s' no es múltiplo de tamaño de entrada"
+
+#: src/nm.c:1303
+#, fuzzy, c-format
+msgid "%s: entries (%zd) in section %zd `%s' is too large"
+msgstr ""
+"%s: el tamaño de la entrada en la sección `%s' no es el que esperábamos "
+
+#. XXX Add machine specific object file types.
+#: src/nm.c:1529
+#, c-format
+msgid "%s%s%s%s: Invalid operation"
+msgstr "%s%s%s%s: Operación inválida"
+
+#: src/nm.c:1586
+#, c-format
+msgid "%s%s%s: no symbols"
+msgstr "%s%s%s: No hay símbolos"
+
+#: src/objdump.c:53
+msgid "Mode selection:"
+msgstr "Selección de modo:"
+
+#: src/objdump.c:54
+msgid "Display relocation information."
+msgstr "Mostrar la reubicación de información."
+
+#: src/objdump.c:56
+msgid "Display the full contents of all sections requested"
+msgstr "Mostrar el contenido total de todas las secciones solicitadas"
+
+#: src/objdump.c:58
+msgid "Display assembler code of executable sections"
+msgstr "Mostrar código de ensamblador de secciones ejecutables"
+
+#: src/objdump.c:60
+#, fuzzy
+msgid "Output content selection:"
+msgstr "Selección de opción de salida:"
+
+#: src/objdump.c:62
+msgid "Only display information for section NAME."
+msgstr "Sólo muestra información para NOMBRE de sección."
+
+#. Short description of program.
+#: src/objdump.c:68
+msgid "Show information from FILEs (a.out by default)."
+msgstr "Muestra información de FICHEROS (a.out por defecto)."
+
+#: src/objdump.c:219 src/readelf.c:499
+msgid "No operation specified.\n"
+msgstr "No se especificó una operación.\n"
+
+#: src/objdump.c:259 src/objdump.c:271
+#, c-format
+msgid "while close `%s'"
+msgstr "mientras cierra `%s'"
+
+#: src/objdump.c:364 src/readelf.c:1979 src/readelf.c:2171
+msgid "INVALID SYMBOL"
+msgstr "SÍMBOLO INVÁLIDO"
+
+#: src/objdump.c:379 src/readelf.c:2013 src/readelf.c:2207
+msgid "INVALID SECTION"
+msgstr "SECCIÓN INVÁLIDA"
+
+#: src/objdump.c:499
+#, c-format
+msgid ""
+"\n"
+"RELOCATION RECORDS FOR [%s]:\n"
+"%-*s TYPE                 VALUE\n"
+msgstr ""
+"\n"
+"REUBICACIÓN DE REGISTROS PARA [%s]:\n"
+"%-*s TIPO                 VALOR\n"
+
+#: src/objdump.c:502
+msgid "OFFSET"
+msgstr "COMPENSACIÓN"
+
+#: src/objdump.c:567
+#, c-format
+msgid "Contents of section %s:\n"
+msgstr "Contenido de la sección %s:\n"
+
+#: src/objdump.c:688
+#, c-format
+msgid "cannot disassemble"
+msgstr "No se puede desensamblar"
+
+#. Short description of program.
+#: src/ranlib.c:64
+msgid "Generate an index to speed access to archives."
+msgstr " Generar un índice para acelerar el acceso a los archivos."
+
+#. Strings for arguments in help texts.
+#: src/ranlib.c:67
+msgid "ARCHIVE"
+msgstr "ARCHIVO "
+
+#: src/ranlib.c:103
+#, c-format
+msgid "Archive name required"
+msgstr "Se requiere nombre de archivo"
+
+#: src/ranlib.c:167
+#, c-format
+msgid "'%s' is no archive"
+msgstr "%s: no es un archivo"
+
+#: src/ranlib.c:202
+#, c-format
+msgid "error while freeing sub-ELF descriptor: %s"
+msgstr "error al liberar descriptor sub-ELF: %s"
+
+#: src/readelf.c:87
+#, fuzzy
+msgid "ELF input selection:"
+msgstr "Selección de salida de ELF:"
+
+#: src/readelf.c:89
+msgid ""
+"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data"
+msgstr ""
+
+#: src/readelf.c:91
+msgid "ELF output selection:"
+msgstr "Selección de salida de ELF:"
+
+#: src/readelf.c:93
+msgid "All these plus -p .strtab -p .dynstr -p .comment"
+msgstr "Todo esto mas -p .strtab -p .dynstr -p .comment"
+
+#: src/readelf.c:94
+msgid "Display the dynamic segment"
+msgstr "Mostrar el segmento dinámico"
+
+#: src/readelf.c:95
+msgid "Display the ELF file header"
+msgstr "Mostrar el encabezamiento del fichero ELF"
+
+#: src/readelf.c:97
+msgid "Display histogram of bucket list lengths"
+msgstr "Mostrar histograma de las longitudes de las listas de cubetas"
+
+#: src/readelf.c:98
+msgid "Display the program headers"
+msgstr "Mostrar encabezamientos de programa"
+
+#: src/readelf.c:100
+msgid "Display relocations"
+msgstr "Mostrar reubicaciones"
+
+#: src/readelf.c:101
+msgid "Display the sections' headers"
+msgstr "Mostrar los encabezados de las secciones"
+
+#: src/readelf.c:104
+#, fuzzy
+msgid "Display the symbol table sections"
+msgstr "Mostrar la tabla de símbolos"
+
+#: src/readelf.c:105
+msgid "Display versioning information"
+msgstr "Mostrar información de versión"
+
+#: src/readelf.c:106
+msgid "Display the ELF notes"
+msgstr "Mostrar las notas ELF"
+
+#: src/readelf.c:108
+msgid "Display architecture specific information, if any"
+msgstr "Mostrar información específica de la arquitectura (si es que la hay)"
+
+#: src/readelf.c:110
+msgid "Display sections for exception handling"
+msgstr "Muestra secciones para manejo de excepciones"
+
+#: src/readelf.c:112
+msgid "Additional output selection:"
+msgstr "Selección de salida adicional:"
+
+#: src/readelf.c:114
+#, fuzzy
+msgid ""
+"Display DWARF section content.  SECTION can be one of abbrev, aranges, "
+"decodedaranges, frame, gdb_index, info, loc, line, decodedline, ranges, "
+"pubnames, str, macinfo, macro or exception"
+msgstr ""
+"Mostrar el contenido de la sección DWARF. SECCIÓN puede ser algo de lo "
+"siguiente: abbrev, aranges, frame, info, loc, line, ranges, pubnames, str, "
+"macinfo, o exception"
+
+#: src/readelf.c:118
+msgid "Dump the uninterpreted contents of SECTION, by number or name"
+msgstr "Vuelca los contenidos no interpretados de SECCIÓN, por número o nombre"
+
+#: src/readelf.c:120
+msgid "Print string contents of sections"
+msgstr "Imprime contenido de cadena de secciones"
+
+#: src/readelf.c:123
+msgid "Display the symbol index of an archive"
+msgstr "Muestra el índice de símbolos de un archivo"
+
+#: src/readelf.c:125
+msgid "Output control:"
+msgstr "Control de salida:"
+
+#: src/readelf.c:127
+msgid "Do not find symbol names for addresses in DWARF data"
+msgstr ""
+"No se encuentran los nombres de símbolos para direcciones en datos DWARF"
+
+#: src/readelf.c:129
+#, fuzzy
+msgid ""
+"Display just offsets instead of resolving values to addresses in DWARF data"
+msgstr ""
+"No se encuentran los nombres de símbolos para direcciones en datos DWARF"
+
+#: src/readelf.c:131
+msgid "Ignored for compatibility (lines always wide)"
+msgstr ""
+
+#: src/readelf.c:133
+msgid ""
+"Show compression information for compressed sections (when used with -S); "
+"decompress section before dumping data (when used with -p or -x)"
+msgstr ""
+
+#. Short description of program.
+#: src/readelf.c:138
+msgid "Print information from ELF file in human-readable form."
+msgstr ""
+"Imprimir información del fichero ELF en una forma comprensible para los "
+"seres humanos."
+
+#: src/readelf.c:467
+#, c-format
+msgid "Unknown DWARF debug section `%s'.\n"
+msgstr "Sección de depuración DWARF desconocida `%s'.\n"
+
+#: src/readelf.c:535 src/readelf.c:646
+#, c-format
+msgid "cannot generate Elf descriptor: %s"
+msgstr "no se puede crear descriptor ELF: %s"
+
+#: src/readelf.c:542 src/readelf.c:858 src/strip.c:641
+#, c-format
+msgid "cannot determine number of sections: %s"
+msgstr "no se pudieron determinar el número de secciones: %s"
+
+#: src/readelf.c:560 src/readelf.c:1151 src/readelf.c:1353
+#, c-format
+msgid "cannot get section: %s"
+msgstr "No se puede encontrar la sección: %s"
+
+#: src/readelf.c:569 src/readelf.c:1158 src/readelf.c:1361 src/readelf.c:9767
+#: src/unstrip.c:375 src/unstrip.c:406 src/unstrip.c:455 src/unstrip.c:565
+#: src/unstrip.c:582 src/unstrip.c:619 src/unstrip.c:817 src/unstrip.c:1109
+#: src/unstrip.c:1301 src/unstrip.c:1362 src/unstrip.c:1535 src/unstrip.c:1650
+#: src/unstrip.c:1790 src/unstrip.c:1885
+#, c-format
+msgid "cannot get section header: %s"
+msgstr "No se puede obtener encabezamiento de sección: %s"
+
+#: src/readelf.c:577
+#, fuzzy, c-format
+msgid "cannot get section name"
+msgstr "no se puede obtener encabezamiento de sección\n"
+
+#: src/readelf.c:586 src/readelf.c:5562 src/readelf.c:7902 src/readelf.c:8004
+#: src/readelf.c:8181
+#, c-format
+msgid "cannot get %s content: %s"
+msgstr "No se puede obtener el contenido %s: %s"
+
+#: src/readelf.c:602
+#, fuzzy, c-format
+msgid "cannot create temp file '%s'"
+msgstr "no se puede crear fichero nuevo '%s': %s"
+
+#: src/readelf.c:611
+#, fuzzy, c-format
+msgid "cannot write section data"
+msgstr "no se puede leer la sección de datos: %s"
+
+#: src/readelf.c:617 src/readelf.c:634 src/readelf.c:663
+#, c-format
+msgid "error while closing Elf descriptor: %s"
+msgstr "error al cerrar el descriptor ELF: %s"
+
+#: src/readelf.c:624
+#, fuzzy, c-format
+msgid "error while rewinding file descriptor"
+msgstr "error al cerrar el descriptor ELF: %s"
+
+#: src/readelf.c:658
+#, c-format
+msgid "'%s' is not an archive, cannot print archive index"
+msgstr "'%s' no es un archivo, no se puede imprimir índice de archivo"
+
+#: src/readelf.c:757
+#, fuzzy, c-format
+msgid "No such section '%s' in '%s'"
+msgstr "No se puede obtener contenido de sección %zu en '%s': %s"
+
+#: src/readelf.c:784
+#, c-format
+msgid "cannot stat input file"
+msgstr "no sepudo stat archivo de entrada"
+
+#: src/readelf.c:786
+#, c-format
+msgid "input file is empty"
+msgstr "archivo de entrada vacío"
+
+#: src/readelf.c:788
+#, c-format
+msgid "failed reading '%s': %s"
+msgstr "Falló lectura de '%s': %s"
+
+#: src/readelf.c:843
+#, c-format
+msgid "cannot read ELF header: %s"
+msgstr "no se pudo leer encabezamiento ELF: %s"
+
+#: src/readelf.c:851
+#, c-format
+msgid "cannot create EBL handle"
+msgstr "no se puede crear EBL"
+
+#: src/readelf.c:864
+#, c-format
+msgid "cannot determine number of program headers: %s"
+msgstr "no se pudo determinar la cantidad de encabezados de programa: %s"
+
+#: src/readelf.c:954
+msgid "NONE (None)"
+msgstr "NONE (Ninguno)"
+
+#: src/readelf.c:955
+msgid "REL (Relocatable file)"
+msgstr "REL (Fichero reubicable)"
+
+#: src/readelf.c:956
+msgid "EXEC (Executable file)"
+msgstr "EXEC (Fichero ejecutable)"
+
+#: src/readelf.c:957
+msgid "DYN (Shared object file)"
+msgstr "DYN (Fichero objeto compartido)"
+
+#: src/readelf.c:958
+msgid "CORE (Core file)"
+msgstr "CORE (Fichero núcleo)"
+
+#: src/readelf.c:963
+#, c-format
+msgid "OS Specific: (%x)\n"
+msgstr "OS Specific: (%x)\n"
+
+#. && e_type <= ET_HIPROC always true
+#: src/readelf.c:965
+#, c-format
+msgid "Processor Specific: (%x)\n"
+msgstr "Específico del procesador: (%x)\n"
+
+#: src/readelf.c:975
+msgid ""
+"ELF Header:\n"
+"  Magic:  "
+msgstr ""
+"Encabezamiento ELF:\n"
+"  Mágico:  "
+
+#: src/readelf.c:979
+#, c-format
+msgid ""
+"\n"
+"  Class:                             %s\n"
+msgstr ""
+"\n"
+"  Clase:                             %s\n"
+
+#: src/readelf.c:984
+#, c-format
+msgid "  Data:                              %s\n"
+msgstr "  Datos:                             %s\n"
+
+#: src/readelf.c:990
+#, c-format
+msgid "  Ident Version:                     %hhd %s\n"
+msgstr "  Versión ident:                     %hhd %s\n"
+
+#: src/readelf.c:992 src/readelf.c:1009
+msgid "(current)"
+msgstr "(actual)"
+
+#: src/readelf.c:996
+#, c-format
+msgid "  OS/ABI:                            %s\n"
+msgstr "  OS/ABI:                            %s\n"
+
+#: src/readelf.c:999
+#, c-format
+msgid "  ABI Version:                       %hhd\n"
+msgstr "  Versión ABI:                       %hhd\n"
+
+#: src/readelf.c:1002
+msgid "  Type:                              "
+msgstr "  Tipo:                              "
+
+#: src/readelf.c:1005
+#, c-format
+msgid "  Machine:                           %s\n"
+msgstr "  Máquina:                           %s\n"
+
+#: src/readelf.c:1007
+#, c-format
+msgid "  Version:                           %d %s\n"
+msgstr "  Versión:                           %d %s\n"
+
+#: src/readelf.c:1011
+#, c-format
+msgid "  Entry point address:               %#<PRIx64>\n"
+msgstr "  Dirección de punto de entrada:               %#<PRIx64>\n"
+
+#: src/readelf.c:1014
+#, c-format
+msgid "  Start of program headers:          %<PRId64> %s\n"
+msgstr "  Inicio de encabezamientos de programa:          %<PRId64> %s\n"
+
+#: src/readelf.c:1015 src/readelf.c:1018
+msgid "(bytes into file)"
+msgstr " (bytes en el archivo)"
+
+#: src/readelf.c:1017
+#, c-format
+msgid "  Start of section headers:          %<PRId64> %s\n"
+msgstr "  Inicio de encabezamientos de sección:          %<PRId64> %s\n"
+
+#: src/readelf.c:1020
+#, c-format
+msgid "  Flags:                             %s\n"
+msgstr "  Indicadores:                             %s\n"
+
+#: src/readelf.c:1023
+#, c-format
+msgid "  Size of this header:               %<PRId16> %s\n"
+msgstr "  Tamaño de este encabezamiento:               %<PRId16> %s\n"
+
+#: src/readelf.c:1024 src/readelf.c:1027 src/readelf.c:1044
+msgid "(bytes)"
+msgstr "(bytes)"
+
+#: src/readelf.c:1026
+#, c-format
+msgid "  Size of program header entries:    %<PRId16> %s\n"
+msgstr ""
+"  Tamaño de las entradas en encabezamiento del programa:    %<PRId16> %s\n"
+
+#: src/readelf.c:1029
+#, c-format
+msgid "  Number of program headers entries: %<PRId16>"
+msgstr "  Cantidad de entradas de encabezados de programa: %<PRId16>"
+
+#: src/readelf.c:1036
+#, c-format
+msgid " (%<PRIu32> in [0].sh_info)"
+msgstr " (%<PRIu32> in [0].sh_info)"
+
+#: src/readelf.c:1039 src/readelf.c:1056 src/readelf.c:1070
+msgid " ([0] not available)"
+msgstr " ([0] no disponible)"
+
+#: src/readelf.c:1043
+#, c-format
+msgid "  Size of section header entries:    %<PRId16> %s\n"
+msgstr ""
+"  Tamaño de las entradas en el encabezamiento de sección:    %<PRId16> %s\n"
+
+#: src/readelf.c:1046
+#, c-format
+msgid "  Number of section headers entries: %<PRId16>"
+msgstr "  Cantidad de entradas en los encabezamientos de sección: %<PRId16>"
+
+#: src/readelf.c:1053
+#, c-format
+msgid " (%<PRIu32> in [0].sh_size)"
+msgstr " (%<PRIu32> en [0].sh_size)"
+
+#. We managed to get the zeroth section.
+#: src/readelf.c:1066
+#, c-format
+msgid " (%<PRIu32> in [0].sh_link)"
+msgstr " (%<PRIu32> en [0].sh_link)"
+
+#: src/readelf.c:1074
+#, c-format
+msgid ""
+"  Section header string table index: XINDEX%s\n"
+"\n"
+msgstr ""
+"  Índice de tabla de cadenas de sección de encabezamiento de : XINDEX%s\n"
+"\n"
+
+#: src/readelf.c:1078
+#, c-format
+msgid ""
+"  Section header string table index: %<PRId16>\n"
+"\n"
+msgstr "  Índice de tabla de cadenas de sección de encabezamiento: %<PRId16>\n"
+
+#: src/readelf.c:1121
+#, c-format
+msgid ""
+"There are %d section headers, starting at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+"Hay %d encabezamientos de sección, comenzando en compensación %#<PRIx64>:\n"
+"\n"
+
+#: src/readelf.c:1131
+msgid "Section Headers:"
+msgstr "encabezamientos de sección:"
+
+#: src/readelf.c:1134
+msgid ""
+"[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
+"Inf Al"
+msgstr ""
+"[Nr] Nombre            Tipo            Dirección    Off    Tamaño    Inf Al "
+"Enlace banderas ES"
+
+#: src/readelf.c:1136
+msgid ""
+"[Nr] Name                 Type         Addr             Off      Size     ES "
+"Flags Lk Inf Al"
+msgstr ""
+"[Nr] Name                 Type         Addr             Off      Size     ES "
+"Flags Lk Inf Al"
+
+#: src/readelf.c:1141
+msgid "     [Compression  Size   Al]"
+msgstr ""
+
+#: src/readelf.c:1143
+msgid "     [Compression  Size     Al]"
+msgstr ""
+
+#: src/readelf.c:1219
+#, fuzzy, c-format
+msgid "bad compression header for section %zd: %s"
+msgstr "No se puede obtener el encabezamiento de sección %zu: %s"
+
+#: src/readelf.c:1230
+#, fuzzy, c-format
+msgid "bad gnu compressed size for section %zd: %s"
+msgstr "No se pueden obtener datos para la sección %d: %s"
+
+#: src/readelf.c:1248
+msgid "Program Headers:"
+msgstr "encabezamientos de programa:"
+
+#: src/readelf.c:1250
+msgid ""
+"  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
+msgstr ""
+"  Tipo           Compensación  Dirección Virtual       Dirección "
+"Física       Tamaño de Fichero  Tamaño de Memoria     Alineación de bandera"
+
+#: src/readelf.c:1253
+msgid ""
+"  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
+"MemSiz   Flg Align"
+msgstr ""
+"  Tipo          Compensación  Dirección Virtual            Dirección "
+"Física          Tamaño de Fichero  Tamaño de Memoria   Alineación de bandera"
+
+#: src/readelf.c:1310
+#, c-format
+msgid "\t[Requesting program interpreter: %s]\n"
+msgstr "\t[Solicitando intérprete de programa: %s]\n"
+
+#: src/readelf.c:1331
+msgid ""
+"\n"
+" Section to Segment mapping:\n"
+"  Segment Sections..."
+msgstr ""
+"\n"
+" Sección para asignación de segmento:\n"
+"  Secciones de segmento..."
+
+#: src/readelf.c:1342 src/unstrip.c:1944 src/unstrip.c:1986 src/unstrip.c:1993
+#, c-format
+msgid "cannot get program header: %s"
+msgstr "no se puede obtener memoria para encabezamiento del programa: %s"
+
+#: src/readelf.c:1485
+#, c-format
+msgid ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"Grupo de sección COMDAT [%2zu] '%s' con firma '%s' contiene entrada %zu:\n"
+msgstr[1] ""
+"\n"
+"Grupo de sección COMDAT [%2zu] '%s' con firma '%s' contiene entradas %zu:\n"
+
+#: src/readelf.c:1490
+#, c-format
+msgid ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"Grupo de sección [%2zu] '%s' con firma '%s' contiene entrada %zu:\n"
+msgstr[1] ""
+"\n"
+"Grupo de sección [%2zu] '%s' con firma '%s' contiene entradas %zu:\n"
+
+#: src/readelf.c:1498
+msgid "<INVALID SYMBOL>"
+msgstr "<SÍMBOLO INVÁLIDO>"
+
+#: src/readelf.c:1512
+msgid "<INVALID SECTION>"
+msgstr "<SECCIÓN INVÁLIDA>"
+
+#: src/readelf.c:1535 src/readelf.c:2262 src/readelf.c:3345 src/readelf.c:9638
+#: src/readelf.c:9645 src/readelf.c:9689 src/readelf.c:9696
+msgid "Couldn't uncompress section"
+msgstr ""
+
+#: src/readelf.c:1540 src/readelf.c:2267 src/readelf.c:3350
+#, fuzzy, c-format
+msgid "cannot get section [%zd] header: %s"
+msgstr "No se puede obtener encabezamiento de sección: %s"
+
+#: src/readelf.c:1684 src/readelf.c:2334 src/readelf.c:2592 src/readelf.c:2668
+#: src/readelf.c:2972 src/readelf.c:3046 src/readelf.c:4773
+#, fuzzy, c-format
+msgid "invalid sh_link value in section %zu"
+msgstr ".debug_line section inválida"
+
+#: src/readelf.c:1687
+#, c-format
+msgid ""
+"\n"
+"Dynamic segment contains %lu entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Dynamic segment contains %lu entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Segmento dinámico contiene entrada %lu:\n"
+" Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
+"[%2u] '%s'\n"
+msgstr[1] ""
+"\n"
+"Segmento dinámico contiene entradas %lu:\n"
+" Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
+"[%2u] '%s'\n"
+
+#: src/readelf.c:1697
+msgid "  Type              Value\n"
+msgstr "  Tipo              Valor\n"
+
+#: src/readelf.c:1721
+#, c-format
+msgid "Shared library: [%s]\n"
+msgstr "Biblioteca compartida: [%s]\n"
+
+#: src/readelf.c:1726
+#, c-format
+msgid "Library soname: [%s]\n"
+msgstr "Nombre-so de la biblioteca: [%s]\n"
+
+#: src/readelf.c:1731
+#, c-format
+msgid "Library rpath: [%s]\n"
+msgstr "Rpath de la biblioteca: [%s]\n"
+
+#: src/readelf.c:1736
+#, c-format
+msgid "Library runpath: [%s]\n"
+msgstr "Ruta de ejecución de la biblioteca: [%s]\n"
+
+#: src/readelf.c:1756
+#, c-format
+msgid "%<PRId64> (bytes)\n"
+msgstr "%<PRId64> (bytes)\n"
+
+#: src/readelf.c:1869 src/readelf.c:2059
+#, c-format
+msgid ""
+"\n"
+"Invalid symbol table at offset %#0<PRIx64>\n"
+msgstr ""
+"\n"
+"Tabla de símbolos inválida en compensación %#0<PRIx64>\n"
+
+#: src/readelf.c:1887 src/readelf.c:2077
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"Sección de reubicación [%2zu] '%s' para sección [%2u] '%s' en compensación "
+"%#0<PRIx64> contiene entrada %d:\n"
+msgstr[1] ""
+"\n"
+"Sección de reubicación [%2zu] '%s' para sección [%2u] '%s' en compensación "
+"%#0<PRIx64> contiene entradas %d:\n"
+
+#. The .rel.dyn section does not refer to a specific section but
+#. instead of section index zero.  Do not try to print a section
+#. name.
+#. The .rela.dyn section does not refer to a specific section but
+#. instead of section index zero.  Do not try to print a section
+#. name.
+#: src/readelf.c:1902 src/readelf.c:2092
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"Sección de reubicación[%2u] '%s' en compensación %#0<PRIx64> contiene "
+"entrada %d:\n"
+msgstr[1] ""
+"\n"
+"Sección de reubicación [%2u] '%s' en compensación %#0<PRIx64> contiene "
+"entradas %d:\n"
+
+#: src/readelf.c:1912
+msgid "  Offset      Type                 Value       Name\n"
+msgstr "   Compensación           Tipo               Valor      Nombre\n"
+
+#: src/readelf.c:1914
+msgid "  Offset              Type                 Value               Name\n"
+msgstr "    Compensación           Tipo               Valor           Nombre\n"
+
+#: src/readelf.c:1967 src/readelf.c:1978 src/readelf.c:1991 src/readelf.c:2012
+#: src/readelf.c:2024 src/readelf.c:2158 src/readelf.c:2170 src/readelf.c:2184
+#: src/readelf.c:2206 src/readelf.c:2219
+msgid "<INVALID RELOC>"
+msgstr "<REUBIC INVÁLIDA>"
+
+#: src/readelf.c:2102
+msgid "  Offset      Type            Value       Addend Name\n"
+msgstr "    Compensación            Tipo               Valor    Nombre Adend\n"
+
+#: src/readelf.c:2104
+msgid "  Offset              Type            Value               Addend Name\n"
+msgstr "    Compensación            Tipo               Valor   Nombre Adend\n"
+
+#: src/readelf.c:2342
+#, c-format
+msgid ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entry:\n"
+msgid_plural ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entries:\n"
+msgstr[0] ""
+"\n"
+"La tabla de símbolos [%2u] '%s' contiene entrada %u:\n"
+msgstr[1] ""
+"\n"
+"La tabla de símbolos [%2u] '%s' contiene entradas %u:\n"
+
+#: src/readelf.c:2347
+#, c-format
+msgid " %lu local symbol  String table: [%2u] '%s'\n"
+msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
+msgstr[0] "símbolos locales %lu Tabla de cadena: [%2u] '%s'\n"
+msgstr[1] " Símbolos locales %lu Tabla de cadenas: [%2u] '%s'\n"
+
+#: src/readelf.c:2355
+msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr "  Núm:    Valor       Tamaño Tipo    Unión  Vis          Nombre Ndx\n"
+
+#: src/readelf.c:2357
+msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr "   Num:    Valor          Tamaño Tipo    Unión  Vis      Nombre Ndx\n"
+
+#: src/readelf.c:2377
+#, c-format
+msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+msgstr "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+
+#: src/readelf.c:2465
+#, c-format
+msgid "bad dynamic symbol"
+msgstr "símbolo dinámico erróneo"
+
+#: src/readelf.c:2547
+msgid "none"
+msgstr "nada"
+
+#: src/readelf.c:2564
+msgid "| <unknown>"
+msgstr "| <desconocido>"
+
+#: src/readelf.c:2595
+#, c-format
+msgid ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Sección de versión necesita [%2u] '%s' contiene entrada %d entry:\n"
+" Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
+"[%2u] '%s'\n"
+msgstr[1] ""
+"\n"
+"Versión necesita sección [%2u] '%s' contiene entrada %d:\n"
+" Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
+"[%2u] '%s'\n"
+
+#: src/readelf.c:2616
+#, c-format
+msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
+msgstr "  %#06x: Versión: %hu  Fichero: %s  Conteo: %hu\n"
+
+#: src/readelf.c:2629
+#, c-format
+msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
+msgstr "  %#06x: Nombre: %s  Banderas: %s  Versión: %hu\n"
+
+#: src/readelf.c:2672
+#, c-format
+msgid ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Sección de definición de versión [%2u] '%s' contiene entrada %d:\n"
+" Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
+"[%2u] '%s'\n"
+msgstr[1] ""
+"\n"
+"Sección de definición de versión [%2u] '%s' contiene %d entrada:\n"
+" Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
+"[%2u] '%s'\n"
+
+#: src/readelf.c:2700
+#, c-format
+msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
+msgstr ""
+"  %#06x: Versión: %hd  Banderas: %s  Índice: %hd  Conteo: %hd  Nombre: %s\n"
+
+#: src/readelf.c:2715
+#, c-format
+msgid "  %#06x: Parent %d: %s\n"
+msgstr "  %#06x: Principal %d: %s\n"
+
+#. Print the header.
+#: src/readelf.c:2976
+#, c-format
+msgid ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgid_plural ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgstr[0] ""
+"\n"
+"Sección de versión de símbolos [%2u] '%s' contiene %d entrada:\n"
+" Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
+"[%2u] '%s'"
+msgstr[1] ""
+"\n"
+"Sección de versión de símbolos [%2u] '%s' contiene entradas %d:\n"
+" Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
+"[%2u] '%s'"
+
+#: src/readelf.c:3004
+msgid "   0 *local*                     "
+msgstr "   0 *local*                     "
+
+#: src/readelf.c:3009
+msgid "   1 *global*                    "
+msgstr "   1 *global*                    "
+
+#: src/readelf.c:3051
+#, c-format
+msgid ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"bucket):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"buckets):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Histograma para longitud de lista de cubeta en sección [%2u] '%s' (total de "
+"cubetas %d):\n"
+" Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
+"[%2u] '%s'\n"
+msgstr[1] ""
+"\n"
+"Histograma para longitud de lista de cubeta en sección [%2u] '%s' (total de "
+"cubetas %d):\n"
+" Dirección: %#0*<PRIx64>  Compensación: %#08<PRIx64>  Enlace a sección: "
+"[%2u] '%s'\n"
+
+#: src/readelf.c:3073
+#, no-c-format
+msgid " Length  Number  % of total  Coverage\n"
+msgstr " Longitud  Número  % of total  Cobertura\n"
+
+#: src/readelf.c:3075
+#, c-format
+msgid "      0  %6<PRIu32>      %5.1f%%\n"
+msgstr "      0  %6<PRIu32>      %5.1f%%\n"
+
+#: src/readelf.c:3082
+#, c-format
+msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+msgstr "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+
+#: src/readelf.c:3095
+#, c-format
+msgid ""
+" Average number of tests:   successful lookup: %f\n"
+"\t\t\t  unsuccessful lookup: %f\n"
+msgstr ""
+" Número promedio de pruebas:   búsqueda exitosa: %f\n"
+"                          búsqueda sin éxito: %f\n"
+
+#: src/readelf.c:3113 src/readelf.c:3168 src/readelf.c:3225
+#, c-format
+msgid "cannot get data for section %d: %s"
+msgstr "No se pueden obtener datos para la sección %d: %s"
+
+#: src/readelf.c:3121
+#, fuzzy, c-format
+msgid "invalid data in sysv.hash section %d"
+msgstr "Datos inválidos en sección [%zu] '%s'"
+
+#: src/readelf.c:3176
+#, fuzzy, c-format
+msgid "invalid data in sysv.hash64 section %d"
+msgstr "Datos inválidos en sección [%zu] '%s'"
+
+#: src/readelf.c:3234
+#, fuzzy, c-format
+msgid "invalid data in gnu.hash section %d"
+msgstr "Datos inválidos en sección [%zu] '%s'"
+
+#: src/readelf.c:3301
+#, c-format
+msgid ""
+" Symbol Bias: %u\n"
+" Bitmask Size: %zu bytes  %<PRIuFAST32>%% bits set  2nd hash shift: %u\n"
+msgstr ""
+" Polarización de símbolo: %u\n"
+" Tamaño de Bitmask: %zu bytes  %<PRIuFAST32>%% bits establecen segundo "
+"cambio de dispersión: %u\n"
+
+#: src/readelf.c:3390
+#, c-format
+msgid ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"Sección de lista de biblioteca [%2zu] '%s' en compensación %#0<PRIx64> "
+"contiene entrada %d:\n"
+msgstr[1] ""
+"\n"
+"Sección de lista de biblioteca [%2zu] '%s' en compensación %#0<PRIx64> "
+"contiene entradas %d:\n"
+
+#: src/readelf.c:3404
+msgid ""
+"       Library                       Time Stamp          Checksum Version "
+"Flags"
+msgstr ""
+"       Biblioteca                       Marca de tiempo          Indicadores "
+"de versión de suma de verificación"
+
+#: src/readelf.c:3454
+#, c-format
+msgid ""
+"\n"
+"Object attributes section [%2zu] '%s' of %<PRIu64> bytes at offset "
+"%#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Sección de atributos de objeto [%2zu] '%s' de %<PRIu64> bytes con "
+"desplazamiento %#0<PRIx64>:\n"
+
+#: src/readelf.c:3471
+msgid "  Owner          Size\n"
+msgstr "  Propietario          Tamaño\n"
+
+#: src/readelf.c:3500
+#, c-format
+msgid "  %-13s  %4<PRIu32>\n"
+msgstr "  %-13s  %4<PRIu32>\n"
+
+#. Unknown subsection, print and skip.
+#: src/readelf.c:3539
+#, c-format
+msgid "    %-4u %12<PRIu32>\n"
+msgstr "    %-4u %12<PRIu32>\n"
+
+#. Tag_File
+#: src/readelf.c:3544
+#, c-format
+msgid "    File: %11<PRIu32>\n"
+msgstr "    File: %11<PRIu32>\n"
+
+#: src/readelf.c:3593
+#, c-format
+msgid "      %s: %<PRId64>, %s\n"
+msgstr "      %s: %<PRId64>, %s\n"
+
+#: src/readelf.c:3596
+#, c-format
+msgid "      %s: %<PRId64>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:3599
+#, c-format
+msgid "      %s: %s\n"
+msgstr "      %s: %s\n"
+
+#: src/readelf.c:3609
+#, c-format
+msgid "      %u: %<PRId64>\n"
+msgstr "      %u: %<PRId64>\n"
+
+#: src/readelf.c:3612
+#, c-format
+msgid "      %u: %s\n"
+msgstr "      %u: %s\n"
+
+#: src/readelf.c:3657
+#, c-format
+msgid "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3660
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3665
+#, c-format
+msgid "%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%#<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3668
+#, c-format
+msgid "%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%#0*<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3674
+#, c-format
+msgid "%s+%#<PRIx64> <%s>"
+msgstr "%s+%#<PRIx64> <%s>"
+
+#: src/readelf.c:3677
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s>"
+msgstr "%s+%#0*<PRIx64> <%s>"
+
+#: src/readelf.c:3681
+#, c-format
+msgid "%#<PRIx64> <%s>"
+msgstr "%#<PRIx64> <%s>"
+
+#: src/readelf.c:3684
+#, c-format
+msgid "%#0*<PRIx64> <%s>"
+msgstr "%#0*<PRIx64> <%s>"
+
+#: src/readelf.c:3689
+#, c-format
+msgid "%s+%#<PRIx64>"
+msgstr "%s+%#<PRIx64>"
+
+#: src/readelf.c:3692
+#, c-format
+msgid "%s+%#0*<PRIx64>"
+msgstr "%s+%#0*<PRIx64>"
+
+#: src/readelf.c:4095
+msgid "empty block"
+msgstr "bloque vacío"
+
+#: src/readelf.c:4098
+#, c-format
+msgid "%zu byte block:"
+msgstr "bloque de byte %zu:"
+
+#: src/readelf.c:4495
+#, c-format
+msgid "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+msgstr "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+
+#: src/readelf.c:4552
+#, c-format
+msgid "%s %#<PRIx64> used with different address sizes"
+msgstr "%s %#<PRIx64> utilizado con direcciones de diferente tamaño"
+
+#: src/readelf.c:4559
+#, c-format
+msgid "%s %#<PRIx64> used with different offset sizes"
+msgstr "%s %#<PRIx64> utilizado con offsetr de diferente tamaño"
+
+#: src/readelf.c:4566
+#, fuzzy, c-format
+msgid "%s %#<PRIx64> used with different base addresses"
+msgstr "%s %#<PRIx64> utilizado con direcciones de diferente tamaño"
+
+#: src/readelf.c:4655
+#, c-format
+msgid " [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"
+msgstr " [%6tx] <MATERIAL INUTIL SIN UTILIZAR EN EL RESTO DE LA SECCION>\n"
+
+#: src/readelf.c:4663
+#, c-format
+msgid " [%6tx]  <UNUSED GARBAGE> ... %<PRIu64> bytes ...\n"
+msgstr " [%6tx]  <MATERIAL INUTIL NO UTILIZADO> ... %<PRIu64> bytes ...\n"
+
+#: src/readelf.c:4689
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [ Code]\n"
+msgstr ""
+"\n"
+"Sección DWARF [%2zu] '%s' en compensación %#<PRIx64>:\n"
+" [ Código]\n"
+
+#: src/readelf.c:4697
+#, c-format
+msgid ""
+"\n"
+"Abbreviation section at offset %<PRIu64>:\n"
+msgstr ""
+"\n"
+"Sección de abreviatura en compensación %<PRIu64>:\n"
+
+#: src/readelf.c:4710
+#, c-format
+msgid " *** error while reading abbreviation: %s\n"
+msgstr " *** error en lectura de abreviatura: %s\n"
+
+#: src/readelf.c:4726
+#, c-format
+msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
+msgstr " [%5u] compensación: %<PRId64>, hijos: %s, etiqueta: %s\n"
+
+#: src/readelf.c:4729 src/readelf.c:6178 src/readelf.c:6186 src/readelf.c:7759
+msgid "yes"
+msgstr "sí"
+
+#: src/readelf.c:4729 src/readelf.c:6178 src/readelf.c:7759
+msgid "no"
+msgstr "no"
+
+#: src/readelf.c:4763 src/readelf.c:4836
+#, c-format
+msgid "cannot get .debug_aranges content: %s"
+msgstr "no se ha podido obtener contenido de .debug_aranges: %s"
+
+#: src/readelf.c:4778
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"Sección DWARF [%2zu] '%s' en compensación %#<PRIx64> contiene entrada %zu:\n"
+msgstr[1] ""
+"\n"
+"Sección DWARF [%2zu] '%s' en compensación %#<PRIx64> contiene entradas %zu:\n"
+
+#: src/readelf.c:4809
+#, c-format
+msgid " [%*zu] ???\n"
+msgstr " [%*zu] ???\n"
+
+#: src/readelf.c:4811
+#, c-format
+msgid ""
+" [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
+msgstr ""
+" Inicio [%*zu]: %0#*<PRIx64>, longitud: %5<PRIu64>, compensación CU DIE: "
+"%6<PRId64>\n"
+
+#: src/readelf.c:4841 src/readelf.c:4995 src/readelf.c:5572 src/readelf.c:6529
+#: src/readelf.c:7061 src/readelf.c:7181 src/readelf.c:7345 src/readelf.c:7833
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+"\n"
+"Sección DWARF [%2zu] '%s' en compensación %#<PRIx64>:\n"
+
+#: src/readelf.c:4854 src/readelf.c:6555
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Table at offset %zu:\n"
+msgstr ""
+"\n"
+"Tabla en compensación %Zu:\n"
+
+#: src/readelf.c:4858 src/readelf.c:5596 src/readelf.c:6566
+#, c-format
+msgid "invalid data in section [%zu] '%s'"
+msgstr "Datos inválidos en sección [%zu] '%s'"
+
+#: src/readelf.c:4874
+#, fuzzy, c-format
+msgid ""
+"\n"
+" Length:        %6<PRIu64>\n"
+msgstr " (compensación: %#<PRIx64>)"
+
+#: src/readelf.c:4886
+#, fuzzy, c-format
+msgid " DWARF version: %6<PRIuFAST16>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:4890
+#, c-format
+msgid "unsupported aranges version"
+msgstr ""
+
+#: src/readelf.c:4901
+#, fuzzy, c-format
+msgid " CU offset:     %6<PRIx64>\n"
+msgstr " (compensación: %#<PRIx64>)"
+
+#: src/readelf.c:4907
+#, fuzzy, c-format
+msgid " Address size:  %6<PRIu64>\n"
+msgstr " (fin de compensación: %#<PRIx64>)"
+
+#: src/readelf.c:4911
+#, fuzzy, c-format
+msgid "unsupported address size"
+msgstr "no hay valor de dirección"
+
+#: src/readelf.c:4916
+#, fuzzy, c-format
+msgid ""
+" Segment size:  %6<PRIu64>\n"
+"\n"
+msgstr " establecer archivo a %<PRIu64>\n"
+
+#: src/readelf.c:4920
+#, c-format
+msgid "unsupported segment size"
+msgstr ""
+
+#: src/readelf.c:4960
+#, fuzzy, c-format
+msgid "   %s..%s (%<PRIx64>)\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:4963
+#, fuzzy, c-format
+msgid "   %s..%s\n"
+msgstr " [%6tx]  %s..%s\n"
+
+#: src/readelf.c:4972
+#, c-format
+msgid "   %zu padding bytes\n"
+msgstr ""
+
+#: src/readelf.c:4990
+#, c-format
+msgid "cannot get .debug_ranges content: %s"
+msgstr "no se ha podido obtener contenido de .debug_ranges: %s"
+
+#: src/readelf.c:5020 src/readelf.c:7088
+#, c-format
+msgid " [%6tx]  <INVALID DATA>\n"
+msgstr " [%6tx]  <DATOS INVÁLIDOS>\n"
+
+#: src/readelf.c:5042 src/readelf.c:7110
+#, c-format
+msgid " [%6tx]  base address %s\n"
+msgstr " [%6tx]   (dirección base) %s\n"
+
+#: src/readelf.c:5049 src/readelf.c:7117
+#, c-format
+msgid " [%6tx]  empty list\n"
+msgstr " [%6tx]  lista vacía\n"
+
+#. We have an address range entry.
+#. First address range entry in a list.
+#: src/readelf.c:5060
+#, c-format
+msgid " [%6tx]  %s..%s\n"
+msgstr " [%6tx]  %s..%s\n"
+
+#: src/readelf.c:5062
+#, c-format
+msgid "           %s..%s\n"
+msgstr "           %s..%s\n"
+
+#: src/readelf.c:5298
+#, fuzzy
+msgid "         <INVALID DATA>\n"
+msgstr "   <DATOS INVÁLIDOS>\n"
+
+#: src/readelf.c:5551
+#, fuzzy, c-format
+msgid "cannot get ELF: %s"
+msgstr "no se puede leer encabezamiento ELF: %s"
+
+#: src/readelf.c:5568
+#, c-format
+msgid ""
+"\n"
+"Call frame information section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+"\n"
+"Sección de información de marco de llamada [%2zu] '%s' en compensación "
+"%#<PRIx64>:\n"
+
+#: src/readelf.c:5618
+#, c-format
+msgid ""
+"\n"
+" [%6tx] Zero terminator\n"
+msgstr ""
+"\n"
+" [%6tx] Terminator cero\n"
+
+#: src/readelf.c:5711 src/readelf.c:5866
+#, c-format
+msgid "invalid augmentation length"
+msgstr "longitud de aumento inválida"
+
+#: src/readelf.c:5726
+msgid "FDE address encoding: "
+msgstr "Codificación de dirección FDE:"
+
+#: src/readelf.c:5732
+msgid "LSDA pointer encoding: "
+msgstr "Codificación de puntero LSDA:"
+
+#: src/readelf.c:5843
+#, c-format
+msgid " (offset: %#<PRIx64>)"
+msgstr " (compensación: %#<PRIx64>)"
+
+#: src/readelf.c:5850
+#, c-format
+msgid " (end offset: %#<PRIx64>)"
+msgstr " (fin de compensación: %#<PRIx64>)"
+
+#: src/readelf.c:5887
+#, c-format
+msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
+msgstr "Puntero   %-26sLSDA: %#<PRIx64>\n"
+
+#: src/readelf.c:5942
+#, c-format
+msgid "cannot get attribute code: %s"
+msgstr "No se puede obtener código de atributo: %s"
+
+#: src/readelf.c:5951
+#, c-format
+msgid "cannot get attribute form: %s"
+msgstr "No se puede obtener forma de atributo: %s"
+
+#: src/readelf.c:5966
+#, c-format
+msgid "cannot get attribute value: %s"
+msgstr "No se puede obtener valor: %s"
+
+#: src/readelf.c:6268
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [Offset]\n"
+msgstr ""
+"\n"
+"Sección DWARF [%2zu] '%s' en compensación %#<PRIx64>:\n"
+" [Offset]\n"
+
+#: src/readelf.c:6300
+#, c-format
+msgid ""
+" Type unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: "
+"%<PRIu8>, Offset size: %<PRIu8>\n"
+" Type signature: %#<PRIx64>, Type offset: %#<PRIx64>\n"
+msgstr ""
+"Tipo de unidad al compensar  %<PRIu64>:\n"
+" Versión: %<PRIu16>, Abreviación de sección de compensación: %<PRIu64>,  "
+"Tamaño de dirección: %<PRIu8>, Tamaño de compensación: %<PRIu8>\n"
+" Tipo de firma: %#<PRIx64>, Tipo de compensación: %#<PRIx64>\n"
+
+#: src/readelf.c:6309
+#, c-format
+msgid ""
+" Compilation unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: "
+"%<PRIu8>, Offset size: %<PRIu8>\n"
+msgstr ""
+"Unidad de compilación en compensación %<PRIu64>:\n"
+" Versión: %<PRIu16>, Compensación de sección de abreviatura: %<PRIu64>,  "
+"Tamaño de dirección: %<PRIu8>, Tamaño de compensación: %<PRIu8>\n"
+
+#: src/readelf.c:6334
+#, c-format
+msgid "cannot get DIE at offset %<PRIu64> in section '%s': %s"
+msgstr "no se puede obtener DIE en compensación %<PRIu64> en sección '%s': %s"
+
+#: src/readelf.c:6348
+#, c-format
+msgid "cannot get DIE offset: %s"
+msgstr "no se puede obtener DIE en compensación: %s"
+
+#: src/readelf.c:6357
+#, c-format
+msgid "cannot get tag of DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+"no se ha podido obtener etiqueta de DIE en compensación%<PRIu64> en sección "
+"'%s': %s"
+
+#: src/readelf.c:6389
+#, c-format
+msgid "cannot get next DIE: %s\n"
+msgstr "No se puede obtener próximo DIE: %s\n"
+
+#: src/readelf.c:6397
+#, c-format
+msgid "cannot get next DIE: %s"
+msgstr "No se puede obtener próximo DIE: %s"
+
+#: src/readelf.c:6433
+#, fuzzy, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+"\n"
+"Sección DWARF [%2zu] '%s' en compensación %#<PRIx64>:\n"
+
+#: src/readelf.c:6542
+#, c-format
+msgid "cannot get line data section data: %s"
+msgstr "No se puede obtener sección de datos de línea: %s"
+
+#. Print what we got so far.
+#: src/readelf.c:6612
+#, c-format
+msgid ""
+"\n"
+" Length:                     %<PRIu64>\n"
+" DWARF version:              %<PRIuFAST16>\n"
+" Prologue length:            %<PRIu64>\n"
+" Minimum instruction length: %<PRIuFAST8>\n"
+" Maximum operations per instruction: %<PRIuFAST8>\n"
+" Initial value if '%s': %<PRIuFAST8>\n"
+" Line base:                  %<PRIdFAST8>\n"
+" Line range:                 %<PRIuFAST8>\n"
+" Opcode base:                %<PRIuFAST8>\n"
+"\n"
+"Opcodes:\n"
+msgstr ""
+"\n"
+" Longitud:                   %<PRIu64>\n"
+" Versión DWARF:              %<PRIuFAST16>\n"
+" Longitud de prólogo:        %<PRIu64>\n"
+" Longitud de instrucción mínima: %<PRIuFAST8>\n"
+" Máximo operaciones por instrucción: %<PRIuFAST8>\n"
+" Valor inicial si '%s': %<PRIuFAST8>\n"
+" Base de línea:              %<PRIdFAST8>\n"
+" Rango de línea:             %<PRIuFAST8>\n"
+" Base de código operativo:   %<PRIuFAST8>\n"
+"\n"
+"Códigos operativos:\n"
+
+#: src/readelf.c:6633
+#, c-format
+msgid "invalid data at offset %tu in section [%zu] '%s'"
+msgstr "datos inválidos en compensación %tu en sección [%zu] '%s'"
+
+#: src/readelf.c:6648
+#, c-format
+msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
+msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
+msgstr[0] "  [%*<PRIuFAST8>]  argumento %hhu \n"
+msgstr[1] "  [%*<PRIuFAST8>]  argumento %hhu\n"
+
+#: src/readelf.c:6656
+msgid ""
+"\n"
+"Directory table:"
+msgstr ""
+"\n"
+"Tabla de Directorio:"
+
+#: src/readelf.c:6672
+msgid ""
+"\n"
+"File name table:\n"
+" Entry Dir   Time      Size      Name"
+msgstr ""
+"\n"
+"Tabla de nombre de archivo:\n"
+" Directorio de entrada   Tiempo      Tamaño      Nombre"
+
+#: src/readelf.c:6707
+msgid ""
+"\n"
+"Line number statements:"
+msgstr ""
+"\n"
+" Declaraciones de número de Línea:"
+
+#: src/readelf.c:6758
+#, fuzzy, c-format
+msgid "invalid maximum operations per instruction is zero"
+msgstr "longitud mínima inválida de tamaño de cadena coincidente"
+
+#: src/readelf.c:6794
+#, c-format
+msgid " special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"
+msgstr ""
+" opcode especial %u: dirección+%u = %s,  op_index = %u, línea%+d = %zu\n"
+
+#: src/readelf.c:6799
+#, c-format
+msgid " special opcode %u: address+%u = %s, line%+d = %zu\n"
+msgstr " opcode especial %u: dirección+%u = %s, línea%+d = %zu\n"
+
+#: src/readelf.c:6819
+#, c-format
+msgid " extended opcode %u: "
+msgstr "  Código operativo extendido %u: "
+
+#: src/readelf.c:6824
+#, fuzzy
+msgid " end of sequence"
+msgstr "Fin de secuencia"
+
+#: src/readelf.c:6843
+#, fuzzy, c-format
+msgid " set address to %s\n"
+msgstr "Establecer dirección a %s\n"
+
+#: src/readelf.c:6870
+#, fuzzy, c-format
+msgid " define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
+msgstr ""
+"definir nuevo archivo: dir=%u, mtime=%<PRIu64>, longitud=%<PRIu64>, nombre="
+"%s\n"
+
+#: src/readelf.c:6883
+#, c-format
+msgid " set discriminator to %u\n"
+msgstr " establecer discriminador a %u\n"
+
+#. Unknown, ignore it.
+#: src/readelf.c:6888
+#, fuzzy
+msgid " unknown opcode"
+msgstr "código operativo desconocido "
+
+#. Takes no argument.
+#: src/readelf.c:6900
+msgid " copy"
+msgstr "Copiar"
+
+#: src/readelf.c:6911
+#, fuzzy, c-format
+msgid " advance address by %u to %s, op_index to %u\n"
+msgstr "dirección avanzada por %u a %s, op_index a %u\n"
+
+#: src/readelf.c:6915
+#, fuzzy, c-format
+msgid " advance address by %u to %s\n"
+msgstr "Dirección de avance por %u a %s\n"
+
+#: src/readelf.c:6926
+#, c-format
+msgid " advance line by constant %d to %<PRId64>\n"
+msgstr " línea de avance por la constante %d a %<PRId64>\n"
+
+#: src/readelf.c:6934
+#, c-format
+msgid " set file to %<PRIu64>\n"
+msgstr " establecer archivo a %<PRIu64>\n"
+
+#: src/readelf.c:6944
+#, c-format
+msgid " set column to %<PRIu64>\n"
+msgstr "  Establecer columna a %<PRIu64>\n"
+
+#: src/readelf.c:6951
+#, c-format
+msgid " set '%s' to %<PRIuFAST8>\n"
+msgstr "Establecer '%s' a %<PRIuFAST8>\n"
+
+#. Takes no argument.
+#: src/readelf.c:6957
+msgid " set basic block flag"
+msgstr "Establecer bandera de bloque básico"
+
+#: src/readelf.c:6970
+#, fuzzy, c-format
+msgid " advance address by constant %u to %s, op_index to %u\n"
+msgstr "dirección avanzada por constante %u a %s, op_index a %u\n"
+
+#: src/readelf.c:6974
+#, fuzzy, c-format
+msgid " advance address by constant %u to %s\n"
+msgstr "Dirección de avance por constante %u a %s\n"
+
+#: src/readelf.c:6992
+#, fuzzy, c-format
+msgid " advance address by fixed value %u to %s\n"
+msgstr "dirección de avance por valor corregido %u a %s\n"
+
+#. Takes no argument.
+#: src/readelf.c:7001
+msgid " set prologue end flag"
+msgstr " Establecer bandera prologue_end"
+
+#. Takes no argument.
+#: src/readelf.c:7006
+msgid " set epilogue begin flag"
+msgstr " Establecer bandera epilogue_begin"
+
+#: src/readelf.c:7015
+#, c-format
+msgid " set isa to %u\n"
+msgstr " establecer isa para %u\n"
+
+#. This is a new opcode the generator but not we know about.
+#. Read the parameters associated with it but then discard
+#. everything.  Read all the parameters for this opcode.
+#: src/readelf.c:7024
+#, c-format
+msgid " unknown opcode with %<PRIu8> parameter:"
+msgid_plural " unknown opcode with %<PRIu8> parameters:"
+msgstr[0] " opcódigo con parámetro %<PRIu8> desconocido:"
+msgstr[1] " opcódigo con parámetros %<PRIu8> desconocido:"
+
+#: src/readelf.c:7056
+#, c-format
+msgid "cannot get .debug_loc content: %s"
+msgstr "no es posible obtener contenido de .debug_loc: %s"
+
+#. First entry in a list.
+#: src/readelf.c:7131
+#, c-format
+msgid " [%6tx]  %s..%s"
+msgstr " [%6tx]  %s..%s"
+
+#: src/readelf.c:7133
+#, c-format
+msgid "           %s..%s"
+msgstr "           %s..%s"
+
+#: src/readelf.c:7140 src/readelf.c:8091
+msgid "   <INVALID DATA>\n"
+msgstr "   <DATOS INVÁLIDOS>\n"
+
+#: src/readelf.c:7192 src/readelf.c:7354
+#, c-format
+msgid "cannot get macro information section data: %s"
+msgstr "no es posible obtener datos de la sección de macro información: %s"
+
+#: src/readelf.c:7272
+#, c-format
+msgid "%*s*** non-terminated string at end of section"
+msgstr "%*s*** cadena no finalizada al final de la sección"
+
+#: src/readelf.c:7295
+#, fuzzy, c-format
+msgid "%*s*** missing DW_MACINFO_start_file argument at end of section"
+msgstr "%*s*** cadena no finalizada al final de la sección"
+
+#: src/readelf.c:7395
+#, fuzzy, c-format
+msgid " Offset:             0x%<PRIx64>\n"
+msgstr "  Propietario          Tamaño\n"
+
+#: src/readelf.c:7407
+#, fuzzy, c-format
+msgid " Version:            %<PRIu16>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:7413 src/readelf.c:8210
+#, c-format
+msgid "  unknown version, cannot parse section\n"
+msgstr ""
+
+#: src/readelf.c:7420
+#, fuzzy, c-format
+msgid " Flag:               0x%<PRIx8>\n"
+msgstr "  Dirección de punto de entrada:               %#<PRIx64>\n"
+
+#: src/readelf.c:7423
+#, fuzzy, c-format
+msgid " Offset length:      %<PRIu8>\n"
+msgstr " (compensación: %#<PRIx64>)"
+
+#: src/readelf.c:7431
+#, fuzzy, c-format
+msgid " .debug_line offset: 0x%<PRIx64>\n"
+msgstr " (fin de compensación: %#<PRIx64>)"
+
+#: src/readelf.c:7444
+#, fuzzy, c-format
+msgid "  extension opcode table, %<PRIu8> items:\n"
+msgstr " opcódigo con parámetro %<PRIu8> desconocido:"
+
+#: src/readelf.c:7451
+#, c-format
+msgid "    [%<PRIx8>]"
+msgstr ""
+
+#: src/readelf.c:7463
+#, fuzzy, c-format
+msgid " %<PRIu8> arguments:"
+msgstr "  [%*<PRIuFAST8>]  argumento %hhu \n"
+
+#: src/readelf.c:7491
+#, c-format
+msgid " no arguments."
+msgstr ""
+
+#: src/readelf.c:7791
+#, c-format
+msgid "vendor opcode not verified?"
+msgstr ""
+
+#: src/readelf.c:7819
+#, c-format
+msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
+msgstr ""
+" Compensación [%5d] DIE: %6<PRId64>, Compensación CU DIE: %6<PRId64>, "
+"nombre: %s\n"
+
+#: src/readelf.c:7860
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" %*s  String\n"
+msgstr ""
+"\n"
+"Sección DWARF [%2zu] '%s' en compensación %#<PRIx64>:\n"
+" %*s  String\n"
+
+#: src/readelf.c:7874
+#, c-format
+msgid " *** error while reading strings: %s\n"
+msgstr " *** error en lectura de cadenas: %s\n"
+
+#: src/readelf.c:7894
+#, c-format
+msgid ""
+"\n"
+"Call frame search table section [%2zu] '.eh_frame_hdr':\n"
+msgstr ""
+"\n"
+"Sección de tabla de búsqueda de marco de llamada [%2zu] '.eh_frame_hdr':\n"
+
+#: src/readelf.c:7996
+#, c-format
+msgid ""
+"\n"
+"Exception handling table section [%2zu] '.gcc_except_table':\n"
+msgstr ""
+"\n"
+"Excepción en el manejo de la sección de tabla [%2zu] '.gcc_except_table':\n"
+
+#: src/readelf.c:8019
+#, c-format
+msgid " LPStart encoding:    %#x "
+msgstr "Codificación LPStart:    %#x "
+
+#: src/readelf.c:8031
+#, c-format
+msgid " TType encoding:      %#x "
+msgstr "Codificación TType:      %#x "
+
+#: src/readelf.c:8046
+#, c-format
+msgid " Call site encoding:  %#x "
+msgstr "Codificación de sitio de llamada:  %#x "
+
+#: src/readelf.c:8059
+msgid ""
+"\n"
+" Call site table:"
+msgstr ""
+"\n"
+" Tabla de sitio de llamada:"
+
+#: src/readelf.c:8073
+#, c-format
+msgid ""
+" [%4u] Call site start:   %#<PRIx64>\n"
+"        Call site length:  %<PRIu64>\n"
+"        Landing pad:       %#<PRIx64>\n"
+"        Action:            %u\n"
+msgstr ""
+" [%4u] Call site start:   %#<PRIx64>\n"
+"        Call site length:  %<PRIu64>\n"
+"        Landing pad:       %#<PRIx64>\n"
+"        Action:            %u\n"
+
+#: src/readelf.c:8146
+#, c-format
+msgid "invalid TType encoding"
+msgstr "Codificación TType inválida"
+
+#: src/readelf.c:8172
+#, fuzzy, c-format
+msgid ""
+"\n"
+"GDB section [%2zu] '%s' at offset %#<PRIx64> contains %<PRId64> bytes :\n"
+msgstr ""
+"\n"
+"Sección DWARF [%2zu] '%s' en compensación %#<PRIx64> contiene entrada %zu:\n"
+
+#: src/readelf.c:8201
+#, fuzzy, c-format
+msgid " Version:         %<PRId32>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:8219
+#, fuzzy, c-format
+msgid " CU offset:       %#<PRIx32>\n"
+msgstr " (compensación: %#<PRIx64>)"
+
+#: src/readelf.c:8226
+#, fuzzy, c-format
+msgid " TU offset:       %#<PRIx32>\n"
+msgstr " (compensación: %#<PRIx64>)"
+
+#: src/readelf.c:8233
+#, fuzzy, c-format
+msgid " address offset:  %#<PRIx32>\n"
+msgstr " (fin de compensación: %#<PRIx64>)"
+
+#: src/readelf.c:8240
+#, fuzzy, c-format
+msgid " symbol offset:   %#<PRIx32>\n"
+msgstr " (compensación: %#<PRIx64>)"
+
+#: src/readelf.c:8247
+#, fuzzy, c-format
+msgid " constant offset: %#<PRIx32>\n"
+msgstr " (fin de compensación: %#<PRIx64>)"
+
+#: src/readelf.c:8261
+#, fuzzy, c-format
+msgid ""
+"\n"
+" CU list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+"Sección DWARF [%2zu] '%s' en compensación %#<PRIx64> contiene entrada %zu:\n"
+
+#: src/readelf.c:8286
+#, fuzzy, c-format
+msgid ""
+"\n"
+" TU list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+"Sección DWARF [%2zu] '%s' en compensación %#<PRIx64> contiene entrada %zu:\n"
+
+#: src/readelf.c:8315
+#, fuzzy, c-format
+msgid ""
+"\n"
+" Address list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+"Sección DWARF [%2zu] '%s' en compensación %#<PRIx64> contiene entrada %zu:\n"
+
+#: src/readelf.c:8348
+#, fuzzy, c-format
+msgid ""
+"\n"
+" Symbol table at offset %#<PRIx32> contains %zu slots:\n"
+msgstr ""
+"\n"
+"Tabla de símbolos inválida en compensación %#0<PRIx64>\n"
+
+#: src/readelf.c:8435
+#, c-format
+msgid "cannot get debug context descriptor: %s"
+msgstr "no se puede depurar descriptor de contexto: %s"
+
+#: src/readelf.c:8591 src/readelf.c:9213 src/readelf.c:9324 src/readelf.c:9382
+#, c-format
+msgid "cannot convert core note data: %s"
+msgstr "no es posible convertir datos de la nota principal: %s"
+
+#: src/readelf.c:8954
+#, c-format
+msgid ""
+"\n"
+"%*s... <repeats %u more times> ..."
+msgstr ""
+"\n"
+"%*s... <repeats %u more times> ..."
+
+#: src/readelf.c:9461
+msgid "  Owner          Data size  Type\n"
+msgstr "  Owner          Data size  Type\n"
+
+#: src/readelf.c:9479
+#, c-format
+msgid "  %-13.*s  %9<PRId32>  %s\n"
+msgstr "  %-13.*s  %9<PRId32>  %s\n"
+
+#: src/readelf.c:9529
+#, c-format
+msgid "cannot get content of note section: %s"
+msgstr "no se puede obtener el contenido de sección de nota: %s"
+
+#: src/readelf.c:9556
+#, c-format
+msgid ""
+"\n"
+"Note section [%2zu] '%s' of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Sección de nota [%2zu] '%s' de %<PRIu64> bytes en compensación %#0<PRIx64>:\n"
+
+#: src/readelf.c:9579
+#, c-format
+msgid ""
+"\n"
+"Note segment of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Segmento de nota de %<PRIu64> bytes en compensación %#0<PRIx64>:\n"
+
+#: src/readelf.c:9625
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Section [%zu] '%s' has no data to dump.\n"
+msgstr ""
+"\n"
+"Sección [%Zu] '%s' no tiene datos para volcar.\n"
+
+#: src/readelf.c:9652 src/readelf.c:9703
+#, fuzzy, c-format
+msgid "cannot get data for section [%zu] '%s': %s"
+msgstr "no se pueden obtener datos para sección [%Zu] '%s': %s"
+
+#: src/readelf.c:9657
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Hex dump of section [%zu] '%s', %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Volcado Hex de sección [%Zu] '%s', %<PRIu64> bytes en compensación "
+"%#0<PRIx64>:\n"
+
+#: src/readelf.c:9662
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Hex dump of section [%zu] '%s', %<PRIu64> bytes (%zd uncompressed) at offset "
+"%#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Volcado Hex de sección [%Zu] '%s', %<PRIu64> bytes en compensación "
+"%#0<PRIx64>:\n"
+
+#: src/readelf.c:9676
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Section [%zu] '%s' has no strings to dump.\n"
+msgstr ""
+"\n"
+"Sección [%Zu] '%s' no tiene datos para volcar.\n"
+
+#: src/readelf.c:9708
+#, fuzzy, c-format
+msgid ""
+"\n"
+"String section [%zu] '%s' contains %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Sección de cadena [%Zu] '%s' contiene %<PRIu64> bytes en compensación "
+"%#0<PRIx64>:\n"
+
+#: src/readelf.c:9713
+#, fuzzy, c-format
+msgid ""
+"\n"
+"String section [%zu] '%s' contains %<PRIu64> bytes (%zd uncompressed) at "
+"offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Sección de cadena [%Zu] '%s' contiene %<PRIu64> bytes en compensación "
+"%#0<PRIx64>:\n"
+
+#: src/readelf.c:9762
+#, c-format
+msgid ""
+"\n"
+"section [%lu] does not exist"
+msgstr ""
+"\n"
+"sección [%lu] no existe"
+
+#: src/readelf.c:9791
+#, c-format
+msgid ""
+"\n"
+"section '%s' does not exist"
+msgstr ""
+"\n"
+"sección '%s' no existe"
+
+#: src/readelf.c:9848
+#, c-format
+msgid "cannot get symbol index of archive '%s': %s"
+msgstr "no se puede obtener el índice de símbolo de archivo '%s': %s"
+
+#: src/readelf.c:9851
+#, c-format
+msgid ""
+"\n"
+"Archive '%s' has no symbol index\n"
+msgstr ""
+"\n"
+"Archivo '%s' no tiene índice de símbolo\n"
+
+#: src/readelf.c:9855
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Index of archive '%s' has %zu entries:\n"
+msgstr ""
+"\n"
+"Índice de archivo '%s' tiene %Zu entradas:\n"
+
+#: src/readelf.c:9873
+#, fuzzy, c-format
+msgid "cannot extract member at offset %zu in '%s': %s"
+msgstr "no es posible extraer miembro en compensación %Zu en '%s': %s"
+
+#: src/readelf.c:9878
+#, c-format
+msgid "Archive member '%s' contains:\n"
+msgstr "Miembro de archivo contiene '%s':\n"
+
+#: src/size.c:57
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd' or `sysv'.  The default "
+"is `bsd'"
+msgstr ""
+"Utilice el formato de salida FORMAT. FORMAT puede ser tanto `bsd' como "
+"`sysv'. El establecido por defecto es `bsd'"
+
+#: src/size.c:59
+msgid "Same as `--format=sysv'"
+msgstr "lo mismo que `--format=sysv'"
+
+#: src/size.c:60
+msgid "Same as `--format=bsd'"
+msgstr "lo mismo que `--format=bsd'"
+
+#: src/size.c:63
+msgid "Same as `--radix=10'"
+msgstr "lo mismo que `--radix=10'"
+
+#: src/size.c:64
+msgid "Same as `--radix=8'"
+msgstr "lo mismo que `--radix=8'"
+
+#: src/size.c:65
+msgid "Same as `--radix=16'"
+msgstr "lo mismo que`--radix=16'"
+
+#: src/size.c:67
+msgid "Similar to `--format=sysv' output but in one line"
+msgstr "Similar a la salida `--format=sysv' pero en una sola línea"
+
+#: src/size.c:71
+msgid "Print size and permission flags for loadable segments"
+msgstr ""
+"Imprime el tamaño y las marcas de permiso para los segmentos que pueden ser "
+"cargados"
+
+#: src/size.c:72
+msgid "Display the total sizes (bsd only)"
+msgstr "Muestra el tamaño total (bsd solamente)"
+
+#. Short description of program.
+#: src/size.c:77
+msgid "List section sizes of FILEs (a.out by default)."
+msgstr "Lista los tamaños de sección de FICHEROS (por defecto a.out). "
+
+#: src/size.c:241
+#, c-format
+msgid "Invalid format: %s"
+msgstr "Formato de archivo inválido: %s"
+
+#: src/size.c:252
+#, c-format
+msgid "Invalid radix: %s"
+msgstr "Radical inválido: %s"
+
+#: src/size.c:311
+#, c-format
+msgid "%s: file format not recognized"
+msgstr "%s: No se reconoce el formato del fichero"
+
+#: src/size.c:417 src/size.c:550
+#, c-format
+msgid " (ex %s)"
+msgstr " (ex %s)"
+
+#: src/size.c:575
+msgid "(TOTALS)\n"
+msgstr "(TOTALES)\n"
+
+#: src/stack.c:483
+#, c-format
+msgid "-p PID should be a positive process id."
+msgstr ""
+
+#: src/stack.c:489
+#, fuzzy, c-format
+msgid "Cannot open core file '%s'"
+msgstr "Imposible abrir el archivo '%s'"
+
+#: src/stack.c:549
+#, c-format
+msgid "-n MAXFRAMES should be 0 or higher."
+msgstr ""
+
+#: src/stack.c:561
+#, c-format
+msgid "-e EXEC needs a core given by --core."
+msgstr ""
+
+#: src/stack.c:565
+#, c-format
+msgid "-1 needs a thread id given by -p."
+msgstr ""
+
+#: src/stack.c:569
+#, c-format
+msgid "One of -p PID or --core COREFILE should be given."
+msgstr ""
+
+#: src/stack.c:641
+#, fuzzy
+msgid "Show stack of process PID"
+msgstr "No se puede crear el árbol de búsqueda"
+
+#: src/stack.c:643
+msgid "Show stack found in COREFILE"
+msgstr ""
+
+#: src/stack.c:644
+msgid "(optional) EXECUTABLE that produced COREFILE"
+msgstr ""
+
+#: src/stack.c:648
+msgid "Output selection options:"
+msgstr "Opciones de selección de salida:"
+
+#: src/stack.c:650
+#, fuzzy
+msgid "Additionally show frame activation"
+msgstr "Selección de salida adicional:"
+
+#: src/stack.c:652
+msgid "Additionally try to lookup DWARF debuginfo name for frame address"
+msgstr ""
+
+#: src/stack.c:655
+msgid ""
+"Additionally show inlined function frames using DWARF debuginfo if available "
+"(implies -d)"
+msgstr ""
+
+#: src/stack.c:657
+msgid "Additionally show module file information"
+msgstr ""
+
+#: src/stack.c:659
+#, fuzzy
+msgid "Additionally show source file information"
+msgstr "Selección de salida adicional:"
+
+#: src/stack.c:661
+msgid ""
+"Show all additional information (activation, debugname, inlines, module and "
+"source)"
+msgstr ""
+
+#: src/stack.c:663
+msgid "Do not resolve address to function symbol name"
+msgstr ""
+
+#: src/stack.c:665
+msgid "Show raw function symbol names, do not try to demangle names"
+msgstr ""
+
+#: src/stack.c:667
+msgid "Show module build-id, load address and pc offset"
+msgstr ""
+
+#: src/stack.c:669
+msgid "Show the backtrace of only one thread"
+msgstr ""
+
+#: src/stack.c:671
+msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)"
+msgstr ""
+
+#: src/stack.c:673
+msgid "Show module memory map with build-id, elf and debug files detected"
+msgstr ""
+
+#: src/stack.c:681
+msgid ""
+"Print a stack for each thread in a process or core file.\n"
+"\n"
+"Program exits with return code 0 if all frames were shown without any "
+"errors.  If some frames were shown, but there were some non-fatal errors, "
+"possibly causing an incomplete backtrace, the program exits with return code "
+"1.  If no frames could be shown, or a fatal error occured the program exits "
+"with return code 2.  If the program was invoked with bad or missing "
+"arguments it will exit with return code 64."
+msgstr ""
+
+#: src/stack.c:756
+#, c-format
+msgid "Couldn't show any frames."
+msgstr ""
+
+#: src/strings.c:66
+msgid "Output Selection:"
+msgstr "Selección de salida:"
+
+#: src/strings.c:67
+msgid "Scan entire file, not only loaded sections"
+msgstr "Explorar todo el archivo, no sólo las secciones cargadas"
+
+#: src/strings.c:69
+msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed"
+msgstr "Sólo secuencias NUL-terminated de caracteres MIN-LEN o más se imprimen"
+
+#: src/strings.c:70
+msgid ""
+"Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, "
+"{B,L} = 32-bit"
+msgstr ""
+"Seleccionar tamaño de caracter y Endianess: s = 7-bit, S = 8-bit, {b,l} = 16-"
+"bit, {B,L} = 32-bit"
+
+#: src/strings.c:74
+msgid "Print name of the file before each string."
+msgstr "Imprimir nombre de archivo antes de cada cadena."
+
+#: src/strings.c:76
+msgid "Print location of the string in base 8, 10, or 16 respectively."
+msgstr "Imprimir ubicación de la cadena en base 8, 10, o 16 respectivamente."
+
+#: src/strings.c:77
+msgid "Alias for --radix=o"
+msgstr "Alias para --radix=o"
+
+#. Short description of program.
+#: src/strings.c:84
+msgid "Print the strings of printable characters in files."
+msgstr "Imprimir las cadenas de caracteres imprimibles en archivos."
+
+#: src/strings.c:257 src/strings.c:292
+#, c-format
+msgid "invalid value '%s' for %s parameter"
+msgstr "Valor inválido '%s' para parámetro %s"
+
+#: src/strings.c:303
+#, c-format
+msgid "invalid minimum length of matched string size"
+msgstr "longitud mínima inválida de tamaño de cadena coincidente"
+
+#: src/strings.c:586
+#, fuzzy, c-format
+msgid "lseek failed"
+msgstr "lseek64 falló"
+
+#: src/strings.c:603 src/strings.c:667
+#, c-format
+msgid "re-mmap failed"
+msgstr "re-mmap falló"
+
+#: src/strings.c:640
+#, c-format
+msgid "mprotect failed"
+msgstr "mprotect falló"
+
+#: src/strings.c:729
+#, c-format
+msgid "Skipping section %zd '%s' data outside file"
+msgstr ""
+
+#: src/strip.c:71
+msgid "Place stripped output into FILE"
+msgstr "Colocar la salida obtenida en FICHERO"
+
+#: src/strip.c:72
+msgid "Extract the removed sections into FILE"
+msgstr "Extraer secciones eliminadas en FICHERO"
+
+#: src/strip.c:73
+msgid "Embed name FILE instead of -f argument"
+msgstr "Incorporar nombre FILE en lugar de argumento -f"
+
+#: src/strip.c:77
+msgid "Remove all debugging symbols"
+msgstr "Elimina todos los símbolos de depuración"
+
+#: src/strip.c:81
+msgid "Remove section headers (not recommended)"
+msgstr "Quitar sección de cabeceras (no recomendado)"
+
+#: src/strip.c:83
+msgid "Copy modified/access timestamps to the output"
+msgstr "Copiar marcas de tiempo modificadas/acceso a la salida"
+
+#: src/strip.c:85
+msgid ""
+"Resolve all trivial relocations between debug sections if the removed "
+"sections are placed in a debug file (only relevant for ET_REL files, "
+"operation is not reversable, needs -f)"
+msgstr ""
+
+#: src/strip.c:87
+msgid "Remove .comment section"
+msgstr "Quitar sección de comentario"
+
+#: src/strip.c:88
+msgid ""
+"Remove the named section.  SECTION is an extended wildcard pattern.  May be "
+"given more than once.  Only non-allocated sections can be removed."
+msgstr ""
+
+#: src/strip.c:89
+msgid ""
+"Keep the named section.  SECTION is an extended wildcard pattern.  May be "
+"given more than once."
+msgstr ""
+
+#. Short description of program.
+#: src/strip.c:96
+msgid "Discard symbols from object files."
+msgstr "Descarta símbolos de archivos objeto."
+
+#: src/strip.c:242
+#, c-format
+msgid "--reloc-debug-sections used without -f"
+msgstr ""
+
+#: src/strip.c:256
+#, c-format
+msgid "Only one input file allowed together with '-o' and '-f'"
+msgstr "Sólo se permite ingresar un archivo junto con '-o' y '-f'"
+
+#: src/strip.c:279
+#, c-format
+msgid "-f option specified twice"
+msgstr "opción -f especificada dos veces"
+
+#: src/strip.c:288
+#, c-format
+msgid "-F option specified twice"
+msgstr "opción -F especificada dos veces"
+
+#: src/strip.c:347
+#, fuzzy, c-format
+msgid "cannot both keep and remove .comment section"
+msgstr "Quitar sección de comentario"
+
+#: src/strip.c:372 src/strip.c:396
+#, c-format
+msgid "cannot stat input file '%s'"
+msgstr "no sepuede stat fichero de entrada '%s'"
+
+#: src/strip.c:386
+#, c-format
+msgid "while opening '%s'"
+msgstr "mientras se abría '%s'"
+
+#: src/strip.c:424
+#, c-format
+msgid "%s: cannot use -o or -f when stripping archive"
+msgstr "%s: no puede utilizarse -o o -f cuando se extrae un archivo"
+
+#. We would like to support ar archives, but currently it just
+#. doesn't work at all since we call elf_clone on the members
+#. which doesn't really support ar members.
+#. result = handle_ar (fd, elf, NULL, fname,
+#. preserve_dates ? tv : NULL);
+#.
+#: src/strip.c:436
+#, fuzzy, c-format
+msgid "%s: no support for stripping archive"
+msgstr "%s: no puede utilizarse -o o -f cuando se extrae un archivo"
+
+#: src/strip.c:535
+#, c-format
+msgid "cannot open EBL backend"
+msgstr "No se puede abrir el segundo plano EBL"
+
+#: src/strip.c:580
+#, fuzzy, c-format
+msgid "cannot get number of phdrs"
+msgstr "no se pudo determinar la cantidad de encabezados de programa: %s"
+
+#: src/strip.c:596 src/strip.c:620
+#, c-format
+msgid "cannot create new file '%s': %s"
+msgstr "no se puede crear fichero nuevo '%s': %s"
+
+#: src/strip.c:686
+#, c-format
+msgid "illformed file '%s'"
+msgstr "Fichero illformed '%s'"
+
+#: src/strip.c:696
+#, fuzzy, c-format
+msgid "Cannot remove allocated section '%s'"
+msgstr "No se puede asignar sección PLT: %s"
+
+#: src/strip.c:705
+#, fuzzy, c-format
+msgid "Cannot both keep and remove section '%s'"
+msgstr "No se puede añadir nueva sección: %s"
+
+#: src/strip.c:1061 src/strip.c:1160
+#, c-format
+msgid "while generating output file: %s"
+msgstr "al generar fichero de salida: %s"
+
+#: src/strip.c:1126 src/strip.c:2208
+#, c-format
+msgid "%s: error while creating ELF header: %s"
+msgstr "%s: error al crear encabezamiento ELF: %s"
+
+#: src/strip.c:1143
+#, c-format
+msgid "while preparing output for '%s'"
+msgstr "al preparar salida para '%s'"
+
+#: src/strip.c:1205 src/strip.c:1268
+#, c-format
+msgid "while create section header section: %s"
+msgstr "al crear sección de encabezamiento de sección: %s"
+
+#: src/strip.c:1214
+#, c-format
+msgid "cannot allocate section data: %s"
+msgstr "no se puede asignar espacio para los datos: %s"
+
+#: src/strip.c:1280
+#, c-format
+msgid "while create section header string table: %s"
+msgstr "al crear tabla de cadenas de encabezamiento de sección: %s"
+
+#: src/strip.c:1287
+#, fuzzy, c-format
+msgid "no memory to create section header string table"
+msgstr "al crear tabla de cadenas de encabezamiento de sección: %s"
+
+#: src/strip.c:1497
+#, c-format
+msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]"
+msgstr ""
+
+#: src/strip.c:1994
+#, fuzzy, c-format
+msgid "bad relocation"
+msgstr "Mostrar reubicaciones"
+
+#: src/strip.c:2119 src/strip.c:2232
+#, c-format
+msgid "while writing '%s': %s"
+msgstr "al escribir '%s': %s"
+
+#: src/strip.c:2130
+#, c-format
+msgid "while creating '%s'"
+msgstr "al crear '%s'"
+
+#: src/strip.c:2153
+#, c-format
+msgid "while computing checksum for debug information"
+msgstr "al computar la suma de verificación para información de depuración"
+
+#: src/strip.c:2217
+#, c-format
+msgid "%s: error while reading the file: %s"
+msgstr "%s: error al leer el fichero: %s"
+
+#: src/strip.c:2257 src/strip.c:2277
+#, c-format
+msgid "while writing '%s'"
+msgstr "al escribir '%s'"
+
+#: src/strip.c:2314 src/strip.c:2321
+#, c-format
+msgid "error while finishing '%s': %s"
+msgstr "Error al terminar '%s': %s"
+
+#: src/strip.c:2338 src/strip.c:2414
+#, c-format
+msgid "cannot set access and modification date of '%s'"
+msgstr "no es posible establecer acceso y fecha de modificación de '%s'"
+
+#: src/unstrip.c:70
+msgid "Match MODULE against file names, not module names"
+msgstr "Coincidir MODULO con nombres de archivo, no con nombres de módulo"
+
+#: src/unstrip.c:71
+msgid "Silently skip unfindable files"
+msgstr "Omitir silenciosamente los archivos perdidos"
+
+#: src/unstrip.c:74
+msgid "Place output into FILE"
+msgstr "Colocar salida en FICHERO"
+
+#: src/unstrip.c:76
+msgid "Create multiple output files under DIRECTORY"
+msgstr "Crear archivos de salida múltiple bajo DIRECTORIO"
+
+#: src/unstrip.c:77
+msgid "Use module rather than file names"
+msgstr "Usar módulo en lugar de nombres de archivo"
+
+#: src/unstrip.c:79
+msgid "Create output for modules that have no separate debug information"
+msgstr ""
+"Crear salida para módulos que no tienen información de depuración "
+"independiente"
+
+#: src/unstrip.c:82
+msgid "Apply relocations to section contents in ET_REL files"
+msgstr "Aplicar reubicaciones a contenido de sección en archivos ET_REL"
+
+#: src/unstrip.c:84
+msgid "Only list module and file names, build IDs"
+msgstr "Solamente listar módulo y nombres de archivo, crear los ID"
+
+#: src/unstrip.c:86
+msgid "Force combining files even if some ELF headers don't seem to match"
+msgstr ""
+
+#: src/unstrip.c:130
+#, c-format
+msgid "-d option specified twice"
+msgstr "opción -d especificada dos veces"
+
+#: src/unstrip.c:165
+#, c-format
+msgid "only one of -o or -d allowed"
+msgstr "Sólo se permite usar -o ó -d "
+
+#: src/unstrip.c:174
+#, c-format
+msgid "-n cannot be used with explicit files or -o or -d"
+msgstr "-n no puede utilizarse con archivos explícitos o con -o ó -d"
+
+#: src/unstrip.c:189
+#, c-format
+msgid "output directory '%s'"
+msgstr "Directorio de salida '%s'"
+
+#: src/unstrip.c:198
+#, c-format
+msgid "exactly two file arguments are required"
+msgstr "dos argumentos de archivos se requieren exactamente"
+
+#: src/unstrip.c:204
+#, c-format
+msgid "-m, -a, -R, and -i options not allowed with explicit files"
+msgstr "No se permiten las opciones -m, -a, -R, ni -i con archivos explícitos"
+
+#: src/unstrip.c:217
+#, c-format
+msgid "-o or -d is required when using implicit files"
+msgstr "se requiere -o ó -d cuando se utilizan archivos implícitos"
+
+#: src/unstrip.c:240
+#, c-format
+msgid "cannot create ELF header: %s"
+msgstr "no se puede crear el encabezamiento ELF: %s"
+
+#: src/unstrip.c:245
+#, c-format
+msgid "cannot copy ELF header: %s"
+msgstr "no se puede copiar encabezamiento ELF: %s"
+
+#: src/unstrip.c:249 src/unstrip.c:1933 src/unstrip.c:1976
+#, fuzzy, c-format
+msgid "cannot get number of program headers: %s"
+msgstr "no se pudo determinar la cantidad de encabezados de programa: %s"
+
+#: src/unstrip.c:254 src/unstrip.c:1937
+#, c-format
+msgid "cannot create program headers: %s"
+msgstr "No pueden crear encabezamientos de programa: %s"
+
+#: src/unstrip.c:260
+#, c-format
+msgid "cannot copy program header: %s"
+msgstr "no puede copiar encabezamiento de programa: %s"
+
+#: src/unstrip.c:270
+#, c-format
+msgid "cannot copy section header: %s"
+msgstr "no se puede copiar encabezamiento de sección: %s"
+
+#: src/unstrip.c:273 src/unstrip.c:1568
+#, c-format
+msgid "cannot get section data: %s"
+msgstr "no se pueden obtener datos de sección: %s"
+
+#: src/unstrip.c:275 src/unstrip.c:1570
+#, c-format
+msgid "cannot copy section data: %s"
+msgstr "no pueden copiar datos de sección: %s"
+
+#: src/unstrip.c:299
+#, c-format
+msgid "cannot create directory '%s'"
+msgstr "no se puede crear el directorio '%s'"
+
+#: src/unstrip.c:371 src/unstrip.c:791 src/unstrip.c:1602
+#, c-format
+msgid "cannot get symbol table entry: %s"
+msgstr "no se puede obtener entrada de tabla de símbolos: %s"
+
+#: src/unstrip.c:387 src/unstrip.c:608 src/unstrip.c:629 src/unstrip.c:641
+#: src/unstrip.c:1623 src/unstrip.c:1799 src/unstrip.c:1823
+#, c-format
+msgid "cannot update symbol table: %s"
+msgstr "no se puede actualizar tabla de símbolos: %s"
+
+#: src/unstrip.c:397
+#, c-format
+msgid "cannot update section header: %s"
+msgstr "no se puede actualizar encabezamiento de sección: %s"
+
+#: src/unstrip.c:436 src/unstrip.c:447
+#, c-format
+msgid "cannot update relocation: %s"
+msgstr "no se puede actualizar reubicación: %s"
+
+#: src/unstrip.c:535
+#, c-format
+msgid "cannot get symbol version: %s"
+msgstr "no se puede obtener versión de símbolo: %s"
+
+#: src/unstrip.c:548
+#, fuzzy, c-format
+msgid "unexpected section type in [%zu] with sh_link to symtab"
+msgstr "tipo de sección inesperado en [%Zu] con sh_link para symtab"
+
+#: src/unstrip.c:797
+#, fuzzy, c-format
+msgid "invalid string offset in symbol [%zu]"
+msgstr "compensación de cadena inválida en símbolo [%Zu]"
+
+#: src/unstrip.c:955 src/unstrip.c:1305
+#, fuzzy, c-format
+msgid "cannot read section [%zu] name: %s"
+msgstr "no se puede leer nombre [%Zu]: %s"
+
+#: src/unstrip.c:996 src/unstrip.c:1015 src/unstrip.c:1053
+#, c-format
+msgid "cannot read '.gnu.prelink_undo' section: %s"
+msgstr "no se puede leer sección '.gnu.prelink_undo': %s"
+
+#: src/unstrip.c:1033
+#, c-format
+msgid "overflow with shnum = %zu in '%s' section"
+msgstr ""
+
+#: src/unstrip.c:1044
+#, c-format
+msgid "invalid contents in '%s' section"
+msgstr "contenido inválido en sección '%s'"
+
+#: src/unstrip.c:1099 src/unstrip.c:1427
+#, fuzzy, c-format
+msgid "cannot find matching section for [%zu] '%s'"
+msgstr "no se puede hallar sección coincidente para [%Zu] '%s'"
+
+#: src/unstrip.c:1224 src/unstrip.c:1239 src/unstrip.c:1506 src/unstrip.c:1758
+#, c-format
+msgid "cannot add section name to string table: %s"
+msgstr "no se puede añadir nombre de sección a tabla de cadenas: %s"
+
+#: src/unstrip.c:1248
+#, c-format
+msgid "cannot update section header string table data: %s"
+msgstr ""
+"no se pueden actualizar datos de tabla de cadenas de encabezamiento de "
+"sección: %s"
+
+#: src/unstrip.c:1276 src/unstrip.c:1280
+#, c-format
+msgid "cannot get section header string table section index: %s"
+msgstr ""
+"no se puede obtener índice de sección de tabla de cadenas de encabezamiento "
+"de sección: %s"
+
+#: src/unstrip.c:1284 src/unstrip.c:1288 src/unstrip.c:1521
+#, c-format
+msgid "cannot get section count: %s"
+msgstr "No se puede obtener cuenta de sección: %s"
+
+#: src/unstrip.c:1291
+#, c-format
+msgid "more sections in stripped file than debug file -- arguments reversed?"
+msgstr ""
+"más secciones en el archivo despojado que en el archivo de depuración -- "
+"¿argumentos invertidos?"
+
+#: src/unstrip.c:1350 src/unstrip.c:1442
+#, c-format
+msgid "cannot read section header string table: %s"
+msgstr "no se puede obtener tabla de cadenas de encabezamiento de sección: %s"
+
+#: src/unstrip.c:1500
+#, c-format
+msgid "cannot add new section: %s"
+msgstr "No se puede añadir nueva sección: %s"
+
+#: src/unstrip.c:1610
+#, fuzzy, c-format
+msgid "symbol [%zu] has invalid section index"
+msgstr "símbolo [%Zu] tiene índice de sección inválido"
+
+#: src/unstrip.c:1894
+#, c-format
+msgid "cannot read section data: %s"
+msgstr "no se puede leer la sección de datos: %s"
+
+#: src/unstrip.c:1915
+#, c-format
+msgid "cannot get ELF header: %s"
+msgstr "no se puede leer encabezamiento ELF: %s"
+
+#: src/unstrip.c:1923
+#, c-format
+msgid "cannot update ELF header: %s"
+msgstr "No se puede actualizar encabezamiento ELF: %s"
+
+#: src/unstrip.c:1947
+#, c-format
+msgid "cannot update program header: %s"
+msgstr "no se puede actualizar encabezamiento de programa: %s"
+
+#: src/unstrip.c:1952 src/unstrip.c:2034
+#, c-format
+msgid "cannot write output file: %s"
+msgstr "no se puede escribir al archivo de salida: %s"
+
+#: src/unstrip.c:2003
+#, c-format
+msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+"datos DWARF no se ajustan para polarización de pre-enlace; considere prelink "
+"-u"
+
+#: src/unstrip.c:2006
+#, c-format
+msgid ""
+"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+"Datos DWARF en '%s' no se ajustan a polarización de pre-enlace; considere "
+"prelink -u"
+
+#: src/unstrip.c:2025 src/unstrip.c:2076 src/unstrip.c:2088 src/unstrip.c:2174
+#, c-format
+msgid "cannot create ELF descriptor: %s"
+msgstr "no se puede crear un descriptor ELF: %s"
+
+#: src/unstrip.c:2067
+msgid "WARNING: "
+msgstr ""
+
+#: src/unstrip.c:2069
+msgid ", use --force"
+msgstr ""
+
+#: src/unstrip.c:2092
+msgid "ELF header identification (e_ident) different"
+msgstr ""
+
+#: src/unstrip.c:2095
+msgid "ELF header type (e_type) different"
+msgstr ""
+
+#: src/unstrip.c:2098
+msgid "ELF header machine type (e_machine) different"
+msgstr ""
+
+#: src/unstrip.c:2101
+msgid "stripped program header (e_phnum) smaller than unstripped"
+msgstr ""
+
+#: src/unstrip.c:2131
+#, c-format
+msgid "cannot find stripped file for module '%s': %s"
+msgstr "no se puede hallar archivo obtenido para módulo '%s': %s "
+
+#: src/unstrip.c:2135
+#, c-format
+msgid "cannot open stripped file '%s' for module '%s': %s"
+msgstr "No se puede abrir el archivo '%s' obtenido para módulo '%s': %s"
+
+#: src/unstrip.c:2150
+#, c-format
+msgid "cannot find debug file for module '%s': %s"
+msgstr "no puede hallar archivo de depuración para módulo '%s': %su"
+
+#: src/unstrip.c:2154
+#, c-format
+msgid "cannot open debug file '%s' for module '%s': %s"
+msgstr "No puede abrir archivo de depuración '%s' para módulo '%s': %s"
+
+#: src/unstrip.c:2167
+#, c-format
+msgid "module '%s' file '%s' is not stripped"
+msgstr "No se obtuvo el archivo '%s' de módulo '%s' "
+
+#: src/unstrip.c:2198
+#, c-format
+msgid "cannot cache section addresses for module '%s': %s"
+msgstr ""
+"No puede almacenar en cache direcciones de sección para módulo '%s': %s"
+
+#: src/unstrip.c:2331
+#, c-format
+msgid "no matching modules found"
+msgstr "No se encontraron módulos coincidentes"
+
+#: src/unstrip.c:2340
+#, c-format
+msgid "matched more than one module"
+msgstr "coincidió con más de un módulo"
+
+#: src/unstrip.c:2384
+msgid ""
+"STRIPPED-FILE DEBUG-FILE\n"
+"[MODULE...]"
+msgstr ""
+"STRIPPED-FILE DEBUG-FILE\n"
+"[MODULE...]"
+
+#: src/unstrip.c:2385
+#, fuzzy
+msgid ""
+"Combine stripped files with separate symbols and debug information.\n"
+"\n"
+"The first form puts the result in DEBUG-FILE if -o was not given.\n"
+"\n"
+"MODULE arguments give file name patterns matching modules to process.\n"
+"With -f these match the file name of the main (stripped) file (slashes are "
+"never special), otherwise they match the simple module names.  With no "
+"arguments, process all modules found.\n"
+"\n"
+"Multiple modules are written to files under OUTPUT-DIRECTORY, creating "
+"subdirectories as needed.  With -m these files have simple module names, "
+"otherwise they have the name of the main file complete with directory "
+"underneath OUTPUT-DIRECTORY.\n"
+"\n"
+"With -n no files are written, but one line to standard output for each "
+"module:\n"
+"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n"
+"START and SIZE are hexadecimal giving the address bounds of the module.  "
+"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the "
+"hexadecimal may be followed by @0xADDR giving the address where the ID "
+"resides if that is known.  FILE is the file name found for the module, or - "
+"if none was found, or . if an ELF image is available but not from any named "
+"file.  DEBUGFILE is the separate debuginfo file name, or - if no debuginfo "
+"was found, or . if FILE contains the debug information."
+msgstr ""
+"Combine stripped files with separate symbols and debug information.\n"
+"\n"
+"The first form puts the result in DEBUG-FILE if -o was not given.\n"
+"\n"
+"MODULE arguments give file name patterns matching modules to process.\n"
+"With -f these match the file name of the main (stripped) file (slashes are "
+"never special), otherwise they match the simple module names.  With no "
+"arguments, process all modules found.\n"
+"\n"
+"Multiple modules are written to files under OUTPUT-DIRECTORY, creating "
+"subdirectories as needed.  With -m these files have simple module names, "
+"otherwise they have the name of the main file complete with directory "
+"underneath OUTPUT-DIRECTORY.\n"
+"\n"
+"With -n no files are written, but one line to standard output for each "
+"module:\n"
+"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n"
+"START and SIZE are hexadecimal giving the address bounds of the module.  "
+"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the "
+"hexadecimal may be followed by @0xADDR giving the address where the ID "
+"resides if that is known.  FILE is the file name found for the module, or - "
+"if none was found, or . if an ELF image is available but not from any named "
+"file.  DEBUGFILE is the separate debuginfo file name, or - if no debuginfo "
+"was found, or . if FILE contains the debug information."
+
+#: tests/backtrace.c:442
+msgid "Run executable"
+msgstr ""
+
+#: tests/dwflmodtest.c:213
+#, fuzzy
+msgid "Additionally show function names"
+msgstr "También mostrar nombres de función"
+
+#: tests/dwflmodtest.c:214
+msgid "Show instances of inlined functions"
+msgstr ""
+
+#~ msgid "-R option supports only .comment section"
+#~ msgstr "la opción -R soporta únicamente. sección de comentario"
+
+#~ msgid "Written by %s.\n"
+#~ msgstr "Escrito por %s.\n"
+
+#~ msgid "cannot allocate PLTREL section: %s"
+#~ msgstr "No se puede asignar sección PLTREL: %s"
+
+#~ msgid "cannot allocate GOT section: %s"
+#~ msgstr "No se puede asignar sección GOT: %s"
+
+#~ msgid "cannot allocate GOTPLT section: %s"
+#~ msgstr "No se puede asignar sección GOTPLT: %s"
+
+#~ msgid "initial-executable TLS relocation cannot be used "
+#~ msgstr "Reubicación TLS ejecutable-inicial no se puede utilizar"
+
+#~ msgid "Input File Control:"
+#~ msgstr "Control de fichero de entrada:"
+
+#~ msgid "Include whole archives in the output from now on."
+#~ msgstr "A partir de ahora incluye archivos completos en la salida."
+
+#~ msgid "Stop including the whole archives in the output."
+#~ msgstr "Deja de incluir archivos completos en la salida."
+
+#~ msgid "FILE"
+#~ msgstr "FICHERO"
+
+#~ msgid "Start a group."
+#~ msgstr "Inicia un grupo"
+
+#~ msgid "End a group."
+#~ msgstr "Termina un grupo."
+
+#~ msgid "PATH"
+#~ msgstr "RUTA"
+
+#~ msgid "Add PATH to list of directories files are searched in."
+#~ msgstr ""
+#~ "Agrega RUTA a la lista de los directorios en los que se realiza la "
+#~ "búsqueda."
+
+#~ msgid "Only set DT_NEEDED for following dynamic libs if actually used"
+#~ msgstr ""
+#~ "Sólo se define DT_NEEDED para las siguientes bibliotecas dinámicas, si "
+#~ "están siendo utilizadas"
+
+#~ msgid "Always set DT_NEEDED for following dynamic libs"
+#~ msgstr ""
+#~ "Siempre establece DT_NEEDED para las siguientes bibliotecas dinámicas"
+
+#~ msgid "Ignore LD_LIBRARY_PATH environment variable."
+#~ msgstr "Ignora la variable de entorno LD_LIBRARY_PATH."
+
+#~ msgid "Output File Control:"
+#~ msgstr "Control de fichero de salida:"
+
+#~ msgid "Place output in FILE."
+#~ msgstr "Coloca salida en FICHERO."
+
+#~ msgid "Object is marked to not use default search path at runtime."
+#~ msgstr ""
+#~ "Objeto está marcado para no usar ruta de búsqueda predeterminada en "
+#~ "tiempo de ejecución."
+
+#~ msgid "Same as --whole-archive."
+#~ msgstr "Lo mismo que --whole-archive."
+
+#~ msgid ""
+#~ "Default rules of extracting from archive; weak references are not enough."
+#~ msgstr ""
+#~ "Reglas establecidas por defecto para extraer desde el archivo; las "
+#~ "referencias débiles no son suficientes."
+
+#~ msgid "Weak references cause extraction from archive."
+#~ msgstr "Referencias débiles causan extracción del archivo."
+
+#~ msgid "Allow multiple definitions; first is used."
+#~ msgstr "Permite definiciones múltiples; se utiliza la primera."
+
+#~ msgid "Disallow/allow undefined symbols in DSOs."
+#~ msgstr "Habilita/inhabilita símbolos indefinidos en los DSO."
+
+#~ msgid "Object requires immediate handling of $ORIGIN."
+#~ msgstr "Los objetos requieren manipulación inmediata de $ORIGIN."
+
+#~ msgid "Relocation will not be processed lazily."
+#~ msgstr "La reubicación no se procesará de forma perezosa."
+
+#~ msgid "Object cannot be unloaded at runtime."
+#~ msgstr "El objeto no se puede descargar en tiempo de ejecución."
+
+#~ msgid "Mark object to be initialized first."
+#~ msgstr "Marcar objeto a ser inicializado primero."
+
+#~ msgid "Enable/disable lazy-loading flag for following dependencies."
+#~ msgstr ""
+#~ "Activar/desactivar marca lazy-loading para las siguientes dependencias."
+
+#~ msgid "Mark object as not loadable with 'dlopen'."
+#~ msgstr "Marcar el objeto como no cargable con 'dlopen'"
+
+#~ msgid "Ignore/record dependencies on unused DSOs."
+#~ msgstr "Ignorar/registrar dependencias sobre DSO no utilizados."
+
+#~ msgid "Generated DSO will be a system library."
+#~ msgstr "El DSO generado será una biblioteca del sistema."
+
+#~ msgid "ADDRESS"
+#~ msgstr "DIRECCIÓN"
+
+#~ msgid "Set entry point address."
+#~ msgstr "Establecer dirección de entrada de punto"
+
+#~ msgid "Do not link against shared libraries."
+#~ msgstr "No enlazar con bibliotecas compartidas."
+
+#~ msgid "Prefer linking against shared libraries."
+#~ msgstr "No enlazar con bibliotecas compartidas."
+
+#~ msgid "Export all dynamic symbols."
+#~ msgstr "Exportar todos los símbolos dinámicos."
+
+#~ msgid "Strip all symbols."
+#~ msgstr "Descartar todos los símbolos."
+
+#~ msgid "Strip debugging symbols."
+#~ msgstr "Descartar los símbolos de depuración."
+
+#~ msgid "Assume pagesize for the target system to be SIZE."
+#~ msgstr "Asumir que pagesize para el sistema de destino sea SIZE."
+
+#~ msgid "Set runtime DSO search path."
+#~ msgstr "Establecer la ruta de búsqueda tiempo de ejecución DSO."
+
+#~ msgid "Set link time DSO search path."
+#~ msgstr "Establecer ruta de tiempo de enlace DSO."
+
+#~ msgid "Generate dynamic shared object."
+#~ msgstr "Generar objeto compartido dinámico."
+
+#~ msgid "Generate relocatable object."
+#~ msgstr "Generar objeto reubicable"
+
+#~ msgid "Causes symbol not assigned to a version be reduced to local."
+#~ msgstr ""
+#~ "Hacer que un símbolo no asignado a una versión sea reducido a local."
+
+#~ msgid "Remove unused sections."
+#~ msgstr "Eliminar las secciones no utilizadas."
+
+#~ msgid "Don't remove unused sections."
+#~ msgstr "No eliminar las secciones no utilizadas."
+
+#~ msgid "Set soname of shared object."
+#~ msgstr "Establecer soname de objeto compartido."
+
+#~ msgid "Set the dynamic linker name."
+#~ msgstr "Establecer el nombre de enlazador dinámico."
+
+#~ msgid "Add/suppress addition indentifying link-editor to .comment section."
+#~ msgstr ""
+#~ "Añadir/suprimir adición identificando enlace-editor para .sección de "
+#~ "comentario."
+
+#~ msgid "Create .eh_frame_hdr section"
+#~ msgstr "Crear una sección .eh_frame_hdr"
+
+#~ msgid "Set hash style to sysv, gnu or both."
+#~ msgstr "Establecer el estilo de dispersión un sysv, gnu o ambos."
+
+#~ msgid "Generate build ID note (md5, sha1 (default), uuid)."
+#~ msgstr ""
+#~ "Crear una nota del ID de compilación (md5, sha1 (por defecto), uuid)."
+
+#~ msgid "Linker Operation Control:"
+#~ msgstr "Control de volumen desconocido:"
+
+#~ msgid "Verbose messages."
+#~ msgstr "Mensajes explicativos."
+
+#~ msgid "Trace file opens."
+#~ msgstr "Rastrear apertura de ficheros."
+
+#~ msgid "Trade speed for less memory usage"
+#~ msgstr "Intercambiar velocidad por menor utilización de memoria"
+
+#~ msgid "LEVEL"
+#~ msgstr "NIVEL"
+
+#~ msgid "Set optimization level to LEVEL."
+#~ msgstr "Establecer el nivel de optimización a LEVEL."
+
+#~ msgid "Use linker script in FILE."
+#~ msgstr "Usar script enlazador en FICHERO."
+
+#~ msgid "Select to get parser debug information"
+#~ msgstr "Seleccionar para obtener análisis de información de depuración"
+
+#~ msgid "Read version information from FILE."
+#~ msgstr "Leer información de versión de FICHERO."
+
+#~ msgid "Set emulation to NAME."
+#~ msgstr "Establecer emulación a NOMBRE."
+
+#~ msgid "Combine object and archive files."
+#~ msgstr "Combinar objeto y archivos de almacenamiento."
+
+#~ msgid "[FILE]..."
+#~ msgstr "[FICHERO]..."
+
+#~ msgid "At least one input file needed"
+#~ msgstr "Se necesita al menos un fichero de entrada"
+
+#~ msgid "error while preparing linking"
+#~ msgstr "Error al preparar vinculación"
+
+#~ msgid "cannot open linker script '%s'"
+#~ msgstr "no se puede abrir script enlazador '%s'"
+
+#~ msgid "-( without matching -)"
+#~ msgstr "-( sin coincidir -)"
+
+#~ msgid "only one option of -G and -r is allowed"
+#~ msgstr "Solamente una opción de -G y -r es permitida"
+
+#~ msgid "more than one '-m' parameter"
+#~ msgstr "más de un parámetro '-m'"
+
+#~ msgid "unknown option `-%c %s'"
+#~ msgstr "opción desconocida `-%c %s'"
+
+#~ msgid "invalid page size value '%s': ignored"
+#~ msgstr "Valor de tamaño de página'%s': ignorado"
+
+#~ msgid "invalid hash style '%s'"
+#~ msgstr "estilo de dispersión inválido '%s'"
+
+#~ msgid "invalid build-ID style '%s'"
+#~ msgstr "estilo de cuerpo-ID inválido '%s'"
+
+#~ msgid "More than one output file name given."
+#~ msgstr "Se ha dado más de un nombre de archivo de salida."
+
+#~ msgid "Invalid optimization level `%s'"
+#~ msgstr "Nivel de optimización inválido `%s'"
+
+#~ msgid "nested -( -) groups are not allowed"
+#~ msgstr "no se permiten grupos -( -) en nido"
+
+#~ msgid "-) without matching -("
+#~ msgstr "-) sin coincidir -("
+
+#~ msgid "unknown option '-%c %s'"
+#~ msgstr "Opción desconocida '-%c %s'"
+
+#~ msgid "could not find input file to determine output file format"
+#~ msgstr ""
+#~ "no se pudo encontrar un archivo de entrada que determine el formato del "
+#~ "archivo de salida"
+
+#~ msgid "try again with an appropriate '-m' parameter"
+#~ msgstr "Inténtelo con una parámetro '-m' apropiado"
+
+#~ msgid "cannot read version script '%s'"
+#~ msgstr "No se puede leer script de versión '%s'"
+
+#~ msgid "duplicate definition of '%s' in linker script"
+#~ msgstr "Duplicar definición de '%s' en script enlazador"
+
+#~ msgid "cannot create string table"
+#~ msgstr "no puede crear tabla de cadenas"
+
+#~ msgid "cannot load ld backend library '%s': %s"
+#~ msgstr "no se puede cargar biblioteca ID de segundo plano '%s': %s"
+
+#~ msgid "cannot find init function in ld backend library '%s': %s"
+#~ msgstr ""
+#~ "no se pudo encontrar la función init en la biblioteca ld de segundo plano "
+#~ "'%s': %s"
+
+#~ msgid "%s listed more than once as input"
+#~ msgstr "%s listado más de una vez como entrada"
+
+#~ msgid "%s (for -l%s)\n"
+#~ msgstr "%s (para -l%s)\n"
+
+#~ msgid "%s (for DT_NEEDED %s)\n"
+#~ msgstr "%s (para DT_NEEDED %s)\n"
+
+#~ msgid "Warning: type of `%s' changed from %s in %s to %s in %s"
+#~ msgstr "Advertencia: el tipo de `%s' cambió de %s en %s a %s en %s"
+
+#~ msgid ""
+#~ "Warning: size of `%s' changed from %<PRIu64> in %s to %<PRIu64> in %s"
+#~ msgstr ""
+#~ "Advertencia: el tamaño de `%s' cambió de %<PRIu64> en %s a %<PRIu64> en %s"
+
+#~ msgid "(%s+%#<PRIx64>): multiple definition of %s `%s'\n"
+#~ msgstr "(%s+%#<PRIx64>): definición múltiplo de %s `%s'\n"
+
+#~ msgid "(%s+%#<PRIx64>): first defined here\n"
+#~ msgstr "(%s+%#<PRIx64>): se definió primero aquí\n"
+
+#~ msgid "%s: cannot get section group data: %s"
+#~ msgstr "%s: no se pueden obtener datos de sección de grupo: %s"
+
+#~ msgid "%s: section '%s' with group flag set does not belong to any group"
+#~ msgstr ""
+#~ "%s: la sección '%s' con bandera de grupo establecida no pertenece a "
+#~ "ningún grupo"
+
+#~ msgid "%s: section [%2d] '%s' is not in the correct section group"
+#~ msgstr ""
+#~ "%s: la sección [%2d] '%s' no se encuentra en el grupo de sección correcto"
+
+#~ msgid "%s: invalid ELF file (%s:%d)\n"
+#~ msgstr "%s: fichero ELF inválido (%s:%d)\n"
+
+#~ msgid "%s: only files of type ET_REL might contain section groups"
+#~ msgstr "%s: solo archivos de tipo ET_REL pueden contener grupos de sección"
+
+#~ msgid "%s: cannot determine signature of section group [%2zd] '%s': %s"
+#~ msgstr ""
+#~ "%s: no es posible determinar la firma del grupo de sección [%2zd] '%s': "
+#~ "%s "
+
+#~ msgid "%s: cannot get content of section group [%2zd] '%s': %s'"
+#~ msgstr ""
+#~ "%s: no es posible obtener el contenido de la sección del grupo [%2zd] "
+#~ "'%s': %s'"
+
+#~ msgid ""
+#~ "%s: group member %zu of section group [%2zd] '%s' has too high index: "
+#~ "%<PRIu32>"
+#~ msgstr ""
+#~ "%s el miembro del grupo %zu del grupo de sección [%2zd] '%s' posee el "
+#~ "índice demasiado alto: %<PRIu32>"
+
+#~ msgid "%s: section '%s' has unknown type: %d"
+#~ msgstr "%s: sección '%s' tiene tipo desconocido: %d"
+
+#~ msgid "cannot get descriptor for ELF file (%s:%d): %s\n"
+#~ msgstr "no es posible obtener descriptor para el archivo ELF (%s:%d): %s\n"
+
+#~ msgid "cannot read archive `%s': %s"
+#~ msgstr "no se puede leer archivo `%s': %s"
+
+#~ msgid "file of type %s cannot be linked in\n"
+#~ msgstr "archivo de tipo %s no puede ser enlazado en\n"
+
+#~ msgid "%s: input file incompatible with ELF machine type %s\n"
+#~ msgstr ""
+#~ "%s: el archivo ingresado es incompatible con una máquina ELF tipo %s\n"
+
+#~ msgid "%s: cannot get section header string table index: %s\n"
+#~ msgstr ""
+#~ "%s: no se ha podido obtener un índice para la tabla de la cadena del "
+#~ "encabezamiento de la sección: %s\n"
+
+#~ msgid "cannot use DSO '%s' when generating relocatable object file"
+#~ msgstr ""
+#~ "no es posible utilizar DSO '%s' al general un archivo de objeto realojable"
+
+#~ msgid "input file '%s' ignored"
+#~ msgstr "archivo de entrada '%s' ignorado"
+
+#~ msgid "undefined symbol `%s' in %s"
+#~ msgstr "símbolo indefinido `%s' en %s"
+
+#~ msgid "cannot create ELF descriptor for output file: %s"
+#~ msgstr "no es posible crear un descriptor ELF para el archivo de salida: %s"
+
+#~ msgid "could not create ELF header for output file: %s"
+#~ msgstr ""
+#~ "no es posible crear un encabezamiento ELF para el archivo de salida: %s"
+
+#~ msgid "cannot create section for output file: %s"
+#~ msgstr "no se puede crear sección para archivo de salida: %s"
+
+#~ msgid "address computation expression contains variable '%s'"
+#~ msgstr "la expresión de computación contiene la variable '%s'"
+
+#~ msgid ""
+#~ "argument '%<PRIuMAX>' of ALIGN in address computation expression is no "
+#~ "power of two"
+#~ msgstr ""
+#~ "el argumento '%<PRIuMAX>' de ALIGN en expresión de dirección de "
+#~ "computación no es potencia de dos"
+
+#~ msgid "cannot find entry symbol '%s': defaulting to %#0*<PRIx64>"
+#~ msgstr ""
+#~ "no se puede encontrar símbolo de entrada '%s': predeterminada para "
+#~ "%#0*<PRIx64>"
+
+#~ msgid "no entry symbol specified: defaulting to %#0*<PRIx64>"
+#~ msgstr ""
+#~ "no se ha especificado una entrada de símbolo: estableciendo por defecto a "
+#~ "%#0*<PRIx64>"
+
+#~ msgid "cannot create GNU hash table section for output file: %s"
+#~ msgstr ""
+#~ "no se puede crear una tabla de dispersión GNU para archivo de salida: %s"
+
+#~ msgid "cannot create hash table section for output file: %s"
+#~ msgstr ""
+#~ "no es posible crear una sección para la tabla de dispersión del archivo "
+#~ "de salida: %s"
+
+#~ msgid "cannot create build ID section: %s"
+#~ msgstr "no se puede crear sección de creación de ID: %s"
+
+#~ msgid "cannot convert section data to file format: %s"
+#~ msgstr ""
+#~ "no es posible convertir los datos de la sección en formato de archivo: %s"
+
+#~ msgid "cannot convert section data to memory format: %s"
+#~ msgstr ""
+#~ "no es posible convertir datos de la sección en formato de memoria: %s"
+
+#~ msgid "cannot read enough data for UUID"
+#~ msgstr "no es posible leer suficientes datos para el UUID"
+
+#~ msgid "cannot create symbol table for output file: %s"
+#~ msgstr "no es posible crear tabla de símbolo para el comando de salida: %s"
+
+#~ msgid "section index too large in dynamic symbol table"
+#~ msgstr ""
+#~ "el índice de la sección es demasiado extenso en la tabla de símbolos "
+#~ "dinámicos"
+
+#~ msgid "cannot create versioning section: %s"
+#~ msgstr "no se puede crear sección de versión: %s"
+
+#~ msgid "cannot create dynamic symbol table for output file: %s"
+#~ msgstr ""
+#~ "no es posible crear tabla de símbolos dinámicos para el archivo de "
+#~ "salida: %s"
+
+#~ msgid "cannot create versioning data: %s"
+#~ msgstr "no se pueden crear datos de versión: %s"
+
+#~ msgid "cannot create section header string section: %s"
+#~ msgstr ""
+#~ "no se puede crear sección de cadenas de encabezamiento de sección: %s"
+
+#~ msgid "cannot create section header string section"
+#~ msgstr "no se puede crear sección de cadenas de encabezamiento de sección"
+
+#~ msgid "cannot create program header: %s"
+#~ msgstr "no se puede crear encabezamiento de programa: %s"
+
+#~ msgid "while determining file layout: %s"
+#~ msgstr "al determinar diseño de fichero: %s"
+
+#~ msgid "internal error: non-nobits section follows nobits section"
+#~ msgstr "error interno: sección non-nobits sigue a sección nobits"
+
+#~ msgid "cannot get header of 0th section: %s"
+#~ msgstr "No se puede obtener encabezamiento de sección 0th: %s"
+
+#~ msgid "linker backend didn't specify function to relocate section"
+#~ msgstr ""
+#~ "enlazador de segundo plano no especificó función para reubicar sección"
+
+#~ msgid "while writing output file: %s"
+#~ msgstr "Ocurrió un error de fichero de salida: %s"
+
+#~ msgid "while finishing output file: %s"
+#~ msgstr "error al cerrar el fichero de salida: %s"
+
+#~ msgid "cannot stat output file"
+#~ msgstr "no se puede generar stat de fichero de salida"
+
+#~ msgid "WARNING: temporary output file overwritten before linking finished"
+#~ msgstr ""
+#~ "ADVERTENCIA: archivo de salida temporal sobreescrito antes que haya "
+#~ "concluido el enlazamiento"
+
+#~ msgid "no machine specific '%s' implementation"
+#~ msgstr "no hay máquina específica de implementación '%s'"
+
+#~ msgid "mode for segment invalid\n"
+#~ msgstr "modo para segmento inválido\n"
+
+#~ msgid "while reading version script '%s': %s at line %d"
+#~ msgstr "al leer script de versión '%s': %s en línea %d"
+
+#~ msgid "while reading linker script '%s': %s at line %d"
+#~ msgstr "al leer script de enlace '%s': %s en línea %d"
+
+#, fuzzy
+#~ msgid ""
+#~ "symbol '%s' is declared both local and global for unnamed version '%s'"
+#~ msgstr ""
+#~ "el símbolo '%s' es declarado tanto local como global para la versión sin "
+#~ "nombre"
+
+#~ msgid "symbol '%s' is declared both local and global for version '%s'"
+#~ msgstr ""
+#~ "el símbolo '%s' es declarado tanto local como global para la versión '%s'"
+
+#~ msgid "default visibility set as local and global"
+#~ msgstr ""
+#~ "la visibilidad establecida por defecto establecida como local y global"
+
+#~ msgid "cannot get section header of section %Zu: %s"
+#~ msgstr "No se puede obtener encabezamiento de sección %Zu: %s"
+
+#, fuzzy
+#~ msgid "cannot attach to core"
+#~ msgstr "No se puede crear el árbol de búsqueda"
+
+#~ msgid "'%s' and '%s' do not seem to match"
+#~ msgstr "Al parecer '%s' y '%s'no coinciden"
+
+#~ msgid "unknown tag %hx"
+#~ msgstr "etiqueta %hx desconocida"
+
+#~ msgid "unknown user tag %hx"
+#~ msgstr "Usuario de etiqueta %hx desconocido "
+
+#~ msgid "unknown attribute %hx"
+#~ msgstr "atributo de sección %hx desconocido"
+
+#~ msgid "unknown user attribute %hx"
+#~ msgstr "Atributo de usuario desconocido %hx"
+
+#, fuzzy
+#~ msgid "unknown form %#<PRIx64>"
+#~ msgstr "Forma %<PRIx64> desconocida"
+
+#~ msgid ""
+#~ "\n"
+#~ "\n"
+#~ "Symbols from %s[%s]:\n"
+#~ "\n"
+#~ msgstr ""
+#~ "\n"
+#~ "\n"
+#~ "Símbolos de %s[%s]:\n"
+#~ "\n"
+
+#~ msgid "%s %s differ: section header"
+#~ msgstr "%s %s differ: encabezamiento de sección"
+
+#~ msgid "Equivalent to: -e -h -l"
+#~ msgstr "Equivalente a: -e -h -l"
+
+#~ msgid "zeroth section has nonzero info field\n"
+#~ msgstr "Sección zeroth tiene campo de información nonzero\n"
+
+#~ msgid " Version String: "
+#~ msgstr "Cadena versión:"
+
+#~ msgid ""
+#~ "\n"
+#~ "Section [%Zu] '%s' is empty.\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Sección [%Zu] '%s' está vacía.\n"
diff --git a/third_party/elfutils/po/fr.po b/third_party/elfutils/po/fr.po
new file mode 100644
index 0000000..1a7a3f8
--- /dev/null
+++ b/third_party/elfutils/po/fr.po
@@ -0,0 +1,5665 @@
+# Translations template for ELFUTILS.
+# Copyright (C) 2009 ORGANIZATION
+# This file is distributed under the same license as the elfutils package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: elfutils.master.fr\n"
+"Report-Msgid-Bugs-To: http://bugzilla.redhat.com/\n"
+"POT-Creation-Date: 2010-04-21 07:41-0700\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <fedora-trans-fr@redhat.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: lib/xmalloc.c:51 lib/xmalloc.c:65 lib/xmalloc.c:79 src/readelf.c:2822
+#: src/readelf.c:3161 src/unstrip.c:2087 src/unstrip.c:2295
+#, c-format
+msgid "memory exhausted"
+msgstr ""
+
+#: libasm/asm_error.c:62 libdw/dwarf_error.c:79 libdwfl/libdwflP.h:70
+#: libelf/elf_error.c:81
+msgid "no error"
+msgstr ""
+
+#: libasm/asm_error.c:63 libdw/dwarf_error.c:88 libdwfl/libdwflP.h:72
+#: libelf/elf_error.c:112
+msgid "out of memory"
+msgstr ""
+
+#: libasm/asm_error.c:64 src/ldgeneric.c:2687
+#, c-format
+msgid "cannot create output file"
+msgstr ""
+
+#: libasm/asm_error.c:65
+msgid "invalid parameter"
+msgstr ""
+
+#: libasm/asm_error.c:66
+msgid "cannot change mode of output file"
+msgstr ""
+
+#: libasm/asm_error.c:67 src/ldgeneric.c:7001
+#, c-format
+msgid "cannot rename output file"
+msgstr ""
+
+#: libasm/asm_error.c:68
+msgid "duplicate symbol"
+msgstr ""
+
+#: libasm/asm_error.c:69
+msgid "invalid section type for operation"
+msgstr ""
+
+#: libasm/asm_error.c:70
+msgid "error during output of data"
+msgstr ""
+
+#: libasm/asm_error.c:71
+msgid "no backend support available"
+msgstr ""
+
+#: libasm/asm_error.c:81 libdw/dwarf_error.c:80 libdwfl/libdwflP.h:71
+#: libelf/elf_error.c:84
+msgid "unknown error"
+msgstr ""
+
+#: libdw/dwarf_error.c:81
+msgid "invalid access"
+msgstr ""
+
+#: libdw/dwarf_error.c:82
+msgid "no regular file"
+msgstr ""
+
+#: libdw/dwarf_error.c:83
+msgid "I/O error"
+msgstr ""
+
+#: libdw/dwarf_error.c:84
+msgid "invalid ELF file"
+msgstr ""
+
+#: libdw/dwarf_error.c:85
+msgid "no DWARF information"
+msgstr ""
+
+#: libdw/dwarf_error.c:86
+msgid "no ELF file"
+msgstr ""
+
+#: libdw/dwarf_error.c:87
+msgid "cannot get ELF header"
+msgstr ""
+
+#: libdw/dwarf_error.c:89
+msgid "not implemented"
+msgstr ""
+
+#: libdw/dwarf_error.c:90 libelf/elf_error.c:128 libelf/elf_error.c:176
+msgid "invalid command"
+msgstr ""
+
+#: libdw/dwarf_error.c:91
+msgid "invalid version"
+msgstr ""
+
+#: libdw/dwarf_error.c:92
+msgid "invalid file"
+msgstr ""
+
+#: libdw/dwarf_error.c:93
+msgid "no entries found"
+msgstr ""
+
+#: libdw/dwarf_error.c:94
+msgid "invalid DWARF"
+msgstr ""
+
+#: libdw/dwarf_error.c:95
+msgid "no string data"
+msgstr ""
+
+#: libdw/dwarf_error.c:96
+msgid "no address value"
+msgstr ""
+
+#: libdw/dwarf_error.c:97
+msgid "no constant value"
+msgstr ""
+
+#: libdw/dwarf_error.c:98
+msgid "no reference value"
+msgstr ""
+
+#: libdw/dwarf_error.c:99
+msgid "invalid reference value"
+msgstr ""
+
+#: libdw/dwarf_error.c:100
+msgid ".debug_line section missing"
+msgstr ""
+
+#: libdw/dwarf_error.c:101
+msgid "invalid .debug_line section"
+msgstr ""
+
+#: libdw/dwarf_error.c:102
+msgid "debug information too big"
+msgstr ""
+
+#: libdw/dwarf_error.c:103
+msgid "invalid DWARF version"
+msgstr ""
+
+#: libdw/dwarf_error.c:104
+msgid "invalid directory index"
+msgstr ""
+
+#: libdw/dwarf_error.c:105 libdwfl/libdwflP.h:91
+msgid "address out of range"
+msgstr ""
+
+#: libdw/dwarf_error.c:106
+msgid "no location list value"
+msgstr ""
+
+#: libdw/dwarf_error.c:107
+msgid "no block data"
+msgstr ""
+
+#: libdw/dwarf_error.c:108
+msgid "invalid line index"
+msgstr ""
+
+#: libdw/dwarf_error.c:109
+msgid "invalid address range index"
+msgstr ""
+
+#: libdw/dwarf_error.c:110 libdwfl/libdwflP.h:92
+msgid "no matching address range"
+msgstr ""
+
+#: libdw/dwarf_error.c:111
+msgid "no flag value"
+msgstr ""
+
+#: libdw/dwarf_error.c:112 libelf/elf_error.c:253
+msgid "invalid offset"
+msgstr ""
+
+#: libdw/dwarf_error.c:113
+msgid ".debug_ranges section missing"
+msgstr ""
+
+#: libdw/dwarf_error.c:114
+msgid "invalid CFI section"
+msgstr ""
+
+#: libdwfl/argp-std.c:67 src/unstrip.c:2237
+msgid "Input selection options:"
+msgstr ""
+
+#: libdwfl/argp-std.c:68
+msgid "Find addresses in FILE"
+msgstr ""
+
+#: libdwfl/argp-std.c:70
+msgid "Find addresses from signatures found in COREFILE"
+msgstr ""
+
+#: libdwfl/argp-std.c:72
+msgid "Find addresses in files mapped into process PID"
+msgstr ""
+
+#: libdwfl/argp-std.c:74
+msgid ""
+"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps "
+"format"
+msgstr ""
+
+#: libdwfl/argp-std.c:76
+msgid "Find addresses in the running kernel"
+msgstr ""
+
+#: libdwfl/argp-std.c:78
+msgid "Kernel with all modules"
+msgstr ""
+
+#: libdwfl/argp-std.c:80
+msgid "Search path for separate debuginfo files"
+msgstr ""
+
+#: libdwfl/argp-std.c:163
+msgid "only one of -e, -p, -k, -K, or --core allowed"
+msgstr ""
+
+#: libdwfl/argp-std.c:223
+#, c-format
+msgid "cannot read ELF core file: %s"
+msgstr ""
+
+#: libdwfl/argp-std.c:241
+msgid "No modules recognized in core file"
+msgstr ""
+
+#: libdwfl/argp-std.c:253
+msgid "cannot load kernel symbols"
+msgstr ""
+
+#: libdwfl/argp-std.c:257
+msgid "cannot find kernel modules"
+msgstr ""
+
+#: libdwfl/argp-std.c:271
+msgid "cannot find kernel or modules"
+msgstr ""
+
+#: libdwfl/libdwflP.h:73
+msgid "See errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:74
+msgid "See elf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:75
+msgid "See dwarf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:76
+msgid "See ebl_errno (XXX missing)"
+msgstr ""
+
+#: libdwfl/libdwflP.h:77
+msgid "gzip decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:78
+msgid "bzip2 decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:79
+msgid "LZMA decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:80
+msgid "no support library found for machine"
+msgstr ""
+
+#: libdwfl/libdwflP.h:81
+msgid "Callbacks missing for ET_REL file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:82
+msgid "Unsupported relocation type"
+msgstr ""
+
+#: libdwfl/libdwflP.h:83
+msgid "r_offset is bogus"
+msgstr ""
+
+#: libdwfl/libdwflP.h:84 libelf/elf_error.c:132 libelf/elf_error.c:192
+msgid "offset out of range"
+msgstr ""
+
+#: libdwfl/libdwflP.h:85
+msgid "relocation refers to undefined symbol"
+msgstr ""
+
+#: libdwfl/libdwflP.h:86
+msgid "Callback returned failure"
+msgstr ""
+
+#: libdwfl/libdwflP.h:87
+msgid "No DWARF information found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:88
+msgid "No symbol table found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:89
+msgid "No ELF program headers"
+msgstr ""
+
+#: libdwfl/libdwflP.h:90
+msgid "address range overlaps an existing module"
+msgstr ""
+
+#: libdwfl/libdwflP.h:93
+msgid "image truncated"
+msgstr ""
+
+#: libdwfl/libdwflP.h:94
+msgid "ELF file opened"
+msgstr ""
+
+#: libdwfl/libdwflP.h:95
+msgid "not a valid ELF file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:96
+msgid "cannot handle DWARF type description"
+msgstr ""
+
+#: libebl/eblbackendname.c:63
+msgid "No backend"
+msgstr ""
+
+#: libebl/eblcorenotetypename.c:107 libebl/eblobjecttypename.c:78
+#: libebl/eblobjnotetypename.c:86 libebl/eblosabiname.c:98
+#: libebl/eblsectionname.c:110 libebl/eblsectiontypename.c:140
+#: libebl/eblsegmenttypename.c:104
+msgid "<unknown>"
+msgstr ""
+
+#: libebl/ebldynamictagname.c:126
+#, c-format
+msgid "<unknown>: %#<PRIx64>"
+msgstr ""
+
+#: libebl/eblobjnote.c:76
+#, c-format
+msgid "    Build ID: "
+msgstr ""
+
+#: libebl/eblobjnote.c:87
+#, c-format
+msgid "    Linker version: %.*s\n"
+msgstr ""
+
+#: libebl/eblobjnote.c:136
+#, c-format
+msgid "    OS: %s, ABI: "
+msgstr ""
+
+#: libebl/eblosabiname.c:95
+msgid "Stand alone"
+msgstr ""
+
+#: libebl/eblsymbolbindingname.c:92 libebl/eblsymboltypename.c:98
+#, c-format
+msgid "<unknown>: %d"
+msgstr ""
+
+#: libelf/elf_error.c:88
+msgid "unknown version"
+msgstr ""
+
+#: libelf/elf_error.c:92
+msgid "unknown type"
+msgstr ""
+
+#: libelf/elf_error.c:96
+msgid "invalid `Elf' handle"
+msgstr ""
+
+#: libelf/elf_error.c:100
+msgid "invalid size of source operand"
+msgstr ""
+
+#: libelf/elf_error.c:104
+msgid "invalid size of destination operand"
+msgstr ""
+
+#: libelf/elf_error.c:108 src/readelf.c:4779
+#, c-format
+msgid "invalid encoding"
+msgstr ""
+
+#: libelf/elf_error.c:116
+msgid "invalid file descriptor"
+msgstr ""
+
+#: libelf/elf_error.c:120
+msgid "invalid operation"
+msgstr ""
+
+#: libelf/elf_error.c:124
+msgid "ELF version not set"
+msgstr ""
+
+#: libelf/elf_error.c:136
+msgid "invalid fmag field in archive header"
+msgstr ""
+
+#: libelf/elf_error.c:140
+msgid "invalid archive file"
+msgstr ""
+
+#: libelf/elf_error.c:144
+msgid "descriptor is not for an archive"
+msgstr ""
+
+#: libelf/elf_error.c:148
+msgid "no index available"
+msgstr ""
+
+#: libelf/elf_error.c:152
+msgid "cannot read data from file"
+msgstr ""
+
+#: libelf/elf_error.c:156
+msgid "cannot write data to file"
+msgstr ""
+
+#: libelf/elf_error.c:160
+msgid "invalid binary class"
+msgstr ""
+
+#: libelf/elf_error.c:164
+msgid "invalid section index"
+msgstr ""
+
+#: libelf/elf_error.c:168
+msgid "invalid operand"
+msgstr ""
+
+#: libelf/elf_error.c:172
+msgid "invalid section"
+msgstr ""
+
+#: libelf/elf_error.c:180
+msgid "executable header not created first"
+msgstr ""
+
+#: libelf/elf_error.c:184
+msgid "file descriptor disabled"
+msgstr ""
+
+#: libelf/elf_error.c:188
+msgid "archive/member file descriptor mismatch"
+msgstr ""
+
+#: libelf/elf_error.c:196
+msgid "cannot manipulate null section"
+msgstr ""
+
+#: libelf/elf_error.c:200
+msgid "data/scn mismatch"
+msgstr ""
+
+#: libelf/elf_error.c:204
+msgid "invalid section header"
+msgstr ""
+
+#: libelf/elf_error.c:208 src/readelf.c:6242 src/readelf.c:6343
+#, c-format
+msgid "invalid data"
+msgstr ""
+
+#: libelf/elf_error.c:212
+msgid "unknown data encoding"
+msgstr ""
+
+#: libelf/elf_error.c:216
+msgid "section `sh_size' too small for data"
+msgstr ""
+
+#: libelf/elf_error.c:220
+msgid "invalid section alignment"
+msgstr ""
+
+#: libelf/elf_error.c:224
+msgid "invalid section entry size"
+msgstr ""
+
+#: libelf/elf_error.c:228
+msgid "update() for write on read-only file"
+msgstr ""
+
+#: libelf/elf_error.c:232
+msgid "no such file"
+msgstr ""
+
+#: libelf/elf_error.c:236
+msgid "only relocatable files can contain section groups"
+msgstr ""
+
+#: libelf/elf_error.c:241
+msgid ""
+"program header only allowed in executables, shared objects, and core files"
+msgstr ""
+
+#: libelf/elf_error.c:248
+msgid "file has no program header"
+msgstr ""
+
+#: src/addr2line.c:66
+msgid "Output selection options:"
+msgstr ""
+
+#: src/addr2line.c:67
+msgid "Show only base names of source files"
+msgstr ""
+
+#: src/addr2line.c:69
+msgid "Show absolute file names using compilation directory"
+msgstr ""
+
+#: src/addr2line.c:70
+msgid "Also show function names"
+msgstr ""
+
+#: src/addr2line.c:71
+msgid "Also show symbol or section names"
+msgstr ""
+
+#: src/addr2line.c:73
+msgid "Treat addresses as offsets relative to NAME section."
+msgstr ""
+
+#: src/addr2line.c:75 src/elfcmp.c:75 src/findtextrel.c:75 src/nm.c:103
+#: src/strings.c:83
+msgid "Miscellaneous:"
+msgstr ""
+
+#: src/addr2line.c:84
+msgid ""
+"Locate source files and line information for ADDRs (in a.out by default)."
+msgstr ""
+
+#: src/addr2line.c:88
+msgid "[ADDR...]"
+msgstr ""
+
+#: src/addr2line.c:185 src/ar.c:289 src/elfcmp.c:555 src/elflint.c:239
+#: src/findtextrel.c:170 src/ld.c:957 src/nm.c:253 src/objdump.c:181
+#: src/ranlib.c:136 src/readelf.c:449 src/size.c:219 src/strings.c:227
+#: src/strip.c:204 src/unstrip.c:234
+#, c-format
+msgid ""
+"Copyright (C) %s Red Hat, Inc.\n"
+"This is free software; see the source for copying conditions.  There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+
+#: src/addr2line.c:190 src/ar.c:294 src/elfcmp.c:560 src/elflint.c:244
+#: src/findtextrel.c:175 src/ld.c:962 src/nm.c:258 src/objdump.c:186
+#: src/ranlib.c:141 src/readelf.c:454 src/size.c:224 src/strings.c:232
+#: src/strip.c:209 src/unstrip.c:239
+#, c-format
+msgid "Written by %s.\n"
+msgstr ""
+
+#: src/addr2line.c:405
+#, c-format
+msgid "Section syntax requires exactly one module"
+msgstr ""
+
+#: src/addr2line.c:428
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside section '%s'"
+msgstr ""
+
+#: src/addr2line.c:461
+#, c-format
+msgid "cannot find symbol '%s'"
+msgstr ""
+
+#: src/addr2line.c:466
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside contents of '%s'"
+msgstr ""
+
+#: src/ar.c:76
+msgid "Commands:"
+msgstr ""
+
+#: src/ar.c:77
+msgid "Delete files from archive."
+msgstr ""
+
+#: src/ar.c:78
+msgid "Move files in archive."
+msgstr ""
+
+#: src/ar.c:79
+msgid "Print files in archive."
+msgstr ""
+
+#: src/ar.c:80
+msgid "Quick append files to archive."
+msgstr ""
+
+#: src/ar.c:82
+msgid "Replace existing or insert new file into archive."
+msgstr ""
+
+#: src/ar.c:83
+msgid "Display content of archive."
+msgstr ""
+
+#: src/ar.c:84
+msgid "Extract files from archive."
+msgstr ""
+
+#: src/ar.c:86
+msgid "Command Modifiers:"
+msgstr ""
+
+#: src/ar.c:87
+msgid "Preserve original dates."
+msgstr ""
+
+#: src/ar.c:88
+msgid "Use instance [COUNT] of name."
+msgstr ""
+
+#: src/ar.c:90
+msgid "Do not replace existing files with extracted files."
+msgstr ""
+
+#: src/ar.c:91
+msgid "Allow filename to be truncated if necessary."
+msgstr ""
+
+#: src/ar.c:93
+msgid "Provide verbose output."
+msgstr ""
+
+#: src/ar.c:94
+msgid "Force regeneration of symbol table."
+msgstr ""
+
+#: src/ar.c:95
+msgid "Insert file after [MEMBER]."
+msgstr ""
+
+#: src/ar.c:96
+msgid "Insert file before [MEMBER]."
+msgstr ""
+
+#: src/ar.c:97
+msgid "Same as -b."
+msgstr ""
+
+#: src/ar.c:98
+msgid "Suppress message when library has to be created."
+msgstr ""
+
+#: src/ar.c:100
+msgid "Use full path for file matching."
+msgstr ""
+
+#: src/ar.c:101
+msgid "Update only older files in archive."
+msgstr ""
+
+#: src/ar.c:107
+msgid "Create, modify, and extract from archives."
+msgstr ""
+
+#: src/ar.c:110
+msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]"
+msgstr ""
+
+#: src/ar.c:192
+#, c-format
+msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options"
+msgstr ""
+
+#: src/ar.c:197
+#, c-format
+msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers"
+msgstr ""
+
+#: src/ar.c:213
+#, c-format
+msgid "'N' is only meaningful with the 'x' and 'd' options"
+msgstr ""
+
+#: src/ar.c:218
+#, c-format
+msgid "COUNT parameter required"
+msgstr ""
+
+#: src/ar.c:230
+#, c-format
+msgid "invalid COUNT parameter %s"
+msgstr ""
+
+#: src/ar.c:237
+#, c-format
+msgid "'%c' is only meaningful with the 'x' option"
+msgstr ""
+
+#: src/ar.c:243
+#, c-format
+msgid "archive name required"
+msgstr ""
+
+#: src/ar.c:314
+#, c-format
+msgid "More than one operation specified"
+msgstr ""
+
+#: src/ar.c:404
+#, c-format
+msgid "cannot open archive '%s'"
+msgstr ""
+
+#: src/ar.c:414
+#, c-format
+msgid "cannot open archive '%s': %s"
+msgstr ""
+
+#: src/ar.c:418
+#, c-format
+msgid "%s: not an archive file"
+msgstr ""
+
+#: src/ar.c:422
+#, c-format
+msgid "cannot stat archive '%s'"
+msgstr ""
+
+#: src/ar.c:434
+#, c-format
+msgid "no entry %s in archive\n"
+msgstr ""
+
+#: src/ar.c:487 src/ar.c:929 src/ar.c:1129
+#, c-format
+msgid "cannot create hash table"
+msgstr ""
+
+#: src/ar.c:494 src/ar.c:936 src/ar.c:1138
+#, c-format
+msgid "cannot insert into hash table"
+msgstr ""
+
+#: src/ar.c:502 src/ranlib.c:176
+#, c-format
+msgid "cannot stat '%s'"
+msgstr ""
+
+#: src/ar.c:598
+#, c-format
+msgid "cannot read content of %s: %s"
+msgstr ""
+
+#: src/ar.c:641
+#, c-format
+msgid "cannot open %.*s"
+msgstr ""
+
+#: src/ar.c:663
+#, c-format
+msgid "failed to write %s"
+msgstr ""
+
+#: src/ar.c:675
+#, c-format
+msgid "cannot change mode of %s"
+msgstr ""
+
+#: src/ar.c:691
+#, c-format
+msgid "cannot change modification time of %s"
+msgstr ""
+
+#: src/ar.c:737
+#, c-format
+msgid "cannot rename temporary file to %.*s"
+msgstr ""
+
+#: src/ar.c:773 src/ar.c:1021 src/ar.c:1419 src/ranlib.c:250
+#, c-format
+msgid "cannot create new file"
+msgstr ""
+
+#: src/ar.c:1220
+#, c-format
+msgid "position member %s not found"
+msgstr ""
+
+#: src/ar.c:1230
+#, c-format
+msgid "%s: no entry %s in archive!\n"
+msgstr ""
+
+#: src/ar.c:1259 src/ldgeneric.c:519 src/objdump.c:257
+#, c-format
+msgid "cannot open %s"
+msgstr ""
+
+#: src/ar.c:1264
+#, c-format
+msgid "cannot stat %s"
+msgstr ""
+
+#: src/ar.c:1270
+#, c-format
+msgid "%s is no regular file"
+msgstr ""
+
+#: src/ar.c:1283
+#, c-format
+msgid "cannot get ELF descriptor for %s: %s\n"
+msgstr ""
+
+#: src/ar.c:1302
+#, c-format
+msgid "cannot read %s: %s"
+msgstr ""
+
+#: src/arlib.c:215
+#, c-format
+msgid "the archive '%s' is too large"
+msgstr ""
+
+#: src/arlib.c:228
+#, c-format
+msgid "cannot read ELF header of %s(%s): %s"
+msgstr ""
+
+#: src/elfcmp.c:69
+msgid "Control options:"
+msgstr ""
+
+#: src/elfcmp.c:70
+msgid ""
+"Control treatment of gaps in loadable segments [ignore|match] (default: "
+"ignore)"
+msgstr ""
+
+#: src/elfcmp.c:72
+msgid "Ignore permutation of buckets in SHT_HASH section"
+msgstr ""
+
+#: src/elfcmp.c:73
+msgid "Output nothing; yield exit status only"
+msgstr ""
+
+#: src/elfcmp.c:80
+msgid "Compare relevant parts of two ELF files for equality."
+msgstr ""
+
+#: src/elfcmp.c:84
+msgid "FILE1 FILE2"
+msgstr ""
+
+#: src/elfcmp.c:140
+msgid "Invalid number of parameters.\n"
+msgstr ""
+
+#: src/elfcmp.c:168 src/elfcmp.c:173
+#, c-format
+msgid "cannot get ELF header of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:190
+#, c-format
+msgid "%s %s diff: ELF header"
+msgstr ""
+
+#: src/elfcmp.c:198 src/elfcmp.c:201
+#, c-format
+msgid "cannot get section count of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:206
+#, c-format
+msgid "%s %s diff: section count"
+msgstr ""
+
+#: src/elfcmp.c:214 src/elfcmp.c:217
+#, c-format
+msgid "cannot get program header count of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:222
+#, c-format
+msgid "%s %s diff: program header count"
+msgstr ""
+
+#: src/elfcmp.c:281
+#, c-format
+msgid "%s %s differ: section header"
+msgstr ""
+
+#: src/elfcmp.c:309 src/elfcmp.c:315
+#, c-format
+msgid "cannot get content of section %zu in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:331 src/elfcmp.c:337
+#, c-format
+msgid "cannot get symbol in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:358
+#, c-format
+msgid "%s %s differ: symbol table [%zu]"
+msgstr ""
+
+#: src/elfcmp.c:361
+#, c-format
+msgid "%s %s differ: symbol table [%zu,%zu]"
+msgstr ""
+
+#: src/elfcmp.c:409
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:413
+#, c-format
+msgid "%s %s differ: section [%zu,%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:429
+#, c-format
+msgid "%s %s differ: unequal amount of important sections"
+msgstr ""
+
+#: src/elfcmp.c:463 src/elfcmp.c:468
+#, c-format
+msgid "cannot load data of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:487 src/elfcmp.c:493
+#, c-format
+msgid "cannot get program header entry %d of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:499
+#, c-format
+msgid "%s %s differ: program header %d"
+msgstr ""
+
+#: src/elfcmp.c:524
+#, c-format
+msgid "%s %s differ: gap"
+msgstr ""
+
+#: src/elfcmp.c:583
+#, c-format
+msgid "Invalid value '%s' for --gaps parameter."
+msgstr ""
+
+#: src/elfcmp.c:607 src/findtextrel.c:229 src/ldgeneric.c:1767
+#: src/ldgeneric.c:4257 src/nm.c:363 src/ranlib.c:169 src/size.c:301
+#: src/strings.c:183 src/strip.c:433 src/strip.c:468 src/unstrip.c:1900
+#: src/unstrip.c:1929
+#, c-format
+msgid "cannot open '%s'"
+msgstr ""
+
+#: src/elfcmp.c:611 src/findtextrel.c:236 src/ranlib.c:186
+#, c-format
+msgid "cannot create ELF descriptor for '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:616
+#, c-format
+msgid "cannot create EBL descriptor for '%s'"
+msgstr ""
+
+#: src/elfcmp.c:634
+#, c-format
+msgid "cannot get section header of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:644
+#, c-format
+msgid "cannot get content of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:654 src/elfcmp.c:668
+#, c-format
+msgid "cannot get relocation: %s"
+msgstr ""
+
+#: src/elflint.c:72
+msgid "Be extremely strict, flag level 2 features."
+msgstr ""
+
+#: src/elflint.c:73
+msgid "Do not print anything if successful"
+msgstr ""
+
+#: src/elflint.c:74
+msgid "Binary is a separate debuginfo file"
+msgstr ""
+
+#: src/elflint.c:76
+msgid ""
+"Binary has been created with GNU ld and is therefore known to be broken in "
+"certain ways"
+msgstr ""
+
+#: src/elflint.c:82
+msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
+msgstr ""
+
+#: src/elflint.c:86 src/readelf.c:118
+msgid "FILE..."
+msgstr ""
+
+#: src/elflint.c:159 src/readelf.c:272
+#, c-format
+msgid "cannot open input file"
+msgstr ""
+
+#: src/elflint.c:166
+#, c-format
+msgid "cannot generate Elf descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:185
+#, c-format
+msgid "error while closing Elf descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:189
+msgid "No errors"
+msgstr ""
+
+#: src/elflint.c:223 src/readelf.c:425
+msgid "Missing file name.\n"
+msgstr ""
+
+#: src/elflint.c:302
+#, c-format
+msgid " error while freeing sub-ELF descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:310
+#, c-format
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr ""
+
+#: src/elflint.c:370
+#, c-format
+msgid "e_ident[%d] == %d is no known class\n"
+msgstr ""
+
+#: src/elflint.c:375
+#, c-format
+msgid "e_ident[%d] == %d is no known data encoding\n"
+msgstr ""
+
+#: src/elflint.c:379
+#, c-format
+msgid "unknown ELF header version number e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:385
+#, c-format
+msgid "unsupported OS ABI e_ident[%d] == '%s'\n"
+msgstr ""
+
+#: src/elflint.c:391
+#, c-format
+msgid "unsupport ABI version e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:396
+#, c-format
+msgid "e_ident[%zu] is not zero\n"
+msgstr ""
+
+#: src/elflint.c:401
+#, c-format
+msgid "unknown object file type %d\n"
+msgstr ""
+
+#: src/elflint.c:408
+#, c-format
+msgid "unknown machine type %d\n"
+msgstr ""
+
+#: src/elflint.c:412
+#, c-format
+msgid "unknown object file version\n"
+msgstr ""
+
+#: src/elflint.c:418
+#, c-format
+msgid "invalid program header offset\n"
+msgstr ""
+
+#: src/elflint.c:420
+#, c-format
+msgid "executables and DSOs cannot have zero program header offset\n"
+msgstr ""
+
+#: src/elflint.c:424
+#, c-format
+msgid "invalid number of program header entries\n"
+msgstr ""
+
+#: src/elflint.c:432
+#, c-format
+msgid "invalid section header table offset\n"
+msgstr ""
+
+#: src/elflint.c:435
+#, c-format
+msgid "section header table must be present\n"
+msgstr ""
+
+#: src/elflint.c:449
+#, c-format
+msgid "invalid number of section header table entries\n"
+msgstr ""
+
+#: src/elflint.c:466
+#, c-format
+msgid "invalid section header index\n"
+msgstr ""
+
+#: src/elflint.c:480
+#, c-format
+msgid "invalid number of program header table entries\n"
+msgstr ""
+
+#: src/elflint.c:489
+#, c-format
+msgid "invalid machine flags: %s\n"
+msgstr ""
+
+#: src/elflint.c:496 src/elflint.c:513
+#, c-format
+msgid "invalid ELF header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:499 src/elflint.c:516
+#, c-format
+msgid "invalid program header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:502 src/elflint.c:519
+#, c-format
+msgid "invalid program header position or size\n"
+msgstr ""
+
+#: src/elflint.c:505 src/elflint.c:522
+#, c-format
+msgid "invalid section header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:508 src/elflint.c:525
+#, c-format
+msgid "invalid section header position or size\n"
+msgstr ""
+
+#: src/elflint.c:569
+#, c-format
+msgid ""
+"section [%2d] '%s': section with SHF_GROUP flag set not part of a section "
+"group\n"
+msgstr ""
+
+#: src/elflint.c:573
+#, c-format
+msgid ""
+"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"
+msgstr ""
+
+#: src/elflint.c:589 src/elflint.c:1432 src/elflint.c:1482 src/elflint.c:1591
+#: src/elflint.c:2185 src/elflint.c:2699 src/elflint.c:2860 src/elflint.c:2990
+#: src/elflint.c:3162 src/elflint.c:4062
+#, c-format
+msgid "section [%2d] '%s': cannot get section data\n"
+msgstr ""
+
+#: src/elflint.c:602 src/elflint.c:1598
+#, c-format
+msgid ""
+"section [%2d] '%s': referenced as string table for section [%2d] '%s' but "
+"type is not SHT_STRTAB\n"
+msgstr ""
+
+#: src/elflint.c:625
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol table cannot have more than one extended index "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:636
+#, c-format
+msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n"
+msgstr ""
+
+#: src/elflint.c:645
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:650 src/elflint.c:653 src/elflint.c:656 src/elflint.c:659
+#: src/elflint.c:662 src/elflint.c:665
+#, c-format
+msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:668
+#, c-format
+msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:678
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:687
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid name value\n"
+msgstr ""
+
+#: src/elflint.c:700
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: too large section index but no extended "
+"section index section\n"
+msgstr ""
+
+#: src/elflint.c:706
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in "
+"st_shndx (%<PRIu32>)\n"
+msgstr ""
+
+#: src/elflint.c:718
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid section index\n"
+msgstr ""
+
+#: src/elflint.c:726
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown type\n"
+msgstr ""
+
+#: src/elflint.c:732
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown symbol binding\n"
+msgstr ""
+
+#: src/elflint.c:737
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unique symbol not of object type\n"
+msgstr ""
+
+#: src/elflint.c:745
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"
+msgstr ""
+
+#: src/elflint.c:749
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"
+msgstr ""
+
+#: src/elflint.c:753
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"
+msgstr ""
+
+#: src/elflint.c:785
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: st_value out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:791 src/elflint.c:816 src/elflint.c:859
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu does not fit completely in referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:800
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have "
+"SHF_TLS flag set\n"
+msgstr ""
+
+#: src/elflint.c:810 src/elflint.c:852
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:837
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"
+msgstr ""
+
+#: src/elflint.c:845
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:872
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:879
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: non-local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:886
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: non-local section symbol\n"
+msgstr ""
+
+#: src/elflint.c:936
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section [%"
+"2d]\n"
+msgstr ""
+
+#: src/elflint.c:943
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:959
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#<PRIx64> does not "
+"match %s section address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:966
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %<PRIu64> does not "
+"match %s section size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:974
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:990
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC_ symbol value %#<PRIx64> does not match dynamic "
+"segment address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:997
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC symbol size %<PRIu64> does not match dynamic "
+"segment size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:1010
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-"
+"default visibility\n"
+msgstr ""
+
+#: src/elflint.c:1014
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"
+msgstr ""
+
+#: src/elflint.c:1059
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"
+msgstr ""
+
+#: src/elflint.c:1068 src/elflint.c:1120
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"
+msgstr ""
+
+#: src/elflint.c:1093 src/elflint.c:1145
+#, c-format
+msgid ""
+"section [%2d] '%s': relative relocations after index %d as specified by "
+"DT_RELCOUNT\n"
+msgstr ""
+
+#: src/elflint.c:1099 src/elflint.c:1151
+#, c-format
+msgid ""
+"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT "
+"specified %d relative relocations\n"
+msgstr ""
+
+#: src/elflint.c:1111
+#, c-format
+msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n"
+msgstr ""
+
+#: src/elflint.c:1193
+#, c-format
+msgid "section [%2d] '%s': invalid destination section index\n"
+msgstr ""
+
+#: src/elflint.c:1206
+#, c-format
+msgid "section [%2d] '%s': invalid destination section type\n"
+msgstr ""
+
+#: src/elflint.c:1214
+#, c-format
+msgid "section [%2d] '%s': sh_info should be zero\n"
+msgstr ""
+
+#: src/elflint.c:1221
+#, c-format
+msgid "section [%2d] '%s': no relocations for merge-able sections possible\n"
+msgstr ""
+
+#: src/elflint.c:1228
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n"
+msgstr ""
+
+#: src/elflint.c:1288
+#, c-format
+msgid "text relocation flag set but there is no read-only segment\n"
+msgstr ""
+
+#: src/elflint.c:1315
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid type\n"
+msgstr ""
+
+#: src/elflint.c:1323
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: relocation type invalid for the file "
+"type\n"
+msgstr ""
+
+#: src/elflint.c:1331
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n"
+msgstr ""
+
+#: src/elflint.c:1349
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can "
+"be used with %s\n"
+msgstr ""
+
+#: src/elflint.c:1366
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:1381
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: copy relocation against symbol of type %"
+"s\n"
+msgstr ""
+
+#: src/elflint.c:1402
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: read-only section modified but text "
+"relocation flag not set\n"
+msgstr ""
+
+#: src/elflint.c:1417
+#, c-format
+msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n"
+msgstr ""
+
+#: src/elflint.c:1456 src/elflint.c:1506
+#, c-format
+msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1586
+#, c-format
+msgid "more than one dynamic section present\n"
+msgstr ""
+
+#: src/elflint.c:1604
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"
+msgstr ""
+
+#: src/elflint.c:1609 src/elflint.c:1901
+#, c-format
+msgid "section [%2d] '%s': sh_info not zero\n"
+msgstr ""
+
+#: src/elflint.c:1619
+#, c-format
+msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1627
+#, c-format
+msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"
+msgstr ""
+
+#: src/elflint.c:1634
+#, c-format
+msgid "section [%2d] '%s': entry %zu: unknown tag\n"
+msgstr ""
+
+#: src/elflint.c:1645
+#, c-format
+msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n"
+msgstr ""
+
+#: src/elflint.c:1655
+#, c-format
+msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n"
+msgstr ""
+
+#: src/elflint.c:1673
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"
+msgstr ""
+
+#: src/elflint.c:1695
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: pointer does not match address of section [%"
+"2d] '%s' referenced by sh_link\n"
+msgstr ""
+
+#: src/elflint.c:1738
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:1753
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must be valid offset in section [%"
+"2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:1773 src/elflint.c:1801
+#, c-format
+msgid "section [%2d] '%s': contains %s entry but not %s\n"
+msgstr ""
+
+#: src/elflint.c:1785
+#, c-format
+msgid "section [%2d] '%s': mandatory tag %s not present\n"
+msgstr ""
+
+#: src/elflint.c:1794
+#, c-format
+msgid "section [%2d] '%s': no hash section present\n"
+msgstr ""
+
+#: src/elflint.c:1809 src/elflint.c:1816
+#, c-format
+msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n"
+msgstr ""
+
+#: src/elflint.c:1826 src/elflint.c:1830
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"
+msgstr ""
+
+#: src/elflint.c:1836
+#, c-format
+msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n"
+msgstr ""
+
+#: src/elflint.c:1847 src/elflint.c:1851 src/elflint.c:1855 src/elflint.c:1859
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in prelinked executable\n"
+msgstr ""
+
+#: src/elflint.c:1871
+#, c-format
+msgid ""
+"section [%2d] '%s': only relocatable files can have extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1881
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index section not for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1886
+#, c-format
+msgid "cannot get data for symbol section\n"
+msgstr ""
+
+#: src/elflint.c:1889
+#, c-format
+msgid "section [%2d] '%s': entry size does not match Elf32_Word\n"
+msgstr ""
+
+#: src/elflint.c:1896
+#, c-format
+msgid "section [%2d] '%s': extended index table too small for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1911
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to "
+"same symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1922
+#, c-format
+msgid "symbol 0 should have zero extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1934
+#, c-format
+msgid "cannot get data for symbol %zu\n"
+msgstr ""
+
+#: src/elflint.c:1939
+#, c-format
+msgid "extended section index is %<PRIu32> but symbol index is not XINDEX\n"
+msgstr ""
+
+#: src/elflint.c:1955 src/elflint.c:1996
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"
+msgstr ""
+
+#: src/elflint.c:1967 src/elflint.c:2008
+#, c-format
+msgid "section [%2d] '%s': chain array too large\n"
+msgstr ""
+
+#: src/elflint.c:1976 src/elflint.c:2017
+#, c-format
+msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:1982
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2023
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %<PRIu64> out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2038
+#, c-format
+msgid "section [%2d] '%s': bitmask size not power of 2: %u\n"
+msgstr ""
+
+#: src/elflint.c:2049
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected at "
+"least%ld)\n"
+msgstr ""
+
+#: src/elflint.c:2057
+#, c-format
+msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n"
+msgstr ""
+
+#: src/elflint.c:2089
+#, c-format
+msgid ""
+"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"
+msgstr ""
+
+#: src/elflint.c:2110
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is "
+"undefined\n"
+msgstr ""
+
+#: src/elflint.c:2121
+#, c-format
+msgid ""
+"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+
+#: src/elflint.c:2152
+#, c-format
+msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2157
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2163
+#, c-format
+msgid "section [%2d] '%s': bitmask does not match names in the hash table\n"
+msgstr ""
+
+#: src/elflint.c:2176
+#, c-format
+msgid "section [%2d] '%s': relocatable files cannot have hash tables\n"
+msgstr ""
+
+#: src/elflint.c:2194
+#, c-format
+msgid "section [%2d] '%s': hash table not for dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2202
+#, c-format
+msgid "section [%2d] '%s': hash table entry size incorrect\n"
+msgstr ""
+
+#: src/elflint.c:2207
+#, c-format
+msgid "section [%2d] '%s': not marked to be allocated\n"
+msgstr ""
+
+#: src/elflint.c:2212
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table has not even room for initial administrative "
+"entries\n"
+msgstr ""
+
+#: src/elflint.c:2260
+#, c-format
+msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"
+msgstr ""
+
+#: src/elflint.c:2338 src/elflint.c:2342
+#, c-format
+msgid "section [%2zu] '%s': reference to symbol index 0\n"
+msgstr ""
+
+#: src/elflint.c:2349
+#, c-format
+msgid ""
+"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2361
+#, c-format
+msgid ""
+"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2377
+#, c-format
+msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n"
+msgstr ""
+
+#: src/elflint.c:2397
+#, c-format
+msgid ""
+"section [%2d] '%s': section groups only allowed in relocatable object files\n"
+msgstr ""
+
+#: src/elflint.c:2408
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol table: %s\n"
+msgstr ""
+
+#: src/elflint.c:2413
+#, c-format
+msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2419
+#, c-format
+msgid "section [%2d] '%s': invalid symbol index in sh_info\n"
+msgstr ""
+
+#: src/elflint.c:2424
+#, c-format
+msgid "section [%2d] '%s': sh_flags not zero\n"
+msgstr ""
+
+#: src/elflint.c:2431
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol for signature\n"
+msgstr ""
+
+#: src/elflint.c:2436
+#, c-format
+msgid "section [%2d] '%s': signature symbol cannot be empty string\n"
+msgstr ""
+
+#: src/elflint.c:2442
+#, c-format
+msgid "section [%2d] '%s': sh_flags not set correctly\n"
+msgstr ""
+
+#: src/elflint.c:2448
+#, c-format
+msgid "section [%2d] '%s': cannot get data: %s\n"
+msgstr ""
+
+#: src/elflint.c:2457
+#, c-format
+msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"
+msgstr ""
+
+#: src/elflint.c:2462
+#, c-format
+msgid "section [%2d] '%s': section group without flags word\n"
+msgstr ""
+
+#: src/elflint.c:2468
+#, c-format
+msgid "section [%2d] '%s': section group without member\n"
+msgstr ""
+
+#: src/elflint.c:2472
+#, c-format
+msgid "section [%2d] '%s': section group with only one member\n"
+msgstr ""
+
+#: src/elflint.c:2483
+#, c-format
+msgid "section [%2d] '%s': unknown section group flags\n"
+msgstr ""
+
+#: src/elflint.c:2495
+#, c-format
+msgid "section [%2d] '%s': section index %Zu out of range\n"
+msgstr ""
+
+#: src/elflint.c:2504
+#, c-format
+msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:2511
+#, c-format
+msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2517
+#, c-format
+msgid ""
+"section [%2d] '%s': element %Zu references section [%2d] '%s' without "
+"SHF_GROUP flag set\n"
+msgstr ""
+
+#: src/elflint.c:2524
+#, c-format
+msgid "section [%2d] '%s' is contained in more than one section group\n"
+msgstr ""
+
+#: src/elflint.c:2713
+#, c-format
+msgid ""
+"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no "
+"dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2724
+#, c-format
+msgid ""
+"section [%2d] '%s' has different number of entries than symbol table [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:2740
+#, c-format
+msgid "section [%2d] '%s': symbol %d: cannot read version data\n"
+msgstr ""
+
+#: src/elflint.c:2756
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n"
+msgstr ""
+
+#: src/elflint.c:2764
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with version\n"
+msgstr ""
+
+#: src/elflint.c:2778
+#, c-format
+msgid "section [%2d] '%s': symbol %d: invalid version index %d\n"
+msgstr ""
+
+#: src/elflint.c:2783
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for defined version\n"
+msgstr ""
+
+#: src/elflint.c:2793
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for requested version\n"
+msgstr ""
+
+#: src/elflint.c:2845
+#, c-format
+msgid "more than one version reference section present\n"
+msgstr ""
+
+#: src/elflint.c:2853 src/elflint.c:2982
+#, c-format
+msgid "section [%2d] '%s': sh_link does not link to string table\n"
+msgstr ""
+
+#: src/elflint.c:2876 src/elflint.c:3034
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong version %d\n"
+msgstr ""
+
+#: src/elflint.c:2882 src/elflint.c:3040
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:2890
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid file reference\n"
+msgstr ""
+
+#: src/elflint.c:2898
+#, c-format
+msgid "section [%2d] '%s': entry %d references unknown dependency\n"
+msgstr ""
+
+#: src/elflint.c:2910
+#, c-format
+msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:2917
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name "
+"reference\n"
+msgstr ""
+
+#: src/elflint.c:2924
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %"
+"#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:2934
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version "
+"name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2945
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"
+msgstr ""
+
+#: src/elflint.c:2961 src/elflint.c:3119
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n"
+msgstr ""
+
+#: src/elflint.c:2974
+#, c-format
+msgid "more than one version definition section present\n"
+msgstr ""
+
+#: src/elflint.c:3019
+#, c-format
+msgid "section [%2d] '%s': more than one BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3023
+#, c-format
+msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"
+msgstr ""
+
+#: src/elflint.c:3029
+#, c-format
+msgid "section [%2d] '%s': entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:3053
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid name reference\n"
+msgstr ""
+
+#: src/elflint.c:3060
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:3069
+#, c-format
+msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3088
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3103
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3125
+#, c-format
+msgid "section [%2d] '%s': no BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3141
+#, c-format
+msgid "section [%2d] '%s': unknown parent version '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3154
+#, c-format
+msgid "section [%2d] '%s': empty object attributes section\n"
+msgstr ""
+
+#: src/elflint.c:3175
+#, c-format
+msgid "section [%2d] '%s': unrecognized attribute format\n"
+msgstr ""
+
+#: src/elflint.c:3191
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3200
+#, c-format
+msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3212
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n"
+msgstr ""
+
+#: src/elflint.c:3229
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"
+msgstr ""
+
+#: src/elflint.c:3238
+#, c-format
+msgid "section [%2d] '%s': offset %zu: truncated attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3247
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3260
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3271
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3289
+#, c-format
+msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"
+msgstr ""
+
+#: src/elflint.c:3300
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n"
+msgstr ""
+
+#: src/elflint.c:3313
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3317
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: unrecognized %s attribute value %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3327
+#, c-format
+msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n"
+msgstr ""
+
+#: src/elflint.c:3333
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3422
+#, c-format
+msgid "cannot get section header of zeroth section\n"
+msgstr ""
+
+#: src/elflint.c:3426
+#, c-format
+msgid "zeroth section has nonzero name\n"
+msgstr ""
+
+#: src/elflint.c:3428
+#, c-format
+msgid "zeroth section has nonzero type\n"
+msgstr ""
+
+#: src/elflint.c:3430
+#, c-format
+msgid "zeroth section has nonzero flags\n"
+msgstr ""
+
+#: src/elflint.c:3432
+#, c-format
+msgid "zeroth section has nonzero address\n"
+msgstr ""
+
+#: src/elflint.c:3434
+#, c-format
+msgid "zeroth section has nonzero offset\n"
+msgstr ""
+
+#: src/elflint.c:3436
+#, c-format
+msgid "zeroth section has nonzero align value\n"
+msgstr ""
+
+#: src/elflint.c:3438
+#, c-format
+msgid "zeroth section has nonzero entry size value\n"
+msgstr ""
+
+#: src/elflint.c:3441
+#, c-format
+msgid ""
+"zeroth section has nonzero size value while ELF header has nonzero shnum "
+"value\n"
+msgstr ""
+
+#: src/elflint.c:3445
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in shstrndx\n"
+msgstr ""
+
+#: src/elflint.c:3449
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in phnum\n"
+msgstr ""
+
+#: src/elflint.c:3466
+#, c-format
+msgid "cannot get section header for section [%2zu] '%s': %s\n"
+msgstr ""
+
+#: src/elflint.c:3475
+#, c-format
+msgid "section [%2zu]: invalid name\n"
+msgstr ""
+
+#: src/elflint.c:3502
+#, c-format
+msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3518
+#, c-format
+msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3535
+#, c-format
+msgid ""
+"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3553
+#, c-format
+msgid "section [%2zu] '%s' present in object file\n"
+msgstr ""
+
+#: src/elflint.c:3559 src/elflint.c:3591
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"
+msgstr ""
+
+#: src/elflint.c:3564 src/elflint.c:3596
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable "
+"segments\n"
+msgstr ""
+
+#: src/elflint.c:3572
+#, c-format
+msgid ""
+"section [%2zu] '%s' is extension section index table in non-object file\n"
+msgstr ""
+
+#: src/elflint.c:3615
+#, c-format
+msgid "section [%2zu] '%s': size not multiple of entry size\n"
+msgstr ""
+
+#: src/elflint.c:3620
+#, c-format
+msgid "cannot get section header\n"
+msgstr ""
+
+#: src/elflint.c:3630
+#, c-format
+msgid "section [%2zu] '%s' has unsupported type %d\n"
+msgstr ""
+
+#: src/elflint.c:3644
+#, c-format
+msgid ""
+"section [%2zu] '%s' contains invalid processor-specific flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3651
+#, c-format
+msgid "section [%2zu] '%s' contains unknown flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3659
+#, c-format
+msgid "section [%2zu] '%s': thread-local data sections address not zero\n"
+msgstr ""
+
+#: src/elflint.c:3667
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in link value\n"
+msgstr ""
+
+#: src/elflint.c:3672
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in info value\n"
+msgstr ""
+
+#: src/elflint.c:3679
+#, c-format
+msgid "section [%2zu] '%s': strings flag set without merge flag\n"
+msgstr ""
+
+#: src/elflint.c:3684
+#, c-format
+msgid "section [%2zu] '%s': merge flag set but entry size is zero\n"
+msgstr ""
+
+#: src/elflint.c:3702
+#, c-format
+msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n"
+msgstr ""
+
+#: src/elflint.c:3711
+#, c-format
+msgid "section [%2zu] '%s' is both executable and writable\n"
+msgstr ""
+
+#: src/elflint.c:3738
+#, c-format
+msgid ""
+"section [%2zu] '%s' not fully contained in segment of program header entry %"
+"d\n"
+msgstr ""
+
+#: src/elflint.c:3746
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:3755
+#, c-format
+msgid ""
+"section [%2zu] '%s' has not type NOBITS but is not read from the file in "
+"segment of program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:3766
+#, c-format
+msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:3776
+#, c-format
+msgid "section [%2zu] '%s' is writable in unwritable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:3786
+#, c-format
+msgid ""
+"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:3792
+#, c-format
+msgid ""
+"section [%2zu] '%s': ELF header says this is the section header string table "
+"but type is not SHT_TYPE\n"
+msgstr ""
+
+#: src/elflint.c:3800
+#, c-format
+msgid ""
+"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"
+msgstr ""
+
+#: src/elflint.c:3851
+#, c-format
+msgid "more than one version symbol table present\n"
+msgstr ""
+
+#: src/elflint.c:3874
+#, c-format
+msgid "INTERP program header entry but no .interp section\n"
+msgstr ""
+
+#: src/elflint.c:3885
+#, c-format
+msgid ""
+"loadable segment [%u] is executable but contains no executable sections\n"
+msgstr ""
+
+#: src/elflint.c:3891
+#, c-format
+msgid "loadable segment [%u] is writable but contains no writable sections\n"
+msgstr ""
+
+#: src/elflint.c:3902
+#, c-format
+msgid ""
+"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section "
+"exist\n"
+msgstr ""
+
+#: src/elflint.c:3915
+#, c-format
+msgid "duplicate version index %d\n"
+msgstr ""
+
+#: src/elflint.c:3929
+#, c-format
+msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"
+msgstr ""
+
+#: src/elflint.c:3978
+#, c-format
+msgid "phdr[%d]: unknown core file note type %<PRIu32> at offset %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3982
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown core file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4005
+#, c-format
+msgid "phdr[%d]: unknown object file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4009
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown object file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4026
+#, c-format
+msgid "phdr[%d]: no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4045
+#, c-format
+msgid "phdr[%d]: cannot get content of note section: %s\n"
+msgstr ""
+
+#: src/elflint.c:4048
+#, c-format
+msgid "phdr[%d]: extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4069
+#, c-format
+msgid "section [%2d] '%s': no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4076
+#, c-format
+msgid "section [%2d] '%s': cannot get content of note section\n"
+msgstr ""
+
+#: src/elflint.c:4079
+#, c-format
+msgid "section [%2d] '%s': extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4097
+#, c-format
+msgid ""
+"only executables, shared objects, and core files can have program headers\n"
+msgstr ""
+
+#: src/elflint.c:4112
+#, c-format
+msgid "cannot get program header entry %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:4121
+#, c-format
+msgid "program header entry %d: unknown program header entry type %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:4132
+#, c-format
+msgid "more than one INTERP entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4140
+#, c-format
+msgid "more than one TLS entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4147
+#, c-format
+msgid "static executable cannot have dynamic sections\n"
+msgstr ""
+
+#: src/elflint.c:4161
+#, c-format
+msgid "dynamic section reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4164
+#, c-format
+msgid "dynamic section size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4174
+#, c-format
+msgid "more than one GNU_RELRO entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4195
+#, c-format
+msgid "loadable segment GNU_RELRO applies to is not writable\n"
+msgstr ""
+
+#: src/elflint.c:4198
+#, c-format
+msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"
+msgstr ""
+
+#: src/elflint.c:4206 src/elflint.c:4229
+#, c-format
+msgid "%s segment not contained in a loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:4235
+#, c-format
+msgid "program header offset in ELF header and PHDR entry do not match"
+msgstr ""
+
+#: src/elflint.c:4259
+#, c-format
+msgid "call frame search table reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4262
+#, c-format
+msgid "call frame search table size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4275
+#, c-format
+msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"
+msgstr ""
+
+#: src/elflint.c:4283
+#, c-format
+msgid "call frame search table must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4286
+#, c-format
+msgid "section [%2zu] '%s' must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4290
+#, c-format
+msgid "call frame search table must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4293
+#, c-format
+msgid "section [%2zu] '%s' must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4298
+#, c-format
+msgid "call frame search table must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4301
+#, c-format
+msgid "section [%2zu] '%s' must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4312
+#, c-format
+msgid "program header entry %d: file size greater than memory size\n"
+msgstr ""
+
+#: src/elflint.c:4319
+#, c-format
+msgid "program header entry %d: alignment not a power of 2\n"
+msgstr ""
+
+#: src/elflint.c:4322
+#, c-format
+msgid ""
+"program header entry %d: file offset and virtual address not module of "
+"alignment\n"
+msgstr ""
+
+#: src/elflint.c:4335
+#, c-format
+msgid ""
+"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME "
+"program header entry"
+msgstr ""
+
+#: src/elflint.c:4369
+#, c-format
+msgid "cannot read ELF header: %s\n"
+msgstr ""
+
+#: src/elflint.c:4395
+#, c-format
+msgid "text relocation flag set but not needed\n"
+msgstr ""
+
+#: src/findtextrel.c:70
+msgid "Input Selection:"
+msgstr ""
+
+#: src/findtextrel.c:71
+msgid "Prepend PATH to all file names"
+msgstr ""
+
+#: src/findtextrel.c:73
+msgid "Use PATH as root of debuginfo hierarchy"
+msgstr ""
+
+#: src/findtextrel.c:80
+msgid "Locate source of text relocations in FILEs (a.out by default)."
+msgstr ""
+
+#: src/findtextrel.c:84 src/nm.c:111 src/objdump.c:80 src/size.c:92
+#: src/strings.c:92 src/strip.c:97
+msgid "[FILE...]"
+msgstr ""
+
+#: src/findtextrel.c:246
+#, c-format
+msgid "cannot get ELF header '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:257
+#, c-format
+msgid "'%s' is not a DSO or PIE"
+msgstr ""
+
+#: src/findtextrel.c:274
+#, c-format
+msgid "getting get section header of section %zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:292
+#, c-format
+msgid "cannot read dynamic section: %s"
+msgstr ""
+
+#: src/findtextrel.c:307
+#, c-format
+msgid "no text relocations reported in '%s'"
+msgstr ""
+
+#: src/findtextrel.c:319
+#, c-format
+msgid "while reading ELF file"
+msgstr ""
+
+#: src/findtextrel.c:328 src/findtextrel.c:345
+#, c-format
+msgid "cannot get program header index at offset %d: %s"
+msgstr ""
+
+#: src/findtextrel.c:397
+#, c-format
+msgid "cannot get section header of section %Zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:409
+#, c-format
+msgid "cannot get symbol table section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:429 src/findtextrel.c:452
+#, c-format
+msgid "cannot get relocation at index %d in section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:517
+#, c-format
+msgid "%s not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:570
+#, c-format
+msgid ""
+"the file containing the function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:577 src/findtextrel.c:597
+#, c-format
+msgid ""
+"the file containing the function '%s' might not be compiled with -fpic/-"
+"fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:585
+#, c-format
+msgid ""
+"either the file containing the function '%s' or the file containing the "
+"function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:605
+#, c-format
+msgid ""
+"a relocation modifies memory at offset %llu in a write-protected segment\n"
+msgstr ""
+
+#: src/i386_ld.c:210
+#, c-format
+msgid "cannot allocate PLT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:232
+#, c-format
+msgid "cannot allocate PLTREL section: %s"
+msgstr ""
+
+#: src/i386_ld.c:253
+#, c-format
+msgid "cannot allocate GOT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:274
+#, c-format
+msgid "cannot allocate GOTPLT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:661
+#, c-format
+msgid "initial-executable TLS relocation cannot be used "
+msgstr ""
+
+#: src/ld.c:87
+msgid "Input File Control:"
+msgstr ""
+
+#: src/ld.c:89
+msgid "Include whole archives in the output from now on."
+msgstr ""
+
+#: src/ld.c:91
+msgid "Stop including the whole archives in the output."
+msgstr ""
+
+#: src/ld.c:92 src/ld.c:106 src/ld.c:184
+msgid "FILE"
+msgstr ""
+
+#: src/ld.c:93
+msgid "Start a group."
+msgstr ""
+
+#: src/ld.c:94
+msgid "End a group."
+msgstr ""
+
+#: src/ld.c:95
+msgid "PATH"
+msgstr ""
+
+#: src/ld.c:96
+msgid "Add PATH to list of directories files are searched in."
+msgstr ""
+
+#: src/ld.c:98
+msgid "Only set DT_NEEDED for following dynamic libs if actually used"
+msgstr ""
+
+#: src/ld.c:100
+msgid "Always set DT_NEEDED for following dynamic libs"
+msgstr ""
+
+#: src/ld.c:102
+msgid "Ignore LD_LIBRARY_PATH environment variable."
+msgstr ""
+
+#: src/ld.c:105
+msgid "Output File Control:"
+msgstr ""
+
+#: src/ld.c:106
+msgid "Place output in FILE."
+msgstr ""
+
+#: src/ld.c:109
+msgid "Object is marked to not use default search path at runtime."
+msgstr ""
+
+#: src/ld.c:111
+msgid "Same as --whole-archive."
+msgstr ""
+
+#: src/ld.c:112
+msgid ""
+"Default rules of extracting from archive; weak references are not enough."
+msgstr ""
+
+#: src/ld.c:116
+msgid "Weak references cause extraction from archive."
+msgstr ""
+
+#: src/ld.c:118
+msgid "Allow multiple definitions; first is used."
+msgstr ""
+
+#: src/ld.c:120
+msgid "Disallow/allow undefined symbols in DSOs."
+msgstr ""
+
+#: src/ld.c:123
+msgid "Object requires immediate handling of $ORIGIN."
+msgstr ""
+
+#: src/ld.c:125
+msgid "Relocation will not be processed lazily."
+msgstr ""
+
+#: src/ld.c:127
+msgid "Object cannot be unloaded at runtime."
+msgstr ""
+
+#: src/ld.c:129
+msgid "Mark object to be initialized first."
+msgstr ""
+
+#: src/ld.c:131
+msgid "Enable/disable lazy-loading flag for following dependencies."
+msgstr ""
+
+#: src/ld.c:133
+msgid "Mark object as not loadable with 'dlopen'."
+msgstr ""
+
+#: src/ld.c:135
+msgid "Ignore/record dependencies on unused DSOs."
+msgstr ""
+
+#: src/ld.c:137
+msgid "Generated DSO will be a system library."
+msgstr ""
+
+#: src/ld.c:138
+msgid "ADDRESS"
+msgstr ""
+
+#: src/ld.c:138
+msgid "Set entry point address."
+msgstr ""
+
+#: src/ld.c:141
+msgid "Do not link against shared libraries."
+msgstr ""
+
+#: src/ld.c:144
+msgid "Prefer linking against shared libraries."
+msgstr ""
+
+#: src/ld.c:145
+msgid "Export all dynamic symbols."
+msgstr ""
+
+#: src/ld.c:146
+msgid "Strip all symbols."
+msgstr ""
+
+#: src/ld.c:147
+msgid "Strip debugging symbols."
+msgstr ""
+
+#: src/ld.c:149
+msgid "Assume pagesize for the target system to be SIZE."
+msgstr ""
+
+#: src/ld.c:151
+msgid "Set runtime DSO search path."
+msgstr ""
+
+#: src/ld.c:154
+msgid "Set link time DSO search path."
+msgstr ""
+
+#: src/ld.c:155
+msgid "Generate dynamic shared object."
+msgstr ""
+
+#: src/ld.c:156
+msgid "Generate relocatable object."
+msgstr ""
+
+#: src/ld.c:159
+msgid "Causes symbol not assigned to a version be reduced to local."
+msgstr ""
+
+#: src/ld.c:160
+msgid "Remove unused sections."
+msgstr ""
+
+#: src/ld.c:163
+msgid "Don't remove unused sections."
+msgstr ""
+
+#: src/ld.c:164
+msgid "Set soname of shared object."
+msgstr ""
+
+#: src/ld.c:165
+msgid "Set the dynamic linker name."
+msgstr ""
+
+#: src/ld.c:168
+msgid "Add/suppress addition indentifying link-editor to .comment section."
+msgstr ""
+
+#: src/ld.c:171
+msgid "Create .eh_frame_hdr section"
+msgstr ""
+
+#: src/ld.c:173
+msgid "Set hash style to sysv, gnu or both."
+msgstr ""
+
+#: src/ld.c:175
+msgid "Generate build ID note (md5, sha1 (default), uuid)."
+msgstr ""
+
+#: src/ld.c:177
+msgid "Linker Operation Control:"
+msgstr ""
+
+#: src/ld.c:178
+msgid "Verbose messages."
+msgstr ""
+
+#: src/ld.c:179
+msgid "Trace file opens."
+msgstr ""
+
+#: src/ld.c:181
+msgid "Trade speed for less memory usage"
+msgstr ""
+
+#: src/ld.c:182
+msgid "LEVEL"
+msgstr ""
+
+#: src/ld.c:183
+msgid "Set optimization level to LEVEL."
+msgstr ""
+
+#: src/ld.c:184
+msgid "Use linker script in FILE."
+msgstr ""
+
+#: src/ld.c:187
+msgid "Select to get parser debug information"
+msgstr ""
+
+#: src/ld.c:190
+msgid "Read version information from FILE."
+msgstr ""
+
+#: src/ld.c:191
+msgid "Set emulation to NAME."
+msgstr ""
+
+#: src/ld.c:197
+msgid "Combine object and archive files."
+msgstr ""
+
+#: src/ld.c:200
+msgid "[FILE]..."
+msgstr ""
+
+#: src/ld.c:333
+#, c-format
+msgid "At least one input file needed"
+msgstr ""
+
+#: src/ld.c:349
+#, c-format
+msgid "error while preparing linking"
+msgstr ""
+
+#: src/ld.c:356
+#, c-format
+msgid "cannot open linker script '%s'"
+msgstr ""
+
+#: src/ld.c:397
+#, c-format
+msgid "-( without matching -)"
+msgstr ""
+
+#: src/ld.c:572 src/ld.c:610
+#, c-format
+msgid "only one option of -G and -r is allowed"
+msgstr ""
+
+#: src/ld.c:594
+#, c-format
+msgid "more than one '-m' parameter"
+msgstr ""
+
+#: src/ld.c:604 src/ld.c:1013
+#, c-format
+msgid "unknown option `-%c %s'"
+msgstr ""
+
+#: src/ld.c:646
+#, c-format
+msgid "invalid page size value '%s': ignored"
+msgstr ""
+
+#: src/ld.c:687
+#, c-format
+msgid "invalid hash style '%s'"
+msgstr ""
+
+#: src/ld.c:697
+#, c-format
+msgid "invalid build-ID style '%s'"
+msgstr ""
+
+#: src/ld.c:785
+#, c-format
+msgid "More than one output file name given."
+msgstr ""
+
+#: src/ld.c:802
+#, c-format
+msgid "Invalid optimization level `%s'"
+msgstr ""
+
+#: src/ld.c:850
+#, c-format
+msgid "nested -( -) groups are not allowed"
+msgstr ""
+
+#: src/ld.c:869
+#, c-format
+msgid "-) without matching -("
+msgstr ""
+
+#: src/ld.c:1046
+#, c-format
+msgid "unknown option '-%c %s'"
+msgstr ""
+
+#: src/ld.c:1150
+#, c-format
+msgid "could not find input file to determine output file format"
+msgstr ""
+
+#: src/ld.c:1152
+#, c-format
+msgid "try again with an appropriate '-m' parameter"
+msgstr ""
+
+#: src/ld.c:1446
+#, c-format
+msgid "cannot read version script '%s'"
+msgstr ""
+
+#: src/ld.c:1512 src/ld.c:1551
+#, c-format
+msgid "duplicate definition of '%s' in linker script"
+msgstr ""
+
+#: src/ldgeneric.c:209 src/ldgeneric.c:5151
+#, c-format
+msgid "cannot create string table"
+msgstr ""
+
+#: src/ldgeneric.c:255
+#, c-format
+msgid "cannot load ld backend library '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:265
+#, c-format
+msgid "cannot find init function in ld backend library '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:310
+#, c-format
+msgid "%s listed more than once as input"
+msgstr ""
+
+#: src/ldgeneric.c:424
+#, c-format
+msgid "%s (for -l%s)\n"
+msgstr ""
+
+#: src/ldgeneric.c:425
+#, c-format
+msgid "%s (for DT_NEEDED %s)\n"
+msgstr ""
+
+#: src/ldgeneric.c:573
+#, c-format
+msgid "Warning: type of `%s' changed from %s in %s to %s in %s"
+msgstr ""
+
+#: src/ldgeneric.c:586
+#, c-format
+msgid "Warning: size of `%s' changed from %<PRIu64> in %s to %<PRIu64> in %s"
+msgstr ""
+
+#: src/ldgeneric.c:661 src/ldgeneric.c:1122 src/readelf.c:629 src/strip.c:543
+#, c-format
+msgid "cannot determine number of sections: %s"
+msgstr ""
+
+#: src/ldgeneric.c:677
+#, c-format
+msgid "(%s+%#<PRIx64>): multiple definition of %s `%s'\n"
+msgstr ""
+
+#: src/ldgeneric.c:700
+#, c-format
+msgid "(%s+%#<PRIx64>): first defined here\n"
+msgstr ""
+
+#: src/ldgeneric.c:819
+#, c-format
+msgid "%s: cannot get section group data: %s"
+msgstr ""
+
+#: src/ldgeneric.c:840
+#, c-format
+msgid "%s: section '%s' with group flag set does not belong to any group"
+msgstr ""
+
+#: src/ldgeneric.c:885
+#, c-format
+msgid "%s: section [%2d] '%s' is not in the correct section group"
+msgstr ""
+
+#: src/ldgeneric.c:1156 src/ldgeneric.c:1413 src/ldgeneric.c:1422
+#: src/ldgeneric.c:1481 src/ldgeneric.c:1490 src/ldgeneric.c:1753
+#: src/ldgeneric.c:2005
+#, c-format
+msgid "%s: invalid ELF file (%s:%d)\n"
+msgstr ""
+
+#: src/ldgeneric.c:1250
+#, c-format
+msgid "%s: only files of type ET_REL might contain section groups"
+msgstr ""
+
+#: src/ldgeneric.c:1302
+#, c-format
+msgid "%s: cannot determine signature of section group [%2zd] '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:1314
+#, c-format
+msgid "%s: cannot get content of section group [%2zd] '%s': %s'"
+msgstr ""
+
+#: src/ldgeneric.c:1328
+#, c-format
+msgid ""
+"%s: group member %zu of section group [%2zd] '%s' has too high index: %"
+"<PRIu32>"
+msgstr ""
+
+#: src/ldgeneric.c:1350
+#, c-format
+msgid "%s: section '%s' has unknown type: %d"
+msgstr ""
+
+#: src/ldgeneric.c:1729
+#, c-format
+msgid "cannot get descriptor for ELF file (%s:%d): %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:1899
+#, c-format
+msgid "cannot read archive `%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:2020
+#, c-format
+msgid "file of type %s cannot be linked in\n"
+msgstr ""
+
+#: src/ldgeneric.c:2032
+#, c-format
+msgid "%s: input file incompatible with ELF machine type %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:2044
+#, c-format
+msgid "%s: cannot get section header string table index: %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:2073
+#, c-format
+msgid "cannot use DSO '%s' when generating relocatable object file"
+msgstr ""
+
+#: src/ldgeneric.c:2158
+#, c-format
+msgid "input file '%s' ignored"
+msgstr ""
+
+#: src/ldgeneric.c:2372
+#, c-format
+msgid "undefined symbol `%s' in %s"
+msgstr ""
+
+#: src/ldgeneric.c:2702
+#, c-format
+msgid "cannot create ELF descriptor for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:2709
+#, c-format
+msgid "could not create ELF header for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:3224 src/ldgeneric.c:3294 src/ldgeneric.c:3330
+#: src/ldgeneric.c:4457 src/ldgeneric.c:4506 src/ldgeneric.c:4538
+#: src/ldgeneric.c:4773 src/ldgeneric.c:4828 src/ldgeneric.c:5075
+#: src/ldgeneric.c:5131 src/ldgeneric.c:5600 src/ldgeneric.c:5612
+#, c-format
+msgid "cannot create section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:3444
+#, c-format
+msgid "address computation expression contains variable '%s'"
+msgstr ""
+
+#: src/ldgeneric.c:3489
+#, c-format
+msgid ""
+"argument '%<PRIuMAX>' of ALIGN in address computation expression is no power "
+"of two"
+msgstr ""
+
+#: src/ldgeneric.c:3684
+#, c-format
+msgid "cannot find entry symbol '%s': defaulting to %#0*<PRIx64>"
+msgstr ""
+
+#: src/ldgeneric.c:3690
+#, c-format
+msgid "no entry symbol specified: defaulting to %#0*<PRIx64>"
+msgstr ""
+
+#: src/ldgeneric.c:3920
+#, c-format
+msgid "cannot create GNU hash table section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4071
+#, c-format
+msgid "cannot create hash table section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4114
+#, c-format
+msgid "cannot create build ID section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4191
+#, c-format
+msgid "cannot convert section data to file format: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4200
+#, c-format
+msgid "cannot convert section data to memory format: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4261
+#, c-format
+msgid "cannot read enough data for UUID"
+msgstr ""
+
+#: src/ldgeneric.c:4358 src/ldgeneric.c:4379 src/ldgeneric.c:4408
+#: src/ldgeneric.c:6062
+#, c-format
+msgid "cannot create symbol table for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5300 src/ldgeneric.c:5852
+#, c-format
+msgid "section index too large in dynamic symbol table"
+msgstr ""
+
+#: src/ldgeneric.c:5745
+#, c-format
+msgid "cannot create versioning section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5818
+#, c-format
+msgid "cannot create dynamic symbol table for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5994
+#, c-format
+msgid "cannot create versioning data: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6094 src/ldgeneric.c:6107 src/ldgeneric.c:6171
+#: src/ldgeneric.c:6179
+#, c-format
+msgid "cannot create section header string section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6101
+#, c-format
+msgid "cannot create section header string section"
+msgstr ""
+
+#: src/ldgeneric.c:6259
+#, c-format
+msgid "cannot create program header: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6267
+#, c-format
+msgid "while determining file layout: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6388
+#, c-format
+msgid "internal error: non-nobits section follows nobits section"
+msgstr ""
+
+#: src/ldgeneric.c:6925
+#, c-format
+msgid "cannot get header of 0th section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6941 src/unstrip.c:1808
+#, c-format
+msgid "cannot update ELF header: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6972
+#, c-format
+msgid "linker backend didn't specify function to relocate section"
+msgstr ""
+
+#: src/ldgeneric.c:6984
+#, c-format
+msgid "while writing output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6989
+#, c-format
+msgid "while finishing output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6995
+#, c-format
+msgid "cannot stat output file"
+msgstr ""
+
+#: src/ldgeneric.c:7011
+#, c-format
+msgid "WARNING: temporary output file overwritten before linking finished"
+msgstr ""
+
+#: src/ldgeneric.c:7064 src/ldgeneric.c:7075 src/ldgeneric.c:7086
+#: src/ldgeneric.c:7097 src/ldgeneric.c:7116 src/ldgeneric.c:7129
+#: src/ldgeneric.c:7141
+#, c-format
+msgid "no machine specific '%s' implementation"
+msgstr ""
+
+#: src/ldscript.y:178
+msgid "mode for segment invalid\n"
+msgstr ""
+
+#: src/ldscript.y:465
+#, c-format
+msgid "while reading version script '%s': %s at line %d"
+msgstr ""
+
+#: src/ldscript.y:466
+#, c-format
+msgid "while reading linker script '%s': %s at line %d"
+msgstr ""
+
+#: src/ldscript.y:745
+#, c-format
+msgid "symbol '%s' is declared both local and global for unnamed version"
+msgstr ""
+
+#: src/ldscript.y:747
+#, c-format
+msgid "symbol '%s' is declared both local and global for version '%s'"
+msgstr ""
+
+#: src/ldscript.y:767 src/ldscript.y:774
+#, c-format
+msgid "default visibility set as local and global"
+msgstr ""
+
+#: src/nm.c:74 src/strip.c:73
+msgid "Output selection:"
+msgstr ""
+
+#: src/nm.c:75
+msgid "Display debugger-only symbols"
+msgstr ""
+
+#: src/nm.c:76
+msgid "Display only defined symbols"
+msgstr ""
+
+#: src/nm.c:79
+msgid "Display dynamic symbols instead of normal symbols"
+msgstr ""
+
+#: src/nm.c:80
+msgid "Display only external symbols"
+msgstr ""
+
+#: src/nm.c:81
+msgid "Display only undefined symbols"
+msgstr ""
+
+#: src/nm.c:83
+msgid "Include index for symbols from archive members"
+msgstr ""
+
+#: src/nm.c:85 src/size.c:66
+msgid "Output format:"
+msgstr ""
+
+#: src/nm.c:87
+msgid "Print name of the input file before every symbol"
+msgstr ""
+
+#: src/nm.c:90
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd', `sysv' or `posix'.  The "
+"default is `sysv'"
+msgstr ""
+
+#: src/nm.c:92
+msgid "Same as --format=bsd"
+msgstr ""
+
+#: src/nm.c:93
+msgid "Same as --format=posix"
+msgstr ""
+
+#: src/nm.c:94 src/size.c:72
+msgid "Use RADIX for printing symbol values"
+msgstr ""
+
+#: src/nm.c:95
+msgid "Mark weak symbols"
+msgstr ""
+
+#: src/nm.c:96
+msgid "Print size of defined symbols"
+msgstr ""
+
+#: src/nm.c:98 src/size.c:80 src/strip.c:78 src/unstrip.c:81
+msgid "Output options:"
+msgstr ""
+
+#: src/nm.c:99
+msgid "Sort symbols numerically by address"
+msgstr ""
+
+#: src/nm.c:101
+msgid "Do not sort the symbols"
+msgstr ""
+
+#: src/nm.c:102
+msgid "Reverse the sense of the sort"
+msgstr ""
+
+#: src/nm.c:108
+msgid "List symbols from FILEs (a.out by default)."
+msgstr ""
+
+#: src/nm.c:136 src/objdump.c:105 src/size.c:117 src/strip.c:121
+#, c-format
+msgid "%s: INTERNAL ERROR %d (%s-%s): %s"
+msgstr ""
+
+#: src/nm.c:380 src/nm.c:392 src/size.c:317 src/size.c:326 src/size.c:337
+#: src/strip.c:1816
+#, c-format
+msgid "while closing '%s'"
+msgstr ""
+
+#: src/nm.c:402 src/objdump.c:296 src/strip.c:359
+#, c-format
+msgid "%s: File format not recognized"
+msgstr ""
+
+#: src/nm.c:442
+msgid ""
+"\n"
+"Archive index:"
+msgstr ""
+
+#: src/nm.c:451
+#, c-format
+msgid "invalid offset %zu for symbol %s"
+msgstr ""
+
+#: src/nm.c:456
+#, c-format
+msgid "%s in %s\n"
+msgstr ""
+
+#: src/nm.c:464
+#, c-format
+msgid "cannot reset archive offset to beginning"
+msgstr ""
+
+#: src/nm.c:488 src/objdump.c:344
+#, c-format
+msgid "%s%s%s: file format not recognized"
+msgstr ""
+
+#: src/nm.c:700
+#, c-format
+msgid "cannot create search tree"
+msgstr ""
+
+#: src/nm.c:740 src/nm.c:1002 src/objdump.c:744 src/readelf.c:885
+#: src/readelf.c:1028 src/readelf.c:1169 src/readelf.c:1351 src/readelf.c:1549
+#: src/readelf.c:1735 src/readelf.c:1945 src/readelf.c:2199 src/readelf.c:2265
+#: src/readelf.c:2343 src/readelf.c:2841 src/readelf.c:2877 src/readelf.c:2939
+#: src/readelf.c:6493 src/readelf.c:7387 src/readelf.c:7534 src/readelf.c:7604
+#: src/size.c:425 src/size.c:499 src/strip.c:483
+#, c-format
+msgid "cannot get section header string table index"
+msgstr ""
+
+#: src/nm.c:766
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s:\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:768
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s[%s]:\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:771
+#, c-format
+msgid ""
+"%*s%-*s %-*s Class  Type     %-*s %*s Section\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:1012
+#, c-format
+msgid "%s: entry size in section `%s' is not what we expect"
+msgstr ""
+
+#: src/nm.c:1016
+#, c-format
+msgid "%s: size of section `%s' is not multiple of entry size"
+msgstr ""
+
+#: src/nm.c:1255
+#, c-format
+msgid "%s%s%s%s: Invalid operation"
+msgstr ""
+
+#: src/nm.c:1312
+#, c-format
+msgid "%s%s%s: no symbols"
+msgstr ""
+
+#: src/objdump.c:61
+msgid "Mode selection:"
+msgstr ""
+
+#: src/objdump.c:62
+msgid "Display relocation information."
+msgstr ""
+
+#: src/objdump.c:64
+msgid "Display the full contents of all sections requested"
+msgstr ""
+
+#: src/objdump.c:66
+msgid "Display assembler code of executable sections"
+msgstr ""
+
+#: src/objdump.c:68
+msgid "Output option selection:"
+msgstr ""
+
+#: src/objdump.c:70
+msgid "Only display information for section NAME."
+msgstr ""
+
+#: src/objdump.c:76
+msgid "Show information from FILEs (a.out by default)."
+msgstr ""
+
+#: src/objdump.c:236 src/readelf.c:430
+msgid "No operation specified.\n"
+msgstr ""
+
+#: src/objdump.c:274 src/objdump.c:286
+#, c-format
+msgid "while close `%s'"
+msgstr ""
+
+#: src/objdump.c:379 src/readelf.c:1644 src/readelf.c:1818
+msgid "INVALID SYMBOL"
+msgstr ""
+
+#: src/objdump.c:394 src/readelf.c:1675 src/readelf.c:1851
+msgid "INVALID SECTION"
+msgstr ""
+
+#: src/objdump.c:510
+#, c-format
+msgid ""
+"\n"
+"RELOCATION RECORDS FOR [%s]:\n"
+"%-*s TYPE                 VALUE\n"
+msgstr ""
+
+#: src/objdump.c:513
+msgid "OFFSET"
+msgstr ""
+
+#: src/objdump.c:576
+#, c-format
+msgid "Contents of section %s:\n"
+msgstr ""
+
+#: src/objdump.c:676
+#, c-format
+msgid "cannot disassemble"
+msgstr ""
+
+#: src/ranlib.c:74
+msgid "Generate an index to speed access to archives."
+msgstr ""
+
+#: src/ranlib.c:77
+msgid "ARCHIVE"
+msgstr ""
+
+#: src/ranlib.c:116
+#, c-format
+msgid "Archive name required"
+msgstr ""
+
+#: src/ranlib.c:194
+#, c-format
+msgid "'%s' is no archive"
+msgstr ""
+
+#: src/ranlib.c:229
+#, c-format
+msgid "error while freeing sub-ELF descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:73
+msgid "ELF output selection:"
+msgstr ""
+
+#: src/readelf.c:75
+msgid "All these plus -p .strtab -p .dynstr -p .comment"
+msgstr ""
+
+#: src/readelf.c:76
+msgid "Display the dynamic segment"
+msgstr ""
+
+#: src/readelf.c:77
+msgid "Display the ELF file header"
+msgstr ""
+
+#: src/readelf.c:79
+msgid "Display histogram of bucket list lengths"
+msgstr ""
+
+#: src/readelf.c:80
+msgid "Display the program headers"
+msgstr ""
+
+#: src/readelf.c:82
+msgid "Display relocations"
+msgstr ""
+
+#: src/readelf.c:83
+msgid "Display the sections' headers"
+msgstr ""
+
+#: src/readelf.c:85
+msgid "Display the symbol table"
+msgstr ""
+
+#: src/readelf.c:86
+msgid "Display versioning information"
+msgstr ""
+
+#: src/readelf.c:87
+msgid "Display the ELF notes"
+msgstr ""
+
+#: src/readelf.c:89
+msgid "Display architecture specific information, if any"
+msgstr ""
+
+#: src/readelf.c:91
+msgid "Display sections for exception handling"
+msgstr ""
+
+#: src/readelf.c:93
+msgid "Additional output selection:"
+msgstr ""
+
+#: src/readelf.c:95
+msgid ""
+"Display DWARF section content.  SECTION can be one of abbrev, aranges, "
+"frame, info, loc, line, ranges, pubnames, str, macinfo, or exception"
+msgstr ""
+
+#: src/readelf.c:99
+msgid "Dump the uninterpreted contents of SECTION, by number or name"
+msgstr ""
+
+#: src/readelf.c:101
+msgid "Print string contents of sections"
+msgstr ""
+
+#: src/readelf.c:104
+msgid "Display the symbol index of an archive"
+msgstr ""
+
+#: src/readelf.c:106
+msgid "Output control:"
+msgstr ""
+
+#: src/readelf.c:108
+msgid "Do not find symbol names for addresses in DWARF data"
+msgstr ""
+
+#: src/readelf.c:114
+msgid "Print information from ELF file in human-readable form."
+msgstr ""
+
+#: src/readelf.c:401
+#, c-format
+msgid "Unknown DWARF debug section `%s'.\n"
+msgstr ""
+
+#: src/readelf.c:465
+#, c-format
+msgid "cannot generate Elf descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:477
+#, c-format
+msgid "'%s' is not an archive, cannot print archive index"
+msgstr ""
+
+#: src/readelf.c:482
+#, c-format
+msgid "error while closing Elf descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:574
+#, c-format
+msgid "cannot stat input file"
+msgstr ""
+
+#: src/readelf.c:576
+#, c-format
+msgid "input file is empty"
+msgstr ""
+
+#: src/readelf.c:578
+#, c-format
+msgid "failed reading '%s': %s"
+msgstr ""
+
+#: src/readelf.c:614
+#, c-format
+msgid "cannot read ELF header: %s"
+msgstr ""
+
+#: src/readelf.c:622
+#, c-format
+msgid "cannot create EBL handle"
+msgstr ""
+
+#: src/readelf.c:635
+#, c-format
+msgid "cannot determine number of program headers: %s"
+msgstr ""
+
+#: src/readelf.c:721
+msgid "NONE (None)"
+msgstr ""
+
+#: src/readelf.c:722
+msgid "REL (Relocatable file)"
+msgstr ""
+
+#: src/readelf.c:723
+msgid "EXEC (Executable file)"
+msgstr ""
+
+#: src/readelf.c:724
+msgid "DYN (Shared object file)"
+msgstr ""
+
+#: src/readelf.c:725
+msgid "CORE (Core file)"
+msgstr ""
+
+#: src/readelf.c:730
+#, c-format
+msgid "OS Specific: (%x)\n"
+msgstr ""
+
+#: src/readelf.c:732
+#, c-format
+msgid "Processor Specific: (%x)\n"
+msgstr ""
+
+#: src/readelf.c:742
+msgid ""
+"ELF Header:\n"
+"  Magic:  "
+msgstr ""
+
+#: src/readelf.c:746
+#, c-format
+msgid ""
+"\n"
+"  Class:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:751
+#, c-format
+msgid "  Data:                              %s\n"
+msgstr ""
+
+#: src/readelf.c:757
+#, c-format
+msgid "  Ident Version:                     %hhd %s\n"
+msgstr ""
+
+#: src/readelf.c:759 src/readelf.c:776
+msgid "(current)"
+msgstr ""
+
+#: src/readelf.c:763
+#, c-format
+msgid "  OS/ABI:                            %s\n"
+msgstr ""
+
+#: src/readelf.c:766
+#, c-format
+msgid "  ABI Version:                       %hhd\n"
+msgstr ""
+
+#: src/readelf.c:769
+msgid "  Type:                              "
+msgstr ""
+
+#: src/readelf.c:772
+#, c-format
+msgid "  Machine:                           %s\n"
+msgstr ""
+
+#: src/readelf.c:774
+#, c-format
+msgid "  Version:                           %d %s\n"
+msgstr ""
+
+#: src/readelf.c:778
+#, c-format
+msgid "  Entry point address:               %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:781
+#, c-format
+msgid "  Start of program headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:782 src/readelf.c:785
+msgid "(bytes into file)"
+msgstr ""
+
+#: src/readelf.c:784
+#, c-format
+msgid "  Start of section headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:787
+#, c-format
+msgid "  Flags:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:790
+#, c-format
+msgid "  Size of this header:               %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:791 src/readelf.c:794 src/readelf.c:811
+msgid "(bytes)"
+msgstr ""
+
+#: src/readelf.c:793
+#, c-format
+msgid "  Size of program header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:796
+#, c-format
+msgid "  Number of program headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:803
+#, c-format
+msgid " (%<PRIu32> in [0].sh_info)"
+msgstr ""
+
+#: src/readelf.c:806 src/readelf.c:823 src/readelf.c:837
+msgid " ([0] not available)"
+msgstr ""
+
+#: src/readelf.c:810
+#, c-format
+msgid "  Size of section header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:813
+#, c-format
+msgid "  Number of section headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:820
+#, c-format
+msgid " (%<PRIu32> in [0].sh_size)"
+msgstr ""
+
+#: src/readelf.c:833
+#, c-format
+msgid " (%<PRIu32> in [0].sh_link)"
+msgstr ""
+
+#: src/readelf.c:841
+#, c-format
+msgid ""
+"  Section header string table index: XINDEX%s\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:845
+#, c-format
+msgid ""
+"  Section header string table index: %<PRId16>\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:877
+#, c-format
+msgid ""
+"There are %d section headers, starting at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:887
+msgid "Section Headers:"
+msgstr ""
+
+#: src/readelf.c:890
+msgid ""
+"[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
+"Inf Al"
+msgstr ""
+
+#: src/readelf.c:892
+msgid ""
+"[Nr] Name                 Type         Addr             Off      Size     ES "
+"Flags Lk Inf Al"
+msgstr ""
+
+#: src/readelf.c:899 src/readelf.c:1052
+#, c-format
+msgid "cannot get section: %s"
+msgstr ""
+
+#: src/readelf.c:906 src/readelf.c:1060 src/readelf.c:7554 src/unstrip.c:353
+#: src/unstrip.c:377 src/unstrip.c:427 src/unstrip.c:536 src/unstrip.c:553
+#: src/unstrip.c:591 src/unstrip.c:789 src/unstrip.c:1057 src/unstrip.c:1244
+#: src/unstrip.c:1305 src/unstrip.c:1427 src/unstrip.c:1480 src/unstrip.c:1588
+#: src/unstrip.c:1778
+#, c-format
+msgid "cannot get section header: %s"
+msgstr ""
+
+#: src/readelf.c:964
+msgid "Program Headers:"
+msgstr ""
+
+#: src/readelf.c:966
+msgid ""
+"  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:969
+msgid ""
+"  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
+"MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:1009
+#, c-format
+msgid "\t[Requesting program interpreter: %s]\n"
+msgstr ""
+
+#: src/readelf.c:1030
+msgid ""
+"\n"
+" Section to Segment mapping:\n"
+"  Segment Sections..."
+msgstr ""
+
+#: src/readelf.c:1041 src/unstrip.c:1824 src/unstrip.c:1863 src/unstrip.c:1870
+#, c-format
+msgid "cannot get program header: %s"
+msgstr ""
+
+#: src/readelf.c:1175
+#, c-format
+msgid ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1180
+#, c-format
+msgid ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1188
+msgid "<INVALID SYMBOL>"
+msgstr ""
+
+#: src/readelf.c:1202
+msgid "<INVALID SECTION>"
+msgstr ""
+
+#: src/readelf.c:1353
+#, c-format
+msgid ""
+"\n"
+"Dynamic segment contains %lu entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Dynamic segment contains %lu entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1365
+msgid "  Type              Value\n"
+msgstr ""
+
+#: src/readelf.c:1389
+#, c-format
+msgid "Shared library: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1394
+#, c-format
+msgid "Library soname: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1399
+#, c-format
+msgid "Library rpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1404
+#, c-format
+msgid "Library runpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1424
+#, c-format
+msgid "%<PRId64> (bytes)\n"
+msgstr ""
+
+#: src/readelf.c:1534 src/readelf.c:1720
+#, c-format
+msgid ""
+"\n"
+"Invalid symbol table at offset %#0<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:1552 src/readelf.c:1737
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1567
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1577
+msgid "  Offset      Type                 Value       Name\n"
+msgstr ""
+
+#: src/readelf.c:1579
+msgid "  Offset              Type                 Value               Name\n"
+msgstr ""
+
+#: src/readelf.c:1632 src/readelf.c:1643 src/readelf.c:1656 src/readelf.c:1674
+#: src/readelf.c:1686 src/readelf.c:1805 src/readelf.c:1817 src/readelf.c:1831
+#: src/readelf.c:1850 src/readelf.c:1863
+msgid "<INVALID RELOC>"
+msgstr ""
+
+#: src/readelf.c:1749
+msgid "  Offset      Type            Value       Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:1751
+msgid "  Offset              Type            Value               Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:1952
+#, c-format
+msgid ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entry:\n"
+msgid_plural ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1958
+#, c-format
+msgid " %lu local symbol  String table: [%2u] '%s'\n"
+msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1968
+msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:1970
+msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:1990
+#, c-format
+msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+msgstr ""
+
+#: src/readelf.c:2078
+#, c-format
+msgid "bad dynamic symbol"
+msgstr ""
+
+#: src/readelf.c:2160
+msgid "none"
+msgstr ""
+
+#: src/readelf.c:2177
+msgid "| <unknown>"
+msgstr ""
+
+#: src/readelf.c:2202
+#, c-format
+msgid ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2225
+#, c-format
+msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
+msgstr ""
+
+#: src/readelf.c:2238
+#, c-format
+msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
+msgstr ""
+
+#: src/readelf.c:2269
+#, c-format
+msgid ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2299
+#, c-format
+msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
+msgstr ""
+
+#: src/readelf.c:2314
+#, c-format
+msgid "  %#06x: Parent %d: %s\n"
+msgstr ""
+
+#: src/readelf.c:2546
+#, c-format
+msgid ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgid_plural ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2576
+msgid "   0 *local*                     "
+msgstr ""
+
+#: src/readelf.c:2581
+msgid "   1 *global*                    "
+msgstr ""
+
+#: src/readelf.c:2612
+#, c-format
+msgid ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"bucket):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"buckets):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2636
+#, no-c-format
+msgid " Length  Number  % of total  Coverage\n"
+msgstr ""
+
+#: src/readelf.c:2638
+#, c-format
+msgid "      0  %6<PRIu32>      %5.1f%%\n"
+msgstr ""
+
+#: src/readelf.c:2645
+#, c-format
+msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+msgstr ""
+
+#: src/readelf.c:2658
+#, c-format
+msgid ""
+" Average number of tests:   successful lookup: %f\n"
+"                          unsuccessful lookup: %f\n"
+msgstr ""
+
+#: src/readelf.c:2676 src/readelf.c:2718 src/readelf.c:2759
+#, c-format
+msgid "cannot get data for section %d: %s"
+msgstr ""
+
+#: src/readelf.c:2813
+#, c-format
+msgid ""
+" Symbol Bias: %u\n"
+" Bitmask Size: %zu bytes  %<PRIuFAST32>%% bits set  2nd hash shift: %u\n"
+msgstr ""
+
+#: src/readelf.c:2887
+#, c-format
+msgid ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2901
+msgid ""
+"       Library                       Time Stamp          Checksum Version "
+"Flags"
+msgstr ""
+
+#: src/readelf.c:2951
+#, c-format
+msgid ""
+"\n"
+"Object attributes section [%2zu] '%s' of %<PRIu64> bytes at offset %"
+"#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:2967
+msgid "  Owner          Size\n"
+msgstr ""
+
+#: src/readelf.c:2993
+#, c-format
+msgid "  %-13s  %4<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3025
+#, c-format
+msgid "    %-4u %12<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3030
+#, c-format
+msgid "    File: %11<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3065
+#, c-format
+msgid "      %s: %<PRId64>, %s\n"
+msgstr ""
+
+#: src/readelf.c:3068
+#, c-format
+msgid "      %s: %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:3071
+#, c-format
+msgid "      %s: %s\n"
+msgstr ""
+
+#: src/readelf.c:3078
+#, c-format
+msgid "      %u: %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:3081
+#, c-format
+msgid "      %u: %s\n"
+msgstr ""
+
+#: src/readelf.c:3117
+#, c-format
+msgid "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3120
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3125
+#, c-format
+msgid "%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3128
+#, c-format
+msgid "%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3134
+#, c-format
+msgid "%s+%#<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3137
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3141
+#, c-format
+msgid "%#<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3144
+#, c-format
+msgid "%#0*<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3149
+#, c-format
+msgid "%s+%#<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3152
+#, c-format
+msgid "%s+%#0*<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3260
+#, c-format
+msgid "unknown tag %hx"
+msgstr ""
+
+#: src/readelf.c:3262
+#, c-format
+msgid "unknown user tag %hx"
+msgstr ""
+
+#: src/readelf.c:3480
+#, c-format
+msgid "unknown attribute %hx"
+msgstr ""
+
+#: src/readelf.c:3483
+#, c-format
+msgid "unknown user attribute %hx"
+msgstr ""
+
+#: src/readelf.c:3529
+#, c-format
+msgid "unknown form %<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3763
+msgid "empty block"
+msgstr ""
+
+#: src/readelf.c:3766
+#, c-format
+msgid "%zu byte block:"
+msgstr ""
+
+#: src/readelf.c:4175
+#, c-format
+msgid "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+msgstr ""
+
+#: src/readelf.c:4188
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [ Code]\n"
+msgstr ""
+
+#: src/readelf.c:4195
+#, c-format
+msgid ""
+"\n"
+"Abbreviation section at offset %<PRIu64>:\n"
+msgstr ""
+
+#: src/readelf.c:4208
+#, c-format
+msgid " *** error while reading abbreviation: %s\n"
+msgstr ""
+
+#: src/readelf.c:4224
+#, c-format
+msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
+msgstr ""
+
+#: src/readelf.c:4227
+msgid "yes"
+msgstr ""
+
+#: src/readelf.c:4227
+msgid "no"
+msgstr ""
+
+#: src/readelf.c:4263
+#, c-format
+msgid "cannot get .debug_aranges content: %s"
+msgstr ""
+
+#: src/readelf.c:4268
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:4298
+#, c-format
+msgid " [%*zu] ???\n"
+msgstr ""
+
+#: src/readelf.c:4300
+#, c-format
+msgid ""
+" [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:4319
+#, c-format
+msgid "cannot get .debug_ranges content: %s"
+msgstr ""
+
+#: src/readelf.c:4324 src/readelf.c:4810 src/readelf.c:5452 src/readelf.c:5897
+#: src/readelf.c:5992 src/readelf.c:6164
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:4338 src/readelf.c:5911
+#, c-format
+msgid " [%6tx]  <INVALID DATA>\n"
+msgstr ""
+
+#: src/readelf.c:4360 src/readelf.c:5933
+#, c-format
+msgid " [%6tx]  base address %s\n"
+msgstr ""
+
+#: src/readelf.c:4371
+#, c-format
+msgid " [%6tx]  %s..%s\n"
+msgstr ""
+
+#: src/readelf.c:4373
+#, c-format
+msgid "           %s..%s\n"
+msgstr ""
+
+#: src/readelf.c:4799 src/readelf.c:6230 src/readelf.c:6332
+#, c-format
+msgid "cannot get %s content: %s"
+msgstr ""
+
+#: src/readelf.c:4806
+#, c-format
+msgid ""
+"\n"
+"Call frame information section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:4833 src/readelf.c:5486
+#, c-format
+msgid "invalid data in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:4855
+#, c-format
+msgid ""
+"\n"
+" [%6tx] Zero terminator\n"
+msgstr ""
+
+#: src/readelf.c:4924
+#, c-format
+msgid "invalid augmentation length"
+msgstr ""
+
+#: src/readelf.c:4936
+msgid "FDE address encoding: "
+msgstr ""
+
+#: src/readelf.c:4942
+msgid "LSDA pointer encoding: "
+msgstr ""
+
+#: src/readelf.c:5034
+#, c-format
+msgid " (offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5041
+#, c-format
+msgid " (end offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5068
+#, c-format
+msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:5114
+#, c-format
+msgid "cannot get attribute code: %s"
+msgstr ""
+
+#: src/readelf.c:5122
+#, c-format
+msgid "cannot get attribute form: %s"
+msgstr ""
+
+#: src/readelf.c:5135
+#, c-format
+msgid "cannot get attribute value: %s"
+msgstr ""
+
+#: src/readelf.c:5331
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [Offset]\n"
+msgstr ""
+
+#: src/readelf.c:5356
+#, c-format
+msgid ""
+" Compilation unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: %"
+"<PRIu8>, Offset size: %<PRIu8>\n"
+msgstr ""
+
+#: src/readelf.c:5374
+#, c-format
+msgid "cannot get DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:5385
+#, c-format
+msgid "cannot get DIE offset: %s"
+msgstr ""
+
+#: src/readelf.c:5393
+#, c-format
+msgid "cannot get tag of DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:5422
+#, c-format
+msgid "cannot get next DIE: %s\n"
+msgstr ""
+
+#: src/readelf.c:5429
+#, c-format
+msgid "cannot get next DIE: %s"
+msgstr ""
+
+#: src/readelf.c:5464
+#, c-format
+msgid "cannot get line data section data: %s"
+msgstr ""
+
+#: src/readelf.c:5477
+#, c-format
+msgid ""
+"\n"
+"Table at offset %Zu:\n"
+msgstr ""
+
+#: src/readelf.c:5529
+#, c-format
+msgid ""
+"\n"
+" Length:                     %<PRIu64>\n"
+" DWARF version:              %<PRIuFAST16>\n"
+" Prologue length:            %<PRIu64>\n"
+" Minimum instruction length: %<PRIuFAST8>\n"
+" Initial value if '%s': %<PRIuFAST8>\n"
+" Line base:                  %<PRIdFAST8>\n"
+" Line range:                 %<PRIuFAST8>\n"
+" Opcode base:                %<PRIuFAST8>\n"
+"\n"
+"Opcodes:\n"
+msgstr ""
+
+#: src/readelf.c:5548
+#, c-format
+msgid "invalid data at offset %tu in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:5563
+#, c-format
+msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
+msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:5571
+msgid ""
+"\n"
+"Directory table:"
+msgstr ""
+
+#: src/readelf.c:5587
+msgid ""
+"\n"
+"File name table:\n"
+" Entry Dir   Time      Size      Name"
+msgstr ""
+
+#: src/readelf.c:5616
+msgid ""
+"\n"
+"Line number statements:"
+msgstr ""
+
+#: src/readelf.c:5677
+#, c-format
+msgid " special opcode %u: address+%u = %s, line%+d = %zu\n"
+msgstr ""
+
+#: src/readelf.c:5697
+#, c-format
+msgid " extended opcode %u: "
+msgstr ""
+
+#: src/readelf.c:5702
+msgid "end of sequence"
+msgstr ""
+
+#: src/readelf.c:5717
+#, c-format
+msgid "set address to %s\n"
+msgstr ""
+
+#: src/readelf.c:5738
+#, c-format
+msgid "define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
+msgstr ""
+
+#: src/readelf.c:5747
+msgid "unknown opcode"
+msgstr ""
+
+#: src/readelf.c:5759
+msgid " copy"
+msgstr ""
+
+#: src/readelf.c:5769
+#, c-format
+msgid "advance address by %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5780
+#, c-format
+msgid " advance line by constant %d to %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:5788
+#, c-format
+msgid " set file to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:5798
+#, c-format
+msgid " set column to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:5805
+#, c-format
+msgid " set '%s' to %<PRIuFAST8>\n"
+msgstr ""
+
+#: src/readelf.c:5811
+msgid " set basic block flag"
+msgstr ""
+
+#: src/readelf.c:5821
+#, c-format
+msgid "advance address by constant %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5837
+#, c-format
+msgid "advance address by fixed value %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5846
+msgid " set prologue end flag"
+msgstr ""
+
+#: src/readelf.c:5851
+msgid " set epilogue begin flag"
+msgstr ""
+
+#: src/readelf.c:5860
+#, c-format
+msgid " unknown opcode with %<PRIu8> parameter:"
+msgid_plural " unknown opcode with %<PRIu8> parameters:"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:5892
+#, c-format
+msgid "cannot get .debug_loc content: %s"
+msgstr ""
+
+#: src/readelf.c:5947
+#, c-format
+msgid " [%6tx]  %s..%s"
+msgstr ""
+
+#: src/readelf.c:5949
+#, c-format
+msgid "           %s..%s"
+msgstr ""
+
+#: src/readelf.c:6002
+#, c-format
+msgid "cannot get macro information section data: %s"
+msgstr ""
+
+#: src/readelf.c:6081
+#, c-format
+msgid "%*s*** non-terminated string at end of section"
+msgstr ""
+
+#: src/readelf.c:6149
+#, c-format
+msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
+msgstr ""
+
+#: src/readelf.c:6188
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" %*s  String\n"
+msgstr ""
+
+#: src/readelf.c:6202
+#, c-format
+msgid " *** error while reading strings: %s\n"
+msgstr ""
+
+#: src/readelf.c:6222
+#, c-format
+msgid ""
+"\n"
+"Call frame search table section [%2zu] '.eh_frame_hdr':\n"
+msgstr ""
+
+#: src/readelf.c:6324
+#, c-format
+msgid ""
+"\n"
+"Exception handling table section [%2zu] '.gcc_except_table':\n"
+msgstr ""
+
+#: src/readelf.c:6347
+#, c-format
+msgid " LPStart encoding:    %#x "
+msgstr ""
+
+#: src/readelf.c:6359
+#, c-format
+msgid " TType encoding:      %#x "
+msgstr ""
+
+#: src/readelf.c:6373
+#, c-format
+msgid " Call site encoding:  %#x "
+msgstr ""
+
+#: src/readelf.c:6386
+msgid ""
+"\n"
+" Call site table:"
+msgstr ""
+
+#: src/readelf.c:6400
+#, c-format
+msgid ""
+" [%4u] Call site start:   %#<PRIx64>\n"
+"        Call site length:  %<PRIu64>\n"
+"        Landing pad:       %#<PRIx64>\n"
+"        Action:            %u\n"
+msgstr ""
+
+#: src/readelf.c:6460
+#, c-format
+msgid "invalid TType encoding"
+msgstr ""
+
+#: src/readelf.c:6484
+#, c-format
+msgid "cannot get debug context descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:6620 src/readelf.c:7221
+#, c-format
+msgid "cannot convert core note data: %s"
+msgstr ""
+
+#: src/readelf.c:6961
+#, c-format
+msgid ""
+"\n"
+"%*s... <repeats %u more times> ..."
+msgstr ""
+
+#: src/readelf.c:7320
+msgid "  Owner          Data size  Type\n"
+msgstr ""
+
+#: src/readelf.c:7338
+#, c-format
+msgid "  %-13.*s  %9<PRId32>  %s\n"
+msgstr ""
+
+#: src/readelf.c:7372
+#, c-format
+msgid "cannot get content of note section: %s"
+msgstr ""
+
+#: src/readelf.c:7399
+#, c-format
+msgid ""
+"\n"
+"Note section [%2zu] '%s' of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7422
+#, c-format
+msgid ""
+"\n"
+"Note segment of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7468
+#, c-format
+msgid ""
+"\n"
+"Section [%Zu] '%s' has no data to dump.\n"
+msgstr ""
+
+#: src/readelf.c:7474 src/readelf.c:7497
+#, c-format
+msgid "cannot get data for section [%Zu] '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7478
+#, c-format
+msgid ""
+"\n"
+"Hex dump of section [%Zu] '%s', %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7491
+#, c-format
+msgid ""
+"\n"
+"Section [%Zu] '%s' has no strings to dump.\n"
+msgstr ""
+
+#: src/readelf.c:7501
+#, c-format
+msgid ""
+"\n"
+"String section [%Zu] '%s' contains %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7549
+#, c-format
+msgid ""
+"\n"
+"section [%lu] does not exist"
+msgstr ""
+
+#: src/readelf.c:7576
+#, c-format
+msgid ""
+"\n"
+"section '%s' does not exist"
+msgstr ""
+
+#: src/readelf.c:7637
+#, c-format
+msgid "cannot get symbol index of archive '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7640
+#, c-format
+msgid ""
+"\n"
+"Archive '%s' has no symbol index\n"
+msgstr ""
+
+#: src/readelf.c:7644
+#, c-format
+msgid ""
+"\n"
+"Index of archive '%s' has %Zu entries:\n"
+msgstr ""
+
+#: src/readelf.c:7662
+#, c-format
+msgid "cannot extract member at offset %Zu in '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7667
+#, c-format
+msgid "Archive member '%s' contains:\n"
+msgstr ""
+
+#: src/size.c:68
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd' or `sysv'.  The default "
+"is `bsd'"
+msgstr ""
+
+#: src/size.c:70
+msgid "Same as `--format=sysv'"
+msgstr ""
+
+#: src/size.c:71
+msgid "Same as `--format=bsd'"
+msgstr ""
+
+#: src/size.c:74
+msgid "Same as `--radix=10'"
+msgstr ""
+
+#: src/size.c:75
+msgid "Same as `--radix=8'"
+msgstr ""
+
+#: src/size.c:76
+msgid "Same as `--radix=16'"
+msgstr ""
+
+#: src/size.c:78
+msgid "Similar to `--format=sysv' output but in one line"
+msgstr ""
+
+#: src/size.c:82
+msgid "Print size and permission flags for loadable segments"
+msgstr ""
+
+#: src/size.c:83
+msgid "Display the total sizes (bsd only)"
+msgstr ""
+
+#: src/size.c:88
+msgid "List section sizes of FILEs (a.out by default)."
+msgstr ""
+
+#: src/size.c:269
+#, c-format
+msgid "Invalid format: %s"
+msgstr ""
+
+#: src/size.c:280
+#, c-format
+msgid "Invalid radix: %s"
+msgstr ""
+
+#: src/size.c:339
+#, c-format
+msgid "%s: file format not recognized"
+msgstr ""
+
+#: src/size.c:446 src/size.c:589
+#, c-format
+msgid " (ex %s)"
+msgstr ""
+
+#: src/size.c:614
+msgid "(TOTALS)\n"
+msgstr ""
+
+#: src/strings.c:70
+msgid "Output Selection:"
+msgstr ""
+
+#: src/strings.c:71
+msgid "Scan entire file, not only loaded sections"
+msgstr ""
+
+#: src/strings.c:73
+msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed"
+msgstr ""
+
+#: src/strings.c:74
+msgid ""
+"Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, "
+"{B,L} = 32-bit"
+msgstr ""
+
+#: src/strings.c:78
+msgid "Print name of the file before each string."
+msgstr ""
+
+#: src/strings.c:80
+msgid "Print location of the string in base 8, 10, or 16 respectively."
+msgstr ""
+
+#: src/strings.c:81
+msgid "Alias for --radix=o"
+msgstr ""
+
+#: src/strings.c:88
+msgid "Print the strings of printable characters in files."
+msgstr ""
+
+#: src/strings.c:268 src/strings.c:303
+#, c-format
+msgid "invalid value '%s' for %s parameter"
+msgstr ""
+
+#: src/strings.c:314
+#, c-format
+msgid "invalid minimum length of matched string size"
+msgstr ""
+
+#: src/strings.c:601
+#, c-format
+msgid "lseek64 failed"
+msgstr ""
+
+#: src/strings.c:616 src/strings.c:680
+#, c-format
+msgid "re-mmap failed"
+msgstr ""
+
+#: src/strings.c:653
+#, c-format
+msgid "mprotect failed"
+msgstr ""
+
+#: src/strip.c:74
+msgid "Place stripped output into FILE"
+msgstr ""
+
+#: src/strip.c:75
+msgid "Extract the removed sections into FILE"
+msgstr ""
+
+#: src/strip.c:76
+msgid "Embed name FILE instead of -f argument"
+msgstr ""
+
+#: src/strip.c:80
+msgid "Remove all debugging symbols"
+msgstr ""
+
+#: src/strip.c:84
+msgid "Copy modified/access timestamps to the output"
+msgstr ""
+
+#: src/strip.c:86
+msgid "Remove .comment section"
+msgstr ""
+
+#: src/strip.c:89
+msgid "Relax a few rules to handle slightly broken ELF files"
+msgstr ""
+
+#: src/strip.c:94
+msgid "Discard symbols from object files."
+msgstr ""
+
+#: src/strip.c:186
+#, c-format
+msgid "Only one input file allowed together with '-o' and '-f'"
+msgstr ""
+
+#: src/strip.c:222
+#, c-format
+msgid "-f option specified twice"
+msgstr ""
+
+#: src/strip.c:231
+#, c-format
+msgid "-F option specified twice"
+msgstr ""
+
+#: src/strip.c:240 src/unstrip.c:125
+#, c-format
+msgid "-o option specified twice"
+msgstr ""
+
+#: src/strip.c:260
+#, c-format
+msgid "-R option supports only .comment section"
+msgstr ""
+
+#: src/strip.c:298 src/strip.c:322
+#, c-format
+msgid "cannot stat input file '%s'"
+msgstr ""
+
+#: src/strip.c:312
+#, c-format
+msgid "while opening '%s'"
+msgstr ""
+
+#: src/strip.c:350
+#, c-format
+msgid "%s: cannot use -o or -f when stripping archive"
+msgstr ""
+
+#: src/strip.c:448
+#, c-format
+msgid "cannot open EBL backend"
+msgstr ""
+
+#: src/strip.c:498 src/strip.c:522
+#, c-format
+msgid "cannot create new file '%s': %s"
+msgstr ""
+
+#: src/strip.c:582
+#, c-format
+msgid "illformed file '%s'"
+msgstr ""
+
+#: src/strip.c:869 src/strip.c:956
+#, c-format
+msgid "while generating output file: %s"
+msgstr ""
+
+#: src/strip.c:929 src/strip.c:1668
+#, c-format
+msgid "%s: error while creating ELF header: %s"
+msgstr ""
+
+#: src/strip.c:943
+#, c-format
+msgid "while preparing output for '%s'"
+msgstr ""
+
+#: src/strip.c:994 src/strip.c:1050
+#, c-format
+msgid "while create section header section: %s"
+msgstr ""
+
+#: src/strip.c:1000
+#, c-format
+msgid "cannot allocate section data: %s"
+msgstr ""
+
+#: src/strip.c:1059
+#, c-format
+msgid "while create section header string table: %s"
+msgstr ""
+
+#: src/strip.c:1593 src/strip.c:1690
+#, c-format
+msgid "while writing '%s': %s"
+msgstr ""
+
+#: src/strip.c:1604
+#, c-format
+msgid "while creating '%s'"
+msgstr ""
+
+#: src/strip.c:1616
+#, c-format
+msgid "while computing checksum for debug information"
+msgstr ""
+
+#: src/strip.c:1676
+#, c-format
+msgid "%s: error while reading the file: %s"
+msgstr ""
+
+#: src/strip.c:1722 src/strip.c:1729
+#, c-format
+msgid "error while finishing '%s': %s"
+msgstr ""
+
+#: src/strip.c:1752 src/strip.c:1809
+#, c-format
+msgid "cannot set access and modification date of '%s'"
+msgstr ""
+
+#: src/unstrip.c:78
+msgid "Match MODULE against file names, not module names"
+msgstr ""
+
+#: src/unstrip.c:79
+msgid "Silently skip unfindable files"
+msgstr ""
+
+#: src/unstrip.c:82
+msgid "Place output into FILE"
+msgstr ""
+
+#: src/unstrip.c:84
+msgid "Create multiple output files under DIRECTORY"
+msgstr ""
+
+#: src/unstrip.c:85
+msgid "Use module rather than file names"
+msgstr ""
+
+#: src/unstrip.c:87
+msgid "Create output for modules that have no separate debug information"
+msgstr ""
+
+#: src/unstrip.c:90
+msgid "Apply relocations to section contents in ET_REL files"
+msgstr ""
+
+#: src/unstrip.c:92
+msgid "Only list module and file names, build IDs"
+msgstr ""
+
+#: src/unstrip.c:134
+#, c-format
+msgid "-d option specified twice"
+msgstr ""
+
+#: src/unstrip.c:166
+#, c-format
+msgid "only one of -o or -d allowed"
+msgstr ""
+
+#: src/unstrip.c:175
+#, c-format
+msgid "-n cannot be used with explicit files or -o or -d"
+msgstr ""
+
+#: src/unstrip.c:190
+#, c-format
+msgid "output directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:199
+#, c-format
+msgid "exactly two file arguments are required"
+msgstr ""
+
+#: src/unstrip.c:205
+#, c-format
+msgid "-m, -a, -R, and -i options not allowed with explicit files"
+msgstr ""
+
+#: src/unstrip.c:218
+#, c-format
+msgid "-o or -d is required when using implicit files"
+msgstr ""
+
+#: src/unstrip.c:254
+#, c-format
+msgid "cannot create ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:259
+#, c-format
+msgid "cannot copy ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:264 src/unstrip.c:1817
+#, c-format
+msgid "cannot create program headers: %s"
+msgstr ""
+
+#: src/unstrip.c:270
+#, c-format
+msgid "cannot copy program header: %s"
+msgstr ""
+
+#: src/unstrip.c:280
+#, c-format
+msgid "cannot copy section header: %s"
+msgstr ""
+
+#: src/unstrip.c:283 src/unstrip.c:1505
+#, c-format
+msgid "cannot get section data: %s"
+msgstr ""
+
+#: src/unstrip.c:285 src/unstrip.c:1507
+#, c-format
+msgid "cannot copy section data: %s"
+msgstr ""
+
+#: src/unstrip.c:309
+#, c-format
+msgid "cannot create directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:349 src/unstrip.c:763 src/unstrip.c:1540
+#, c-format
+msgid "cannot get symbol table entry: %s"
+msgstr ""
+
+#: src/unstrip.c:365 src/unstrip.c:580 src/unstrip.c:601 src/unstrip.c:613
+#: src/unstrip.c:1561 src/unstrip.c:1691 src/unstrip.c:1715
+#, c-format
+msgid "cannot update symbol table: %s"
+msgstr ""
+
+#: src/unstrip.c:382 src/unstrip.c:432 src/unstrip.c:562 src/unstrip.c:1209
+#: src/unstrip.c:1525 src/unstrip.c:1720 src/unstrip.c:1791
+#, c-format
+msgid "cannot update section header: %s"
+msgstr ""
+
+#: src/unstrip.c:408 src/unstrip.c:419
+#, c-format
+msgid "cannot update relocation: %s"
+msgstr ""
+
+#: src/unstrip.c:507
+#, c-format
+msgid "cannot get symbol version: %s"
+msgstr ""
+
+#: src/unstrip.c:519
+#, c-format
+msgid "unexpected section type in [%Zu] with sh_link to symtab"
+msgstr ""
+
+#: src/unstrip.c:769
+#, c-format
+msgid "invalid string offset in symbol [%Zu]"
+msgstr ""
+
+#: src/unstrip.c:911 src/unstrip.c:1248
+#, c-format
+msgid "cannot read section [%Zu] name: %s"
+msgstr ""
+
+#: src/unstrip.c:952 src/unstrip.c:971 src/unstrip.c:1004
+#, c-format
+msgid "cannot read '.gnu.prelink_undo' section: %s"
+msgstr ""
+
+#: src/unstrip.c:992
+#, c-format
+msgid "invalid contents in '%s' section"
+msgstr ""
+
+#: src/unstrip.c:1047 src/unstrip.c:1370
+#, c-format
+msgid "cannot find matching section for [%Zu] '%s'"
+msgstr ""
+
+#: src/unstrip.c:1171 src/unstrip.c:1186 src/unstrip.c:1451
+#, c-format
+msgid "cannot add section name to string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1195
+#, c-format
+msgid "cannot update section header string table data: %s"
+msgstr ""
+
+#: src/unstrip.c:1223 src/unstrip.c:1227
+#, c-format
+msgid "cannot get section header string table section index: %s"
+msgstr ""
+
+#: src/unstrip.c:1231 src/unstrip.c:1235 src/unstrip.c:1466
+#, c-format
+msgid "cannot get section count: %s"
+msgstr ""
+
+#: src/unstrip.c:1293 src/unstrip.c:1385
+#, c-format
+msgid "cannot read section header string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1445
+#, c-format
+msgid "cannot add new section: %s"
+msgstr ""
+
+#: src/unstrip.c:1548
+#, c-format
+msgid "symbol [%Zu] has invalid section index"
+msgstr ""
+
+#: src/unstrip.c:1800
+#, c-format
+msgid "cannot get ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:1827
+#, c-format
+msgid "cannot update program header: %s"
+msgstr ""
+
+#: src/unstrip.c:1832 src/unstrip.c:1911
+#, c-format
+msgid "cannot write output file: %s"
+msgstr ""
+
+#: src/unstrip.c:1880
+#, c-format
+msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:1883
+#, c-format
+msgid ""
+"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:1902 src/unstrip.c:1942 src/unstrip.c:1954 src/unstrip.c:2034
+#, c-format
+msgid "cannot create ELF descriptor: %s"
+msgstr ""
+
+#: src/unstrip.c:1960
+#, c-format
+msgid "'%s' and '%s' do not seem to match"
+msgstr ""
+
+#: src/unstrip.c:1991
+#, c-format
+msgid "cannot find stripped file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:1995
+#, c-format
+msgid "cannot open stripped file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2010
+#, c-format
+msgid "cannot find debug file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2014
+#, c-format
+msgid "cannot open debug file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2027
+#, c-format
+msgid "module '%s' file '%s' is not stripped"
+msgstr ""
+
+#: src/unstrip.c:2058
+#, c-format
+msgid "cannot cache section addresses for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2191
+#, c-format
+msgid "no matching modules found"
+msgstr ""
+
+#: src/unstrip.c:2200
+#, c-format
+msgid "matched more than one module"
+msgstr ""
+
+#: src/unstrip.c:2247
+msgid ""
+"STRIPPED-FILE DEBUG-FILE\n"
+"[MODULE...]"
+msgstr ""
+
+#: src/unstrip.c:2248
+msgid ""
+"Combine stripped files with separate symbols and debug information.\n\nThe "
+"first form puts the result in DEBUG-FILE if -o was not given.\n"
+"\n"
+"MODULE arguments give file name patterns matching modules to process.\n"
+"With -f these match the file name of the main (stripped) file (slashes are "
+"never special), otherwise they match the simple module names.  With no "
+"arguments, process all modules found.\n"
+"\n"
+"Multiple modules are written to files under OUTPUT-DIRECTORY, creating "
+"subdirectories as needed.  With -m these files have simple module names, "
+"otherwise they have the name of the main file complete with directory "
+"underneath OUTPUT-DIRECTORY.\n"
+"\n"
+"With -n no files are written, but one line to standard output for each "
+"module:\n"
+"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n"
+"START and SIZE are hexadecimal giving the address bounds of the module.  "
+"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the "
+"hexadecimal may be followed by @0xADDR giving the address where the ID "
+"resides if that is known.  FILE is the file name found for the module, or - "
+"if none was found, or . if an ELF image is available but not from any named "
+"file.  DEBUGFILE is the separate debuginfo file name, or - if no debuginfo "
+"was found, or . if FILE contains the debug information."
+msgstr ""
diff --git a/third_party/elfutils/po/insert-header.sin b/third_party/elfutils/po/insert-header.sin
new file mode 100644
index 0000000..b26de01
--- /dev/null
+++ b/third_party/elfutils/po/insert-header.sin
@@ -0,0 +1,23 @@
+# Sed script that inserts the file called HEADER before the header entry.
+#
+# At each occurrence of a line starting with "msgid ", we execute the following
+# commands. At the first occurrence, insert the file. At the following
+# occurrences, do nothing. The distinction between the first and the following
+# occurrences is achieved by looking at the hold space.
+/^msgid /{
+x
+# Test if the hold space is empty.
+s/m/m/
+ta
+# Yes it was empty. First occurrence. Read the file.
+r HEADER
+# Output the file's contents by reading the next line. But don't lose the
+# current line while doing this.
+g
+N
+bb
+:a
+# The hold space was nonempty. Following occurrences. Do nothing.
+x
+:b
+}
diff --git a/third_party/elfutils/po/it.po b/third_party/elfutils/po/it.po
new file mode 100644
index 0000000..61e8ae0
--- /dev/null
+++ b/third_party/elfutils/po/it.po
@@ -0,0 +1,5666 @@
+# translation of elfutils.master.RedHatelfutils.it.po to Italiano
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Francesco Tombolini <tombo@adamantio.net>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: elfutils.master.RedHatelfutils.it\n"
+"Report-Msgid-Bugs-To: http://bugzilla.redhat.com/\n"
+"POT-Creation-Date: 2010-04-21 07:41-0700\n"
+"PO-Revision-Date: 2009-04-30 03:50+0200\n"
+"Last-Translator: Francesco Tombolini <tombo@adamantio.net>\n"
+"Language-Team: Italiano <fedora-trans-it@redhat.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms:  nplurals=2; plural=(n != 1);\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: lib/xmalloc.c:51 lib/xmalloc.c:65 lib/xmalloc.c:79 src/readelf.c:2822
+#: src/readelf.c:3161 src/unstrip.c:2087 src/unstrip.c:2295
+#, c-format
+msgid "memory exhausted"
+msgstr ""
+
+#: libasm/asm_error.c:62 libdw/dwarf_error.c:79 libdwfl/libdwflP.h:70
+#: libelf/elf_error.c:81
+msgid "no error"
+msgstr ""
+
+#: libasm/asm_error.c:63 libdw/dwarf_error.c:88 libdwfl/libdwflP.h:72
+#: libelf/elf_error.c:112
+msgid "out of memory"
+msgstr ""
+
+#: libasm/asm_error.c:64 src/ldgeneric.c:2687
+#, c-format
+msgid "cannot create output file"
+msgstr ""
+
+#: libasm/asm_error.c:65
+msgid "invalid parameter"
+msgstr ""
+
+#: libasm/asm_error.c:66
+msgid "cannot change mode of output file"
+msgstr ""
+
+#: libasm/asm_error.c:67 src/ldgeneric.c:7001
+#, c-format
+msgid "cannot rename output file"
+msgstr ""
+
+#: libasm/asm_error.c:68
+msgid "duplicate symbol"
+msgstr ""
+
+#: libasm/asm_error.c:69
+msgid "invalid section type for operation"
+msgstr ""
+
+#: libasm/asm_error.c:70
+msgid "error during output of data"
+msgstr ""
+
+#: libasm/asm_error.c:71
+msgid "no backend support available"
+msgstr ""
+
+#: libasm/asm_error.c:81 libdw/dwarf_error.c:80 libdwfl/libdwflP.h:71
+#: libelf/elf_error.c:84
+msgid "unknown error"
+msgstr ""
+
+#: libdw/dwarf_error.c:81
+msgid "invalid access"
+msgstr ""
+
+#: libdw/dwarf_error.c:82
+msgid "no regular file"
+msgstr ""
+
+#: libdw/dwarf_error.c:83
+msgid "I/O error"
+msgstr ""
+
+#: libdw/dwarf_error.c:84
+msgid "invalid ELF file"
+msgstr ""
+
+#: libdw/dwarf_error.c:85
+msgid "no DWARF information"
+msgstr ""
+
+#: libdw/dwarf_error.c:86
+msgid "no ELF file"
+msgstr ""
+
+#: libdw/dwarf_error.c:87
+msgid "cannot get ELF header"
+msgstr ""
+
+#: libdw/dwarf_error.c:89
+msgid "not implemented"
+msgstr ""
+
+#: libdw/dwarf_error.c:90 libelf/elf_error.c:128 libelf/elf_error.c:176
+msgid "invalid command"
+msgstr ""
+
+#: libdw/dwarf_error.c:91
+msgid "invalid version"
+msgstr ""
+
+#: libdw/dwarf_error.c:92
+msgid "invalid file"
+msgstr ""
+
+#: libdw/dwarf_error.c:93
+msgid "no entries found"
+msgstr ""
+
+#: libdw/dwarf_error.c:94
+msgid "invalid DWARF"
+msgstr ""
+
+#: libdw/dwarf_error.c:95
+msgid "no string data"
+msgstr ""
+
+#: libdw/dwarf_error.c:96
+msgid "no address value"
+msgstr ""
+
+#: libdw/dwarf_error.c:97
+msgid "no constant value"
+msgstr ""
+
+#: libdw/dwarf_error.c:98
+msgid "no reference value"
+msgstr ""
+
+#: libdw/dwarf_error.c:99
+msgid "invalid reference value"
+msgstr ""
+
+#: libdw/dwarf_error.c:100
+msgid ".debug_line section missing"
+msgstr ""
+
+#: libdw/dwarf_error.c:101
+msgid "invalid .debug_line section"
+msgstr ""
+
+#: libdw/dwarf_error.c:102
+msgid "debug information too big"
+msgstr ""
+
+#: libdw/dwarf_error.c:103
+msgid "invalid DWARF version"
+msgstr ""
+
+#: libdw/dwarf_error.c:104
+msgid "invalid directory index"
+msgstr ""
+
+#: libdw/dwarf_error.c:105 libdwfl/libdwflP.h:91
+msgid "address out of range"
+msgstr ""
+
+#: libdw/dwarf_error.c:106
+msgid "no location list value"
+msgstr ""
+
+#: libdw/dwarf_error.c:107
+msgid "no block data"
+msgstr ""
+
+#: libdw/dwarf_error.c:108
+msgid "invalid line index"
+msgstr ""
+
+#: libdw/dwarf_error.c:109
+msgid "invalid address range index"
+msgstr ""
+
+#: libdw/dwarf_error.c:110 libdwfl/libdwflP.h:92
+msgid "no matching address range"
+msgstr ""
+
+#: libdw/dwarf_error.c:111
+msgid "no flag value"
+msgstr ""
+
+#: libdw/dwarf_error.c:112 libelf/elf_error.c:253
+msgid "invalid offset"
+msgstr ""
+
+#: libdw/dwarf_error.c:113
+msgid ".debug_ranges section missing"
+msgstr ""
+
+#: libdw/dwarf_error.c:114
+msgid "invalid CFI section"
+msgstr ""
+
+#: libdwfl/argp-std.c:67 src/unstrip.c:2237
+msgid "Input selection options:"
+msgstr ""
+
+#: libdwfl/argp-std.c:68
+msgid "Find addresses in FILE"
+msgstr ""
+
+#: libdwfl/argp-std.c:70
+msgid "Find addresses from signatures found in COREFILE"
+msgstr ""
+
+#: libdwfl/argp-std.c:72
+msgid "Find addresses in files mapped into process PID"
+msgstr ""
+
+#: libdwfl/argp-std.c:74
+msgid ""
+"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps "
+"format"
+msgstr ""
+
+#: libdwfl/argp-std.c:76
+msgid "Find addresses in the running kernel"
+msgstr ""
+
+#: libdwfl/argp-std.c:78
+msgid "Kernel with all modules"
+msgstr ""
+
+#: libdwfl/argp-std.c:80
+msgid "Search path for separate debuginfo files"
+msgstr ""
+
+#: libdwfl/argp-std.c:163
+msgid "only one of -e, -p, -k, -K, or --core allowed"
+msgstr ""
+
+#: libdwfl/argp-std.c:223
+#, c-format
+msgid "cannot read ELF core file: %s"
+msgstr ""
+
+#: libdwfl/argp-std.c:241
+msgid "No modules recognized in core file"
+msgstr ""
+
+#: libdwfl/argp-std.c:253
+msgid "cannot load kernel symbols"
+msgstr ""
+
+#: libdwfl/argp-std.c:257
+msgid "cannot find kernel modules"
+msgstr ""
+
+#: libdwfl/argp-std.c:271
+msgid "cannot find kernel or modules"
+msgstr ""
+
+#: libdwfl/libdwflP.h:73
+msgid "See errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:74
+msgid "See elf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:75
+msgid "See dwarf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:76
+msgid "See ebl_errno (XXX missing)"
+msgstr ""
+
+#: libdwfl/libdwflP.h:77
+msgid "gzip decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:78
+msgid "bzip2 decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:79
+msgid "LZMA decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:80
+msgid "no support library found for machine"
+msgstr ""
+
+#: libdwfl/libdwflP.h:81
+msgid "Callbacks missing for ET_REL file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:82
+msgid "Unsupported relocation type"
+msgstr ""
+
+#: libdwfl/libdwflP.h:83
+msgid "r_offset is bogus"
+msgstr ""
+
+#: libdwfl/libdwflP.h:84 libelf/elf_error.c:132 libelf/elf_error.c:192
+msgid "offset out of range"
+msgstr ""
+
+#: libdwfl/libdwflP.h:85
+msgid "relocation refers to undefined symbol"
+msgstr ""
+
+#: libdwfl/libdwflP.h:86
+msgid "Callback returned failure"
+msgstr ""
+
+#: libdwfl/libdwflP.h:87
+msgid "No DWARF information found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:88
+msgid "No symbol table found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:89
+msgid "No ELF program headers"
+msgstr ""
+
+#: libdwfl/libdwflP.h:90
+msgid "address range overlaps an existing module"
+msgstr ""
+
+#: libdwfl/libdwflP.h:93
+msgid "image truncated"
+msgstr ""
+
+#: libdwfl/libdwflP.h:94
+msgid "ELF file opened"
+msgstr ""
+
+#: libdwfl/libdwflP.h:95
+msgid "not a valid ELF file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:96
+msgid "cannot handle DWARF type description"
+msgstr ""
+
+#: libebl/eblbackendname.c:63
+msgid "No backend"
+msgstr ""
+
+#: libebl/eblcorenotetypename.c:107 libebl/eblobjecttypename.c:78
+#: libebl/eblobjnotetypename.c:86 libebl/eblosabiname.c:98
+#: libebl/eblsectionname.c:110 libebl/eblsectiontypename.c:140
+#: libebl/eblsegmenttypename.c:104
+msgid "<unknown>"
+msgstr ""
+
+#: libebl/ebldynamictagname.c:126
+#, c-format
+msgid "<unknown>: %#<PRIx64>"
+msgstr ""
+
+#: libebl/eblobjnote.c:76
+#, c-format
+msgid "    Build ID: "
+msgstr ""
+
+#: libebl/eblobjnote.c:87
+#, c-format
+msgid "    Linker version: %.*s\n"
+msgstr ""
+
+#: libebl/eblobjnote.c:136
+#, c-format
+msgid "    OS: %s, ABI: "
+msgstr ""
+
+#: libebl/eblosabiname.c:95
+msgid "Stand alone"
+msgstr ""
+
+#: libebl/eblsymbolbindingname.c:92 libebl/eblsymboltypename.c:98
+#, c-format
+msgid "<unknown>: %d"
+msgstr ""
+
+#: libelf/elf_error.c:88
+msgid "unknown version"
+msgstr ""
+
+#: libelf/elf_error.c:92
+msgid "unknown type"
+msgstr ""
+
+#: libelf/elf_error.c:96
+msgid "invalid `Elf' handle"
+msgstr ""
+
+#: libelf/elf_error.c:100
+msgid "invalid size of source operand"
+msgstr ""
+
+#: libelf/elf_error.c:104
+msgid "invalid size of destination operand"
+msgstr ""
+
+#: libelf/elf_error.c:108 src/readelf.c:4779
+#, c-format
+msgid "invalid encoding"
+msgstr ""
+
+#: libelf/elf_error.c:116
+msgid "invalid file descriptor"
+msgstr ""
+
+#: libelf/elf_error.c:120
+msgid "invalid operation"
+msgstr ""
+
+#: libelf/elf_error.c:124
+msgid "ELF version not set"
+msgstr ""
+
+#: libelf/elf_error.c:136
+msgid "invalid fmag field in archive header"
+msgstr ""
+
+#: libelf/elf_error.c:140
+msgid "invalid archive file"
+msgstr ""
+
+#: libelf/elf_error.c:144
+msgid "descriptor is not for an archive"
+msgstr ""
+
+#: libelf/elf_error.c:148
+msgid "no index available"
+msgstr ""
+
+#: libelf/elf_error.c:152
+msgid "cannot read data from file"
+msgstr ""
+
+#: libelf/elf_error.c:156
+msgid "cannot write data to file"
+msgstr ""
+
+#: libelf/elf_error.c:160
+msgid "invalid binary class"
+msgstr ""
+
+#: libelf/elf_error.c:164
+msgid "invalid section index"
+msgstr ""
+
+#: libelf/elf_error.c:168
+msgid "invalid operand"
+msgstr ""
+
+#: libelf/elf_error.c:172
+msgid "invalid section"
+msgstr ""
+
+#: libelf/elf_error.c:180
+msgid "executable header not created first"
+msgstr ""
+
+#: libelf/elf_error.c:184
+msgid "file descriptor disabled"
+msgstr ""
+
+#: libelf/elf_error.c:188
+msgid "archive/member file descriptor mismatch"
+msgstr ""
+
+#: libelf/elf_error.c:196
+msgid "cannot manipulate null section"
+msgstr ""
+
+#: libelf/elf_error.c:200
+msgid "data/scn mismatch"
+msgstr ""
+
+#: libelf/elf_error.c:204
+msgid "invalid section header"
+msgstr ""
+
+#: libelf/elf_error.c:208 src/readelf.c:6242 src/readelf.c:6343
+#, c-format
+msgid "invalid data"
+msgstr ""
+
+#: libelf/elf_error.c:212
+msgid "unknown data encoding"
+msgstr ""
+
+#: libelf/elf_error.c:216
+msgid "section `sh_size' too small for data"
+msgstr ""
+
+#: libelf/elf_error.c:220
+msgid "invalid section alignment"
+msgstr ""
+
+#: libelf/elf_error.c:224
+msgid "invalid section entry size"
+msgstr ""
+
+#: libelf/elf_error.c:228
+msgid "update() for write on read-only file"
+msgstr ""
+
+#: libelf/elf_error.c:232
+msgid "no such file"
+msgstr ""
+
+#: libelf/elf_error.c:236
+msgid "only relocatable files can contain section groups"
+msgstr ""
+
+#: libelf/elf_error.c:241
+msgid ""
+"program header only allowed in executables, shared objects, and core files"
+msgstr ""
+
+#: libelf/elf_error.c:248
+msgid "file has no program header"
+msgstr ""
+
+#: src/addr2line.c:66
+msgid "Output selection options:"
+msgstr ""
+
+#: src/addr2line.c:67
+msgid "Show only base names of source files"
+msgstr ""
+
+#: src/addr2line.c:69
+msgid "Show absolute file names using compilation directory"
+msgstr ""
+
+#: src/addr2line.c:70
+msgid "Also show function names"
+msgstr ""
+
+#: src/addr2line.c:71
+msgid "Also show symbol or section names"
+msgstr ""
+
+#: src/addr2line.c:73
+msgid "Treat addresses as offsets relative to NAME section."
+msgstr ""
+
+#: src/addr2line.c:75 src/elfcmp.c:75 src/findtextrel.c:75 src/nm.c:103
+#: src/strings.c:83
+msgid "Miscellaneous:"
+msgstr ""
+
+#: src/addr2line.c:84
+msgid ""
+"Locate source files and line information for ADDRs (in a.out by default)."
+msgstr ""
+
+#: src/addr2line.c:88
+msgid "[ADDR...]"
+msgstr ""
+
+#: src/addr2line.c:185 src/ar.c:289 src/elfcmp.c:555 src/elflint.c:239
+#: src/findtextrel.c:170 src/ld.c:957 src/nm.c:253 src/objdump.c:181
+#: src/ranlib.c:136 src/readelf.c:449 src/size.c:219 src/strings.c:227
+#: src/strip.c:204 src/unstrip.c:234
+#, c-format
+msgid ""
+"Copyright (C) %s Red Hat, Inc.\n"
+"This is free software; see the source for copying conditions.  There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+
+#: src/addr2line.c:190 src/ar.c:294 src/elfcmp.c:560 src/elflint.c:244
+#: src/findtextrel.c:175 src/ld.c:962 src/nm.c:258 src/objdump.c:186
+#: src/ranlib.c:141 src/readelf.c:454 src/size.c:224 src/strings.c:232
+#: src/strip.c:209 src/unstrip.c:239
+#, c-format
+msgid "Written by %s.\n"
+msgstr ""
+
+#: src/addr2line.c:405
+#, c-format
+msgid "Section syntax requires exactly one module"
+msgstr ""
+
+#: src/addr2line.c:428
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside section '%s'"
+msgstr ""
+
+#: src/addr2line.c:461
+#, c-format
+msgid "cannot find symbol '%s'"
+msgstr ""
+
+#: src/addr2line.c:466
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside contents of '%s'"
+msgstr ""
+
+#: src/ar.c:76
+msgid "Commands:"
+msgstr ""
+
+#: src/ar.c:77
+msgid "Delete files from archive."
+msgstr ""
+
+#: src/ar.c:78
+msgid "Move files in archive."
+msgstr ""
+
+#: src/ar.c:79
+msgid "Print files in archive."
+msgstr ""
+
+#: src/ar.c:80
+msgid "Quick append files to archive."
+msgstr ""
+
+#: src/ar.c:82
+msgid "Replace existing or insert new file into archive."
+msgstr ""
+
+#: src/ar.c:83
+msgid "Display content of archive."
+msgstr ""
+
+#: src/ar.c:84
+msgid "Extract files from archive."
+msgstr ""
+
+#: src/ar.c:86
+msgid "Command Modifiers:"
+msgstr ""
+
+#: src/ar.c:87
+msgid "Preserve original dates."
+msgstr ""
+
+#: src/ar.c:88
+msgid "Use instance [COUNT] of name."
+msgstr ""
+
+#: src/ar.c:90
+msgid "Do not replace existing files with extracted files."
+msgstr ""
+
+#: src/ar.c:91
+msgid "Allow filename to be truncated if necessary."
+msgstr ""
+
+#: src/ar.c:93
+msgid "Provide verbose output."
+msgstr ""
+
+#: src/ar.c:94
+msgid "Force regeneration of symbol table."
+msgstr ""
+
+#: src/ar.c:95
+msgid "Insert file after [MEMBER]."
+msgstr ""
+
+#: src/ar.c:96
+msgid "Insert file before [MEMBER]."
+msgstr ""
+
+#: src/ar.c:97
+msgid "Same as -b."
+msgstr ""
+
+#: src/ar.c:98
+msgid "Suppress message when library has to be created."
+msgstr ""
+
+#: src/ar.c:100
+msgid "Use full path for file matching."
+msgstr ""
+
+#: src/ar.c:101
+msgid "Update only older files in archive."
+msgstr ""
+
+#: src/ar.c:107
+msgid "Create, modify, and extract from archives."
+msgstr ""
+
+#: src/ar.c:110
+msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]"
+msgstr ""
+
+#: src/ar.c:192
+#, c-format
+msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options"
+msgstr ""
+
+#: src/ar.c:197
+#, c-format
+msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers"
+msgstr ""
+
+#: src/ar.c:213
+#, c-format
+msgid "'N' is only meaningful with the 'x' and 'd' options"
+msgstr ""
+
+#: src/ar.c:218
+#, c-format
+msgid "COUNT parameter required"
+msgstr ""
+
+#: src/ar.c:230
+#, c-format
+msgid "invalid COUNT parameter %s"
+msgstr ""
+
+#: src/ar.c:237
+#, c-format
+msgid "'%c' is only meaningful with the 'x' option"
+msgstr ""
+
+#: src/ar.c:243
+#, c-format
+msgid "archive name required"
+msgstr ""
+
+#: src/ar.c:314
+#, c-format
+msgid "More than one operation specified"
+msgstr ""
+
+#: src/ar.c:404
+#, c-format
+msgid "cannot open archive '%s'"
+msgstr ""
+
+#: src/ar.c:414
+#, c-format
+msgid "cannot open archive '%s': %s"
+msgstr ""
+
+#: src/ar.c:418
+#, c-format
+msgid "%s: not an archive file"
+msgstr ""
+
+#: src/ar.c:422
+#, c-format
+msgid "cannot stat archive '%s'"
+msgstr ""
+
+#: src/ar.c:434
+#, c-format
+msgid "no entry %s in archive\n"
+msgstr ""
+
+#: src/ar.c:487 src/ar.c:929 src/ar.c:1129
+#, c-format
+msgid "cannot create hash table"
+msgstr ""
+
+#: src/ar.c:494 src/ar.c:936 src/ar.c:1138
+#, c-format
+msgid "cannot insert into hash table"
+msgstr ""
+
+#: src/ar.c:502 src/ranlib.c:176
+#, c-format
+msgid "cannot stat '%s'"
+msgstr ""
+
+#: src/ar.c:598
+#, c-format
+msgid "cannot read content of %s: %s"
+msgstr ""
+
+#: src/ar.c:641
+#, c-format
+msgid "cannot open %.*s"
+msgstr ""
+
+#: src/ar.c:663
+#, c-format
+msgid "failed to write %s"
+msgstr ""
+
+#: src/ar.c:675
+#, c-format
+msgid "cannot change mode of %s"
+msgstr ""
+
+#: src/ar.c:691
+#, c-format
+msgid "cannot change modification time of %s"
+msgstr ""
+
+#: src/ar.c:737
+#, c-format
+msgid "cannot rename temporary file to %.*s"
+msgstr ""
+
+#: src/ar.c:773 src/ar.c:1021 src/ar.c:1419 src/ranlib.c:250
+#, c-format
+msgid "cannot create new file"
+msgstr ""
+
+#: src/ar.c:1220
+#, c-format
+msgid "position member %s not found"
+msgstr ""
+
+#: src/ar.c:1230
+#, c-format
+msgid "%s: no entry %s in archive!\n"
+msgstr ""
+
+#: src/ar.c:1259 src/ldgeneric.c:519 src/objdump.c:257
+#, c-format
+msgid "cannot open %s"
+msgstr ""
+
+#: src/ar.c:1264
+#, c-format
+msgid "cannot stat %s"
+msgstr ""
+
+#: src/ar.c:1270
+#, c-format
+msgid "%s is no regular file"
+msgstr ""
+
+#: src/ar.c:1283
+#, c-format
+msgid "cannot get ELF descriptor for %s: %s\n"
+msgstr ""
+
+#: src/ar.c:1302
+#, c-format
+msgid "cannot read %s: %s"
+msgstr ""
+
+#: src/arlib.c:215
+#, c-format
+msgid "the archive '%s' is too large"
+msgstr ""
+
+#: src/arlib.c:228
+#, c-format
+msgid "cannot read ELF header of %s(%s): %s"
+msgstr ""
+
+#: src/elfcmp.c:69
+msgid "Control options:"
+msgstr ""
+
+#: src/elfcmp.c:70
+msgid ""
+"Control treatment of gaps in loadable segments [ignore|match] (default: "
+"ignore)"
+msgstr ""
+
+#: src/elfcmp.c:72
+msgid "Ignore permutation of buckets in SHT_HASH section"
+msgstr ""
+
+#: src/elfcmp.c:73
+msgid "Output nothing; yield exit status only"
+msgstr ""
+
+#: src/elfcmp.c:80
+msgid "Compare relevant parts of two ELF files for equality."
+msgstr ""
+
+#: src/elfcmp.c:84
+msgid "FILE1 FILE2"
+msgstr ""
+
+#: src/elfcmp.c:140
+msgid "Invalid number of parameters.\n"
+msgstr ""
+
+#: src/elfcmp.c:168 src/elfcmp.c:173
+#, c-format
+msgid "cannot get ELF header of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:190
+#, c-format
+msgid "%s %s diff: ELF header"
+msgstr ""
+
+#: src/elfcmp.c:198 src/elfcmp.c:201
+#, c-format
+msgid "cannot get section count of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:206
+#, c-format
+msgid "%s %s diff: section count"
+msgstr ""
+
+#: src/elfcmp.c:214 src/elfcmp.c:217
+#, c-format
+msgid "cannot get program header count of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:222
+#, c-format
+msgid "%s %s diff: program header count"
+msgstr ""
+
+#: src/elfcmp.c:281
+#, c-format
+msgid "%s %s differ: section header"
+msgstr ""
+
+#: src/elfcmp.c:309 src/elfcmp.c:315
+#, c-format
+msgid "cannot get content of section %zu in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:331 src/elfcmp.c:337
+#, c-format
+msgid "cannot get symbol in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:358
+#, c-format
+msgid "%s %s differ: symbol table [%zu]"
+msgstr ""
+
+#: src/elfcmp.c:361
+#, c-format
+msgid "%s %s differ: symbol table [%zu,%zu]"
+msgstr ""
+
+#: src/elfcmp.c:409
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:413
+#, c-format
+msgid "%s %s differ: section [%zu,%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:429
+#, c-format
+msgid "%s %s differ: unequal amount of important sections"
+msgstr ""
+
+#: src/elfcmp.c:463 src/elfcmp.c:468
+#, c-format
+msgid "cannot load data of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:487 src/elfcmp.c:493
+#, c-format
+msgid "cannot get program header entry %d of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:499
+#, c-format
+msgid "%s %s differ: program header %d"
+msgstr ""
+
+#: src/elfcmp.c:524
+#, c-format
+msgid "%s %s differ: gap"
+msgstr ""
+
+#: src/elfcmp.c:583
+#, c-format
+msgid "Invalid value '%s' for --gaps parameter."
+msgstr ""
+
+#: src/elfcmp.c:607 src/findtextrel.c:229 src/ldgeneric.c:1767
+#: src/ldgeneric.c:4257 src/nm.c:363 src/ranlib.c:169 src/size.c:301
+#: src/strings.c:183 src/strip.c:433 src/strip.c:468 src/unstrip.c:1900
+#: src/unstrip.c:1929
+#, c-format
+msgid "cannot open '%s'"
+msgstr ""
+
+#: src/elfcmp.c:611 src/findtextrel.c:236 src/ranlib.c:186
+#, c-format
+msgid "cannot create ELF descriptor for '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:616
+#, c-format
+msgid "cannot create EBL descriptor for '%s'"
+msgstr ""
+
+#: src/elfcmp.c:634
+#, c-format
+msgid "cannot get section header of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:644
+#, c-format
+msgid "cannot get content of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:654 src/elfcmp.c:668
+#, c-format
+msgid "cannot get relocation: %s"
+msgstr ""
+
+#: src/elflint.c:72
+msgid "Be extremely strict, flag level 2 features."
+msgstr ""
+
+#: src/elflint.c:73
+msgid "Do not print anything if successful"
+msgstr ""
+
+#: src/elflint.c:74
+msgid "Binary is a separate debuginfo file"
+msgstr ""
+
+#: src/elflint.c:76
+msgid ""
+"Binary has been created with GNU ld and is therefore known to be broken in "
+"certain ways"
+msgstr ""
+
+#: src/elflint.c:82
+msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
+msgstr ""
+
+#: src/elflint.c:86 src/readelf.c:118
+msgid "FILE..."
+msgstr ""
+
+#: src/elflint.c:159 src/readelf.c:272
+#, c-format
+msgid "cannot open input file"
+msgstr ""
+
+#: src/elflint.c:166
+#, c-format
+msgid "cannot generate Elf descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:185
+#, c-format
+msgid "error while closing Elf descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:189
+msgid "No errors"
+msgstr ""
+
+#: src/elflint.c:223 src/readelf.c:425
+msgid "Missing file name.\n"
+msgstr ""
+
+#: src/elflint.c:302
+#, c-format
+msgid " error while freeing sub-ELF descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:310
+#, c-format
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr ""
+
+#: src/elflint.c:370
+#, c-format
+msgid "e_ident[%d] == %d is no known class\n"
+msgstr ""
+
+#: src/elflint.c:375
+#, c-format
+msgid "e_ident[%d] == %d is no known data encoding\n"
+msgstr ""
+
+#: src/elflint.c:379
+#, c-format
+msgid "unknown ELF header version number e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:385
+#, c-format
+msgid "unsupported OS ABI e_ident[%d] == '%s'\n"
+msgstr ""
+
+#: src/elflint.c:391
+#, c-format
+msgid "unsupport ABI version e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:396
+#, c-format
+msgid "e_ident[%zu] is not zero\n"
+msgstr ""
+
+#: src/elflint.c:401
+#, c-format
+msgid "unknown object file type %d\n"
+msgstr ""
+
+#: src/elflint.c:408
+#, c-format
+msgid "unknown machine type %d\n"
+msgstr ""
+
+#: src/elflint.c:412
+#, c-format
+msgid "unknown object file version\n"
+msgstr ""
+
+#: src/elflint.c:418
+#, c-format
+msgid "invalid program header offset\n"
+msgstr ""
+
+#: src/elflint.c:420
+#, c-format
+msgid "executables and DSOs cannot have zero program header offset\n"
+msgstr ""
+
+#: src/elflint.c:424
+#, c-format
+msgid "invalid number of program header entries\n"
+msgstr ""
+
+#: src/elflint.c:432
+#, c-format
+msgid "invalid section header table offset\n"
+msgstr ""
+
+#: src/elflint.c:435
+#, c-format
+msgid "section header table must be present\n"
+msgstr ""
+
+#: src/elflint.c:449
+#, c-format
+msgid "invalid number of section header table entries\n"
+msgstr ""
+
+#: src/elflint.c:466
+#, c-format
+msgid "invalid section header index\n"
+msgstr ""
+
+#: src/elflint.c:480
+#, c-format
+msgid "invalid number of program header table entries\n"
+msgstr ""
+
+#: src/elflint.c:489
+#, c-format
+msgid "invalid machine flags: %s\n"
+msgstr ""
+
+#: src/elflint.c:496 src/elflint.c:513
+#, c-format
+msgid "invalid ELF header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:499 src/elflint.c:516
+#, c-format
+msgid "invalid program header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:502 src/elflint.c:519
+#, c-format
+msgid "invalid program header position or size\n"
+msgstr ""
+
+#: src/elflint.c:505 src/elflint.c:522
+#, c-format
+msgid "invalid section header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:508 src/elflint.c:525
+#, c-format
+msgid "invalid section header position or size\n"
+msgstr ""
+
+#: src/elflint.c:569
+#, c-format
+msgid ""
+"section [%2d] '%s': section with SHF_GROUP flag set not part of a section "
+"group\n"
+msgstr ""
+
+#: src/elflint.c:573
+#, c-format
+msgid ""
+"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"
+msgstr ""
+
+#: src/elflint.c:589 src/elflint.c:1432 src/elflint.c:1482 src/elflint.c:1591
+#: src/elflint.c:2185 src/elflint.c:2699 src/elflint.c:2860 src/elflint.c:2990
+#: src/elflint.c:3162 src/elflint.c:4062
+#, c-format
+msgid "section [%2d] '%s': cannot get section data\n"
+msgstr ""
+
+#: src/elflint.c:602 src/elflint.c:1598
+#, c-format
+msgid ""
+"section [%2d] '%s': referenced as string table for section [%2d] '%s' but "
+"type is not SHT_STRTAB\n"
+msgstr ""
+
+#: src/elflint.c:625
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol table cannot have more than one extended index "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:636
+#, c-format
+msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n"
+msgstr ""
+
+#: src/elflint.c:645
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:650 src/elflint.c:653 src/elflint.c:656 src/elflint.c:659
+#: src/elflint.c:662 src/elflint.c:665
+#, c-format
+msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:668
+#, c-format
+msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:678
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:687
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid name value\n"
+msgstr ""
+
+#: src/elflint.c:700
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: too large section index but no extended "
+"section index section\n"
+msgstr ""
+
+#: src/elflint.c:706
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in "
+"st_shndx (%<PRIu32>)\n"
+msgstr ""
+
+#: src/elflint.c:718
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid section index\n"
+msgstr ""
+
+#: src/elflint.c:726
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown type\n"
+msgstr ""
+
+#: src/elflint.c:732
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown symbol binding\n"
+msgstr ""
+
+#: src/elflint.c:737
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unique symbol not of object type\n"
+msgstr ""
+
+#: src/elflint.c:745
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"
+msgstr ""
+
+#: src/elflint.c:749
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"
+msgstr ""
+
+#: src/elflint.c:753
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"
+msgstr ""
+
+#: src/elflint.c:785
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: st_value out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:791 src/elflint.c:816 src/elflint.c:859
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu does not fit completely in referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:800
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have "
+"SHF_TLS flag set\n"
+msgstr ""
+
+#: src/elflint.c:810 src/elflint.c:852
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:837
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"
+msgstr ""
+
+#: src/elflint.c:845
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:872
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:879
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: non-local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:886
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: non-local section symbol\n"
+msgstr ""
+
+#: src/elflint.c:936
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section [%"
+"2d]\n"
+msgstr ""
+
+#: src/elflint.c:943
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:959
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#<PRIx64> does not "
+"match %s section address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:966
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %<PRIu64> does not "
+"match %s section size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:974
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:990
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC_ symbol value %#<PRIx64> does not match dynamic "
+"segment address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:997
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC symbol size %<PRIu64> does not match dynamic "
+"segment size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:1010
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-"
+"default visibility\n"
+msgstr ""
+
+#: src/elflint.c:1014
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"
+msgstr ""
+
+#: src/elflint.c:1059
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"
+msgstr ""
+
+#: src/elflint.c:1068 src/elflint.c:1120
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"
+msgstr ""
+
+#: src/elflint.c:1093 src/elflint.c:1145
+#, c-format
+msgid ""
+"section [%2d] '%s': relative relocations after index %d as specified by "
+"DT_RELCOUNT\n"
+msgstr ""
+
+#: src/elflint.c:1099 src/elflint.c:1151
+#, c-format
+msgid ""
+"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT "
+"specified %d relative relocations\n"
+msgstr ""
+
+#: src/elflint.c:1111
+#, c-format
+msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n"
+msgstr ""
+
+#: src/elflint.c:1193
+#, c-format
+msgid "section [%2d] '%s': invalid destination section index\n"
+msgstr ""
+
+#: src/elflint.c:1206
+#, c-format
+msgid "section [%2d] '%s': invalid destination section type\n"
+msgstr ""
+
+#: src/elflint.c:1214
+#, c-format
+msgid "section [%2d] '%s': sh_info should be zero\n"
+msgstr ""
+
+#: src/elflint.c:1221
+#, c-format
+msgid "section [%2d] '%s': no relocations for merge-able sections possible\n"
+msgstr ""
+
+#: src/elflint.c:1228
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n"
+msgstr ""
+
+#: src/elflint.c:1288
+#, c-format
+msgid "text relocation flag set but there is no read-only segment\n"
+msgstr ""
+
+#: src/elflint.c:1315
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid type\n"
+msgstr ""
+
+#: src/elflint.c:1323
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: relocation type invalid for the file "
+"type\n"
+msgstr ""
+
+#: src/elflint.c:1331
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n"
+msgstr ""
+
+#: src/elflint.c:1349
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can "
+"be used with %s\n"
+msgstr ""
+
+#: src/elflint.c:1366
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:1381
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: copy relocation against symbol of type %"
+"s\n"
+msgstr ""
+
+#: src/elflint.c:1402
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: read-only section modified but text "
+"relocation flag not set\n"
+msgstr ""
+
+#: src/elflint.c:1417
+#, c-format
+msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n"
+msgstr ""
+
+#: src/elflint.c:1456 src/elflint.c:1506
+#, c-format
+msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1586
+#, c-format
+msgid "more than one dynamic section present\n"
+msgstr ""
+
+#: src/elflint.c:1604
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"
+msgstr ""
+
+#: src/elflint.c:1609 src/elflint.c:1901
+#, c-format
+msgid "section [%2d] '%s': sh_info not zero\n"
+msgstr ""
+
+#: src/elflint.c:1619
+#, c-format
+msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1627
+#, c-format
+msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"
+msgstr ""
+
+#: src/elflint.c:1634
+#, c-format
+msgid "section [%2d] '%s': entry %zu: unknown tag\n"
+msgstr ""
+
+#: src/elflint.c:1645
+#, c-format
+msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n"
+msgstr ""
+
+#: src/elflint.c:1655
+#, c-format
+msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n"
+msgstr ""
+
+#: src/elflint.c:1673
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"
+msgstr ""
+
+#: src/elflint.c:1695
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: pointer does not match address of section [%"
+"2d] '%s' referenced by sh_link\n"
+msgstr ""
+
+#: src/elflint.c:1738
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:1753
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must be valid offset in section [%"
+"2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:1773 src/elflint.c:1801
+#, c-format
+msgid "section [%2d] '%s': contains %s entry but not %s\n"
+msgstr ""
+
+#: src/elflint.c:1785
+#, c-format
+msgid "section [%2d] '%s': mandatory tag %s not present\n"
+msgstr ""
+
+#: src/elflint.c:1794
+#, c-format
+msgid "section [%2d] '%s': no hash section present\n"
+msgstr ""
+
+#: src/elflint.c:1809 src/elflint.c:1816
+#, c-format
+msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n"
+msgstr ""
+
+#: src/elflint.c:1826 src/elflint.c:1830
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"
+msgstr ""
+
+#: src/elflint.c:1836
+#, c-format
+msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n"
+msgstr ""
+
+#: src/elflint.c:1847 src/elflint.c:1851 src/elflint.c:1855 src/elflint.c:1859
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in prelinked executable\n"
+msgstr ""
+
+#: src/elflint.c:1871
+#, c-format
+msgid ""
+"section [%2d] '%s': only relocatable files can have extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1881
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index section not for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1886
+#, c-format
+msgid "cannot get data for symbol section\n"
+msgstr ""
+
+#: src/elflint.c:1889
+#, c-format
+msgid "section [%2d] '%s': entry size does not match Elf32_Word\n"
+msgstr ""
+
+#: src/elflint.c:1896
+#, c-format
+msgid "section [%2d] '%s': extended index table too small for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1911
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to "
+"same symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1922
+#, c-format
+msgid "symbol 0 should have zero extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1934
+#, c-format
+msgid "cannot get data for symbol %zu\n"
+msgstr ""
+
+#: src/elflint.c:1939
+#, c-format
+msgid "extended section index is %<PRIu32> but symbol index is not XINDEX\n"
+msgstr ""
+
+#: src/elflint.c:1955 src/elflint.c:1996
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"
+msgstr ""
+
+#: src/elflint.c:1967 src/elflint.c:2008
+#, c-format
+msgid "section [%2d] '%s': chain array too large\n"
+msgstr ""
+
+#: src/elflint.c:1976 src/elflint.c:2017
+#, c-format
+msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:1982
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2023
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %<PRIu64> out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2038
+#, c-format
+msgid "section [%2d] '%s': bitmask size not power of 2: %u\n"
+msgstr ""
+
+#: src/elflint.c:2049
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected at "
+"least%ld)\n"
+msgstr ""
+
+#: src/elflint.c:2057
+#, c-format
+msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n"
+msgstr ""
+
+#: src/elflint.c:2089
+#, c-format
+msgid ""
+"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"
+msgstr ""
+
+#: src/elflint.c:2110
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is "
+"undefined\n"
+msgstr ""
+
+#: src/elflint.c:2121
+#, c-format
+msgid ""
+"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+
+#: src/elflint.c:2152
+#, c-format
+msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2157
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2163
+#, c-format
+msgid "section [%2d] '%s': bitmask does not match names in the hash table\n"
+msgstr ""
+
+#: src/elflint.c:2176
+#, c-format
+msgid "section [%2d] '%s': relocatable files cannot have hash tables\n"
+msgstr ""
+
+#: src/elflint.c:2194
+#, c-format
+msgid "section [%2d] '%s': hash table not for dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2202
+#, c-format
+msgid "section [%2d] '%s': hash table entry size incorrect\n"
+msgstr ""
+
+#: src/elflint.c:2207
+#, c-format
+msgid "section [%2d] '%s': not marked to be allocated\n"
+msgstr ""
+
+#: src/elflint.c:2212
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table has not even room for initial administrative "
+"entries\n"
+msgstr ""
+
+#: src/elflint.c:2260
+#, c-format
+msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"
+msgstr ""
+
+#: src/elflint.c:2338 src/elflint.c:2342
+#, c-format
+msgid "section [%2zu] '%s': reference to symbol index 0\n"
+msgstr ""
+
+#: src/elflint.c:2349
+#, c-format
+msgid ""
+"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2361
+#, c-format
+msgid ""
+"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2377
+#, c-format
+msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n"
+msgstr ""
+
+#: src/elflint.c:2397
+#, c-format
+msgid ""
+"section [%2d] '%s': section groups only allowed in relocatable object files\n"
+msgstr ""
+
+#: src/elflint.c:2408
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol table: %s\n"
+msgstr ""
+
+#: src/elflint.c:2413
+#, c-format
+msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2419
+#, c-format
+msgid "section [%2d] '%s': invalid symbol index in sh_info\n"
+msgstr ""
+
+#: src/elflint.c:2424
+#, c-format
+msgid "section [%2d] '%s': sh_flags not zero\n"
+msgstr ""
+
+#: src/elflint.c:2431
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol for signature\n"
+msgstr ""
+
+#: src/elflint.c:2436
+#, c-format
+msgid "section [%2d] '%s': signature symbol cannot be empty string\n"
+msgstr ""
+
+#: src/elflint.c:2442
+#, c-format
+msgid "section [%2d] '%s': sh_flags not set correctly\n"
+msgstr ""
+
+#: src/elflint.c:2448
+#, c-format
+msgid "section [%2d] '%s': cannot get data: %s\n"
+msgstr ""
+
+#: src/elflint.c:2457
+#, c-format
+msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"
+msgstr ""
+
+#: src/elflint.c:2462
+#, c-format
+msgid "section [%2d] '%s': section group without flags word\n"
+msgstr ""
+
+#: src/elflint.c:2468
+#, c-format
+msgid "section [%2d] '%s': section group without member\n"
+msgstr ""
+
+#: src/elflint.c:2472
+#, c-format
+msgid "section [%2d] '%s': section group with only one member\n"
+msgstr ""
+
+#: src/elflint.c:2483
+#, c-format
+msgid "section [%2d] '%s': unknown section group flags\n"
+msgstr ""
+
+#: src/elflint.c:2495
+#, c-format
+msgid "section [%2d] '%s': section index %Zu out of range\n"
+msgstr ""
+
+#: src/elflint.c:2504
+#, c-format
+msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:2511
+#, c-format
+msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2517
+#, c-format
+msgid ""
+"section [%2d] '%s': element %Zu references section [%2d] '%s' without "
+"SHF_GROUP flag set\n"
+msgstr ""
+
+#: src/elflint.c:2524
+#, c-format
+msgid "section [%2d] '%s' is contained in more than one section group\n"
+msgstr ""
+
+#: src/elflint.c:2713
+#, c-format
+msgid ""
+"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no "
+"dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2724
+#, c-format
+msgid ""
+"section [%2d] '%s' has different number of entries than symbol table [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:2740
+#, c-format
+msgid "section [%2d] '%s': symbol %d: cannot read version data\n"
+msgstr ""
+
+#: src/elflint.c:2756
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n"
+msgstr ""
+
+#: src/elflint.c:2764
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with version\n"
+msgstr ""
+
+#: src/elflint.c:2778
+#, c-format
+msgid "section [%2d] '%s': symbol %d: invalid version index %d\n"
+msgstr ""
+
+#: src/elflint.c:2783
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for defined version\n"
+msgstr ""
+
+#: src/elflint.c:2793
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for requested version\n"
+msgstr ""
+
+#: src/elflint.c:2845
+#, c-format
+msgid "more than one version reference section present\n"
+msgstr ""
+
+#: src/elflint.c:2853 src/elflint.c:2982
+#, c-format
+msgid "section [%2d] '%s': sh_link does not link to string table\n"
+msgstr ""
+
+#: src/elflint.c:2876 src/elflint.c:3034
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong version %d\n"
+msgstr ""
+
+#: src/elflint.c:2882 src/elflint.c:3040
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:2890
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid file reference\n"
+msgstr ""
+
+#: src/elflint.c:2898
+#, c-format
+msgid "section [%2d] '%s': entry %d references unknown dependency\n"
+msgstr ""
+
+#: src/elflint.c:2910
+#, c-format
+msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:2917
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name "
+"reference\n"
+msgstr ""
+
+#: src/elflint.c:2924
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %"
+"#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:2934
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version "
+"name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2945
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"
+msgstr ""
+
+#: src/elflint.c:2961 src/elflint.c:3119
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n"
+msgstr ""
+
+#: src/elflint.c:2974
+#, c-format
+msgid "more than one version definition section present\n"
+msgstr ""
+
+#: src/elflint.c:3019
+#, c-format
+msgid "section [%2d] '%s': more than one BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3023
+#, c-format
+msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"
+msgstr ""
+
+#: src/elflint.c:3029
+#, c-format
+msgid "section [%2d] '%s': entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:3053
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid name reference\n"
+msgstr ""
+
+#: src/elflint.c:3060
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:3069
+#, c-format
+msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3088
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3103
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3125
+#, c-format
+msgid "section [%2d] '%s': no BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3141
+#, c-format
+msgid "section [%2d] '%s': unknown parent version '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3154
+#, c-format
+msgid "section [%2d] '%s': empty object attributes section\n"
+msgstr ""
+
+#: src/elflint.c:3175
+#, c-format
+msgid "section [%2d] '%s': unrecognized attribute format\n"
+msgstr ""
+
+#: src/elflint.c:3191
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3200
+#, c-format
+msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3212
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n"
+msgstr ""
+
+#: src/elflint.c:3229
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"
+msgstr ""
+
+#: src/elflint.c:3238
+#, c-format
+msgid "section [%2d] '%s': offset %zu: truncated attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3247
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3260
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3271
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3289
+#, c-format
+msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"
+msgstr ""
+
+#: src/elflint.c:3300
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n"
+msgstr ""
+
+#: src/elflint.c:3313
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3317
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: unrecognized %s attribute value %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3327
+#, c-format
+msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n"
+msgstr ""
+
+#: src/elflint.c:3333
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3422
+#, c-format
+msgid "cannot get section header of zeroth section\n"
+msgstr ""
+
+#: src/elflint.c:3426
+#, c-format
+msgid "zeroth section has nonzero name\n"
+msgstr ""
+
+#: src/elflint.c:3428
+#, c-format
+msgid "zeroth section has nonzero type\n"
+msgstr ""
+
+#: src/elflint.c:3430
+#, c-format
+msgid "zeroth section has nonzero flags\n"
+msgstr ""
+
+#: src/elflint.c:3432
+#, c-format
+msgid "zeroth section has nonzero address\n"
+msgstr ""
+
+#: src/elflint.c:3434
+#, c-format
+msgid "zeroth section has nonzero offset\n"
+msgstr ""
+
+#: src/elflint.c:3436
+#, c-format
+msgid "zeroth section has nonzero align value\n"
+msgstr ""
+
+#: src/elflint.c:3438
+#, c-format
+msgid "zeroth section has nonzero entry size value\n"
+msgstr ""
+
+#: src/elflint.c:3441
+#, c-format
+msgid ""
+"zeroth section has nonzero size value while ELF header has nonzero shnum "
+"value\n"
+msgstr ""
+
+#: src/elflint.c:3445
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in shstrndx\n"
+msgstr ""
+
+#: src/elflint.c:3449
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in phnum\n"
+msgstr ""
+
+#: src/elflint.c:3466
+#, c-format
+msgid "cannot get section header for section [%2zu] '%s': %s\n"
+msgstr ""
+
+#: src/elflint.c:3475
+#, c-format
+msgid "section [%2zu]: invalid name\n"
+msgstr ""
+
+#: src/elflint.c:3502
+#, c-format
+msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3518
+#, c-format
+msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3535
+#, c-format
+msgid ""
+"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3553
+#, c-format
+msgid "section [%2zu] '%s' present in object file\n"
+msgstr ""
+
+#: src/elflint.c:3559 src/elflint.c:3591
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"
+msgstr ""
+
+#: src/elflint.c:3564 src/elflint.c:3596
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable "
+"segments\n"
+msgstr ""
+
+#: src/elflint.c:3572
+#, c-format
+msgid ""
+"section [%2zu] '%s' is extension section index table in non-object file\n"
+msgstr ""
+
+#: src/elflint.c:3615
+#, c-format
+msgid "section [%2zu] '%s': size not multiple of entry size\n"
+msgstr ""
+
+#: src/elflint.c:3620
+#, c-format
+msgid "cannot get section header\n"
+msgstr ""
+
+#: src/elflint.c:3630
+#, c-format
+msgid "section [%2zu] '%s' has unsupported type %d\n"
+msgstr ""
+
+#: src/elflint.c:3644
+#, c-format
+msgid ""
+"section [%2zu] '%s' contains invalid processor-specific flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3651
+#, c-format
+msgid "section [%2zu] '%s' contains unknown flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3659
+#, c-format
+msgid "section [%2zu] '%s': thread-local data sections address not zero\n"
+msgstr ""
+
+#: src/elflint.c:3667
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in link value\n"
+msgstr ""
+
+#: src/elflint.c:3672
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in info value\n"
+msgstr ""
+
+#: src/elflint.c:3679
+#, c-format
+msgid "section [%2zu] '%s': strings flag set without merge flag\n"
+msgstr ""
+
+#: src/elflint.c:3684
+#, c-format
+msgid "section [%2zu] '%s': merge flag set but entry size is zero\n"
+msgstr ""
+
+#: src/elflint.c:3702
+#, c-format
+msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n"
+msgstr ""
+
+#: src/elflint.c:3711
+#, c-format
+msgid "section [%2zu] '%s' is both executable and writable\n"
+msgstr ""
+
+#: src/elflint.c:3738
+#, c-format
+msgid ""
+"section [%2zu] '%s' not fully contained in segment of program header entry %"
+"d\n"
+msgstr ""
+
+#: src/elflint.c:3746
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:3755
+#, c-format
+msgid ""
+"section [%2zu] '%s' has not type NOBITS but is not read from the file in "
+"segment of program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:3766
+#, c-format
+msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:3776
+#, c-format
+msgid "section [%2zu] '%s' is writable in unwritable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:3786
+#, c-format
+msgid ""
+"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:3792
+#, c-format
+msgid ""
+"section [%2zu] '%s': ELF header says this is the section header string table "
+"but type is not SHT_TYPE\n"
+msgstr ""
+
+#: src/elflint.c:3800
+#, c-format
+msgid ""
+"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"
+msgstr ""
+
+#: src/elflint.c:3851
+#, c-format
+msgid "more than one version symbol table present\n"
+msgstr ""
+
+#: src/elflint.c:3874
+#, c-format
+msgid "INTERP program header entry but no .interp section\n"
+msgstr ""
+
+#: src/elflint.c:3885
+#, c-format
+msgid ""
+"loadable segment [%u] is executable but contains no executable sections\n"
+msgstr ""
+
+#: src/elflint.c:3891
+#, c-format
+msgid "loadable segment [%u] is writable but contains no writable sections\n"
+msgstr ""
+
+#: src/elflint.c:3902
+#, c-format
+msgid ""
+"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section "
+"exist\n"
+msgstr ""
+
+#: src/elflint.c:3915
+#, c-format
+msgid "duplicate version index %d\n"
+msgstr ""
+
+#: src/elflint.c:3929
+#, c-format
+msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"
+msgstr ""
+
+#: src/elflint.c:3978
+#, c-format
+msgid "phdr[%d]: unknown core file note type %<PRIu32> at offset %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3982
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown core file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4005
+#, c-format
+msgid "phdr[%d]: unknown object file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4009
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown object file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4026
+#, c-format
+msgid "phdr[%d]: no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4045
+#, c-format
+msgid "phdr[%d]: cannot get content of note section: %s\n"
+msgstr ""
+
+#: src/elflint.c:4048
+#, c-format
+msgid "phdr[%d]: extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4069
+#, c-format
+msgid "section [%2d] '%s': no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4076
+#, c-format
+msgid "section [%2d] '%s': cannot get content of note section\n"
+msgstr ""
+
+#: src/elflint.c:4079
+#, c-format
+msgid "section [%2d] '%s': extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4097
+#, c-format
+msgid ""
+"only executables, shared objects, and core files can have program headers\n"
+msgstr ""
+
+#: src/elflint.c:4112
+#, c-format
+msgid "cannot get program header entry %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:4121
+#, c-format
+msgid "program header entry %d: unknown program header entry type %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:4132
+#, c-format
+msgid "more than one INTERP entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4140
+#, c-format
+msgid "more than one TLS entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4147
+#, c-format
+msgid "static executable cannot have dynamic sections\n"
+msgstr ""
+
+#: src/elflint.c:4161
+#, c-format
+msgid "dynamic section reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4164
+#, c-format
+msgid "dynamic section size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4174
+#, c-format
+msgid "more than one GNU_RELRO entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4195
+#, c-format
+msgid "loadable segment GNU_RELRO applies to is not writable\n"
+msgstr ""
+
+#: src/elflint.c:4198
+#, c-format
+msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"
+msgstr ""
+
+#: src/elflint.c:4206 src/elflint.c:4229
+#, c-format
+msgid "%s segment not contained in a loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:4235
+#, c-format
+msgid "program header offset in ELF header and PHDR entry do not match"
+msgstr ""
+
+#: src/elflint.c:4259
+#, c-format
+msgid "call frame search table reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4262
+#, c-format
+msgid "call frame search table size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4275
+#, c-format
+msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"
+msgstr ""
+
+#: src/elflint.c:4283
+#, c-format
+msgid "call frame search table must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4286
+#, c-format
+msgid "section [%2zu] '%s' must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4290
+#, c-format
+msgid "call frame search table must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4293
+#, c-format
+msgid "section [%2zu] '%s' must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4298
+#, c-format
+msgid "call frame search table must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4301
+#, c-format
+msgid "section [%2zu] '%s' must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4312
+#, c-format
+msgid "program header entry %d: file size greater than memory size\n"
+msgstr ""
+
+#: src/elflint.c:4319
+#, c-format
+msgid "program header entry %d: alignment not a power of 2\n"
+msgstr ""
+
+#: src/elflint.c:4322
+#, c-format
+msgid ""
+"program header entry %d: file offset and virtual address not module of "
+"alignment\n"
+msgstr ""
+
+#: src/elflint.c:4335
+#, c-format
+msgid ""
+"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME "
+"program header entry"
+msgstr ""
+
+#: src/elflint.c:4369
+#, c-format
+msgid "cannot read ELF header: %s\n"
+msgstr ""
+
+#: src/elflint.c:4395
+#, c-format
+msgid "text relocation flag set but not needed\n"
+msgstr ""
+
+#: src/findtextrel.c:70
+msgid "Input Selection:"
+msgstr ""
+
+#: src/findtextrel.c:71
+msgid "Prepend PATH to all file names"
+msgstr ""
+
+#: src/findtextrel.c:73
+msgid "Use PATH as root of debuginfo hierarchy"
+msgstr ""
+
+#: src/findtextrel.c:80
+msgid "Locate source of text relocations in FILEs (a.out by default)."
+msgstr ""
+
+#: src/findtextrel.c:84 src/nm.c:111 src/objdump.c:80 src/size.c:92
+#: src/strings.c:92 src/strip.c:97
+msgid "[FILE...]"
+msgstr ""
+
+#: src/findtextrel.c:246
+#, c-format
+msgid "cannot get ELF header '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:257
+#, c-format
+msgid "'%s' is not a DSO or PIE"
+msgstr ""
+
+#: src/findtextrel.c:274
+#, c-format
+msgid "getting get section header of section %zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:292
+#, c-format
+msgid "cannot read dynamic section: %s"
+msgstr ""
+
+#: src/findtextrel.c:307
+#, c-format
+msgid "no text relocations reported in '%s'"
+msgstr ""
+
+#: src/findtextrel.c:319
+#, c-format
+msgid "while reading ELF file"
+msgstr ""
+
+#: src/findtextrel.c:328 src/findtextrel.c:345
+#, c-format
+msgid "cannot get program header index at offset %d: %s"
+msgstr ""
+
+#: src/findtextrel.c:397
+#, c-format
+msgid "cannot get section header of section %Zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:409
+#, c-format
+msgid "cannot get symbol table section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:429 src/findtextrel.c:452
+#, c-format
+msgid "cannot get relocation at index %d in section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:517
+#, c-format
+msgid "%s not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:570
+#, c-format
+msgid ""
+"the file containing the function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:577 src/findtextrel.c:597
+#, c-format
+msgid ""
+"the file containing the function '%s' might not be compiled with -fpic/-"
+"fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:585
+#, c-format
+msgid ""
+"either the file containing the function '%s' or the file containing the "
+"function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:605
+#, c-format
+msgid ""
+"a relocation modifies memory at offset %llu in a write-protected segment\n"
+msgstr ""
+
+#: src/i386_ld.c:210
+#, c-format
+msgid "cannot allocate PLT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:232
+#, c-format
+msgid "cannot allocate PLTREL section: %s"
+msgstr ""
+
+#: src/i386_ld.c:253
+#, c-format
+msgid "cannot allocate GOT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:274
+#, c-format
+msgid "cannot allocate GOTPLT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:661
+#, c-format
+msgid "initial-executable TLS relocation cannot be used "
+msgstr ""
+
+#: src/ld.c:87
+msgid "Input File Control:"
+msgstr ""
+
+#: src/ld.c:89
+msgid "Include whole archives in the output from now on."
+msgstr ""
+
+#: src/ld.c:91
+msgid "Stop including the whole archives in the output."
+msgstr ""
+
+#: src/ld.c:92 src/ld.c:106 src/ld.c:184
+msgid "FILE"
+msgstr ""
+
+#: src/ld.c:93
+msgid "Start a group."
+msgstr ""
+
+#: src/ld.c:94
+msgid "End a group."
+msgstr ""
+
+#: src/ld.c:95
+msgid "PATH"
+msgstr ""
+
+#: src/ld.c:96
+msgid "Add PATH to list of directories files are searched in."
+msgstr ""
+
+#: src/ld.c:98
+msgid "Only set DT_NEEDED for following dynamic libs if actually used"
+msgstr ""
+
+#: src/ld.c:100
+msgid "Always set DT_NEEDED for following dynamic libs"
+msgstr ""
+
+#: src/ld.c:102
+msgid "Ignore LD_LIBRARY_PATH environment variable."
+msgstr ""
+
+#: src/ld.c:105
+msgid "Output File Control:"
+msgstr ""
+
+#: src/ld.c:106
+msgid "Place output in FILE."
+msgstr ""
+
+#: src/ld.c:109
+msgid "Object is marked to not use default search path at runtime."
+msgstr ""
+
+#: src/ld.c:111
+msgid "Same as --whole-archive."
+msgstr ""
+
+#: src/ld.c:112
+msgid ""
+"Default rules of extracting from archive; weak references are not enough."
+msgstr ""
+
+#: src/ld.c:116
+msgid "Weak references cause extraction from archive."
+msgstr ""
+
+#: src/ld.c:118
+msgid "Allow multiple definitions; first is used."
+msgstr ""
+
+#: src/ld.c:120
+msgid "Disallow/allow undefined symbols in DSOs."
+msgstr ""
+
+#: src/ld.c:123
+msgid "Object requires immediate handling of $ORIGIN."
+msgstr ""
+
+#: src/ld.c:125
+msgid "Relocation will not be processed lazily."
+msgstr ""
+
+#: src/ld.c:127
+msgid "Object cannot be unloaded at runtime."
+msgstr ""
+
+#: src/ld.c:129
+msgid "Mark object to be initialized first."
+msgstr ""
+
+#: src/ld.c:131
+msgid "Enable/disable lazy-loading flag for following dependencies."
+msgstr ""
+
+#: src/ld.c:133
+msgid "Mark object as not loadable with 'dlopen'."
+msgstr ""
+
+#: src/ld.c:135
+msgid "Ignore/record dependencies on unused DSOs."
+msgstr ""
+
+#: src/ld.c:137
+msgid "Generated DSO will be a system library."
+msgstr ""
+
+#: src/ld.c:138
+msgid "ADDRESS"
+msgstr ""
+
+#: src/ld.c:138
+msgid "Set entry point address."
+msgstr ""
+
+#: src/ld.c:141
+msgid "Do not link against shared libraries."
+msgstr ""
+
+#: src/ld.c:144
+msgid "Prefer linking against shared libraries."
+msgstr ""
+
+#: src/ld.c:145
+msgid "Export all dynamic symbols."
+msgstr ""
+
+#: src/ld.c:146
+msgid "Strip all symbols."
+msgstr ""
+
+#: src/ld.c:147
+msgid "Strip debugging symbols."
+msgstr ""
+
+#: src/ld.c:149
+msgid "Assume pagesize for the target system to be SIZE."
+msgstr ""
+
+#: src/ld.c:151
+msgid "Set runtime DSO search path."
+msgstr ""
+
+#: src/ld.c:154
+msgid "Set link time DSO search path."
+msgstr ""
+
+#: src/ld.c:155
+msgid "Generate dynamic shared object."
+msgstr ""
+
+#: src/ld.c:156
+msgid "Generate relocatable object."
+msgstr ""
+
+#: src/ld.c:159
+msgid "Causes symbol not assigned to a version be reduced to local."
+msgstr ""
+
+#: src/ld.c:160
+msgid "Remove unused sections."
+msgstr ""
+
+#: src/ld.c:163
+msgid "Don't remove unused sections."
+msgstr ""
+
+#: src/ld.c:164
+msgid "Set soname of shared object."
+msgstr ""
+
+#: src/ld.c:165
+msgid "Set the dynamic linker name."
+msgstr ""
+
+#: src/ld.c:168
+msgid "Add/suppress addition indentifying link-editor to .comment section."
+msgstr ""
+
+#: src/ld.c:171
+msgid "Create .eh_frame_hdr section"
+msgstr ""
+
+#: src/ld.c:173
+msgid "Set hash style to sysv, gnu or both."
+msgstr ""
+
+#: src/ld.c:175
+msgid "Generate build ID note (md5, sha1 (default), uuid)."
+msgstr ""
+
+#: src/ld.c:177
+msgid "Linker Operation Control:"
+msgstr ""
+
+#: src/ld.c:178
+msgid "Verbose messages."
+msgstr ""
+
+#: src/ld.c:179
+msgid "Trace file opens."
+msgstr ""
+
+#: src/ld.c:181
+msgid "Trade speed for less memory usage"
+msgstr ""
+
+#: src/ld.c:182
+msgid "LEVEL"
+msgstr ""
+
+#: src/ld.c:183
+msgid "Set optimization level to LEVEL."
+msgstr ""
+
+#: src/ld.c:184
+msgid "Use linker script in FILE."
+msgstr ""
+
+#: src/ld.c:187
+msgid "Select to get parser debug information"
+msgstr ""
+
+#: src/ld.c:190
+msgid "Read version information from FILE."
+msgstr ""
+
+#: src/ld.c:191
+msgid "Set emulation to NAME."
+msgstr ""
+
+#: src/ld.c:197
+msgid "Combine object and archive files."
+msgstr ""
+
+#: src/ld.c:200
+msgid "[FILE]..."
+msgstr ""
+
+#: src/ld.c:333
+#, c-format
+msgid "At least one input file needed"
+msgstr ""
+
+#: src/ld.c:349
+#, c-format
+msgid "error while preparing linking"
+msgstr ""
+
+#: src/ld.c:356
+#, c-format
+msgid "cannot open linker script '%s'"
+msgstr ""
+
+#: src/ld.c:397
+#, c-format
+msgid "-( without matching -)"
+msgstr ""
+
+#: src/ld.c:572 src/ld.c:610
+#, c-format
+msgid "only one option of -G and -r is allowed"
+msgstr ""
+
+#: src/ld.c:594
+#, c-format
+msgid "more than one '-m' parameter"
+msgstr ""
+
+#: src/ld.c:604 src/ld.c:1013
+#, c-format
+msgid "unknown option `-%c %s'"
+msgstr ""
+
+#: src/ld.c:646
+#, c-format
+msgid "invalid page size value '%s': ignored"
+msgstr ""
+
+#: src/ld.c:687
+#, c-format
+msgid "invalid hash style '%s'"
+msgstr ""
+
+#: src/ld.c:697
+#, c-format
+msgid "invalid build-ID style '%s'"
+msgstr ""
+
+#: src/ld.c:785
+#, c-format
+msgid "More than one output file name given."
+msgstr ""
+
+#: src/ld.c:802
+#, c-format
+msgid "Invalid optimization level `%s'"
+msgstr ""
+
+#: src/ld.c:850
+#, c-format
+msgid "nested -( -) groups are not allowed"
+msgstr ""
+
+#: src/ld.c:869
+#, c-format
+msgid "-) without matching -("
+msgstr ""
+
+#: src/ld.c:1046
+#, c-format
+msgid "unknown option '-%c %s'"
+msgstr ""
+
+#: src/ld.c:1150
+#, c-format
+msgid "could not find input file to determine output file format"
+msgstr ""
+
+#: src/ld.c:1152
+#, c-format
+msgid "try again with an appropriate '-m' parameter"
+msgstr ""
+
+#: src/ld.c:1446
+#, c-format
+msgid "cannot read version script '%s'"
+msgstr ""
+
+#: src/ld.c:1512 src/ld.c:1551
+#, c-format
+msgid "duplicate definition of '%s' in linker script"
+msgstr ""
+
+#: src/ldgeneric.c:209 src/ldgeneric.c:5151
+#, c-format
+msgid "cannot create string table"
+msgstr ""
+
+#: src/ldgeneric.c:255
+#, c-format
+msgid "cannot load ld backend library '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:265
+#, c-format
+msgid "cannot find init function in ld backend library '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:310
+#, c-format
+msgid "%s listed more than once as input"
+msgstr ""
+
+#: src/ldgeneric.c:424
+#, c-format
+msgid "%s (for -l%s)\n"
+msgstr ""
+
+#: src/ldgeneric.c:425
+#, c-format
+msgid "%s (for DT_NEEDED %s)\n"
+msgstr ""
+
+#: src/ldgeneric.c:573
+#, c-format
+msgid "Warning: type of `%s' changed from %s in %s to %s in %s"
+msgstr ""
+
+#: src/ldgeneric.c:586
+#, c-format
+msgid "Warning: size of `%s' changed from %<PRIu64> in %s to %<PRIu64> in %s"
+msgstr ""
+
+#: src/ldgeneric.c:661 src/ldgeneric.c:1122 src/readelf.c:629 src/strip.c:543
+#, c-format
+msgid "cannot determine number of sections: %s"
+msgstr ""
+
+#: src/ldgeneric.c:677
+#, c-format
+msgid "(%s+%#<PRIx64>): multiple definition of %s `%s'\n"
+msgstr ""
+
+#: src/ldgeneric.c:700
+#, c-format
+msgid "(%s+%#<PRIx64>): first defined here\n"
+msgstr ""
+
+#: src/ldgeneric.c:819
+#, c-format
+msgid "%s: cannot get section group data: %s"
+msgstr ""
+
+#: src/ldgeneric.c:840
+#, c-format
+msgid "%s: section '%s' with group flag set does not belong to any group"
+msgstr ""
+
+#: src/ldgeneric.c:885
+#, c-format
+msgid "%s: section [%2d] '%s' is not in the correct section group"
+msgstr ""
+
+#: src/ldgeneric.c:1156 src/ldgeneric.c:1413 src/ldgeneric.c:1422
+#: src/ldgeneric.c:1481 src/ldgeneric.c:1490 src/ldgeneric.c:1753
+#: src/ldgeneric.c:2005
+#, c-format
+msgid "%s: invalid ELF file (%s:%d)\n"
+msgstr ""
+
+#: src/ldgeneric.c:1250
+#, c-format
+msgid "%s: only files of type ET_REL might contain section groups"
+msgstr ""
+
+#: src/ldgeneric.c:1302
+#, c-format
+msgid "%s: cannot determine signature of section group [%2zd] '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:1314
+#, c-format
+msgid "%s: cannot get content of section group [%2zd] '%s': %s'"
+msgstr ""
+
+#: src/ldgeneric.c:1328
+#, c-format
+msgid ""
+"%s: group member %zu of section group [%2zd] '%s' has too high index: %"
+"<PRIu32>"
+msgstr ""
+
+#: src/ldgeneric.c:1350
+#, c-format
+msgid "%s: section '%s' has unknown type: %d"
+msgstr ""
+
+#: src/ldgeneric.c:1729
+#, c-format
+msgid "cannot get descriptor for ELF file (%s:%d): %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:1899
+#, c-format
+msgid "cannot read archive `%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:2020
+#, c-format
+msgid "file of type %s cannot be linked in\n"
+msgstr ""
+
+#: src/ldgeneric.c:2032
+#, c-format
+msgid "%s: input file incompatible with ELF machine type %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:2044
+#, c-format
+msgid "%s: cannot get section header string table index: %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:2073
+#, c-format
+msgid "cannot use DSO '%s' when generating relocatable object file"
+msgstr ""
+
+#: src/ldgeneric.c:2158
+#, c-format
+msgid "input file '%s' ignored"
+msgstr ""
+
+#: src/ldgeneric.c:2372
+#, c-format
+msgid "undefined symbol `%s' in %s"
+msgstr ""
+
+#: src/ldgeneric.c:2702
+#, c-format
+msgid "cannot create ELF descriptor for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:2709
+#, c-format
+msgid "could not create ELF header for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:3224 src/ldgeneric.c:3294 src/ldgeneric.c:3330
+#: src/ldgeneric.c:4457 src/ldgeneric.c:4506 src/ldgeneric.c:4538
+#: src/ldgeneric.c:4773 src/ldgeneric.c:4828 src/ldgeneric.c:5075
+#: src/ldgeneric.c:5131 src/ldgeneric.c:5600 src/ldgeneric.c:5612
+#, c-format
+msgid "cannot create section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:3444
+#, c-format
+msgid "address computation expression contains variable '%s'"
+msgstr ""
+
+#: src/ldgeneric.c:3489
+#, c-format
+msgid ""
+"argument '%<PRIuMAX>' of ALIGN in address computation expression is no power "
+"of two"
+msgstr ""
+
+#: src/ldgeneric.c:3684
+#, c-format
+msgid "cannot find entry symbol '%s': defaulting to %#0*<PRIx64>"
+msgstr ""
+
+#: src/ldgeneric.c:3690
+#, c-format
+msgid "no entry symbol specified: defaulting to %#0*<PRIx64>"
+msgstr ""
+
+#: src/ldgeneric.c:3920
+#, c-format
+msgid "cannot create GNU hash table section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4071
+#, c-format
+msgid "cannot create hash table section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4114
+#, c-format
+msgid "cannot create build ID section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4191
+#, c-format
+msgid "cannot convert section data to file format: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4200
+#, c-format
+msgid "cannot convert section data to memory format: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4261
+#, c-format
+msgid "cannot read enough data for UUID"
+msgstr ""
+
+#: src/ldgeneric.c:4358 src/ldgeneric.c:4379 src/ldgeneric.c:4408
+#: src/ldgeneric.c:6062
+#, c-format
+msgid "cannot create symbol table for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5300 src/ldgeneric.c:5852
+#, c-format
+msgid "section index too large in dynamic symbol table"
+msgstr ""
+
+#: src/ldgeneric.c:5745
+#, c-format
+msgid "cannot create versioning section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5818
+#, c-format
+msgid "cannot create dynamic symbol table for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5994
+#, c-format
+msgid "cannot create versioning data: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6094 src/ldgeneric.c:6107 src/ldgeneric.c:6171
+#: src/ldgeneric.c:6179
+#, c-format
+msgid "cannot create section header string section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6101
+#, c-format
+msgid "cannot create section header string section"
+msgstr ""
+
+#: src/ldgeneric.c:6259
+#, c-format
+msgid "cannot create program header: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6267
+#, c-format
+msgid "while determining file layout: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6388
+#, c-format
+msgid "internal error: non-nobits section follows nobits section"
+msgstr ""
+
+#: src/ldgeneric.c:6925
+#, c-format
+msgid "cannot get header of 0th section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6941 src/unstrip.c:1808
+#, c-format
+msgid "cannot update ELF header: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6972
+#, c-format
+msgid "linker backend didn't specify function to relocate section"
+msgstr ""
+
+#: src/ldgeneric.c:6984
+#, c-format
+msgid "while writing output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6989
+#, c-format
+msgid "while finishing output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6995
+#, c-format
+msgid "cannot stat output file"
+msgstr ""
+
+#: src/ldgeneric.c:7011
+#, c-format
+msgid "WARNING: temporary output file overwritten before linking finished"
+msgstr ""
+
+#: src/ldgeneric.c:7064 src/ldgeneric.c:7075 src/ldgeneric.c:7086
+#: src/ldgeneric.c:7097 src/ldgeneric.c:7116 src/ldgeneric.c:7129
+#: src/ldgeneric.c:7141
+#, c-format
+msgid "no machine specific '%s' implementation"
+msgstr ""
+
+#: src/ldscript.y:178
+msgid "mode for segment invalid\n"
+msgstr ""
+
+#: src/ldscript.y:465
+#, c-format
+msgid "while reading version script '%s': %s at line %d"
+msgstr ""
+
+#: src/ldscript.y:466
+#, c-format
+msgid "while reading linker script '%s': %s at line %d"
+msgstr ""
+
+#: src/ldscript.y:745
+#, c-format
+msgid "symbol '%s' is declared both local and global for unnamed version"
+msgstr ""
+
+#: src/ldscript.y:747
+#, c-format
+msgid "symbol '%s' is declared both local and global for version '%s'"
+msgstr ""
+
+#: src/ldscript.y:767 src/ldscript.y:774
+#, c-format
+msgid "default visibility set as local and global"
+msgstr ""
+
+#: src/nm.c:74 src/strip.c:73
+msgid "Output selection:"
+msgstr ""
+
+#: src/nm.c:75
+msgid "Display debugger-only symbols"
+msgstr ""
+
+#: src/nm.c:76
+msgid "Display only defined symbols"
+msgstr ""
+
+#: src/nm.c:79
+msgid "Display dynamic symbols instead of normal symbols"
+msgstr ""
+
+#: src/nm.c:80
+msgid "Display only external symbols"
+msgstr ""
+
+#: src/nm.c:81
+msgid "Display only undefined symbols"
+msgstr ""
+
+#: src/nm.c:83
+msgid "Include index for symbols from archive members"
+msgstr ""
+
+#: src/nm.c:85 src/size.c:66
+msgid "Output format:"
+msgstr ""
+
+#: src/nm.c:87
+msgid "Print name of the input file before every symbol"
+msgstr ""
+
+#: src/nm.c:90
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd', `sysv' or `posix'.  The "
+"default is `sysv'"
+msgstr ""
+
+#: src/nm.c:92
+msgid "Same as --format=bsd"
+msgstr ""
+
+#: src/nm.c:93
+msgid "Same as --format=posix"
+msgstr ""
+
+#: src/nm.c:94 src/size.c:72
+msgid "Use RADIX for printing symbol values"
+msgstr ""
+
+#: src/nm.c:95
+msgid "Mark weak symbols"
+msgstr ""
+
+#: src/nm.c:96
+msgid "Print size of defined symbols"
+msgstr ""
+
+#: src/nm.c:98 src/size.c:80 src/strip.c:78 src/unstrip.c:81
+msgid "Output options:"
+msgstr ""
+
+#: src/nm.c:99
+msgid "Sort symbols numerically by address"
+msgstr ""
+
+#: src/nm.c:101
+msgid "Do not sort the symbols"
+msgstr ""
+
+#: src/nm.c:102
+msgid "Reverse the sense of the sort"
+msgstr ""
+
+#: src/nm.c:108
+msgid "List symbols from FILEs (a.out by default)."
+msgstr ""
+
+#: src/nm.c:136 src/objdump.c:105 src/size.c:117 src/strip.c:121
+#, c-format
+msgid "%s: INTERNAL ERROR %d (%s-%s): %s"
+msgstr ""
+
+#: src/nm.c:380 src/nm.c:392 src/size.c:317 src/size.c:326 src/size.c:337
+#: src/strip.c:1816
+#, c-format
+msgid "while closing '%s'"
+msgstr ""
+
+#: src/nm.c:402 src/objdump.c:296 src/strip.c:359
+#, c-format
+msgid "%s: File format not recognized"
+msgstr ""
+
+#: src/nm.c:442
+msgid ""
+"\n"
+"Archive index:"
+msgstr ""
+
+#: src/nm.c:451
+#, c-format
+msgid "invalid offset %zu for symbol %s"
+msgstr ""
+
+#: src/nm.c:456
+#, c-format
+msgid "%s in %s\n"
+msgstr ""
+
+#: src/nm.c:464
+#, c-format
+msgid "cannot reset archive offset to beginning"
+msgstr ""
+
+#: src/nm.c:488 src/objdump.c:344
+#, c-format
+msgid "%s%s%s: file format not recognized"
+msgstr ""
+
+#: src/nm.c:700
+#, c-format
+msgid "cannot create search tree"
+msgstr ""
+
+#: src/nm.c:740 src/nm.c:1002 src/objdump.c:744 src/readelf.c:885
+#: src/readelf.c:1028 src/readelf.c:1169 src/readelf.c:1351 src/readelf.c:1549
+#: src/readelf.c:1735 src/readelf.c:1945 src/readelf.c:2199 src/readelf.c:2265
+#: src/readelf.c:2343 src/readelf.c:2841 src/readelf.c:2877 src/readelf.c:2939
+#: src/readelf.c:6493 src/readelf.c:7387 src/readelf.c:7534 src/readelf.c:7604
+#: src/size.c:425 src/size.c:499 src/strip.c:483
+#, c-format
+msgid "cannot get section header string table index"
+msgstr ""
+
+#: src/nm.c:766
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s:\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:768
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s[%s]:\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:771
+#, c-format
+msgid ""
+"%*s%-*s %-*s Class  Type     %-*s %*s Section\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:1012
+#, c-format
+msgid "%s: entry size in section `%s' is not what we expect"
+msgstr ""
+
+#: src/nm.c:1016
+#, c-format
+msgid "%s: size of section `%s' is not multiple of entry size"
+msgstr ""
+
+#: src/nm.c:1255
+#, c-format
+msgid "%s%s%s%s: Invalid operation"
+msgstr ""
+
+#: src/nm.c:1312
+#, c-format
+msgid "%s%s%s: no symbols"
+msgstr ""
+
+#: src/objdump.c:61
+msgid "Mode selection:"
+msgstr ""
+
+#: src/objdump.c:62
+msgid "Display relocation information."
+msgstr ""
+
+#: src/objdump.c:64
+msgid "Display the full contents of all sections requested"
+msgstr ""
+
+#: src/objdump.c:66
+msgid "Display assembler code of executable sections"
+msgstr ""
+
+#: src/objdump.c:68
+msgid "Output option selection:"
+msgstr ""
+
+#: src/objdump.c:70
+msgid "Only display information for section NAME."
+msgstr ""
+
+#: src/objdump.c:76
+msgid "Show information from FILEs (a.out by default)."
+msgstr ""
+
+#: src/objdump.c:236 src/readelf.c:430
+msgid "No operation specified.\n"
+msgstr ""
+
+#: src/objdump.c:274 src/objdump.c:286
+#, c-format
+msgid "while close `%s'"
+msgstr ""
+
+#: src/objdump.c:379 src/readelf.c:1644 src/readelf.c:1818
+msgid "INVALID SYMBOL"
+msgstr ""
+
+#: src/objdump.c:394 src/readelf.c:1675 src/readelf.c:1851
+msgid "INVALID SECTION"
+msgstr ""
+
+#: src/objdump.c:510
+#, c-format
+msgid ""
+"\n"
+"RELOCATION RECORDS FOR [%s]:\n"
+"%-*s TYPE                 VALUE\n"
+msgstr ""
+
+#: src/objdump.c:513
+msgid "OFFSET"
+msgstr ""
+
+#: src/objdump.c:576
+#, c-format
+msgid "Contents of section %s:\n"
+msgstr ""
+
+#: src/objdump.c:676
+#, c-format
+msgid "cannot disassemble"
+msgstr ""
+
+#: src/ranlib.c:74
+msgid "Generate an index to speed access to archives."
+msgstr ""
+
+#: src/ranlib.c:77
+msgid "ARCHIVE"
+msgstr ""
+
+#: src/ranlib.c:116
+#, c-format
+msgid "Archive name required"
+msgstr ""
+
+#: src/ranlib.c:194
+#, c-format
+msgid "'%s' is no archive"
+msgstr ""
+
+#: src/ranlib.c:229
+#, c-format
+msgid "error while freeing sub-ELF descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:73
+msgid "ELF output selection:"
+msgstr ""
+
+#: src/readelf.c:75
+msgid "All these plus -p .strtab -p .dynstr -p .comment"
+msgstr ""
+
+#: src/readelf.c:76
+msgid "Display the dynamic segment"
+msgstr ""
+
+#: src/readelf.c:77
+msgid "Display the ELF file header"
+msgstr ""
+
+#: src/readelf.c:79
+msgid "Display histogram of bucket list lengths"
+msgstr ""
+
+#: src/readelf.c:80
+msgid "Display the program headers"
+msgstr ""
+
+#: src/readelf.c:82
+msgid "Display relocations"
+msgstr ""
+
+#: src/readelf.c:83
+msgid "Display the sections' headers"
+msgstr ""
+
+#: src/readelf.c:85
+msgid "Display the symbol table"
+msgstr ""
+
+#: src/readelf.c:86
+msgid "Display versioning information"
+msgstr ""
+
+#: src/readelf.c:87
+msgid "Display the ELF notes"
+msgstr ""
+
+#: src/readelf.c:89
+msgid "Display architecture specific information, if any"
+msgstr ""
+
+#: src/readelf.c:91
+msgid "Display sections for exception handling"
+msgstr ""
+
+#: src/readelf.c:93
+msgid "Additional output selection:"
+msgstr ""
+
+#: src/readelf.c:95
+msgid ""
+"Display DWARF section content.  SECTION can be one of abbrev, aranges, "
+"frame, info, loc, line, ranges, pubnames, str, macinfo, or exception"
+msgstr ""
+
+#: src/readelf.c:99
+msgid "Dump the uninterpreted contents of SECTION, by number or name"
+msgstr ""
+
+#: src/readelf.c:101
+msgid "Print string contents of sections"
+msgstr ""
+
+#: src/readelf.c:104
+msgid "Display the symbol index of an archive"
+msgstr ""
+
+#: src/readelf.c:106
+msgid "Output control:"
+msgstr ""
+
+#: src/readelf.c:108
+msgid "Do not find symbol names for addresses in DWARF data"
+msgstr ""
+
+#: src/readelf.c:114
+msgid "Print information from ELF file in human-readable form."
+msgstr ""
+
+#: src/readelf.c:401
+#, c-format
+msgid "Unknown DWARF debug section `%s'.\n"
+msgstr ""
+
+#: src/readelf.c:465
+#, c-format
+msgid "cannot generate Elf descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:477
+#, c-format
+msgid "'%s' is not an archive, cannot print archive index"
+msgstr ""
+
+#: src/readelf.c:482
+#, c-format
+msgid "error while closing Elf descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:574
+#, c-format
+msgid "cannot stat input file"
+msgstr ""
+
+#: src/readelf.c:576
+#, c-format
+msgid "input file is empty"
+msgstr ""
+
+#: src/readelf.c:578
+#, c-format
+msgid "failed reading '%s': %s"
+msgstr ""
+
+#: src/readelf.c:614
+#, c-format
+msgid "cannot read ELF header: %s"
+msgstr ""
+
+#: src/readelf.c:622
+#, c-format
+msgid "cannot create EBL handle"
+msgstr ""
+
+#: src/readelf.c:635
+#, c-format
+msgid "cannot determine number of program headers: %s"
+msgstr ""
+
+#: src/readelf.c:721
+msgid "NONE (None)"
+msgstr ""
+
+#: src/readelf.c:722
+msgid "REL (Relocatable file)"
+msgstr ""
+
+#: src/readelf.c:723
+msgid "EXEC (Executable file)"
+msgstr ""
+
+#: src/readelf.c:724
+msgid "DYN (Shared object file)"
+msgstr ""
+
+#: src/readelf.c:725
+msgid "CORE (Core file)"
+msgstr ""
+
+#: src/readelf.c:730
+#, c-format
+msgid "OS Specific: (%x)\n"
+msgstr ""
+
+#: src/readelf.c:732
+#, c-format
+msgid "Processor Specific: (%x)\n"
+msgstr ""
+
+#: src/readelf.c:742
+msgid ""
+"ELF Header:\n"
+"  Magic:  "
+msgstr ""
+
+#: src/readelf.c:746
+#, c-format
+msgid ""
+"\n"
+"  Class:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:751
+#, c-format
+msgid "  Data:                              %s\n"
+msgstr ""
+
+#: src/readelf.c:757
+#, c-format
+msgid "  Ident Version:                     %hhd %s\n"
+msgstr ""
+
+#: src/readelf.c:759 src/readelf.c:776
+msgid "(current)"
+msgstr ""
+
+#: src/readelf.c:763
+#, c-format
+msgid "  OS/ABI:                            %s\n"
+msgstr ""
+
+#: src/readelf.c:766
+#, c-format
+msgid "  ABI Version:                       %hhd\n"
+msgstr ""
+
+#: src/readelf.c:769
+msgid "  Type:                              "
+msgstr ""
+
+#: src/readelf.c:772
+#, c-format
+msgid "  Machine:                           %s\n"
+msgstr ""
+
+#: src/readelf.c:774
+#, c-format
+msgid "  Version:                           %d %s\n"
+msgstr ""
+
+#: src/readelf.c:778
+#, c-format
+msgid "  Entry point address:               %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:781
+#, c-format
+msgid "  Start of program headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:782 src/readelf.c:785
+msgid "(bytes into file)"
+msgstr ""
+
+#: src/readelf.c:784
+#, c-format
+msgid "  Start of section headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:787
+#, c-format
+msgid "  Flags:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:790
+#, c-format
+msgid "  Size of this header:               %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:791 src/readelf.c:794 src/readelf.c:811
+msgid "(bytes)"
+msgstr ""
+
+#: src/readelf.c:793
+#, c-format
+msgid "  Size of program header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:796
+#, c-format
+msgid "  Number of program headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:803
+#, c-format
+msgid " (%<PRIu32> in [0].sh_info)"
+msgstr ""
+
+#: src/readelf.c:806 src/readelf.c:823 src/readelf.c:837
+msgid " ([0] not available)"
+msgstr ""
+
+#: src/readelf.c:810
+#, c-format
+msgid "  Size of section header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:813
+#, c-format
+msgid "  Number of section headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:820
+#, c-format
+msgid " (%<PRIu32> in [0].sh_size)"
+msgstr ""
+
+#: src/readelf.c:833
+#, c-format
+msgid " (%<PRIu32> in [0].sh_link)"
+msgstr ""
+
+#: src/readelf.c:841
+#, c-format
+msgid ""
+"  Section header string table index: XINDEX%s\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:845
+#, c-format
+msgid ""
+"  Section header string table index: %<PRId16>\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:877
+#, c-format
+msgid ""
+"There are %d section headers, starting at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:887
+msgid "Section Headers:"
+msgstr ""
+
+#: src/readelf.c:890
+msgid ""
+"[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
+"Inf Al"
+msgstr ""
+
+#: src/readelf.c:892
+msgid ""
+"[Nr] Name                 Type         Addr             Off      Size     ES "
+"Flags Lk Inf Al"
+msgstr ""
+
+#: src/readelf.c:899 src/readelf.c:1052
+#, c-format
+msgid "cannot get section: %s"
+msgstr ""
+
+#: src/readelf.c:906 src/readelf.c:1060 src/readelf.c:7554 src/unstrip.c:353
+#: src/unstrip.c:377 src/unstrip.c:427 src/unstrip.c:536 src/unstrip.c:553
+#: src/unstrip.c:591 src/unstrip.c:789 src/unstrip.c:1057 src/unstrip.c:1244
+#: src/unstrip.c:1305 src/unstrip.c:1427 src/unstrip.c:1480 src/unstrip.c:1588
+#: src/unstrip.c:1778
+#, c-format
+msgid "cannot get section header: %s"
+msgstr ""
+
+#: src/readelf.c:964
+msgid "Program Headers:"
+msgstr ""
+
+#: src/readelf.c:966
+msgid ""
+"  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:969
+msgid ""
+"  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
+"MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:1009
+#, c-format
+msgid "\t[Requesting program interpreter: %s]\n"
+msgstr ""
+
+#: src/readelf.c:1030
+msgid ""
+"\n"
+" Section to Segment mapping:\n"
+"  Segment Sections..."
+msgstr ""
+
+#: src/readelf.c:1041 src/unstrip.c:1824 src/unstrip.c:1863 src/unstrip.c:1870
+#, c-format
+msgid "cannot get program header: %s"
+msgstr ""
+
+#: src/readelf.c:1175
+#, c-format
+msgid ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1180
+#, c-format
+msgid ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1188
+msgid "<INVALID SYMBOL>"
+msgstr ""
+
+#: src/readelf.c:1202
+msgid "<INVALID SECTION>"
+msgstr ""
+
+#: src/readelf.c:1353
+#, c-format
+msgid ""
+"\n"
+"Dynamic segment contains %lu entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Dynamic segment contains %lu entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1365
+msgid "  Type              Value\n"
+msgstr ""
+
+#: src/readelf.c:1389
+#, c-format
+msgid "Shared library: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1394
+#, c-format
+msgid "Library soname: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1399
+#, c-format
+msgid "Library rpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1404
+#, c-format
+msgid "Library runpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1424
+#, c-format
+msgid "%<PRId64> (bytes)\n"
+msgstr ""
+
+#: src/readelf.c:1534 src/readelf.c:1720
+#, c-format
+msgid ""
+"\n"
+"Invalid symbol table at offset %#0<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:1552 src/readelf.c:1737
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1567
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1577
+msgid "  Offset      Type                 Value       Name\n"
+msgstr ""
+
+#: src/readelf.c:1579
+msgid "  Offset              Type                 Value               Name\n"
+msgstr ""
+
+#: src/readelf.c:1632 src/readelf.c:1643 src/readelf.c:1656 src/readelf.c:1674
+#: src/readelf.c:1686 src/readelf.c:1805 src/readelf.c:1817 src/readelf.c:1831
+#: src/readelf.c:1850 src/readelf.c:1863
+msgid "<INVALID RELOC>"
+msgstr ""
+
+#: src/readelf.c:1749
+msgid "  Offset      Type            Value       Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:1751
+msgid "  Offset              Type            Value               Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:1952
+#, c-format
+msgid ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entry:\n"
+msgid_plural ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1958
+#, c-format
+msgid " %lu local symbol  String table: [%2u] '%s'\n"
+msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1968
+msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:1970
+msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:1990
+#, c-format
+msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+msgstr ""
+
+#: src/readelf.c:2078
+#, c-format
+msgid "bad dynamic symbol"
+msgstr ""
+
+#: src/readelf.c:2160
+msgid "none"
+msgstr ""
+
+#: src/readelf.c:2177
+msgid "| <unknown>"
+msgstr ""
+
+#: src/readelf.c:2202
+#, c-format
+msgid ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2225
+#, c-format
+msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
+msgstr ""
+
+#: src/readelf.c:2238
+#, c-format
+msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
+msgstr ""
+
+#: src/readelf.c:2269
+#, c-format
+msgid ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2299
+#, c-format
+msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
+msgstr ""
+
+#: src/readelf.c:2314
+#, c-format
+msgid "  %#06x: Parent %d: %s\n"
+msgstr ""
+
+#: src/readelf.c:2546
+#, c-format
+msgid ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgid_plural ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2576
+msgid "   0 *local*                     "
+msgstr ""
+
+#: src/readelf.c:2581
+msgid "   1 *global*                    "
+msgstr ""
+
+#: src/readelf.c:2612
+#, c-format
+msgid ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"bucket):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"buckets):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2636
+#, no-c-format
+msgid " Length  Number  % of total  Coverage\n"
+msgstr ""
+
+#: src/readelf.c:2638
+#, c-format
+msgid "      0  %6<PRIu32>      %5.1f%%\n"
+msgstr ""
+
+#: src/readelf.c:2645
+#, c-format
+msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+msgstr ""
+
+#: src/readelf.c:2658
+#, c-format
+msgid ""
+" Average number of tests:   successful lookup: %f\n"
+"                          unsuccessful lookup: %f\n"
+msgstr ""
+
+#: src/readelf.c:2676 src/readelf.c:2718 src/readelf.c:2759
+#, c-format
+msgid "cannot get data for section %d: %s"
+msgstr ""
+
+#: src/readelf.c:2813
+#, c-format
+msgid ""
+" Symbol Bias: %u\n"
+" Bitmask Size: %zu bytes  %<PRIuFAST32>%% bits set  2nd hash shift: %u\n"
+msgstr ""
+
+#: src/readelf.c:2887
+#, c-format
+msgid ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2901
+msgid ""
+"       Library                       Time Stamp          Checksum Version "
+"Flags"
+msgstr ""
+
+#: src/readelf.c:2951
+#, c-format
+msgid ""
+"\n"
+"Object attributes section [%2zu] '%s' of %<PRIu64> bytes at offset %"
+"#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:2967
+msgid "  Owner          Size\n"
+msgstr ""
+
+#: src/readelf.c:2993
+#, c-format
+msgid "  %-13s  %4<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3025
+#, c-format
+msgid "    %-4u %12<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3030
+#, c-format
+msgid "    File: %11<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3065
+#, c-format
+msgid "      %s: %<PRId64>, %s\n"
+msgstr ""
+
+#: src/readelf.c:3068
+#, c-format
+msgid "      %s: %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:3071
+#, c-format
+msgid "      %s: %s\n"
+msgstr ""
+
+#: src/readelf.c:3078
+#, c-format
+msgid "      %u: %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:3081
+#, c-format
+msgid "      %u: %s\n"
+msgstr ""
+
+#: src/readelf.c:3117
+#, c-format
+msgid "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3120
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3125
+#, c-format
+msgid "%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3128
+#, c-format
+msgid "%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3134
+#, c-format
+msgid "%s+%#<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3137
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3141
+#, c-format
+msgid "%#<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3144
+#, c-format
+msgid "%#0*<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3149
+#, c-format
+msgid "%s+%#<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3152
+#, c-format
+msgid "%s+%#0*<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3260
+#, c-format
+msgid "unknown tag %hx"
+msgstr ""
+
+#: src/readelf.c:3262
+#, c-format
+msgid "unknown user tag %hx"
+msgstr ""
+
+#: src/readelf.c:3480
+#, c-format
+msgid "unknown attribute %hx"
+msgstr ""
+
+#: src/readelf.c:3483
+#, c-format
+msgid "unknown user attribute %hx"
+msgstr ""
+
+#: src/readelf.c:3529
+#, c-format
+msgid "unknown form %<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3763
+msgid "empty block"
+msgstr ""
+
+#: src/readelf.c:3766
+#, c-format
+msgid "%zu byte block:"
+msgstr ""
+
+#: src/readelf.c:4175
+#, c-format
+msgid "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+msgstr ""
+
+#: src/readelf.c:4188
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [ Code]\n"
+msgstr ""
+
+#: src/readelf.c:4195
+#, c-format
+msgid ""
+"\n"
+"Abbreviation section at offset %<PRIu64>:\n"
+msgstr ""
+
+#: src/readelf.c:4208
+#, c-format
+msgid " *** error while reading abbreviation: %s\n"
+msgstr ""
+
+#: src/readelf.c:4224
+#, c-format
+msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
+msgstr ""
+
+#: src/readelf.c:4227
+msgid "yes"
+msgstr ""
+
+#: src/readelf.c:4227
+msgid "no"
+msgstr ""
+
+#: src/readelf.c:4263
+#, c-format
+msgid "cannot get .debug_aranges content: %s"
+msgstr ""
+
+#: src/readelf.c:4268
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:4298
+#, c-format
+msgid " [%*zu] ???\n"
+msgstr ""
+
+#: src/readelf.c:4300
+#, c-format
+msgid ""
+" [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:4319
+#, c-format
+msgid "cannot get .debug_ranges content: %s"
+msgstr ""
+
+#: src/readelf.c:4324 src/readelf.c:4810 src/readelf.c:5452 src/readelf.c:5897
+#: src/readelf.c:5992 src/readelf.c:6164
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:4338 src/readelf.c:5911
+#, c-format
+msgid " [%6tx]  <INVALID DATA>\n"
+msgstr ""
+
+#: src/readelf.c:4360 src/readelf.c:5933
+#, c-format
+msgid " [%6tx]  base address %s\n"
+msgstr ""
+
+#: src/readelf.c:4371
+#, c-format
+msgid " [%6tx]  %s..%s\n"
+msgstr ""
+
+#: src/readelf.c:4373
+#, c-format
+msgid "           %s..%s\n"
+msgstr ""
+
+#: src/readelf.c:4799 src/readelf.c:6230 src/readelf.c:6332
+#, c-format
+msgid "cannot get %s content: %s"
+msgstr ""
+
+#: src/readelf.c:4806
+#, c-format
+msgid ""
+"\n"
+"Call frame information section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:4833 src/readelf.c:5486
+#, c-format
+msgid "invalid data in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:4855
+#, c-format
+msgid ""
+"\n"
+" [%6tx] Zero terminator\n"
+msgstr ""
+
+#: src/readelf.c:4924
+#, c-format
+msgid "invalid augmentation length"
+msgstr ""
+
+#: src/readelf.c:4936
+msgid "FDE address encoding: "
+msgstr ""
+
+#: src/readelf.c:4942
+msgid "LSDA pointer encoding: "
+msgstr ""
+
+#: src/readelf.c:5034
+#, c-format
+msgid " (offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5041
+#, c-format
+msgid " (end offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5068
+#, c-format
+msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:5114
+#, c-format
+msgid "cannot get attribute code: %s"
+msgstr ""
+
+#: src/readelf.c:5122
+#, c-format
+msgid "cannot get attribute form: %s"
+msgstr ""
+
+#: src/readelf.c:5135
+#, c-format
+msgid "cannot get attribute value: %s"
+msgstr ""
+
+#: src/readelf.c:5331
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [Offset]\n"
+msgstr ""
+
+#: src/readelf.c:5356
+#, c-format
+msgid ""
+" Compilation unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: %"
+"<PRIu8>, Offset size: %<PRIu8>\n"
+msgstr ""
+
+#: src/readelf.c:5374
+#, c-format
+msgid "cannot get DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:5385
+#, c-format
+msgid "cannot get DIE offset: %s"
+msgstr ""
+
+#: src/readelf.c:5393
+#, c-format
+msgid "cannot get tag of DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:5422
+#, c-format
+msgid "cannot get next DIE: %s\n"
+msgstr ""
+
+#: src/readelf.c:5429
+#, c-format
+msgid "cannot get next DIE: %s"
+msgstr ""
+
+#: src/readelf.c:5464
+#, c-format
+msgid "cannot get line data section data: %s"
+msgstr ""
+
+#: src/readelf.c:5477
+#, c-format
+msgid ""
+"\n"
+"Table at offset %Zu:\n"
+msgstr ""
+
+#: src/readelf.c:5529
+#, c-format
+msgid ""
+"\n"
+" Length:                     %<PRIu64>\n"
+" DWARF version:              %<PRIuFAST16>\n"
+" Prologue length:            %<PRIu64>\n"
+" Minimum instruction length: %<PRIuFAST8>\n"
+" Initial value if '%s': %<PRIuFAST8>\n"
+" Line base:                  %<PRIdFAST8>\n"
+" Line range:                 %<PRIuFAST8>\n"
+" Opcode base:                %<PRIuFAST8>\n"
+"\n"
+"Opcodes:\n"
+msgstr ""
+
+#: src/readelf.c:5548
+#, c-format
+msgid "invalid data at offset %tu in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:5563
+#, c-format
+msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
+msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:5571
+msgid ""
+"\n"
+"Directory table:"
+msgstr ""
+
+#: src/readelf.c:5587
+msgid ""
+"\n"
+"File name table:\n"
+" Entry Dir   Time      Size      Name"
+msgstr ""
+
+#: src/readelf.c:5616
+msgid ""
+"\n"
+"Line number statements:"
+msgstr ""
+
+#: src/readelf.c:5677
+#, c-format
+msgid " special opcode %u: address+%u = %s, line%+d = %zu\n"
+msgstr ""
+
+#: src/readelf.c:5697
+#, c-format
+msgid " extended opcode %u: "
+msgstr ""
+
+#: src/readelf.c:5702
+msgid "end of sequence"
+msgstr ""
+
+#: src/readelf.c:5717
+#, c-format
+msgid "set address to %s\n"
+msgstr ""
+
+#: src/readelf.c:5738
+#, c-format
+msgid "define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
+msgstr ""
+
+#: src/readelf.c:5747
+msgid "unknown opcode"
+msgstr ""
+
+#: src/readelf.c:5759
+msgid " copy"
+msgstr ""
+
+#: src/readelf.c:5769
+#, c-format
+msgid "advance address by %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5780
+#, c-format
+msgid " advance line by constant %d to %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:5788
+#, c-format
+msgid " set file to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:5798
+#, c-format
+msgid " set column to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:5805
+#, c-format
+msgid " set '%s' to %<PRIuFAST8>\n"
+msgstr ""
+
+#: src/readelf.c:5811
+msgid " set basic block flag"
+msgstr ""
+
+#: src/readelf.c:5821
+#, c-format
+msgid "advance address by constant %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5837
+#, c-format
+msgid "advance address by fixed value %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5846
+msgid " set prologue end flag"
+msgstr ""
+
+#: src/readelf.c:5851
+msgid " set epilogue begin flag"
+msgstr ""
+
+#: src/readelf.c:5860
+#, c-format
+msgid " unknown opcode with %<PRIu8> parameter:"
+msgid_plural " unknown opcode with %<PRIu8> parameters:"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:5892
+#, c-format
+msgid "cannot get .debug_loc content: %s"
+msgstr ""
+
+#: src/readelf.c:5947
+#, c-format
+msgid " [%6tx]  %s..%s"
+msgstr ""
+
+#: src/readelf.c:5949
+#, c-format
+msgid "           %s..%s"
+msgstr ""
+
+#: src/readelf.c:6002
+#, c-format
+msgid "cannot get macro information section data: %s"
+msgstr ""
+
+#: src/readelf.c:6081
+#, c-format
+msgid "%*s*** non-terminated string at end of section"
+msgstr ""
+
+#: src/readelf.c:6149
+#, c-format
+msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
+msgstr ""
+
+#: src/readelf.c:6188
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" %*s  String\n"
+msgstr ""
+
+#: src/readelf.c:6202
+#, c-format
+msgid " *** error while reading strings: %s\n"
+msgstr ""
+
+#: src/readelf.c:6222
+#, c-format
+msgid ""
+"\n"
+"Call frame search table section [%2zu] '.eh_frame_hdr':\n"
+msgstr ""
+
+#: src/readelf.c:6324
+#, c-format
+msgid ""
+"\n"
+"Exception handling table section [%2zu] '.gcc_except_table':\n"
+msgstr ""
+
+#: src/readelf.c:6347
+#, c-format
+msgid " LPStart encoding:    %#x "
+msgstr ""
+
+#: src/readelf.c:6359
+#, c-format
+msgid " TType encoding:      %#x "
+msgstr ""
+
+#: src/readelf.c:6373
+#, c-format
+msgid " Call site encoding:  %#x "
+msgstr ""
+
+#: src/readelf.c:6386
+msgid ""
+"\n"
+" Call site table:"
+msgstr ""
+
+#: src/readelf.c:6400
+#, c-format
+msgid ""
+" [%4u] Call site start:   %#<PRIx64>\n"
+"        Call site length:  %<PRIu64>\n"
+"        Landing pad:       %#<PRIx64>\n"
+"        Action:            %u\n"
+msgstr ""
+
+#: src/readelf.c:6460
+#, c-format
+msgid "invalid TType encoding"
+msgstr ""
+
+#: src/readelf.c:6484
+#, c-format
+msgid "cannot get debug context descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:6620 src/readelf.c:7221
+#, c-format
+msgid "cannot convert core note data: %s"
+msgstr ""
+
+#: src/readelf.c:6961
+#, c-format
+msgid ""
+"\n"
+"%*s... <repeats %u more times> ..."
+msgstr ""
+
+#: src/readelf.c:7320
+msgid "  Owner          Data size  Type\n"
+msgstr ""
+
+#: src/readelf.c:7338
+#, c-format
+msgid "  %-13.*s  %9<PRId32>  %s\n"
+msgstr ""
+
+#: src/readelf.c:7372
+#, c-format
+msgid "cannot get content of note section: %s"
+msgstr ""
+
+#: src/readelf.c:7399
+#, c-format
+msgid ""
+"\n"
+"Note section [%2zu] '%s' of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7422
+#, c-format
+msgid ""
+"\n"
+"Note segment of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7468
+#, c-format
+msgid ""
+"\n"
+"Section [%Zu] '%s' has no data to dump.\n"
+msgstr ""
+
+#: src/readelf.c:7474 src/readelf.c:7497
+#, c-format
+msgid "cannot get data for section [%Zu] '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7478
+#, c-format
+msgid ""
+"\n"
+"Hex dump of section [%Zu] '%s', %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7491
+#, c-format
+msgid ""
+"\n"
+"Section [%Zu] '%s' has no strings to dump.\n"
+msgstr ""
+
+#: src/readelf.c:7501
+#, c-format
+msgid ""
+"\n"
+"String section [%Zu] '%s' contains %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7549
+#, c-format
+msgid ""
+"\n"
+"section [%lu] does not exist"
+msgstr ""
+
+#: src/readelf.c:7576
+#, c-format
+msgid ""
+"\n"
+"section '%s' does not exist"
+msgstr ""
+
+#: src/readelf.c:7637
+#, c-format
+msgid "cannot get symbol index of archive '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7640
+#, c-format
+msgid ""
+"\n"
+"Archive '%s' has no symbol index\n"
+msgstr ""
+
+#: src/readelf.c:7644
+#, c-format
+msgid ""
+"\n"
+"Index of archive '%s' has %Zu entries:\n"
+msgstr ""
+
+#: src/readelf.c:7662
+#, c-format
+msgid "cannot extract member at offset %Zu in '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7667
+#, c-format
+msgid "Archive member '%s' contains:\n"
+msgstr ""
+
+#: src/size.c:68
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd' or `sysv'.  The default "
+"is `bsd'"
+msgstr ""
+
+#: src/size.c:70
+msgid "Same as `--format=sysv'"
+msgstr ""
+
+#: src/size.c:71
+msgid "Same as `--format=bsd'"
+msgstr ""
+
+#: src/size.c:74
+msgid "Same as `--radix=10'"
+msgstr ""
+
+#: src/size.c:75
+msgid "Same as `--radix=8'"
+msgstr ""
+
+#: src/size.c:76
+msgid "Same as `--radix=16'"
+msgstr ""
+
+#: src/size.c:78
+msgid "Similar to `--format=sysv' output but in one line"
+msgstr ""
+
+#: src/size.c:82
+msgid "Print size and permission flags for loadable segments"
+msgstr ""
+
+#: src/size.c:83
+msgid "Display the total sizes (bsd only)"
+msgstr ""
+
+#: src/size.c:88
+msgid "List section sizes of FILEs (a.out by default)."
+msgstr ""
+
+#: src/size.c:269
+#, c-format
+msgid "Invalid format: %s"
+msgstr ""
+
+#: src/size.c:280
+#, c-format
+msgid "Invalid radix: %s"
+msgstr ""
+
+#: src/size.c:339
+#, c-format
+msgid "%s: file format not recognized"
+msgstr ""
+
+#: src/size.c:446 src/size.c:589
+#, c-format
+msgid " (ex %s)"
+msgstr ""
+
+#: src/size.c:614
+msgid "(TOTALS)\n"
+msgstr ""
+
+#: src/strings.c:70
+msgid "Output Selection:"
+msgstr ""
+
+#: src/strings.c:71
+msgid "Scan entire file, not only loaded sections"
+msgstr ""
+
+#: src/strings.c:73
+msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed"
+msgstr ""
+
+#: src/strings.c:74
+msgid ""
+"Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, "
+"{B,L} = 32-bit"
+msgstr ""
+
+#: src/strings.c:78
+msgid "Print name of the file before each string."
+msgstr ""
+
+#: src/strings.c:80
+msgid "Print location of the string in base 8, 10, or 16 respectively."
+msgstr ""
+
+#: src/strings.c:81
+msgid "Alias for --radix=o"
+msgstr ""
+
+#: src/strings.c:88
+msgid "Print the strings of printable characters in files."
+msgstr ""
+
+#: src/strings.c:268 src/strings.c:303
+#, c-format
+msgid "invalid value '%s' for %s parameter"
+msgstr ""
+
+#: src/strings.c:314
+#, c-format
+msgid "invalid minimum length of matched string size"
+msgstr ""
+
+#: src/strings.c:601
+#, c-format
+msgid "lseek64 failed"
+msgstr ""
+
+#: src/strings.c:616 src/strings.c:680
+#, c-format
+msgid "re-mmap failed"
+msgstr ""
+
+#: src/strings.c:653
+#, c-format
+msgid "mprotect failed"
+msgstr ""
+
+#: src/strip.c:74
+msgid "Place stripped output into FILE"
+msgstr ""
+
+#: src/strip.c:75
+msgid "Extract the removed sections into FILE"
+msgstr ""
+
+#: src/strip.c:76
+msgid "Embed name FILE instead of -f argument"
+msgstr ""
+
+#: src/strip.c:80
+msgid "Remove all debugging symbols"
+msgstr ""
+
+#: src/strip.c:84
+msgid "Copy modified/access timestamps to the output"
+msgstr ""
+
+#: src/strip.c:86
+msgid "Remove .comment section"
+msgstr ""
+
+#: src/strip.c:89
+msgid "Relax a few rules to handle slightly broken ELF files"
+msgstr ""
+
+#: src/strip.c:94
+msgid "Discard symbols from object files."
+msgstr ""
+
+#: src/strip.c:186
+#, c-format
+msgid "Only one input file allowed together with '-o' and '-f'"
+msgstr ""
+
+#: src/strip.c:222
+#, c-format
+msgid "-f option specified twice"
+msgstr ""
+
+#: src/strip.c:231
+#, c-format
+msgid "-F option specified twice"
+msgstr ""
+
+#: src/strip.c:240 src/unstrip.c:125
+#, c-format
+msgid "-o option specified twice"
+msgstr ""
+
+#: src/strip.c:260
+#, c-format
+msgid "-R option supports only .comment section"
+msgstr ""
+
+#: src/strip.c:298 src/strip.c:322
+#, c-format
+msgid "cannot stat input file '%s'"
+msgstr ""
+
+#: src/strip.c:312
+#, c-format
+msgid "while opening '%s'"
+msgstr ""
+
+#: src/strip.c:350
+#, c-format
+msgid "%s: cannot use -o or -f when stripping archive"
+msgstr ""
+
+#: src/strip.c:448
+#, c-format
+msgid "cannot open EBL backend"
+msgstr ""
+
+#: src/strip.c:498 src/strip.c:522
+#, c-format
+msgid "cannot create new file '%s': %s"
+msgstr ""
+
+#: src/strip.c:582
+#, c-format
+msgid "illformed file '%s'"
+msgstr ""
+
+#: src/strip.c:869 src/strip.c:956
+#, c-format
+msgid "while generating output file: %s"
+msgstr ""
+
+#: src/strip.c:929 src/strip.c:1668
+#, c-format
+msgid "%s: error while creating ELF header: %s"
+msgstr ""
+
+#: src/strip.c:943
+#, c-format
+msgid "while preparing output for '%s'"
+msgstr ""
+
+#: src/strip.c:994 src/strip.c:1050
+#, c-format
+msgid "while create section header section: %s"
+msgstr ""
+
+#: src/strip.c:1000
+#, c-format
+msgid "cannot allocate section data: %s"
+msgstr ""
+
+#: src/strip.c:1059
+#, c-format
+msgid "while create section header string table: %s"
+msgstr ""
+
+#: src/strip.c:1593 src/strip.c:1690
+#, c-format
+msgid "while writing '%s': %s"
+msgstr ""
+
+#: src/strip.c:1604
+#, c-format
+msgid "while creating '%s'"
+msgstr ""
+
+#: src/strip.c:1616
+#, c-format
+msgid "while computing checksum for debug information"
+msgstr ""
+
+#: src/strip.c:1676
+#, c-format
+msgid "%s: error while reading the file: %s"
+msgstr ""
+
+#: src/strip.c:1722 src/strip.c:1729
+#, c-format
+msgid "error while finishing '%s': %s"
+msgstr ""
+
+#: src/strip.c:1752 src/strip.c:1809
+#, c-format
+msgid "cannot set access and modification date of '%s'"
+msgstr ""
+
+#: src/unstrip.c:78
+msgid "Match MODULE against file names, not module names"
+msgstr ""
+
+#: src/unstrip.c:79
+msgid "Silently skip unfindable files"
+msgstr ""
+
+#: src/unstrip.c:82
+msgid "Place output into FILE"
+msgstr ""
+
+#: src/unstrip.c:84
+msgid "Create multiple output files under DIRECTORY"
+msgstr ""
+
+#: src/unstrip.c:85
+msgid "Use module rather than file names"
+msgstr ""
+
+#: src/unstrip.c:87
+msgid "Create output for modules that have no separate debug information"
+msgstr ""
+
+#: src/unstrip.c:90
+msgid "Apply relocations to section contents in ET_REL files"
+msgstr ""
+
+#: src/unstrip.c:92
+msgid "Only list module and file names, build IDs"
+msgstr ""
+
+#: src/unstrip.c:134
+#, c-format
+msgid "-d option specified twice"
+msgstr ""
+
+#: src/unstrip.c:166
+#, c-format
+msgid "only one of -o or -d allowed"
+msgstr ""
+
+#: src/unstrip.c:175
+#, c-format
+msgid "-n cannot be used with explicit files or -o or -d"
+msgstr ""
+
+#: src/unstrip.c:190
+#, c-format
+msgid "output directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:199
+#, c-format
+msgid "exactly two file arguments are required"
+msgstr ""
+
+#: src/unstrip.c:205
+#, c-format
+msgid "-m, -a, -R, and -i options not allowed with explicit files"
+msgstr ""
+
+#: src/unstrip.c:218
+#, c-format
+msgid "-o or -d is required when using implicit files"
+msgstr ""
+
+#: src/unstrip.c:254
+#, c-format
+msgid "cannot create ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:259
+#, c-format
+msgid "cannot copy ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:264 src/unstrip.c:1817
+#, c-format
+msgid "cannot create program headers: %s"
+msgstr ""
+
+#: src/unstrip.c:270
+#, c-format
+msgid "cannot copy program header: %s"
+msgstr ""
+
+#: src/unstrip.c:280
+#, c-format
+msgid "cannot copy section header: %s"
+msgstr ""
+
+#: src/unstrip.c:283 src/unstrip.c:1505
+#, c-format
+msgid "cannot get section data: %s"
+msgstr ""
+
+#: src/unstrip.c:285 src/unstrip.c:1507
+#, c-format
+msgid "cannot copy section data: %s"
+msgstr ""
+
+#: src/unstrip.c:309
+#, c-format
+msgid "cannot create directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:349 src/unstrip.c:763 src/unstrip.c:1540
+#, c-format
+msgid "cannot get symbol table entry: %s"
+msgstr ""
+
+#: src/unstrip.c:365 src/unstrip.c:580 src/unstrip.c:601 src/unstrip.c:613
+#: src/unstrip.c:1561 src/unstrip.c:1691 src/unstrip.c:1715
+#, c-format
+msgid "cannot update symbol table: %s"
+msgstr ""
+
+#: src/unstrip.c:382 src/unstrip.c:432 src/unstrip.c:562 src/unstrip.c:1209
+#: src/unstrip.c:1525 src/unstrip.c:1720 src/unstrip.c:1791
+#, c-format
+msgid "cannot update section header: %s"
+msgstr ""
+
+#: src/unstrip.c:408 src/unstrip.c:419
+#, c-format
+msgid "cannot update relocation: %s"
+msgstr ""
+
+#: src/unstrip.c:507
+#, c-format
+msgid "cannot get symbol version: %s"
+msgstr ""
+
+#: src/unstrip.c:519
+#, c-format
+msgid "unexpected section type in [%Zu] with sh_link to symtab"
+msgstr ""
+
+#: src/unstrip.c:769
+#, c-format
+msgid "invalid string offset in symbol [%Zu]"
+msgstr ""
+
+#: src/unstrip.c:911 src/unstrip.c:1248
+#, c-format
+msgid "cannot read section [%Zu] name: %s"
+msgstr ""
+
+#: src/unstrip.c:952 src/unstrip.c:971 src/unstrip.c:1004
+#, c-format
+msgid "cannot read '.gnu.prelink_undo' section: %s"
+msgstr ""
+
+#: src/unstrip.c:992
+#, c-format
+msgid "invalid contents in '%s' section"
+msgstr ""
+
+#: src/unstrip.c:1047 src/unstrip.c:1370
+#, c-format
+msgid "cannot find matching section for [%Zu] '%s'"
+msgstr ""
+
+#: src/unstrip.c:1171 src/unstrip.c:1186 src/unstrip.c:1451
+#, c-format
+msgid "cannot add section name to string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1195
+#, c-format
+msgid "cannot update section header string table data: %s"
+msgstr ""
+
+#: src/unstrip.c:1223 src/unstrip.c:1227
+#, c-format
+msgid "cannot get section header string table section index: %s"
+msgstr ""
+
+#: src/unstrip.c:1231 src/unstrip.c:1235 src/unstrip.c:1466
+#, c-format
+msgid "cannot get section count: %s"
+msgstr ""
+
+#: src/unstrip.c:1293 src/unstrip.c:1385
+#, c-format
+msgid "cannot read section header string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1445
+#, c-format
+msgid "cannot add new section: %s"
+msgstr ""
+
+#: src/unstrip.c:1548
+#, c-format
+msgid "symbol [%Zu] has invalid section index"
+msgstr ""
+
+#: src/unstrip.c:1800
+#, c-format
+msgid "cannot get ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:1827
+#, c-format
+msgid "cannot update program header: %s"
+msgstr ""
+
+#: src/unstrip.c:1832 src/unstrip.c:1911
+#, c-format
+msgid "cannot write output file: %s"
+msgstr ""
+
+#: src/unstrip.c:1880
+#, c-format
+msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:1883
+#, c-format
+msgid ""
+"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:1902 src/unstrip.c:1942 src/unstrip.c:1954 src/unstrip.c:2034
+#, c-format
+msgid "cannot create ELF descriptor: %s"
+msgstr ""
+
+#: src/unstrip.c:1960
+#, c-format
+msgid "'%s' and '%s' do not seem to match"
+msgstr ""
+
+#: src/unstrip.c:1991
+#, c-format
+msgid "cannot find stripped file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:1995
+#, c-format
+msgid "cannot open stripped file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2010
+#, c-format
+msgid "cannot find debug file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2014
+#, c-format
+msgid "cannot open debug file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2027
+#, c-format
+msgid "module '%s' file '%s' is not stripped"
+msgstr ""
+
+#: src/unstrip.c:2058
+#, c-format
+msgid "cannot cache section addresses for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2191
+#, c-format
+msgid "no matching modules found"
+msgstr ""
+
+#: src/unstrip.c:2200
+#, c-format
+msgid "matched more than one module"
+msgstr ""
+
+#: src/unstrip.c:2247
+msgid ""
+"STRIPPED-FILE DEBUG-FILE\n"
+"[MODULE...]"
+msgstr ""
+
+#: src/unstrip.c:2248
+msgid ""
+"Combine stripped files with separate symbols and debug information.\n\nThe "
+"first form puts the result in DEBUG-FILE if -o was not given.\n"
+"\n"
+"MODULE arguments give file name patterns matching modules to process.\n"
+"With -f these match the file name of the main (stripped) file (slashes are "
+"never special), otherwise they match the simple module names.  With no "
+"arguments, process all modules found.\n"
+"\n"
+"Multiple modules are written to files under OUTPUT-DIRECTORY, creating "
+"subdirectories as needed.  With -m these files have simple module names, "
+"otherwise they have the name of the main file complete with directory "
+"underneath OUTPUT-DIRECTORY.\n"
+"\n"
+"With -n no files are written, but one line to standard output for each "
+"module:\n"
+"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n"
+"START and SIZE are hexadecimal giving the address bounds of the module.  "
+"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the "
+"hexadecimal may be followed by @0xADDR giving the address where the ID "
+"resides if that is known.  FILE is the file name found for the module, or - "
+"if none was found, or . if an ELF image is available but not from any named "
+"file.  DEBUGFILE is the separate debuginfo file name, or - if no debuginfo "
+"was found, or . if FILE contains the debug information."
+msgstr ""
diff --git a/third_party/elfutils/po/ja.po b/third_party/elfutils/po/ja.po
new file mode 100644
index 0000000..68ca8a7
--- /dev/null
+++ b/third_party/elfutils/po/ja.po
@@ -0,0 +1,6931 @@
+# translation of ja.po to Japanese
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Kiyoto Hashida <khashida@redhat.com>, 2009.
+# Hyu_gabaru Ryu_ichi <hyu_gabaru@yahoo.co.jp>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: ja\n"
+"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n"
+"POT-Creation-Date: 2017-09-01 12:27+0200\n"
+"PO-Revision-Date: 2009-09-20 15:32+0900\n"
+"Last-Translator: Hyu_gabaru Ryu_ichi <hyu_gabaru@yahoo.co.jp>\n"
+"Language-Team: Japanese <jp@li.org>\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: lib/color.c:53
+msgid ""
+"colorize the output.  WHEN defaults to 'always' or can be 'auto' or 'never'"
+msgstr ""
+
+#: lib/color.c:127
+#, c-format
+msgid ""
+"%s: invalid argument '%s' for '--color'\n"
+"valid arguments are:\n"
+"  - 'always', 'yes', 'force'\n"
+"  - 'never', 'no', 'none'\n"
+"  - 'auto', 'tty', 'if-tty'\n"
+msgstr ""
+
+#: lib/color.c:190 src/objdump.c:727
+#, fuzzy, c-format
+msgid "cannot allocate memory"
+msgstr "PLT セクションを割り当てられません: %s"
+
+#: lib/printversion.c:40
+#, fuzzy, c-format
+msgid ""
+"Copyright (C) %s The elfutils developers <%s>.\n"
+"This is free software; see the source for copying conditions.  There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+"Copyright (C) %s Red Hat, Inc.\n"
+"This is free software; see the source for copying conditions.  There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+
+#: lib/xmalloc.c:53 lib/xmalloc.c:66 lib/xmalloc.c:78 src/readelf.c:3310
+#: src/readelf.c:3701 src/readelf.c:8540 src/unstrip.c:2227 src/unstrip.c:2433
+#, c-format
+msgid "memory exhausted"
+msgstr "メモリー消費済み"
+
+#: libasm/asm_error.c:65 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:50
+#: libelf/elf_error.c:60
+msgid "no error"
+msgstr "エラー無し"
+
+#: libasm/asm_error.c:66 libdw/dwarf_error.c:68 libdwfl/libdwflP.h:52
+#: libelf/elf_error.c:91
+msgid "out of memory"
+msgstr "メモリー不足"
+
+#: libasm/asm_error.c:67
+msgid "cannot create output file"
+msgstr "出力ファイルを作成できません"
+
+#: libasm/asm_error.c:68
+msgid "invalid parameter"
+msgstr "不当なパラメーター"
+
+#: libasm/asm_error.c:69
+msgid "cannot change mode of output file"
+msgstr "出力ファイルのモードを変更できません"
+
+#: libasm/asm_error.c:70
+msgid "cannot rename output file"
+msgstr "出力ファイルの名前を変更できません"
+
+#: libasm/asm_error.c:71
+msgid "duplicate symbol"
+msgstr "重複シンボル"
+
+#: libasm/asm_error.c:72
+msgid "invalid section type for operation"
+msgstr "操作に不当なセクションタイプ"
+
+#: libasm/asm_error.c:73
+msgid "error during output of data"
+msgstr "データの出力中にエラー"
+
+#: libasm/asm_error.c:74
+msgid "no backend support available"
+msgstr "バックエンドサポートが利用できません"
+
+#: libasm/asm_error.c:83 libdw/dwarf_error.c:59 libdwfl/libdwflP.h:51
+#: libelf/elf_error.c:63
+msgid "unknown error"
+msgstr "不明なエラー"
+
+#: libdw/dwarf_error.c:60
+msgid "invalid access"
+msgstr "不当なアクセス"
+
+#: libdw/dwarf_error.c:61
+msgid "no regular file"
+msgstr "一般ファイルではありません"
+
+#: libdw/dwarf_error.c:62
+msgid "I/O error"
+msgstr "I/O エラー"
+
+#: libdw/dwarf_error.c:63
+msgid "invalid ELF file"
+msgstr "不当な ELF ファイル"
+
+#: libdw/dwarf_error.c:64
+msgid "no DWARF information"
+msgstr "DWARF 情報がありません"
+
+#: libdw/dwarf_error.c:65
+msgid "cannot decompress DWARF"
+msgstr ""
+
+#: libdw/dwarf_error.c:66
+msgid "no ELF file"
+msgstr "ELF ファイルがありません"
+
+#: libdw/dwarf_error.c:67
+msgid "cannot get ELF header"
+msgstr "ELF ヘッダーを得られません"
+
+#: libdw/dwarf_error.c:69
+msgid "not implemented"
+msgstr "未実装"
+
+#: libdw/dwarf_error.c:70 libelf/elf_error.c:107 libelf/elf_error.c:155
+msgid "invalid command"
+msgstr "不当なコマンド"
+
+#: libdw/dwarf_error.c:71
+msgid "invalid version"
+msgstr "不当なバージョン"
+
+#: libdw/dwarf_error.c:72
+msgid "invalid file"
+msgstr "不当なファイル"
+
+#: libdw/dwarf_error.c:73
+msgid "no entries found"
+msgstr "項目が見つかりません"
+
+#: libdw/dwarf_error.c:74
+msgid "invalid DWARF"
+msgstr "不当な DWARF"
+
+#: libdw/dwarf_error.c:75
+msgid "no string data"
+msgstr "文字データがありません"
+
+#: libdw/dwarf_error.c:76
+msgid "no address value"
+msgstr "アドレス値ではありません"
+
+#: libdw/dwarf_error.c:77
+msgid "no constant value"
+msgstr "固定値ではありません"
+
+#: libdw/dwarf_error.c:78
+msgid "no reference value"
+msgstr "参照値がありません"
+
+#: libdw/dwarf_error.c:79
+msgid "invalid reference value"
+msgstr "不当な参照値"
+
+#: libdw/dwarf_error.c:80
+msgid ".debug_line section missing"
+msgstr ".debug_line セクションがありません"
+
+#: libdw/dwarf_error.c:81
+msgid "invalid .debug_line section"
+msgstr "不当な .debug_line セクション"
+
+#: libdw/dwarf_error.c:82
+msgid "debug information too big"
+msgstr "デバッグ情報が大きすぎます"
+
+#: libdw/dwarf_error.c:83
+msgid "invalid DWARF version"
+msgstr "不当な DWARF バージョン"
+
+#: libdw/dwarf_error.c:84
+msgid "invalid directory index"
+msgstr "不当なディレクトリー索引"
+
+#: libdw/dwarf_error.c:85 libdwfl/libdwflP.h:71
+msgid "address out of range"
+msgstr "アドレスが範囲外です"
+
+#: libdw/dwarf_error.c:86
+msgid "no location list value"
+msgstr "ロケーションリスト値ではありません"
+
+#: libdw/dwarf_error.c:87
+msgid "no block data"
+msgstr "ブロックデータではありません"
+
+#: libdw/dwarf_error.c:88
+msgid "invalid line index"
+msgstr "不当な行索引"
+
+#: libdw/dwarf_error.c:89
+msgid "invalid address range index"
+msgstr "不当なアドレス範囲索引"
+
+#: libdw/dwarf_error.c:90 libdwfl/libdwflP.h:72
+msgid "no matching address range"
+msgstr "アドレス範囲に対応しません"
+
+#: libdw/dwarf_error.c:91
+msgid "no flag value"
+msgstr "フラグ値がありません"
+
+#: libdw/dwarf_error.c:92 libelf/elf_error.c:232
+msgid "invalid offset"
+msgstr "不当なオフセット"
+
+#: libdw/dwarf_error.c:93
+msgid ".debug_ranges section missing"
+msgstr ".debug_ranges セクションがありません"
+
+#: libdw/dwarf_error.c:94
+msgid "invalid CFI section"
+msgstr "不当な CFI セクション"
+
+#: libdw/dwarf_error.c:95
+msgid "no alternative debug link found"
+msgstr ""
+
+#: libdw/dwarf_error.c:96
+#, fuzzy
+msgid "invalid opcode"
+msgstr "不当なオペランド"
+
+#: libdw/dwarf_error.c:97
+msgid "not a CU (unit) DIE"
+msgstr ""
+
+#: libdw/dwarf_error.c:98
+#, fuzzy
+msgid "unknown language code"
+msgstr "不明な命令コード"
+
+#: libdwfl/argp-std.c:50 src/stack.c:639 src/unstrip.c:2374
+msgid "Input selection options:"
+msgstr "選択オプションを入力してください:"
+
+#: libdwfl/argp-std.c:51
+msgid "Find addresses in FILE"
+msgstr "ふぁいる 中のアドレスを探す"
+
+#: libdwfl/argp-std.c:53
+msgid "Find addresses from signatures found in COREFILE"
+msgstr "COREFILE 中で見つかった署名からアドレスを探す"
+
+#: libdwfl/argp-std.c:55
+msgid "Find addresses in files mapped into process PID"
+msgstr "プロセス PID に対応するファイル中のアドレスを探す"
+
+#: libdwfl/argp-std.c:57
+msgid ""
+"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps "
+"format"
+msgstr ""
+"Linux の /proc/PID/maps 形式の ふぁいる から読み込んだものに対応するファイル"
+"のアドレスを探す"
+
+#: libdwfl/argp-std.c:59
+msgid "Find addresses in the running kernel"
+msgstr "実行中のカーネルのアドレスを探す"
+
+#: libdwfl/argp-std.c:61
+msgid "Kernel with all modules"
+msgstr "全てのモジュール付きのカーネル"
+
+#: libdwfl/argp-std.c:63 src/stack.c:646
+msgid "Search path for separate debuginfo files"
+msgstr "分離した debuginfo ファイルべきパスを探す"
+
+#: libdwfl/argp-std.c:164
+msgid "only one of -e, -p, -k, -K, or --core allowed"
+msgstr "-e か、-p、-k、-K、--core のひとつだけが認められます"
+
+#: libdwfl/argp-std.c:237
+msgid "cannot load kernel symbols"
+msgstr "カーネルシンボルをロードできません"
+
+#. Non-fatal to have no modules since we do have the kernel.
+#: libdwfl/argp-std.c:241
+msgid "cannot find kernel modules"
+msgstr "カーネルモジュールを見つけられません"
+
+#: libdwfl/argp-std.c:258
+msgid "cannot find kernel or modules"
+msgstr "カーネルかモジュールを見つけられません"
+
+#: libdwfl/argp-std.c:297
+#, c-format
+msgid "cannot read ELF core file: %s"
+msgstr "ELF コアファイルを読めません: %s"
+
+#: libdwfl/argp-std.c:320
+#, fuzzy
+msgid "Not enough memory"
+msgstr "メモリー不足"
+
+#: libdwfl/argp-std.c:330
+msgid "No modules recognized in core file"
+msgstr "コアファイルの中にモジュールを認識できません"
+
+#: libdwfl/libdwflP.h:53
+msgid "See errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:54
+msgid "See elf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:55
+msgid "See dwarf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:56
+msgid "See ebl_errno (XXX missing)"
+msgstr ""
+
+#: libdwfl/libdwflP.h:57
+msgid "gzip decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:58
+msgid "bzip2 decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:59
+msgid "LZMA decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:60
+msgid "no support library found for machine"
+msgstr ""
+
+#: libdwfl/libdwflP.h:61
+msgid "Callbacks missing for ET_REL file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:62
+msgid "Unsupported relocation type"
+msgstr ""
+
+#: libdwfl/libdwflP.h:63
+msgid "r_offset is bogus"
+msgstr ""
+
+#: libdwfl/libdwflP.h:64 libelf/elf_error.c:111 libelf/elf_error.c:171
+msgid "offset out of range"
+msgstr "オフセットが範囲を越えている"
+
+#: libdwfl/libdwflP.h:65
+#, fuzzy
+msgid "relocation refers to undefined symbol"
+msgstr "定義されたシンボルの印刷サイズ"
+
+#: libdwfl/libdwflP.h:66
+msgid "Callback returned failure"
+msgstr ""
+
+#: libdwfl/libdwflP.h:67
+#, fuzzy
+msgid "No DWARF information found"
+msgstr "DWARF 情報がありません"
+
+#: libdwfl/libdwflP.h:68
+msgid "No symbol table found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:69
+#, fuzzy
+msgid "No ELF program headers"
+msgstr "プログラムヘッダーを得られません: %s"
+
+#: libdwfl/libdwflP.h:70
+msgid "address range overlaps an existing module"
+msgstr ""
+
+#: libdwfl/libdwflP.h:73
+msgid "image truncated"
+msgstr ""
+
+#: libdwfl/libdwflP.h:74
+#, fuzzy
+msgid "ELF file opened"
+msgstr "ファイルのオープンを追跡します。"
+
+#: libdwfl/libdwflP.h:75
+#, fuzzy
+msgid "not a valid ELF file"
+msgstr "不当な ELF ファイル"
+
+#: libdwfl/libdwflP.h:76
+#, fuzzy
+msgid "cannot handle DWARF type description"
+msgstr "Elf 記述子を生成できません: %s"
+
+#: libdwfl/libdwflP.h:77
+msgid "ELF file does not match build ID"
+msgstr ""
+
+#: libdwfl/libdwflP.h:78
+#, fuzzy
+msgid "corrupt .gnu.prelink_undo section data"
+msgstr "ラインデータセクションデータを得られません: %s"
+
+#: libdwfl/libdwflP.h:79
+msgid "Internal error due to ebl"
+msgstr ""
+
+#: libdwfl/libdwflP.h:80
+msgid "Missing data in core file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:81
+#, fuzzy
+msgid "Invalid register"
+msgstr "不当なパラメーター"
+
+#: libdwfl/libdwflP.h:82
+msgid "Error reading process memory"
+msgstr ""
+
+#: libdwfl/libdwflP.h:83
+msgid "Couldn't find architecture of any ELF"
+msgstr ""
+
+#: libdwfl/libdwflP.h:84
+msgid "Error parsing /proc filesystem"
+msgstr ""
+
+#: libdwfl/libdwflP.h:85
+#, fuzzy
+msgid "Invalid DWARF"
+msgstr "不当な DWARF"
+
+#: libdwfl/libdwflP.h:86
+msgid "Unsupported DWARF"
+msgstr ""
+
+#: libdwfl/libdwflP.h:87
+msgid "Unable to find more threads"
+msgstr ""
+
+#: libdwfl/libdwflP.h:88
+msgid "Dwfl already has attached state"
+msgstr ""
+
+#: libdwfl/libdwflP.h:89
+msgid "Dwfl has no attached state"
+msgstr ""
+
+#: libdwfl/libdwflP.h:90
+msgid "Unwinding not supported for this architecture"
+msgstr ""
+
+#: libdwfl/libdwflP.h:91
+#, fuzzy
+msgid "Invalid argument"
+msgstr "不当なパラメーター"
+
+#: libdwfl/libdwflP.h:92
+#, fuzzy
+msgid "Not an ET_CORE ELF file"
+msgstr "不当な ELF ファイル"
+
+#: libebl/eblbackendname.c:41
+msgid "No backend"
+msgstr "バックエンドがありません"
+
+#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:76
+#: libebl/eblobjnotetypename.c:83 libebl/eblobjnotetypename.c:102
+#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83
+#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:79
+msgid "<unknown>"
+msgstr "<不明>"
+
+#: libebl/ebldynamictagname.c:101
+#, c-format
+msgid "<unknown>: %#<PRIx64>"
+msgstr "<不明>: %#<PRIx64>"
+
+#: libebl/eblobjnote.c:53
+#, fuzzy, c-format
+msgid "unknown SDT version %u\n"
+msgstr "不明なバージョン"
+
+#: libebl/eblobjnote.c:71
+#, fuzzy, c-format
+msgid "invalid SDT probe descriptor\n"
+msgstr "不当なファイル記述子"
+
+#: libebl/eblobjnote.c:121
+#, c-format
+msgid "    PC: "
+msgstr ""
+
+#: libebl/eblobjnote.c:123
+#, c-format
+msgid " Base: "
+msgstr ""
+
+#: libebl/eblobjnote.c:125
+#, c-format
+msgid " Semaphore: "
+msgstr ""
+
+#: libebl/eblobjnote.c:127
+#, c-format
+msgid "    Provider: "
+msgstr ""
+
+#: libebl/eblobjnote.c:129
+#, c-format
+msgid " Name: "
+msgstr ""
+
+#: libebl/eblobjnote.c:131
+#, c-format
+msgid " Args: "
+msgstr ""
+
+#: libebl/eblobjnote.c:141
+#, c-format
+msgid "    Build ID: "
+msgstr "   ビルト ID: "
+
+#. A non-null terminated version string.
+#: libebl/eblobjnote.c:152
+#, c-format
+msgid "    Linker version: %.*s\n"
+msgstr ""
+
+#: libebl/eblobjnote.c:213
+#, c-format
+msgid "    OS: %s, ABI: "
+msgstr "    OS: %s、ABI: "
+
+#: libebl/eblosabiname.c:70
+msgid "Stand alone"
+msgstr "スタンドアローン"
+
+#: libebl/eblsymbolbindingname.c:67 libebl/eblsymboltypename.c:73
+#, c-format
+msgid "<unknown>: %d"
+msgstr "<不明>: %d"
+
+#: libelf/elf_error.c:67
+msgid "unknown version"
+msgstr "不明なバージョン"
+
+#: libelf/elf_error.c:71
+msgid "unknown type"
+msgstr "不明なタイプ"
+
+#: libelf/elf_error.c:75
+msgid "invalid `Elf' handle"
+msgstr "無効な `Elf' の処理"
+
+#: libelf/elf_error.c:79
+msgid "invalid size of source operand"
+msgstr "ソース演算子の大きさが無効"
+
+#: libelf/elf_error.c:83
+msgid "invalid size of destination operand"
+msgstr "宛先演算子の大きさが無効"
+
+#: libelf/elf_error.c:87 src/readelf.c:5153
+#, c-format
+msgid "invalid encoding"
+msgstr "無効なエンコード"
+
+#: libelf/elf_error.c:95
+msgid "invalid file descriptor"
+msgstr "不当なファイル記述子"
+
+#: libelf/elf_error.c:99
+msgid "invalid operation"
+msgstr "不当な操作"
+
+#: libelf/elf_error.c:103
+msgid "ELF version not set"
+msgstr "ELF のバージョンが設定されていない"
+
+#: libelf/elf_error.c:115
+msgid "invalid fmag field in archive header"
+msgstr "アーカイブヘッダーの不当な fmag 領域"
+
+#: libelf/elf_error.c:119
+msgid "invalid archive file"
+msgstr "不当なアーカイブファイル"
+
+#: libelf/elf_error.c:123
+msgid "descriptor is not for an archive"
+msgstr "記述子はアーカイブ用ではありません"
+
+#: libelf/elf_error.c:127
+msgid "no index available"
+msgstr "索引が使えません"
+
+#: libelf/elf_error.c:131
+msgid "cannot read data from file"
+msgstr "ファイルからデータを読みません"
+
+#: libelf/elf_error.c:135
+msgid "cannot write data to file"
+msgstr "ファイルへデータを書けません"
+
+#: libelf/elf_error.c:139
+msgid "invalid binary class"
+msgstr "不当なバイナリークラス"
+
+#: libelf/elf_error.c:143
+msgid "invalid section index"
+msgstr "不当なセクション索引"
+
+#: libelf/elf_error.c:147
+msgid "invalid operand"
+msgstr "不当なオペランド"
+
+#: libelf/elf_error.c:151
+msgid "invalid section"
+msgstr "不当なセクション"
+
+#: libelf/elf_error.c:159
+msgid "executable header not created first"
+msgstr "エクゼキュータブルヘッダーが最初に作られていません"
+
+#: libelf/elf_error.c:163
+msgid "file descriptor disabled"
+msgstr "ファイル記述子が機能しません"
+
+#: libelf/elf_error.c:167
+#, fuzzy
+msgid "archive/member file descriptor mismatch"
+msgstr "アーカイブ/メンバー領域が不整合です"
+
+#: libelf/elf_error.c:175
+msgid "cannot manipulate null section"
+msgstr "null セクションを操作できません"
+
+#: libelf/elf_error.c:179
+msgid "data/scn mismatch"
+msgstr "データ/scnが不整合です"
+
+#: libelf/elf_error.c:183
+msgid "invalid section header"
+msgstr "不当なセクションヘッダー"
+
+#: libelf/elf_error.c:187 src/readelf.c:7403 src/readelf.c:7914
+#: src/readelf.c:8015 src/readelf.c:8196
+#, c-format
+msgid "invalid data"
+msgstr "不当なデータ"
+
+#: libelf/elf_error.c:191
+msgid "unknown data encoding"
+msgstr "不明なデータエンコード"
+
+#: libelf/elf_error.c:195
+msgid "section `sh_size' too small for data"
+msgstr "`sh_size' セクションがデータには小さすぎます"
+
+#: libelf/elf_error.c:199
+msgid "invalid section alignment"
+msgstr "不当なセクション調整"
+
+#: libelf/elf_error.c:203
+msgid "invalid section entry size"
+msgstr "不当なセクション項目の大きさ"
+
+#: libelf/elf_error.c:207
+msgid "update() for write on read-only file"
+msgstr "読込み専用ファイルでの書込みのための update()"
+
+#: libelf/elf_error.c:211
+msgid "no such file"
+msgstr "そのようなファイルはありません"
+
+#: libelf/elf_error.c:215
+msgid "only relocatable files can contain section groups"
+msgstr "リロケータブルファイルのみセクショングループを含むことができます"
+
+#: libelf/elf_error.c:220
+msgid ""
+"program header only allowed in executables, shared objects, and core files"
+msgstr ""
+"プログラムヘッダーはエクゼキュータブルか、共用オブジェクト、コアファイルにの"
+"み認められています"
+
+#: libelf/elf_error.c:227
+msgid "file has no program header"
+msgstr "ファイルにプログラムヘッダーがありません"
+
+#: libelf/elf_error.c:237
+#, fuzzy
+msgid "invalid section type"
+msgstr "不当なセクション"
+
+#: libelf/elf_error.c:242
+#, fuzzy
+msgid "invalid section flags"
+msgstr "不当なセクション"
+
+#: libelf/elf_error.c:247
+#, fuzzy
+msgid "section does not contain compressed data"
+msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
+
+#: libelf/elf_error.c:252
+msgid "section contains compressed data"
+msgstr ""
+
+#: libelf/elf_error.c:257
+#, fuzzy
+msgid "unknown compression type"
+msgstr "不明なタイプ"
+
+#: libelf/elf_error.c:262
+#, fuzzy
+msgid "cannot compress data"
+msgstr "セクションデータを割り当てられません: %s"
+
+#: libelf/elf_error.c:267
+#, fuzzy
+msgid "cannot decompress data"
+msgstr "セクションデータを割り当てられません: %s"
+
+#: src/addr2line.c:58
+#, fuzzy
+msgid "Input format options:"
+msgstr "選択オプションを入力してください:"
+
+#: src/addr2line.c:60
+msgid "Treat addresses as offsets relative to NAME section."
+msgstr ""
+
+#: src/addr2line.c:62
+#, fuzzy
+msgid "Output format options:"
+msgstr "出力形式:"
+
+#: src/addr2line.c:63
+msgid "Print address before each entry"
+msgstr ""
+
+#: src/addr2line.c:64
+msgid "Show only base names of source files"
+msgstr ""
+
+#: src/addr2line.c:66
+msgid "Show absolute file names using compilation directory"
+msgstr ""
+
+#: src/addr2line.c:67
+msgid "Also show function names"
+msgstr ""
+
+#: src/addr2line.c:68
+msgid "Also show symbol or section names"
+msgstr ""
+
+#: src/addr2line.c:69
+msgid "Also show symbol and the section names"
+msgstr ""
+
+#: src/addr2line.c:70
+msgid "Also show line table flags"
+msgstr ""
+
+#: src/addr2line.c:72
+msgid ""
+"Show all source locations that caused inline expansion of subroutines at the "
+"address."
+msgstr ""
+
+#: src/addr2line.c:75
+msgid "Show demangled symbols (ARG is always ignored)"
+msgstr ""
+
+#: src/addr2line.c:77
+msgid "Print all information on one line, and indent inlines"
+msgstr ""
+
+#: src/addr2line.c:79 src/elfcmp.c:71 src/findtextrel.c:66 src/nm.c:101
+#: src/strings.c:79
+msgid "Miscellaneous:"
+msgstr "雑則:"
+
+#. Short description of program.
+#: src/addr2line.c:87
+msgid ""
+"Locate source files and line information for ADDRs (in a.out by default)."
+msgstr ""
+
+#. Strings for arguments in help texts.
+#: src/addr2line.c:91
+msgid "[ADDR...]"
+msgstr ""
+
+#: src/addr2line.c:519
+#, c-format
+msgid "Section syntax requires exactly one module"
+msgstr ""
+
+#: src/addr2line.c:542
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside section '%s'"
+msgstr ""
+
+#: src/addr2line.c:632
+#, c-format
+msgid "cannot find symbol '%s'"
+msgstr ""
+
+#: src/addr2line.c:637
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside contents of '%s'"
+msgstr ""
+
+#: src/ar.c:68
+msgid "Commands:"
+msgstr "コマンド:"
+
+#: src/ar.c:69
+msgid "Delete files from archive."
+msgstr "アーカイブからファイルを削除。"
+
+#: src/ar.c:70
+msgid "Move files in archive."
+msgstr "アーカイブ内のファイルを移動。"
+
+#: src/ar.c:71
+msgid "Print files in archive."
+msgstr "アーカイブ内のファイルを印刷。"
+
+#: src/ar.c:72
+msgid "Quick append files to archive."
+msgstr "アーカイブへの即座のファイル追加。"
+
+#: src/ar.c:74
+msgid "Replace existing or insert new file into archive."
+msgstr "アーカイブへの既存のファイルの置き換えか、新しいファイルの挿入。"
+
+#: src/ar.c:75
+msgid "Display content of archive."
+msgstr "アーカイブの内容の表示"
+
+#: src/ar.c:76
+msgid "Extract files from archive."
+msgstr "アーカイブからのファイルの取出し"
+
+#: src/ar.c:78
+msgid "Command Modifiers:"
+msgstr "コマンド修飾子:"
+
+#: src/ar.c:79
+msgid "Preserve original dates."
+msgstr "元データの保存。"
+
+#: src/ar.c:80
+msgid "Use instance [COUNT] of name."
+msgstr "名前のインスタンス [COUNT] の使用。"
+
+#: src/ar.c:82
+msgid "Do not replace existing files with extracted files."
+msgstr "既存のファイルを抽出したファイルで置き換えない。"
+
+#: src/ar.c:83
+msgid "Allow filename to be truncated if necessary."
+msgstr "必要ならばファイル名の切り捨てを認める。"
+
+#: src/ar.c:85
+msgid "Provide verbose output."
+msgstr "饒舌な出力を提供する。"
+
+#: src/ar.c:86
+msgid "Force regeneration of symbol table."
+msgstr "シンボルテーブルの再生成を強制する。"
+
+#: src/ar.c:87
+msgid "Insert file after [MEMBER]."
+msgstr "[MEMBER]の後にファイルを挿入する。"
+
+#: src/ar.c:88
+msgid "Insert file before [MEMBER]."
+msgstr "[MEMBER]の前にファイルを挿入する。"
+
+#: src/ar.c:89
+msgid "Same as -b."
+msgstr "-b と同じ。"
+
+#: src/ar.c:90
+msgid "Suppress message when library has to be created."
+msgstr "ライブラリーを生成しなければならない時にメッセージを抑止する。"
+
+#: src/ar.c:92
+msgid "Use full path for file matching."
+msgstr "ファイル照合にフルパスを使う。"
+
+#: src/ar.c:93
+msgid "Update only older files in archive."
+msgstr "アーカイブの古いファイルのみ更新する。"
+
+#. Short description of program.
+#: src/ar.c:99
+msgid "Create, modify, and extract from archives."
+msgstr "アーカイブから作成や、修正、抽出する。"
+
+#. Strings for arguments in help texts.
+#: src/ar.c:102
+msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]"
+msgstr "[メンバー] [合計] アーカイブ [ファイル...]"
+
+#: src/ar.c:181
+#, c-format
+msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options"
+msgstr "'a'や、'b'、'i'は、'm' や 'r' オプションと一緒にしか指定できません"
+
+#: src/ar.c:186
+#, c-format
+msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers"
+msgstr "'a'や、'b'、'i' 修飾子には MEMBER パラメーターが必要です"
+
+#: src/ar.c:202
+#, c-format
+msgid "'N' is only meaningful with the 'x' and 'd' options"
+msgstr "'N' は 'x' や 'd' オプションと一緒の時のみ意味を持ちます"
+
+#: src/ar.c:207
+#, c-format
+msgid "COUNT parameter required"
+msgstr "COUNT パラメーターが必要です"
+
+#: src/ar.c:219
+#, c-format
+msgid "invalid COUNT parameter %s"
+msgstr "不当な COUNT パラメーター %s"
+
+#: src/ar.c:226
+#, c-format
+msgid "'%c' is only meaningful with the 'x' option"
+msgstr "'%c' は 'x' オプションと一緒の時のみ意味を持ちます"
+
+#: src/ar.c:232
+#, c-format
+msgid "archive name required"
+msgstr "アーカイブ名が必要です"
+
+#: src/ar.c:245
+#, c-format
+msgid "command option required"
+msgstr ""
+
+#: src/ar.c:296
+#, c-format
+msgid "More than one operation specified"
+msgstr "1つを越える操作が指定されました"
+
+#: src/ar.c:390
+#, c-format
+msgid "cannot open archive '%s'"
+msgstr "アーカイブ '%s' を開くことができません"
+
+#: src/ar.c:400
+#, c-format
+msgid "cannot open archive '%s': %s"
+msgstr "アーカイブ '%s' を開けません: %s"
+
+#: src/ar.c:404
+#, c-format
+msgid "%s: not an archive file"
+msgstr "%s: アーカイブファイルではありません"
+
+#: src/ar.c:408
+#, c-format
+msgid "cannot stat archive '%s'"
+msgstr "アーカイブに stat できません: '%s'"
+
+#: src/ar.c:420
+#, c-format
+msgid "no entry %s in archive\n"
+msgstr "アーカイブに項目 %s がありません\n"
+
+#: src/ar.c:473 src/ar.c:918 src/ar.c:1118
+#, c-format
+msgid "cannot create hash table"
+msgstr "ハッシュテーブルを生成できません"
+
+#: src/ar.c:480 src/ar.c:925 src/ar.c:1127
+#, c-format
+msgid "cannot insert into hash table"
+msgstr "ハッシュに挿入できません"
+
+#: src/ar.c:488 src/ranlib.c:149
+#, c-format
+msgid "cannot stat '%s'"
+msgstr "'%s' に stat できません"
+
+#: src/ar.c:584
+#, c-format
+msgid "cannot read content of %s: %s"
+msgstr "%s の内容を読むことができません: %s"
+
+#: src/ar.c:627
+#, c-format
+msgid "cannot open %.*s"
+msgstr "%.*s を開けません"
+
+#: src/ar.c:649
+#, c-format
+msgid "failed to write %s"
+msgstr "%s への書込みに失敗しました"
+
+#: src/ar.c:661
+#, c-format
+msgid "cannot change mode of %s"
+msgstr "%s のモードを変更できません"
+
+#: src/ar.c:677
+#, c-format
+msgid "cannot change modification time of %s"
+msgstr "%s の更新時間を変更できません"
+
+#: src/ar.c:723
+#, c-format
+msgid "cannot rename temporary file to %.*s"
+msgstr "一時ファイルを %.*s に名前変更できません"
+
+#: src/ar.c:759 src/ar.c:1010 src/ar.c:1409 src/ranlib.c:223
+#, c-format
+msgid "cannot create new file"
+msgstr "新しいファイルを生成できません"
+
+#: src/ar.c:1209
+#, c-format
+msgid "position member %s not found"
+msgstr "位置メンバー %s が見つかりません"
+
+#: src/ar.c:1219
+#, c-format
+msgid "%s: no entry %s in archive!\n"
+msgstr "%s: 項目 %s がアーカイブにありません!\n"
+
+#: src/ar.c:1248 src/objdump.c:242
+#, c-format
+msgid "cannot open %s"
+msgstr "%s を開けません"
+
+#: src/ar.c:1253
+#, c-format
+msgid "cannot stat %s"
+msgstr "%s を stat できません"
+
+#: src/ar.c:1259
+#, c-format
+msgid "%s is no regular file"
+msgstr "%s は一般ファイルではありません"
+
+#: src/ar.c:1272
+#, c-format
+msgid "cannot get ELF descriptor for %s: %s\n"
+msgstr "%s の ELF 記述子を得られません: %s\n"
+
+#: src/ar.c:1292
+#, c-format
+msgid "cannot read %s: %s"
+msgstr "%s を読みません: %s"
+
+#: src/arlib-argp.c:32
+msgid "Use zero for uid, gid, and date in archive members."
+msgstr ""
+
+#: src/arlib-argp.c:34
+msgid "Use actual uid, gid, and date in archive members."
+msgstr ""
+
+#: src/arlib-argp.c:65
+#, c-format
+msgid "%s (default)"
+msgstr ""
+
+#. The archive is too big.
+#: src/arlib.c:213
+#, c-format
+msgid "the archive '%s' is too large"
+msgstr "アーカイブ '%s' は大きすぎます"
+
+#: src/arlib.c:226
+#, c-format
+msgid "cannot read ELF header of %s(%s): %s"
+msgstr "%s(%s) の  ELF ヘッダーを読めません: %s"
+
+#: src/elfcmp.c:61
+msgid "Control options:"
+msgstr ""
+
+#: src/elfcmp.c:63
+msgid "Output all differences, not just the first"
+msgstr ""
+
+#: src/elfcmp.c:64
+msgid ""
+"Control treatment of gaps in loadable segments [ignore|match] (default: "
+"ignore)"
+msgstr ""
+
+#: src/elfcmp.c:66
+msgid "Ignore permutation of buckets in SHT_HASH section"
+msgstr ""
+
+#: src/elfcmp.c:68
+msgid "Ignore differences in build ID"
+msgstr ""
+
+#: src/elfcmp.c:69
+msgid "Output nothing; yield exit status only"
+msgstr ""
+
+#. Short description of program.
+#: src/elfcmp.c:76
+msgid "Compare relevant parts of two ELF files for equality."
+msgstr ""
+
+#. Strings for arguments in help texts.
+#: src/elfcmp.c:80
+msgid "FILE1 FILE2"
+msgstr ""
+
+#: src/elfcmp.c:142
+msgid "Invalid number of parameters.\n"
+msgstr ""
+
+#: src/elfcmp.c:173 src/elfcmp.c:178
+#, c-format
+msgid "cannot get ELF header of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:204
+#, c-format
+msgid "%s %s diff: ELF header"
+msgstr ""
+
+#: src/elfcmp.c:211 src/elfcmp.c:214
+#, fuzzy, c-format
+msgid "cannot get section count of '%s': %s"
+msgstr "セクションを得られません: %s"
+
+#: src/elfcmp.c:219
+#, c-format
+msgid "%s %s diff: section count"
+msgstr ""
+
+#: src/elfcmp.c:226 src/elfcmp.c:229
+#, fuzzy, c-format
+msgid "cannot get program header count of '%s': %s"
+msgstr "プログラムヘッダーを得られません: %s"
+
+#: src/elfcmp.c:234
+#, fuzzy, c-format
+msgid "%s %s diff: program header count"
+msgstr "ファイルにプログラムヘッダーがありません"
+
+#: src/elfcmp.c:292
+#, c-format
+msgid "%s %s differ: section [%zu], [%zu] name"
+msgstr ""
+
+#: src/elfcmp.c:315
+#, fuzzy, c-format
+msgid "%s %s differ: section [%zu] '%s' header"
+msgstr "セクション [%zu] '%s' の不当なデータ"
+
+#: src/elfcmp.c:323 src/elfcmp.c:329
+#, c-format
+msgid "cannot get content of section %zu in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:338
+#, fuzzy, c-format
+msgid "symbol table [%zu] in '%s' has zero sh_entsize"
+msgstr ""
+"\n"
+"シンボルテーブル [%2u] '%s' には %u 個の項目があります:\n"
+
+#: src/elfcmp.c:350 src/elfcmp.c:356
+#, c-format
+msgid "cannot get symbol in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:378
+#, c-format
+msgid "%s %s differ: symbol table [%zu]"
+msgstr ""
+
+#: src/elfcmp.c:381
+#, c-format
+msgid "%s %s differ: symbol table [%zu,%zu]"
+msgstr ""
+
+#: src/elfcmp.c:428 src/elfcmp.c:498
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' number of notes"
+msgstr ""
+
+#: src/elfcmp.c:436
+#, fuzzy, c-format
+msgid "cannot read note section [%zu] '%s' in '%s': %s"
+msgstr "セクション [%Zu] '%s' からデータが得られません: %s"
+
+#: src/elfcmp.c:447
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note name"
+msgstr ""
+
+#: src/elfcmp.c:455
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note '%s' type"
+msgstr ""
+
+#: src/elfcmp.c:470
+#, c-format
+msgid "%s %s differ: build ID length"
+msgstr ""
+
+#: src/elfcmp.c:478
+#, c-format
+msgid "%s %s differ: build ID content"
+msgstr ""
+
+#: src/elfcmp.c:487
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:528
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:532
+#, c-format
+msgid "%s %s differ: section [%zu,%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:547
+#, c-format
+msgid "%s %s differ: unequal amount of important sections"
+msgstr ""
+
+#: src/elfcmp.c:580 src/elfcmp.c:585
+#, c-format
+msgid "cannot load data of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:604 src/elfcmp.c:610
+#, c-format
+msgid "cannot get program header entry %d of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:616
+#, c-format
+msgid "%s %s differ: program header %d"
+msgstr ""
+
+#: src/elfcmp.c:640
+#, c-format
+msgid "%s %s differ: gap"
+msgstr ""
+
+#: src/elfcmp.c:691
+#, c-format
+msgid "Invalid value '%s' for --gaps parameter."
+msgstr ""
+
+#: src/elfcmp.c:719 src/findtextrel.c:206 src/nm.c:365 src/ranlib.c:142
+#: src/size.c:273 src/strings.c:186 src/strip.c:518 src/strip.c:555
+#: src/unstrip.c:2023 src/unstrip.c:2052
+#, c-format
+msgid "cannot open '%s'"
+msgstr "'%s' を開けません"
+
+#: src/elfcmp.c:723 src/findtextrel.c:213 src/ranlib.c:159
+#, c-format
+msgid "cannot create ELF descriptor for '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:728
+#, c-format
+msgid "cannot create EBL descriptor for '%s'"
+msgstr ""
+
+#: src/elfcmp.c:746 src/findtextrel.c:394
+#, c-format
+msgid "cannot get section header of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:756
+#, c-format
+msgid "cannot get content of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:766 src/elfcmp.c:780
+#, c-format
+msgid "cannot get relocation: %s"
+msgstr ""
+
+#: src/elfcompress.c:115 src/strip.c:297 src/unstrip.c:121
+#, c-format
+msgid "-o option specified twice"
+msgstr "-o オプションが 2 回指定されています"
+
+#: src/elfcompress.c:122
+#, fuzzy, c-format
+msgid "-t option specified twice"
+msgstr "-f オプションが 2 回指定されています"
+
+#: src/elfcompress.c:131
+#, fuzzy, c-format
+msgid "unknown compression type '%s'"
+msgstr "不明なタイプ"
+
+#. We need at least one input file.
+#: src/elfcompress.c:143 src/elfcompress.c:1305
+#, fuzzy, c-format
+msgid "No input file given"
+msgstr "入力ファイルが空です"
+
+#: src/elfcompress.c:149 src/elfcompress.c:1310
+#, fuzzy, c-format
+msgid "Only one input file allowed together with '-o'"
+msgstr "'-o' と '-f' と一緒の場合は入力ファイルは 1 つしか認められません"
+
+#: src/elfcompress.c:1267
+#, fuzzy
+msgid "Place (de)compressed output into FILE"
+msgstr "はぎ取った出力を ふぁいる に置く"
+
+#: src/elfcompress.c:1270
+msgid ""
+"What type of compression to apply. TYPE can be 'none' (decompress), "
+"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-"
+"gnu' (.zdebug GNU style compression, 'gnu' is an alias)"
+msgstr ""
+
+#: src/elfcompress.c:1273
+msgid ""
+"SECTION name to (de)compress, SECTION is an extended wildcard pattern "
+"(defaults to '.?(z)debug*')"
+msgstr ""
+
+#: src/elfcompress.c:1276
+msgid "Print a message for each section being (de)compressed"
+msgstr ""
+
+#: src/elfcompress.c:1279
+msgid "Force compression of section even if it would become larger"
+msgstr ""
+
+#: src/elfcompress.c:1282 src/strip.c:91
+msgid "Relax a few rules to handle slightly broken ELF files"
+msgstr "少し壊れた ELF ファイルを取り扱うためにルールを少し緩和する"
+
+#: src/elfcompress.c:1285
+#, fuzzy
+msgid "Be silent when a section cannot be compressed"
+msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
+
+#. Strings for arguments in help texts.
+#: src/elfcompress.c:1294 src/elflint.c:78 src/readelf.c:142
+msgid "FILE..."
+msgstr "ふぁいる..."
+
+#: src/elfcompress.c:1295
+msgid "Compress or decompress sections in an ELF file."
+msgstr ""
+
+#: src/elflint.c:64
+msgid "Be extremely strict, flag level 2 features."
+msgstr "非常に厳密にやってください、フラグレベル 2 機能。"
+
+#: src/elflint.c:65
+msgid "Do not print anything if successful"
+msgstr "成功したら何も印刷しない"
+
+#: src/elflint.c:66
+msgid "Binary is a separate debuginfo file"
+msgstr "バイナリーは別の debuginfo ファイルです"
+
+#: src/elflint.c:68
+msgid ""
+"Binary has been created with GNU ld and is therefore known to be broken in "
+"certain ways"
+msgstr ""
+"バイナリーは GNU ld で作成され、従ってある方法で壊れているのが知られている"
+
+#. Short description of program.
+#: src/elflint.c:74
+msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
+msgstr "ELF ファイルが gABI/psABI 仕様へ準拠しているかの厳密なチェック。"
+
+#: src/elflint.c:155 src/readelf.c:317
+#, c-format
+msgid "cannot open input file"
+msgstr "入力ファイルを開けません"
+
+#: src/elflint.c:162
+#, c-format
+msgid "cannot generate Elf descriptor: %s\n"
+msgstr "Elf 記述子を生成できません: %s\n"
+
+#: src/elflint.c:181
+#, c-format
+msgid "error while closing Elf descriptor: %s\n"
+msgstr "Elf 記述子を閉じている時にエラー: %s\n"
+
+#: src/elflint.c:185
+msgid "No errors"
+msgstr "エラーはありません"
+
+#: src/elflint.c:220 src/readelf.c:494
+msgid "Missing file name.\n"
+msgstr "ファイル名がありません。\n"
+
+#: src/elflint.c:285
+#, c-format
+msgid " error while freeing sub-ELF descriptor: %s\n"
+msgstr "副-ELF 記述子を解放している時にエラー: %s\n"
+
+#. We cannot do anything.
+#: src/elflint.c:293
+#, c-format
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr "ELF ファイルではありません - 最初に誤ったマジックバイトがあります\n"
+
+#: src/elflint.c:358
+#, c-format
+msgid "e_ident[%d] == %d is no known class\n"
+msgstr "e_ident[%d] == %d は既知のクラスではありません\n"
+
+#: src/elflint.c:363
+#, c-format
+msgid "e_ident[%d] == %d is no known data encoding\n"
+msgstr "e_ident[%d] == %d は既知のデータエンコードではありません\n"
+
+#: src/elflint.c:367
+#, c-format
+msgid "unknown ELF header version number e_ident[%d] == %d\n"
+msgstr "不明な ELF ヘッダーバージョン数 e_ident[%d] == %d\n"
+
+#: src/elflint.c:375
+#, c-format
+msgid "unsupported OS ABI e_ident[%d] == '%s'\n"
+msgstr "不明な OS ABI e_ident[%d] == '%s'\n"
+
+#: src/elflint.c:381
+#, c-format
+msgid "unsupport ABI version e_ident[%d] == %d\n"
+msgstr "不明な ABI バージョン e_ident[%d] == %d\n"
+
+#: src/elflint.c:386
+#, c-format
+msgid "e_ident[%zu] is not zero\n"
+msgstr "e_ident[%zu] がゼロではありません\n"
+
+#: src/elflint.c:391
+#, c-format
+msgid "unknown object file type %d\n"
+msgstr "不明なオブジェクトファイルタイプ %d\n"
+
+#: src/elflint.c:398
+#, c-format
+msgid "unknown machine type %d\n"
+msgstr "不明なマシンタイプ %d\n"
+
+#: src/elflint.c:402
+#, c-format
+msgid "unknown object file version\n"
+msgstr "不明なオブジェクトファイルバージョン\n"
+
+#: src/elflint.c:408
+#, c-format
+msgid "invalid program header offset\n"
+msgstr "不当なプログラムヘッダーオフセット\n"
+
+#: src/elflint.c:410
+#, c-format
+msgid "executables and DSOs cannot have zero program header offset\n"
+msgstr ""
+"実行ファイルと DSO はプログラムヘッダーオフセットが 0 であってはいけません\n"
+
+#: src/elflint.c:414
+#, c-format
+msgid "invalid number of program header entries\n"
+msgstr "プログラムヘッダー項目数として不当な数\n"
+
+#: src/elflint.c:422
+#, c-format
+msgid "invalid section header table offset\n"
+msgstr "不当なセクションヘッダーテーブルオフセット\n"
+
+#: src/elflint.c:425
+#, c-format
+msgid "section header table must be present\n"
+msgstr "セクションヘッダーテーブルがなければなりません\n"
+
+#: src/elflint.c:439
+#, c-format
+msgid "invalid number of section header table entries\n"
+msgstr "セクションヘッダーテーブル項目数として不当な数\n"
+
+#: src/elflint.c:456
+#, c-format
+msgid "invalid section header index\n"
+msgstr "不当なセクションヘッダーインデックス\n"
+
+#: src/elflint.c:474
+#, c-format
+msgid "Can only check %u headers, shnum was %u\n"
+msgstr ""
+
+#: src/elflint.c:488
+#, fuzzy, c-format
+msgid "invalid number of program header table entries\n"
+msgstr "プログラムヘッダー項目数として不当な数\n"
+
+#: src/elflint.c:505
+#, c-format
+msgid "Can only check %u headers, phnum was %u\n"
+msgstr ""
+
+#: src/elflint.c:510
+#, c-format
+msgid "invalid machine flags: %s\n"
+msgstr "不当なマシンフラグ: %s\n"
+
+#: src/elflint.c:517 src/elflint.c:534
+#, c-format
+msgid "invalid ELF header size: %hd\n"
+msgstr "不当な ELF ヘッダーサイズ: %hd\n"
+
+#: src/elflint.c:520 src/elflint.c:537
+#, c-format
+msgid "invalid program header size: %hd\n"
+msgstr "不当なプログラムヘッダーサイズ: %hd\n"
+
+#: src/elflint.c:523 src/elflint.c:540
+#, c-format
+msgid "invalid program header position or size\n"
+msgstr "不当なプログラムヘッダー位置かサイズ\n"
+
+#: src/elflint.c:526 src/elflint.c:543
+#, c-format
+msgid "invalid section header size: %hd\n"
+msgstr "不当なセクションヘッダーサイズ: %hd\n"
+
+#: src/elflint.c:529 src/elflint.c:546
+#, c-format
+msgid "invalid section header position or size\n"
+msgstr "不当なセクションヘッダー位置かサイズ\n"
+
+#: src/elflint.c:591
+#, c-format
+msgid ""
+"section [%2d] '%s': section with SHF_GROUP flag set not part of a section "
+"group\n"
+msgstr ""
+"セクション [%2d] '%s': SHF_GROUP フラグのあるセクションにセクショングループの"
+"一部分が設定されていません\n"
+
+#: src/elflint.c:595
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"
+msgstr ""
+"セクション [%2d] '%s': セクショングループ [%2zu] '%s' がグループメンバーを継"
+"続していません\n"
+
+#: src/elflint.c:611 src/elflint.c:1495 src/elflint.c:1546 src/elflint.c:1652
+#: src/elflint.c:1988 src/elflint.c:2311 src/elflint.c:2930 src/elflint.c:3093
+#: src/elflint.c:3241 src/elflint.c:3431 src/elflint.c:4399
+#, c-format
+msgid "section [%2d] '%s': cannot get section data\n"
+msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
+
+#: src/elflint.c:624 src/elflint.c:1659
+#, c-format
+msgid ""
+"section [%2d] '%s': referenced as string table for section [%2d] '%s' but "
+"type is not SHT_STRTAB\n"
+msgstr ""
+"セクション [%2d] '%s': セクション [%2d] '%s' 用の文字列テーブルとして参照され"
+"ていますが、タイプが SHT_STRTAB ではありません\n"
+
+#: src/elflint.c:647
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol table cannot have more than one extended index "
+"section\n"
+msgstr ""
+"セクション [%2d] '%s': シンボルテーブルは 1 個を越える拡張インデックスセク"
+"ションを持てません\n"
+
+#: src/elflint.c:659
+#, c-format
+msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n"
+msgstr "セクション [%2u] '%s': 項目サイズが ElfXX_Sym と一致しません\n"
+
+#: src/elflint.c:668
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %d: %s\n"
+msgstr "セクション [%2d] '%s': シンボル %d を得られません: %s\n"
+
+#: src/elflint.c:673 src/elflint.c:676 src/elflint.c:679 src/elflint.c:682
+#: src/elflint.c:685 src/elflint.c:688
+#, c-format
+msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n"
+msgstr "セクション [%2d] '%s': 0番目の項目にある '%s' ゼロではありません\n"
+
+#: src/elflint.c:691
+#, c-format
+msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n"
+msgstr "セクション [%2d] '%s': 0番目の項目用の XINDEX がゼロではありません\n"
+
+#: src/elflint.c:701
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %zu: %s\n"
+msgstr "セクション [%2d] '%s': シンボル %zu を得られません: %s\n"
+
+#: src/elflint.c:710
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid name value\n"
+msgstr "セクション [%2d] '%s': シンボル %zu: 不当な名前の値\n"
+
+#: src/elflint.c:725
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: too large section index but no extended "
+"section index section\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: 大きすぎるセクションインデックスだが、拡"
+"張セクションインデックスセクションがありません\n"
+
+#: src/elflint.c:731
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in "
+"st_shndx (%<PRIu32>)\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: st_shndx (%<PRIu32>) に適合するインデッ"
+"クス用に使われる XINDEX\n"
+
+#. || sym->st_shndx > SHN_HIRESERVE  always false
+#: src/elflint.c:743
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid section index\n"
+msgstr "セクション [%2d] '%s': シンボル %zu: 不当なセクションインデックス\n"
+
+#: src/elflint.c:751
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown type\n"
+msgstr "セクション [%2d] '%s': シンボル %zu: 不明なタイプ\n"
+
+#: src/elflint.c:757
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown symbol binding\n"
+msgstr "セクション [%2d] '%s': シンボル %zu: 不明なシンボルバインディング\n"
+
+#: src/elflint.c:762
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unique symbol not of object type\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: オブジェクトタイプと異なる固有のシンボ"
+"ル\n"
+
+#: src/elflint.c:770
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: COMMON はリロケータブルファイル内のみで"
+"許されます\n"
+
+#: src/elflint.c:774
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: ローカルな COMMON シンボルは意味がありま"
+"せん\n"
+
+#: src/elflint.c:778
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: COMMON セクションの機能は意味がありませ"
+"ん\n"
+
+#: src/elflint.c:829
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: st_value out of bounds\n"
+msgstr "セクション [%2d] '%s': シンボル %zu: st_value 境界外\n"
+
+#: src/elflint.c:835 src/elflint.c:860 src/elflint.c:909
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu does not fit completely in referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu は参照されるセクション [%2d] '%s' とは完"
+"全に一致しません\n"
+
+#: src/elflint.c:844
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have "
+"SHF_TLS flag set\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: 参照されるセクション [%2d] '%s' は "
+"SHF_TLS フラグが設定されていません\n"
+
+#: src/elflint.c:854 src/elflint.c:902
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: st_value 参照されるセクション [%2d] "
+"'%s' の境界外\n"
+
+#: src/elflint.c:881
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: TLS プログラムヘッダー項目がない TLS シ"
+"ンボル\n"
+
+#: src/elflint.c:887
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but couldn't get TLS program "
+"header entry\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: TLS プログラムヘッダー項目がない TLS シ"
+"ンボル\n"
+
+#: src/elflint.c:895
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] "
+"'%s'\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: 参照されるセクション [%2d] '%s' の"
+"st_value 不足\n"
+
+#: src/elflint.c:922
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: sh_info に記述された範囲外のローカルシン"
+"ボル\n"
+
+#: src/elflint.c:929
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: non-local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: sh_info に記述された範囲外の非ローカルシ"
+"ンボル\n"
+
+#: src/elflint.c:936
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: non-local section symbol\n"
+msgstr "セクション [%2d] '%s': シンボル %zu: 非ローカルセクションシンボル\n"
+
+#: src/elflint.c:986
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section "
+"[%2d]\n"
+msgstr ""
+"セクション [%2d] '%s': _GLOBAL_OFFSET_TABLE_ シンボルが間違ったセクション "
+"[%2d] を参照しています\n"
+
+#: src/elflint.c:993
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] "
+"'%s'\n"
+msgstr ""
+"セクション [%2d] '%s': _GLOBAL_OFFSET_TABLE_ シンボルはセクション [%2d] '%s' "
+"を参照しています\n"
+
+#. This test is more strict than the psABIs which
+#. usually allow the symbol to be in the middle of
+#. the .got section, allowing negative offsets.
+#: src/elflint.c:1009
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#<PRIx64> does not "
+"match %s section address %#<PRIx64>\n"
+msgstr ""
+"セクション [%2d] '%s': _GLOBAL_OFFSET_TABLE_ シンボル値 %#<PRIx64> は %s のセ"
+"クションアドレス %#<PRIx64> と一致しません\n"
+
+#: src/elflint.c:1016
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %<PRIu64> does not "
+"match %s section size %<PRIu64>\n"
+msgstr ""
+"セクション [%2d] '%s': _GLOBAL_OFFSET_TABLE_ シンボルサイズ %<PRIu64> は %s "
+"のセクションサイズ %<PRIu64> と一致しません\n"
+
+#: src/elflint.c:1024
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got "
+"section\n"
+msgstr ""
+"セクション [%2d] '%s': _GLOBAL_OFFSET_TABLE_ シンボルはありますが、.got セク"
+"ションがありません\n"
+
+#: src/elflint.c:1040
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC_ symbol value %#<PRIx64> does not match dynamic "
+"segment address %#<PRIx64>\n"
+msgstr ""
+"セクション [%2d] '%s': _DYNAMIC_ シンボル値 %#<PRIx64> は動的セグメントアドレ"
+"ス %#<PRIx64> と一致しません\n"
+
+#: src/elflint.c:1047
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC symbol size %<PRIu64> does not match dynamic "
+"segment size %<PRIu64>\n"
+msgstr ""
+"セクション [%2d] '%s': _DYNAMIC シンボルサイズ %<PRIu64> は動的セグメントサイ"
+"ズ %<PRIu64> と一致しません\n"
+
+#: src/elflint.c:1060
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-"
+"default visibility\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: 省略以外の可視性を持った動的シンボルテー"
+"ブル中のシンボル\n"
+
+#: src/elflint.c:1064
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: st_other 中に設定された不明なビット\n"
+
+#: src/elflint.c:1102
+#, fuzzy, c-format
+msgid "section [%2d] '%s': cannot get section data.\n"
+msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
+
+#: src/elflint.c:1118
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"
+msgstr "セクション [%2d] '%s': この RELA セクション用に使われる DT_RELCOUNT\n"
+
+#: src/elflint.c:1129 src/elflint.c:1182
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"
+msgstr ""
+"セクション [%2d] '%s': このセクション用には高すぎる DT_RELCOUNT 値 %d\n"
+
+#: src/elflint.c:1154 src/elflint.c:1207
+#, c-format
+msgid ""
+"section [%2d] '%s': relative relocations after index %d as specified by "
+"DT_RELCOUNT\n"
+msgstr ""
+"セクション [%2d] '%s': UT_RELOCOUNT で指定されたインデックス %d 後の相対リロ"
+"ケーション\n"
+
+#: src/elflint.c:1160 src/elflint.c:1213
+#, c-format
+msgid ""
+"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT "
+"specified %d relative relocations\n"
+msgstr ""
+"セクション [%2d] '%s': インデックス %zu での非相対リロケーション;  %d 相対リ"
+"ロケーションで指定された DT_RELCOUNT\n"
+
+#: src/elflint.c:1172
+#, c-format
+msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n"
+msgstr "セクション [%2d] '%s': この REL セクション用に使われる DT_RELACOUNT\n"
+
+#: src/elflint.c:1255
+#, c-format
+msgid "section [%2d] '%s': invalid destination section index\n"
+msgstr "セクション [%2d] '%s': 不当な宛先セクションインデックス\n"
+
+#: src/elflint.c:1267
+#, c-format
+msgid "section [%2d] '%s': invalid destination section type\n"
+msgstr "セクション [%2d] '%s': 不当な宛先セクションタイプ\n"
+
+#: src/elflint.c:1275
+#, c-format
+msgid "section [%2d] '%s': sh_info should be zero\n"
+msgstr "セクション [%2d] '%s': sh_info はゼロでなければなりません\n"
+
+#: src/elflint.c:1283
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': no relocations for merge-able string sections possible\n"
+msgstr ""
+"セクション [%2d] '%s': マージできるセクションのリロケーションは不可能です\n"
+
+#: src/elflint.c:1291
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n"
+msgstr ""
+"セクション [%2d] '%s': セクション項目サイズが ElfXX_Rela と一致しません\n"
+
+#: src/elflint.c:1351
+#, c-format
+msgid "text relocation flag set but there is no read-only segment\n"
+msgstr ""
+"テキストリロケーションフラグが設定されていますが、読込み専用セグメントがあり"
+"ません\n"
+
+#: src/elflint.c:1378
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid type\n"
+msgstr "セクション [%2d] '%s': リロケーション %zu: 不当なタイプ\n"
+
+#: src/elflint.c:1386
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: relocation type invalid for the file "
+"type\n"
+msgstr ""
+"セクション [%2d] '%s': リロケーション %zu: このファイル用のリロケーションタイ"
+"プは不当です\n"
+
+#: src/elflint.c:1394
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n"
+msgstr ""
+"セクション [%2d] '%s': リロケーション %zu: 不当なシンボルインデックス\n"
+
+#: src/elflint.c:1412
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can "
+"be used with %s\n"
+msgstr ""
+"セクション [%2d] '%s': リロケーション %zu: シンボル '_GLOBAL_OFFSET_TABLE_' "
+"のみが %s と一緒に使用できます\n"
+
+#: src/elflint.c:1429
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n"
+msgstr "セクション [%2d] '%s': リロケーション %zu: オフセット境界外\n"
+
+#: src/elflint.c:1444
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: copy relocation against symbol of type "
+"%s\n"
+msgstr ""
+"セクション [%2d] '%s': リロケーション %zu: タイプ %s のシンボルに対するコピー"
+"リロケーション\n"
+
+#: src/elflint.c:1465
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: read-only section modified but text "
+"relocation flag not set\n"
+msgstr ""
+"セクション [%2d] '%s': リロケーション %zu: 読込み専用セクションが変更されまし"
+"たが、テキストリロケーションフラグが設定されていません\n"
+
+#: src/elflint.c:1480
+#, c-format
+msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n"
+msgstr ""
+"セクション [%2d] '%s': リロケーションがロードされたデータとロードされなかった"
+"データに対してです\n"
+
+#: src/elflint.c:1520 src/elflint.c:1571
+#, c-format
+msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1647
+#, c-format
+msgid "more than one dynamic section present\n"
+msgstr ""
+
+#: src/elflint.c:1665
+#, fuzzy, c-format
+msgid ""
+"section [%2d]: referenced as string table for section [%2d] '%s' but section "
+"link value is invalid\n"
+msgstr ""
+"セクション [%2d] '%s': セクション [%2d] '%s' 用の文字列テーブルとして参照され"
+"ていますが、タイプが SHT_STRTAB ではありません\n"
+
+#: src/elflint.c:1673
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"
+msgstr ""
+
+#: src/elflint.c:1678 src/elflint.c:1967
+#, c-format
+msgid "section [%2d] '%s': sh_info not zero\n"
+msgstr ""
+
+#: src/elflint.c:1688
+#, c-format
+msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1696
+#, c-format
+msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"
+msgstr ""
+
+#: src/elflint.c:1703
+#, c-format
+msgid "section [%2d] '%s': entry %zu: unknown tag\n"
+msgstr ""
+
+#: src/elflint.c:1714
+#, c-format
+msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n"
+msgstr ""
+
+#: src/elflint.c:1724
+#, c-format
+msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n"
+msgstr ""
+
+#: src/elflint.c:1742
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"
+msgstr ""
+
+#: src/elflint.c:1755
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: pointer does not match address of section "
+"[%2d] '%s' referenced by sh_link\n"
+msgstr ""
+
+#: src/elflint.c:1798
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:1813
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must be valid offset in section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:1833 src/elflint.c:1861
+#, c-format
+msgid "section [%2d] '%s': contains %s entry but not %s\n"
+msgstr ""
+
+#: src/elflint.c:1845
+#, c-format
+msgid "section [%2d] '%s': mandatory tag %s not present\n"
+msgstr ""
+
+#: src/elflint.c:1854
+#, c-format
+msgid "section [%2d] '%s': no hash section present\n"
+msgstr ""
+
+#: src/elflint.c:1869 src/elflint.c:1876
+#, c-format
+msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n"
+msgstr ""
+
+#: src/elflint.c:1886 src/elflint.c:1890
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"
+msgstr ""
+
+#: src/elflint.c:1896
+#, c-format
+msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n"
+msgstr ""
+
+#: src/elflint.c:1907 src/elflint.c:1911 src/elflint.c:1915 src/elflint.c:1919
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in prelinked executable\n"
+msgstr ""
+
+#: src/elflint.c:1931
+#, c-format
+msgid ""
+"section [%2d] '%s': only relocatable files can have extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1941
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index section not for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1945
+#, fuzzy, c-format
+msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n"
+msgstr "セクション [%2d] '%s': 不当な宛先セクションインデックス\n"
+
+#: src/elflint.c:1950
+#, c-format
+msgid "cannot get data for symbol section\n"
+msgstr ""
+
+#: src/elflint.c:1953
+#, c-format
+msgid "section [%2d] '%s': entry size does not match Elf32_Word\n"
+msgstr ""
+
+#: src/elflint.c:1962
+#, c-format
+msgid "section [%2d] '%s': extended index table too small for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1977
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to "
+"same symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1995
+#, c-format
+msgid "symbol 0 should have zero extended section index\n"
+msgstr ""
+
+#: src/elflint.c:2007
+#, c-format
+msgid "cannot get data for symbol %zu\n"
+msgstr ""
+
+#: src/elflint.c:2012
+#, c-format
+msgid "extended section index is %<PRIu32> but symbol index is not XINDEX\n"
+msgstr ""
+
+#: src/elflint.c:2029 src/elflint.c:2083
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"
+msgstr ""
+
+#: src/elflint.c:2043 src/elflint.c:2097
+#, c-format
+msgid "section [%2d] '%s': chain array too large\n"
+msgstr ""
+
+#: src/elflint.c:2057 src/elflint.c:2111
+#, c-format
+msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2067
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2121
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %<PRIu64> out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2134
+#, fuzzy, c-format
+msgid "section [%2d] '%s': not enough data\n"
+msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
+
+#: src/elflint.c:2146
+#, fuzzy, c-format
+msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n"
+msgstr "セクション [%2d] '%s': 0番目の項目にある '%s' ゼロではありません\n"
+
+#: src/elflint.c:2162
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected at "
+"least %ld)\n"
+msgstr ""
+
+#: src/elflint.c:2171
+#, c-format
+msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n"
+msgstr ""
+
+#: src/elflint.c:2205
+#, c-format
+msgid ""
+"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"
+msgstr ""
+
+#: src/elflint.c:2226
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is "
+"undefined\n"
+msgstr ""
+
+#: src/elflint.c:2239
+#, c-format
+msgid ""
+"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+
+#: src/elflint.c:2248
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n"
+msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
+
+#: src/elflint.c:2278
+#, c-format
+msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2283
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2289
+#, c-format
+msgid "section [%2d] '%s': bitmask does not match names in the hash table\n"
+msgstr ""
+
+#: src/elflint.c:2302
+#, c-format
+msgid "section [%2d] '%s': relocatable files cannot have hash tables\n"
+msgstr ""
+
+#: src/elflint.c:2320
+#, c-format
+msgid "section [%2d] '%s': hash table not for dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2324
+#, fuzzy, c-format
+msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n"
+msgstr "セクション [%2d] '%s': 不当な宛先セクションインデックス\n"
+
+#: src/elflint.c:2334
+#, c-format
+msgid "section [%2d] '%s': hash table entry size incorrect\n"
+msgstr ""
+
+#: src/elflint.c:2339
+#, c-format
+msgid "section [%2d] '%s': not marked to be allocated\n"
+msgstr ""
+
+#: src/elflint.c:2344
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table has not even room for initial administrative "
+"entries\n"
+msgstr ""
+
+#: src/elflint.c:2393
+#, c-format
+msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"
+msgstr ""
+
+#: src/elflint.c:2417 src/elflint.c:2482 src/elflint.c:2517
+#, fuzzy, c-format
+msgid "hash section [%2zu] '%s' does not contain enough data\n"
+msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
+
+#: src/elflint.c:2438
+#, fuzzy, c-format
+msgid "hash section [%2zu] '%s' has zero bit mask words\n"
+msgstr ""
+"\n"
+"セクション [%Zu] '%s' にはダンプすべきデータがありません。\n"
+
+#: src/elflint.c:2449 src/elflint.c:2493 src/elflint.c:2530
+#, fuzzy, c-format
+msgid "hash section [%2zu] '%s' uses too much data\n"
+msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
+
+#: src/elflint.c:2464
+#, c-format
+msgid ""
+"hash section [%2zu] '%s' invalid symbol index %<PRIu32> (max_nsyms: "
+"%<PRIu32>, nentries: %<PRIu32>\n"
+msgstr ""
+
+#: src/elflint.c:2551
+#, fuzzy, c-format
+msgid "hash section [%2zu] '%s' invalid sh_entsize\n"
+msgstr "セクション [%2d] '%s': 不当な宛先セクションタイプ\n"
+
+#: src/elflint.c:2561 src/elflint.c:2565
+#, c-format
+msgid "section [%2zu] '%s': reference to symbol index 0\n"
+msgstr ""
+
+#: src/elflint.c:2572
+#, c-format
+msgid ""
+"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2584
+#, c-format
+msgid ""
+"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2600
+#, c-format
+msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n"
+msgstr ""
+
+#: src/elflint.c:2620
+#, c-format
+msgid ""
+"section [%2d] '%s': section groups only allowed in relocatable object files\n"
+msgstr ""
+
+#: src/elflint.c:2631
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol table: %s\n"
+msgstr ""
+
+#: src/elflint.c:2636
+#, c-format
+msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2642
+#, c-format
+msgid "section [%2d] '%s': invalid symbol index in sh_info\n"
+msgstr ""
+
+#: src/elflint.c:2647
+#, c-format
+msgid "section [%2d] '%s': sh_flags not zero\n"
+msgstr ""
+
+#: src/elflint.c:2654
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol for signature\n"
+msgstr ""
+
+#: src/elflint.c:2658
+#, fuzzy, c-format
+msgid "section [%2d] '%s': cannot get symbol name for signature\n"
+msgstr "セクション [%2d] '%s': シンボル %d を得られません: %s\n"
+
+#: src/elflint.c:2663
+#, fuzzy, c-format
+msgid "section [%2d] '%s': signature symbol cannot be empty string\n"
+msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
+
+#: src/elflint.c:2669
+#, c-format
+msgid "section [%2d] '%s': sh_flags not set correctly\n"
+msgstr ""
+
+#: src/elflint.c:2675
+#, c-format
+msgid "section [%2d] '%s': cannot get data: %s\n"
+msgstr ""
+
+#: src/elflint.c:2684
+#, c-format
+msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"
+msgstr ""
+
+#: src/elflint.c:2690
+#, c-format
+msgid "section [%2d] '%s': section group without flags word\n"
+msgstr ""
+
+#: src/elflint.c:2698
+#, c-format
+msgid "section [%2d] '%s': section group without member\n"
+msgstr ""
+
+#: src/elflint.c:2702
+#, c-format
+msgid "section [%2d] '%s': section group with only one member\n"
+msgstr ""
+
+#: src/elflint.c:2713
+#, c-format
+msgid "section [%2d] '%s': unknown section group flags\n"
+msgstr ""
+
+#: src/elflint.c:2725
+#, fuzzy, c-format
+msgid "section [%2d] '%s': section index %zu out of range\n"
+msgstr "セクション [%2d] '%s': リロケーション %zu: オフセット境界外\n"
+
+#: src/elflint.c:2734
+#, c-format
+msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:2741
+#, c-format
+msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2747
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': element %zu references section [%2d] '%s' without "
+"SHF_GROUP flag set\n"
+msgstr ""
+"セクション [%2d] '%s': シンボル %zu: 参照されるセクション [%2d] '%s' は "
+"SHF_TLS フラグが設定されていません\n"
+
+#: src/elflint.c:2754
+#, c-format
+msgid "section [%2d] '%s' is contained in more than one section group\n"
+msgstr ""
+
+#: src/elflint.c:2944
+#, c-format
+msgid ""
+"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no "
+"dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2956
+#, c-format
+msgid ""
+"section [%2d] '%s' has different number of entries than symbol table [%2d] "
+"'%s'\n"
+msgstr ""
+
+#: src/elflint.c:2972
+#, c-format
+msgid "section [%2d] '%s': symbol %d: cannot read version data\n"
+msgstr ""
+
+#: src/elflint.c:2988
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n"
+msgstr ""
+
+#: src/elflint.c:2996
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with version\n"
+msgstr ""
+
+#: src/elflint.c:3010
+#, c-format
+msgid "section [%2d] '%s': symbol %d: invalid version index %d\n"
+msgstr ""
+
+#: src/elflint.c:3015
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for defined version\n"
+msgstr ""
+
+#: src/elflint.c:3025
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for requested version\n"
+msgstr ""
+
+#: src/elflint.c:3078
+#, c-format
+msgid "more than one version reference section present\n"
+msgstr ""
+
+#: src/elflint.c:3086 src/elflint.c:3233
+#, c-format
+msgid "section [%2d] '%s': sh_link does not link to string table\n"
+msgstr ""
+
+#: src/elflint.c:3111 src/elflint.c:3287
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong version %d\n"
+msgstr ""
+
+#: src/elflint.c:3118 src/elflint.c:3294
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3128
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid file reference\n"
+msgstr ""
+
+#: src/elflint.c:3136
+#, c-format
+msgid "section [%2d] '%s': entry %d references unknown dependency\n"
+msgstr ""
+
+#: src/elflint.c:3148
+#, c-format
+msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:3156
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name "
+"reference\n"
+msgstr ""
+
+#: src/elflint.c:3165
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: "
+"%#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:3174
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version "
+"name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3185
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"
+msgstr ""
+
+#: src/elflint.c:3202 src/elflint.c:3378
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n"
+msgstr ""
+
+#: src/elflint.c:3210 src/elflint.c:3386
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says "
+"there are more entries\n"
+msgstr ""
+
+#: src/elflint.c:3225
+#, c-format
+msgid "more than one version definition section present\n"
+msgstr ""
+
+#: src/elflint.c:3272
+#, c-format
+msgid "section [%2d] '%s': more than one BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3276
+#, c-format
+msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"
+msgstr ""
+
+#: src/elflint.c:3282
+#, c-format
+msgid "section [%2d] '%s': entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:3309
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid name reference\n"
+msgstr ""
+
+#: src/elflint.c:3316
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:3324
+#, c-format
+msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3344
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3361
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3394
+#, c-format
+msgid "section [%2d] '%s': no BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3410
+#, c-format
+msgid "section [%2d] '%s': unknown parent version '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3423
+#, c-format
+msgid "section [%2d] '%s': empty object attributes section\n"
+msgstr ""
+
+#: src/elflint.c:3444
+#, c-format
+msgid "section [%2d] '%s': unrecognized attribute format\n"
+msgstr ""
+
+#: src/elflint.c:3460
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3469
+#, c-format
+msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3481
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n"
+msgstr ""
+
+#: src/elflint.c:3498
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"
+msgstr ""
+
+#: src/elflint.c:3507
+#, c-format
+msgid "section [%2d] '%s': offset %zu: truncated attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3516
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3531
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"
+msgstr ""
+
+#. Tag_File
+#: src/elflint.c:3542
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3560
+#, c-format
+msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"
+msgstr ""
+
+#: src/elflint.c:3571
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n"
+msgstr ""
+
+#: src/elflint.c:3584
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3588
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: unrecognized %s attribute value %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3598
+#, c-format
+msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n"
+msgstr ""
+
+#: src/elflint.c:3604
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3693
+#, c-format
+msgid "cannot get section header of zeroth section\n"
+msgstr ""
+
+#: src/elflint.c:3697
+#, c-format
+msgid "zeroth section has nonzero name\n"
+msgstr ""
+
+#: src/elflint.c:3699
+#, c-format
+msgid "zeroth section has nonzero type\n"
+msgstr ""
+
+#: src/elflint.c:3701
+#, c-format
+msgid "zeroth section has nonzero flags\n"
+msgstr ""
+
+#: src/elflint.c:3703
+#, c-format
+msgid "zeroth section has nonzero address\n"
+msgstr ""
+
+#: src/elflint.c:3705
+#, c-format
+msgid "zeroth section has nonzero offset\n"
+msgstr ""
+
+#: src/elflint.c:3707
+#, c-format
+msgid "zeroth section has nonzero align value\n"
+msgstr ""
+
+#: src/elflint.c:3709
+#, c-format
+msgid "zeroth section has nonzero entry size value\n"
+msgstr ""
+
+#: src/elflint.c:3712
+#, c-format
+msgid ""
+"zeroth section has nonzero size value while ELF header has nonzero shnum "
+"value\n"
+msgstr ""
+
+#: src/elflint.c:3716
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in shstrndx\n"
+msgstr ""
+
+#: src/elflint.c:3720
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in phnum\n"
+msgstr ""
+
+#: src/elflint.c:3738
+#, c-format
+msgid "cannot get section header for section [%2zu] '%s': %s\n"
+msgstr ""
+
+#: src/elflint.c:3747
+#, c-format
+msgid "section [%2zu]: invalid name\n"
+msgstr ""
+
+#: src/elflint.c:3774
+#, c-format
+msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3792
+#, c-format
+msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3810
+#, c-format
+msgid ""
+"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3828
+#, c-format
+msgid "section [%2zu] '%s' present in object file\n"
+msgstr ""
+
+#: src/elflint.c:3834 src/elflint.c:3866
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"
+msgstr ""
+
+#: src/elflint.c:3839 src/elflint.c:3871
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable "
+"segments\n"
+msgstr ""
+
+#: src/elflint.c:3847
+#, c-format
+msgid ""
+"section [%2zu] '%s' is extension section index table in non-object file\n"
+msgstr ""
+
+#: src/elflint.c:3890
+#, c-format
+msgid "section [%2zu] '%s': size not multiple of entry size\n"
+msgstr ""
+
+#: src/elflint.c:3895
+#, c-format
+msgid "cannot get section header\n"
+msgstr ""
+
+#: src/elflint.c:3905
+#, c-format
+msgid "section [%2zu] '%s' has unsupported type %d\n"
+msgstr ""
+
+#: src/elflint.c:3920
+#, c-format
+msgid ""
+"section [%2zu] '%s' contains invalid processor-specific flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3927
+#, c-format
+msgid "section [%2zu] '%s' contains unknown flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3935
+#, c-format
+msgid "section [%2zu] '%s': thread-local data sections address not zero\n"
+msgstr ""
+
+#: src/elflint.c:3945
+#, fuzzy, c-format
+msgid "section [%2zu] '%s': allocated section cannot be compressed\n"
+msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
+
+#: src/elflint.c:3950
+#, fuzzy, c-format
+msgid "section [%2zu] '%s': nobits section cannot be compressed\n"
+msgstr "セクション [%2d] '%s': セクションデータを得られません\n"
+
+#: src/elflint.c:3956
+#, c-format
+msgid ""
+"section [%2zu] '%s': compressed section with no compression header: %s\n"
+msgstr ""
+
+#: src/elflint.c:3962
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in link value\n"
+msgstr ""
+
+#: src/elflint.c:3967
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in info value\n"
+msgstr ""
+
+#: src/elflint.c:3974
+#, c-format
+msgid "section [%2zu] '%s': strings flag set without merge flag\n"
+msgstr ""
+
+#: src/elflint.c:3979
+#, c-format
+msgid "section [%2zu] '%s': merge flag set but entry size is zero\n"
+msgstr ""
+
+#: src/elflint.c:3998
+#, c-format
+msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n"
+msgstr ""
+
+#: src/elflint.c:4007
+#, c-format
+msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n"
+msgstr ""
+
+#: src/elflint.c:4014
+#, c-format
+msgid "section [%2zu] '%s' is both executable and writable\n"
+msgstr ""
+
+#: src/elflint.c:4045
+#, c-format
+msgid ""
+"section [%2zu] '%s' not fully contained in segment of program header entry "
+"%d\n"
+msgstr ""
+
+#: src/elflint.c:4055
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:4081
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d and file contents is non-zero\n"
+msgstr ""
+
+#: src/elflint.c:4092
+#, c-format
+msgid ""
+"section [%2zu] '%s' has not type NOBITS but is not read from the file in "
+"segment of program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:4103
+#, c-format
+msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:4113
+#, c-format
+msgid "section [%2zu] '%s' is writable in unwritable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:4123
+#, c-format
+msgid ""
+"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:4129
+#, c-format
+msgid ""
+"section [%2zu] '%s': ELF header says this is the section header string table "
+"but type is not SHT_TYPE\n"
+msgstr ""
+
+#: src/elflint.c:4137
+#, c-format
+msgid ""
+"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"
+msgstr ""
+
+#: src/elflint.c:4188
+#, c-format
+msgid "more than one version symbol table present\n"
+msgstr ""
+
+#: src/elflint.c:4211
+#, c-format
+msgid "INTERP program header entry but no .interp section\n"
+msgstr ""
+
+#: src/elflint.c:4222
+#, c-format
+msgid ""
+"loadable segment [%u] is executable but contains no executable sections\n"
+msgstr ""
+
+#: src/elflint.c:4228
+#, c-format
+msgid "loadable segment [%u] is writable but contains no writable sections\n"
+msgstr ""
+
+#: src/elflint.c:4239
+#, c-format
+msgid ""
+"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section "
+"exist\n"
+msgstr ""
+
+#: src/elflint.c:4252
+#, c-format
+msgid "duplicate version index %d\n"
+msgstr ""
+
+#: src/elflint.c:4266
+#, c-format
+msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"
+msgstr ""
+
+#: src/elflint.c:4315
+#, c-format
+msgid "phdr[%d]: unknown core file note type %<PRIu32> at offset %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:4319
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown core file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+
+#: src/elflint.c:4342
+#, c-format
+msgid "phdr[%d]: unknown object file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+
+#: src/elflint.c:4346
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown object file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+
+#: src/elflint.c:4363
+#, c-format
+msgid "phdr[%d]: no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4382
+#, c-format
+msgid "phdr[%d]: cannot get content of note section: %s\n"
+msgstr ""
+
+#: src/elflint.c:4385
+#, c-format
+msgid "phdr[%d]: extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4406
+#, c-format
+msgid "section [%2d] '%s': no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4413
+#, c-format
+msgid "section [%2d] '%s': cannot get content of note section\n"
+msgstr ""
+
+#: src/elflint.c:4416
+#, c-format
+msgid "section [%2d] '%s': extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4434
+#, c-format
+msgid ""
+"only executables, shared objects, and core files can have program headers\n"
+msgstr ""
+
+#: src/elflint.c:4449
+#, c-format
+msgid "cannot get program header entry %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:4458
+#, c-format
+msgid "program header entry %d: unknown program header entry type %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:4469
+#, c-format
+msgid "more than one INTERP entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4477
+#, c-format
+msgid "more than one TLS entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4484
+#, c-format
+msgid "static executable cannot have dynamic sections\n"
+msgstr ""
+
+#: src/elflint.c:4498
+#, c-format
+msgid "dynamic section reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4501
+#, c-format
+msgid "dynamic section size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4511
+#, c-format
+msgid "more than one GNU_RELRO entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4532
+#, c-format
+msgid "loadable segment GNU_RELRO applies to is not writable\n"
+msgstr ""
+
+#: src/elflint.c:4543
+#, c-format
+msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"
+msgstr ""
+
+#: src/elflint.c:4550
+#, c-format
+msgid ""
+"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n"
+msgstr ""
+
+#: src/elflint.c:4559 src/elflint.c:4582
+#, c-format
+msgid "%s segment not contained in a loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:4588
+#, c-format
+msgid "program header offset in ELF header and PHDR entry do not match"
+msgstr ""
+
+#: src/elflint.c:4613
+#, c-format
+msgid "call frame search table reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4616
+#, c-format
+msgid "call frame search table size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4629
+#, c-format
+msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"
+msgstr ""
+
+#: src/elflint.c:4637
+#, c-format
+msgid "call frame search table must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4640
+#, c-format
+msgid "section [%2zu] '%s' must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4644
+#, c-format
+msgid "call frame search table must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4647
+#, c-format
+msgid "section [%2zu] '%s' must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4652
+#, c-format
+msgid "call frame search table must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4655
+#, c-format
+msgid "section [%2zu] '%s' must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4666
+#, c-format
+msgid "program header entry %d: file size greater than memory size\n"
+msgstr ""
+
+#: src/elflint.c:4673
+#, c-format
+msgid "program header entry %d: alignment not a power of 2\n"
+msgstr ""
+
+#: src/elflint.c:4676
+#, c-format
+msgid ""
+"program header entry %d: file offset and virtual address not module of "
+"alignment\n"
+msgstr ""
+
+#: src/elflint.c:4689
+#, c-format
+msgid ""
+"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME "
+"program header entry"
+msgstr ""
+
+#: src/elflint.c:4723
+#, c-format
+msgid "cannot read ELF header: %s\n"
+msgstr ""
+
+#: src/elflint.c:4749
+#, c-format
+msgid "text relocation flag set but not needed\n"
+msgstr ""
+
+#: src/findtextrel.c:61
+msgid "Input Selection:"
+msgstr ""
+
+#: src/findtextrel.c:62
+msgid "Prepend PATH to all file names"
+msgstr ""
+
+#: src/findtextrel.c:64
+msgid "Use PATH as root of debuginfo hierarchy"
+msgstr ""
+
+#. Short description of program.
+#: src/findtextrel.c:71
+msgid "Locate source of text relocations in FILEs (a.out by default)."
+msgstr ""
+
+#. Strings for arguments in help texts.
+#: src/findtextrel.c:75 src/nm.c:109 src/objdump.c:72 src/size.c:81
+#: src/strings.c:88 src/strip.c:99
+msgid "[FILE...]"
+msgstr "[ふぁいる...]"
+
+#: src/findtextrel.c:223
+#, c-format
+msgid "cannot get ELF header '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:234
+#, c-format
+msgid "'%s' is not a DSO or PIE"
+msgstr ""
+
+#: src/findtextrel.c:254
+#, c-format
+msgid "getting get section header of section %zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:277
+#, c-format
+msgid "cannot read dynamic section: %s"
+msgstr ""
+
+#: src/findtextrel.c:298
+#, c-format
+msgid "no text relocations reported in '%s'"
+msgstr ""
+
+#: src/findtextrel.c:310
+#, c-format
+msgid "while reading ELF file"
+msgstr ""
+
+#: src/findtextrel.c:314
+#, fuzzy, c-format
+msgid "cannot get program header count: %s"
+msgstr "プログラムヘッダーを得られません: %s"
+
+#: src/findtextrel.c:325 src/findtextrel.c:342
+#, fuzzy, c-format
+msgid "cannot get program header index at offset %zd: %s"
+msgstr "プログラムヘッダーを得られません: %s"
+
+#: src/findtextrel.c:406
+#, c-format
+msgid "cannot get symbol table section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:426 src/findtextrel.c:449
+#, c-format
+msgid "cannot get relocation at index %d in section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:515
+#, c-format
+msgid "%s not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:568
+#, c-format
+msgid ""
+"the file containing the function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:575 src/findtextrel.c:595
+#, c-format
+msgid ""
+"the file containing the function '%s' might not be compiled with -fpic/-"
+"fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:583
+#, c-format
+msgid ""
+"either the file containing the function '%s' or the file containing the "
+"function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:603
+#, c-format
+msgid ""
+"a relocation modifies memory at offset %llu in a write-protected segment\n"
+msgstr ""
+
+#: src/nm.c:67 src/strip.c:70
+msgid "Output selection:"
+msgstr "出力選択:"
+
+#: src/nm.c:68
+msgid "Display debugger-only symbols"
+msgstr "デバッガー専用シンボルを表示"
+
+#: src/nm.c:69
+msgid "Display only defined symbols"
+msgstr "定義されたシンボルのみを表示"
+
+#: src/nm.c:72
+msgid "Display dynamic symbols instead of normal symbols"
+msgstr "通常シンボルの代わりに動的シンボルを表示"
+
+#: src/nm.c:73
+msgid "Display only external symbols"
+msgstr "外部シンボルのみを表示"
+
+#: src/nm.c:74
+msgid "Display only undefined symbols"
+msgstr "未定義シンボルのみを表示"
+
+#: src/nm.c:76
+msgid "Include index for symbols from archive members"
+msgstr "アーカイブメンバーからのシンボルの索引を含める"
+
+#: src/nm.c:78 src/size.c:55
+msgid "Output format:"
+msgstr "出力形式:"
+
+#: src/nm.c:80
+msgid "Print name of the input file before every symbol"
+msgstr "全てのシンボルの前に入力ファイル名を印刷"
+
+#: src/nm.c:83
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd', `sysv' or `posix'.  The "
+"default is `sysv'"
+msgstr ""
+"出力形式として FORMATを使う。FORMAT は `bsd'か、`sysv'、`posix' のどれか。省"
+"略値は `sysv'"
+
+#: src/nm.c:85
+msgid "Same as --format=bsd"
+msgstr "--format=bsd と同じ"
+
+#: src/nm.c:86
+msgid "Same as --format=posix"
+msgstr "--format=posix と同じ"
+
+#: src/nm.c:87 src/size.c:61
+msgid "Use RADIX for printing symbol values"
+msgstr "シンボル値を印刷するために RADIX を使う"
+
+#: src/nm.c:88
+#, fuzzy
+msgid "Mark special symbols"
+msgstr "弱いシンボルに印を点ける"
+
+#: src/nm.c:90
+msgid "Print size of defined symbols"
+msgstr "定義されたシンボルの印刷サイズ"
+
+#: src/nm.c:92 src/size.c:69 src/strip.c:75 src/unstrip.c:73
+msgid "Output options:"
+msgstr "出力オプション:"
+
+#: src/nm.c:93
+msgid "Sort symbols numerically by address"
+msgstr "シンボルをアドレスにより数値的に並べ替える"
+
+#: src/nm.c:95
+msgid "Do not sort the symbols"
+msgstr "シンボルを並べ替えない"
+
+#: src/nm.c:96
+msgid "Reverse the sense of the sort"
+msgstr "並べ替えの意味を逆にする"
+
+#: src/nm.c:99
+msgid "Decode low-level symbol names into source code names"
+msgstr ""
+
+#. Short description of program.
+#: src/nm.c:106
+msgid "List symbols from FILEs (a.out by default)."
+msgstr "ふぁいる からシンボルを表示 (デフォルトではa.out)。"
+
+#: src/nm.c:117 src/objdump.c:80
+#, fuzzy
+msgid "Output formatting"
+msgstr "出力形式:"
+
+#: src/nm.c:141 src/objdump.c:104 src/size.c:106 src/strip.c:131
+#, fuzzy, c-format
+msgid "%s: INTERNAL ERROR %d (%s): %s"
+msgstr "%s: 内部エラー %d (%s-%s): %s"
+
+#: src/nm.c:382 src/nm.c:394 src/size.c:289 src/size.c:298 src/size.c:309
+#: src/strip.c:2421
+#, c-format
+msgid "while closing '%s'"
+msgstr "'%s' を閉じている最中"
+
+#: src/nm.c:404 src/objdump.c:281 src/strip.c:443
+#, c-format
+msgid "%s: File format not recognized"
+msgstr "%s: ファイル形式を認識できませんでした"
+
+#. Note: 0 is no valid offset.
+#: src/nm.c:444
+#, fuzzy
+msgid ""
+"\n"
+"Archive index:\n"
+msgstr ""
+"\n"
+"アーカイブ索引:"
+
+#: src/nm.c:453
+#, c-format
+msgid "invalid offset %zu for symbol %s"
+msgstr "シンボル %2$sの不正なオフセット %1$zu "
+
+#: src/nm.c:458
+#, c-format
+msgid "%s in %s\n"
+msgstr "%2$s の中の %1$s\n"
+
+#: src/nm.c:466
+#, c-format
+msgid "cannot reset archive offset to beginning"
+msgstr "アーカイブのオフセットを最初にリセットできません"
+
+#: src/nm.c:491 src/objdump.c:329
+#, c-format
+msgid "%s%s%s: file format not recognized"
+msgstr "%s%s%s: ファイル形式を認識できません"
+
+#: src/nm.c:706
+#, c-format
+msgid "cannot create search tree"
+msgstr "検索ツリーを生成できません"
+
+#: src/nm.c:747 src/nm.c:1208 src/objdump.c:778 src/readelf.c:551
+#: src/readelf.c:1129 src/readelf.c:1329 src/readelf.c:1477 src/readelf.c:1678
+#: src/readelf.c:1884 src/readelf.c:2074 src/readelf.c:2252 src/readelf.c:2328
+#: src/readelf.c:2586 src/readelf.c:2662 src/readelf.c:2749 src/readelf.c:3329
+#: src/readelf.c:3379 src/readelf.c:3442 src/readelf.c:8444 src/readelf.c:9544
+#: src/readelf.c:9747 src/readelf.c:9815 src/size.c:397 src/size.c:466
+#: src/strip.c:572
+#, c-format
+msgid "cannot get section header string table index"
+msgstr "セクションヘッダー文字列テーブル索引が得られません"
+
+#. We always print this prolog.
+#: src/nm.c:774
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s:\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"%s からのシンボル:\n"
+"\n"
+
+#. The header line.
+#: src/nm.c:777
+#, c-format
+msgid ""
+"%*s%-*s %-*s Class  Type     %-*s %*s Section\n"
+"\n"
+msgstr ""
+"%*s%-*s %-*s クラス タイプ   %-*s %*s セクション\n"
+"\n"
+
+#: src/nm.c:1219
+#, fuzzy, c-format
+msgid "%s: entry size in section %zd `%s' is not what we expect"
+msgstr "%s: セクションの項目の大きさ `%s' は予期したものとは異なります"
+
+#: src/nm.c:1224
+#, fuzzy, c-format
+msgid "%s: size of section %zd `%s' is not multiple of entry size"
+msgstr "%s: セクション `%s' の大きさは項目の大きさの整数倍ではありません"
+
+#: src/nm.c:1303
+#, fuzzy, c-format
+msgid "%s: entries (%zd) in section %zd `%s' is too large"
+msgstr "%s: セクションの項目の大きさ `%s' は予期したものとは異なります"
+
+#. XXX Add machine specific object file types.
+#: src/nm.c:1529
+#, c-format
+msgid "%s%s%s%s: Invalid operation"
+msgstr "%s%s%s%s: 不当な操作"
+
+#: src/nm.c:1586
+#, c-format
+msgid "%s%s%s: no symbols"
+msgstr "%s%s%s: シンボルがありません"
+
+#: src/objdump.c:53
+msgid "Mode selection:"
+msgstr ""
+
+#: src/objdump.c:54
+msgid "Display relocation information."
+msgstr ""
+
+#: src/objdump.c:56
+msgid "Display the full contents of all sections requested"
+msgstr ""
+
+#: src/objdump.c:58
+msgid "Display assembler code of executable sections"
+msgstr ""
+
+#: src/objdump.c:60
+#, fuzzy
+msgid "Output content selection:"
+msgstr "出力選択:"
+
+#: src/objdump.c:62
+msgid "Only display information for section NAME."
+msgstr ""
+
+#. Short description of program.
+#: src/objdump.c:68
+msgid "Show information from FILEs (a.out by default)."
+msgstr ""
+
+#: src/objdump.c:219 src/readelf.c:499
+msgid "No operation specified.\n"
+msgstr "操作が指定されていません。\n"
+
+#: src/objdump.c:259 src/objdump.c:271
+#, c-format
+msgid "while close `%s'"
+msgstr ""
+
+#: src/objdump.c:364 src/readelf.c:1979 src/readelf.c:2171
+msgid "INVALID SYMBOL"
+msgstr "不当なシンボル"
+
+#: src/objdump.c:379 src/readelf.c:2013 src/readelf.c:2207
+msgid "INVALID SECTION"
+msgstr "不当なセクション"
+
+#: src/objdump.c:499
+#, c-format
+msgid ""
+"\n"
+"RELOCATION RECORDS FOR [%s]:\n"
+"%-*s TYPE                 VALUE\n"
+msgstr ""
+
+#: src/objdump.c:502
+msgid "OFFSET"
+msgstr ""
+
+#: src/objdump.c:567
+#, c-format
+msgid "Contents of section %s:\n"
+msgstr ""
+
+#: src/objdump.c:688
+#, c-format
+msgid "cannot disassemble"
+msgstr ""
+
+#. Short description of program.
+#: src/ranlib.c:64
+msgid "Generate an index to speed access to archives."
+msgstr ""
+
+#. Strings for arguments in help texts.
+#: src/ranlib.c:67
+msgid "ARCHIVE"
+msgstr ""
+
+#: src/ranlib.c:103
+#, c-format
+msgid "Archive name required"
+msgstr ""
+
+#: src/ranlib.c:167
+#, c-format
+msgid "'%s' is no archive"
+msgstr ""
+
+#: src/ranlib.c:202
+#, c-format
+msgid "error while freeing sub-ELF descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:87
+#, fuzzy
+msgid "ELF input selection:"
+msgstr "出力選択:"
+
+#: src/readelf.c:89
+msgid ""
+"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data"
+msgstr ""
+
+#: src/readelf.c:91
+#, fuzzy
+msgid "ELF output selection:"
+msgstr "出力選択:"
+
+#: src/readelf.c:93
+msgid "All these plus -p .strtab -p .dynstr -p .comment"
+msgstr ""
+
+#: src/readelf.c:94
+msgid "Display the dynamic segment"
+msgstr "動的セグメントを表示"
+
+#: src/readelf.c:95
+msgid "Display the ELF file header"
+msgstr "ELF ファイルヘッダーを表示"
+
+#: src/readelf.c:97
+msgid "Display histogram of bucket list lengths"
+msgstr "バケットリスト長の柱状図を表示"
+
+#: src/readelf.c:98
+msgid "Display the program headers"
+msgstr "プログラムヘッダーを表示"
+
+#: src/readelf.c:100
+msgid "Display relocations"
+msgstr "リロケーションを表示"
+
+#: src/readelf.c:101
+#, fuzzy
+msgid "Display the sections' headers"
+msgstr "セクションのヘッダーを表示"
+
+#: src/readelf.c:104
+#, fuzzy
+msgid "Display the symbol table sections"
+msgstr "シンボルテーブルを表示"
+
+#: src/readelf.c:105
+msgid "Display versioning information"
+msgstr "バージョニング情報の表示"
+
+#: src/readelf.c:106
+#, fuzzy
+msgid "Display the ELF notes"
+msgstr "コアノートを表示"
+
+#: src/readelf.c:108
+#, fuzzy
+msgid "Display architecture specific information, if any"
+msgstr "(もしあれば)アーキテクチャー固有の情報を表示"
+
+#: src/readelf.c:110
+msgid "Display sections for exception handling"
+msgstr "例外を取り扱うためのセクションを表示"
+
+#: src/readelf.c:112
+#, fuzzy
+msgid "Additional output selection:"
+msgstr "出力選択:"
+
+#: src/readelf.c:114
+#, fuzzy
+msgid ""
+"Display DWARF section content.  SECTION can be one of abbrev, aranges, "
+"decodedaranges, frame, gdb_index, info, loc, line, decodedline, ranges, "
+"pubnames, str, macinfo, macro or exception"
+msgstr ""
+"DWARF セクションの内容を表示。SECTION は addrevか、aranges、frame、info、"
+"loc、ranges、pubnames、str、macinfo、exception のいずれかです"
+
+#: src/readelf.c:118
+msgid "Dump the uninterpreted contents of SECTION, by number or name"
+msgstr "数字か名前で解釈できないセクションの内容をダンプする"
+
+#: src/readelf.c:120
+msgid "Print string contents of sections"
+msgstr "セクションの文字列内容を印刷する"
+
+#: src/readelf.c:123
+msgid "Display the symbol index of an archive"
+msgstr "アーカイブのシンボル索引を表示"
+
+#: src/readelf.c:125
+msgid "Output control:"
+msgstr "出力制御:"
+
+#: src/readelf.c:127
+msgid "Do not find symbol names for addresses in DWARF data"
+msgstr "DWARFデータ中のアドレスのためのシンボル名を探さない"
+
+#: src/readelf.c:129
+#, fuzzy
+msgid ""
+"Display just offsets instead of resolving values to addresses in DWARF data"
+msgstr "DWARFデータ中のアドレスのためのシンボル名を探さない"
+
+#: src/readelf.c:131
+msgid "Ignored for compatibility (lines always wide)"
+msgstr ""
+
+#: src/readelf.c:133
+msgid ""
+"Show compression information for compressed sections (when used with -S); "
+"decompress section before dumping data (when used with -p or -x)"
+msgstr ""
+
+#. Short description of program.
+#: src/readelf.c:138
+msgid "Print information from ELF file in human-readable form."
+msgstr "ELF ファイルから人間が読める形で情報を印刷する。"
+
+#: src/readelf.c:467
+#, c-format
+msgid "Unknown DWARF debug section `%s'.\n"
+msgstr "不明な DWARF デバッグセクション `%s'.\n"
+
+#: src/readelf.c:535 src/readelf.c:646
+#, c-format
+msgid "cannot generate Elf descriptor: %s"
+msgstr "Elf 記述子を生成できません: %s"
+
+#: src/readelf.c:542 src/readelf.c:858 src/strip.c:641
+#, c-format
+msgid "cannot determine number of sections: %s"
+msgstr "セクション数を決定できません: %s"
+
+#: src/readelf.c:560 src/readelf.c:1151 src/readelf.c:1353
+#, c-format
+msgid "cannot get section: %s"
+msgstr "セクションを得られません: %s"
+
+#: src/readelf.c:569 src/readelf.c:1158 src/readelf.c:1361 src/readelf.c:9767
+#: src/unstrip.c:375 src/unstrip.c:406 src/unstrip.c:455 src/unstrip.c:565
+#: src/unstrip.c:582 src/unstrip.c:619 src/unstrip.c:817 src/unstrip.c:1109
+#: src/unstrip.c:1301 src/unstrip.c:1362 src/unstrip.c:1535 src/unstrip.c:1650
+#: src/unstrip.c:1790 src/unstrip.c:1885
+#, c-format
+msgid "cannot get section header: %s"
+msgstr "セクションヘッダーを得られません: %s"
+
+#: src/readelf.c:577
+#, fuzzy, c-format
+msgid "cannot get section name"
+msgstr "セクションを得られません: %s"
+
+#: src/readelf.c:586 src/readelf.c:5562 src/readelf.c:7902 src/readelf.c:8004
+#: src/readelf.c:8181
+#, c-format
+msgid "cannot get %s content: %s"
+msgstr "%s の内容を得られません: %s"
+
+#: src/readelf.c:602
+#, fuzzy, c-format
+msgid "cannot create temp file '%s'"
+msgstr "新しいファイル '%s' を生成できません: %s"
+
+#: src/readelf.c:611
+#, fuzzy, c-format
+msgid "cannot write section data"
+msgstr "セクションデータを割り当てられません: %s"
+
+#: src/readelf.c:617 src/readelf.c:634 src/readelf.c:663
+#, c-format
+msgid "error while closing Elf descriptor: %s"
+msgstr "Elf 記述子を閉じている時にエラー: %s"
+
+#: src/readelf.c:624
+#, fuzzy, c-format
+msgid "error while rewinding file descriptor"
+msgstr "Elf 記述子を閉じている時にエラー: %s"
+
+#: src/readelf.c:658
+#, c-format
+msgid "'%s' is not an archive, cannot print archive index"
+msgstr "'%s' はアーカイブではなく、アーカイブ索引を印刷できません"
+
+#: src/readelf.c:757
+#, fuzzy, c-format
+msgid "No such section '%s' in '%s'"
+msgstr "セクション [%Zu] '%s' からデータが得られません: %s"
+
+#: src/readelf.c:784
+#, c-format
+msgid "cannot stat input file"
+msgstr "入力ファイルを stat できません"
+
+#: src/readelf.c:786
+#, c-format
+msgid "input file is empty"
+msgstr "入力ファイルが空です"
+
+#: src/readelf.c:788
+#, c-format
+msgid "failed reading '%s': %s"
+msgstr "'%s' の読込みに失敗: %s"
+
+#: src/readelf.c:843
+#, c-format
+msgid "cannot read ELF header: %s"
+msgstr "ELF ヘッダーが読めません: %s"
+
+#: src/readelf.c:851
+#, c-format
+msgid "cannot create EBL handle"
+msgstr "EBL ヘッダーを生成できません"
+
+#: src/readelf.c:864
+#, fuzzy, c-format
+msgid "cannot determine number of program headers: %s"
+msgstr "セクション数を決定できません: %s"
+
+#: src/readelf.c:954
+msgid "NONE (None)"
+msgstr "なし (なし)"
+
+#: src/readelf.c:955
+msgid "REL (Relocatable file)"
+msgstr "REL (リロケータブルファイル)"
+
+#: src/readelf.c:956
+msgid "EXEC (Executable file)"
+msgstr "(EXEC (実行ファイル)"
+
+#: src/readelf.c:957
+msgid "DYN (Shared object file)"
+msgstr "DYN (共用オブジェクトファイル)"
+
+#: src/readelf.c:958
+msgid "CORE (Core file)"
+msgstr "CORE (コアファイル)"
+
+#: src/readelf.c:963
+#, c-format
+msgid "OS Specific: (%x)\n"
+msgstr "OS 固有: (%x)\n"
+
+#. && e_type <= ET_HIPROC always true
+#: src/readelf.c:965
+#, c-format
+msgid "Processor Specific: (%x)\n"
+msgstr "プロセッサー固有: (%x)\n"
+
+#: src/readelf.c:975
+msgid ""
+"ELF Header:\n"
+"  Magic:  "
+msgstr ""
+"ELF ヘッダー:\n"
+" マジック: "
+
+#: src/readelf.c:979
+#, c-format
+msgid ""
+"\n"
+"  Class:                             %s\n"
+msgstr ""
+"\n"
+"  クラス:                            %s\n"
+
+#: src/readelf.c:984
+#, c-format
+msgid "  Data:                              %s\n"
+msgstr "  データ:                            %s\n"
+
+#: src/readelf.c:990
+#, c-format
+msgid "  Ident Version:                     %hhd %s\n"
+msgstr "  識別バージョン:                    %hhd %s\n"
+
+#: src/readelf.c:992 src/readelf.c:1009
+msgid "(current)"
+msgstr "(現在)"
+
+#: src/readelf.c:996
+#, c-format
+msgid "  OS/ABI:                            %s\n"
+msgstr "  OS/ABI:                            %s\n"
+
+#: src/readelf.c:999
+#, c-format
+msgid "  ABI Version:                       %hhd\n"
+msgstr "  ABI バージョン:                    %hhd\n"
+
+#: src/readelf.c:1002
+msgid "  Type:                              "
+msgstr "  タイプ:                            "
+
+#: src/readelf.c:1005
+#, c-format
+msgid "  Machine:                           %s\n"
+msgstr "  マシン :                           %s\n"
+
+#: src/readelf.c:1007
+#, c-format
+msgid "  Version:                           %d %s\n"
+msgstr "  バージョン:                        %d %s\n"
+
+#: src/readelf.c:1011
+#, c-format
+msgid "  Entry point address:               %#<PRIx64>\n"
+msgstr "  入口点アドレス     :               %#<PRIx64>\n"
+
+#: src/readelf.c:1014
+#, c-format
+msgid "  Start of program headers:          %<PRId64> %s\n"
+msgstr "  プログラムヘッダーの開始:          %<PRId64> %s\n"
+
+#: src/readelf.c:1015 src/readelf.c:1018
+msgid "(bytes into file)"
+msgstr "(ファイルへのバイト数)"
+
+#: src/readelf.c:1017
+#, c-format
+msgid "  Start of section headers:          %<PRId64> %s\n"
+msgstr "  セクションヘッダーの開始:          %<PRId64> %s\n"
+
+#: src/readelf.c:1020
+#, c-format
+msgid "  Flags:                             %s\n"
+msgstr "  フラグ:                            %s\n"
+
+#: src/readelf.c:1023
+#, c-format
+msgid "  Size of this header:               %<PRId16> %s\n"
+msgstr "  このヘッダーの大きさ:              %<PRId16> %s\n"
+
+#: src/readelf.c:1024 src/readelf.c:1027 src/readelf.c:1044
+msgid "(bytes)"
+msgstr "(バイト)"
+
+#: src/readelf.c:1026
+#, c-format
+msgid "  Size of program header entries:    %<PRId16> %s\n"
+msgstr "  プログラムヘッダー項目の大きさ:%<PRId16> %s\n"
+
+#: src/readelf.c:1029
+#, fuzzy, c-format
+msgid "  Number of program headers entries: %<PRId16>"
+msgstr "  プログラムヘッダー項目の数 : %<PRId16>\n"
+
+#: src/readelf.c:1036
+#, fuzzy, c-format
+msgid " (%<PRIu32> in [0].sh_info)"
+msgstr "([0].sh_link の %<PRIu32>)"
+
+#: src/readelf.c:1039 src/readelf.c:1056 src/readelf.c:1070
+msgid " ([0] not available)"
+msgstr "([0]は使えません)"
+
+#: src/readelf.c:1043
+#, c-format
+msgid "  Size of section header entries:    %<PRId16> %s\n"
+msgstr "  セクションヘッダー項目の大きさ:%<PRId16> %s\n"
+
+#: src/readelf.c:1046
+#, c-format
+msgid "  Number of section headers entries: %<PRId16>"
+msgstr "  セクションヘッダー項目の数 : %<PRId16>"
+
+#: src/readelf.c:1053
+#, c-format
+msgid " (%<PRIu32> in [0].sh_size)"
+msgstr " ([0].sh_size の %<PRIu32>)"
+
+#. We managed to get the zeroth section.
+#: src/readelf.c:1066
+#, c-format
+msgid " (%<PRIu32> in [0].sh_link)"
+msgstr "([0].sh_link の %<PRIu32>)"
+
+#: src/readelf.c:1074
+#, c-format
+msgid ""
+"  Section header string table index: XINDEX%s\n"
+"\n"
+msgstr ""
+"  セクションヘッダー文字列テーブル索引: XINDEX%s\n"
+"\n"
+
+#: src/readelf.c:1078
+#, c-format
+msgid ""
+"  Section header string table index: %<PRId16>\n"
+"\n"
+msgstr ""
+"  セクションヘッダー文字列テーブル索引: %<PRId16>\n"
+"\n"
+
+#: src/readelf.c:1121
+#, c-format
+msgid ""
+"There are %d section headers, starting at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+"オフセット %2$#<PRIx64> から始まる %1$d 個のセクションヘッダーがあります:\n"
+"\n"
+
+#: src/readelf.c:1131
+msgid "Section Headers:"
+msgstr "セクションヘッダー:"
+
+#: src/readelf.c:1134
+msgid ""
+"[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
+"Inf Al"
+msgstr ""
+"[番] 名前                 タイプ       アドレス オフセ 大きさ ES フラグLk "
+"Inf Al"
+
+#: src/readelf.c:1136
+msgid ""
+"[Nr] Name                 Type         Addr             Off      Size     ES "
+"Flags Lk Inf Al"
+msgstr ""
+"[番] 名前                 タイプ       アドレス         オフセ   大きさ   ES "
+"フラグLk Inf Al"
+
+#: src/readelf.c:1141
+msgid "     [Compression  Size   Al]"
+msgstr ""
+
+#: src/readelf.c:1143
+msgid "     [Compression  Size     Al]"
+msgstr ""
+
+#: src/readelf.c:1219
+#, fuzzy, c-format
+msgid "bad compression header for section %zd: %s"
+msgstr "セクションヘッダー文字列セクションを生成できません: %s"
+
+#: src/readelf.c:1230
+#, fuzzy, c-format
+msgid "bad gnu compressed size for section %zd: %s"
+msgstr "セクションからデータを得られません %d: %s"
+
+#: src/readelf.c:1248
+msgid "Program Headers:"
+msgstr "プログラムヘッダー:"
+
+#: src/readelf.c:1250
+msgid ""
+"  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
+msgstr ""
+"  タイプ         オフセ   仮アドレス 物アドレス ファイ量 メモ量   Flg 調整 "
+
+#: src/readelf.c:1253
+msgid ""
+"  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
+"MemSiz   Flg Align"
+msgstr ""
+"  タイプ         オフセ   仮想アドレス       物理アドレス      ファイル量メモ"
+"量   Flg 調整 "
+
+#: src/readelf.c:1310
+#, c-format
+msgid "\t[Requesting program interpreter: %s]\n"
+msgstr "\t[プログラム割込みを要求: %s]\n"
+
+#: src/readelf.c:1331
+msgid ""
+"\n"
+" Section to Segment mapping:\n"
+"  Segment Sections..."
+msgstr ""
+"\n"
+" セクションからセグメントへのマッビング:\n"
+"  セグメント セクション..."
+
+#: src/readelf.c:1342 src/unstrip.c:1944 src/unstrip.c:1986 src/unstrip.c:1993
+#, c-format
+msgid "cannot get program header: %s"
+msgstr "プログラムヘッダーを得られません: %s"
+
+#: src/readelf.c:1485
+#, c-format
+msgid ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"署名 '%3$s' を持つ COMDAT セクショングループ [%1$2zu] '%2$s' には %4$zu 個の"
+"項目があります:\n"
+
+#: src/readelf.c:1490
+#, c-format
+msgid ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"署名 '%3$s' を持つセクショングループ [%1$2zu] '%2$s' には %4$zu 個の項目があ"
+"ります:\n"
+
+#: src/readelf.c:1498
+msgid "<INVALID SYMBOL>"
+msgstr "<不当なシンボル>"
+
+#: src/readelf.c:1512
+msgid "<INVALID SECTION>"
+msgstr "<不当なセクション>"
+
+#: src/readelf.c:1535 src/readelf.c:2262 src/readelf.c:3345 src/readelf.c:9638
+#: src/readelf.c:9645 src/readelf.c:9689 src/readelf.c:9696
+msgid "Couldn't uncompress section"
+msgstr ""
+
+#: src/readelf.c:1540 src/readelf.c:2267 src/readelf.c:3350
+#, fuzzy, c-format
+msgid "cannot get section [%zd] header: %s"
+msgstr "セクションヘッダーを得られません: %s"
+
+#: src/readelf.c:1684 src/readelf.c:2334 src/readelf.c:2592 src/readelf.c:2668
+#: src/readelf.c:2972 src/readelf.c:3046 src/readelf.c:4773
+#, fuzzy, c-format
+msgid "invalid sh_link value in section %zu"
+msgstr "不当な .debug_line セクション"
+
+#: src/readelf.c:1687
+#, c-format
+msgid ""
+"\n"
+"Dynamic segment contains %lu entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Dynamic segment contains %lu entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"動的セグメントには %lu 個の項目があります:\n"
+" アドレス: %#0*<PRIx64>  オフセット: %#08<PRIx64>  セクションへのリンク: "
+"[%2u] '%s'\n"
+
+#: src/readelf.c:1697
+msgid "  Type              Value\n"
+msgstr "  タイプ            値\n"
+
+#: src/readelf.c:1721
+#, c-format
+msgid "Shared library: [%s]\n"
+msgstr "共用ライブラリー: [%s]\n"
+
+#: src/readelf.c:1726
+#, c-format
+msgid "Library soname: [%s]\n"
+msgstr "ライブラリー so 名: [%s]\n"
+
+#: src/readelf.c:1731
+#, c-format
+msgid "Library rpath: [%s]\n"
+msgstr "ライブラリー rパス: [%s]\n"
+
+#: src/readelf.c:1736
+#, c-format
+msgid "Library runpath: [%s]\n"
+msgstr "ライブラリー run パス: [%s]\n"
+
+#: src/readelf.c:1756
+#, c-format
+msgid "%<PRId64> (bytes)\n"
+msgstr "%<PRId64> (バイト)\n"
+
+#: src/readelf.c:1869 src/readelf.c:2059
+#, c-format
+msgid ""
+"\n"
+"Invalid symbol table at offset %#0<PRIx64>\n"
+msgstr ""
+"\n"
+"オフセット %#0<PRIx64> に不当なシンボルテーブル\n"
+
+#: src/readelf.c:1887 src/readelf.c:2077
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"オフセット %5$#0<PRIx64> のセクション [%3$2u] '%4$s' 用のリロケーションセク"
+"ション [%1$2zu] '%2$s' には %6$d 個の項目があります:\n"
+
+#. The .rel.dyn section does not refer to a specific section but
+#. instead of section index zero.  Do not try to print a section
+#. name.
+#. The .rela.dyn section does not refer to a specific section but
+#. instead of section index zero.  Do not try to print a section
+#. name.
+#: src/readelf.c:1902 src/readelf.c:2092
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"オフセット %3$#0<PRIx64> のリロケーションセクション [%1$2u] '%2$s' には %4$d "
+"個の項目があります:\n"
+
+#: src/readelf.c:1912
+msgid "  Offset      Type                 Value       Name\n"
+msgstr "  オフセット  タイプ               値          名前\n"
+
+#: src/readelf.c:1914
+msgid "  Offset              Type                 Value               Name\n"
+msgstr "  オフセット          タイプ               値                  名前\n"
+
+#: src/readelf.c:1967 src/readelf.c:1978 src/readelf.c:1991 src/readelf.c:2012
+#: src/readelf.c:2024 src/readelf.c:2158 src/readelf.c:2170 src/readelf.c:2184
+#: src/readelf.c:2206 src/readelf.c:2219
+msgid "<INVALID RELOC>"
+msgstr "<不当なRELOC>"
+
+#: src/readelf.c:2102
+msgid "  Offset      Type            Value       Addend Name\n"
+msgstr "  オフセット  タイプ          値          付加名\n"
+
+#: src/readelf.c:2104
+msgid "  Offset              Type            Value               Addend Name\n"
+msgstr "  オフセット          タイプ          値                  付加名\n"
+
+#: src/readelf.c:2342
+#, c-format
+msgid ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entry:\n"
+msgid_plural ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entries:\n"
+msgstr[0] ""
+"\n"
+"シンボルテーブル [%2u] '%s' には %u 個の項目があります:\n"
+
+#: src/readelf.c:2347
+#, c-format
+msgid " %lu local symbol  String table: [%2u] '%s'\n"
+msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
+msgstr[0] " %lu ローカルシンボル文字列テーブル: [%2u] '%s'\n"
+
+#: src/readelf.c:2355
+msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr "  数 :    値      大き タイプ  Bind   Vis          Ndx 名前\n"
+
+#: src/readelf.c:2357
+msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr "  数 :            値      大き タイプ  Bind   Vis          Ndx 名前\n"
+
+#: src/readelf.c:2377
+#, c-format
+msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+msgstr "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+
+#: src/readelf.c:2465
+#, c-format
+msgid "bad dynamic symbol"
+msgstr "不正な動的シンボル"
+
+#: src/readelf.c:2547
+msgid "none"
+msgstr "なし"
+
+#: src/readelf.c:2564
+msgid "| <unknown>"
+msgstr "| <不明>"
+
+#: src/readelf.c:2595
+#, c-format
+msgid ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"セクション [%2u] '%s' を必要とするバージョンには %d 個の項目があります:\n"
+" アドレス: %#0*<PRIx64>  オフセット: %#08<PRIx64>  セクションへのリンク: "
+"[%2u] '%s'\n"
+
+#: src/readelf.c:2616
+#, c-format
+msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
+msgstr "  %#06x: バージョン: %hu  ファイル: %s  数: %hu\n"
+
+#: src/readelf.c:2629
+#, c-format
+msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
+msgstr "  %#06x: 名前: %s  フラグ: %s  バージョン: %hu\n"
+
+#: src/readelf.c:2672
+#, c-format
+msgid ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"バージョン定義セクション [%2u] '%s' には %d 個の項目があります:\n"
+" アドレス: %#0*<PRIx64>  オフセット: %#08<PRIx64>  セクションへのリンク: "
+"[%2u] '%s'\n"
+
+#: src/readelf.c:2700
+#, c-format
+msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
+msgstr "  %#06x: バージョン: %hd  フラグ: %s  索引: %hd  数: %hd  名前: %s\n"
+
+#: src/readelf.c:2715
+#, c-format
+msgid "  %#06x: Parent %d: %s\n"
+msgstr "  %#06x: 親 %d: %s\n"
+
+#. Print the header.
+#: src/readelf.c:2976
+#, c-format
+msgid ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgid_plural ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgstr[0] ""
+"\n"
+"バージョンシンボルセクション [%2u] '%s' には %d 個の項目があります:\n"
+" アドレス: %#0*<PRIx64>  オフセット: %#08<PRIx64>  セクションへのリンク: "
+"[%2u] '%s'"
+
+#: src/readelf.c:3004
+msgid "   0 *local*                     "
+msgstr "   0 *ローカル*                  "
+
+#: src/readelf.c:3009
+msgid "   1 *global*                    "
+msgstr "   1 *グローバル*                "
+
+#: src/readelf.c:3051
+#, c-format
+msgid ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"bucket):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"buckets):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"セクション [%2u] '%s' のバケット一覧の長さの柱状図(合計 %d バケット):\n"
+" アドレス: %#0*<PRIx64>  オフセット: %#08<PRIx64>  セクションへのリンク: "
+"[%2u] '%s'\n"
+
+#: src/readelf.c:3073
+#, fuzzy, no-c-format
+msgid " Length  Number  % of total  Coverage\n"
+msgstr " 長さ    数      全体の%     範囲    \n"
+
+#: src/readelf.c:3075
+#, c-format
+msgid "      0  %6<PRIu32>      %5.1f%%\n"
+msgstr "      0  %6<PRIu32>      %5.1f%%\n"
+
+#: src/readelf.c:3082
+#, c-format
+msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+msgstr "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+
+#: src/readelf.c:3095
+#, fuzzy, c-format
+msgid ""
+" Average number of tests:   successful lookup: %f\n"
+"\t\t\t  unsuccessful lookup: %f\n"
+msgstr ""
+" テストの平均数: 検索成功: %f\n"
+"                 検索失敗: %f\n"
+
+#: src/readelf.c:3113 src/readelf.c:3168 src/readelf.c:3225
+#, c-format
+msgid "cannot get data for section %d: %s"
+msgstr "セクションからデータを得られません %d: %s"
+
+#: src/readelf.c:3121
+#, fuzzy, c-format
+msgid "invalid data in sysv.hash section %d"
+msgstr "セクション [%zu] '%s' の不当なデータ"
+
+#: src/readelf.c:3176
+#, fuzzy, c-format
+msgid "invalid data in sysv.hash64 section %d"
+msgstr "セクション [%zu] '%s' の不当なデータ"
+
+#: src/readelf.c:3234
+#, fuzzy, c-format
+msgid "invalid data in gnu.hash section %d"
+msgstr "セクション [%zu] '%s' の不当なデータ"
+
+#: src/readelf.c:3301
+#, c-format
+msgid ""
+" Symbol Bias: %u\n"
+" Bitmask Size: %zu bytes  %<PRIuFAST32>%% bits set  2nd hash shift: %u\n"
+msgstr ""
+" シンボルの偏り: %u\n"
+" ビットマスクの大きさ: %zu バイト  %<PRIuFAST32>%% ビット設定 第2ハッシュシフ"
+"ト: %u\n"
+
+#: src/readelf.c:3390
+#, c-format
+msgid ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"オフセット %3$#0<PRIx64> のライブラリー一覧セクション [%1$2zu] '%2$s' には "
+"%4$d 個の項目があります:\n"
+
+#: src/readelf.c:3404
+msgid ""
+"       Library                       Time Stamp          Checksum Version "
+"Flags"
+msgstr ""
+"       ライブラリー                  タイムスタンプ      チェックサム バー"
+"ジョン フラグ"
+
+#: src/readelf.c:3454
+#, c-format
+msgid ""
+"\n"
+"Object attributes section [%2zu] '%s' of %<PRIu64> bytes at offset "
+"%#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"オフセット %4$#0<PRIx64> の %3$<PRIu64> バイトのオブジェクト属性セクション "
+"[%1$2zu] '%2$s':\n"
+
+#: src/readelf.c:3471
+msgid "  Owner          Size\n"
+msgstr "  所有者         大きさ\n"
+
+#: src/readelf.c:3500
+#, c-format
+msgid "  %-13s  %4<PRIu32>\n"
+msgstr "  %-13s  %4<PRIu32>\n"
+
+#. Unknown subsection, print and skip.
+#: src/readelf.c:3539
+#, c-format
+msgid "    %-4u %12<PRIu32>\n"
+msgstr "    %-4u %12<PRIu32>\n"
+
+#. Tag_File
+#: src/readelf.c:3544
+#, c-format
+msgid "    File: %11<PRIu32>\n"
+msgstr "    ファイル: %11<PRIu32>\n"
+
+#: src/readelf.c:3593
+#, c-format
+msgid "      %s: %<PRId64>, %s\n"
+msgstr "      %s: %<PRId64>、%s\n"
+
+#: src/readelf.c:3596
+#, c-format
+msgid "      %s: %<PRId64>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:3599
+#, c-format
+msgid "      %s: %s\n"
+msgstr "      %s: %s\n"
+
+#: src/readelf.c:3609
+#, c-format
+msgid "      %u: %<PRId64>\n"
+msgstr "      %u: %<PRId64>\n"
+
+#: src/readelf.c:3612
+#, c-format
+msgid "      %u: %s\n"
+msgstr "      %u: %s\n"
+
+#: src/readelf.c:3657
+#, c-format
+msgid "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3660
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3665
+#, c-format
+msgid "%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%#<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3668
+#, c-format
+msgid "%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%#0*<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3674
+#, c-format
+msgid "%s+%#<PRIx64> <%s>"
+msgstr "%s+%#<PRIx64> <%s>"
+
+#: src/readelf.c:3677
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s>"
+msgstr "%s+%#0*<PRIx64> <%s>"
+
+#: src/readelf.c:3681
+#, c-format
+msgid "%#<PRIx64> <%s>"
+msgstr "%#<PRIx64> <%s>"
+
+#: src/readelf.c:3684
+#, c-format
+msgid "%#0*<PRIx64> <%s>"
+msgstr "%#0*<PRIx64> <%s>"
+
+#: src/readelf.c:3689
+#, c-format
+msgid "%s+%#<PRIx64>"
+msgstr "%s+%#<PRIx64>"
+
+#: src/readelf.c:3692
+#, c-format
+msgid "%s+%#0*<PRIx64>"
+msgstr "%s+%#0*<PRIx64>"
+
+#: src/readelf.c:4095
+msgid "empty block"
+msgstr "空ブロック"
+
+#: src/readelf.c:4098
+#, c-format
+msgid "%zu byte block:"
+msgstr "%zu バイトのブロック:"
+
+#: src/readelf.c:4495
+#, c-format
+msgid "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+msgstr "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+
+#: src/readelf.c:4552
+#, c-format
+msgid "%s %#<PRIx64> used with different address sizes"
+msgstr ""
+
+#: src/readelf.c:4559
+#, c-format
+msgid "%s %#<PRIx64> used with different offset sizes"
+msgstr ""
+
+#: src/readelf.c:4566
+#, c-format
+msgid "%s %#<PRIx64> used with different base addresses"
+msgstr ""
+
+#: src/readelf.c:4655
+#, c-format
+msgid " [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"
+msgstr ""
+
+#: src/readelf.c:4663
+#, c-format
+msgid " [%6tx]  <UNUSED GARBAGE> ... %<PRIu64> bytes ...\n"
+msgstr ""
+
+#: src/readelf.c:4689
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [ Code]\n"
+msgstr ""
+"\n"
+"オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s':\n"
+" [ コード]\n"
+
+#: src/readelf.c:4697
+#, c-format
+msgid ""
+"\n"
+"Abbreviation section at offset %<PRIu64>:\n"
+msgstr ""
+"\n"
+"オフセット %<PRIu64> の略語セクション:\n"
+
+#: src/readelf.c:4710
+#, c-format
+msgid " *** error while reading abbreviation: %s\n"
+msgstr " *** 略語を読んでいる間にエラー: %s\n"
+
+#: src/readelf.c:4726
+#, c-format
+msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
+msgstr " [%5u] オフセット: %<PRId64>、子: %s、タグ: %s\n"
+
+#: src/readelf.c:4729 src/readelf.c:6178 src/readelf.c:6186 src/readelf.c:7759
+msgid "yes"
+msgstr "はい"
+
+#: src/readelf.c:4729 src/readelf.c:6178 src/readelf.c:7759
+msgid "no"
+msgstr "いいえ"
+
+#: src/readelf.c:4763 src/readelf.c:4836
+#, c-format
+msgid "cannot get .debug_aranges content: %s"
+msgstr ".debug_aragnes の内容を得られません: %s"
+
+#: src/readelf.c:4778
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s' には %4$zu 個の項"
+"目があります:\n"
+
+#: src/readelf.c:4809
+#, c-format
+msgid " [%*zu] ???\n"
+msgstr " [%*zu] ???\n"
+
+#: src/readelf.c:4811
+#, c-format
+msgid ""
+" [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
+msgstr ""
+" [%*zu] 開始: %0#*<PRIx64>、長さ: %5<PRIu64>、CU DIE オフセット: %6<PRId64>\n"
+
+#: src/readelf.c:4841 src/readelf.c:4995 src/readelf.c:5572 src/readelf.c:6529
+#: src/readelf.c:7061 src/readelf.c:7181 src/readelf.c:7345 src/readelf.c:7833
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+"\n"
+"オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s':\n"
+
+#: src/readelf.c:4854 src/readelf.c:6555
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Table at offset %zu:\n"
+msgstr ""
+"\n"
+"オフセット %Zu のテーブル:\n"
+
+#: src/readelf.c:4858 src/readelf.c:5596 src/readelf.c:6566
+#, c-format
+msgid "invalid data in section [%zu] '%s'"
+msgstr "セクション [%zu] '%s' の不当なデータ"
+
+#: src/readelf.c:4874
+#, fuzzy, c-format
+msgid ""
+"\n"
+" Length:        %6<PRIu64>\n"
+msgstr " (オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:4886
+#, fuzzy, c-format
+msgid " DWARF version: %6<PRIuFAST16>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:4890
+#, c-format
+msgid "unsupported aranges version"
+msgstr ""
+
+#: src/readelf.c:4901
+#, fuzzy, c-format
+msgid " CU offset:     %6<PRIx64>\n"
+msgstr " (オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:4907
+#, fuzzy, c-format
+msgid " Address size:  %6<PRIu64>\n"
+msgstr " (終了オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:4911
+#, fuzzy, c-format
+msgid "unsupported address size"
+msgstr "アドレス値ではありません"
+
+#: src/readelf.c:4916
+#, fuzzy, c-format
+msgid ""
+" Segment size:  %6<PRIu64>\n"
+"\n"
+msgstr " ファイルを %<PRIu64> に設定する\n"
+
+#: src/readelf.c:4920
+#, c-format
+msgid "unsupported segment size"
+msgstr ""
+
+#: src/readelf.c:4960
+#, fuzzy, c-format
+msgid "   %s..%s (%<PRIx64>)\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:4963
+#, fuzzy, c-format
+msgid "   %s..%s\n"
+msgstr " [%6tx]  %s..%s\n"
+
+#: src/readelf.c:4972
+#, c-format
+msgid "   %zu padding bytes\n"
+msgstr ""
+
+#: src/readelf.c:4990
+#, c-format
+msgid "cannot get .debug_ranges content: %s"
+msgstr ".degub_ranges の内容を得られません: %s"
+
+#: src/readelf.c:5020 src/readelf.c:7088
+#, c-format
+msgid " [%6tx]  <INVALID DATA>\n"
+msgstr " [%6tx]  <不当なデータ>\n"
+
+#: src/readelf.c:5042 src/readelf.c:7110
+#, c-format
+msgid " [%6tx]  base address %s\n"
+msgstr " [%6tx]  ベースアドレス %s\n"
+
+#: src/readelf.c:5049 src/readelf.c:7117
+#, fuzzy, c-format
+msgid " [%6tx]  empty list\n"
+msgstr ""
+"\n"
+" [%6tx] ゼロ終端\n"
+
+#. We have an address range entry.
+#. First address range entry in a list.
+#: src/readelf.c:5060
+#, c-format
+msgid " [%6tx]  %s..%s\n"
+msgstr " [%6tx]  %s..%s\n"
+
+#: src/readelf.c:5062
+#, c-format
+msgid "           %s..%s\n"
+msgstr "           %s..%s\n"
+
+#: src/readelf.c:5298
+#, fuzzy
+msgid "         <INVALID DATA>\n"
+msgstr " [%6tx]  <不当なデータ>\n"
+
+#: src/readelf.c:5551
+#, fuzzy, c-format
+msgid "cannot get ELF: %s"
+msgstr "次の DIE を得られません: %s"
+
+#: src/readelf.c:5568
+#, c-format
+msgid ""
+"\n"
+"Call frame information section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+"\n"
+"オフセット %3$#<PRIx64> の フレーム情報呼出しセクション [%1$2zu] '%2$s':\n"
+
+#: src/readelf.c:5618
+#, c-format
+msgid ""
+"\n"
+" [%6tx] Zero terminator\n"
+msgstr ""
+"\n"
+" [%6tx] ゼロ終端\n"
+
+#: src/readelf.c:5711 src/readelf.c:5866
+#, fuzzy, c-format
+msgid "invalid augmentation length"
+msgstr "不当な拡大エンコード"
+
+#: src/readelf.c:5726
+msgid "FDE address encoding: "
+msgstr "FDE アドレスエンコード"
+
+#: src/readelf.c:5732
+msgid "LSDA pointer encoding: "
+msgstr "LSDA ポインターエンコード:"
+
+#: src/readelf.c:5843
+#, c-format
+msgid " (offset: %#<PRIx64>)"
+msgstr " (オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:5850
+#, c-format
+msgid " (end offset: %#<PRIx64>)"
+msgstr " (終了オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:5887
+#, c-format
+msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
+msgstr "   %-26sLSDA ポインター: %#<PRIx64>\n"
+
+#: src/readelf.c:5942
+#, c-format
+msgid "cannot get attribute code: %s"
+msgstr "属性コードを得られません: %s"
+
+#: src/readelf.c:5951
+#, c-format
+msgid "cannot get attribute form: %s"
+msgstr "属性様式を得られません: %s"
+
+#: src/readelf.c:5966
+#, c-format
+msgid "cannot get attribute value: %s"
+msgstr "属性値を得られません: %s"
+
+#: src/readelf.c:6268
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [Offset]\n"
+msgstr ""
+"\n"
+"オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s':\n"
+" [オフセット]\n"
+
+#: src/readelf.c:6300
+#, fuzzy, c-format
+msgid ""
+" Type unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: "
+"%<PRIu8>, Offset size: %<PRIu8>\n"
+" Type signature: %#<PRIx64>, Type offset: %#<PRIx64>\n"
+msgstr ""
+" オフセット %1$<PRIu64> のコンパイル単位:\n"
+" バージョン: %2$<PRIu16>、略語セクションオフセット: %3$<PRIu64>、アドレスの大"
+"きさ: %4$<PRIu8>、オフセットの大きさ: %5$<PRIu8>\n"
+
+#: src/readelf.c:6309
+#, c-format
+msgid ""
+" Compilation unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: "
+"%<PRIu8>, Offset size: %<PRIu8>\n"
+msgstr ""
+" オフセット %1$<PRIu64> のコンパイル単位:\n"
+" バージョン: %2$<PRIu16>、略語セクションオフセット: %3$<PRIu64>、アドレスの大"
+"きさ: %4$<PRIu8>、オフセットの大きさ: %5$<PRIu8>\n"
+
+#: src/readelf.c:6334
+#, c-format
+msgid "cannot get DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+"セクション '%2$s' の オフセット %1$<PRIu64> の DIE を得られません: %3$s"
+
+#: src/readelf.c:6348
+#, c-format
+msgid "cannot get DIE offset: %s"
+msgstr "DIE オフセットを得られません: %s"
+
+#: src/readelf.c:6357
+#, c-format
+msgid "cannot get tag of DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+"セクション '%2$s' 中のオフセット %1$<PRIu64> の DIE のタグを得られません: "
+"%3$s"
+
+#: src/readelf.c:6389
+#, c-format
+msgid "cannot get next DIE: %s\n"
+msgstr "次の DIE を得られません: %s\n"
+
+#: src/readelf.c:6397
+#, c-format
+msgid "cannot get next DIE: %s"
+msgstr "次の DIE を得られません: %s"
+
+#: src/readelf.c:6433
+#, fuzzy, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+"\n"
+"オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s':\n"
+
+#: src/readelf.c:6542
+#, c-format
+msgid "cannot get line data section data: %s"
+msgstr "ラインデータセクションデータを得られません: %s"
+
+#. Print what we got so far.
+#: src/readelf.c:6612
+#, fuzzy, c-format
+msgid ""
+"\n"
+" Length:                     %<PRIu64>\n"
+" DWARF version:              %<PRIuFAST16>\n"
+" Prologue length:            %<PRIu64>\n"
+" Minimum instruction length: %<PRIuFAST8>\n"
+" Maximum operations per instruction: %<PRIuFAST8>\n"
+" Initial value if '%s': %<PRIuFAST8>\n"
+" Line base:                  %<PRIdFAST8>\n"
+" Line range:                 %<PRIuFAST8>\n"
+" Opcode base:                %<PRIuFAST8>\n"
+"\n"
+"Opcodes:\n"
+msgstr ""
+"\n"
+" 長さ:             %<PRIu64>\n"
+" DWARF バージョン: %<PRIuFAST16>\n"
+" プロローグ長:     %<PRIu64>\n"
+" 最小命令長:       %<PRIuFAST8>\n"
+" もし '%s' なら初期値: %<PRIuFAST8>\n"
+" 行ベース:         %<PRIdFAST8>\n"
+" 行範囲:           %<PRIuFAST8>\n"
+" 命令コードベース: %<PRIuFAST8>\n"
+"\n"
+"命令コード:\n"
+
+#: src/readelf.c:6633
+#, c-format
+msgid "invalid data at offset %tu in section [%zu] '%s'"
+msgstr "セクション [%2$zu] '%3$s' 中のオフセット %1$tu に不当なデータ"
+
+#: src/readelf.c:6648
+#, c-format
+msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
+msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
+msgstr[0] "  [%*<PRIuFAST8>]  %hhu パラメーター\n"
+
+#: src/readelf.c:6656
+msgid ""
+"\n"
+"Directory table:"
+msgstr ""
+"\n"
+"ディレクトリーテーブル:"
+
+#: src/readelf.c:6672
+msgid ""
+"\n"
+"File name table:\n"
+" Entry Dir   Time      Size      Name"
+msgstr ""
+"\n"
+"ファイル名テーブル:\n"
+" Entry Dir   時刻     大きさ    名前"
+
+#: src/readelf.c:6707
+msgid ""
+"\n"
+"Line number statements:"
+msgstr ""
+"\n"
+"行   番号   文:"
+
+#: src/readelf.c:6758
+#, c-format
+msgid "invalid maximum operations per instruction is zero"
+msgstr ""
+
+#: src/readelf.c:6794
+#, fuzzy, c-format
+msgid " special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"
+msgstr " 特殊命令コード %u: アドレス+%u = %s, 行%+d = %zu\n"
+
+#: src/readelf.c:6799
+#, c-format
+msgid " special opcode %u: address+%u = %s, line%+d = %zu\n"
+msgstr " 特殊命令コード %u: アドレス+%u = %s, 行%+d = %zu\n"
+
+#: src/readelf.c:6819
+#, c-format
+msgid " extended opcode %u: "
+msgstr " 拡張命令コード %u: "
+
+#: src/readelf.c:6824
+#, fuzzy
+msgid " end of sequence"
+msgstr "列の終わり"
+
+#: src/readelf.c:6843
+#, fuzzy, c-format
+msgid " set address to %s\n"
+msgstr "アドレスを %s に設定する\n"
+
+#: src/readelf.c:6870
+#, fuzzy, c-format
+msgid " define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
+msgstr ""
+"新ファイルを定義する: dir=%u、mtime=%<PRIu64>、長さh=%<PRIu64>、名前=%s\n"
+
+#: src/readelf.c:6883
+#, fuzzy, c-format
+msgid " set discriminator to %u\n"
+msgstr "カラムを %<PRIu64> に設定する\n"
+
+#. Unknown, ignore it.
+#: src/readelf.c:6888
+#, fuzzy
+msgid " unknown opcode"
+msgstr "不明な命令コード"
+
+#. Takes no argument.
+#: src/readelf.c:6900
+msgid " copy"
+msgstr "複写"
+
+#: src/readelf.c:6911
+#, fuzzy, c-format
+msgid " advance address by %u to %s, op_index to %u\n"
+msgstr "アドレスを %u だけ進めて %s にする\n"
+
+#: src/readelf.c:6915
+#, fuzzy, c-format
+msgid " advance address by %u to %s\n"
+msgstr "アドレスを %u だけ進めて %s にする\n"
+
+#: src/readelf.c:6926
+#, c-format
+msgid " advance line by constant %d to %<PRId64>\n"
+msgstr "行を定数 %d だけ進めて %<PRId64> にする\n"
+
+#: src/readelf.c:6934
+#, c-format
+msgid " set file to %<PRIu64>\n"
+msgstr " ファイルを %<PRIu64> に設定する\n"
+
+#: src/readelf.c:6944
+#, c-format
+msgid " set column to %<PRIu64>\n"
+msgstr "カラムを %<PRIu64> に設定する\n"
+
+#: src/readelf.c:6951
+#, c-format
+msgid " set '%s' to %<PRIuFAST8>\n"
+msgstr " '%s' を %<PRIuFAST8> に設定する\n"
+
+#. Takes no argument.
+#: src/readelf.c:6957
+msgid " set basic block flag"
+msgstr "基本ブロックフラグを設定する"
+
+#: src/readelf.c:6970
+#, fuzzy, c-format
+msgid " advance address by constant %u to %s, op_index to %u\n"
+msgstr "アドレスを定数 %u だけ済めて %s にする\n"
+
+#: src/readelf.c:6974
+#, fuzzy, c-format
+msgid " advance address by constant %u to %s\n"
+msgstr "アドレスを定数 %u だけ済めて %s にする\n"
+
+#: src/readelf.c:6992
+#, fuzzy, c-format
+msgid " advance address by fixed value %u to %s\n"
+msgstr "アドレスを固定値 %u だけ進めて %s にする\n"
+
+#. Takes no argument.
+#: src/readelf.c:7001
+msgid " set prologue end flag"
+msgstr "プロローグ終了フラグを設定する"
+
+#. Takes no argument.
+#: src/readelf.c:7006
+msgid " set epilogue begin flag"
+msgstr "エピローグ開始フラグを設定する"
+
+#: src/readelf.c:7015
+#, fuzzy, c-format
+msgid " set isa to %u\n"
+msgstr " ファイルを %<PRIu64> に設定する\n"
+
+#. This is a new opcode the generator but not we know about.
+#. Read the parameters associated with it but then discard
+#. everything.  Read all the parameters for this opcode.
+#: src/readelf.c:7024
+#, c-format
+msgid " unknown opcode with %<PRIu8> parameter:"
+msgid_plural " unknown opcode with %<PRIu8> parameters:"
+msgstr[0] " %<PRIu8> 個のパラメーターのある不明な命令コード:"
+
+#: src/readelf.c:7056
+#, c-format
+msgid "cannot get .debug_loc content: %s"
+msgstr ".debug_loc の内容を得られません: %s"
+
+#. First entry in a list.
+#: src/readelf.c:7131
+#, c-format
+msgid " [%6tx]  %s..%s"
+msgstr " [%6tx]  %s..%s"
+
+#: src/readelf.c:7133
+#, c-format
+msgid "           %s..%s"
+msgstr "           %s..%s"
+
+#: src/readelf.c:7140 src/readelf.c:8091
+#, fuzzy
+msgid "   <INVALID DATA>\n"
+msgstr " [%6tx]  <不当なデータ>\n"
+
+#: src/readelf.c:7192 src/readelf.c:7354
+#, c-format
+msgid "cannot get macro information section data: %s"
+msgstr "マクロ情報セクションのデータを得られません: %s"
+
+#: src/readelf.c:7272
+#, c-format
+msgid "%*s*** non-terminated string at end of section"
+msgstr "%*s*** 最後のセクションの終端していない文字列"
+
+#: src/readelf.c:7295
+#, fuzzy, c-format
+msgid "%*s*** missing DW_MACINFO_start_file argument at end of section"
+msgstr "%*s*** 最後のセクションの終端していない文字列"
+
+#: src/readelf.c:7395
+#, fuzzy, c-format
+msgid " Offset:             0x%<PRIx64>\n"
+msgstr "  所有者         大きさ\n"
+
+#: src/readelf.c:7407
+#, fuzzy, c-format
+msgid " Version:            %<PRIu16>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:7413 src/readelf.c:8210
+#, c-format
+msgid "  unknown version, cannot parse section\n"
+msgstr ""
+
+#: src/readelf.c:7420
+#, fuzzy, c-format
+msgid " Flag:               0x%<PRIx8>\n"
+msgstr "  入口点アドレス     :               %#<PRIx64>\n"
+
+#: src/readelf.c:7423
+#, fuzzy, c-format
+msgid " Offset length:      %<PRIu8>\n"
+msgstr " (オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:7431
+#, fuzzy, c-format
+msgid " .debug_line offset: 0x%<PRIx64>\n"
+msgstr " (終了オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:7444
+#, fuzzy, c-format
+msgid "  extension opcode table, %<PRIu8> items:\n"
+msgstr " %<PRIu8> 個のパラメーターのある不明な命令コード:"
+
+#: src/readelf.c:7451
+#, c-format
+msgid "    [%<PRIx8>]"
+msgstr ""
+
+#: src/readelf.c:7463
+#, fuzzy, c-format
+msgid " %<PRIu8> arguments:"
+msgstr "  [%*<PRIuFAST8>]  %hhu パラメーター\n"
+
+#: src/readelf.c:7491
+#, c-format
+msgid " no arguments."
+msgstr ""
+
+#: src/readelf.c:7791
+#, c-format
+msgid "vendor opcode not verified?"
+msgstr ""
+
+#: src/readelf.c:7819
+#, c-format
+msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
+msgstr ""
+" [%5d] DIE オフセット: %6<PRId64>, CU DIE オフセット: %6<PRId64>, 名前: %s\n"
+
+# # "オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s':\n"
+# # " %4$*s  文字列\n" がエラーになるのは何故? 取り敢えず fuzzy扱い
+#: src/readelf.c:7860
+#, fuzzy, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" %*s  String\n"
+msgstr ""
+"\n"
+"オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s':\n"
+" %4$*s  文字列\n"
+
+#: src/readelf.c:7874
+#, c-format
+msgid " *** error while reading strings: %s\n"
+msgstr " *** 文字列の読込み中にエラー: %s\n"
+
+#: src/readelf.c:7894
+#, c-format
+msgid ""
+"\n"
+"Call frame search table section [%2zu] '.eh_frame_hdr':\n"
+msgstr ""
+"\n"
+"呼出しフレーム検索テーブルセクション [%2zu] '.eh_frame_hdr':\n"
+
+#: src/readelf.c:7996
+#, c-format
+msgid ""
+"\n"
+"Exception handling table section [%2zu] '.gcc_except_table':\n"
+msgstr ""
+"\n"
+"例外取扱いテーブルセクション [%2zu] '.gcc_except_table':\n"
+
+#: src/readelf.c:8019
+#, c-format
+msgid " LPStart encoding:    %#x "
+msgstr " LPStart コード化:    %#x "
+
+#: src/readelf.c:8031
+#, c-format
+msgid " TType encoding:      %#x "
+msgstr "TType コード化:       %#x "
+
+#: src/readelf.c:8046
+#, c-format
+msgid " Call site encoding:  %#x "
+msgstr "呼出しサイトコード化: %#x "
+
+#: src/readelf.c:8059
+msgid ""
+"\n"
+" Call site table:"
+msgstr ""
+"\n"
+" 呼出しサイトテーブル:"
+
+#: src/readelf.c:8073
+#, c-format
+msgid ""
+" [%4u] Call site start:   %#<PRIx64>\n"
+"        Call site length:  %<PRIu64>\n"
+"        Landing pad:       %#<PRIx64>\n"
+"        Action:            %u\n"
+msgstr ""
+" [%4u] 呼出しサイト開始 :  %#<PRIx64>\n"
+"        呼出しサイト長:     %<PRIu64>\n"
+"        離着陸場:           %#<PRIx64>\n"
+"        行動:               %u\n"
+
+#: src/readelf.c:8146
+#, c-format
+msgid "invalid TType encoding"
+msgstr "不当な TType コード化"
+
+#: src/readelf.c:8172
+#, fuzzy, c-format
+msgid ""
+"\n"
+"GDB section [%2zu] '%s' at offset %#<PRIx64> contains %<PRId64> bytes :\n"
+msgstr ""
+"\n"
+"オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s' には %4$zu 個の項"
+"目があります:\n"
+
+#: src/readelf.c:8201
+#, fuzzy, c-format
+msgid " Version:         %<PRId32>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:8219
+#, fuzzy, c-format
+msgid " CU offset:       %#<PRIx32>\n"
+msgstr " (オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:8226
+#, fuzzy, c-format
+msgid " TU offset:       %#<PRIx32>\n"
+msgstr " (オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:8233
+#, fuzzy, c-format
+msgid " address offset:  %#<PRIx32>\n"
+msgstr " (終了オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:8240
+#, fuzzy, c-format
+msgid " symbol offset:   %#<PRIx32>\n"
+msgstr " (オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:8247
+#, fuzzy, c-format
+msgid " constant offset: %#<PRIx32>\n"
+msgstr " (終了オフセット: %#<PRIx64>)"
+
+#: src/readelf.c:8261
+#, fuzzy, c-format
+msgid ""
+"\n"
+" CU list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+"オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s' には %4$zu 個の項"
+"目があります:\n"
+
+#: src/readelf.c:8286
+#, fuzzy, c-format
+msgid ""
+"\n"
+" TU list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+"オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s' には %4$zu 個の項"
+"目があります:\n"
+
+#: src/readelf.c:8315
+#, fuzzy, c-format
+msgid ""
+"\n"
+" Address list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+"オフセット %3$#<PRIx64> の DWARF セクション [%1$2zu] '%2$s' には %4$zu 個の項"
+"目があります:\n"
+
+#: src/readelf.c:8348
+#, fuzzy, c-format
+msgid ""
+"\n"
+" Symbol table at offset %#<PRIx32> contains %zu slots:\n"
+msgstr ""
+"\n"
+"オフセット %#0<PRIx64> に不当なシンボルテーブル\n"
+
+#: src/readelf.c:8435
+#, c-format
+msgid "cannot get debug context descriptor: %s"
+msgstr "デバッグ内容記述子を得られません: %s"
+
+#: src/readelf.c:8591 src/readelf.c:9213 src/readelf.c:9324 src/readelf.c:9382
+#, c-format
+msgid "cannot convert core note data: %s"
+msgstr "コアノートデータの変換ができません: %s"
+
+#: src/readelf.c:8954
+#, c-format
+msgid ""
+"\n"
+"%*s... <repeats %u more times> ..."
+msgstr ""
+"\n"
+"%*s... < %u 回の繰返し> ..."
+
+#: src/readelf.c:9461
+msgid "  Owner          Data size  Type\n"
+msgstr "  所有者         データ大きさタイプ\n"
+
+#: src/readelf.c:9479
+#, c-format
+msgid "  %-13.*s  %9<PRId32>  %s\n"
+msgstr "  %-13.*s  %9<PRId32>  %s\n"
+
+#: src/readelf.c:9529
+#, c-format
+msgid "cannot get content of note section: %s"
+msgstr "ノートセクションの内容を得られません: %s"
+
+#: src/readelf.c:9556
+#, c-format
+msgid ""
+"\n"
+"Note section [%2zu] '%s' of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"オフセット %4$#0<PRIx64> の %3$<PRIu64> バイトのノートセクション [%1$2zu] "
+"'%2$s':\n"
+
+#: src/readelf.c:9579
+#, c-format
+msgid ""
+"\n"
+"Note segment of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"オフセット %2$#0<PRIx64> の %1$<PRIu64> バイトのノートセグメント:\n"
+
+#: src/readelf.c:9625
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Section [%zu] '%s' has no data to dump.\n"
+msgstr ""
+"\n"
+"セクション [%Zu] '%s' にはダンプすべきデータがありません。\n"
+
+#: src/readelf.c:9652 src/readelf.c:9703
+#, fuzzy, c-format
+msgid "cannot get data for section [%zu] '%s': %s"
+msgstr "セクション [%Zu] '%s' からデータが得られません: %s"
+
+#: src/readelf.c:9657
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Hex dump of section [%zu] '%s', %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"オフセット %4$#0<PRIx64> のセクション [%1$Zu] '%2$s' の16進ダン"
+"プ、%3$<PRIu64> バイト:\n"
+
+#: src/readelf.c:9662
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Hex dump of section [%zu] '%s', %<PRIu64> bytes (%zd uncompressed) at offset "
+"%#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"オフセット %4$#0<PRIx64> のセクション [%1$Zu] '%2$s' の16進ダン"
+"プ、%3$<PRIu64> バイト:\n"
+
+#: src/readelf.c:9676
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Section [%zu] '%s' has no strings to dump.\n"
+msgstr ""
+"\n"
+"セクション [%Zu] '%s' にはダンプすべきデータがありません。\n"
+
+#: src/readelf.c:9708
+#, fuzzy, c-format
+msgid ""
+"\n"
+"String section [%zu] '%s' contains %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"オフセット %4$#0<PRIx64> 文字列セクション [%1$Zu] '%2$s' には %3$<PRIu64> バ"
+"イトあります:\n"
+
+#: src/readelf.c:9713
+#, fuzzy, c-format
+msgid ""
+"\n"
+"String section [%zu] '%s' contains %<PRIu64> bytes (%zd uncompressed) at "
+"offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"オフセット %4$#0<PRIx64> 文字列セクション [%1$Zu] '%2$s' には %3$<PRIu64> バ"
+"イトあります:\n"
+
+#: src/readelf.c:9762
+#, c-format
+msgid ""
+"\n"
+"section [%lu] does not exist"
+msgstr ""
+"\n"
+"セクション [%lu] がありません"
+
+#: src/readelf.c:9791
+#, c-format
+msgid ""
+"\n"
+"section '%s' does not exist"
+msgstr ""
+"\n"
+"セクション '%s' がありません"
+
+#: src/readelf.c:9848
+#, c-format
+msgid "cannot get symbol index of archive '%s': %s"
+msgstr "アーカイブのシンボル索引 '%s' を得られません: %s"
+
+#: src/readelf.c:9851
+#, c-format
+msgid ""
+"\n"
+"Archive '%s' has no symbol index\n"
+msgstr ""
+"\n"
+"アーカイブ '%s' にはシンボル索引がありません\n"
+
+#: src/readelf.c:9855
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Index of archive '%s' has %zu entries:\n"
+msgstr ""
+"\n"
+"アーカイブ '%s' の索引には %Zu 項目あります:\n"
+
+#: src/readelf.c:9873
+#, fuzzy, c-format
+msgid "cannot extract member at offset %zu in '%s': %s"
+msgstr "'%2$s' の オフセット %1$Zu のメンバーを抽出できません: %3$s"
+
+#: src/readelf.c:9878
+#, c-format
+msgid "Archive member '%s' contains:\n"
+msgstr "アーカイブメンバー '%s' には以下があります:\n"
+
+#: src/size.c:57
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd' or `sysv'.  The default "
+"is `bsd'"
+msgstr ""
+"出力形式として FORMAT を使ってください。FORMAT は `bsd'か、`sysv' のどちらか"
+"です。省略値は `bsd'です"
+
+#: src/size.c:59
+msgid "Same as `--format=sysv'"
+msgstr "`--format=sysv' と同じ"
+
+#: src/size.c:60
+msgid "Same as `--format=bsd'"
+msgstr "`--format=bsd' と同じ"
+
+#: src/size.c:63
+msgid "Same as `--radix=10'"
+msgstr "`--radix=10' と同じ"
+
+#: src/size.c:64
+msgid "Same as `--radix=8'"
+msgstr "`--radix=8' と同じ"
+
+#: src/size.c:65
+msgid "Same as `--radix=16'"
+msgstr "`--radix=16' と同じ"
+
+#: src/size.c:67
+msgid "Similar to `--format=sysv' output but in one line"
+msgstr "`--format=sysv' の出力と似ていますが、1行です"
+
+#: src/size.c:71
+msgid "Print size and permission flags for loadable segments"
+msgstr "ロード可能セグメントのための印刷の大きさと許可フラグ"
+
+#: src/size.c:72
+msgid "Display the total sizes (bsd only)"
+msgstr "合計の大きさを表示 (bsd のみ)"
+
+#. Short description of program.
+#: src/size.c:77
+msgid "List section sizes of FILEs (a.out by default)."
+msgstr "ふぁいる のセクションの大きさの一覧 (省略値は a.out)"
+
+#: src/size.c:241
+#, c-format
+msgid "Invalid format: %s"
+msgstr "不当な形式: %s"
+
+#: src/size.c:252
+#, c-format
+msgid "Invalid radix: %s"
+msgstr "不当な基数: %s"
+
+#: src/size.c:311
+#, c-format
+msgid "%s: file format not recognized"
+msgstr "%s: ファイル形式を認識できません"
+
+#: src/size.c:417 src/size.c:550
+#, c-format
+msgid " (ex %s)"
+msgstr " (ex %s)"
+
+#: src/size.c:575
+msgid "(TOTALS)\n"
+msgstr "(合計)\n"
+
+#: src/stack.c:483
+#, c-format
+msgid "-p PID should be a positive process id."
+msgstr ""
+
+#: src/stack.c:489
+#, fuzzy, c-format
+msgid "Cannot open core file '%s'"
+msgstr "アーカイブ '%s' を開くことができません"
+
+#: src/stack.c:549
+#, c-format
+msgid "-n MAXFRAMES should be 0 or higher."
+msgstr ""
+
+#: src/stack.c:561
+#, c-format
+msgid "-e EXEC needs a core given by --core."
+msgstr ""
+
+#: src/stack.c:565
+#, c-format
+msgid "-1 needs a thread id given by -p."
+msgstr ""
+
+#: src/stack.c:569
+#, c-format
+msgid "One of -p PID or --core COREFILE should be given."
+msgstr ""
+
+#: src/stack.c:641
+#, fuzzy
+msgid "Show stack of process PID"
+msgstr "検索ツリーを生成できません"
+
+#: src/stack.c:643
+msgid "Show stack found in COREFILE"
+msgstr ""
+
+#: src/stack.c:644
+msgid "(optional) EXECUTABLE that produced COREFILE"
+msgstr ""
+
+#: src/stack.c:648
+#, fuzzy
+msgid "Output selection options:"
+msgstr "選択オプションを入力してください:"
+
+#: src/stack.c:650
+#, fuzzy
+msgid "Additionally show frame activation"
+msgstr "出力選択:"
+
+#: src/stack.c:652
+msgid "Additionally try to lookup DWARF debuginfo name for frame address"
+msgstr ""
+
+#: src/stack.c:655
+msgid ""
+"Additionally show inlined function frames using DWARF debuginfo if available "
+"(implies -d)"
+msgstr ""
+
+#: src/stack.c:657
+msgid "Additionally show module file information"
+msgstr ""
+
+#: src/stack.c:659
+#, fuzzy
+msgid "Additionally show source file information"
+msgstr "出力選択:"
+
+#: src/stack.c:661
+msgid ""
+"Show all additional information (activation, debugname, inlines, module and "
+"source)"
+msgstr ""
+
+#: src/stack.c:663
+msgid "Do not resolve address to function symbol name"
+msgstr ""
+
+#: src/stack.c:665
+msgid "Show raw function symbol names, do not try to demangle names"
+msgstr ""
+
+#: src/stack.c:667
+msgid "Show module build-id, load address and pc offset"
+msgstr ""
+
+#: src/stack.c:669
+msgid "Show the backtrace of only one thread"
+msgstr ""
+
+#: src/stack.c:671
+msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)"
+msgstr ""
+
+#: src/stack.c:673
+msgid "Show module memory map with build-id, elf and debug files detected"
+msgstr ""
+
+#: src/stack.c:681
+msgid ""
+"Print a stack for each thread in a process or core file.\n"
+"\n"
+"Program exits with return code 0 if all frames were shown without any "
+"errors.  If some frames were shown, but there were some non-fatal errors, "
+"possibly causing an incomplete backtrace, the program exits with return code "
+"1.  If no frames could be shown, or a fatal error occured the program exits "
+"with return code 2.  If the program was invoked with bad or missing "
+"arguments it will exit with return code 64."
+msgstr ""
+
+#: src/stack.c:756
+#, c-format
+msgid "Couldn't show any frames."
+msgstr ""
+
+#: src/strings.c:66
+msgid "Output Selection:"
+msgstr ""
+
+#: src/strings.c:67
+msgid "Scan entire file, not only loaded sections"
+msgstr ""
+
+#: src/strings.c:69
+msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed"
+msgstr ""
+
+#: src/strings.c:70
+msgid ""
+"Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, "
+"{B,L} = 32-bit"
+msgstr ""
+
+#: src/strings.c:74
+msgid "Print name of the file before each string."
+msgstr ""
+
+#: src/strings.c:76
+msgid "Print location of the string in base 8, 10, or 16 respectively."
+msgstr ""
+
+#: src/strings.c:77
+msgid "Alias for --radix=o"
+msgstr ""
+
+#. Short description of program.
+#: src/strings.c:84
+msgid "Print the strings of printable characters in files."
+msgstr ""
+
+#: src/strings.c:257 src/strings.c:292
+#, c-format
+msgid "invalid value '%s' for %s parameter"
+msgstr ""
+
+#: src/strings.c:303
+#, c-format
+msgid "invalid minimum length of matched string size"
+msgstr ""
+
+#: src/strings.c:586
+#, c-format
+msgid "lseek failed"
+msgstr ""
+
+#: src/strings.c:603 src/strings.c:667
+#, c-format
+msgid "re-mmap failed"
+msgstr ""
+
+#: src/strings.c:640
+#, c-format
+msgid "mprotect failed"
+msgstr ""
+
+#: src/strings.c:729
+#, c-format
+msgid "Skipping section %zd '%s' data outside file"
+msgstr ""
+
+#: src/strip.c:71
+msgid "Place stripped output into FILE"
+msgstr "はぎ取った出力を ふぁいる に置く"
+
+#: src/strip.c:72
+msgid "Extract the removed sections into FILE"
+msgstr "抽出した取り除いたセクションを ふぁいる に置く"
+
+#: src/strip.c:73
+msgid "Embed name FILE instead of -f argument"
+msgstr "-f パラメーターの代わりに 名前 ふぁいる を有効にする"
+
+#: src/strip.c:77
+msgid "Remove all debugging symbols"
+msgstr "デバッグ用のシンボルを全て取り除く"
+
+#: src/strip.c:81
+msgid "Remove section headers (not recommended)"
+msgstr ""
+
+#: src/strip.c:83
+msgid "Copy modified/access timestamps to the output"
+msgstr "修正/アクセスタイムスタンプを出力へ複写する"
+
+#: src/strip.c:85
+msgid ""
+"Resolve all trivial relocations between debug sections if the removed "
+"sections are placed in a debug file (only relevant for ET_REL files, "
+"operation is not reversable, needs -f)"
+msgstr ""
+
+#: src/strip.c:87
+msgid "Remove .comment section"
+msgstr ".comment セクションを取り除く"
+
+#: src/strip.c:88
+msgid ""
+"Remove the named section.  SECTION is an extended wildcard pattern.  May be "
+"given more than once.  Only non-allocated sections can be removed."
+msgstr ""
+
+#: src/strip.c:89
+msgid ""
+"Keep the named section.  SECTION is an extended wildcard pattern.  May be "
+"given more than once."
+msgstr ""
+
+#. Short description of program.
+#: src/strip.c:96
+msgid "Discard symbols from object files."
+msgstr "オブジェクトファイルからシンボルを破棄する"
+
+#: src/strip.c:242
+#, c-format
+msgid "--reloc-debug-sections used without -f"
+msgstr ""
+
+#: src/strip.c:256
+#, c-format
+msgid "Only one input file allowed together with '-o' and '-f'"
+msgstr "'-o' と '-f' と一緒の場合は入力ファイルは 1 つしか認められません"
+
+#: src/strip.c:279
+#, c-format
+msgid "-f option specified twice"
+msgstr "-f オプションが 2 回指定されています"
+
+#: src/strip.c:288
+#, c-format
+msgid "-F option specified twice"
+msgstr "-F オプションが 2 回指定されています"
+
+#: src/strip.c:347
+#, fuzzy, c-format
+msgid "cannot both keep and remove .comment section"
+msgstr ".comment セクションを取り除く"
+
+#: src/strip.c:372 src/strip.c:396
+#, c-format
+msgid "cannot stat input file '%s'"
+msgstr "入力ファイル '%s' を stat できません"
+
+#: src/strip.c:386
+#, c-format
+msgid "while opening '%s'"
+msgstr "'%s' を開いている間"
+
+#: src/strip.c:424
+#, c-format
+msgid "%s: cannot use -o or -f when stripping archive"
+msgstr "%s: アーカイブから抜き出している時は -o や -f は使えません"
+
+#. We would like to support ar archives, but currently it just
+#. doesn't work at all since we call elf_clone on the members
+#. which doesn't really support ar members.
+#. result = handle_ar (fd, elf, NULL, fname,
+#. preserve_dates ? tv : NULL);
+#.
+#: src/strip.c:436
+#, fuzzy, c-format
+msgid "%s: no support for stripping archive"
+msgstr "%s: アーカイブから抜き出している時は -o や -f は使えません"
+
+#: src/strip.c:535
+#, c-format
+msgid "cannot open EBL backend"
+msgstr "EBL バックエンドを開けません"
+
+#: src/strip.c:580
+#, fuzzy, c-format
+msgid "cannot get number of phdrs"
+msgstr "セクション数を決定できません: %s"
+
+#: src/strip.c:596 src/strip.c:620
+#, c-format
+msgid "cannot create new file '%s': %s"
+msgstr "新しいファイル '%s' を生成できません: %s"
+
+#: src/strip.c:686
+#, c-format
+msgid "illformed file '%s'"
+msgstr "不適格なファイル '%s'"
+
+#: src/strip.c:696
+#, fuzzy, c-format
+msgid "Cannot remove allocated section '%s'"
+msgstr "PLT セクションを割り当てられません: %s"
+
+#: src/strip.c:705
+#, fuzzy, c-format
+msgid "Cannot both keep and remove section '%s'"
+msgstr "0番目のセクションのヘッダーを得られません: %s"
+
+#: src/strip.c:1061 src/strip.c:1160
+#, c-format
+msgid "while generating output file: %s"
+msgstr "出力ファイルを生成している間: %s"
+
+#: src/strip.c:1126 src/strip.c:2208
+#, c-format
+msgid "%s: error while creating ELF header: %s"
+msgstr "%s: ELF ヘッダーを生成している間にエラー: %s"
+
+#: src/strip.c:1143
+#, c-format
+msgid "while preparing output for '%s'"
+msgstr "'%s' のための出力を準備している間"
+
+#: src/strip.c:1205 src/strip.c:1268
+#, c-format
+msgid "while create section header section: %s"
+msgstr "セクションヘッダーセクションを生成している間: %s"
+
+#: src/strip.c:1214
+#, c-format
+msgid "cannot allocate section data: %s"
+msgstr "セクションデータを割り当てられません: %s"
+
+#: src/strip.c:1280
+#, c-format
+msgid "while create section header string table: %s"
+msgstr "セクションヘッダー文字列テーブルを生成中: %s"
+
+#: src/strip.c:1287
+#, fuzzy, c-format
+msgid "no memory to create section header string table"
+msgstr "セクションヘッダー文字列テーブルを生成中: %s"
+
+#: src/strip.c:1497
+#, c-format
+msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]"
+msgstr ""
+
+#: src/strip.c:1994
+#, fuzzy, c-format
+msgid "bad relocation"
+msgstr "リロケーションを表示"
+
+#: src/strip.c:2119 src/strip.c:2232
+#, c-format
+msgid "while writing '%s': %s"
+msgstr "'%s' を書込み中: %s"
+
+#: src/strip.c:2130
+#, c-format
+msgid "while creating '%s'"
+msgstr "'%s' を生成中"
+
+#: src/strip.c:2153
+#, c-format
+msgid "while computing checksum for debug information"
+msgstr "デバッグ情報のチェックサムを計算中"
+
+#: src/strip.c:2217
+#, c-format
+msgid "%s: error while reading the file: %s"
+msgstr "%s: ファイルを読込み中にエラー: %s"
+
+#: src/strip.c:2257 src/strip.c:2277
+#, fuzzy, c-format
+msgid "while writing '%s'"
+msgstr "'%s' を書込み中: %s"
+
+#: src/strip.c:2314 src/strip.c:2321
+#, c-format
+msgid "error while finishing '%s': %s"
+msgstr "'%s' の終了中にエラー: %s"
+
+#: src/strip.c:2338 src/strip.c:2414
+#, c-format
+msgid "cannot set access and modification date of '%s'"
+msgstr "'%s' のアクセスと変更日付を設定できません"
+
+#: src/unstrip.c:70
+msgid "Match MODULE against file names, not module names"
+msgstr ""
+
+#: src/unstrip.c:71
+msgid "Silently skip unfindable files"
+msgstr ""
+
+#: src/unstrip.c:74
+msgid "Place output into FILE"
+msgstr ""
+
+#: src/unstrip.c:76
+msgid "Create multiple output files under DIRECTORY"
+msgstr ""
+
+#: src/unstrip.c:77
+msgid "Use module rather than file names"
+msgstr ""
+
+#: src/unstrip.c:79
+msgid "Create output for modules that have no separate debug information"
+msgstr ""
+
+#: src/unstrip.c:82
+msgid "Apply relocations to section contents in ET_REL files"
+msgstr ""
+
+#: src/unstrip.c:84
+msgid "Only list module and file names, build IDs"
+msgstr ""
+
+#: src/unstrip.c:86
+msgid "Force combining files even if some ELF headers don't seem to match"
+msgstr ""
+
+#: src/unstrip.c:130
+#, c-format
+msgid "-d option specified twice"
+msgstr ""
+
+#: src/unstrip.c:165
+#, c-format
+msgid "only one of -o or -d allowed"
+msgstr ""
+
+#: src/unstrip.c:174
+#, c-format
+msgid "-n cannot be used with explicit files or -o or -d"
+msgstr ""
+
+#: src/unstrip.c:189
+#, c-format
+msgid "output directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:198
+#, c-format
+msgid "exactly two file arguments are required"
+msgstr ""
+
+#: src/unstrip.c:204
+#, c-format
+msgid "-m, -a, -R, and -i options not allowed with explicit files"
+msgstr ""
+
+#: src/unstrip.c:217
+#, c-format
+msgid "-o or -d is required when using implicit files"
+msgstr ""
+
+#: src/unstrip.c:240
+#, c-format
+msgid "cannot create ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:245
+#, c-format
+msgid "cannot copy ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:249 src/unstrip.c:1933 src/unstrip.c:1976
+#, fuzzy, c-format
+msgid "cannot get number of program headers: %s"
+msgstr "セクション数を決定できません: %s"
+
+#: src/unstrip.c:254 src/unstrip.c:1937
+#, c-format
+msgid "cannot create program headers: %s"
+msgstr ""
+
+#: src/unstrip.c:260
+#, c-format
+msgid "cannot copy program header: %s"
+msgstr ""
+
+#: src/unstrip.c:270
+#, c-format
+msgid "cannot copy section header: %s"
+msgstr ""
+
+#: src/unstrip.c:273 src/unstrip.c:1568
+#, c-format
+msgid "cannot get section data: %s"
+msgstr ""
+
+#: src/unstrip.c:275 src/unstrip.c:1570
+#, c-format
+msgid "cannot copy section data: %s"
+msgstr ""
+
+#: src/unstrip.c:299
+#, c-format
+msgid "cannot create directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:371 src/unstrip.c:791 src/unstrip.c:1602
+#, c-format
+msgid "cannot get symbol table entry: %s"
+msgstr ""
+
+#: src/unstrip.c:387 src/unstrip.c:608 src/unstrip.c:629 src/unstrip.c:641
+#: src/unstrip.c:1623 src/unstrip.c:1799 src/unstrip.c:1823
+#, c-format
+msgid "cannot update symbol table: %s"
+msgstr ""
+
+#: src/unstrip.c:397
+#, c-format
+msgid "cannot update section header: %s"
+msgstr ""
+
+#: src/unstrip.c:436 src/unstrip.c:447
+#, c-format
+msgid "cannot update relocation: %s"
+msgstr ""
+
+#: src/unstrip.c:535
+#, c-format
+msgid "cannot get symbol version: %s"
+msgstr ""
+
+#: src/unstrip.c:548
+#, c-format
+msgid "unexpected section type in [%zu] with sh_link to symtab"
+msgstr ""
+
+#: src/unstrip.c:797
+#, fuzzy, c-format
+msgid "invalid string offset in symbol [%zu]"
+msgstr "シンボル %2$sの不正なオフセット %1$zu "
+
+#: src/unstrip.c:955 src/unstrip.c:1305
+#, fuzzy, c-format
+msgid "cannot read section [%zu] name: %s"
+msgstr "セクションデータを割り当てられません: %s"
+
+#: src/unstrip.c:996 src/unstrip.c:1015 src/unstrip.c:1053
+#, c-format
+msgid "cannot read '.gnu.prelink_undo' section: %s"
+msgstr ""
+
+#: src/unstrip.c:1033
+#, c-format
+msgid "overflow with shnum = %zu in '%s' section"
+msgstr ""
+
+#: src/unstrip.c:1044
+#, c-format
+msgid "invalid contents in '%s' section"
+msgstr ""
+
+#: src/unstrip.c:1099 src/unstrip.c:1427
+#, fuzzy, c-format
+msgid "cannot find matching section for [%zu] '%s'"
+msgstr "セクション [%zu] '%s' の不当なデータ"
+
+#: src/unstrip.c:1224 src/unstrip.c:1239 src/unstrip.c:1506 src/unstrip.c:1758
+#, c-format
+msgid "cannot add section name to string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1248
+#, c-format
+msgid "cannot update section header string table data: %s"
+msgstr ""
+
+#: src/unstrip.c:1276 src/unstrip.c:1280
+#, c-format
+msgid "cannot get section header string table section index: %s"
+msgstr ""
+
+#: src/unstrip.c:1284 src/unstrip.c:1288 src/unstrip.c:1521
+#, c-format
+msgid "cannot get section count: %s"
+msgstr ""
+
+#: src/unstrip.c:1291
+#, c-format
+msgid "more sections in stripped file than debug file -- arguments reversed?"
+msgstr ""
+
+#: src/unstrip.c:1350 src/unstrip.c:1442
+#, c-format
+msgid "cannot read section header string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1500
+#, c-format
+msgid "cannot add new section: %s"
+msgstr ""
+
+#: src/unstrip.c:1610
+#, fuzzy, c-format
+msgid "symbol [%zu] has invalid section index"
+msgstr "不当なセクション索引"
+
+#: src/unstrip.c:1894
+#, fuzzy, c-format
+msgid "cannot read section data: %s"
+msgstr "セクションデータを割り当てられません: %s"
+
+#: src/unstrip.c:1915
+#, c-format
+msgid "cannot get ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:1923
+#, c-format
+msgid "cannot update ELF header: %s"
+msgstr "ELF ヘッダーを更新できません: %s"
+
+#: src/unstrip.c:1947
+#, c-format
+msgid "cannot update program header: %s"
+msgstr ""
+
+#: src/unstrip.c:1952 src/unstrip.c:2034
+#, c-format
+msgid "cannot write output file: %s"
+msgstr ""
+
+#: src/unstrip.c:2003
+#, c-format
+msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:2006
+#, c-format
+msgid ""
+"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:2025 src/unstrip.c:2076 src/unstrip.c:2088 src/unstrip.c:2174
+#, c-format
+msgid "cannot create ELF descriptor: %s"
+msgstr ""
+
+#: src/unstrip.c:2067
+msgid "WARNING: "
+msgstr ""
+
+#: src/unstrip.c:2069
+msgid ", use --force"
+msgstr ""
+
+#: src/unstrip.c:2092
+msgid "ELF header identification (e_ident) different"
+msgstr ""
+
+#: src/unstrip.c:2095
+msgid "ELF header type (e_type) different"
+msgstr ""
+
+#: src/unstrip.c:2098
+msgid "ELF header machine type (e_machine) different"
+msgstr ""
+
+#: src/unstrip.c:2101
+msgid "stripped program header (e_phnum) smaller than unstripped"
+msgstr ""
+
+#: src/unstrip.c:2131
+#, c-format
+msgid "cannot find stripped file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2135
+#, c-format
+msgid "cannot open stripped file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2150
+#, c-format
+msgid "cannot find debug file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2154
+#, c-format
+msgid "cannot open debug file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2167
+#, c-format
+msgid "module '%s' file '%s' is not stripped"
+msgstr ""
+
+#: src/unstrip.c:2198
+#, c-format
+msgid "cannot cache section addresses for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2331
+#, c-format
+msgid "no matching modules found"
+msgstr ""
+
+#: src/unstrip.c:2340
+#, c-format
+msgid "matched more than one module"
+msgstr ""
+
+#: src/unstrip.c:2384
+msgid ""
+"STRIPPED-FILE DEBUG-FILE\n"
+"[MODULE...]"
+msgstr ""
+
+#: src/unstrip.c:2385
+msgid ""
+"Combine stripped files with separate symbols and debug information.\n"
+"\n"
+"The first form puts the result in DEBUG-FILE if -o was not given.\n"
+"\n"
+"MODULE arguments give file name patterns matching modules to process.\n"
+"With -f these match the file name of the main (stripped) file (slashes are "
+"never special), otherwise they match the simple module names.  With no "
+"arguments, process all modules found.\n"
+"\n"
+"Multiple modules are written to files under OUTPUT-DIRECTORY, creating "
+"subdirectories as needed.  With -m these files have simple module names, "
+"otherwise they have the name of the main file complete with directory "
+"underneath OUTPUT-DIRECTORY.\n"
+"\n"
+"With -n no files are written, but one line to standard output for each "
+"module:\n"
+"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n"
+"START and SIZE are hexadecimal giving the address bounds of the module.  "
+"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the "
+"hexadecimal may be followed by @0xADDR giving the address where the ID "
+"resides if that is known.  FILE is the file name found for the module, or - "
+"if none was found, or . if an ELF image is available but not from any named "
+"file.  DEBUGFILE is the separate debuginfo file name, or - if no debuginfo "
+"was found, or . if FILE contains the debug information."
+msgstr ""
+
+#: tests/backtrace.c:442
+msgid "Run executable"
+msgstr ""
+
+#: tests/dwflmodtest.c:213
+#, fuzzy
+msgid "Additionally show function names"
+msgstr "出力選択:"
+
+#: tests/dwflmodtest.c:214
+msgid "Show instances of inlined functions"
+msgstr ""
+
+#~ msgid "-R option supports only .comment section"
+#~ msgstr "-R オプションは .comment セクションのみをサポートします"
+
+#~ msgid "Written by %s.\n"
+#~ msgstr "%s によって書かれました。\n"
+
+#~ msgid "cannot allocate PLTREL section: %s"
+#~ msgstr "PLTREL セクションを割り当てられません: %s"
+
+#~ msgid "cannot allocate GOT section: %s"
+#~ msgstr "GOT セクションを割り当てられません: %s"
+
+#~ msgid "cannot allocate GOTPLT section: %s"
+#~ msgstr "GOTPLT セクションを割り当てられません: %s"
+
+#~ msgid "initial-executable TLS relocation cannot be used "
+#~ msgstr "最初に実行される TLS リロケーションが使用されません "
+
+#~ msgid "Input File Control:"
+#~ msgstr "入力ファイル制御:"
+
+#~ msgid "Include whole archives in the output from now on."
+#~ msgstr "今から出力中の全アーカイブを含める。"
+
+#, fuzzy
+#~ msgid "Stop including the whole archives in the output."
+#~ msgstr "出力中の全アーカイブを含めるのを止める。"
+
+#~ msgid "FILE"
+#~ msgstr "ふぁいる"
+
+#~ msgid "Start a group."
+#~ msgstr "グループの開始。"
+
+#~ msgid "End a group."
+#~ msgstr "グループの終了。"
+
+#~ msgid "PATH"
+#~ msgstr "パス"
+
+#~ msgid "Add PATH to list of directories files are searched in."
+#~ msgstr "ファイルが検索されるディレクトリーの一覧にPATHを追加する。"
+
+#~ msgid "Only set DT_NEEDED for following dynamic libs if actually used"
+#~ msgstr ""
+#~ "実際に使用されるのなら以下のダイナミックライブラリーに DT_NEEDED を設定す"
+#~ "る"
+
+#~ msgid "Always set DT_NEEDED for following dynamic libs"
+#~ msgstr "以下のダイナミックライブラリーに常に DT_NEEDED を設定する"
+
+#~ msgid "Ignore LD_LIBRARY_PATH environment variable."
+#~ msgstr "LD_LIBRARY_PATH 環境変数を無視する。"
+
+#~ msgid "Output File Control:"
+#~ msgstr "出力ファイル制御:"
+
+#~ msgid "Place output in FILE."
+#~ msgstr "出力を ふぁいる に置く。"
+
+#~ msgid "Object is marked to not use default search path at runtime."
+#~ msgstr "オブジェクトは実行時に省略値の検索パスを使わないと記されています。"
+
+#~ msgid "Same as --whole-archive."
+#~ msgstr "--whole-archive と同じ。"
+
+#~ msgid ""
+#~ "Default rules of extracting from archive; weak references are not enough."
+#~ msgstr ""
+#~ "アーカイブから抽出する時の省略値の規則: 弱い参照では十分ではありません。"
+
+#~ msgid "Weak references cause extraction from archive."
+#~ msgstr "弱い参照はアーカイブから抽出します。"
+
+#~ msgid "Allow multiple definitions; first is used."
+#~ msgstr "複数の定義を認めます: 最初を使用します。"
+
+#~ msgid "Disallow/allow undefined symbols in DSOs."
+#~ msgstr "DSO 中の未定義のシンボルを認めない/認める。"
+
+#~ msgid "Object requires immediate handling of $ORIGIN."
+#~ msgstr "オブジェクトには %ORIGIN の直接ハンドルが必要です。"
+
+#~ msgid "Relocation will not be processed lazily."
+#~ msgstr "リロケーションは遅延処理されません。"
+
+#~ msgid "Object cannot be unloaded at runtime."
+#~ msgstr "オプションは実行時にはアンロードできません。"
+
+#~ msgid "Mark object to be initialized first."
+#~ msgstr "オブジェクトは最初に初期化されると記します。"
+
+#~ msgid "Enable/disable lazy-loading flag for following dependencies."
+#~ msgstr "以下の依存性のための遅延ロードを有効/無効にします。"
+
+#~ msgid "Mark object as not loadable with 'dlopen'."
+#~ msgstr "'dlopen' でロードできないと記します。"
+
+#~ msgid "Ignore/record dependencies on unused DSOs."
+#~ msgstr "使用されない DSO の依存性を無視/記録します。"
+
+#~ msgid "Generated DSO will be a system library."
+#~ msgstr "生成された DSO はシステムライブラリーになります。"
+
+#~ msgid "ADDRESS"
+#~ msgstr "アドレス"
+
+#~ msgid "Set entry point address."
+#~ msgstr "入口点アドレスを設定します。"
+
+#~ msgid "Do not link against shared libraries."
+#~ msgstr "共用ライブラリーに対してリンクを設定してはいけません。"
+
+#~ msgid "Prefer linking against shared libraries."
+#~ msgstr "共用ライブラリーに対してリンクを好みます。"
+
+#~ msgid "Export all dynamic symbols."
+#~ msgstr "全ダイナミックシンボルをエクスポートします。"
+
+#~ msgid "Strip all symbols."
+#~ msgstr "全シンボルを取り除きます。"
+
+#~ msgid "Strip debugging symbols."
+#~ msgstr "デバッグシンボルを取り除きます。"
+
+#~ msgid "Assume pagesize for the target system to be SIZE."
+#~ msgstr "ターゲットシステムのページサイズを SIZE と見做します。"
+
+#~ msgid "Set runtime DSO search path."
+#~ msgstr "実行時 DSO 検索パスを設定します。"
+
+#~ msgid "Set link time DSO search path."
+#~ msgstr "リンク時 DSO 検索パスを設定します。"
+
+#~ msgid "Generate dynamic shared object."
+#~ msgstr "動的共用オブジェクトを生成します。"
+
+#~ msgid "Generate relocatable object."
+#~ msgstr "リロケータブルオブジェクトを生成します。"
+
+#~ msgid "Causes symbol not assigned to a version be reduced to local."
+#~ msgstr "バージョンが指定されていないシンボルはローカルに減少します。"
+
+#~ msgid "Remove unused sections."
+#~ msgstr "使用されていないセクションを取り除きます。"
+
+#~ msgid "Don't remove unused sections."
+#~ msgstr "利用されていていセクションを取り除いてはいけません。"
+
+#~ msgid "Set soname of shared object."
+#~ msgstr "共用ライブラリーの so 名を設定します。"
+
+#~ msgid "Set the dynamic linker name."
+#~ msgstr "動的リンカーの名前を設定します。"
+
+#~ msgid "Add/suppress addition indentifying link-editor to .comment section."
+#~ msgstr ""
+#~ ".comment セクションにリンクエディターを識別する追加情報を追加/抑止します。"
+
+#~ msgid "Create .eh_frame_hdr section"
+#~ msgstr ".eh_frame_hdr セクションを生成します"
+
+#~ msgid "Set hash style to sysv, gnu or both."
+#~ msgstr "ハッシュ形式を sysvか、gnu、両方のどれかに設定します。"
+
+#~ msgid "Generate build ID note (md5, sha1 (default), uuid)."
+#~ msgstr "ビルド ID ノート (md5、sh1 (省略値)、uuid) を生成します。"
+
+#~ msgid "Linker Operation Control:"
+#~ msgstr "リンカー操作制御:"
+
+#~ msgid "Verbose messages."
+#~ msgstr "饒舌メッセージ。"
+
+#~ msgid "Trace file opens."
+#~ msgstr "ファイルのオープンを追跡します。"
+
+#~ msgid "Trade speed for less memory usage"
+#~ msgstr "速度と引き換えにメモリー使用量を減らします"
+
+#~ msgid "LEVEL"
+#~ msgstr "れべる"
+
+#~ msgid "Set optimization level to LEVEL."
+#~ msgstr "最適化レベルを れべる に設定します。"
+
+#~ msgid "Use linker script in FILE."
+#~ msgstr "ふぁいる でリンカースクリプトを使用します。"
+
+#~ msgid "Select to get parser debug information"
+#~ msgstr "パーサーのデバッグ情報を得るように選択します"
+
+#~ msgid "Read version information from FILE."
+#~ msgstr "ふぁいる からバージョン情報を読みます。"
+
+#~ msgid "Set emulation to NAME."
+#~ msgstr "エミュレーションを なまえ に設定します。"
+
+#~ msgid "Combine object and archive files."
+#~ msgstr "オブジェクトとアーカイブファイルを一体化します。"
+
+#~ msgid "[FILE]..."
+#~ msgstr "[ふぁいる]..."
+
+#~ msgid "At least one input file needed"
+#~ msgstr "少なくとも 1 つの入力ファイルが必要です"
+
+#~ msgid "error while preparing linking"
+#~ msgstr "リンクの準備中にエラー"
+
+#~ msgid "cannot open linker script '%s'"
+#~ msgstr "リンカースクリプト '%s' を開けません"
+
+#~ msgid "-( without matching -)"
+#~ msgstr "-( 何も一致しない -)"
+
+#~ msgid "only one option of -G and -r is allowed"
+#~ msgstr "-G か -r のどちらかひとつのオプションだけ認められます"
+
+#~ msgid "more than one '-m' parameter"
+#~ msgstr "-m パラメーターが1つを越えています"
+
+#~ msgid "unknown option `-%c %s'"
+#~ msgstr "不明なオプション `%c %s'"
+
+#~ msgid "invalid page size value '%s': ignored"
+#~ msgstr "不当なページサイズ値 '%s': 無視しました"
+
+#~ msgid "invalid hash style '%s'"
+#~ msgstr "不当なハッシュスタイル '%s'"
+
+#~ msgid "invalid build-ID style '%s'"
+#~ msgstr "不当なビルド-ID スタイル '%s'"
+
+#~ msgid "More than one output file name given."
+#~ msgstr "ひとつを越える出力ファイル名が与えられました。"
+
+#~ msgid "Invalid optimization level `%s'"
+#~ msgstr "不当な最適化レベル `%s'"
+
+#~ msgid "nested -( -) groups are not allowed"
+#~ msgstr "ネストされた -( -) グループは認められません"
+
+#~ msgid "-) without matching -("
+#~ msgstr "対応する -( がない -)"
+
+#~ msgid "unknown option '-%c %s'"
+#~ msgstr "不明なオプション '-%c %s'"
+
+#~ msgid "could not find input file to determine output file format"
+#~ msgstr "出力ファイル形式を決定するための入力ファイルが見つかりません"
+
+#~ msgid "try again with an appropriate '-m' parameter"
+#~ msgstr "適切な '-m' パラメーターを付けて再試行してください"
+
+#~ msgid "cannot read version script '%s'"
+#~ msgstr "バージョンスクリプト '%s' を読めません"
+
+#~ msgid "duplicate definition of '%s' in linker script"
+#~ msgstr "リンカースクリプトに '%s' の重複定義"
+
+#~ msgid "cannot create string table"
+#~ msgstr "文字列テーブルを生成できません"
+
+#~ msgid "cannot load ld backend library '%s': %s"
+#~ msgstr "ld バックエンドライブラリー '%s' をロードできません: %s"
+
+#~ msgid "cannot find init function in ld backend library '%s': %s"
+#~ msgstr "ld バックエンドライブラリー '%s' に初期化機能が見つかりません: %s "
+
+#~ msgid "%s listed more than once as input"
+#~ msgstr "入力に %s が 1回を越えて書かれています"
+
+#~ msgid "%s (for -l%s)\n"
+#~ msgstr "%s (-l%s 用)\n"
+
+#~ msgid "%s (for DT_NEEDED %s)\n"
+#~ msgstr "%s (DT_NEEDED %s 用)\n"
+
+#~ msgid "Warning: type of `%s' changed from %s in %s to %s in %s"
+#~ msgstr ""
+#~ "警告: `%1$s' のタイプが %3$s の %2$s から %5$s の %4$s に変更されました"
+
+#~ msgid ""
+#~ "Warning: size of `%s' changed from %<PRIu64> in %s to %<PRIu64> in %s"
+#~ msgstr ""
+#~ "警告: `%1$s の大きさが %3$s の %2$<PRIu64> から %5$s の %4$<PRIu64> に変更"
+#~ "されました"
+
+#~ msgid "(%s+%#<PRIx64>): multiple definition of %s `%s'\n"
+#~ msgstr "(%s+%#<PRIx64>): %s の複数定義 '%s'\n"
+
+#~ msgid "(%s+%#<PRIx64>): first defined here\n"
+#~ msgstr "(%s+%#<PRIx64>): 最初の定義はここ\n"
+
+#~ msgid "%s: cannot get section group data: %s"
+#~ msgstr "%s: セクショングループデータを得られません: %s"
+
+#~ msgid "%s: section '%s' with group flag set does not belong to any group"
+#~ msgstr ""
+#~ "%s: グループフラグが設定されているセクション '%s' はどのグループにも属して"
+#~ "いません"
+
+#~ msgid "%s: section [%2d] '%s' is not in the correct section group"
+#~ msgstr ""
+#~ "%s: セクション [%2d] '%s& は正しいセクショングループに入っていません"
+
+#~ msgid "%s: invalid ELF file (%s:%d)\n"
+#~ msgstr "%s: 不当な ELF ファイル (%s:%d)\n"
+
+#~ msgid "%s: only files of type ET_REL might contain section groups"
+#~ msgstr ""
+#~ "%s: タイプ ET_REL のファイルのみセクショングループを含むことができます"
+
+#~ msgid "%s: cannot determine signature of section group [%2zd] '%s': %s"
+#~ msgstr "%s: セクショングループ [%2zd] '%s' の署名を決定できません: %s"
+
+#~ msgid "%s: cannot get content of section group [%2zd] '%s': %s'"
+#~ msgstr "%s: セクショングループ [%2zd] '%s' の内容を得られません: %s'"
+
+#~ msgid ""
+#~ "%s: group member %zu of section group [%2zd] '%s' has too high index: "
+#~ "%<PRIu32>"
+#~ msgstr ""
+#~ "%1$s: セクショングループ [%3$2zd] '%4$s' のグループメンバー %2$zu は大きす"
+#~ "ぎるインデックスを持っています: %5$<PRIu32>"
+
+#~ msgid "%s: section '%s' has unknown type: %d"
+#~ msgstr "%s: セクション '%s' は不明なタイプを持っています: %d"
+
+#~ msgid "cannot get descriptor for ELF file (%s:%d): %s\n"
+#~ msgstr "ELF ファイル (%s:%d) のための記述子を得られません: %s\n"
+
+#~ msgid "cannot read archive `%s': %s"
+#~ msgstr "アーカイブ `%s' を読めません: %s"
+
+#~ msgid "file of type %s cannot be linked in\n"
+#~ msgstr "%s のファイルタイプがリンクされていません\n"
+
+#~ msgid "%s: input file incompatible with ELF machine type %s\n"
+#~ msgstr "%s: 入力ファイルは ELF マシンタイプ %s と互換性がありません\n"
+
+#~ msgid "%s: cannot get section header string table index: %s\n"
+#~ msgstr ""
+#~ "%s: セクションヘッダー文字列テーブルインデックスを得られません: %s\n"
+
+#~ msgid "cannot use DSO '%s' when generating relocatable object file"
+#~ msgstr "リロケータブルオブジェクトファイル生成時に DSO '%s' を使えません"
+
+#~ msgid "input file '%s' ignored"
+#~ msgstr "入力ファイル '%s' を無視しました"
+
+#~ msgid "undefined symbol `%s' in %s"
+#~ msgstr "%2$s 中に未定義のシンボル `%1$s'"
+
+#~ msgid "cannot create ELF descriptor for output file: %s"
+#~ msgstr "出力ファイル用の ELF 記述子を生成できません: %s"
+
+#~ msgid "could not create ELF header for output file: %s"
+#~ msgstr "出力ファイル用の ELF ヘッダーを生成できませんでした: %s"
+
+#~ msgid "cannot create section for output file: %s"
+#~ msgstr "出力ファイル用のセクションを生成できません: %s"
+
+#~ msgid "address computation expression contains variable '%s'"
+#~ msgstr "アドレス計算式が変数 '%s' を含んでいます"
+
+#~ msgid ""
+#~ "argument '%<PRIuMAX>' of ALIGN in address computation expression is no "
+#~ "power of two"
+#~ msgstr ""
+#~ "アドレス計算式中の ALIGN のパラメーター %<PRIuMAX> が 2 の累乗ではありませ"
+#~ "ん"
+
+#~ msgid "cannot find entry symbol '%s': defaulting to %#0*<PRIx64>"
+#~ msgstr ""
+#~ "エントリーシンボル '%s' が見つかりません: デフォルトの %#0*<PRIx64> にしま"
+#~ "す"
+
+#~ msgid "no entry symbol specified: defaulting to %#0*<PRIx64>"
+#~ msgstr ""
+#~ "エントリーシンボルが指定されていません: デフォルトの %#0*<PRIx64> にします"
+
+#~ msgid "cannot create GNU hash table section for output file: %s"
+#~ msgstr "出力ファイル用の GNU ハッシュテーブルセクションを生成できません: %s"
+
+#~ msgid "cannot create hash table section for output file: %s"
+#~ msgstr "出力ファイル用のハッシュテーブルセクションを生成できません: %s"
+
+#~ msgid "cannot create build ID section: %s"
+#~ msgstr "ビルド ID セクションを生成できません: %s"
+
+#~ msgid "cannot convert section data to file format: %s"
+#~ msgstr "セクションデータをファイル形式に変換できません: %s"
+
+#~ msgid "cannot convert section data to memory format: %s"
+#~ msgstr "セクションデータをメモリー形式に変換できません: %s"
+
+#~ msgid "cannot read enough data for UUID"
+#~ msgstr "UUID に十分なデータを読めません"
+
+#~ msgid "cannot create symbol table for output file: %s"
+#~ msgstr "出力ファイル用のシンボルテーブルを生成できません: %s"
+
+#~ msgid "section index too large in dynamic symbol table"
+#~ msgstr "動的シンボルテーブルのセクションインデックスが大きすぎます"
+
+#~ msgid "cannot create versioning section: %s"
+#~ msgstr "バージョニングセクションを生成できません: %s"
+
+#~ msgid "cannot create dynamic symbol table for output file: %s"
+#~ msgstr "出力ファイル用の動的シンボルテーブルを生成できません: %s"
+
+#~ msgid "cannot create versioning data: %s"
+#~ msgstr "バージョニングデータを生成できません: %s"
+
+#~ msgid "cannot create section header string section: %s"
+#~ msgstr "セクションヘッダー文字列セクションを生成できません: %s"
+
+#~ msgid "cannot create section header string section"
+#~ msgstr "セクションヘッダー文字列セクションを生成できません"
+
+#~ msgid "cannot create program header: %s"
+#~ msgstr "プログラムヘッダーを生成できません: %s"
+
+#~ msgid "while determining file layout: %s"
+#~ msgstr "ファイルレイアウトを決定中: %s"
+
+#~ msgid "internal error: non-nobits section follows nobits section"
+#~ msgstr "内部エラー: 非 nobits セクションが nobits セクションに続きます"
+
+#~ msgid "linker backend didn't specify function to relocate section"
+#~ msgstr ""
+#~ "リンカーバックエンドがセクションをリロケートするための機能を指定していませ"
+#~ "ん"
+
+#~ msgid "while writing output file: %s"
+#~ msgstr "出力ファイルに書込み中: %s"
+
+#~ msgid "while finishing output file: %s"
+#~ msgstr "出力ファイルの仕上げ中: %s"
+
+#~ msgid "cannot stat output file"
+#~ msgstr "出力ファイルを stat できません"
+
+#~ msgid "WARNING: temporary output file overwritten before linking finished"
+#~ msgstr "警告: リンクを仕上げる前に一時出力ファイルが上書きされました"
+
+#~ msgid "no machine specific '%s' implementation"
+#~ msgstr "マシン固有の '%s' 実装はありません"
+
+#~ msgid "mode for segment invalid\n"
+#~ msgstr "セグメント用のモードが不当です\n"
+
+#~ msgid "while reading version script '%s': %s at line %d"
+#~ msgstr "バージョンスクリプト '%1$s' 読込み中: %3$d 行目の %2$s"
+
+#~ msgid "while reading linker script '%s': %s at line %d"
+#~ msgstr "リンカースクリプト '%1$s' 読込み中: %3$d 行目の %2$s"
+
+#, fuzzy
+#~ msgid ""
+#~ "symbol '%s' is declared both local and global for unnamed version '%s'"
+#~ msgstr "名前なしバージョン用のローカルとグローバルで宣言されたシンボル '%s'"
+
+#, fuzzy
+#~ msgid "symbol '%s' is declared both local and global for version '%s'"
+#~ msgstr ""
+#~ "バージョン '%2$s' 用のローカルとグローバルで宣言されたシンボル '%1$s'"
+
+#~ msgid "default visibility set as local and global"
+#~ msgstr "ローカルとグローバルに設定されたデフォルトの可視性"
+
+#, fuzzy
+#~ msgid "cannot attach to core"
+#~ msgstr "検索ツリーを生成できません"
+
+#~ msgid "unknown tag %hx"
+#~ msgstr "不明なタグ %hx"
+
+#~ msgid "unknown user tag %hx"
+#~ msgstr "不明な利用者タグ %hx"
+
+#~ msgid "unknown attribute %hx"
+#~ msgstr "不明な属性 %hx"
+
+#~ msgid "unknown user attribute %hx"
+#~ msgstr "不明な利用者属性 %hx"
+
+#, fuzzy
+#~ msgid "unknown form %#<PRIx64>"
+#~ msgstr "不明な様式 %<PRIx64>"
+
+#~ msgid ""
+#~ "\n"
+#~ "\n"
+#~ "Symbols from %s[%s]:\n"
+#~ "\n"
+#~ msgstr ""
+#~ "\n"
+#~ "\n"
+#~ "%s[%s]からのシンボル:\n"
+#~ "\n"
+
+#~ msgid " Version String: "
+#~ msgstr "バージョン文字列:"
+
+#~ msgid "Equivalent to: -e -h -l"
+#~ msgstr "右記と同等: -e -h -l"
+
+#~ msgid ""
+#~ "\n"
+#~ "Section [%Zu] '%s' is empty.\n"
+#~ msgstr ""
+#~ "\n"
+#~ "セクション [%Zu] '%s' は空です。\n"
diff --git a/third_party/elfutils/po/nl.po b/third_party/elfutils/po/nl.po
new file mode 100644
index 0000000..ff3e5d5
--- /dev/null
+++ b/third_party/elfutils/po/nl.po
@@ -0,0 +1,5666 @@
+# Dutch translation of elfutils
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+# Geert Warrink <geert.warrink@onsnet.nu>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Elfutils\n"
+"Report-Msgid-Bugs-To: http://bugzilla.redhat.com/\n"
+"POT-Creation-Date: 2010-04-21 07:41-0700\n"
+"PO-Revision-Date: 2009-09-01 18:02+0200\n"
+"Last-Translator: Geert Warrink <geert.warrink@onsnet.nu>\n"
+"Language-Team: nl <nl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding:  \n"
+
+#: lib/xmalloc.c:51 lib/xmalloc.c:65 lib/xmalloc.c:79 src/readelf.c:2822
+#: src/readelf.c:3161 src/unstrip.c:2087 src/unstrip.c:2295
+#, c-format
+msgid "memory exhausted"
+msgstr ""
+
+#: libasm/asm_error.c:62 libdw/dwarf_error.c:79 libdwfl/libdwflP.h:70
+#: libelf/elf_error.c:81
+msgid "no error"
+msgstr ""
+
+#: libasm/asm_error.c:63 libdw/dwarf_error.c:88 libdwfl/libdwflP.h:72
+#: libelf/elf_error.c:112
+msgid "out of memory"
+msgstr ""
+
+#: libasm/asm_error.c:64 src/ldgeneric.c:2687
+#, c-format
+msgid "cannot create output file"
+msgstr ""
+
+#: libasm/asm_error.c:65
+msgid "invalid parameter"
+msgstr ""
+
+#: libasm/asm_error.c:66
+msgid "cannot change mode of output file"
+msgstr ""
+
+#: libasm/asm_error.c:67 src/ldgeneric.c:7001
+#, c-format
+msgid "cannot rename output file"
+msgstr ""
+
+#: libasm/asm_error.c:68
+msgid "duplicate symbol"
+msgstr ""
+
+#: libasm/asm_error.c:69
+msgid "invalid section type for operation"
+msgstr ""
+
+#: libasm/asm_error.c:70
+msgid "error during output of data"
+msgstr ""
+
+#: libasm/asm_error.c:71
+msgid "no backend support available"
+msgstr ""
+
+#: libasm/asm_error.c:81 libdw/dwarf_error.c:80 libdwfl/libdwflP.h:71
+#: libelf/elf_error.c:84
+msgid "unknown error"
+msgstr ""
+
+#: libdw/dwarf_error.c:81
+msgid "invalid access"
+msgstr ""
+
+#: libdw/dwarf_error.c:82
+msgid "no regular file"
+msgstr ""
+
+#: libdw/dwarf_error.c:83
+msgid "I/O error"
+msgstr ""
+
+#: libdw/dwarf_error.c:84
+msgid "invalid ELF file"
+msgstr ""
+
+#: libdw/dwarf_error.c:85
+msgid "no DWARF information"
+msgstr ""
+
+#: libdw/dwarf_error.c:86
+msgid "no ELF file"
+msgstr ""
+
+#: libdw/dwarf_error.c:87
+msgid "cannot get ELF header"
+msgstr ""
+
+#: libdw/dwarf_error.c:89
+msgid "not implemented"
+msgstr ""
+
+#: libdw/dwarf_error.c:90 libelf/elf_error.c:128 libelf/elf_error.c:176
+msgid "invalid command"
+msgstr ""
+
+#: libdw/dwarf_error.c:91
+msgid "invalid version"
+msgstr ""
+
+#: libdw/dwarf_error.c:92
+msgid "invalid file"
+msgstr ""
+
+#: libdw/dwarf_error.c:93
+msgid "no entries found"
+msgstr ""
+
+#: libdw/dwarf_error.c:94
+msgid "invalid DWARF"
+msgstr ""
+
+#: libdw/dwarf_error.c:95
+msgid "no string data"
+msgstr ""
+
+#: libdw/dwarf_error.c:96
+msgid "no address value"
+msgstr ""
+
+#: libdw/dwarf_error.c:97
+msgid "no constant value"
+msgstr ""
+
+#: libdw/dwarf_error.c:98
+msgid "no reference value"
+msgstr ""
+
+#: libdw/dwarf_error.c:99
+msgid "invalid reference value"
+msgstr ""
+
+#: libdw/dwarf_error.c:100
+msgid ".debug_line section missing"
+msgstr ""
+
+#: libdw/dwarf_error.c:101
+msgid "invalid .debug_line section"
+msgstr ""
+
+#: libdw/dwarf_error.c:102
+msgid "debug information too big"
+msgstr ""
+
+#: libdw/dwarf_error.c:103
+msgid "invalid DWARF version"
+msgstr ""
+
+#: libdw/dwarf_error.c:104
+msgid "invalid directory index"
+msgstr ""
+
+#: libdw/dwarf_error.c:105 libdwfl/libdwflP.h:91
+msgid "address out of range"
+msgstr ""
+
+#: libdw/dwarf_error.c:106
+msgid "no location list value"
+msgstr ""
+
+#: libdw/dwarf_error.c:107
+msgid "no block data"
+msgstr ""
+
+#: libdw/dwarf_error.c:108
+msgid "invalid line index"
+msgstr ""
+
+#: libdw/dwarf_error.c:109
+msgid "invalid address range index"
+msgstr ""
+
+#: libdw/dwarf_error.c:110 libdwfl/libdwflP.h:92
+msgid "no matching address range"
+msgstr ""
+
+#: libdw/dwarf_error.c:111
+msgid "no flag value"
+msgstr ""
+
+#: libdw/dwarf_error.c:112 libelf/elf_error.c:253
+msgid "invalid offset"
+msgstr ""
+
+#: libdw/dwarf_error.c:113
+msgid ".debug_ranges section missing"
+msgstr ""
+
+#: libdw/dwarf_error.c:114
+msgid "invalid CFI section"
+msgstr ""
+
+#: libdwfl/argp-std.c:67 src/unstrip.c:2237
+msgid "Input selection options:"
+msgstr ""
+
+#: libdwfl/argp-std.c:68
+msgid "Find addresses in FILE"
+msgstr ""
+
+#: libdwfl/argp-std.c:70
+msgid "Find addresses from signatures found in COREFILE"
+msgstr ""
+
+#: libdwfl/argp-std.c:72
+msgid "Find addresses in files mapped into process PID"
+msgstr ""
+
+#: libdwfl/argp-std.c:74
+msgid ""
+"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps "
+"format"
+msgstr ""
+
+#: libdwfl/argp-std.c:76
+msgid "Find addresses in the running kernel"
+msgstr ""
+
+#: libdwfl/argp-std.c:78
+msgid "Kernel with all modules"
+msgstr ""
+
+#: libdwfl/argp-std.c:80
+msgid "Search path for separate debuginfo files"
+msgstr ""
+
+#: libdwfl/argp-std.c:163
+msgid "only one of -e, -p, -k, -K, or --core allowed"
+msgstr ""
+
+#: libdwfl/argp-std.c:223
+#, c-format
+msgid "cannot read ELF core file: %s"
+msgstr ""
+
+#: libdwfl/argp-std.c:241
+msgid "No modules recognized in core file"
+msgstr ""
+
+#: libdwfl/argp-std.c:253
+msgid "cannot load kernel symbols"
+msgstr ""
+
+#: libdwfl/argp-std.c:257
+msgid "cannot find kernel modules"
+msgstr ""
+
+#: libdwfl/argp-std.c:271
+msgid "cannot find kernel or modules"
+msgstr ""
+
+#: libdwfl/libdwflP.h:73
+msgid "See errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:74
+msgid "See elf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:75
+msgid "See dwarf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:76
+msgid "See ebl_errno (XXX missing)"
+msgstr ""
+
+#: libdwfl/libdwflP.h:77
+msgid "gzip decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:78
+msgid "bzip2 decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:79
+msgid "LZMA decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:80
+msgid "no support library found for machine"
+msgstr ""
+
+#: libdwfl/libdwflP.h:81
+msgid "Callbacks missing for ET_REL file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:82
+msgid "Unsupported relocation type"
+msgstr ""
+
+#: libdwfl/libdwflP.h:83
+msgid "r_offset is bogus"
+msgstr ""
+
+#: libdwfl/libdwflP.h:84 libelf/elf_error.c:132 libelf/elf_error.c:192
+msgid "offset out of range"
+msgstr ""
+
+#: libdwfl/libdwflP.h:85
+msgid "relocation refers to undefined symbol"
+msgstr ""
+
+#: libdwfl/libdwflP.h:86
+msgid "Callback returned failure"
+msgstr ""
+
+#: libdwfl/libdwflP.h:87
+msgid "No DWARF information found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:88
+msgid "No symbol table found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:89
+msgid "No ELF program headers"
+msgstr ""
+
+#: libdwfl/libdwflP.h:90
+msgid "address range overlaps an existing module"
+msgstr ""
+
+#: libdwfl/libdwflP.h:93
+msgid "image truncated"
+msgstr ""
+
+#: libdwfl/libdwflP.h:94
+msgid "ELF file opened"
+msgstr ""
+
+#: libdwfl/libdwflP.h:95
+msgid "not a valid ELF file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:96
+msgid "cannot handle DWARF type description"
+msgstr ""
+
+#: libebl/eblbackendname.c:63
+msgid "No backend"
+msgstr ""
+
+#: libebl/eblcorenotetypename.c:107 libebl/eblobjecttypename.c:78
+#: libebl/eblobjnotetypename.c:86 libebl/eblosabiname.c:98
+#: libebl/eblsectionname.c:110 libebl/eblsectiontypename.c:140
+#: libebl/eblsegmenttypename.c:104
+msgid "<unknown>"
+msgstr ""
+
+#: libebl/ebldynamictagname.c:126
+#, c-format
+msgid "<unknown>: %#<PRIx64>"
+msgstr ""
+
+#: libebl/eblobjnote.c:76
+#, c-format
+msgid "    Build ID: "
+msgstr ""
+
+#: libebl/eblobjnote.c:87
+#, c-format
+msgid "    Linker version: %.*s\n"
+msgstr ""
+
+#: libebl/eblobjnote.c:136
+#, c-format
+msgid "    OS: %s, ABI: "
+msgstr ""
+
+#: libebl/eblosabiname.c:95
+msgid "Stand alone"
+msgstr ""
+
+#: libebl/eblsymbolbindingname.c:92 libebl/eblsymboltypename.c:98
+#, c-format
+msgid "<unknown>: %d"
+msgstr ""
+
+#: libelf/elf_error.c:88
+msgid "unknown version"
+msgstr ""
+
+#: libelf/elf_error.c:92
+msgid "unknown type"
+msgstr ""
+
+#: libelf/elf_error.c:96
+msgid "invalid `Elf' handle"
+msgstr ""
+
+#: libelf/elf_error.c:100
+msgid "invalid size of source operand"
+msgstr ""
+
+#: libelf/elf_error.c:104
+msgid "invalid size of destination operand"
+msgstr ""
+
+#: libelf/elf_error.c:108 src/readelf.c:4779
+#, c-format
+msgid "invalid encoding"
+msgstr ""
+
+#: libelf/elf_error.c:116
+msgid "invalid file descriptor"
+msgstr ""
+
+#: libelf/elf_error.c:120
+msgid "invalid operation"
+msgstr ""
+
+#: libelf/elf_error.c:124
+msgid "ELF version not set"
+msgstr ""
+
+#: libelf/elf_error.c:136
+msgid "invalid fmag field in archive header"
+msgstr ""
+
+#: libelf/elf_error.c:140
+msgid "invalid archive file"
+msgstr ""
+
+#: libelf/elf_error.c:144
+msgid "descriptor is not for an archive"
+msgstr ""
+
+#: libelf/elf_error.c:148
+msgid "no index available"
+msgstr ""
+
+#: libelf/elf_error.c:152
+msgid "cannot read data from file"
+msgstr ""
+
+#: libelf/elf_error.c:156
+msgid "cannot write data to file"
+msgstr ""
+
+#: libelf/elf_error.c:160
+msgid "invalid binary class"
+msgstr ""
+
+#: libelf/elf_error.c:164
+msgid "invalid section index"
+msgstr ""
+
+#: libelf/elf_error.c:168
+msgid "invalid operand"
+msgstr ""
+
+#: libelf/elf_error.c:172
+msgid "invalid section"
+msgstr ""
+
+#: libelf/elf_error.c:180
+msgid "executable header not created first"
+msgstr ""
+
+#: libelf/elf_error.c:184
+msgid "file descriptor disabled"
+msgstr ""
+
+#: libelf/elf_error.c:188
+msgid "archive/member file descriptor mismatch"
+msgstr ""
+
+#: libelf/elf_error.c:196
+msgid "cannot manipulate null section"
+msgstr ""
+
+#: libelf/elf_error.c:200
+msgid "data/scn mismatch"
+msgstr ""
+
+#: libelf/elf_error.c:204
+msgid "invalid section header"
+msgstr ""
+
+#: libelf/elf_error.c:208 src/readelf.c:6242 src/readelf.c:6343
+#, c-format
+msgid "invalid data"
+msgstr ""
+
+#: libelf/elf_error.c:212
+msgid "unknown data encoding"
+msgstr ""
+
+#: libelf/elf_error.c:216
+msgid "section `sh_size' too small for data"
+msgstr ""
+
+#: libelf/elf_error.c:220
+msgid "invalid section alignment"
+msgstr ""
+
+#: libelf/elf_error.c:224
+msgid "invalid section entry size"
+msgstr ""
+
+#: libelf/elf_error.c:228
+msgid "update() for write on read-only file"
+msgstr ""
+
+#: libelf/elf_error.c:232
+msgid "no such file"
+msgstr ""
+
+#: libelf/elf_error.c:236
+msgid "only relocatable files can contain section groups"
+msgstr ""
+
+#: libelf/elf_error.c:241
+msgid ""
+"program header only allowed in executables, shared objects, and core files"
+msgstr ""
+
+#: libelf/elf_error.c:248
+msgid "file has no program header"
+msgstr ""
+
+#: src/addr2line.c:66
+msgid "Output selection options:"
+msgstr ""
+
+#: src/addr2line.c:67
+msgid "Show only base names of source files"
+msgstr ""
+
+#: src/addr2line.c:69
+msgid "Show absolute file names using compilation directory"
+msgstr ""
+
+#: src/addr2line.c:70
+msgid "Also show function names"
+msgstr ""
+
+#: src/addr2line.c:71
+msgid "Also show symbol or section names"
+msgstr ""
+
+#: src/addr2line.c:73
+msgid "Treat addresses as offsets relative to NAME section."
+msgstr ""
+
+#: src/addr2line.c:75 src/elfcmp.c:75 src/findtextrel.c:75 src/nm.c:103
+#: src/strings.c:83
+msgid "Miscellaneous:"
+msgstr ""
+
+#: src/addr2line.c:84
+msgid ""
+"Locate source files and line information for ADDRs (in a.out by default)."
+msgstr ""
+
+#: src/addr2line.c:88
+msgid "[ADDR...]"
+msgstr ""
+
+#: src/addr2line.c:185 src/ar.c:289 src/elfcmp.c:555 src/elflint.c:239
+#: src/findtextrel.c:170 src/ld.c:957 src/nm.c:253 src/objdump.c:181
+#: src/ranlib.c:136 src/readelf.c:449 src/size.c:219 src/strings.c:227
+#: src/strip.c:204 src/unstrip.c:234
+#, c-format
+msgid ""
+"Copyright (C) %s Red Hat, Inc.\n"
+"This is free software; see the source for copying conditions.  There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+
+#: src/addr2line.c:190 src/ar.c:294 src/elfcmp.c:560 src/elflint.c:244
+#: src/findtextrel.c:175 src/ld.c:962 src/nm.c:258 src/objdump.c:186
+#: src/ranlib.c:141 src/readelf.c:454 src/size.c:224 src/strings.c:232
+#: src/strip.c:209 src/unstrip.c:239
+#, c-format
+msgid "Written by %s.\n"
+msgstr ""
+
+#: src/addr2line.c:405
+#, c-format
+msgid "Section syntax requires exactly one module"
+msgstr ""
+
+#: src/addr2line.c:428
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside section '%s'"
+msgstr ""
+
+#: src/addr2line.c:461
+#, c-format
+msgid "cannot find symbol '%s'"
+msgstr ""
+
+#: src/addr2line.c:466
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside contents of '%s'"
+msgstr ""
+
+#: src/ar.c:76
+msgid "Commands:"
+msgstr ""
+
+#: src/ar.c:77
+msgid "Delete files from archive."
+msgstr ""
+
+#: src/ar.c:78
+msgid "Move files in archive."
+msgstr ""
+
+#: src/ar.c:79
+msgid "Print files in archive."
+msgstr ""
+
+#: src/ar.c:80
+msgid "Quick append files to archive."
+msgstr ""
+
+#: src/ar.c:82
+msgid "Replace existing or insert new file into archive."
+msgstr ""
+
+#: src/ar.c:83
+msgid "Display content of archive."
+msgstr ""
+
+#: src/ar.c:84
+msgid "Extract files from archive."
+msgstr ""
+
+#: src/ar.c:86
+msgid "Command Modifiers:"
+msgstr ""
+
+#: src/ar.c:87
+msgid "Preserve original dates."
+msgstr ""
+
+#: src/ar.c:88
+msgid "Use instance [COUNT] of name."
+msgstr ""
+
+#: src/ar.c:90
+msgid "Do not replace existing files with extracted files."
+msgstr ""
+
+#: src/ar.c:91
+msgid "Allow filename to be truncated if necessary."
+msgstr ""
+
+#: src/ar.c:93
+msgid "Provide verbose output."
+msgstr ""
+
+#: src/ar.c:94
+msgid "Force regeneration of symbol table."
+msgstr ""
+
+#: src/ar.c:95
+msgid "Insert file after [MEMBER]."
+msgstr ""
+
+#: src/ar.c:96
+msgid "Insert file before [MEMBER]."
+msgstr ""
+
+#: src/ar.c:97
+msgid "Same as -b."
+msgstr ""
+
+#: src/ar.c:98
+msgid "Suppress message when library has to be created."
+msgstr ""
+
+#: src/ar.c:100
+msgid "Use full path for file matching."
+msgstr ""
+
+#: src/ar.c:101
+msgid "Update only older files in archive."
+msgstr ""
+
+#: src/ar.c:107
+msgid "Create, modify, and extract from archives."
+msgstr ""
+
+#: src/ar.c:110
+msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]"
+msgstr ""
+
+#: src/ar.c:192
+#, c-format
+msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options"
+msgstr ""
+
+#: src/ar.c:197
+#, c-format
+msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers"
+msgstr ""
+
+#: src/ar.c:213
+#, c-format
+msgid "'N' is only meaningful with the 'x' and 'd' options"
+msgstr ""
+
+#: src/ar.c:218
+#, c-format
+msgid "COUNT parameter required"
+msgstr ""
+
+#: src/ar.c:230
+#, c-format
+msgid "invalid COUNT parameter %s"
+msgstr ""
+
+#: src/ar.c:237
+#, c-format
+msgid "'%c' is only meaningful with the 'x' option"
+msgstr ""
+
+#: src/ar.c:243
+#, c-format
+msgid "archive name required"
+msgstr ""
+
+#: src/ar.c:314
+#, c-format
+msgid "More than one operation specified"
+msgstr ""
+
+#: src/ar.c:404
+#, c-format
+msgid "cannot open archive '%s'"
+msgstr ""
+
+#: src/ar.c:414
+#, c-format
+msgid "cannot open archive '%s': %s"
+msgstr ""
+
+#: src/ar.c:418
+#, c-format
+msgid "%s: not an archive file"
+msgstr ""
+
+#: src/ar.c:422
+#, c-format
+msgid "cannot stat archive '%s'"
+msgstr ""
+
+#: src/ar.c:434
+#, c-format
+msgid "no entry %s in archive\n"
+msgstr ""
+
+#: src/ar.c:487 src/ar.c:929 src/ar.c:1129
+#, c-format
+msgid "cannot create hash table"
+msgstr ""
+
+#: src/ar.c:494 src/ar.c:936 src/ar.c:1138
+#, c-format
+msgid "cannot insert into hash table"
+msgstr ""
+
+#: src/ar.c:502 src/ranlib.c:176
+#, c-format
+msgid "cannot stat '%s'"
+msgstr ""
+
+#: src/ar.c:598
+#, c-format
+msgid "cannot read content of %s: %s"
+msgstr ""
+
+#: src/ar.c:641
+#, c-format
+msgid "cannot open %.*s"
+msgstr ""
+
+#: src/ar.c:663
+#, c-format
+msgid "failed to write %s"
+msgstr ""
+
+#: src/ar.c:675
+#, c-format
+msgid "cannot change mode of %s"
+msgstr ""
+
+#: src/ar.c:691
+#, c-format
+msgid "cannot change modification time of %s"
+msgstr ""
+
+#: src/ar.c:737
+#, c-format
+msgid "cannot rename temporary file to %.*s"
+msgstr ""
+
+#: src/ar.c:773 src/ar.c:1021 src/ar.c:1419 src/ranlib.c:250
+#, c-format
+msgid "cannot create new file"
+msgstr ""
+
+#: src/ar.c:1220
+#, c-format
+msgid "position member %s not found"
+msgstr ""
+
+#: src/ar.c:1230
+#, c-format
+msgid "%s: no entry %s in archive!\n"
+msgstr ""
+
+#: src/ar.c:1259 src/ldgeneric.c:519 src/objdump.c:257
+#, c-format
+msgid "cannot open %s"
+msgstr ""
+
+#: src/ar.c:1264
+#, c-format
+msgid "cannot stat %s"
+msgstr ""
+
+#: src/ar.c:1270
+#, c-format
+msgid "%s is no regular file"
+msgstr ""
+
+#: src/ar.c:1283
+#, c-format
+msgid "cannot get ELF descriptor for %s: %s\n"
+msgstr ""
+
+#: src/ar.c:1302
+#, c-format
+msgid "cannot read %s: %s"
+msgstr ""
+
+#: src/arlib.c:215
+#, c-format
+msgid "the archive '%s' is too large"
+msgstr ""
+
+#: src/arlib.c:228
+#, c-format
+msgid "cannot read ELF header of %s(%s): %s"
+msgstr ""
+
+#: src/elfcmp.c:69
+msgid "Control options:"
+msgstr ""
+
+#: src/elfcmp.c:70
+msgid ""
+"Control treatment of gaps in loadable segments [ignore|match] (default: "
+"ignore)"
+msgstr ""
+
+#: src/elfcmp.c:72
+msgid "Ignore permutation of buckets in SHT_HASH section"
+msgstr ""
+
+#: src/elfcmp.c:73
+msgid "Output nothing; yield exit status only"
+msgstr ""
+
+#: src/elfcmp.c:80
+msgid "Compare relevant parts of two ELF files for equality."
+msgstr ""
+
+#: src/elfcmp.c:84
+msgid "FILE1 FILE2"
+msgstr ""
+
+#: src/elfcmp.c:140
+msgid "Invalid number of parameters.\n"
+msgstr ""
+
+#: src/elfcmp.c:168 src/elfcmp.c:173
+#, c-format
+msgid "cannot get ELF header of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:190
+#, c-format
+msgid "%s %s diff: ELF header"
+msgstr ""
+
+#: src/elfcmp.c:198 src/elfcmp.c:201
+#, c-format
+msgid "cannot get section count of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:206
+#, c-format
+msgid "%s %s diff: section count"
+msgstr ""
+
+#: src/elfcmp.c:214 src/elfcmp.c:217
+#, c-format
+msgid "cannot get program header count of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:222
+#, c-format
+msgid "%s %s diff: program header count"
+msgstr ""
+
+#: src/elfcmp.c:281
+#, c-format
+msgid "%s %s differ: section header"
+msgstr ""
+
+#: src/elfcmp.c:309 src/elfcmp.c:315
+#, c-format
+msgid "cannot get content of section %zu in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:331 src/elfcmp.c:337
+#, c-format
+msgid "cannot get symbol in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:358
+#, c-format
+msgid "%s %s differ: symbol table [%zu]"
+msgstr ""
+
+#: src/elfcmp.c:361
+#, c-format
+msgid "%s %s differ: symbol table [%zu,%zu]"
+msgstr ""
+
+#: src/elfcmp.c:409
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:413
+#, c-format
+msgid "%s %s differ: section [%zu,%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:429
+#, c-format
+msgid "%s %s differ: unequal amount of important sections"
+msgstr ""
+
+#: src/elfcmp.c:463 src/elfcmp.c:468
+#, c-format
+msgid "cannot load data of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:487 src/elfcmp.c:493
+#, c-format
+msgid "cannot get program header entry %d of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:499
+#, c-format
+msgid "%s %s differ: program header %d"
+msgstr ""
+
+#: src/elfcmp.c:524
+#, c-format
+msgid "%s %s differ: gap"
+msgstr ""
+
+#: src/elfcmp.c:583
+#, c-format
+msgid "Invalid value '%s' for --gaps parameter."
+msgstr ""
+
+#: src/elfcmp.c:607 src/findtextrel.c:229 src/ldgeneric.c:1767
+#: src/ldgeneric.c:4257 src/nm.c:363 src/ranlib.c:169 src/size.c:301
+#: src/strings.c:183 src/strip.c:433 src/strip.c:468 src/unstrip.c:1900
+#: src/unstrip.c:1929
+#, c-format
+msgid "cannot open '%s'"
+msgstr ""
+
+#: src/elfcmp.c:611 src/findtextrel.c:236 src/ranlib.c:186
+#, c-format
+msgid "cannot create ELF descriptor for '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:616
+#, c-format
+msgid "cannot create EBL descriptor for '%s'"
+msgstr ""
+
+#: src/elfcmp.c:634
+#, c-format
+msgid "cannot get section header of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:644
+#, c-format
+msgid "cannot get content of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:654 src/elfcmp.c:668
+#, c-format
+msgid "cannot get relocation: %s"
+msgstr ""
+
+#: src/elflint.c:72
+msgid "Be extremely strict, flag level 2 features."
+msgstr ""
+
+#: src/elflint.c:73
+msgid "Do not print anything if successful"
+msgstr ""
+
+#: src/elflint.c:74
+msgid "Binary is a separate debuginfo file"
+msgstr ""
+
+#: src/elflint.c:76
+msgid ""
+"Binary has been created with GNU ld and is therefore known to be broken in "
+"certain ways"
+msgstr ""
+
+#: src/elflint.c:82
+msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
+msgstr ""
+
+#: src/elflint.c:86 src/readelf.c:118
+msgid "FILE..."
+msgstr ""
+
+#: src/elflint.c:159 src/readelf.c:272
+#, c-format
+msgid "cannot open input file"
+msgstr ""
+
+#: src/elflint.c:166
+#, c-format
+msgid "cannot generate Elf descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:185
+#, c-format
+msgid "error while closing Elf descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:189
+msgid "No errors"
+msgstr ""
+
+#: src/elflint.c:223 src/readelf.c:425
+msgid "Missing file name.\n"
+msgstr ""
+
+#: src/elflint.c:302
+#, c-format
+msgid " error while freeing sub-ELF descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:310
+#, c-format
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr ""
+
+#: src/elflint.c:370
+#, c-format
+msgid "e_ident[%d] == %d is no known class\n"
+msgstr ""
+
+#: src/elflint.c:375
+#, c-format
+msgid "e_ident[%d] == %d is no known data encoding\n"
+msgstr ""
+
+#: src/elflint.c:379
+#, c-format
+msgid "unknown ELF header version number e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:385
+#, c-format
+msgid "unsupported OS ABI e_ident[%d] == '%s'\n"
+msgstr ""
+
+#: src/elflint.c:391
+#, c-format
+msgid "unsupport ABI version e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:396
+#, c-format
+msgid "e_ident[%zu] is not zero\n"
+msgstr ""
+
+#: src/elflint.c:401
+#, c-format
+msgid "unknown object file type %d\n"
+msgstr ""
+
+#: src/elflint.c:408
+#, c-format
+msgid "unknown machine type %d\n"
+msgstr ""
+
+#: src/elflint.c:412
+#, c-format
+msgid "unknown object file version\n"
+msgstr ""
+
+#: src/elflint.c:418
+#, c-format
+msgid "invalid program header offset\n"
+msgstr ""
+
+#: src/elflint.c:420
+#, c-format
+msgid "executables and DSOs cannot have zero program header offset\n"
+msgstr ""
+
+#: src/elflint.c:424
+#, c-format
+msgid "invalid number of program header entries\n"
+msgstr ""
+
+#: src/elflint.c:432
+#, c-format
+msgid "invalid section header table offset\n"
+msgstr ""
+
+#: src/elflint.c:435
+#, c-format
+msgid "section header table must be present\n"
+msgstr ""
+
+#: src/elflint.c:449
+#, c-format
+msgid "invalid number of section header table entries\n"
+msgstr ""
+
+#: src/elflint.c:466
+#, c-format
+msgid "invalid section header index\n"
+msgstr ""
+
+#: src/elflint.c:480
+#, c-format
+msgid "invalid number of program header table entries\n"
+msgstr ""
+
+#: src/elflint.c:489
+#, c-format
+msgid "invalid machine flags: %s\n"
+msgstr ""
+
+#: src/elflint.c:496 src/elflint.c:513
+#, c-format
+msgid "invalid ELF header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:499 src/elflint.c:516
+#, c-format
+msgid "invalid program header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:502 src/elflint.c:519
+#, c-format
+msgid "invalid program header position or size\n"
+msgstr ""
+
+#: src/elflint.c:505 src/elflint.c:522
+#, c-format
+msgid "invalid section header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:508 src/elflint.c:525
+#, c-format
+msgid "invalid section header position or size\n"
+msgstr ""
+
+#: src/elflint.c:569
+#, c-format
+msgid ""
+"section [%2d] '%s': section with SHF_GROUP flag set not part of a section "
+"group\n"
+msgstr ""
+
+#: src/elflint.c:573
+#, c-format
+msgid ""
+"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"
+msgstr ""
+
+#: src/elflint.c:589 src/elflint.c:1432 src/elflint.c:1482 src/elflint.c:1591
+#: src/elflint.c:2185 src/elflint.c:2699 src/elflint.c:2860 src/elflint.c:2990
+#: src/elflint.c:3162 src/elflint.c:4062
+#, c-format
+msgid "section [%2d] '%s': cannot get section data\n"
+msgstr ""
+
+#: src/elflint.c:602 src/elflint.c:1598
+#, c-format
+msgid ""
+"section [%2d] '%s': referenced as string table for section [%2d] '%s' but "
+"type is not SHT_STRTAB\n"
+msgstr ""
+
+#: src/elflint.c:625
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol table cannot have more than one extended index "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:636
+#, c-format
+msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n"
+msgstr ""
+
+#: src/elflint.c:645
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:650 src/elflint.c:653 src/elflint.c:656 src/elflint.c:659
+#: src/elflint.c:662 src/elflint.c:665
+#, c-format
+msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:668
+#, c-format
+msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:678
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:687
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid name value\n"
+msgstr ""
+
+#: src/elflint.c:700
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: too large section index but no extended "
+"section index section\n"
+msgstr ""
+
+#: src/elflint.c:706
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in "
+"st_shndx (%<PRIu32>)\n"
+msgstr ""
+
+#: src/elflint.c:718
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid section index\n"
+msgstr ""
+
+#: src/elflint.c:726
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown type\n"
+msgstr ""
+
+#: src/elflint.c:732
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown symbol binding\n"
+msgstr ""
+
+#: src/elflint.c:737
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unique symbol not of object type\n"
+msgstr ""
+
+#: src/elflint.c:745
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"
+msgstr ""
+
+#: src/elflint.c:749
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"
+msgstr ""
+
+#: src/elflint.c:753
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"
+msgstr ""
+
+#: src/elflint.c:785
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: st_value out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:791 src/elflint.c:816 src/elflint.c:859
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu does not fit completely in referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:800
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have "
+"SHF_TLS flag set\n"
+msgstr ""
+
+#: src/elflint.c:810 src/elflint.c:852
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:837
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"
+msgstr ""
+
+#: src/elflint.c:845
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:872
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:879
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: non-local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:886
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: non-local section symbol\n"
+msgstr ""
+
+#: src/elflint.c:936
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section [%"
+"2d]\n"
+msgstr ""
+
+#: src/elflint.c:943
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:959
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#<PRIx64> does not "
+"match %s section address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:966
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %<PRIu64> does not "
+"match %s section size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:974
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:990
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC_ symbol value %#<PRIx64> does not match dynamic "
+"segment address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:997
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC symbol size %<PRIu64> does not match dynamic "
+"segment size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:1010
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-"
+"default visibility\n"
+msgstr ""
+
+#: src/elflint.c:1014
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"
+msgstr ""
+
+#: src/elflint.c:1059
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"
+msgstr ""
+
+#: src/elflint.c:1068 src/elflint.c:1120
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"
+msgstr ""
+
+#: src/elflint.c:1093 src/elflint.c:1145
+#, c-format
+msgid ""
+"section [%2d] '%s': relative relocations after index %d as specified by "
+"DT_RELCOUNT\n"
+msgstr ""
+
+#: src/elflint.c:1099 src/elflint.c:1151
+#, c-format
+msgid ""
+"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT "
+"specified %d relative relocations\n"
+msgstr ""
+
+#: src/elflint.c:1111
+#, c-format
+msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n"
+msgstr ""
+
+#: src/elflint.c:1193
+#, c-format
+msgid "section [%2d] '%s': invalid destination section index\n"
+msgstr ""
+
+#: src/elflint.c:1206
+#, c-format
+msgid "section [%2d] '%s': invalid destination section type\n"
+msgstr ""
+
+#: src/elflint.c:1214
+#, c-format
+msgid "section [%2d] '%s': sh_info should be zero\n"
+msgstr ""
+
+#: src/elflint.c:1221
+#, c-format
+msgid "section [%2d] '%s': no relocations for merge-able sections possible\n"
+msgstr ""
+
+#: src/elflint.c:1228
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n"
+msgstr ""
+
+#: src/elflint.c:1288
+#, c-format
+msgid "text relocation flag set but there is no read-only segment\n"
+msgstr ""
+
+#: src/elflint.c:1315
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid type\n"
+msgstr ""
+
+#: src/elflint.c:1323
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: relocation type invalid for the file "
+"type\n"
+msgstr ""
+
+#: src/elflint.c:1331
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n"
+msgstr ""
+
+#: src/elflint.c:1349
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can "
+"be used with %s\n"
+msgstr ""
+
+#: src/elflint.c:1366
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:1381
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: copy relocation against symbol of type %"
+"s\n"
+msgstr ""
+
+#: src/elflint.c:1402
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: read-only section modified but text "
+"relocation flag not set\n"
+msgstr ""
+
+#: src/elflint.c:1417
+#, c-format
+msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n"
+msgstr ""
+
+#: src/elflint.c:1456 src/elflint.c:1506
+#, c-format
+msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1586
+#, c-format
+msgid "more than one dynamic section present\n"
+msgstr ""
+
+#: src/elflint.c:1604
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"
+msgstr ""
+
+#: src/elflint.c:1609 src/elflint.c:1901
+#, c-format
+msgid "section [%2d] '%s': sh_info not zero\n"
+msgstr ""
+
+#: src/elflint.c:1619
+#, c-format
+msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1627
+#, c-format
+msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"
+msgstr ""
+
+#: src/elflint.c:1634
+#, c-format
+msgid "section [%2d] '%s': entry %zu: unknown tag\n"
+msgstr ""
+
+#: src/elflint.c:1645
+#, c-format
+msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n"
+msgstr ""
+
+#: src/elflint.c:1655
+#, c-format
+msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n"
+msgstr ""
+
+#: src/elflint.c:1673
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"
+msgstr ""
+
+#: src/elflint.c:1695
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: pointer does not match address of section [%"
+"2d] '%s' referenced by sh_link\n"
+msgstr ""
+
+#: src/elflint.c:1738
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:1753
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must be valid offset in section [%"
+"2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:1773 src/elflint.c:1801
+#, c-format
+msgid "section [%2d] '%s': contains %s entry but not %s\n"
+msgstr ""
+
+#: src/elflint.c:1785
+#, c-format
+msgid "section [%2d] '%s': mandatory tag %s not present\n"
+msgstr ""
+
+#: src/elflint.c:1794
+#, c-format
+msgid "section [%2d] '%s': no hash section present\n"
+msgstr ""
+
+#: src/elflint.c:1809 src/elflint.c:1816
+#, c-format
+msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n"
+msgstr ""
+
+#: src/elflint.c:1826 src/elflint.c:1830
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"
+msgstr ""
+
+#: src/elflint.c:1836
+#, c-format
+msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n"
+msgstr ""
+
+#: src/elflint.c:1847 src/elflint.c:1851 src/elflint.c:1855 src/elflint.c:1859
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in prelinked executable\n"
+msgstr ""
+
+#: src/elflint.c:1871
+#, c-format
+msgid ""
+"section [%2d] '%s': only relocatable files can have extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1881
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index section not for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1886
+#, c-format
+msgid "cannot get data for symbol section\n"
+msgstr ""
+
+#: src/elflint.c:1889
+#, c-format
+msgid "section [%2d] '%s': entry size does not match Elf32_Word\n"
+msgstr ""
+
+#: src/elflint.c:1896
+#, c-format
+msgid "section [%2d] '%s': extended index table too small for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1911
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to "
+"same symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1922
+#, c-format
+msgid "symbol 0 should have zero extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1934
+#, c-format
+msgid "cannot get data for symbol %zu\n"
+msgstr ""
+
+#: src/elflint.c:1939
+#, c-format
+msgid "extended section index is %<PRIu32> but symbol index is not XINDEX\n"
+msgstr ""
+
+#: src/elflint.c:1955 src/elflint.c:1996
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"
+msgstr ""
+
+#: src/elflint.c:1967 src/elflint.c:2008
+#, c-format
+msgid "section [%2d] '%s': chain array too large\n"
+msgstr ""
+
+#: src/elflint.c:1976 src/elflint.c:2017
+#, c-format
+msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:1982
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2023
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %<PRIu64> out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2038
+#, c-format
+msgid "section [%2d] '%s': bitmask size not power of 2: %u\n"
+msgstr ""
+
+#: src/elflint.c:2049
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected at "
+"least%ld)\n"
+msgstr ""
+
+#: src/elflint.c:2057
+#, c-format
+msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n"
+msgstr ""
+
+#: src/elflint.c:2089
+#, c-format
+msgid ""
+"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"
+msgstr ""
+
+#: src/elflint.c:2110
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is "
+"undefined\n"
+msgstr ""
+
+#: src/elflint.c:2121
+#, c-format
+msgid ""
+"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+
+#: src/elflint.c:2152
+#, c-format
+msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2157
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2163
+#, c-format
+msgid "section [%2d] '%s': bitmask does not match names in the hash table\n"
+msgstr ""
+
+#: src/elflint.c:2176
+#, c-format
+msgid "section [%2d] '%s': relocatable files cannot have hash tables\n"
+msgstr ""
+
+#: src/elflint.c:2194
+#, c-format
+msgid "section [%2d] '%s': hash table not for dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2202
+#, c-format
+msgid "section [%2d] '%s': hash table entry size incorrect\n"
+msgstr ""
+
+#: src/elflint.c:2207
+#, c-format
+msgid "section [%2d] '%s': not marked to be allocated\n"
+msgstr ""
+
+#: src/elflint.c:2212
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table has not even room for initial administrative "
+"entries\n"
+msgstr ""
+
+#: src/elflint.c:2260
+#, c-format
+msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"
+msgstr ""
+
+#: src/elflint.c:2338 src/elflint.c:2342
+#, c-format
+msgid "section [%2zu] '%s': reference to symbol index 0\n"
+msgstr ""
+
+#: src/elflint.c:2349
+#, c-format
+msgid ""
+"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2361
+#, c-format
+msgid ""
+"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2377
+#, c-format
+msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n"
+msgstr ""
+
+#: src/elflint.c:2397
+#, c-format
+msgid ""
+"section [%2d] '%s': section groups only allowed in relocatable object files\n"
+msgstr ""
+
+#: src/elflint.c:2408
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol table: %s\n"
+msgstr ""
+
+#: src/elflint.c:2413
+#, c-format
+msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2419
+#, c-format
+msgid "section [%2d] '%s': invalid symbol index in sh_info\n"
+msgstr ""
+
+#: src/elflint.c:2424
+#, c-format
+msgid "section [%2d] '%s': sh_flags not zero\n"
+msgstr ""
+
+#: src/elflint.c:2431
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol for signature\n"
+msgstr ""
+
+#: src/elflint.c:2436
+#, c-format
+msgid "section [%2d] '%s': signature symbol cannot be empty string\n"
+msgstr ""
+
+#: src/elflint.c:2442
+#, c-format
+msgid "section [%2d] '%s': sh_flags not set correctly\n"
+msgstr ""
+
+#: src/elflint.c:2448
+#, c-format
+msgid "section [%2d] '%s': cannot get data: %s\n"
+msgstr ""
+
+#: src/elflint.c:2457
+#, c-format
+msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"
+msgstr ""
+
+#: src/elflint.c:2462
+#, c-format
+msgid "section [%2d] '%s': section group without flags word\n"
+msgstr ""
+
+#: src/elflint.c:2468
+#, c-format
+msgid "section [%2d] '%s': section group without member\n"
+msgstr ""
+
+#: src/elflint.c:2472
+#, c-format
+msgid "section [%2d] '%s': section group with only one member\n"
+msgstr ""
+
+#: src/elflint.c:2483
+#, c-format
+msgid "section [%2d] '%s': unknown section group flags\n"
+msgstr ""
+
+#: src/elflint.c:2495
+#, c-format
+msgid "section [%2d] '%s': section index %Zu out of range\n"
+msgstr ""
+
+#: src/elflint.c:2504
+#, c-format
+msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:2511
+#, c-format
+msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2517
+#, c-format
+msgid ""
+"section [%2d] '%s': element %Zu references section [%2d] '%s' without "
+"SHF_GROUP flag set\n"
+msgstr ""
+
+#: src/elflint.c:2524
+#, c-format
+msgid "section [%2d] '%s' is contained in more than one section group\n"
+msgstr ""
+
+#: src/elflint.c:2713
+#, c-format
+msgid ""
+"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no "
+"dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2724
+#, c-format
+msgid ""
+"section [%2d] '%s' has different number of entries than symbol table [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:2740
+#, c-format
+msgid "section [%2d] '%s': symbol %d: cannot read version data\n"
+msgstr ""
+
+#: src/elflint.c:2756
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n"
+msgstr ""
+
+#: src/elflint.c:2764
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with version\n"
+msgstr ""
+
+#: src/elflint.c:2778
+#, c-format
+msgid "section [%2d] '%s': symbol %d: invalid version index %d\n"
+msgstr ""
+
+#: src/elflint.c:2783
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for defined version\n"
+msgstr ""
+
+#: src/elflint.c:2793
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for requested version\n"
+msgstr ""
+
+#: src/elflint.c:2845
+#, c-format
+msgid "more than one version reference section present\n"
+msgstr ""
+
+#: src/elflint.c:2853 src/elflint.c:2982
+#, c-format
+msgid "section [%2d] '%s': sh_link does not link to string table\n"
+msgstr ""
+
+#: src/elflint.c:2876 src/elflint.c:3034
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong version %d\n"
+msgstr ""
+
+#: src/elflint.c:2882 src/elflint.c:3040
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:2890
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid file reference\n"
+msgstr ""
+
+#: src/elflint.c:2898
+#, c-format
+msgid "section [%2d] '%s': entry %d references unknown dependency\n"
+msgstr ""
+
+#: src/elflint.c:2910
+#, c-format
+msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:2917
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name "
+"reference\n"
+msgstr ""
+
+#: src/elflint.c:2924
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %"
+"#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:2934
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version "
+"name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2945
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"
+msgstr ""
+
+#: src/elflint.c:2961 src/elflint.c:3119
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n"
+msgstr ""
+
+#: src/elflint.c:2974
+#, c-format
+msgid "more than one version definition section present\n"
+msgstr ""
+
+#: src/elflint.c:3019
+#, c-format
+msgid "section [%2d] '%s': more than one BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3023
+#, c-format
+msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"
+msgstr ""
+
+#: src/elflint.c:3029
+#, c-format
+msgid "section [%2d] '%s': entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:3053
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid name reference\n"
+msgstr ""
+
+#: src/elflint.c:3060
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:3069
+#, c-format
+msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3088
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3103
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3125
+#, c-format
+msgid "section [%2d] '%s': no BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3141
+#, c-format
+msgid "section [%2d] '%s': unknown parent version '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3154
+#, c-format
+msgid "section [%2d] '%s': empty object attributes section\n"
+msgstr ""
+
+#: src/elflint.c:3175
+#, c-format
+msgid "section [%2d] '%s': unrecognized attribute format\n"
+msgstr ""
+
+#: src/elflint.c:3191
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3200
+#, c-format
+msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3212
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n"
+msgstr ""
+
+#: src/elflint.c:3229
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"
+msgstr ""
+
+#: src/elflint.c:3238
+#, c-format
+msgid "section [%2d] '%s': offset %zu: truncated attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3247
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3260
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3271
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3289
+#, c-format
+msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"
+msgstr ""
+
+#: src/elflint.c:3300
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n"
+msgstr ""
+
+#: src/elflint.c:3313
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3317
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: unrecognized %s attribute value %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3327
+#, c-format
+msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n"
+msgstr ""
+
+#: src/elflint.c:3333
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3422
+#, c-format
+msgid "cannot get section header of zeroth section\n"
+msgstr ""
+
+#: src/elflint.c:3426
+#, c-format
+msgid "zeroth section has nonzero name\n"
+msgstr ""
+
+#: src/elflint.c:3428
+#, c-format
+msgid "zeroth section has nonzero type\n"
+msgstr ""
+
+#: src/elflint.c:3430
+#, c-format
+msgid "zeroth section has nonzero flags\n"
+msgstr ""
+
+#: src/elflint.c:3432
+#, c-format
+msgid "zeroth section has nonzero address\n"
+msgstr ""
+
+#: src/elflint.c:3434
+#, c-format
+msgid "zeroth section has nonzero offset\n"
+msgstr ""
+
+#: src/elflint.c:3436
+#, c-format
+msgid "zeroth section has nonzero align value\n"
+msgstr ""
+
+#: src/elflint.c:3438
+#, c-format
+msgid "zeroth section has nonzero entry size value\n"
+msgstr ""
+
+#: src/elflint.c:3441
+#, c-format
+msgid ""
+"zeroth section has nonzero size value while ELF header has nonzero shnum "
+"value\n"
+msgstr ""
+
+#: src/elflint.c:3445
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in shstrndx\n"
+msgstr ""
+
+#: src/elflint.c:3449
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in phnum\n"
+msgstr ""
+
+#: src/elflint.c:3466
+#, c-format
+msgid "cannot get section header for section [%2zu] '%s': %s\n"
+msgstr ""
+
+#: src/elflint.c:3475
+#, c-format
+msgid "section [%2zu]: invalid name\n"
+msgstr ""
+
+#: src/elflint.c:3502
+#, c-format
+msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3518
+#, c-format
+msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3535
+#, c-format
+msgid ""
+"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3553
+#, c-format
+msgid "section [%2zu] '%s' present in object file\n"
+msgstr ""
+
+#: src/elflint.c:3559 src/elflint.c:3591
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"
+msgstr ""
+
+#: src/elflint.c:3564 src/elflint.c:3596
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable "
+"segments\n"
+msgstr ""
+
+#: src/elflint.c:3572
+#, c-format
+msgid ""
+"section [%2zu] '%s' is extension section index table in non-object file\n"
+msgstr ""
+
+#: src/elflint.c:3615
+#, c-format
+msgid "section [%2zu] '%s': size not multiple of entry size\n"
+msgstr ""
+
+#: src/elflint.c:3620
+#, c-format
+msgid "cannot get section header\n"
+msgstr ""
+
+#: src/elflint.c:3630
+#, c-format
+msgid "section [%2zu] '%s' has unsupported type %d\n"
+msgstr ""
+
+#: src/elflint.c:3644
+#, c-format
+msgid ""
+"section [%2zu] '%s' contains invalid processor-specific flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3651
+#, c-format
+msgid "section [%2zu] '%s' contains unknown flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3659
+#, c-format
+msgid "section [%2zu] '%s': thread-local data sections address not zero\n"
+msgstr ""
+
+#: src/elflint.c:3667
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in link value\n"
+msgstr ""
+
+#: src/elflint.c:3672
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in info value\n"
+msgstr ""
+
+#: src/elflint.c:3679
+#, c-format
+msgid "section [%2zu] '%s': strings flag set without merge flag\n"
+msgstr ""
+
+#: src/elflint.c:3684
+#, c-format
+msgid "section [%2zu] '%s': merge flag set but entry size is zero\n"
+msgstr ""
+
+#: src/elflint.c:3702
+#, c-format
+msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n"
+msgstr ""
+
+#: src/elflint.c:3711
+#, c-format
+msgid "section [%2zu] '%s' is both executable and writable\n"
+msgstr ""
+
+#: src/elflint.c:3738
+#, c-format
+msgid ""
+"section [%2zu] '%s' not fully contained in segment of program header entry %"
+"d\n"
+msgstr ""
+
+#: src/elflint.c:3746
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:3755
+#, c-format
+msgid ""
+"section [%2zu] '%s' has not type NOBITS but is not read from the file in "
+"segment of program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:3766
+#, c-format
+msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:3776
+#, c-format
+msgid "section [%2zu] '%s' is writable in unwritable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:3786
+#, c-format
+msgid ""
+"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:3792
+#, c-format
+msgid ""
+"section [%2zu] '%s': ELF header says this is the section header string table "
+"but type is not SHT_TYPE\n"
+msgstr ""
+
+#: src/elflint.c:3800
+#, c-format
+msgid ""
+"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"
+msgstr ""
+
+#: src/elflint.c:3851
+#, c-format
+msgid "more than one version symbol table present\n"
+msgstr ""
+
+#: src/elflint.c:3874
+#, c-format
+msgid "INTERP program header entry but no .interp section\n"
+msgstr ""
+
+#: src/elflint.c:3885
+#, c-format
+msgid ""
+"loadable segment [%u] is executable but contains no executable sections\n"
+msgstr ""
+
+#: src/elflint.c:3891
+#, c-format
+msgid "loadable segment [%u] is writable but contains no writable sections\n"
+msgstr ""
+
+#: src/elflint.c:3902
+#, c-format
+msgid ""
+"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section "
+"exist\n"
+msgstr ""
+
+#: src/elflint.c:3915
+#, c-format
+msgid "duplicate version index %d\n"
+msgstr ""
+
+#: src/elflint.c:3929
+#, c-format
+msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"
+msgstr ""
+
+#: src/elflint.c:3978
+#, c-format
+msgid "phdr[%d]: unknown core file note type %<PRIu32> at offset %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3982
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown core file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4005
+#, c-format
+msgid "phdr[%d]: unknown object file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4009
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown object file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4026
+#, c-format
+msgid "phdr[%d]: no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4045
+#, c-format
+msgid "phdr[%d]: cannot get content of note section: %s\n"
+msgstr ""
+
+#: src/elflint.c:4048
+#, c-format
+msgid "phdr[%d]: extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4069
+#, c-format
+msgid "section [%2d] '%s': no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4076
+#, c-format
+msgid "section [%2d] '%s': cannot get content of note section\n"
+msgstr ""
+
+#: src/elflint.c:4079
+#, c-format
+msgid "section [%2d] '%s': extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4097
+#, c-format
+msgid ""
+"only executables, shared objects, and core files can have program headers\n"
+msgstr ""
+
+#: src/elflint.c:4112
+#, c-format
+msgid "cannot get program header entry %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:4121
+#, c-format
+msgid "program header entry %d: unknown program header entry type %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:4132
+#, c-format
+msgid "more than one INTERP entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4140
+#, c-format
+msgid "more than one TLS entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4147
+#, c-format
+msgid "static executable cannot have dynamic sections\n"
+msgstr ""
+
+#: src/elflint.c:4161
+#, c-format
+msgid "dynamic section reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4164
+#, c-format
+msgid "dynamic section size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4174
+#, c-format
+msgid "more than one GNU_RELRO entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4195
+#, c-format
+msgid "loadable segment GNU_RELRO applies to is not writable\n"
+msgstr ""
+
+#: src/elflint.c:4198
+#, c-format
+msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"
+msgstr ""
+
+#: src/elflint.c:4206 src/elflint.c:4229
+#, c-format
+msgid "%s segment not contained in a loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:4235
+#, c-format
+msgid "program header offset in ELF header and PHDR entry do not match"
+msgstr ""
+
+#: src/elflint.c:4259
+#, c-format
+msgid "call frame search table reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4262
+#, c-format
+msgid "call frame search table size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4275
+#, c-format
+msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"
+msgstr ""
+
+#: src/elflint.c:4283
+#, c-format
+msgid "call frame search table must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4286
+#, c-format
+msgid "section [%2zu] '%s' must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4290
+#, c-format
+msgid "call frame search table must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4293
+#, c-format
+msgid "section [%2zu] '%s' must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4298
+#, c-format
+msgid "call frame search table must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4301
+#, c-format
+msgid "section [%2zu] '%s' must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4312
+#, c-format
+msgid "program header entry %d: file size greater than memory size\n"
+msgstr ""
+
+#: src/elflint.c:4319
+#, c-format
+msgid "program header entry %d: alignment not a power of 2\n"
+msgstr ""
+
+#: src/elflint.c:4322
+#, c-format
+msgid ""
+"program header entry %d: file offset and virtual address not module of "
+"alignment\n"
+msgstr ""
+
+#: src/elflint.c:4335
+#, c-format
+msgid ""
+"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME "
+"program header entry"
+msgstr ""
+
+#: src/elflint.c:4369
+#, c-format
+msgid "cannot read ELF header: %s\n"
+msgstr ""
+
+#: src/elflint.c:4395
+#, c-format
+msgid "text relocation flag set but not needed\n"
+msgstr ""
+
+#: src/findtextrel.c:70
+msgid "Input Selection:"
+msgstr ""
+
+#: src/findtextrel.c:71
+msgid "Prepend PATH to all file names"
+msgstr ""
+
+#: src/findtextrel.c:73
+msgid "Use PATH as root of debuginfo hierarchy"
+msgstr ""
+
+#: src/findtextrel.c:80
+msgid "Locate source of text relocations in FILEs (a.out by default)."
+msgstr ""
+
+#: src/findtextrel.c:84 src/nm.c:111 src/objdump.c:80 src/size.c:92
+#: src/strings.c:92 src/strip.c:97
+msgid "[FILE...]"
+msgstr ""
+
+#: src/findtextrel.c:246
+#, c-format
+msgid "cannot get ELF header '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:257
+#, c-format
+msgid "'%s' is not a DSO or PIE"
+msgstr ""
+
+#: src/findtextrel.c:274
+#, c-format
+msgid "getting get section header of section %zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:292
+#, c-format
+msgid "cannot read dynamic section: %s"
+msgstr ""
+
+#: src/findtextrel.c:307
+#, c-format
+msgid "no text relocations reported in '%s'"
+msgstr ""
+
+#: src/findtextrel.c:319
+#, c-format
+msgid "while reading ELF file"
+msgstr ""
+
+#: src/findtextrel.c:328 src/findtextrel.c:345
+#, c-format
+msgid "cannot get program header index at offset %d: %s"
+msgstr ""
+
+#: src/findtextrel.c:397
+#, c-format
+msgid "cannot get section header of section %Zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:409
+#, c-format
+msgid "cannot get symbol table section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:429 src/findtextrel.c:452
+#, c-format
+msgid "cannot get relocation at index %d in section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:517
+#, c-format
+msgid "%s not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:570
+#, c-format
+msgid ""
+"the file containing the function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:577 src/findtextrel.c:597
+#, c-format
+msgid ""
+"the file containing the function '%s' might not be compiled with -fpic/-"
+"fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:585
+#, c-format
+msgid ""
+"either the file containing the function '%s' or the file containing the "
+"function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:605
+#, c-format
+msgid ""
+"a relocation modifies memory at offset %llu in a write-protected segment\n"
+msgstr ""
+
+#: src/i386_ld.c:210
+#, c-format
+msgid "cannot allocate PLT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:232
+#, c-format
+msgid "cannot allocate PLTREL section: %s"
+msgstr ""
+
+#: src/i386_ld.c:253
+#, c-format
+msgid "cannot allocate GOT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:274
+#, c-format
+msgid "cannot allocate GOTPLT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:661
+#, c-format
+msgid "initial-executable TLS relocation cannot be used "
+msgstr ""
+
+#: src/ld.c:87
+msgid "Input File Control:"
+msgstr ""
+
+#: src/ld.c:89
+msgid "Include whole archives in the output from now on."
+msgstr ""
+
+#: src/ld.c:91
+msgid "Stop including the whole archives in the output."
+msgstr ""
+
+#: src/ld.c:92 src/ld.c:106 src/ld.c:184
+msgid "FILE"
+msgstr ""
+
+#: src/ld.c:93
+msgid "Start a group."
+msgstr ""
+
+#: src/ld.c:94
+msgid "End a group."
+msgstr ""
+
+#: src/ld.c:95
+msgid "PATH"
+msgstr ""
+
+#: src/ld.c:96
+msgid "Add PATH to list of directories files are searched in."
+msgstr ""
+
+#: src/ld.c:98
+msgid "Only set DT_NEEDED for following dynamic libs if actually used"
+msgstr ""
+
+#: src/ld.c:100
+msgid "Always set DT_NEEDED for following dynamic libs"
+msgstr ""
+
+#: src/ld.c:102
+msgid "Ignore LD_LIBRARY_PATH environment variable."
+msgstr ""
+
+#: src/ld.c:105
+msgid "Output File Control:"
+msgstr ""
+
+#: src/ld.c:106
+msgid "Place output in FILE."
+msgstr ""
+
+#: src/ld.c:109
+msgid "Object is marked to not use default search path at runtime."
+msgstr ""
+
+#: src/ld.c:111
+msgid "Same as --whole-archive."
+msgstr ""
+
+#: src/ld.c:112
+msgid ""
+"Default rules of extracting from archive; weak references are not enough."
+msgstr ""
+
+#: src/ld.c:116
+msgid "Weak references cause extraction from archive."
+msgstr ""
+
+#: src/ld.c:118
+msgid "Allow multiple definitions; first is used."
+msgstr ""
+
+#: src/ld.c:120
+msgid "Disallow/allow undefined symbols in DSOs."
+msgstr ""
+
+#: src/ld.c:123
+msgid "Object requires immediate handling of $ORIGIN."
+msgstr ""
+
+#: src/ld.c:125
+msgid "Relocation will not be processed lazily."
+msgstr ""
+
+#: src/ld.c:127
+msgid "Object cannot be unloaded at runtime."
+msgstr ""
+
+#: src/ld.c:129
+msgid "Mark object to be initialized first."
+msgstr ""
+
+#: src/ld.c:131
+msgid "Enable/disable lazy-loading flag for following dependencies."
+msgstr ""
+
+#: src/ld.c:133
+msgid "Mark object as not loadable with 'dlopen'."
+msgstr ""
+
+#: src/ld.c:135
+msgid "Ignore/record dependencies on unused DSOs."
+msgstr ""
+
+#: src/ld.c:137
+msgid "Generated DSO will be a system library."
+msgstr ""
+
+#: src/ld.c:138
+msgid "ADDRESS"
+msgstr ""
+
+#: src/ld.c:138
+msgid "Set entry point address."
+msgstr ""
+
+#: src/ld.c:141
+msgid "Do not link against shared libraries."
+msgstr ""
+
+#: src/ld.c:144
+msgid "Prefer linking against shared libraries."
+msgstr ""
+
+#: src/ld.c:145
+msgid "Export all dynamic symbols."
+msgstr ""
+
+#: src/ld.c:146
+msgid "Strip all symbols."
+msgstr ""
+
+#: src/ld.c:147
+msgid "Strip debugging symbols."
+msgstr ""
+
+#: src/ld.c:149
+msgid "Assume pagesize for the target system to be SIZE."
+msgstr ""
+
+#: src/ld.c:151
+msgid "Set runtime DSO search path."
+msgstr ""
+
+#: src/ld.c:154
+msgid "Set link time DSO search path."
+msgstr ""
+
+#: src/ld.c:155
+msgid "Generate dynamic shared object."
+msgstr ""
+
+#: src/ld.c:156
+msgid "Generate relocatable object."
+msgstr ""
+
+#: src/ld.c:159
+msgid "Causes symbol not assigned to a version be reduced to local."
+msgstr ""
+
+#: src/ld.c:160
+msgid "Remove unused sections."
+msgstr ""
+
+#: src/ld.c:163
+msgid "Don't remove unused sections."
+msgstr ""
+
+#: src/ld.c:164
+msgid "Set soname of shared object."
+msgstr ""
+
+#: src/ld.c:165
+msgid "Set the dynamic linker name."
+msgstr ""
+
+#: src/ld.c:168
+msgid "Add/suppress addition indentifying link-editor to .comment section."
+msgstr ""
+
+#: src/ld.c:171
+msgid "Create .eh_frame_hdr section"
+msgstr ""
+
+#: src/ld.c:173
+msgid "Set hash style to sysv, gnu or both."
+msgstr ""
+
+#: src/ld.c:175
+msgid "Generate build ID note (md5, sha1 (default), uuid)."
+msgstr ""
+
+#: src/ld.c:177
+msgid "Linker Operation Control:"
+msgstr ""
+
+#: src/ld.c:178
+msgid "Verbose messages."
+msgstr ""
+
+#: src/ld.c:179
+msgid "Trace file opens."
+msgstr ""
+
+#: src/ld.c:181
+msgid "Trade speed for less memory usage"
+msgstr ""
+
+#: src/ld.c:182
+msgid "LEVEL"
+msgstr ""
+
+#: src/ld.c:183
+msgid "Set optimization level to LEVEL."
+msgstr ""
+
+#: src/ld.c:184
+msgid "Use linker script in FILE."
+msgstr ""
+
+#: src/ld.c:187
+msgid "Select to get parser debug information"
+msgstr ""
+
+#: src/ld.c:190
+msgid "Read version information from FILE."
+msgstr ""
+
+#: src/ld.c:191
+msgid "Set emulation to NAME."
+msgstr ""
+
+#: src/ld.c:197
+msgid "Combine object and archive files."
+msgstr ""
+
+#: src/ld.c:200
+msgid "[FILE]..."
+msgstr ""
+
+#: src/ld.c:333
+#, c-format
+msgid "At least one input file needed"
+msgstr ""
+
+#: src/ld.c:349
+#, c-format
+msgid "error while preparing linking"
+msgstr ""
+
+#: src/ld.c:356
+#, c-format
+msgid "cannot open linker script '%s'"
+msgstr ""
+
+#: src/ld.c:397
+#, c-format
+msgid "-( without matching -)"
+msgstr ""
+
+#: src/ld.c:572 src/ld.c:610
+#, c-format
+msgid "only one option of -G and -r is allowed"
+msgstr ""
+
+#: src/ld.c:594
+#, c-format
+msgid "more than one '-m' parameter"
+msgstr ""
+
+#: src/ld.c:604 src/ld.c:1013
+#, c-format
+msgid "unknown option `-%c %s'"
+msgstr ""
+
+#: src/ld.c:646
+#, c-format
+msgid "invalid page size value '%s': ignored"
+msgstr ""
+
+#: src/ld.c:687
+#, c-format
+msgid "invalid hash style '%s'"
+msgstr ""
+
+#: src/ld.c:697
+#, c-format
+msgid "invalid build-ID style '%s'"
+msgstr ""
+
+#: src/ld.c:785
+#, c-format
+msgid "More than one output file name given."
+msgstr ""
+
+#: src/ld.c:802
+#, c-format
+msgid "Invalid optimization level `%s'"
+msgstr ""
+
+#: src/ld.c:850
+#, c-format
+msgid "nested -( -) groups are not allowed"
+msgstr ""
+
+#: src/ld.c:869
+#, c-format
+msgid "-) without matching -("
+msgstr ""
+
+#: src/ld.c:1046
+#, c-format
+msgid "unknown option '-%c %s'"
+msgstr ""
+
+#: src/ld.c:1150
+#, c-format
+msgid "could not find input file to determine output file format"
+msgstr ""
+
+#: src/ld.c:1152
+#, c-format
+msgid "try again with an appropriate '-m' parameter"
+msgstr ""
+
+#: src/ld.c:1446
+#, c-format
+msgid "cannot read version script '%s'"
+msgstr ""
+
+#: src/ld.c:1512 src/ld.c:1551
+#, c-format
+msgid "duplicate definition of '%s' in linker script"
+msgstr ""
+
+#: src/ldgeneric.c:209 src/ldgeneric.c:5151
+#, c-format
+msgid "cannot create string table"
+msgstr ""
+
+#: src/ldgeneric.c:255
+#, c-format
+msgid "cannot load ld backend library '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:265
+#, c-format
+msgid "cannot find init function in ld backend library '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:310
+#, c-format
+msgid "%s listed more than once as input"
+msgstr ""
+
+#: src/ldgeneric.c:424
+#, c-format
+msgid "%s (for -l%s)\n"
+msgstr ""
+
+#: src/ldgeneric.c:425
+#, c-format
+msgid "%s (for DT_NEEDED %s)\n"
+msgstr ""
+
+#: src/ldgeneric.c:573
+#, c-format
+msgid "Warning: type of `%s' changed from %s in %s to %s in %s"
+msgstr ""
+
+#: src/ldgeneric.c:586
+#, c-format
+msgid "Warning: size of `%s' changed from %<PRIu64> in %s to %<PRIu64> in %s"
+msgstr ""
+
+#: src/ldgeneric.c:661 src/ldgeneric.c:1122 src/readelf.c:629 src/strip.c:543
+#, c-format
+msgid "cannot determine number of sections: %s"
+msgstr ""
+
+#: src/ldgeneric.c:677
+#, c-format
+msgid "(%s+%#<PRIx64>): multiple definition of %s `%s'\n"
+msgstr ""
+
+#: src/ldgeneric.c:700
+#, c-format
+msgid "(%s+%#<PRIx64>): first defined here\n"
+msgstr ""
+
+#: src/ldgeneric.c:819
+#, c-format
+msgid "%s: cannot get section group data: %s"
+msgstr ""
+
+#: src/ldgeneric.c:840
+#, c-format
+msgid "%s: section '%s' with group flag set does not belong to any group"
+msgstr ""
+
+#: src/ldgeneric.c:885
+#, c-format
+msgid "%s: section [%2d] '%s' is not in the correct section group"
+msgstr ""
+
+#: src/ldgeneric.c:1156 src/ldgeneric.c:1413 src/ldgeneric.c:1422
+#: src/ldgeneric.c:1481 src/ldgeneric.c:1490 src/ldgeneric.c:1753
+#: src/ldgeneric.c:2005
+#, c-format
+msgid "%s: invalid ELF file (%s:%d)\n"
+msgstr ""
+
+#: src/ldgeneric.c:1250
+#, c-format
+msgid "%s: only files of type ET_REL might contain section groups"
+msgstr ""
+
+#: src/ldgeneric.c:1302
+#, c-format
+msgid "%s: cannot determine signature of section group [%2zd] '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:1314
+#, c-format
+msgid "%s: cannot get content of section group [%2zd] '%s': %s'"
+msgstr ""
+
+#: src/ldgeneric.c:1328
+#, c-format
+msgid ""
+"%s: group member %zu of section group [%2zd] '%s' has too high index: %"
+"<PRIu32>"
+msgstr ""
+
+#: src/ldgeneric.c:1350
+#, c-format
+msgid "%s: section '%s' has unknown type: %d"
+msgstr ""
+
+#: src/ldgeneric.c:1729
+#, c-format
+msgid "cannot get descriptor for ELF file (%s:%d): %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:1899
+#, c-format
+msgid "cannot read archive `%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:2020
+#, c-format
+msgid "file of type %s cannot be linked in\n"
+msgstr ""
+
+#: src/ldgeneric.c:2032
+#, c-format
+msgid "%s: input file incompatible with ELF machine type %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:2044
+#, c-format
+msgid "%s: cannot get section header string table index: %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:2073
+#, c-format
+msgid "cannot use DSO '%s' when generating relocatable object file"
+msgstr ""
+
+#: src/ldgeneric.c:2158
+#, c-format
+msgid "input file '%s' ignored"
+msgstr ""
+
+#: src/ldgeneric.c:2372
+#, c-format
+msgid "undefined symbol `%s' in %s"
+msgstr ""
+
+#: src/ldgeneric.c:2702
+#, c-format
+msgid "cannot create ELF descriptor for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:2709
+#, c-format
+msgid "could not create ELF header for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:3224 src/ldgeneric.c:3294 src/ldgeneric.c:3330
+#: src/ldgeneric.c:4457 src/ldgeneric.c:4506 src/ldgeneric.c:4538
+#: src/ldgeneric.c:4773 src/ldgeneric.c:4828 src/ldgeneric.c:5075
+#: src/ldgeneric.c:5131 src/ldgeneric.c:5600 src/ldgeneric.c:5612
+#, c-format
+msgid "cannot create section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:3444
+#, c-format
+msgid "address computation expression contains variable '%s'"
+msgstr ""
+
+#: src/ldgeneric.c:3489
+#, c-format
+msgid ""
+"argument '%<PRIuMAX>' of ALIGN in address computation expression is no power "
+"of two"
+msgstr ""
+
+#: src/ldgeneric.c:3684
+#, c-format
+msgid "cannot find entry symbol '%s': defaulting to %#0*<PRIx64>"
+msgstr ""
+
+#: src/ldgeneric.c:3690
+#, c-format
+msgid "no entry symbol specified: defaulting to %#0*<PRIx64>"
+msgstr ""
+
+#: src/ldgeneric.c:3920
+#, c-format
+msgid "cannot create GNU hash table section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4071
+#, c-format
+msgid "cannot create hash table section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4114
+#, c-format
+msgid "cannot create build ID section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4191
+#, c-format
+msgid "cannot convert section data to file format: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4200
+#, c-format
+msgid "cannot convert section data to memory format: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4261
+#, c-format
+msgid "cannot read enough data for UUID"
+msgstr ""
+
+#: src/ldgeneric.c:4358 src/ldgeneric.c:4379 src/ldgeneric.c:4408
+#: src/ldgeneric.c:6062
+#, c-format
+msgid "cannot create symbol table for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5300 src/ldgeneric.c:5852
+#, c-format
+msgid "section index too large in dynamic symbol table"
+msgstr ""
+
+#: src/ldgeneric.c:5745
+#, c-format
+msgid "cannot create versioning section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5818
+#, c-format
+msgid "cannot create dynamic symbol table for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5994
+#, c-format
+msgid "cannot create versioning data: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6094 src/ldgeneric.c:6107 src/ldgeneric.c:6171
+#: src/ldgeneric.c:6179
+#, c-format
+msgid "cannot create section header string section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6101
+#, c-format
+msgid "cannot create section header string section"
+msgstr ""
+
+#: src/ldgeneric.c:6259
+#, c-format
+msgid "cannot create program header: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6267
+#, c-format
+msgid "while determining file layout: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6388
+#, c-format
+msgid "internal error: non-nobits section follows nobits section"
+msgstr ""
+
+#: src/ldgeneric.c:6925
+#, c-format
+msgid "cannot get header of 0th section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6941 src/unstrip.c:1808
+#, c-format
+msgid "cannot update ELF header: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6972
+#, c-format
+msgid "linker backend didn't specify function to relocate section"
+msgstr ""
+
+#: src/ldgeneric.c:6984
+#, c-format
+msgid "while writing output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6989
+#, c-format
+msgid "while finishing output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6995
+#, c-format
+msgid "cannot stat output file"
+msgstr ""
+
+#: src/ldgeneric.c:7011
+#, c-format
+msgid "WARNING: temporary output file overwritten before linking finished"
+msgstr ""
+
+#: src/ldgeneric.c:7064 src/ldgeneric.c:7075 src/ldgeneric.c:7086
+#: src/ldgeneric.c:7097 src/ldgeneric.c:7116 src/ldgeneric.c:7129
+#: src/ldgeneric.c:7141
+#, c-format
+msgid "no machine specific '%s' implementation"
+msgstr ""
+
+#: src/ldscript.y:178
+msgid "mode for segment invalid\n"
+msgstr ""
+
+#: src/ldscript.y:465
+#, c-format
+msgid "while reading version script '%s': %s at line %d"
+msgstr ""
+
+#: src/ldscript.y:466
+#, c-format
+msgid "while reading linker script '%s': %s at line %d"
+msgstr ""
+
+#: src/ldscript.y:745
+#, c-format
+msgid "symbol '%s' is declared both local and global for unnamed version"
+msgstr ""
+
+#: src/ldscript.y:747
+#, c-format
+msgid "symbol '%s' is declared both local and global for version '%s'"
+msgstr ""
+
+#: src/ldscript.y:767 src/ldscript.y:774
+#, c-format
+msgid "default visibility set as local and global"
+msgstr ""
+
+#: src/nm.c:74 src/strip.c:73
+msgid "Output selection:"
+msgstr ""
+
+#: src/nm.c:75
+msgid "Display debugger-only symbols"
+msgstr ""
+
+#: src/nm.c:76
+msgid "Display only defined symbols"
+msgstr ""
+
+#: src/nm.c:79
+msgid "Display dynamic symbols instead of normal symbols"
+msgstr ""
+
+#: src/nm.c:80
+msgid "Display only external symbols"
+msgstr ""
+
+#: src/nm.c:81
+msgid "Display only undefined symbols"
+msgstr ""
+
+#: src/nm.c:83
+msgid "Include index for symbols from archive members"
+msgstr ""
+
+#: src/nm.c:85 src/size.c:66
+msgid "Output format:"
+msgstr ""
+
+#: src/nm.c:87
+msgid "Print name of the input file before every symbol"
+msgstr ""
+
+#: src/nm.c:90
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd', `sysv' or `posix'.  The "
+"default is `sysv'"
+msgstr ""
+
+#: src/nm.c:92
+msgid "Same as --format=bsd"
+msgstr ""
+
+#: src/nm.c:93
+msgid "Same as --format=posix"
+msgstr ""
+
+#: src/nm.c:94 src/size.c:72
+msgid "Use RADIX for printing symbol values"
+msgstr ""
+
+#: src/nm.c:95
+msgid "Mark weak symbols"
+msgstr ""
+
+#: src/nm.c:96
+msgid "Print size of defined symbols"
+msgstr ""
+
+#: src/nm.c:98 src/size.c:80 src/strip.c:78 src/unstrip.c:81
+msgid "Output options:"
+msgstr ""
+
+#: src/nm.c:99
+msgid "Sort symbols numerically by address"
+msgstr ""
+
+#: src/nm.c:101
+msgid "Do not sort the symbols"
+msgstr ""
+
+#: src/nm.c:102
+msgid "Reverse the sense of the sort"
+msgstr ""
+
+#: src/nm.c:108
+msgid "List symbols from FILEs (a.out by default)."
+msgstr ""
+
+#: src/nm.c:136 src/objdump.c:105 src/size.c:117 src/strip.c:121
+#, c-format
+msgid "%s: INTERNAL ERROR %d (%s-%s): %s"
+msgstr ""
+
+#: src/nm.c:380 src/nm.c:392 src/size.c:317 src/size.c:326 src/size.c:337
+#: src/strip.c:1816
+#, c-format
+msgid "while closing '%s'"
+msgstr ""
+
+#: src/nm.c:402 src/objdump.c:296 src/strip.c:359
+#, c-format
+msgid "%s: File format not recognized"
+msgstr ""
+
+#: src/nm.c:442
+msgid ""
+"\n"
+"Archive index:"
+msgstr ""
+
+#: src/nm.c:451
+#, c-format
+msgid "invalid offset %zu for symbol %s"
+msgstr ""
+
+#: src/nm.c:456
+#, c-format
+msgid "%s in %s\n"
+msgstr ""
+
+#: src/nm.c:464
+#, c-format
+msgid "cannot reset archive offset to beginning"
+msgstr ""
+
+#: src/nm.c:488 src/objdump.c:344
+#, c-format
+msgid "%s%s%s: file format not recognized"
+msgstr ""
+
+#: src/nm.c:700
+#, c-format
+msgid "cannot create search tree"
+msgstr ""
+
+#: src/nm.c:740 src/nm.c:1002 src/objdump.c:744 src/readelf.c:885
+#: src/readelf.c:1028 src/readelf.c:1169 src/readelf.c:1351 src/readelf.c:1549
+#: src/readelf.c:1735 src/readelf.c:1945 src/readelf.c:2199 src/readelf.c:2265
+#: src/readelf.c:2343 src/readelf.c:2841 src/readelf.c:2877 src/readelf.c:2939
+#: src/readelf.c:6493 src/readelf.c:7387 src/readelf.c:7534 src/readelf.c:7604
+#: src/size.c:425 src/size.c:499 src/strip.c:483
+#, c-format
+msgid "cannot get section header string table index"
+msgstr ""
+
+#: src/nm.c:766
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s:\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:768
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s[%s]:\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:771
+#, c-format
+msgid ""
+"%*s%-*s %-*s Class  Type     %-*s %*s Section\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:1012
+#, c-format
+msgid "%s: entry size in section `%s' is not what we expect"
+msgstr ""
+
+#: src/nm.c:1016
+#, c-format
+msgid "%s: size of section `%s' is not multiple of entry size"
+msgstr ""
+
+#: src/nm.c:1255
+#, c-format
+msgid "%s%s%s%s: Invalid operation"
+msgstr ""
+
+#: src/nm.c:1312
+#, c-format
+msgid "%s%s%s: no symbols"
+msgstr ""
+
+#: src/objdump.c:61
+msgid "Mode selection:"
+msgstr ""
+
+#: src/objdump.c:62
+msgid "Display relocation information."
+msgstr ""
+
+#: src/objdump.c:64
+msgid "Display the full contents of all sections requested"
+msgstr ""
+
+#: src/objdump.c:66
+msgid "Display assembler code of executable sections"
+msgstr ""
+
+#: src/objdump.c:68
+msgid "Output option selection:"
+msgstr ""
+
+#: src/objdump.c:70
+msgid "Only display information for section NAME."
+msgstr ""
+
+#: src/objdump.c:76
+msgid "Show information from FILEs (a.out by default)."
+msgstr ""
+
+#: src/objdump.c:236 src/readelf.c:430
+msgid "No operation specified.\n"
+msgstr ""
+
+#: src/objdump.c:274 src/objdump.c:286
+#, c-format
+msgid "while close `%s'"
+msgstr ""
+
+#: src/objdump.c:379 src/readelf.c:1644 src/readelf.c:1818
+msgid "INVALID SYMBOL"
+msgstr ""
+
+#: src/objdump.c:394 src/readelf.c:1675 src/readelf.c:1851
+msgid "INVALID SECTION"
+msgstr ""
+
+#: src/objdump.c:510
+#, c-format
+msgid ""
+"\n"
+"RELOCATION RECORDS FOR [%s]:\n"
+"%-*s TYPE                 VALUE\n"
+msgstr ""
+
+#: src/objdump.c:513
+msgid "OFFSET"
+msgstr ""
+
+#: src/objdump.c:576
+#, c-format
+msgid "Contents of section %s:\n"
+msgstr ""
+
+#: src/objdump.c:676
+#, c-format
+msgid "cannot disassemble"
+msgstr ""
+
+#: src/ranlib.c:74
+msgid "Generate an index to speed access to archives."
+msgstr ""
+
+#: src/ranlib.c:77
+msgid "ARCHIVE"
+msgstr ""
+
+#: src/ranlib.c:116
+#, c-format
+msgid "Archive name required"
+msgstr ""
+
+#: src/ranlib.c:194
+#, c-format
+msgid "'%s' is no archive"
+msgstr ""
+
+#: src/ranlib.c:229
+#, c-format
+msgid "error while freeing sub-ELF descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:73
+msgid "ELF output selection:"
+msgstr ""
+
+#: src/readelf.c:75
+msgid "All these plus -p .strtab -p .dynstr -p .comment"
+msgstr ""
+
+#: src/readelf.c:76
+msgid "Display the dynamic segment"
+msgstr ""
+
+#: src/readelf.c:77
+msgid "Display the ELF file header"
+msgstr ""
+
+#: src/readelf.c:79
+msgid "Display histogram of bucket list lengths"
+msgstr ""
+
+#: src/readelf.c:80
+msgid "Display the program headers"
+msgstr ""
+
+#: src/readelf.c:82
+msgid "Display relocations"
+msgstr ""
+
+#: src/readelf.c:83
+msgid "Display the sections' headers"
+msgstr ""
+
+#: src/readelf.c:85
+msgid "Display the symbol table"
+msgstr ""
+
+#: src/readelf.c:86
+msgid "Display versioning information"
+msgstr ""
+
+#: src/readelf.c:87
+msgid "Display the ELF notes"
+msgstr ""
+
+#: src/readelf.c:89
+msgid "Display architecture specific information, if any"
+msgstr ""
+
+#: src/readelf.c:91
+msgid "Display sections for exception handling"
+msgstr ""
+
+#: src/readelf.c:93
+msgid "Additional output selection:"
+msgstr ""
+
+#: src/readelf.c:95
+msgid ""
+"Display DWARF section content.  SECTION can be one of abbrev, aranges, "
+"frame, info, loc, line, ranges, pubnames, str, macinfo, or exception"
+msgstr ""
+
+#: src/readelf.c:99
+msgid "Dump the uninterpreted contents of SECTION, by number or name"
+msgstr ""
+
+#: src/readelf.c:101
+msgid "Print string contents of sections"
+msgstr ""
+
+#: src/readelf.c:104
+msgid "Display the symbol index of an archive"
+msgstr ""
+
+#: src/readelf.c:106
+msgid "Output control:"
+msgstr ""
+
+#: src/readelf.c:108
+msgid "Do not find symbol names for addresses in DWARF data"
+msgstr ""
+
+#: src/readelf.c:114
+msgid "Print information from ELF file in human-readable form."
+msgstr ""
+
+#: src/readelf.c:401
+#, c-format
+msgid "Unknown DWARF debug section `%s'.\n"
+msgstr ""
+
+#: src/readelf.c:465
+#, c-format
+msgid "cannot generate Elf descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:477
+#, c-format
+msgid "'%s' is not an archive, cannot print archive index"
+msgstr ""
+
+#: src/readelf.c:482
+#, c-format
+msgid "error while closing Elf descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:574
+#, c-format
+msgid "cannot stat input file"
+msgstr ""
+
+#: src/readelf.c:576
+#, c-format
+msgid "input file is empty"
+msgstr ""
+
+#: src/readelf.c:578
+#, c-format
+msgid "failed reading '%s': %s"
+msgstr ""
+
+#: src/readelf.c:614
+#, c-format
+msgid "cannot read ELF header: %s"
+msgstr ""
+
+#: src/readelf.c:622
+#, c-format
+msgid "cannot create EBL handle"
+msgstr ""
+
+#: src/readelf.c:635
+#, c-format
+msgid "cannot determine number of program headers: %s"
+msgstr ""
+
+#: src/readelf.c:721
+msgid "NONE (None)"
+msgstr ""
+
+#: src/readelf.c:722
+msgid "REL (Relocatable file)"
+msgstr ""
+
+#: src/readelf.c:723
+msgid "EXEC (Executable file)"
+msgstr ""
+
+#: src/readelf.c:724
+msgid "DYN (Shared object file)"
+msgstr ""
+
+#: src/readelf.c:725
+msgid "CORE (Core file)"
+msgstr ""
+
+#: src/readelf.c:730
+#, c-format
+msgid "OS Specific: (%x)\n"
+msgstr ""
+
+#: src/readelf.c:732
+#, c-format
+msgid "Processor Specific: (%x)\n"
+msgstr ""
+
+#: src/readelf.c:742
+msgid ""
+"ELF Header:\n"
+"  Magic:  "
+msgstr ""
+
+#: src/readelf.c:746
+#, c-format
+msgid ""
+"\n"
+"  Class:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:751
+#, c-format
+msgid "  Data:                              %s\n"
+msgstr ""
+
+#: src/readelf.c:757
+#, c-format
+msgid "  Ident Version:                     %hhd %s\n"
+msgstr ""
+
+#: src/readelf.c:759 src/readelf.c:776
+msgid "(current)"
+msgstr ""
+
+#: src/readelf.c:763
+#, c-format
+msgid "  OS/ABI:                            %s\n"
+msgstr ""
+
+#: src/readelf.c:766
+#, c-format
+msgid "  ABI Version:                       %hhd\n"
+msgstr ""
+
+#: src/readelf.c:769
+msgid "  Type:                              "
+msgstr ""
+
+#: src/readelf.c:772
+#, c-format
+msgid "  Machine:                           %s\n"
+msgstr ""
+
+#: src/readelf.c:774
+#, c-format
+msgid "  Version:                           %d %s\n"
+msgstr ""
+
+#: src/readelf.c:778
+#, c-format
+msgid "  Entry point address:               %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:781
+#, c-format
+msgid "  Start of program headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:782 src/readelf.c:785
+msgid "(bytes into file)"
+msgstr ""
+
+#: src/readelf.c:784
+#, c-format
+msgid "  Start of section headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:787
+#, c-format
+msgid "  Flags:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:790
+#, c-format
+msgid "  Size of this header:               %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:791 src/readelf.c:794 src/readelf.c:811
+msgid "(bytes)"
+msgstr ""
+
+#: src/readelf.c:793
+#, c-format
+msgid "  Size of program header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:796
+#, c-format
+msgid "  Number of program headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:803
+#, c-format
+msgid " (%<PRIu32> in [0].sh_info)"
+msgstr ""
+
+#: src/readelf.c:806 src/readelf.c:823 src/readelf.c:837
+msgid " ([0] not available)"
+msgstr ""
+
+#: src/readelf.c:810
+#, c-format
+msgid "  Size of section header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:813
+#, c-format
+msgid "  Number of section headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:820
+#, c-format
+msgid " (%<PRIu32> in [0].sh_size)"
+msgstr ""
+
+#: src/readelf.c:833
+#, c-format
+msgid " (%<PRIu32> in [0].sh_link)"
+msgstr ""
+
+#: src/readelf.c:841
+#, c-format
+msgid ""
+"  Section header string table index: XINDEX%s\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:845
+#, c-format
+msgid ""
+"  Section header string table index: %<PRId16>\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:877
+#, c-format
+msgid ""
+"There are %d section headers, starting at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:887
+msgid "Section Headers:"
+msgstr ""
+
+#: src/readelf.c:890
+msgid ""
+"[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
+"Inf Al"
+msgstr ""
+
+#: src/readelf.c:892
+msgid ""
+"[Nr] Name                 Type         Addr             Off      Size     ES "
+"Flags Lk Inf Al"
+msgstr ""
+
+#: src/readelf.c:899 src/readelf.c:1052
+#, c-format
+msgid "cannot get section: %s"
+msgstr ""
+
+#: src/readelf.c:906 src/readelf.c:1060 src/readelf.c:7554 src/unstrip.c:353
+#: src/unstrip.c:377 src/unstrip.c:427 src/unstrip.c:536 src/unstrip.c:553
+#: src/unstrip.c:591 src/unstrip.c:789 src/unstrip.c:1057 src/unstrip.c:1244
+#: src/unstrip.c:1305 src/unstrip.c:1427 src/unstrip.c:1480 src/unstrip.c:1588
+#: src/unstrip.c:1778
+#, c-format
+msgid "cannot get section header: %s"
+msgstr ""
+
+#: src/readelf.c:964
+msgid "Program Headers:"
+msgstr ""
+
+#: src/readelf.c:966
+msgid ""
+"  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:969
+msgid ""
+"  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
+"MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:1009
+#, c-format
+msgid "\t[Requesting program interpreter: %s]\n"
+msgstr ""
+
+#: src/readelf.c:1030
+msgid ""
+"\n"
+" Section to Segment mapping:\n"
+"  Segment Sections..."
+msgstr ""
+
+#: src/readelf.c:1041 src/unstrip.c:1824 src/unstrip.c:1863 src/unstrip.c:1870
+#, c-format
+msgid "cannot get program header: %s"
+msgstr ""
+
+#: src/readelf.c:1175
+#, c-format
+msgid ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1180
+#, c-format
+msgid ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1188
+msgid "<INVALID SYMBOL>"
+msgstr ""
+
+#: src/readelf.c:1202
+msgid "<INVALID SECTION>"
+msgstr ""
+
+#: src/readelf.c:1353
+#, c-format
+msgid ""
+"\n"
+"Dynamic segment contains %lu entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Dynamic segment contains %lu entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1365
+msgid "  Type              Value\n"
+msgstr ""
+
+#: src/readelf.c:1389
+#, c-format
+msgid "Shared library: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1394
+#, c-format
+msgid "Library soname: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1399
+#, c-format
+msgid "Library rpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1404
+#, c-format
+msgid "Library runpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1424
+#, c-format
+msgid "%<PRId64> (bytes)\n"
+msgstr ""
+
+#: src/readelf.c:1534 src/readelf.c:1720
+#, c-format
+msgid ""
+"\n"
+"Invalid symbol table at offset %#0<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:1552 src/readelf.c:1737
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1567
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1577
+msgid "  Offset      Type                 Value       Name\n"
+msgstr ""
+
+#: src/readelf.c:1579
+msgid "  Offset              Type                 Value               Name\n"
+msgstr ""
+
+#: src/readelf.c:1632 src/readelf.c:1643 src/readelf.c:1656 src/readelf.c:1674
+#: src/readelf.c:1686 src/readelf.c:1805 src/readelf.c:1817 src/readelf.c:1831
+#: src/readelf.c:1850 src/readelf.c:1863
+msgid "<INVALID RELOC>"
+msgstr ""
+
+#: src/readelf.c:1749
+msgid "  Offset      Type            Value       Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:1751
+msgid "  Offset              Type            Value               Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:1952
+#, c-format
+msgid ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entry:\n"
+msgid_plural ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1958
+#, c-format
+msgid " %lu local symbol  String table: [%2u] '%s'\n"
+msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1968
+msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:1970
+msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:1990
+#, c-format
+msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+msgstr ""
+
+#: src/readelf.c:2078
+#, c-format
+msgid "bad dynamic symbol"
+msgstr ""
+
+#: src/readelf.c:2160
+msgid "none"
+msgstr ""
+
+#: src/readelf.c:2177
+msgid "| <unknown>"
+msgstr ""
+
+#: src/readelf.c:2202
+#, c-format
+msgid ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2225
+#, c-format
+msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
+msgstr ""
+
+#: src/readelf.c:2238
+#, c-format
+msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
+msgstr ""
+
+#: src/readelf.c:2269
+#, c-format
+msgid ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2299
+#, c-format
+msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
+msgstr ""
+
+#: src/readelf.c:2314
+#, c-format
+msgid "  %#06x: Parent %d: %s\n"
+msgstr ""
+
+#: src/readelf.c:2546
+#, c-format
+msgid ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgid_plural ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2576
+msgid "   0 *local*                     "
+msgstr ""
+
+#: src/readelf.c:2581
+msgid "   1 *global*                    "
+msgstr ""
+
+#: src/readelf.c:2612
+#, c-format
+msgid ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"bucket):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"buckets):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2636
+#, no-c-format
+msgid " Length  Number  % of total  Coverage\n"
+msgstr ""
+
+#: src/readelf.c:2638
+#, c-format
+msgid "      0  %6<PRIu32>      %5.1f%%\n"
+msgstr ""
+
+#: src/readelf.c:2645
+#, c-format
+msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+msgstr ""
+
+#: src/readelf.c:2658
+#, c-format
+msgid ""
+" Average number of tests:   successful lookup: %f\n"
+"                          unsuccessful lookup: %f\n"
+msgstr ""
+
+#: src/readelf.c:2676 src/readelf.c:2718 src/readelf.c:2759
+#, c-format
+msgid "cannot get data for section %d: %s"
+msgstr ""
+
+#: src/readelf.c:2813
+#, c-format
+msgid ""
+" Symbol Bias: %u\n"
+" Bitmask Size: %zu bytes  %<PRIuFAST32>%% bits set  2nd hash shift: %u\n"
+msgstr ""
+
+#: src/readelf.c:2887
+#, c-format
+msgid ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2901
+msgid ""
+"       Library                       Time Stamp          Checksum Version "
+"Flags"
+msgstr ""
+
+#: src/readelf.c:2951
+#, c-format
+msgid ""
+"\n"
+"Object attributes section [%2zu] '%s' of %<PRIu64> bytes at offset %"
+"#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:2967
+msgid "  Owner          Size\n"
+msgstr ""
+
+#: src/readelf.c:2993
+#, c-format
+msgid "  %-13s  %4<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3025
+#, c-format
+msgid "    %-4u %12<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3030
+#, c-format
+msgid "    File: %11<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3065
+#, c-format
+msgid "      %s: %<PRId64>, %s\n"
+msgstr ""
+
+#: src/readelf.c:3068
+#, c-format
+msgid "      %s: %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:3071
+#, c-format
+msgid "      %s: %s\n"
+msgstr ""
+
+#: src/readelf.c:3078
+#, c-format
+msgid "      %u: %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:3081
+#, c-format
+msgid "      %u: %s\n"
+msgstr ""
+
+#: src/readelf.c:3117
+#, c-format
+msgid "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3120
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3125
+#, c-format
+msgid "%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3128
+#, c-format
+msgid "%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3134
+#, c-format
+msgid "%s+%#<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3137
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3141
+#, c-format
+msgid "%#<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3144
+#, c-format
+msgid "%#0*<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3149
+#, c-format
+msgid "%s+%#<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3152
+#, c-format
+msgid "%s+%#0*<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3260
+#, c-format
+msgid "unknown tag %hx"
+msgstr ""
+
+#: src/readelf.c:3262
+#, c-format
+msgid "unknown user tag %hx"
+msgstr ""
+
+#: src/readelf.c:3480
+#, c-format
+msgid "unknown attribute %hx"
+msgstr ""
+
+#: src/readelf.c:3483
+#, c-format
+msgid "unknown user attribute %hx"
+msgstr ""
+
+#: src/readelf.c:3529
+#, c-format
+msgid "unknown form %<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3763
+msgid "empty block"
+msgstr ""
+
+#: src/readelf.c:3766
+#, c-format
+msgid "%zu byte block:"
+msgstr ""
+
+#: src/readelf.c:4175
+#, c-format
+msgid "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+msgstr ""
+
+#: src/readelf.c:4188
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [ Code]\n"
+msgstr ""
+
+#: src/readelf.c:4195
+#, c-format
+msgid ""
+"\n"
+"Abbreviation section at offset %<PRIu64>:\n"
+msgstr ""
+
+#: src/readelf.c:4208
+#, c-format
+msgid " *** error while reading abbreviation: %s\n"
+msgstr ""
+
+#: src/readelf.c:4224
+#, c-format
+msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
+msgstr ""
+
+#: src/readelf.c:4227
+msgid "yes"
+msgstr ""
+
+#: src/readelf.c:4227
+msgid "no"
+msgstr ""
+
+#: src/readelf.c:4263
+#, c-format
+msgid "cannot get .debug_aranges content: %s"
+msgstr ""
+
+#: src/readelf.c:4268
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:4298
+#, c-format
+msgid " [%*zu] ???\n"
+msgstr ""
+
+#: src/readelf.c:4300
+#, c-format
+msgid ""
+" [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:4319
+#, c-format
+msgid "cannot get .debug_ranges content: %s"
+msgstr ""
+
+#: src/readelf.c:4324 src/readelf.c:4810 src/readelf.c:5452 src/readelf.c:5897
+#: src/readelf.c:5992 src/readelf.c:6164
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:4338 src/readelf.c:5911
+#, c-format
+msgid " [%6tx]  <INVALID DATA>\n"
+msgstr ""
+
+#: src/readelf.c:4360 src/readelf.c:5933
+#, c-format
+msgid " [%6tx]  base address %s\n"
+msgstr ""
+
+#: src/readelf.c:4371
+#, c-format
+msgid " [%6tx]  %s..%s\n"
+msgstr ""
+
+#: src/readelf.c:4373
+#, c-format
+msgid "           %s..%s\n"
+msgstr ""
+
+#: src/readelf.c:4799 src/readelf.c:6230 src/readelf.c:6332
+#, c-format
+msgid "cannot get %s content: %s"
+msgstr ""
+
+#: src/readelf.c:4806
+#, c-format
+msgid ""
+"\n"
+"Call frame information section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:4833 src/readelf.c:5486
+#, c-format
+msgid "invalid data in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:4855
+#, c-format
+msgid ""
+"\n"
+" [%6tx] Zero terminator\n"
+msgstr ""
+
+#: src/readelf.c:4924
+#, c-format
+msgid "invalid augmentation length"
+msgstr ""
+
+#: src/readelf.c:4936
+msgid "FDE address encoding: "
+msgstr ""
+
+#: src/readelf.c:4942
+msgid "LSDA pointer encoding: "
+msgstr ""
+
+#: src/readelf.c:5034
+#, c-format
+msgid " (offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5041
+#, c-format
+msgid " (end offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5068
+#, c-format
+msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:5114
+#, c-format
+msgid "cannot get attribute code: %s"
+msgstr ""
+
+#: src/readelf.c:5122
+#, c-format
+msgid "cannot get attribute form: %s"
+msgstr ""
+
+#: src/readelf.c:5135
+#, c-format
+msgid "cannot get attribute value: %s"
+msgstr ""
+
+#: src/readelf.c:5331
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [Offset]\n"
+msgstr ""
+
+#: src/readelf.c:5356
+#, c-format
+msgid ""
+" Compilation unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: %"
+"<PRIu8>, Offset size: %<PRIu8>\n"
+msgstr ""
+
+#: src/readelf.c:5374
+#, c-format
+msgid "cannot get DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:5385
+#, c-format
+msgid "cannot get DIE offset: %s"
+msgstr ""
+
+#: src/readelf.c:5393
+#, c-format
+msgid "cannot get tag of DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:5422
+#, c-format
+msgid "cannot get next DIE: %s\n"
+msgstr ""
+
+#: src/readelf.c:5429
+#, c-format
+msgid "cannot get next DIE: %s"
+msgstr ""
+
+#: src/readelf.c:5464
+#, c-format
+msgid "cannot get line data section data: %s"
+msgstr ""
+
+#: src/readelf.c:5477
+#, c-format
+msgid ""
+"\n"
+"Table at offset %Zu:\n"
+msgstr ""
+
+#: src/readelf.c:5529
+#, c-format
+msgid ""
+"\n"
+" Length:                     %<PRIu64>\n"
+" DWARF version:              %<PRIuFAST16>\n"
+" Prologue length:            %<PRIu64>\n"
+" Minimum instruction length: %<PRIuFAST8>\n"
+" Initial value if '%s': %<PRIuFAST8>\n"
+" Line base:                  %<PRIdFAST8>\n"
+" Line range:                 %<PRIuFAST8>\n"
+" Opcode base:                %<PRIuFAST8>\n"
+"\n"
+"Opcodes:\n"
+msgstr ""
+
+#: src/readelf.c:5548
+#, c-format
+msgid "invalid data at offset %tu in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:5563
+#, c-format
+msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
+msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:5571
+msgid ""
+"\n"
+"Directory table:"
+msgstr ""
+
+#: src/readelf.c:5587
+msgid ""
+"\n"
+"File name table:\n"
+" Entry Dir   Time      Size      Name"
+msgstr ""
+
+#: src/readelf.c:5616
+msgid ""
+"\n"
+"Line number statements:"
+msgstr ""
+
+#: src/readelf.c:5677
+#, c-format
+msgid " special opcode %u: address+%u = %s, line%+d = %zu\n"
+msgstr ""
+
+#: src/readelf.c:5697
+#, c-format
+msgid " extended opcode %u: "
+msgstr ""
+
+#: src/readelf.c:5702
+msgid "end of sequence"
+msgstr ""
+
+#: src/readelf.c:5717
+#, c-format
+msgid "set address to %s\n"
+msgstr ""
+
+#: src/readelf.c:5738
+#, c-format
+msgid "define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
+msgstr ""
+
+#: src/readelf.c:5747
+msgid "unknown opcode"
+msgstr ""
+
+#: src/readelf.c:5759
+msgid " copy"
+msgstr ""
+
+#: src/readelf.c:5769
+#, c-format
+msgid "advance address by %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5780
+#, c-format
+msgid " advance line by constant %d to %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:5788
+#, c-format
+msgid " set file to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:5798
+#, c-format
+msgid " set column to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:5805
+#, c-format
+msgid " set '%s' to %<PRIuFAST8>\n"
+msgstr ""
+
+#: src/readelf.c:5811
+msgid " set basic block flag"
+msgstr ""
+
+#: src/readelf.c:5821
+#, c-format
+msgid "advance address by constant %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5837
+#, c-format
+msgid "advance address by fixed value %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5846
+msgid " set prologue end flag"
+msgstr ""
+
+#: src/readelf.c:5851
+msgid " set epilogue begin flag"
+msgstr ""
+
+#: src/readelf.c:5860
+#, c-format
+msgid " unknown opcode with %<PRIu8> parameter:"
+msgid_plural " unknown opcode with %<PRIu8> parameters:"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:5892
+#, c-format
+msgid "cannot get .debug_loc content: %s"
+msgstr ""
+
+#: src/readelf.c:5947
+#, c-format
+msgid " [%6tx]  %s..%s"
+msgstr ""
+
+#: src/readelf.c:5949
+#, c-format
+msgid "           %s..%s"
+msgstr ""
+
+#: src/readelf.c:6002
+#, c-format
+msgid "cannot get macro information section data: %s"
+msgstr ""
+
+#: src/readelf.c:6081
+#, c-format
+msgid "%*s*** non-terminated string at end of section"
+msgstr ""
+
+#: src/readelf.c:6149
+#, c-format
+msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
+msgstr ""
+
+#: src/readelf.c:6188
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" %*s  String\n"
+msgstr ""
+
+#: src/readelf.c:6202
+#, c-format
+msgid " *** error while reading strings: %s\n"
+msgstr ""
+
+#: src/readelf.c:6222
+#, c-format
+msgid ""
+"\n"
+"Call frame search table section [%2zu] '.eh_frame_hdr':\n"
+msgstr ""
+
+#: src/readelf.c:6324
+#, c-format
+msgid ""
+"\n"
+"Exception handling table section [%2zu] '.gcc_except_table':\n"
+msgstr ""
+
+#: src/readelf.c:6347
+#, c-format
+msgid " LPStart encoding:    %#x "
+msgstr ""
+
+#: src/readelf.c:6359
+#, c-format
+msgid " TType encoding:      %#x "
+msgstr ""
+
+#: src/readelf.c:6373
+#, c-format
+msgid " Call site encoding:  %#x "
+msgstr ""
+
+#: src/readelf.c:6386
+msgid ""
+"\n"
+" Call site table:"
+msgstr ""
+
+#: src/readelf.c:6400
+#, c-format
+msgid ""
+" [%4u] Call site start:   %#<PRIx64>\n"
+"        Call site length:  %<PRIu64>\n"
+"        Landing pad:       %#<PRIx64>\n"
+"        Action:            %u\n"
+msgstr ""
+
+#: src/readelf.c:6460
+#, c-format
+msgid "invalid TType encoding"
+msgstr ""
+
+#: src/readelf.c:6484
+#, c-format
+msgid "cannot get debug context descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:6620 src/readelf.c:7221
+#, c-format
+msgid "cannot convert core note data: %s"
+msgstr ""
+
+#: src/readelf.c:6961
+#, c-format
+msgid ""
+"\n"
+"%*s... <repeats %u more times> ..."
+msgstr ""
+
+#: src/readelf.c:7320
+msgid "  Owner          Data size  Type\n"
+msgstr ""
+
+#: src/readelf.c:7338
+#, c-format
+msgid "  %-13.*s  %9<PRId32>  %s\n"
+msgstr ""
+
+#: src/readelf.c:7372
+#, c-format
+msgid "cannot get content of note section: %s"
+msgstr ""
+
+#: src/readelf.c:7399
+#, c-format
+msgid ""
+"\n"
+"Note section [%2zu] '%s' of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7422
+#, c-format
+msgid ""
+"\n"
+"Note segment of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7468
+#, c-format
+msgid ""
+"\n"
+"Section [%Zu] '%s' has no data to dump.\n"
+msgstr ""
+
+#: src/readelf.c:7474 src/readelf.c:7497
+#, c-format
+msgid "cannot get data for section [%Zu] '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7478
+#, c-format
+msgid ""
+"\n"
+"Hex dump of section [%Zu] '%s', %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7491
+#, c-format
+msgid ""
+"\n"
+"Section [%Zu] '%s' has no strings to dump.\n"
+msgstr ""
+
+#: src/readelf.c:7501
+#, c-format
+msgid ""
+"\n"
+"String section [%Zu] '%s' contains %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7549
+#, c-format
+msgid ""
+"\n"
+"section [%lu] does not exist"
+msgstr ""
+
+#: src/readelf.c:7576
+#, c-format
+msgid ""
+"\n"
+"section '%s' does not exist"
+msgstr ""
+
+#: src/readelf.c:7637
+#, c-format
+msgid "cannot get symbol index of archive '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7640
+#, c-format
+msgid ""
+"\n"
+"Archive '%s' has no symbol index\n"
+msgstr ""
+
+#: src/readelf.c:7644
+#, c-format
+msgid ""
+"\n"
+"Index of archive '%s' has %Zu entries:\n"
+msgstr ""
+
+#: src/readelf.c:7662
+#, c-format
+msgid "cannot extract member at offset %Zu in '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7667
+#, c-format
+msgid "Archive member '%s' contains:\n"
+msgstr ""
+
+#: src/size.c:68
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd' or `sysv'.  The default "
+"is `bsd'"
+msgstr ""
+
+#: src/size.c:70
+msgid "Same as `--format=sysv'"
+msgstr ""
+
+#: src/size.c:71
+msgid "Same as `--format=bsd'"
+msgstr ""
+
+#: src/size.c:74
+msgid "Same as `--radix=10'"
+msgstr ""
+
+#: src/size.c:75
+msgid "Same as `--radix=8'"
+msgstr ""
+
+#: src/size.c:76
+msgid "Same as `--radix=16'"
+msgstr ""
+
+#: src/size.c:78
+msgid "Similar to `--format=sysv' output but in one line"
+msgstr ""
+
+#: src/size.c:82
+msgid "Print size and permission flags for loadable segments"
+msgstr ""
+
+#: src/size.c:83
+msgid "Display the total sizes (bsd only)"
+msgstr ""
+
+#: src/size.c:88
+msgid "List section sizes of FILEs (a.out by default)."
+msgstr ""
+
+#: src/size.c:269
+#, c-format
+msgid "Invalid format: %s"
+msgstr ""
+
+#: src/size.c:280
+#, c-format
+msgid "Invalid radix: %s"
+msgstr ""
+
+#: src/size.c:339
+#, c-format
+msgid "%s: file format not recognized"
+msgstr ""
+
+#: src/size.c:446 src/size.c:589
+#, c-format
+msgid " (ex %s)"
+msgstr ""
+
+#: src/size.c:614
+msgid "(TOTALS)\n"
+msgstr ""
+
+#: src/strings.c:70
+msgid "Output Selection:"
+msgstr ""
+
+#: src/strings.c:71
+msgid "Scan entire file, not only loaded sections"
+msgstr ""
+
+#: src/strings.c:73
+msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed"
+msgstr ""
+
+#: src/strings.c:74
+msgid ""
+"Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, "
+"{B,L} = 32-bit"
+msgstr ""
+
+#: src/strings.c:78
+msgid "Print name of the file before each string."
+msgstr ""
+
+#: src/strings.c:80
+msgid "Print location of the string in base 8, 10, or 16 respectively."
+msgstr ""
+
+#: src/strings.c:81
+msgid "Alias for --radix=o"
+msgstr ""
+
+#: src/strings.c:88
+msgid "Print the strings of printable characters in files."
+msgstr ""
+
+#: src/strings.c:268 src/strings.c:303
+#, c-format
+msgid "invalid value '%s' for %s parameter"
+msgstr ""
+
+#: src/strings.c:314
+#, c-format
+msgid "invalid minimum length of matched string size"
+msgstr ""
+
+#: src/strings.c:601
+#, c-format
+msgid "lseek64 failed"
+msgstr ""
+
+#: src/strings.c:616 src/strings.c:680
+#, c-format
+msgid "re-mmap failed"
+msgstr ""
+
+#: src/strings.c:653
+#, c-format
+msgid "mprotect failed"
+msgstr ""
+
+#: src/strip.c:74
+msgid "Place stripped output into FILE"
+msgstr ""
+
+#: src/strip.c:75
+msgid "Extract the removed sections into FILE"
+msgstr ""
+
+#: src/strip.c:76
+msgid "Embed name FILE instead of -f argument"
+msgstr ""
+
+#: src/strip.c:80
+msgid "Remove all debugging symbols"
+msgstr ""
+
+#: src/strip.c:84
+msgid "Copy modified/access timestamps to the output"
+msgstr ""
+
+#: src/strip.c:86
+msgid "Remove .comment section"
+msgstr ""
+
+#: src/strip.c:89
+msgid "Relax a few rules to handle slightly broken ELF files"
+msgstr ""
+
+#: src/strip.c:94
+msgid "Discard symbols from object files."
+msgstr ""
+
+#: src/strip.c:186
+#, c-format
+msgid "Only one input file allowed together with '-o' and '-f'"
+msgstr ""
+
+#: src/strip.c:222
+#, c-format
+msgid "-f option specified twice"
+msgstr ""
+
+#: src/strip.c:231
+#, c-format
+msgid "-F option specified twice"
+msgstr ""
+
+#: src/strip.c:240 src/unstrip.c:125
+#, c-format
+msgid "-o option specified twice"
+msgstr ""
+
+#: src/strip.c:260
+#, c-format
+msgid "-R option supports only .comment section"
+msgstr ""
+
+#: src/strip.c:298 src/strip.c:322
+#, c-format
+msgid "cannot stat input file '%s'"
+msgstr ""
+
+#: src/strip.c:312
+#, c-format
+msgid "while opening '%s'"
+msgstr ""
+
+#: src/strip.c:350
+#, c-format
+msgid "%s: cannot use -o or -f when stripping archive"
+msgstr ""
+
+#: src/strip.c:448
+#, c-format
+msgid "cannot open EBL backend"
+msgstr ""
+
+#: src/strip.c:498 src/strip.c:522
+#, c-format
+msgid "cannot create new file '%s': %s"
+msgstr ""
+
+#: src/strip.c:582
+#, c-format
+msgid "illformed file '%s'"
+msgstr ""
+
+#: src/strip.c:869 src/strip.c:956
+#, c-format
+msgid "while generating output file: %s"
+msgstr ""
+
+#: src/strip.c:929 src/strip.c:1668
+#, c-format
+msgid "%s: error while creating ELF header: %s"
+msgstr ""
+
+#: src/strip.c:943
+#, c-format
+msgid "while preparing output for '%s'"
+msgstr ""
+
+#: src/strip.c:994 src/strip.c:1050
+#, c-format
+msgid "while create section header section: %s"
+msgstr ""
+
+#: src/strip.c:1000
+#, c-format
+msgid "cannot allocate section data: %s"
+msgstr ""
+
+#: src/strip.c:1059
+#, c-format
+msgid "while create section header string table: %s"
+msgstr ""
+
+#: src/strip.c:1593 src/strip.c:1690
+#, c-format
+msgid "while writing '%s': %s"
+msgstr ""
+
+#: src/strip.c:1604
+#, c-format
+msgid "while creating '%s'"
+msgstr ""
+
+#: src/strip.c:1616
+#, c-format
+msgid "while computing checksum for debug information"
+msgstr ""
+
+#: src/strip.c:1676
+#, c-format
+msgid "%s: error while reading the file: %s"
+msgstr ""
+
+#: src/strip.c:1722 src/strip.c:1729
+#, c-format
+msgid "error while finishing '%s': %s"
+msgstr ""
+
+#: src/strip.c:1752 src/strip.c:1809
+#, c-format
+msgid "cannot set access and modification date of '%s'"
+msgstr ""
+
+#: src/unstrip.c:78
+msgid "Match MODULE against file names, not module names"
+msgstr ""
+
+#: src/unstrip.c:79
+msgid "Silently skip unfindable files"
+msgstr ""
+
+#: src/unstrip.c:82
+msgid "Place output into FILE"
+msgstr ""
+
+#: src/unstrip.c:84
+msgid "Create multiple output files under DIRECTORY"
+msgstr ""
+
+#: src/unstrip.c:85
+msgid "Use module rather than file names"
+msgstr ""
+
+#: src/unstrip.c:87
+msgid "Create output for modules that have no separate debug information"
+msgstr ""
+
+#: src/unstrip.c:90
+msgid "Apply relocations to section contents in ET_REL files"
+msgstr ""
+
+#: src/unstrip.c:92
+msgid "Only list module and file names, build IDs"
+msgstr ""
+
+#: src/unstrip.c:134
+#, c-format
+msgid "-d option specified twice"
+msgstr ""
+
+#: src/unstrip.c:166
+#, c-format
+msgid "only one of -o or -d allowed"
+msgstr ""
+
+#: src/unstrip.c:175
+#, c-format
+msgid "-n cannot be used with explicit files or -o or -d"
+msgstr ""
+
+#: src/unstrip.c:190
+#, c-format
+msgid "output directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:199
+#, c-format
+msgid "exactly two file arguments are required"
+msgstr ""
+
+#: src/unstrip.c:205
+#, c-format
+msgid "-m, -a, -R, and -i options not allowed with explicit files"
+msgstr ""
+
+#: src/unstrip.c:218
+#, c-format
+msgid "-o or -d is required when using implicit files"
+msgstr ""
+
+#: src/unstrip.c:254
+#, c-format
+msgid "cannot create ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:259
+#, c-format
+msgid "cannot copy ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:264 src/unstrip.c:1817
+#, c-format
+msgid "cannot create program headers: %s"
+msgstr ""
+
+#: src/unstrip.c:270
+#, c-format
+msgid "cannot copy program header: %s"
+msgstr ""
+
+#: src/unstrip.c:280
+#, c-format
+msgid "cannot copy section header: %s"
+msgstr ""
+
+#: src/unstrip.c:283 src/unstrip.c:1505
+#, c-format
+msgid "cannot get section data: %s"
+msgstr ""
+
+#: src/unstrip.c:285 src/unstrip.c:1507
+#, c-format
+msgid "cannot copy section data: %s"
+msgstr ""
+
+#: src/unstrip.c:309
+#, c-format
+msgid "cannot create directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:349 src/unstrip.c:763 src/unstrip.c:1540
+#, c-format
+msgid "cannot get symbol table entry: %s"
+msgstr ""
+
+#: src/unstrip.c:365 src/unstrip.c:580 src/unstrip.c:601 src/unstrip.c:613
+#: src/unstrip.c:1561 src/unstrip.c:1691 src/unstrip.c:1715
+#, c-format
+msgid "cannot update symbol table: %s"
+msgstr ""
+
+#: src/unstrip.c:382 src/unstrip.c:432 src/unstrip.c:562 src/unstrip.c:1209
+#: src/unstrip.c:1525 src/unstrip.c:1720 src/unstrip.c:1791
+#, c-format
+msgid "cannot update section header: %s"
+msgstr ""
+
+#: src/unstrip.c:408 src/unstrip.c:419
+#, c-format
+msgid "cannot update relocation: %s"
+msgstr ""
+
+#: src/unstrip.c:507
+#, c-format
+msgid "cannot get symbol version: %s"
+msgstr ""
+
+#: src/unstrip.c:519
+#, c-format
+msgid "unexpected section type in [%Zu] with sh_link to symtab"
+msgstr ""
+
+#: src/unstrip.c:769
+#, c-format
+msgid "invalid string offset in symbol [%Zu]"
+msgstr ""
+
+#: src/unstrip.c:911 src/unstrip.c:1248
+#, c-format
+msgid "cannot read section [%Zu] name: %s"
+msgstr ""
+
+#: src/unstrip.c:952 src/unstrip.c:971 src/unstrip.c:1004
+#, c-format
+msgid "cannot read '.gnu.prelink_undo' section: %s"
+msgstr ""
+
+#: src/unstrip.c:992
+#, c-format
+msgid "invalid contents in '%s' section"
+msgstr ""
+
+#: src/unstrip.c:1047 src/unstrip.c:1370
+#, c-format
+msgid "cannot find matching section for [%Zu] '%s'"
+msgstr ""
+
+#: src/unstrip.c:1171 src/unstrip.c:1186 src/unstrip.c:1451
+#, c-format
+msgid "cannot add section name to string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1195
+#, c-format
+msgid "cannot update section header string table data: %s"
+msgstr ""
+
+#: src/unstrip.c:1223 src/unstrip.c:1227
+#, c-format
+msgid "cannot get section header string table section index: %s"
+msgstr ""
+
+#: src/unstrip.c:1231 src/unstrip.c:1235 src/unstrip.c:1466
+#, c-format
+msgid "cannot get section count: %s"
+msgstr ""
+
+#: src/unstrip.c:1293 src/unstrip.c:1385
+#, c-format
+msgid "cannot read section header string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1445
+#, c-format
+msgid "cannot add new section: %s"
+msgstr ""
+
+#: src/unstrip.c:1548
+#, c-format
+msgid "symbol [%Zu] has invalid section index"
+msgstr ""
+
+#: src/unstrip.c:1800
+#, c-format
+msgid "cannot get ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:1827
+#, c-format
+msgid "cannot update program header: %s"
+msgstr ""
+
+#: src/unstrip.c:1832 src/unstrip.c:1911
+#, c-format
+msgid "cannot write output file: %s"
+msgstr ""
+
+#: src/unstrip.c:1880
+#, c-format
+msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:1883
+#, c-format
+msgid ""
+"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:1902 src/unstrip.c:1942 src/unstrip.c:1954 src/unstrip.c:2034
+#, c-format
+msgid "cannot create ELF descriptor: %s"
+msgstr ""
+
+#: src/unstrip.c:1960
+#, c-format
+msgid "'%s' and '%s' do not seem to match"
+msgstr ""
+
+#: src/unstrip.c:1991
+#, c-format
+msgid "cannot find stripped file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:1995
+#, c-format
+msgid "cannot open stripped file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2010
+#, c-format
+msgid "cannot find debug file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2014
+#, c-format
+msgid "cannot open debug file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2027
+#, c-format
+msgid "module '%s' file '%s' is not stripped"
+msgstr ""
+
+#: src/unstrip.c:2058
+#, c-format
+msgid "cannot cache section addresses for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2191
+#, c-format
+msgid "no matching modules found"
+msgstr ""
+
+#: src/unstrip.c:2200
+#, c-format
+msgid "matched more than one module"
+msgstr ""
+
+#: src/unstrip.c:2247
+msgid ""
+"STRIPPED-FILE DEBUG-FILE\n"
+"[MODULE...]"
+msgstr ""
+
+#: src/unstrip.c:2248
+msgid ""
+"Combine stripped files with separate symbols and debug information.\n\nThe "
+"first form puts the result in DEBUG-FILE if -o was not given.\n"
+"\n"
+"MODULE arguments give file name patterns matching modules to process.\n"
+"With -f these match the file name of the main (stripped) file (slashes are "
+"never special), otherwise they match the simple module names.  With no "
+"arguments, process all modules found.\n"
+"\n"
+"Multiple modules are written to files under OUTPUT-DIRECTORY, creating "
+"subdirectories as needed.  With -m these files have simple module names, "
+"otherwise they have the name of the main file complete with directory "
+"underneath OUTPUT-DIRECTORY.\n"
+"\n"
+"With -n no files are written, but one line to standard output for each "
+"module:\n"
+"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n"
+"START and SIZE are hexadecimal giving the address bounds of the module.  "
+"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the "
+"hexadecimal may be followed by @0xADDR giving the address where the ID "
+"resides if that is known.  FILE is the file name found for the module, or - "
+"if none was found, or . if an ELF image is available but not from any named "
+"file.  DEBUGFILE is the separate debuginfo file name, or - if no debuginfo "
+"was found, or . if FILE contains the debug information."
+msgstr ""
diff --git a/third_party/elfutils/po/pl.po b/third_party/elfutils/po/pl.po
new file mode 100644
index 0000000..583e4ab
--- /dev/null
+++ b/third_party/elfutils/po/pl.po
@@ -0,0 +1,6710 @@
+# Polish translation for elfutils.
+# Copyright © 2003-2016 the elfutils authors.
+# This file is distributed under the same license as the elfutils package.
+# Jakub Bogusz <qboosh@pld-linux.org>, 2003-2007.
+# Piotr Drąg <piotrdrag@gmail.com>, 2010-2016.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: elfutils\n"
+"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n"
+"POT-Creation-Date: 2017-09-01 12:27+0200\n"
+"PO-Revision-Date: 2016-12-29 17:48+0100\n"
+"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
+"Language-Team: Polish <trans-pl@lists.fedoraproject.org>\n"
+"Language: pl\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2);\n"
+
+#: lib/color.c:53
+msgid ""
+"colorize the output.  WHEN defaults to 'always' or can be 'auto' or 'never'"
+msgstr ""
+"koloruje wyjście. WHEN domyślnie wynosi „always” lub może wynosić „auto” lub "
+"„never”"
+
+#: lib/color.c:127
+#, c-format
+msgid ""
+"%s: invalid argument '%s' for '--color'\n"
+"valid arguments are:\n"
+"  - 'always', 'yes', 'force'\n"
+"  - 'never', 'no', 'none'\n"
+"  - 'auto', 'tty', 'if-tty'\n"
+msgstr ""
+"%s: nieprawidłowy parametr „%s” dla „--color”\n"
+"prawidłowe parametry:\n"
+"  • „always”, „yes”, „force”\n"
+"  • „never”, „no”, „none”\n"
+"  • „auto”, „tty”, „if-tty”\n"
+
+#: lib/color.c:190 src/objdump.c:727
+#, c-format
+msgid "cannot allocate memory"
+msgstr "nie można przydzielić pamięci"
+
+#: lib/printversion.c:40
+#, c-format
+msgid ""
+"Copyright (C) %s The elfutils developers <%s>.\n"
+"This is free software; see the source for copying conditions.  There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+"Copyright © %s programiści projektu elfutils <%s>.\n"
+"Niniejszy program jest wolnym oprogramowaniem; proszę zobaczyć kod źródłowy\n"
+"w celu poznania warunków kopiowania. Niniejszy program rozprowadzany jest\n"
+"BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej gwarancji PRZYDATNOŚCI\n"
+"HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH ZASTOSOWAŃ.\n"
+
+#: lib/xmalloc.c:53 lib/xmalloc.c:66 lib/xmalloc.c:78 src/readelf.c:3310
+#: src/readelf.c:3701 src/readelf.c:8540 src/unstrip.c:2227 src/unstrip.c:2433
+#, c-format
+msgid "memory exhausted"
+msgstr "pamięć wyczerpana"
+
+#: libasm/asm_error.c:65 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:50
+#: libelf/elf_error.c:60
+msgid "no error"
+msgstr "brak błędu"
+
+#: libasm/asm_error.c:66 libdw/dwarf_error.c:68 libdwfl/libdwflP.h:52
+#: libelf/elf_error.c:91
+msgid "out of memory"
+msgstr "brak pamięci"
+
+#: libasm/asm_error.c:67
+msgid "cannot create output file"
+msgstr "nie można utworzyć pliku wyjściowego"
+
+#: libasm/asm_error.c:68
+msgid "invalid parameter"
+msgstr "nieprawidłowy parametr"
+
+#: libasm/asm_error.c:69
+msgid "cannot change mode of output file"
+msgstr "nie można zmienić trybu pliku wyjściowego"
+
+#: libasm/asm_error.c:70
+msgid "cannot rename output file"
+msgstr "nie można zmienić nazwy pliku wyjściowego"
+
+#: libasm/asm_error.c:71
+msgid "duplicate symbol"
+msgstr "powtórzony symbol"
+
+#: libasm/asm_error.c:72
+msgid "invalid section type for operation"
+msgstr "nieprawidłowy typ sekcji dla działania"
+
+#: libasm/asm_error.c:73
+msgid "error during output of data"
+msgstr "błąd podczas wyprowadzania danych"
+
+#: libasm/asm_error.c:74
+msgid "no backend support available"
+msgstr "brak dostępnej obsługi zaplecza"
+
+#: libasm/asm_error.c:83 libdw/dwarf_error.c:59 libdwfl/libdwflP.h:51
+#: libelf/elf_error.c:63
+msgid "unknown error"
+msgstr "nieznany błąd"
+
+#: libdw/dwarf_error.c:60
+msgid "invalid access"
+msgstr "nieprawidłowy dostęp"
+
+#: libdw/dwarf_error.c:61
+msgid "no regular file"
+msgstr "nie jest zwykłym plikiem"
+
+#: libdw/dwarf_error.c:62
+msgid "I/O error"
+msgstr "błąd wejścia/wyjścia"
+
+#: libdw/dwarf_error.c:63
+msgid "invalid ELF file"
+msgstr "nieprawidłowy plik ELF"
+
+#: libdw/dwarf_error.c:64
+msgid "no DWARF information"
+msgstr "brak informacji DWARF"
+
+#: libdw/dwarf_error.c:65
+msgid "cannot decompress DWARF"
+msgstr "nie można dekompresować DWARF"
+
+#: libdw/dwarf_error.c:66
+msgid "no ELF file"
+msgstr "brak pliku ELF"
+
+#: libdw/dwarf_error.c:67
+msgid "cannot get ELF header"
+msgstr "nie można uzyskać nagłówka ELF"
+
+#: libdw/dwarf_error.c:69
+msgid "not implemented"
+msgstr "niezaimplementowane"
+
+#: libdw/dwarf_error.c:70 libelf/elf_error.c:107 libelf/elf_error.c:155
+msgid "invalid command"
+msgstr "nieprawidłowe polecenie"
+
+#: libdw/dwarf_error.c:71
+msgid "invalid version"
+msgstr "nieprawidłowa wersja"
+
+#: libdw/dwarf_error.c:72
+msgid "invalid file"
+msgstr "nieprawidłowy plik"
+
+#: libdw/dwarf_error.c:73
+msgid "no entries found"
+msgstr "nie odnaleziono wpisów"
+
+#: libdw/dwarf_error.c:74
+msgid "invalid DWARF"
+msgstr "nieprawidłowy DWARF"
+
+#: libdw/dwarf_error.c:75
+msgid "no string data"
+msgstr "brak danych w postaci ciągu"
+
+#: libdw/dwarf_error.c:76
+msgid "no address value"
+msgstr "brak wartości adresu"
+
+#: libdw/dwarf_error.c:77
+msgid "no constant value"
+msgstr "brak wartości stałej"
+
+#: libdw/dwarf_error.c:78
+msgid "no reference value"
+msgstr "brak wartości odwołania"
+
+#: libdw/dwarf_error.c:79
+msgid "invalid reference value"
+msgstr "nieprawidłowa wartość odwołania"
+
+#: libdw/dwarf_error.c:80
+msgid ".debug_line section missing"
+msgstr "brak sekcji .debug_line"
+
+#: libdw/dwarf_error.c:81
+msgid "invalid .debug_line section"
+msgstr "nieprawidłowa sekcja .debug_line"
+
+#: libdw/dwarf_error.c:82
+msgid "debug information too big"
+msgstr "informacje debugowania są za duże"
+
+#: libdw/dwarf_error.c:83
+msgid "invalid DWARF version"
+msgstr "nieprawidłowa wersja DWARF"
+
+#: libdw/dwarf_error.c:84
+msgid "invalid directory index"
+msgstr "nieprawidłowy indeks katalogu"
+
+#: libdw/dwarf_error.c:85 libdwfl/libdwflP.h:71
+msgid "address out of range"
+msgstr "adres jest spoza zakresu"
+
+#: libdw/dwarf_error.c:86
+msgid "no location list value"
+msgstr "brak wartości listy położeń"
+
+#: libdw/dwarf_error.c:87
+msgid "no block data"
+msgstr "brak danych blokowych"
+
+#: libdw/dwarf_error.c:88
+msgid "invalid line index"
+msgstr "nieprawidłowy indeks wiersza"
+
+#: libdw/dwarf_error.c:89
+msgid "invalid address range index"
+msgstr "nieprawidłowy indeks zakresu adresów"
+
+#: libdw/dwarf_error.c:90 libdwfl/libdwflP.h:72
+msgid "no matching address range"
+msgstr "brak pasującego zakresu adresów"
+
+#: libdw/dwarf_error.c:91
+msgid "no flag value"
+msgstr "brak wartości flagi"
+
+#: libdw/dwarf_error.c:92 libelf/elf_error.c:232
+msgid "invalid offset"
+msgstr "nieprawidłowy offset"
+
+#: libdw/dwarf_error.c:93
+msgid ".debug_ranges section missing"
+msgstr "brak sekcji .debug_ranges"
+
+#: libdw/dwarf_error.c:94
+msgid "invalid CFI section"
+msgstr "nieprawidłowa wersja CFI"
+
+#: libdw/dwarf_error.c:95
+msgid "no alternative debug link found"
+msgstr "nie odnaleziono alternatywnego dowiązania debugowania"
+
+#: libdw/dwarf_error.c:96
+msgid "invalid opcode"
+msgstr "nieprawidłowa instrukcja"
+
+#: libdw/dwarf_error.c:97
+msgid "not a CU (unit) DIE"
+msgstr "nie jest CU (jednostką) DIE"
+
+#: libdw/dwarf_error.c:98
+#, fuzzy
+msgid "unknown language code"
+msgstr " nieznana instrukcja"
+
+#: libdwfl/argp-std.c:50 src/stack.c:639 src/unstrip.c:2374
+msgid "Input selection options:"
+msgstr "Opcje wyboru wejścia:"
+
+#: libdwfl/argp-std.c:51
+msgid "Find addresses in FILE"
+msgstr "Wyszukuje adresy w PLIKU"
+
+#: libdwfl/argp-std.c:53
+msgid "Find addresses from signatures found in COREFILE"
+msgstr "Wyszukuje adresy z podpisów odnalezionych w PLIKU_CORE"
+
+#: libdwfl/argp-std.c:55
+msgid "Find addresses in files mapped into process PID"
+msgstr "Wyszukuje adresy w plikach zmapowanych do PID procesów"
+
+#: libdwfl/argp-std.c:57
+msgid ""
+"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps "
+"format"
+msgstr ""
+"Wyszukuje adresy w plikach zmapowanych jako odczyt z PLIKU w formacie /proc/"
+"PID/maps systemu Linux"
+
+#: libdwfl/argp-std.c:59
+msgid "Find addresses in the running kernel"
+msgstr "Wyszukuje adresy w uruchomionych jądrze"
+
+#: libdwfl/argp-std.c:61
+msgid "Kernel with all modules"
+msgstr "Jądro ze wszystkimi modułami"
+
+#: libdwfl/argp-std.c:63 src/stack.c:646
+msgid "Search path for separate debuginfo files"
+msgstr "Wyszukuje ścieżkę dla oddzielnych plików debuginfo"
+
+#: libdwfl/argp-std.c:164
+msgid "only one of -e, -p, -k, -K, or --core allowed"
+msgstr "dopuszczalna jest tylko jedna z opcji -e, -p, -k, -K lub --core"
+
+#: libdwfl/argp-std.c:237
+msgid "cannot load kernel symbols"
+msgstr "nie można wczytać symboli jądra"
+
+#. Non-fatal to have no modules since we do have the kernel.
+#: libdwfl/argp-std.c:241
+msgid "cannot find kernel modules"
+msgstr "nie można odnaleźć modułów jądra"
+
+#: libdwfl/argp-std.c:258
+msgid "cannot find kernel or modules"
+msgstr "nie można odnaleźć jądra lub modułów"
+
+#: libdwfl/argp-std.c:297
+#, c-format
+msgid "cannot read ELF core file: %s"
+msgstr "nie można odczytać pliku core ELF: %s"
+
+#: libdwfl/argp-std.c:320
+msgid "Not enough memory"
+msgstr "Za mało pamięci"
+
+#: libdwfl/argp-std.c:330
+msgid "No modules recognized in core file"
+msgstr "Nie rozpoznano żadnych modułów w pliku core"
+
+#: libdwfl/libdwflP.h:53
+msgid "See errno"
+msgstr "Proszę zobaczyć errno"
+
+#: libdwfl/libdwflP.h:54
+msgid "See elf_errno"
+msgstr "Proszę zobaczyć elf_errno"
+
+#: libdwfl/libdwflP.h:55
+msgid "See dwarf_errno"
+msgstr "Proszę zobaczyć dwarf_errno"
+
+#: libdwfl/libdwflP.h:56
+msgid "See ebl_errno (XXX missing)"
+msgstr "Proszę zobaczyć ebl_errno (brak XXX)"
+
+#: libdwfl/libdwflP.h:57
+msgid "gzip decompression failed"
+msgstr "dekompresja gzip się nie powiodła"
+
+#: libdwfl/libdwflP.h:58
+msgid "bzip2 decompression failed"
+msgstr "dekompresja bzip2 się nie powiodła"
+
+#: libdwfl/libdwflP.h:59
+msgid "LZMA decompression failed"
+msgstr "dekompresja LZMA się nie powiodła"
+
+#: libdwfl/libdwflP.h:60
+msgid "no support library found for machine"
+msgstr "nie odnaleziono biblioteki obsługi dla komputera"
+
+#: libdwfl/libdwflP.h:61
+msgid "Callbacks missing for ET_REL file"
+msgstr "Brak wywołań zwrotnych dla pliku ET_REL"
+
+#: libdwfl/libdwflP.h:62
+msgid "Unsupported relocation type"
+msgstr "Nieobsługiwany typ relokacji"
+
+#: libdwfl/libdwflP.h:63
+msgid "r_offset is bogus"
+msgstr "r_offset jest fałszywe"
+
+#: libdwfl/libdwflP.h:64 libelf/elf_error.c:111 libelf/elf_error.c:171
+msgid "offset out of range"
+msgstr "offset spoza zakresu"
+
+#: libdwfl/libdwflP.h:65
+msgid "relocation refers to undefined symbol"
+msgstr "relokacja odnosi się do nieokreślonego symbolu"
+
+#: libdwfl/libdwflP.h:66
+msgid "Callback returned failure"
+msgstr "Wywołanie zwrotne zwróciło niepowodzenie"
+
+#: libdwfl/libdwflP.h:67
+msgid "No DWARF information found"
+msgstr "Nie odnaleziono informacji DWARF"
+
+#: libdwfl/libdwflP.h:68
+msgid "No symbol table found"
+msgstr "Nie odnaleziono tabeli symboli"
+
+#: libdwfl/libdwflP.h:69
+msgid "No ELF program headers"
+msgstr "Brak nagłówków programu ELF"
+
+#: libdwfl/libdwflP.h:70
+msgid "address range overlaps an existing module"
+msgstr "zakres adresów pokrywa się z istniejącym modułem"
+
+#: libdwfl/libdwflP.h:73
+msgid "image truncated"
+msgstr "skrócono obraz"
+
+#: libdwfl/libdwflP.h:74
+msgid "ELF file opened"
+msgstr "otwarto plik ELF"
+
+#: libdwfl/libdwflP.h:75
+msgid "not a valid ELF file"
+msgstr "nie jest prawidłowym plikiem ELF"
+
+#: libdwfl/libdwflP.h:76
+msgid "cannot handle DWARF type description"
+msgstr "nie można obsłużyć opisu typu DWARF"
+
+#: libdwfl/libdwflP.h:77
+msgid "ELF file does not match build ID"
+msgstr "plik ELF nie ma pasującego identyfikatora kopii"
+
+#: libdwfl/libdwflP.h:78
+msgid "corrupt .gnu.prelink_undo section data"
+msgstr "uszkodzone dane sekcji .gnu.prelink_undo"
+
+#: libdwfl/libdwflP.h:79
+msgid "Internal error due to ebl"
+msgstr "Wewnętrzny błąd z powodu ebl"
+
+#: libdwfl/libdwflP.h:80
+msgid "Missing data in core file"
+msgstr "Brak danych w pliku core"
+
+#: libdwfl/libdwflP.h:81
+msgid "Invalid register"
+msgstr "Nieprawidłowy rejestr"
+
+#: libdwfl/libdwflP.h:82
+msgid "Error reading process memory"
+msgstr "Błąd podczas odczytywania pamięci procesu"
+
+#: libdwfl/libdwflP.h:83
+msgid "Couldn't find architecture of any ELF"
+msgstr "Nie można odnaleźć architektury żadnego ELF"
+
+#: libdwfl/libdwflP.h:84
+msgid "Error parsing /proc filesystem"
+msgstr "Błąd podczas przetwarzania systemu plików /proc"
+
+#: libdwfl/libdwflP.h:85
+msgid "Invalid DWARF"
+msgstr "Nieprawidłowy DWARF"
+
+#: libdwfl/libdwflP.h:86
+msgid "Unsupported DWARF"
+msgstr "Nieobsługiwany DWARF"
+
+#: libdwfl/libdwflP.h:87
+msgid "Unable to find more threads"
+msgstr "Nie można odnaleźć więcej wątków"
+
+#: libdwfl/libdwflP.h:88
+msgid "Dwfl already has attached state"
+msgstr "Dwfl już ma załączony stan"
+
+#: libdwfl/libdwflP.h:89
+msgid "Dwfl has no attached state"
+msgstr "Dwfl nie ma załączonego stanu"
+
+#: libdwfl/libdwflP.h:90
+msgid "Unwinding not supported for this architecture"
+msgstr "Odwijanie nie jest obsługiwane dla tej architektury"
+
+#: libdwfl/libdwflP.h:91
+msgid "Invalid argument"
+msgstr "Nieprawidłowy parametr"
+
+#: libdwfl/libdwflP.h:92
+msgid "Not an ET_CORE ELF file"
+msgstr "Nie jest plikiem ELF ET_CORE"
+
+#: libebl/eblbackendname.c:41
+msgid "No backend"
+msgstr "Brak zaplecza"
+
+#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:76
+#: libebl/eblobjnotetypename.c:83 libebl/eblobjnotetypename.c:102
+#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83
+#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:79
+msgid "<unknown>"
+msgstr "<nieznany>"
+
+#: libebl/ebldynamictagname.c:101
+#, c-format
+msgid "<unknown>: %#<PRIx64>"
+msgstr "<nieznany>: %#<PRIx64>"
+
+#: libebl/eblobjnote.c:53
+#, c-format
+msgid "unknown SDT version %u\n"
+msgstr "nieznana wersja SDT %u\n"
+
+#: libebl/eblobjnote.c:71
+#, c-format
+msgid "invalid SDT probe descriptor\n"
+msgstr "nieprawidłowy deskryptor sondy SDT\n"
+
+#: libebl/eblobjnote.c:121
+#, c-format
+msgid "    PC: "
+msgstr "    PC: "
+
+#: libebl/eblobjnote.c:123
+#, c-format
+msgid " Base: "
+msgstr " Podstawa: "
+
+#: libebl/eblobjnote.c:125
+#, c-format
+msgid " Semaphore: "
+msgstr " Semafor: "
+
+#: libebl/eblobjnote.c:127
+#, c-format
+msgid "    Provider: "
+msgstr "    Dostawca: "
+
+#: libebl/eblobjnote.c:129
+#, c-format
+msgid " Name: "
+msgstr " Nazwa: "
+
+#: libebl/eblobjnote.c:131
+#, c-format
+msgid " Args: "
+msgstr " Parametry: "
+
+#: libebl/eblobjnote.c:141
+#, c-format
+msgid "    Build ID: "
+msgstr "    Identyfikator kopii: "
+
+#. A non-null terminated version string.
+#: libebl/eblobjnote.c:152
+#, c-format
+msgid "    Linker version: %.*s\n"
+msgstr "    Wersja konsolidatora: %.*s\n"
+
+#: libebl/eblobjnote.c:213
+#, c-format
+msgid "    OS: %s, ABI: "
+msgstr "    System operacyjny: %s, ABI: "
+
+#: libebl/eblosabiname.c:70
+msgid "Stand alone"
+msgstr "Samodzielny"
+
+#: libebl/eblsymbolbindingname.c:67 libebl/eblsymboltypename.c:73
+#, c-format
+msgid "<unknown>: %d"
+msgstr "<nieznany>: %d"
+
+#: libelf/elf_error.c:67
+msgid "unknown version"
+msgstr "nieznana wersja"
+
+#: libelf/elf_error.c:71
+msgid "unknown type"
+msgstr "nieznany typ"
+
+#: libelf/elf_error.c:75
+msgid "invalid `Elf' handle"
+msgstr "nieprawidłowa obsługa „Elf”"
+
+#: libelf/elf_error.c:79
+msgid "invalid size of source operand"
+msgstr "nieprawidłowy rozmiar operanda źródłowego"
+
+#: libelf/elf_error.c:83
+msgid "invalid size of destination operand"
+msgstr "nieprawidłowy rozmiar operanda docelowego"
+
+#: libelf/elf_error.c:87 src/readelf.c:5153
+#, c-format
+msgid "invalid encoding"
+msgstr "nieprawidłowe kodowanie"
+
+#: libelf/elf_error.c:95
+msgid "invalid file descriptor"
+msgstr "nieprawidłowy deskryptor pliku"
+
+#: libelf/elf_error.c:99
+msgid "invalid operation"
+msgstr "nieprawidłowe działanie"
+
+#: libelf/elf_error.c:103
+msgid "ELF version not set"
+msgstr "wersja ELF nie została ustawiona"
+
+#: libelf/elf_error.c:115
+msgid "invalid fmag field in archive header"
+msgstr "nieprawidłowe pole fmag w nagłówku archiwum"
+
+#: libelf/elf_error.c:119
+msgid "invalid archive file"
+msgstr "nieprawidłowy plik archiwum"
+
+#: libelf/elf_error.c:123
+msgid "descriptor is not for an archive"
+msgstr "deskryptor nie jest dla archiwum"
+
+#: libelf/elf_error.c:127
+msgid "no index available"
+msgstr "brak dostępnego indeksu"
+
+#: libelf/elf_error.c:131
+msgid "cannot read data from file"
+msgstr "nie można odczytać danych z pliku"
+
+#: libelf/elf_error.c:135
+msgid "cannot write data to file"
+msgstr "nie można zapisać danych do pliku"
+
+#: libelf/elf_error.c:139
+msgid "invalid binary class"
+msgstr "nieprawidłowa klasa pliku binarnego"
+
+#: libelf/elf_error.c:143
+msgid "invalid section index"
+msgstr "nieprawidłowy indeks sekcji"
+
+#: libelf/elf_error.c:147
+msgid "invalid operand"
+msgstr "nieprawidłowy operand"
+
+#: libelf/elf_error.c:151
+msgid "invalid section"
+msgstr "nieprawidłowa sekcja"
+
+#: libelf/elf_error.c:159
+msgid "executable header not created first"
+msgstr "nie utworzono najpierw nagłówka pliku wykonywalnego"
+
+#: libelf/elf_error.c:163
+msgid "file descriptor disabled"
+msgstr "deskryptor pliku jest wyłączony"
+
+#: libelf/elf_error.c:167
+msgid "archive/member file descriptor mismatch"
+msgstr "deskryptory archiwum/elementu nie zgadzają się"
+
+#: libelf/elf_error.c:175
+msgid "cannot manipulate null section"
+msgstr "nie można zmieniać pustej sekcji"
+
+#: libelf/elf_error.c:179
+msgid "data/scn mismatch"
+msgstr "dane/scn nie zgadzają się"
+
+#: libelf/elf_error.c:183
+msgid "invalid section header"
+msgstr "nieprawidłowy nagłówek sekcji"
+
+#: libelf/elf_error.c:187 src/readelf.c:7403 src/readelf.c:7914
+#: src/readelf.c:8015 src/readelf.c:8196
+#, c-format
+msgid "invalid data"
+msgstr "nieprawidłowe dane"
+
+#: libelf/elf_error.c:191
+msgid "unknown data encoding"
+msgstr "nieznane kodowanie danych"
+
+#: libelf/elf_error.c:195
+msgid "section `sh_size' too small for data"
+msgstr "sekcja „sh_size” jest za mała dla danych"
+
+#: libelf/elf_error.c:199
+msgid "invalid section alignment"
+msgstr "nieprawidłowe wyrównanie sekcji"
+
+#: libelf/elf_error.c:203
+msgid "invalid section entry size"
+msgstr "nieprawidłowy rozmiar wpisu sekcji"
+
+#: libelf/elf_error.c:207
+msgid "update() for write on read-only file"
+msgstr "update() dla zapisu pliku tylko do odczytu"
+
+#: libelf/elf_error.c:211
+msgid "no such file"
+msgstr "nie ma takiego pliku"
+
+#: libelf/elf_error.c:215
+msgid "only relocatable files can contain section groups"
+msgstr "tylko relokowalne pliki mogą zawierać grupy sekcji"
+
+#: libelf/elf_error.c:220
+msgid ""
+"program header only allowed in executables, shared objects, and core files"
+msgstr ""
+"tylko pliki wykonywalne, obiektów współdzielone i pliki core mogą mieć "
+"nagłówki programu"
+
+#: libelf/elf_error.c:227
+msgid "file has no program header"
+msgstr "plik nie ma nagłówków programu"
+
+#: libelf/elf_error.c:237
+msgid "invalid section type"
+msgstr "nieprawidłowy typ sekcji"
+
+#: libelf/elf_error.c:242
+msgid "invalid section flags"
+msgstr "nieprawidłowe flagi sekcji"
+
+#: libelf/elf_error.c:247
+msgid "section does not contain compressed data"
+msgstr "sekcja nie zawiera skompresowanych danych"
+
+#: libelf/elf_error.c:252
+msgid "section contains compressed data"
+msgstr "sekcja zawiera skompresowane dane"
+
+#: libelf/elf_error.c:257
+msgid "unknown compression type"
+msgstr "nieznany typ kompresji"
+
+#: libelf/elf_error.c:262
+msgid "cannot compress data"
+msgstr "nie można kompresować danych"
+
+#: libelf/elf_error.c:267
+msgid "cannot decompress data"
+msgstr "nie można dekompresować danych"
+
+#: src/addr2line.c:58
+msgid "Input format options:"
+msgstr "Opcje formatowania wejścia:"
+
+#: src/addr2line.c:60
+msgid "Treat addresses as offsets relative to NAME section."
+msgstr "Traktuje adresy jako offsety względne do sekcji NAZWA."
+
+#: src/addr2line.c:62
+msgid "Output format options:"
+msgstr "Opcje formatowania wyjścia:"
+
+#: src/addr2line.c:63
+msgid "Print address before each entry"
+msgstr "Wyświetla adres pliku przed każdym wpisem"
+
+#: src/addr2line.c:64
+msgid "Show only base names of source files"
+msgstr "Wyświetla tylko podstawowe nazwy plików źródłowych"
+
+#: src/addr2line.c:66
+msgid "Show absolute file names using compilation directory"
+msgstr "Wyświetla bezwzględne nazwy plików używając katalogu kompilacji"
+
+#: src/addr2line.c:67
+msgid "Also show function names"
+msgstr "Wyświetla także nazwy funkcji"
+
+#: src/addr2line.c:68
+msgid "Also show symbol or section names"
+msgstr "Wyświetla także nazwy symboli lub sekcji"
+
+#: src/addr2line.c:69
+msgid "Also show symbol and the section names"
+msgstr "Wyświetla także nazwy symboli i sekcji"
+
+#: src/addr2line.c:70
+msgid "Also show line table flags"
+msgstr "Wyświetla także flagi tabeli wierszy"
+
+#: src/addr2line.c:72
+msgid ""
+"Show all source locations that caused inline expansion of subroutines at the "
+"address."
+msgstr ""
+"Wyświetla wszystkie położenia źródłowe, które spowodowały wstawione "
+"rozszerzenie podprogramów pod tym adresem."
+
+#: src/addr2line.c:75
+msgid "Show demangled symbols (ARG is always ignored)"
+msgstr ""
+"Wyświetla symbole z usuniętym dekorowaniem (PARAMETR jest zawsze ignorowany)"
+
+#: src/addr2line.c:77
+msgid "Print all information on one line, and indent inlines"
+msgstr "Wyświetla wszystkie informacje w jednym wierszy i wyrównuje wstawki"
+
+#: src/addr2line.c:79 src/elfcmp.c:71 src/findtextrel.c:66 src/nm.c:101
+#: src/strings.c:79
+msgid "Miscellaneous:"
+msgstr "Różne:"
+
+#. Short description of program.
+#: src/addr2line.c:87
+msgid ""
+"Locate source files and line information for ADDRs (in a.out by default)."
+msgstr ""
+"Odnajdywanie plików źródłowych i informacji o wierszu dla ADRESU (domyślne "
+"w a.out)."
+
+#. Strings for arguments in help texts.
+#: src/addr2line.c:91
+msgid "[ADDR...]"
+msgstr "[ADRES…]"
+
+#: src/addr2line.c:519
+#, c-format
+msgid "Section syntax requires exactly one module"
+msgstr "Składnia sekcji wymaga dokładnie jednego modułu"
+
+#: src/addr2line.c:542
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside section '%s'"
+msgstr "offset %#<PRIxMAX> leży poza sekcją „%s”"
+
+#: src/addr2line.c:632
+#, c-format
+msgid "cannot find symbol '%s'"
+msgstr "nie można odnaleźć symbolu „%s”"
+
+#: src/addr2line.c:637
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside contents of '%s'"
+msgstr "offset %#<PRIxMAX> leży poza zawartością „%s”"
+
+#: src/ar.c:68
+msgid "Commands:"
+msgstr "Polecenia:"
+
+#: src/ar.c:69
+msgid "Delete files from archive."
+msgstr "Usuwa pliki z archiwum."
+
+#: src/ar.c:70
+msgid "Move files in archive."
+msgstr "Przenosi pliki w archiwum."
+
+#: src/ar.c:71
+msgid "Print files in archive."
+msgstr "Wyświetla pliki w archiwum."
+
+#: src/ar.c:72
+msgid "Quick append files to archive."
+msgstr "Szybko dodaje pliki do archiwum."
+
+#: src/ar.c:74
+msgid "Replace existing or insert new file into archive."
+msgstr "Zastępuje istniejący lub umieszcza nowy plik w archiwum."
+
+#: src/ar.c:75
+msgid "Display content of archive."
+msgstr "Wyświetla zawartość archiwum."
+
+#: src/ar.c:76
+msgid "Extract files from archive."
+msgstr "Wypakowuje pliki z archiwum."
+
+#: src/ar.c:78
+msgid "Command Modifiers:"
+msgstr "Modyfikatory poleceń:"
+
+#: src/ar.c:79
+msgid "Preserve original dates."
+msgstr "Zachowuje pierwotne daty."
+
+#: src/ar.c:80
+msgid "Use instance [COUNT] of name."
+msgstr "Używa wystąpienia [LICZNIK] nazwy."
+
+#: src/ar.c:82
+msgid "Do not replace existing files with extracted files."
+msgstr "Nie zastępuje istniejących plików wypakowanymi plikami."
+
+#: src/ar.c:83
+msgid "Allow filename to be truncated if necessary."
+msgstr "Zezwala na skrócenie nazwy pliku, jeśli jest to wymagane."
+
+#: src/ar.c:85
+msgid "Provide verbose output."
+msgstr "Wyświetla więcej informacji."
+
+#: src/ar.c:86
+msgid "Force regeneration of symbol table."
+msgstr "Wymusza ponowne utworzenie tabeli symboli."
+
+#: src/ar.c:87
+msgid "Insert file after [MEMBER]."
+msgstr "Umieszcza plik po [ELEMENCIE]."
+
+#: src/ar.c:88
+msgid "Insert file before [MEMBER]."
+msgstr "Umieszcza plik przed [ELEMENTEM]."
+
+#: src/ar.c:89
+msgid "Same as -b."
+msgstr "To samo, co -b."
+
+#: src/ar.c:90
+msgid "Suppress message when library has to be created."
+msgstr "Zmniejsza komunikat, jeśli biblioteka musi zostać utworzona."
+
+#: src/ar.c:92
+msgid "Use full path for file matching."
+msgstr "Używa pełnej ścieżki do dopasowywania plików."
+
+#: src/ar.c:93
+msgid "Update only older files in archive."
+msgstr "Aktualizuje tylko starsze pliki w archiwum."
+
+#. Short description of program.
+#: src/ar.c:99
+msgid "Create, modify, and extract from archives."
+msgstr "Tworzenie, modyfikowanie i wypakowywanie archiwów."
+
+#. Strings for arguments in help texts.
+#: src/ar.c:102
+msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]"
+msgstr "[ELEMENT] [LICZNIK] ARCHIWUM [PLIK…]"
+
+#: src/ar.c:181
+#, c-format
+msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options"
+msgstr "„a”, „b” i „i” są dozwolone tylko z opcjami „m” i „r”"
+
+#: src/ar.c:186
+#, c-format
+msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers"
+msgstr "parametr ELEMENT jest wymagany dla modyfikatorów „a”, „b” i „i”"
+
+#: src/ar.c:202
+#, c-format
+msgid "'N' is only meaningful with the 'x' and 'd' options"
+msgstr "„N” ma znaczenie tylko z opcjami „x” i „d”"
+
+#: src/ar.c:207
+#, c-format
+msgid "COUNT parameter required"
+msgstr "wymagany jest parametr LICZNIK"
+
+#: src/ar.c:219
+#, c-format
+msgid "invalid COUNT parameter %s"
+msgstr "nieprawidłowy parametr LICZNIK %s"
+
+#: src/ar.c:226
+#, c-format
+msgid "'%c' is only meaningful with the 'x' option"
+msgstr "„%c” ma znaczenie tylko z opcją „x”"
+
+#: src/ar.c:232
+#, c-format
+msgid "archive name required"
+msgstr "wymagana jest nazwa archiwum"
+
+#: src/ar.c:245
+#, c-format
+msgid "command option required"
+msgstr "wymagana jest opcja polecenia"
+
+#: src/ar.c:296
+#, c-format
+msgid "More than one operation specified"
+msgstr "Podano więcej niż jedno działanie"
+
+#: src/ar.c:390
+#, c-format
+msgid "cannot open archive '%s'"
+msgstr "nie można otworzyć archiwum „%s”"
+
+#: src/ar.c:400
+#, c-format
+msgid "cannot open archive '%s': %s"
+msgstr "nie można otworzyć archiwum „%s”: %s"
+
+#: src/ar.c:404
+#, c-format
+msgid "%s: not an archive file"
+msgstr "%s: nie jest plikiem archiwum"
+
+#: src/ar.c:408
+#, c-format
+msgid "cannot stat archive '%s'"
+msgstr "nie można wykonać stat na archiwum „%s”"
+
+#: src/ar.c:420
+#, c-format
+msgid "no entry %s in archive\n"
+msgstr "brak wpisu %s w archiwum\n"
+
+#: src/ar.c:473 src/ar.c:918 src/ar.c:1118
+#, c-format
+msgid "cannot create hash table"
+msgstr "nie można utworzyć tabeli mieszającej"
+
+#: src/ar.c:480 src/ar.c:925 src/ar.c:1127
+#, c-format
+msgid "cannot insert into hash table"
+msgstr "nie można umieścić w tabeli mieszającej"
+
+#: src/ar.c:488 src/ranlib.c:149
+#, c-format
+msgid "cannot stat '%s'"
+msgstr "nie można wykonać stat na „%s”"
+
+#: src/ar.c:584
+#, c-format
+msgid "cannot read content of %s: %s"
+msgstr "nie można odczytać zawartości %s: %s"
+
+#: src/ar.c:627
+#, c-format
+msgid "cannot open %.*s"
+msgstr "nie można otworzyć %.*s"
+
+#: src/ar.c:649
+#, c-format
+msgid "failed to write %s"
+msgstr "zapisanie %s się nie powiodło"
+
+#: src/ar.c:661
+#, c-format
+msgid "cannot change mode of %s"
+msgstr "nie można zmienić trybu %s"
+
+#: src/ar.c:677
+#, c-format
+msgid "cannot change modification time of %s"
+msgstr "nie można zmienić czasu modyfikacji %s"
+
+#: src/ar.c:723
+#, c-format
+msgid "cannot rename temporary file to %.*s"
+msgstr "nie można zmienić nazwy pliku tymczasowego na %.*s"
+
+#: src/ar.c:759 src/ar.c:1010 src/ar.c:1409 src/ranlib.c:223
+#, c-format
+msgid "cannot create new file"
+msgstr "nie można utworzyć nowego pliku"
+
+#: src/ar.c:1209
+#, c-format
+msgid "position member %s not found"
+msgstr "nie odnaleziono położenia elementu %s"
+
+#: src/ar.c:1219
+#, c-format
+msgid "%s: no entry %s in archive!\n"
+msgstr "%s: brak wpisu %s w archiwum.\n"
+
+#: src/ar.c:1248 src/objdump.c:242
+#, c-format
+msgid "cannot open %s"
+msgstr "nie można otworzyć %s"
+
+#: src/ar.c:1253
+#, c-format
+msgid "cannot stat %s"
+msgstr "nie można wykonać stat na %s"
+
+#: src/ar.c:1259
+#, c-format
+msgid "%s is no regular file"
+msgstr "%s nie jest zwykłym plikiem"
+
+#: src/ar.c:1272
+#, c-format
+msgid "cannot get ELF descriptor for %s: %s\n"
+msgstr "nie można uzyskać deskryptora ELF dla %s: %s\n"
+
+#: src/ar.c:1292
+#, c-format
+msgid "cannot read %s: %s"
+msgstr "nie można odczytać %s: %s"
+
+#: src/arlib-argp.c:32
+msgid "Use zero for uid, gid, and date in archive members."
+msgstr "Używa zero jako UID, GID i datę w elementach archiwum."
+
+#: src/arlib-argp.c:34
+msgid "Use actual uid, gid, and date in archive members."
+msgstr "Używa prawdziwe UID, GID i datę w elementach archiwum."
+
+#: src/arlib-argp.c:65
+#, c-format
+msgid "%s (default)"
+msgstr "%s (domyślnie)"
+
+#. The archive is too big.
+#: src/arlib.c:213
+#, c-format
+msgid "the archive '%s' is too large"
+msgstr "archiwum „%s” jest za duże"
+
+#: src/arlib.c:226
+#, c-format
+msgid "cannot read ELF header of %s(%s): %s"
+msgstr "nie można odczytać nagłówka ELF %s(%s): %s"
+
+#: src/elfcmp.c:61
+msgid "Control options:"
+msgstr "Opcje sterujące:"
+
+#: src/elfcmp.c:63
+msgid "Output all differences, not just the first"
+msgstr "Wyświetlanie wszystkich różnic, nie tylko pierwszej"
+
+#: src/elfcmp.c:64
+msgid ""
+"Control treatment of gaps in loadable segments [ignore|match] (default: "
+"ignore)"
+msgstr ""
+"Sterowanie traktowaniem luk w segmentach wczytywalnych [ignore|match] "
+"(domyślne: ignore)"
+
+#: src/elfcmp.c:66
+msgid "Ignore permutation of buckets in SHT_HASH section"
+msgstr "Ignorowanie permutacji kubełków w sekcji SHT_HASH"
+
+#: src/elfcmp.c:68
+msgid "Ignore differences in build ID"
+msgstr "Ignorowanie różnic w identyfikatorze kopii"
+
+#: src/elfcmp.c:69
+msgid "Output nothing; yield exit status only"
+msgstr "Bez wypisywania; przekazanie tylko kodu wyjścia"
+
+#. Short description of program.
+#: src/elfcmp.c:76
+msgid "Compare relevant parts of two ELF files for equality."
+msgstr "Porównywanie odpowiednich części dwóch plików ELF pod kątem równości."
+
+#. Strings for arguments in help texts.
+#: src/elfcmp.c:80
+msgid "FILE1 FILE2"
+msgstr "PLIK1 PLIK2"
+
+#: src/elfcmp.c:142
+msgid "Invalid number of parameters.\n"
+msgstr "Nieprawidłowa liczba parametrów.\n"
+
+#: src/elfcmp.c:173 src/elfcmp.c:178
+#, c-format
+msgid "cannot get ELF header of '%s': %s"
+msgstr "nie można uzyskać nagłówka ELF „%s”: %s"
+
+#: src/elfcmp.c:204
+#, c-format
+msgid "%s %s diff: ELF header"
+msgstr "%s %s różnią się: nagłówek ELF"
+
+#: src/elfcmp.c:211 src/elfcmp.c:214
+#, c-format
+msgid "cannot get section count of '%s': %s"
+msgstr "nie można uzyskać licznika sekcji „%s”: %s"
+
+#: src/elfcmp.c:219
+#, c-format
+msgid "%s %s diff: section count"
+msgstr "%s %s różnią się: licznik sekcji"
+
+#: src/elfcmp.c:226 src/elfcmp.c:229
+#, c-format
+msgid "cannot get program header count of '%s': %s"
+msgstr "nie można uzyskać licznika nagłówka programu „%s”: %s"
+
+#: src/elfcmp.c:234
+#, c-format
+msgid "%s %s diff: program header count"
+msgstr "%s %s różnią się: licznik nagłówka programu"
+
+#: src/elfcmp.c:292
+#, c-format
+msgid "%s %s differ: section [%zu], [%zu] name"
+msgstr "%s %s różnią się: nazwa sekcji [%zu], [%zu]"
+
+#: src/elfcmp.c:315
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' header"
+msgstr "%s %s różnią się: nagłówek sekcji [%zu] „%s”"
+
+#: src/elfcmp.c:323 src/elfcmp.c:329
+#, c-format
+msgid "cannot get content of section %zu in '%s': %s"
+msgstr "nie można uzyskać zawartości sekcji %zu w „%s”: %s"
+
+#: src/elfcmp.c:338
+#, c-format
+msgid "symbol table [%zu] in '%s' has zero sh_entsize"
+msgstr "tabela symboli [%zu] w „%s” ma zerowe sh_entsize"
+
+#: src/elfcmp.c:350 src/elfcmp.c:356
+#, c-format
+msgid "cannot get symbol in '%s': %s"
+msgstr "nie można uzyskać symbolu w „%s”: %s"
+
+#: src/elfcmp.c:378
+#, c-format
+msgid "%s %s differ: symbol table [%zu]"
+msgstr "%s %s różnią się: tabela symboli [%zu]"
+
+#: src/elfcmp.c:381
+#, c-format
+msgid "%s %s differ: symbol table [%zu,%zu]"
+msgstr "%s %s różnią się: tabela symboli [%zu,%zu]"
+
+#: src/elfcmp.c:428 src/elfcmp.c:498
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' number of notes"
+msgstr "%s %s różnią się: liczba notatek sekcji [%zu] „%s”"
+
+#: src/elfcmp.c:436
+#, c-format
+msgid "cannot read note section [%zu] '%s' in '%s': %s"
+msgstr "nie można odczytać notatki sekcji [%zu] „%s” w „%s”: %s"
+
+#: src/elfcmp.c:447
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note name"
+msgstr "%s %s różnią się: nazwa notatki sekcji [%zu] „%s”"
+
+#: src/elfcmp.c:455
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note '%s' type"
+msgstr "%s %s różnią się: sekcja [%zu] „%s” notatka „%s” typ"
+
+#: src/elfcmp.c:470
+#, c-format
+msgid "%s %s differ: build ID length"
+msgstr "%s %s różnią się: długość identyfikatora kopii"
+
+#: src/elfcmp.c:478
+#, c-format
+msgid "%s %s differ: build ID content"
+msgstr "%s %s różnią się: zawartość identyfikatora kopii"
+
+#: src/elfcmp.c:487
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note '%s' content"
+msgstr "%s %s różnią się: sekcja [%zu] „%s” notatka „%s” zawartość"
+
+#: src/elfcmp.c:528
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' content"
+msgstr "%s %s różnią się: zawartość sekcji [%zu] „%s”"
+
+#: src/elfcmp.c:532
+#, c-format
+msgid "%s %s differ: section [%zu,%zu] '%s' content"
+msgstr "%s %s różnią się: zawartość sekcji [%zu,%zu] „%s”"
+
+#: src/elfcmp.c:547
+#, c-format
+msgid "%s %s differ: unequal amount of important sections"
+msgstr "%s %s różnią się: różna liczba ważnych sekcji"
+
+#: src/elfcmp.c:580 src/elfcmp.c:585
+#, c-format
+msgid "cannot load data of '%s': %s"
+msgstr "nie można wczytać danych z „%s”: %s"
+
+#: src/elfcmp.c:604 src/elfcmp.c:610
+#, c-format
+msgid "cannot get program header entry %d of '%s': %s"
+msgstr "nie można uzyskać wpisu nagłówka programu %d z „%s”: %s"
+
+#: src/elfcmp.c:616
+#, c-format
+msgid "%s %s differ: program header %d"
+msgstr "%s %s różnią się: nagłówek programu %d"
+
+#: src/elfcmp.c:640
+#, c-format
+msgid "%s %s differ: gap"
+msgstr "%s %s różnią się: luka"
+
+#: src/elfcmp.c:691
+#, c-format
+msgid "Invalid value '%s' for --gaps parameter."
+msgstr "Nieprawidłowa wartość „%s” dla parametru --gaps."
+
+#: src/elfcmp.c:719 src/findtextrel.c:206 src/nm.c:365 src/ranlib.c:142
+#: src/size.c:273 src/strings.c:186 src/strip.c:518 src/strip.c:555
+#: src/unstrip.c:2023 src/unstrip.c:2052
+#, c-format
+msgid "cannot open '%s'"
+msgstr "nie można otworzyć „%s”"
+
+#: src/elfcmp.c:723 src/findtextrel.c:213 src/ranlib.c:159
+#, c-format
+msgid "cannot create ELF descriptor for '%s': %s"
+msgstr "nie można utworzyć deskryptora ELF dla „%s”: %s"
+
+#: src/elfcmp.c:728
+#, c-format
+msgid "cannot create EBL descriptor for '%s'"
+msgstr "nie można utworzyć deskryptora EBL dla „%s”"
+
+#: src/elfcmp.c:746 src/findtextrel.c:394
+#, c-format
+msgid "cannot get section header of section %zu: %s"
+msgstr "nie można uzyskać nagłówka sekcji dla sekcji %zu: %s"
+
+#: src/elfcmp.c:756
+#, c-format
+msgid "cannot get content of section %zu: %s"
+msgstr "nie można uzyskać zawartości sekcji %zu: %s"
+
+#: src/elfcmp.c:766 src/elfcmp.c:780
+#, c-format
+msgid "cannot get relocation: %s"
+msgstr "nie można uzyskać relokacji: %s"
+
+#: src/elfcompress.c:115 src/strip.c:297 src/unstrip.c:121
+#, c-format
+msgid "-o option specified twice"
+msgstr "Opcję -o podano dwukrotnie"
+
+#: src/elfcompress.c:122
+#, c-format
+msgid "-t option specified twice"
+msgstr "Opcję -t podano dwukrotnie"
+
+#: src/elfcompress.c:131
+#, c-format
+msgid "unknown compression type '%s'"
+msgstr "nieznany typ kompresji „%s”"
+
+#. We need at least one input file.
+#: src/elfcompress.c:143 src/elfcompress.c:1305
+#, c-format
+msgid "No input file given"
+msgstr "Nie podano pliku wejściowego"
+
+#: src/elfcompress.c:149 src/elfcompress.c:1310
+#, c-format
+msgid "Only one input file allowed together with '-o'"
+msgstr "Tylko jeden plik wejściowy jest dozwolony z „-o”"
+
+#: src/elfcompress.c:1267
+msgid "Place (de)compressed output into FILE"
+msgstr "Umieszcza zdekompresowane wyjście w PLIKU"
+
+#: src/elfcompress.c:1270
+msgid ""
+"What type of compression to apply. TYPE can be 'none' (decompress), "
+"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-"
+"gnu' (.zdebug GNU style compression, 'gnu' is an alias)"
+msgstr ""
+"Typ stosowanej kompresji. TYP może wynosić „none” (dekompresja), "
+"„zlib” (kompresja zlib ELF, domyślna, „zlib-gabi” to alias) lub „zlib-"
+"gnu” (kompresja .zdebug w stylu GNU, „gnu” to alias)"
+
+#: src/elfcompress.c:1273
+msgid ""
+"SECTION name to (de)compress, SECTION is an extended wildcard pattern "
+"(defaults to '.?(z)debug*')"
+msgstr ""
+"Nazwa SEKCJI do (de)kompresowania, SEKCJA jest rozszerzonym wzorem "
+"(domyślnie „.?(z)debug*”)"
+
+#: src/elfcompress.c:1276
+msgid "Print a message for each section being (de)compressed"
+msgstr "Wyświetla komunikat dla każdej (de)kompresowanej sekcji"
+
+#: src/elfcompress.c:1279
+msgid "Force compression of section even if it would become larger"
+msgstr "Wymusza kompresję sekcji nawet, jeśli spowodowałoby to jej zwiększenie"
+
+#: src/elfcompress.c:1282 src/strip.c:91
+msgid "Relax a few rules to handle slightly broken ELF files"
+msgstr "Łagodzi kilka reguł, aby obsłużyć lekko uszkodzone pliki ELF"
+
+#: src/elfcompress.c:1285
+msgid "Be silent when a section cannot be compressed"
+msgstr "Bez zgłaszania, kiedy nie można zdekompresować sekcji"
+
+#. Strings for arguments in help texts.
+#: src/elfcompress.c:1294 src/elflint.c:78 src/readelf.c:142
+msgid "FILE..."
+msgstr "PLIK…"
+
+#: src/elfcompress.c:1295
+msgid "Compress or decompress sections in an ELF file."
+msgstr "Kompresuje lub dekompresuje sekcje w pliku ELF."
+
+#: src/elflint.c:64
+msgid "Be extremely strict, flag level 2 features."
+msgstr "Bardzo ścisłe sprawdzanie, cechy poziomu 2 flag."
+
+#: src/elflint.c:65
+msgid "Do not print anything if successful"
+msgstr "Nie wypisywanie niczego w przypadku powodzenia"
+
+#: src/elflint.c:66
+msgid "Binary is a separate debuginfo file"
+msgstr "Plik binarny jest oddzielnym plikiem debuginfo"
+
+#: src/elflint.c:68
+msgid ""
+"Binary has been created with GNU ld and is therefore known to be broken in "
+"certain ways"
+msgstr ""
+"Plik binarny został utworzony przez program GNU ld, przez co jest uszkodzony "
+"w pewien sposób"
+
+#. Short description of program.
+#: src/elflint.c:74
+msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
+msgstr ""
+"Szczegółowe sprawdzanie zgodności plików ELF ze specyfikacją gABI/psABI."
+
+#: src/elflint.c:155 src/readelf.c:317
+#, c-format
+msgid "cannot open input file"
+msgstr "nie można otworzyć pliku wejściowego"
+
+#: src/elflint.c:162
+#, c-format
+msgid "cannot generate Elf descriptor: %s\n"
+msgstr "nie można utworzyć deskryptora ELF: %s\n"
+
+#: src/elflint.c:181
+#, c-format
+msgid "error while closing Elf descriptor: %s\n"
+msgstr "błąd podczas zamykania deskryptora ELF: %s\n"
+
+#: src/elflint.c:185
+msgid "No errors"
+msgstr "Brak błędów"
+
+#: src/elflint.c:220 src/readelf.c:494
+msgid "Missing file name.\n"
+msgstr "Brak nazwy pliku.\n"
+
+#: src/elflint.c:285
+#, c-format
+msgid " error while freeing sub-ELF descriptor: %s\n"
+msgstr " błąd podczas zwalniania deskryptora pod-ELF: %s\n"
+
+#. We cannot do anything.
+#: src/elflint.c:293
+#, c-format
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr "To nie jest plik ELF — ma błędne bajty magiczne na początku\n"
+
+#: src/elflint.c:358
+#, c-format
+msgid "e_ident[%d] == %d is no known class\n"
+msgstr "e_ident[%d] == %d nie jest znaną klasą\n"
+
+#: src/elflint.c:363
+#, c-format
+msgid "e_ident[%d] == %d is no known data encoding\n"
+msgstr "e_ident[%d] == %d nie jest znanym kodowaniem danych\n"
+
+#: src/elflint.c:367
+#, c-format
+msgid "unknown ELF header version number e_ident[%d] == %d\n"
+msgstr "nieznany numer wersji nagłówka ELF e_ident[%d] == %d\n"
+
+#: src/elflint.c:375
+#, c-format
+msgid "unsupported OS ABI e_ident[%d] == '%s'\n"
+msgstr "nieobsługiwane ABI systemu operacyjnego e_ident[%d] == „%s”\n"
+
+#: src/elflint.c:381
+#, c-format
+msgid "unsupport ABI version e_ident[%d] == %d\n"
+msgstr "nieobsługiwana wersja ABI e_ident[%d] == %d\n"
+
+#: src/elflint.c:386
+#, c-format
+msgid "e_ident[%zu] is not zero\n"
+msgstr "e_ident[%zu] nie wynosi zero\n"
+
+#: src/elflint.c:391
+#, c-format
+msgid "unknown object file type %d\n"
+msgstr "nieznany typ pliku obiektu %d\n"
+
+#: src/elflint.c:398
+#, c-format
+msgid "unknown machine type %d\n"
+msgstr "nieznany typ komputera %d\n"
+
+#: src/elflint.c:402
+#, c-format
+msgid "unknown object file version\n"
+msgstr "nieznana wersja pliku obiektu\n"
+
+#: src/elflint.c:408
+#, c-format
+msgid "invalid program header offset\n"
+msgstr "nieprawidłowy offset nagłówka programu\n"
+
+#: src/elflint.c:410
+#, c-format
+msgid "executables and DSOs cannot have zero program header offset\n"
+msgstr ""
+"pliki wykonywalne i DSO nie mogą mieć zerowego offsetu nagłówka programu\n"
+
+#: src/elflint.c:414
+#, c-format
+msgid "invalid number of program header entries\n"
+msgstr "nieprawidłowa liczba wpisów nagłówka programu\n"
+
+#: src/elflint.c:422
+#, c-format
+msgid "invalid section header table offset\n"
+msgstr "nieprawidłowy offset tabeli nagłówków sekcji\n"
+
+#: src/elflint.c:425
+#, c-format
+msgid "section header table must be present\n"
+msgstr "tabela nagłówków sekcji musi istnieć\n"
+
+#: src/elflint.c:439
+#, c-format
+msgid "invalid number of section header table entries\n"
+msgstr "nieprawidłowa liczba wpisów tabeli nagłówków sekcji\n"
+
+#: src/elflint.c:456
+#, c-format
+msgid "invalid section header index\n"
+msgstr "nieprawidłowy indeks nagłówka sekcji\n"
+
+#: src/elflint.c:474
+#, c-format
+msgid "Can only check %u headers, shnum was %u\n"
+msgstr ""
+
+#: src/elflint.c:488
+#, c-format
+msgid "invalid number of program header table entries\n"
+msgstr "nieprawidłowa liczba wpisów tabeli nagłówka programu\n"
+
+#: src/elflint.c:505
+#, c-format
+msgid "Can only check %u headers, phnum was %u\n"
+msgstr ""
+
+#: src/elflint.c:510
+#, c-format
+msgid "invalid machine flags: %s\n"
+msgstr "nieprawidłowe flagi komputera: %s\n"
+
+#: src/elflint.c:517 src/elflint.c:534
+#, c-format
+msgid "invalid ELF header size: %hd\n"
+msgstr "nieprawidłowy rozmiar nagłówka ELF: %hd\n"
+
+#: src/elflint.c:520 src/elflint.c:537
+#, c-format
+msgid "invalid program header size: %hd\n"
+msgstr "nieprawidłowa rozmiar nagłówka programu: %hd\n"
+
+#: src/elflint.c:523 src/elflint.c:540
+#, c-format
+msgid "invalid program header position or size\n"
+msgstr "nieprawidłowe położenie lub rozmiar nagłówka programu\n"
+
+#: src/elflint.c:526 src/elflint.c:543
+#, c-format
+msgid "invalid section header size: %hd\n"
+msgstr "nieprawidłowy rozmiar nagłówka sekcji: %hd\n"
+
+#: src/elflint.c:529 src/elflint.c:546
+#, c-format
+msgid "invalid section header position or size\n"
+msgstr "nieprawidłowe położenie lub rozmiar nagłówka sekcji\n"
+
+#: src/elflint.c:591
+#, c-format
+msgid ""
+"section [%2d] '%s': section with SHF_GROUP flag set not part of a section "
+"group\n"
+msgstr ""
+"sekcja [%2d] „%s”: sekcja z flagą SHF_GROUP nie jest częścią grupy sekcji\n"
+
+#: src/elflint.c:595
+#, c-format
+msgid ""
+"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"
+msgstr ""
+"sekcja [%2d] „%s”: grupa sekcji [%2zu] „%s” nie poprzedza elementu grupy\n"
+
+#: src/elflint.c:611 src/elflint.c:1495 src/elflint.c:1546 src/elflint.c:1652
+#: src/elflint.c:1988 src/elflint.c:2311 src/elflint.c:2930 src/elflint.c:3093
+#: src/elflint.c:3241 src/elflint.c:3431 src/elflint.c:4399
+#, c-format
+msgid "section [%2d] '%s': cannot get section data\n"
+msgstr "sekcja [%2d] „%s”: nie można uzyskać danych sekcji\n"
+
+#: src/elflint.c:624 src/elflint.c:1659
+#, c-format
+msgid ""
+"section [%2d] '%s': referenced as string table for section [%2d] '%s' but "
+"type is not SHT_STRTAB\n"
+msgstr ""
+"sekcja [%2d] „%s”: użyta jako tabela ciągów dla sekcji [%2d] „%s”, ale nie "
+"jest typu SHT_STRTAB\n"
+
+#: src/elflint.c:647
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol table cannot have more than one extended index "
+"section\n"
+msgstr ""
+"sekcja [%2d] „%s”: tabela symboli nie może mieć więcej niż jednej "
+"rozszerzonej sekcji indeksów\n"
+
+#: src/elflint.c:659
+#, c-format
+msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n"
+msgstr "sekcja [%2u] „%s”: rozmiar wpisu nie zgadza się z ElfXX_Sym\n"
+
+#: src/elflint.c:668
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %d: %s\n"
+msgstr "sekcja [%2d] „%s”: nie można uzyskać symbolu %d: %s\n"
+
+#: src/elflint.c:673 src/elflint.c:676 src/elflint.c:679 src/elflint.c:682
+#: src/elflint.c:685 src/elflint.c:688
+#, c-format
+msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n"
+msgstr "sekcja [%2d] „%s”: „%s” w zerowym wpisie nie jest zerem\n"
+
+#: src/elflint.c:691
+#, c-format
+msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n"
+msgstr "sekcja [%2d] „%s”: XINDEX dla zerowego wpisu nie jest zerem\n"
+
+#: src/elflint.c:701
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %zu: %s\n"
+msgstr "sekcja [%2d] „%s”: nie można uzyskać symbolu %zu: %s\n"
+
+#: src/elflint.c:710
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid name value\n"
+msgstr "sekcja [%2d] „%s”: symbol %zu: nieprawidłowa wartość nazwy\n"
+
+#: src/elflint.c:725
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: too large section index but no extended "
+"section index section\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: za duży indeks sekcji, ale nie ma sekcji "
+"rozszerzonych indeksów sekcji\n"
+
+#: src/elflint.c:731
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in "
+"st_shndx (%<PRIu32>)\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: XINDEX użyty dla indeksu, który zmieściłby "
+"się w st_shndx (%<PRIu32>)\n"
+
+#. || sym->st_shndx > SHN_HIRESERVE  always false
+#: src/elflint.c:743
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid section index\n"
+msgstr "sekcja [%2d] „%s”: symbol %zu: nieprawidłowy indeks sekcji\n"
+
+#: src/elflint.c:751
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown type\n"
+msgstr "sekcja [%2d] „%s”: symbol %zu: nieznany typ\n"
+
+#: src/elflint.c:757
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown symbol binding\n"
+msgstr "sekcja [%2d] „%s”: symbol %zu: nieznane dowiązanie symbolu\n"
+
+#: src/elflint.c:762
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unique symbol not of object type\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: unikalny symbol nie jest typem obiektu\n"
+
+#: src/elflint.c:770
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: COMMON jest dozwolone tylko w plikach "
+"relokowalnych\n"
+
+#: src/elflint.c:774
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"
+msgstr "sekcja [%2d] „%s”: symbol %zu: lokalne symbole COMMON to nonsens\n"
+
+#: src/elflint.c:778
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"
+msgstr "sekcja [%2d] „%s”: symbol %zu: funkcja w sekcji COMMON to nonsens\n"
+
+#: src/elflint.c:829
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: st_value out of bounds\n"
+msgstr "sekcja [%2d] „%s”: symbol %zu: st_value spoza zakresu\n"
+
+#: src/elflint.c:835 src/elflint.c:860 src/elflint.c:909
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu does not fit completely in referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu nie mieści się w całości we wskazywanej sekcji "
+"[%2d] „%s”\n"
+
+#: src/elflint.c:844
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have "
+"SHF_TLS flag set\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: wskazywana sekcja [%2d] „%s” nie ma "
+"ustawionej flagi SHF_TLS\n"
+
+#: src/elflint.c:854 src/elflint.c:902
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: st_value spoza zakresu wskazywanej sekcji "
+"[%2d] „%s”\n"
+
+#: src/elflint.c:881
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: symbol TLS, ale brak wpisu TLS nagłówka "
+"programu\n"
+
+#: src/elflint.c:887
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but couldn't get TLS program "
+"header entry\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: symbol TLS, ale nie można uzyskać wpisu TLS "
+"nagłówka programu\n"
+
+#: src/elflint.c:895
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] "
+"'%s'\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: st_value pomija wskazywaną sekcję [%2d] „%s”\n"
+
+#: src/elflint.c:922
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: lokalny symbol spoza zakresu określonego "
+"w sh_info\n"
+
+#: src/elflint.c:929
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: non-local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: nielokalny symbol spoza zakresu określonego "
+"w sh_info\n"
+
+#: src/elflint.c:936
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: non-local section symbol\n"
+msgstr "sekcja [%2d] „%s”: symbol %zu: nielokalny symbol sekcji\n"
+
+#: src/elflint.c:986
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section "
+"[%2d]\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol _GLOBAL_OFFSET_TABLE_ odnosi się do błędnej sekcji "
+"[%2d]\n"
+
+#: src/elflint.c:993
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] "
+"'%s'\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol _GLOBAL_OFFSET_TABLE_ odnosi się do sekcji [%2d] "
+"„%s”\n"
+
+#. This test is more strict than the psABIs which
+#. usually allow the symbol to be in the middle of
+#. the .got section, allowing negative offsets.
+#: src/elflint.c:1009
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#<PRIx64> does not "
+"match %s section address %#<PRIx64>\n"
+msgstr ""
+"sekcja [%2d] „%s”: wartość symbolu _GLOBAL_OFFSET_TABLE_ %#<PRIx64> nie "
+"pasuje do adresu sekcji %s %#<PRIx64>\n"
+
+#: src/elflint.c:1016
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %<PRIu64> does not "
+"match %s section size %<PRIu64>\n"
+msgstr ""
+"sekcja [%2d] „%s”: rozmiar symbolu _GLOBAL_OFFSET_TABLE_ %<PRIu64> nie "
+"pasuje do rozmiaru sekcji %s %<PRIu64>\n"
+
+#: src/elflint.c:1024
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got "
+"section\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol _GLOBAL_OFFSET_TABLE_ istnieje, ale brak sekcji ."
+"got\n"
+
+#: src/elflint.c:1040
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC_ symbol value %#<PRIx64> does not match dynamic "
+"segment address %#<PRIx64>\n"
+msgstr ""
+"sekcja [%2d] „%s”: wartość symbolu _DYNAMIC_ %#<PRIx64> nie pasuje do adresu "
+"segmentu dynamicznego %#<PRIx64>\n"
+
+#: src/elflint.c:1047
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC symbol size %<PRIu64> does not match dynamic "
+"segment size %<PRIu64>\n"
+msgstr ""
+"sekcja [%2d] „%s”: rozmiar symbolu _DYNAMIC_ %<PRIu64> nie pasuje do "
+"rozmiaru segmentu dynamicznego %<PRIu64>\n"
+
+#: src/elflint.c:1060
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-"
+"default visibility\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %zu: symbol w dynamicznej tabeli symboli "
+"z niedomyślną widocznością\n"
+
+#: src/elflint.c:1064
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"
+msgstr "sekcja [%2d] „%s”: symbol %zu: ustawiono nieznany bit w st_other\n"
+
+#: src/elflint.c:1102
+#, c-format
+msgid "section [%2d] '%s': cannot get section data.\n"
+msgstr "sekcja [%2d] „%s”: nie można uzyskać danych sekcji.\n"
+
+#: src/elflint.c:1118
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"
+msgstr "sekcja [%2d] „%s”: DT_RELCOUNT użyte dla tej sekcji RELA\n"
+
+#: src/elflint.c:1129 src/elflint.c:1182
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"
+msgstr "sekcja [%2d] „%s”: DT_RELCOUNT %d za duże dla tej sekcji\n"
+
+#: src/elflint.c:1154 src/elflint.c:1207
+#, c-format
+msgid ""
+"section [%2d] '%s': relative relocations after index %d as specified by "
+"DT_RELCOUNT\n"
+msgstr ""
+"sekcja [%2d] „%s”: relokacje względne po indeksie %d podanym przez "
+"DT_RELCOUNT\n"
+
+#: src/elflint.c:1160 src/elflint.c:1213
+#, c-format
+msgid ""
+"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT "
+"specified %d relative relocations\n"
+msgstr ""
+"sekcja [%2d] „%s”: relokacja bezwzględna pod indeksem %zu; DT_RELCOUNT podał "
+"%d relokacji względnych\n"
+
+#: src/elflint.c:1172
+#, c-format
+msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n"
+msgstr "sekcja [%2d] „%s”: DT_RELACOUNT użyte dla tej sekcji REL\n"
+
+#: src/elflint.c:1255
+#, c-format
+msgid "section [%2d] '%s': invalid destination section index\n"
+msgstr "sekcja [%2d] „%s”: nieprawidłowy indeks sekcji docelowej\n"
+
+#: src/elflint.c:1267
+#, c-format
+msgid "section [%2d] '%s': invalid destination section type\n"
+msgstr "sekcja [%2d] „%s”: nieprawidłowy typ sekcji docelowej\n"
+
+#: src/elflint.c:1275
+#, c-format
+msgid "section [%2d] '%s': sh_info should be zero\n"
+msgstr "sekcja [%2d] „%s”: sh_info powinno wynosić zero\n"
+
+#: src/elflint.c:1283
+#, c-format
+msgid ""
+"section [%2d] '%s': no relocations for merge-able string sections possible\n"
+msgstr ""
+"sekcja [%2d] „%s”: relokacje dla sekcji złączalnych ciągów są niemożliwe\n"
+
+#: src/elflint.c:1291
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n"
+msgstr "sekcja [%2d] „%s”: rozmiar wpisu sekcji nie zgadza się z ElfXX_Rela\n"
+
+#: src/elflint.c:1351
+#, c-format
+msgid "text relocation flag set but there is no read-only segment\n"
+msgstr ""
+"flaga relokacji tekstu jest ustawiona, ale nie ma segmentu tylko do odczytu\n"
+
+#: src/elflint.c:1378
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid type\n"
+msgstr "sekcja [%2d] „%s”: relokacja %zu: nieprawidłowy typ\n"
+
+#: src/elflint.c:1386
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: relocation type invalid for the file "
+"type\n"
+msgstr ""
+"sekcja [%2d] „%s”: relokacja %zu: typ relokacji nieprawidłowy dla tego typu "
+"pliku\n"
+
+#: src/elflint.c:1394
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n"
+msgstr "sekcja [%2d] „%s”: relokacja %zu: nieprawidłowy indeks symbolu\n"
+
+#: src/elflint.c:1412
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can "
+"be used with %s\n"
+msgstr ""
+"sekcja [%2d] „%s”: relokacja %zu: z %s można użyć tylko symbolu "
+"„_GLOBAL_OFFSET_TABLE_”\n"
+
+#: src/elflint.c:1429
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n"
+msgstr "sekcja [%2d] „%s”: relokacja %zu: offset spoza zakresu\n"
+
+#: src/elflint.c:1444
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: copy relocation against symbol of type "
+"%s\n"
+msgstr ""
+"sekcja [%2d] „%s”: relokacja %zu: relokacja kopii względem symbolu typu %s\n"
+
+#: src/elflint.c:1465
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: read-only section modified but text "
+"relocation flag not set\n"
+msgstr ""
+"sekcja [%2d] „%s”: relokacja %zu: sekcja tylko do odczytu została "
+"zmodyfikowana, ale nie ustawiono flagi relokacji tekstu\n"
+
+#: src/elflint.c:1480
+#, c-format
+msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n"
+msgstr ""
+"sekcja [%2d] „%s”: relokacje względem wczytanych i niewczytanych danych\n"
+
+#: src/elflint.c:1520 src/elflint.c:1571
+#, c-format
+msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
+msgstr "sekcja [%2d] „%s”: nie można uzyskać relokacji %zu: %s\n"
+
+#: src/elflint.c:1647
+#, c-format
+msgid "more than one dynamic section present\n"
+msgstr "obecna jest więcej niż jedna sekcja dynamiczna\n"
+
+#: src/elflint.c:1665
+#, c-format
+msgid ""
+"section [%2d]: referenced as string table for section [%2d] '%s' but section "
+"link value is invalid\n"
+msgstr ""
+"sekcja [%2d]: wskazane jako tabela ciągów dla sekcji [%2d] „%s”, ale wartość "
+"dowiązania sekcji jest nieprawidłowa\n"
+
+#: src/elflint.c:1673
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"
+msgstr "sekcja [%2d] „%s”: rozmiar wpisu sekcji nie zgadza się z ElfXX_Dyn\n"
+
+#: src/elflint.c:1678 src/elflint.c:1967
+#, c-format
+msgid "section [%2d] '%s': sh_info not zero\n"
+msgstr "sekcja [%2d] „%s”: sh_info nie wynosi zero\n"
+
+#: src/elflint.c:1688
+#, c-format
+msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"
+msgstr ""
+"sekcja [%2d] „%s”: nie można uzyskać wpisu %zu sekcji dynamicznej: %s\n"
+
+#: src/elflint.c:1696
+#, c-format
+msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"
+msgstr "sekcja [%2d] „%s”: wpisy nie-DT_NULL występują po wpisie DT_NULL\n"
+
+#: src/elflint.c:1703
+#, c-format
+msgid "section [%2d] '%s': entry %zu: unknown tag\n"
+msgstr "sekcja [%2d] „%s”: wpis %zu: nieznany znacznik\n"
+
+#: src/elflint.c:1714
+#, c-format
+msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n"
+msgstr "sekcja [%2d] „%s”: wpis %zu: więcej niż jeden wpis ze znacznikiem %s\n"
+
+#: src/elflint.c:1724
+#, c-format
+msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n"
+msgstr "sekcja [%2d] „%s”: wpis %zu: użyto znacznika %s poziomu 2\n"
+
+#: src/elflint.c:1742
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis %zu: wartość DT_PLTREL musi wynosić DT_REL lub "
+"DT_RELA\n"
+
+#: src/elflint.c:1755
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: pointer does not match address of section "
+"[%2d] '%s' referenced by sh_link\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis %zu: wskaźnik nie pasuje do adresu sekcji [%2d] „%s” "
+"wskazywanej przez sh_link\n"
+
+#: src/elflint.c:1798
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis %zu: wartość %s musi wskazywać na wczytany segment\n"
+
+#: src/elflint.c:1813
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must be valid offset in section "
+"[%2d] '%s'\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis %zu: wartość %s musi być prawidłowym offsetem "
+"w sekcji [%2d] „%s”\n"
+
+#: src/elflint.c:1833 src/elflint.c:1861
+#, c-format
+msgid "section [%2d] '%s': contains %s entry but not %s\n"
+msgstr "sekcja [%2d] „%s”: zawiera wpis %s, ale nie %s\n"
+
+#: src/elflint.c:1845
+#, c-format
+msgid "section [%2d] '%s': mandatory tag %s not present\n"
+msgstr "sekcja [%2d] „%s”: brak obowiązkowego znacznika %s\n"
+
+#: src/elflint.c:1854
+#, c-format
+msgid "section [%2d] '%s': no hash section present\n"
+msgstr "sekcja [%2d] „%s”: brak sekcji skrótów\n"
+
+#: src/elflint.c:1869 src/elflint.c:1876
+#, c-format
+msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n"
+msgstr "sekcja [%2d] „%s”: nie wszystkie z %s, %s i %s są obecne\n"
+
+#: src/elflint.c:1886 src/elflint.c:1890
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"
+msgstr ""
+"sekcja [%2d] „%s”: brak znacznika %s w DSO oznaczonym podczas wstępnej "
+"konsolidacji\n"
+
+#: src/elflint.c:1896
+#, c-format
+msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n"
+msgstr ""
+"sekcja [%2d] „%s”: plik nie-DSO oznaczony jako zależność podczas wstępnej "
+"konsolidacji\n"
+
+#: src/elflint.c:1907 src/elflint.c:1911 src/elflint.c:1915 src/elflint.c:1919
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in prelinked executable\n"
+msgstr ""
+"sekcja [%2d] „%s”: brak znacznika %s we wstępnie konsolidowanym pliku "
+"wykonywalnym\n"
+
+#: src/elflint.c:1931
+#, c-format
+msgid ""
+"section [%2d] '%s': only relocatable files can have extended section index\n"
+msgstr ""
+"sekcja [%2d] „%s”: tylko pliki relokowalne mogą mieć rozszerzoną sekcję "
+"indeksów\n"
+
+#: src/elflint.c:1941
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index section not for symbol table\n"
+msgstr ""
+"sekcja [%2d] „%s”: sekcja rozszerzonych indeksów sekcji nie dla tabeli "
+"symboli\n"
+
+#: src/elflint.c:1945
+#, c-format
+msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n"
+msgstr ""
+"sekcja [%2d] „%s”: rozszerzony indeks sekcji sh_link [%2d] jest "
+"nieprawidłowy\n"
+
+#: src/elflint.c:1950
+#, c-format
+msgid "cannot get data for symbol section\n"
+msgstr "nie można uzyskać danych dla sekcji symboli\n"
+
+#: src/elflint.c:1953
+#, c-format
+msgid "section [%2d] '%s': entry size does not match Elf32_Word\n"
+msgstr "sekcja [%2d] „%s”: rozmiar wpisu nie zgadza się z Elf32_Word\n"
+
+#: src/elflint.c:1962
+#, c-format
+msgid "section [%2d] '%s': extended index table too small for symbol table\n"
+msgstr ""
+"sekcja [%2d] „%s”: tabela rozszerzonych indeksów jest za mała dla tabeli "
+"symboli\n"
+
+#: src/elflint.c:1977
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to "
+"same symbol table\n"
+msgstr ""
+"sekcja [%2d] „%s”: rozszerzony indeks sekcji w sekcji [%2zu] „%s” odwołuje "
+"się do tej samej tabeli symboli\n"
+
+#: src/elflint.c:1995
+#, c-format
+msgid "symbol 0 should have zero extended section index\n"
+msgstr "symbol 0 powinien mieć zerowy rozszerzony indeks sekcji\n"
+
+#: src/elflint.c:2007
+#, c-format
+msgid "cannot get data for symbol %zu\n"
+msgstr "nie można uzyskać danych dla symbolu %zu\n"
+
+#: src/elflint.c:2012
+#, c-format
+msgid "extended section index is %<PRIu32> but symbol index is not XINDEX\n"
+msgstr ""
+"rozszerzony indeks sekcji wynosi %<PRIu32>, ale indeks symbolu nie wynosi "
+"XINDEX\n"
+
+#: src/elflint.c:2029 src/elflint.c:2083
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"
+msgstr ""
+"sekcja [%2d] „%s”: sekcja tabeli mieszającej jest za mała (%ld, oczekiwano "
+"%ld)\n"
+
+#: src/elflint.c:2043 src/elflint.c:2097
+#, c-format
+msgid "section [%2d] '%s': chain array too large\n"
+msgstr "sekcja [%2d] „%s”: tabela łańcuchowa jest za duża\n"
+
+#: src/elflint.c:2057 src/elflint.c:2111
+#, c-format
+msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n"
+msgstr ""
+"sekcja [%2d] „%s”: odwołanie do kubełka skrótu %zu jest spoza zakresu\n"
+
+#: src/elflint.c:2067
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n"
+msgstr ""
+"sekcja [%2d] „%s”: odwołanie do łańcucha skrótu %zu jest spoza zakresu\n"
+
+#: src/elflint.c:2121
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %<PRIu64> out of bounds\n"
+msgstr ""
+"sekcja [%2d] „%s”: odwołanie do łańcucha skrótu %<PRIu64> jest spoza "
+"zakresu\n"
+
+#: src/elflint.c:2134
+#, c-format
+msgid "section [%2d] '%s': not enough data\n"
+msgstr "sekcja [%2d] „%s”: brak wystarczającej ilości danych\n"
+
+#: src/elflint.c:2146
+#, c-format
+msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n"
+msgstr ""
+"sekcja [%2d] „%s”: rozmiar maski bitowej wynosi zero lub nie jest potęgą 2: "
+"%u\n"
+
+#: src/elflint.c:2162
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected at "
+"least %ld)\n"
+msgstr ""
+"sekcja [%2d] „%s”: sekcja tabeli mieszającej jest za mała (wynosi %ld, "
+"oczekiwano co najmniej %ld)\n"
+
+#: src/elflint.c:2171
+#, c-format
+msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n"
+msgstr ""
+"sekcja [%2d] „%s”: drugie przesunięcie funkcji mieszającej jest za duże: %u\n"
+
+#: src/elflint.c:2205
+#, c-format
+msgid ""
+"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"
+msgstr ""
+"sekcja [%2d] „%s”: łańcuch mieszający dla kubełka %zu jest mniejszy niż "
+"przesunięcie indeksu symboli\n"
+
+#: src/elflint.c:2226
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is "
+"undefined\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %u wskazywany w łańcuchu dla kubełka %zu jest "
+"nieokreślony\n"
+
+#: src/elflint.c:2239
+#, c-format
+msgid ""
+"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+"sekcja [%2d] „%s”: wartość skrótu dla symbolu %u w łańcuchu dla kubełka %zu "
+"jest błędna\n"
+
+#: src/elflint.c:2248
+#, c-format
+msgid ""
+"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+"sekcja [%2d] „%s”: indeks maski dla symbolu %u w łańcuchu dla kubełka %zu "
+"jest błędny\n"
+
+#: src/elflint.c:2278
+#, c-format
+msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n"
+msgstr "sekcja [%2d] „%s”: łańcuch skrótu dla kubełka %zu jest spoza zakresu\n"
+
+#: src/elflint.c:2283
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"
+msgstr ""
+"sekcja [%2d] „%s”: odwołanie do symbolu w łańcuchu dla kubełka %zu jest "
+"spoza zakresu\n"
+
+#: src/elflint.c:2289
+#, c-format
+msgid "section [%2d] '%s': bitmask does not match names in the hash table\n"
+msgstr ""
+"sekcja [%2d] „%s”: maska bitowa nie pasuje do nazw w tabeli mieszającej\n"
+
+#: src/elflint.c:2302
+#, c-format
+msgid "section [%2d] '%s': relocatable files cannot have hash tables\n"
+msgstr ""
+"sekcja [%2d] „%s”: pliki relokowalne nie mogą mieć tabeli mieszających\n"
+
+#: src/elflint.c:2320
+#, c-format
+msgid "section [%2d] '%s': hash table not for dynamic symbol table\n"
+msgstr ""
+"sekcja [%2d] „%s”: tabela mieszająca nie dla tabeli dynamicznych symboli\n"
+
+#: src/elflint.c:2324
+#, c-format
+msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n"
+msgstr ""
+"sekcja [%2d] „%s”: nieprawidłowy indeks sekcji tabeli symboli sh_link [%2d]\n"
+
+#: src/elflint.c:2334
+#, c-format
+msgid "section [%2d] '%s': hash table entry size incorrect\n"
+msgstr "sekcja [%2d] „%s”: niepoprawny rozmiar wpisu tabeli mieszającej\n"
+
+#: src/elflint.c:2339
+#, c-format
+msgid "section [%2d] '%s': not marked to be allocated\n"
+msgstr "sekcja [%2d] „%s”: nieoznaczona do przydzielenia\n"
+
+#: src/elflint.c:2344
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table has not even room for initial administrative "
+"entries\n"
+msgstr ""
+"sekcja [%2d] „%s”: tabela mieszająca nie ma miejsca nawet na początkowe "
+"wpisy administracyjne\n"
+
+#: src/elflint.c:2393
+#, c-format
+msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"
+msgstr ""
+"sh_link w sekcjach skrótu [%2zu] „%s” i [%2zu] „%s” nie są identyczne\n"
+
+#: src/elflint.c:2417 src/elflint.c:2482 src/elflint.c:2517
+#, c-format
+msgid "hash section [%2zu] '%s' does not contain enough data\n"
+msgstr ""
+"sekcja mieszania [%2zu] „%s” nie zawiera wystarczającej ilości danych\n"
+
+#: src/elflint.c:2438
+#, c-format
+msgid "hash section [%2zu] '%s' has zero bit mask words\n"
+msgstr "sekcja mieszania [%2zu] „%s” ma zerowe słowa maski bitów\n"
+
+#: src/elflint.c:2449 src/elflint.c:2493 src/elflint.c:2530
+#, c-format
+msgid "hash section [%2zu] '%s' uses too much data\n"
+msgstr "sekcja mieszania [%2zu] „%s” używa za dużo danych\n"
+
+#: src/elflint.c:2464
+#, c-format
+msgid ""
+"hash section [%2zu] '%s' invalid symbol index %<PRIu32> (max_nsyms: "
+"%<PRIu32>, nentries: %<PRIu32>\n"
+msgstr ""
+"sekcja mieszająca [%2zu] „%s” nieprawidłowy indeks symboli %<PRIu32> "
+"(max_nsyms: %<PRIu32>, nentries: %<PRIu32>\n"
+
+#: src/elflint.c:2551
+#, c-format
+msgid "hash section [%2zu] '%s' invalid sh_entsize\n"
+msgstr "sekcja mieszania [%2zu] „%s” nieprawidłowe sh_entsize\n"
+
+#: src/elflint.c:2561 src/elflint.c:2565
+#, c-format
+msgid "section [%2zu] '%s': reference to symbol index 0\n"
+msgstr "sekcja [%2zu] „%s”: odwołanie do symbolu o indeksie 0\n"
+
+#: src/elflint.c:2572
+#, c-format
+msgid ""
+"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+"symbol %d wymieniony w nowej tabeli mieszającej w [%2zu] „%s”, ale nie "
+"w poprzedniej tabeli mieszającej [%2zu] „%s”\n"
+
+#: src/elflint.c:2584
+#, c-format
+msgid ""
+"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+"symbol %d wymieniony w poprzedniej tabeli mieszającej w [%2zu] „%s”, ale nie "
+"w nowej tabeli mieszającej w [%2zu] „%s”\n"
+
+#: src/elflint.c:2600
+#, c-format
+msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n"
+msgstr "sekcja [%2d] „%s”: niezerowe sh_%s dla sekcji NULL\n"
+
+#: src/elflint.c:2620
+#, c-format
+msgid ""
+"section [%2d] '%s': section groups only allowed in relocatable object files\n"
+msgstr ""
+"sekcja [%2d] „%s”: w plikach obiektów relokowalnych dozwolone są tylko grupy "
+"sekcji\n"
+
+#: src/elflint.c:2631
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol table: %s\n"
+msgstr "sekcja [%2d] „%s”: nie można uzyskać tabeli symboli: %s\n"
+
+#: src/elflint.c:2636
+#, c-format
+msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n"
+msgstr ""
+"sekcja [%2d] „%s”: odwołanie do sekcji w sh_link nie ma tabeli symboli\n"
+
+#: src/elflint.c:2642
+#, c-format
+msgid "section [%2d] '%s': invalid symbol index in sh_info\n"
+msgstr "sekcja [%2d] „%s”: nieprawidłowy indeks symbolu w sh_info\n"
+
+#: src/elflint.c:2647
+#, c-format
+msgid "section [%2d] '%s': sh_flags not zero\n"
+msgstr "sekcja [%2d] „%s”: niezerowe sh_flags\n"
+
+#: src/elflint.c:2654
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol for signature\n"
+msgstr "sekcja [%2d] „%s”: nie można uzyskać symbolu dla podpisu\n"
+
+#: src/elflint.c:2658
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol name for signature\n"
+msgstr "sekcja [%2d] „%s”: nie można uzyskać nazwy symbolu dla podpisu\n"
+
+#: src/elflint.c:2663
+#, c-format
+msgid "section [%2d] '%s': signature symbol cannot be empty string\n"
+msgstr "sekcja [%2d] „%s”: symbol podpisu nie można być pustym ciągiem\n"
+
+#: src/elflint.c:2669
+#, c-format
+msgid "section [%2d] '%s': sh_flags not set correctly\n"
+msgstr "sekcja [%2d] „%s”: sh_flags nie ustawione poprawnie\n"
+
+#: src/elflint.c:2675
+#, c-format
+msgid "section [%2d] '%s': cannot get data: %s\n"
+msgstr "sekcja [%2d] „%s”: nie można uzyskać danych: %s\n"
+
+#: src/elflint.c:2684
+#, c-format
+msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"
+msgstr ""
+"sekcja [%2d] „%s”: rozmiar sekcji nie jest wielokrotnością "
+"sizeof(Elf32_Word)\n"
+
+#: src/elflint.c:2690
+#, c-format
+msgid "section [%2d] '%s': section group without flags word\n"
+msgstr "sekcja [%2d] „%s”: grupa sekcji bez słowa flag\n"
+
+#: src/elflint.c:2698
+#, c-format
+msgid "section [%2d] '%s': section group without member\n"
+msgstr "sekcja [%2d] „%s”: grupa sekcji bez elementów\n"
+
+#: src/elflint.c:2702
+#, c-format
+msgid "section [%2d] '%s': section group with only one member\n"
+msgstr "sekcja [%2d] „%s”: grupa sekcji z tylko jednym elementem\n"
+
+#: src/elflint.c:2713
+#, c-format
+msgid "section [%2d] '%s': unknown section group flags\n"
+msgstr "sekcja [%2d] „%s”: nieznane flagi grupy sekcji\n"
+
+#: src/elflint.c:2725
+#, c-format
+msgid "section [%2d] '%s': section index %zu out of range\n"
+msgstr "sekcja [%2d] „%s”: indeks sekcji %zu jest spoza zakresu\n"
+
+#: src/elflint.c:2734
+#, c-format
+msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n"
+msgstr ""
+"sekcja [%2d] „%s”: nie można uzyskać nagłówka sekcji dla elementu %zu: %s\n"
+
+#: src/elflint.c:2741
+#, c-format
+msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n"
+msgstr "sekcja [%2d] „%s”: grupa sekcji zawiera inną grupę [%2d] „%s”\n"
+
+#: src/elflint.c:2747
+#, c-format
+msgid ""
+"section [%2d] '%s': element %zu references section [%2d] '%s' without "
+"SHF_GROUP flag set\n"
+msgstr ""
+"sekcja [%2d] „%s”: element %zu odwołuje się do sekcji [%2d] „%s” bez flagi "
+"SHF_GROUP\n"
+
+#: src/elflint.c:2754
+#, c-format
+msgid "section [%2d] '%s' is contained in more than one section group\n"
+msgstr "sekcja [%2d] „%s” jest zawarta w więcej niż jednej grupie sekcji\n"
+
+#: src/elflint.c:2944
+#, c-format
+msgid ""
+"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no "
+"dynamic symbol table\n"
+msgstr ""
+"sekcja [%2d] „%s” odwołuje się w sh_link do sekcji [%2d] „%s”, która nie "
+"jest tabelą symboli dynamicznych\n"
+
+#: src/elflint.c:2956
+#, c-format
+msgid ""
+"section [%2d] '%s' has different number of entries than symbol table [%2d] "
+"'%s'\n"
+msgstr ""
+"sekcja [%2d] „%s” ma inną liczbę wpisów niż tabela symboli [%2d] „%s”\n"
+
+#: src/elflint.c:2972
+#, c-format
+msgid "section [%2d] '%s': symbol %d: cannot read version data\n"
+msgstr "sekcja [%2d] „%s”: symbol %d: nie można odczytać danych wersji\n"
+
+#: src/elflint.c:2988
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n"
+msgstr "sekcja [%2d] „%s”: symbol %d: symbol lokalny z zakresem globalnym\n"
+
+#: src/elflint.c:2996
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with version\n"
+msgstr "sekcja [%2d] „%s”: symbol %d: symbol lokalny z wersją\n"
+
+#: src/elflint.c:3010
+#, c-format
+msgid "section [%2d] '%s': symbol %d: invalid version index %d\n"
+msgstr "sekcja [%2d] „%s”: symbol %d: nieprawidłowy indeks wersji %d\n"
+
+#: src/elflint.c:3015
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for defined version\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %d: indeks wersji %d jest dla wersji określonej\n"
+
+#: src/elflint.c:3025
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for requested version\n"
+msgstr ""
+"sekcja [%2d] „%s”: symbol %d: indeks wersji %d jest dla wersji żądanej\n"
+
+#: src/elflint.c:3078
+#, c-format
+msgid "more than one version reference section present\n"
+msgstr "obecna jest więcej niż jedna sekcja odniesienia wersji\n"
+
+#: src/elflint.c:3086 src/elflint.c:3233
+#, c-format
+msgid "section [%2d] '%s': sh_link does not link to string table\n"
+msgstr "sekcja [%2d] „%s”: sh_link nie łączy się z tabelą ciągów\n"
+
+#: src/elflint.c:3111 src/elflint.c:3287
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong version %d\n"
+msgstr "sekcja [%2d] „%s”: wpis %d ma błędną wersję %d\n"
+
+#: src/elflint.c:3118 src/elflint.c:3294
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"
+msgstr "sekcja [%2d] „%s”: wpis %d ma błędny offset dla danych dodatkowych\n"
+
+#: src/elflint.c:3128
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid file reference\n"
+msgstr "sekcja [%2d] „%s”: symbol %d ma błędne odniesienie do pliku\n"
+
+#: src/elflint.c:3136
+#, c-format
+msgid "section [%2d] '%s': entry %d references unknown dependency\n"
+msgstr "sekcja [%2d] „%s”: wpis %d odnosi się do nieznanej zależności\n"
+
+#: src/elflint.c:3148
+#, c-format
+msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"
+msgstr "sekcja [%2d] „%s”: wpis dodatkowy %d do wpisu %d ma nieznaną flagę\n"
+
+#: src/elflint.c:3156
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name "
+"reference\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis dodatkowy %d do wpisu %d ma nieprawidłowe "
+"odniesienie do nazwy\n"
+
+#: src/elflint.c:3165
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: "
+"%#x, expected %#x\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis dodatkowy %d do wpisu %d ma błędną wartość skrótu: "
+"%#x, oczekiwano %#x\n"
+
+#: src/elflint.c:3174
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version "
+"name '%s'\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis dodatkowy %d do wpisu %d ma powtórzoną nazwę wersji "
+"„%s”\n"
+
+#: src/elflint.c:3185
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis dodatkowy %d do wpisu %d ma błędne następne pole\n"
+
+#: src/elflint.c:3202 src/elflint.c:3378
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n"
+msgstr "sekcja [%2d] „%s”: wpis %d ma błędny offset do następnego wpisu\n"
+
+#: src/elflint.c:3210 src/elflint.c:3386
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says "
+"there are more entries\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis %d ma zerowy offset do następnego wpisu, ale sh_info "
+"zawiera informacje o większej liczbie wpisów\n"
+
+#: src/elflint.c:3225
+#, c-format
+msgid "more than one version definition section present\n"
+msgstr "obecna jest więcej niż jedna sekcja definicji wersji\n"
+
+#: src/elflint.c:3272
+#, c-format
+msgid "section [%2d] '%s': more than one BASE definition\n"
+msgstr "sekcja [%2d] „%s”: jest więcej niż jedna definicja BASE\n"
+
+#: src/elflint.c:3276
+#, c-format
+msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"
+msgstr "sekcja [%2d] „%s”: definicja BASE musi mieć indeks VER_NDX_GLOBAL\n"
+
+#: src/elflint.c:3282
+#, c-format
+msgid "section [%2d] '%s': entry %d has unknown flag\n"
+msgstr "sekcja [%2d] „%s”: wpis %d ma nieznaną flagę\n"
+
+#: src/elflint.c:3309
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid name reference\n"
+msgstr "sekcja [%2d] „%s”: wpis %d ma nieprawidłowe odniesienie do nazwy\n"
+
+#: src/elflint.c:3316
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis %d ma błędną wartość skrótu: %#x, oczekiwano %#x\n"
+
+#: src/elflint.c:3324
+#, c-format
+msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n"
+msgstr "sekcja [%2d] „%s”: wpis %d ma powtórzoną nazwę wersji „%s”\n"
+
+#: src/elflint.c:3344
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis %d ma nieprawidłowe odniesienie do nazwy w danych "
+"dodatkowych\n"
+
+#: src/elflint.c:3361
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"
+msgstr ""
+"sekcja [%2d] „%s”: wpis %d ma błędne następne pole w danych dodatkowych\n"
+
+#: src/elflint.c:3394
+#, c-format
+msgid "section [%2d] '%s': no BASE definition\n"
+msgstr "sekcja [%2d] „%s”: brak definicji BASE\n"
+
+#: src/elflint.c:3410
+#, c-format
+msgid "section [%2d] '%s': unknown parent version '%s'\n"
+msgstr "sekcja [%2d] „%s”: nieznana wersja rodzica „%s”\n"
+
+#: src/elflint.c:3423
+#, c-format
+msgid "section [%2d] '%s': empty object attributes section\n"
+msgstr "sekcja [%2d] „%s”: pusta sekcja atrybutów obiektu\n"
+
+#: src/elflint.c:3444
+#, c-format
+msgid "section [%2d] '%s': unrecognized attribute format\n"
+msgstr "sekcja [%2d] „%s”: nierozpoznany format atrybutu\n"
+
+#: src/elflint.c:3460
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute section\n"
+msgstr ""
+"sekcja [%2d] „%s”: offset %zu: pole o zerowej długości w sekcji atrybutów\n"
+
+#: src/elflint.c:3469
+#, c-format
+msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n"
+msgstr ""
+"sekcja [%2d] „%s”: offset %zu: nieprawidłowa długość w sekcji atrybutów\n"
+
+#: src/elflint.c:3481
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n"
+msgstr "sekcja [%2d] „%s”: offset %zu: niezakończony ciąg nazwy producenta\n"
+
+#: src/elflint.c:3498
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"
+msgstr ""
+"sekcja [%2d] „%s”: offset %zu: niekończące się ULEB128 w znaczniku podsekcji "
+"atrybutów\n"
+
+#: src/elflint.c:3507
+#, c-format
+msgid "section [%2d] '%s': offset %zu: truncated attribute section\n"
+msgstr "sekcja [%2d] „%s”: offset %zu: skrócona sekcja atrybutów\n"
+
+#: src/elflint.c:3516
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"
+msgstr ""
+"sekcja [%2d] „%s”: offset %zu: zerowej długości pole w podsekcji atrybutów\n"
+
+#: src/elflint.c:3531
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"
+msgstr ""
+"sekcja [%2d] „%s”: offset %zu: nieprawidłowa długość w podsekcji atrybutów\n"
+
+#. Tag_File
+#: src/elflint.c:3542
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"
+msgstr ""
+"sekcja [%2d] „%s”: offset %zu: podsekcja atrybutów ma nieoczekiwany znacznik "
+"%u\n"
+
+#: src/elflint.c:3560
+#, c-format
+msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"
+msgstr ""
+"sekcja [%2d] „%s”: offset %zu: niekończące się ULEB128 w znaczniku atrybutu\n"
+
+#: src/elflint.c:3571
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n"
+msgstr "sekcja [%2d] „%s”: offset %zu: niezakończony ciąg w atrybucie\n"
+
+#: src/elflint.c:3584
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"
+msgstr "sekcja [%2d] „%s”: offset %zu: nierozpoznany znacznik atrybutu %u\n"
+
+#: src/elflint.c:3588
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: unrecognized %s attribute value %<PRIu64>\n"
+msgstr ""
+"sekcja [%2d] „%s”: offset %zu: atrybut %s ma nierozpoznaną wartość "
+"%<PRIu64>\n"
+
+#: src/elflint.c:3598
+#, c-format
+msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n"
+msgstr "sekcja [%2d] „%s”: offset %zu: producent „%s” jest nieznany\n"
+
+#: src/elflint.c:3604
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"
+msgstr ""
+"sekcja [%2d] „%s”: offset %zu: dodatkowe bajty po ostatniej sekcji "
+"atrybutów\n"
+
+#: src/elflint.c:3693
+#, c-format
+msgid "cannot get section header of zeroth section\n"
+msgstr "nie można uzyskać nagłówka sekcji zerowej\n"
+
+#: src/elflint.c:3697
+#, c-format
+msgid "zeroth section has nonzero name\n"
+msgstr "sekcja zerowa ma niezerową nazwę\n"
+
+#: src/elflint.c:3699
+#, c-format
+msgid "zeroth section has nonzero type\n"
+msgstr "sekcja zerowa ma niezerowy typ\n"
+
+#: src/elflint.c:3701
+#, c-format
+msgid "zeroth section has nonzero flags\n"
+msgstr "sekcja zerowa ma niezerowe flagi\n"
+
+#: src/elflint.c:3703
+#, c-format
+msgid "zeroth section has nonzero address\n"
+msgstr "sekcja zerowa ma niezerowy adres\n"
+
+#: src/elflint.c:3705
+#, c-format
+msgid "zeroth section has nonzero offset\n"
+msgstr "sekcja zerowa ma niezerowy offset\n"
+
+#: src/elflint.c:3707
+#, c-format
+msgid "zeroth section has nonzero align value\n"
+msgstr "sekcja zerowa ma niezerową wartość wyrównania\n"
+
+#: src/elflint.c:3709
+#, c-format
+msgid "zeroth section has nonzero entry size value\n"
+msgstr "sekcja zerowa ma niezerową wartość rozmiaru wpisu\n"
+
+#: src/elflint.c:3712
+#, c-format
+msgid ""
+"zeroth section has nonzero size value while ELF header has nonzero shnum "
+"value\n"
+msgstr ""
+"sekcja zerowa ma niezerową wartość rozmiaru, a nagłówek ELF ma niezerową "
+"wartość shnum\n"
+
+#: src/elflint.c:3716
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in shstrndx\n"
+msgstr ""
+"sekcja zerowa ma niezerową wartość dowiązań, a nagłówek ELF nie wskazuje "
+"przepełnienia w shstrndx\n"
+
+#: src/elflint.c:3720
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in phnum\n"
+msgstr ""
+"sekcja zerowa ma niezerową wartość dowiązań, a nagłówek ELF nie wskazuje "
+"przepełnienia w phnum\n"
+
+#: src/elflint.c:3738
+#, c-format
+msgid "cannot get section header for section [%2zu] '%s': %s\n"
+msgstr "nie można uzyskać nagłówka sekcji dla sekcji [%2zu] „%s”: %s\n"
+
+#: src/elflint.c:3747
+#, c-format
+msgid "section [%2zu]: invalid name\n"
+msgstr "sekcja [%2zu]: nieprawidłowa nazwa\n"
+
+#: src/elflint.c:3774
+#, c-format
+msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n"
+msgstr "sekcja [%2d] „%s” ma błędny typ: oczekiwano %s, jest %s\n"
+
+#: src/elflint.c:3792
+#, c-format
+msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n"
+msgstr "sekcja [%2zu] „%s” ma błędne flagi: oczekiwano %s, jest %s\n"
+
+#: src/elflint.c:3810
+#, c-format
+msgid ""
+"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"
+msgstr ""
+"sekcja [%2zu] „%s” ma błędne flagi: oczekiwano %s i być może %s, jest %s\n"
+
+#: src/elflint.c:3828
+#, c-format
+msgid "section [%2zu] '%s' present in object file\n"
+msgstr "sekcja [%2zu] „%s” jest obecna w pliku obiektu\n"
+
+#: src/elflint.c:3834 src/elflint.c:3866
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"
+msgstr ""
+"sekcja [%2zu] „%s” ma flagę SHF_ALLOC, ale nie ma segmentu wczytywalnego\n"
+
+#: src/elflint.c:3839 src/elflint.c:3871
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable "
+"segments\n"
+msgstr ""
+"sekcja [%2zu] „%s” nie ma flagi SHF_ALLOC, ale są segmenty wczytywalne\n"
+
+#: src/elflint.c:3847
+#, c-format
+msgid ""
+"section [%2zu] '%s' is extension section index table in non-object file\n"
+msgstr ""
+"sekcja [%2zu] „%s” jest tabelą indeksów sekcji rozszerzeń w pliku "
+"nieobiektowym\n"
+
+#: src/elflint.c:3890
+#, c-format
+msgid "section [%2zu] '%s': size not multiple of entry size\n"
+msgstr "sekcja [%2zu] „%s”: rozmiar nie jest wielokrotnością rozmiaru wpisu\n"
+
+#: src/elflint.c:3895
+#, c-format
+msgid "cannot get section header\n"
+msgstr "nie można uzyskać nagłówka sekcji\n"
+
+#: src/elflint.c:3905
+#, c-format
+msgid "section [%2zu] '%s' has unsupported type %d\n"
+msgstr "sekcja [%2zu] „%s” ma nieobsługiwany typ %d\n"
+
+#: src/elflint.c:3920
+#, c-format
+msgid ""
+"section [%2zu] '%s' contains invalid processor-specific flag(s) %#<PRIx64>\n"
+msgstr ""
+"sekcja [%2zu] „%s” zawiera nieprawidłowe flagi dla konkretnego procesora "
+"%#<PRIx64>\n"
+
+#: src/elflint.c:3927
+#, c-format
+msgid "section [%2zu] '%s' contains unknown flag(s) %#<PRIx64>\n"
+msgstr "sekcja [%2zu] „%s” zawiera nieznane flagi %#<PRIx64>\n"
+
+#: src/elflint.c:3935
+#, c-format
+msgid "section [%2zu] '%s': thread-local data sections address not zero\n"
+msgstr ""
+"sekcja [%2zu] „%s”: adres sekcji danych lokalnych dla wątków nie jest zerem\n"
+
+#: src/elflint.c:3945
+#, c-format
+msgid "section [%2zu] '%s': allocated section cannot be compressed\n"
+msgstr "sekcja [%2zu] „%s”: nie można skompresować przydzielonej sekcji\n"
+
+#: src/elflint.c:3950
+#, c-format
+msgid "section [%2zu] '%s': nobits section cannot be compressed\n"
+msgstr "sekcja [%2zu] „%s”: nie można skompresować sekcji „nobits”\n"
+
+#: src/elflint.c:3956
+#, c-format
+msgid ""
+"section [%2zu] '%s': compressed section with no compression header: %s\n"
+msgstr "sekcja [%2zu] „%s”: skompresowana sekcja bez nagłówka kompresji: %s\n"
+
+#: src/elflint.c:3962
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in link value\n"
+msgstr ""
+"sekcja [%2zu] „%s”: nieprawidłowe odwołanie do sekcji w wartości dowiązania\n"
+
+#: src/elflint.c:3967
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in info value\n"
+msgstr ""
+"sekcja [%2zu] „%s”: nieprawidłowe odwołanie do sekcji w wartości "
+"informacyjnej\n"
+
+#: src/elflint.c:3974
+#, c-format
+msgid "section [%2zu] '%s': strings flag set without merge flag\n"
+msgstr "sekcja [%2zu] „%s”: flaga ciągów jest ustawiona bez flagi merge\n"
+
+#: src/elflint.c:3979
+#, c-format
+msgid "section [%2zu] '%s': merge flag set but entry size is zero\n"
+msgstr ""
+"sekcja [%2zu] „%s”: flaga merge jest ustawiona, ale rozmiar wpisu jest "
+"zerowy\n"
+
+#: src/elflint.c:3998
+#, c-format
+msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n"
+msgstr "sekcja [%2zu] „%s” ma nieoczekiwany typ %d dla sekcji wykonywalnej\n"
+
+#: src/elflint.c:4007
+#, c-format
+msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n"
+msgstr "sekcja [%2zu] „%s” musi być typu NOBITS w plikach debuginfo\n"
+
+#: src/elflint.c:4014
+#, c-format
+msgid "section [%2zu] '%s' is both executable and writable\n"
+msgstr "sekcja [%2zu] „%s” jest wykonywalne i zapisywalne\n"
+
+#: src/elflint.c:4045
+#, c-format
+msgid ""
+"section [%2zu] '%s' not fully contained in segment of program header entry "
+"%d\n"
+msgstr ""
+"sekcja [%2zu] „%s” nie jest w całości zawarta w segmencie wpisu %d nagłówka "
+"programu\n"
+
+#: src/elflint.c:4055
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d\n"
+msgstr ""
+"sekcja [%2zu] „%s” ma typ NOBITS, a jest odczytywana z pliku w segmencie "
+"wpisu %d nagłówka programu\n"
+
+#: src/elflint.c:4081
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d and file contents is non-zero\n"
+msgstr ""
+"sekcja [%2zu] „%s” ma typ NOBITS, ale jest odczytywana z pliku w segmencie "
+"wpisu %d nagłówka programu, a zawartość pliku jest niezerowa\n"
+
+#: src/elflint.c:4092
+#, c-format
+msgid ""
+"section [%2zu] '%s' has not type NOBITS but is not read from the file in "
+"segment of program header entry %d\n"
+msgstr ""
+"sekcja [%2zu] „%s” nie ma typu NOBITS, a nie jest odczytywana z pliku "
+"w segmencie wpisu %d nagłówka programu\n"
+
+#: src/elflint.c:4103
+#, c-format
+msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n"
+msgstr "sekcja [%2zu] „%s” jest wykonywalne w segmencie niewykonywalnym %d\n"
+
+#: src/elflint.c:4113
+#, c-format
+msgid "section [%2zu] '%s' is writable in unwritable segment %d\n"
+msgstr "sekcja [%2zu] „%s” jest zapisywalne w niezapisywalnym segmencie %d\n"
+
+#: src/elflint.c:4123
+#, c-format
+msgid ""
+"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"
+msgstr ""
+"sekcja [%2zu] „%s”: ma flagę alloc, ale sekcja nie jest w żadnym segmencie "
+"wczytywalnym\n"
+
+#: src/elflint.c:4129
+#, c-format
+msgid ""
+"section [%2zu] '%s': ELF header says this is the section header string table "
+"but type is not SHT_TYPE\n"
+msgstr ""
+"sekcja [%2zu] „%s”: według nagłówka ELF to jest tabela ciągów nagłówków "
+"sekcji, ale typ nie jest SHT_TYPE\n"
+
+#: src/elflint.c:4137
+#, c-format
+msgid ""
+"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"
+msgstr ""
+"sekcja [%2zu] „%s”: pliki relokowalne nie mogą mieć tabeli symboli "
+"dynamicznych\n"
+
+#: src/elflint.c:4188
+#, c-format
+msgid "more than one version symbol table present\n"
+msgstr "obecna jest więcej niż jedna tabela symboli wersji\n"
+
+#: src/elflint.c:4211
+#, c-format
+msgid "INTERP program header entry but no .interp section\n"
+msgstr "jest wpis nagłówka programu INTERP, ale nie ma sekcji .interp\n"
+
+#: src/elflint.c:4222
+#, c-format
+msgid ""
+"loadable segment [%u] is executable but contains no executable sections\n"
+msgstr ""
+"wczytywalny segment [%u] jest wykonywalny, ale nie zawiera wykonywalnych "
+"sekcji\n"
+
+#: src/elflint.c:4228
+#, c-format
+msgid "loadable segment [%u] is writable but contains no writable sections\n"
+msgstr ""
+"wczytywalny segment [%u] jest zapisywalny, ale nie zawiera zapisywalnych "
+"sekcji\n"
+
+#: src/elflint.c:4239
+#, c-format
+msgid ""
+"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section "
+"exist\n"
+msgstr ""
+"brak sekcji .gnu.versym, ale istnieje sekcja .gnu.versym_d lub .gnu."
+"versym_r\n"
+
+#: src/elflint.c:4252
+#, c-format
+msgid "duplicate version index %d\n"
+msgstr "powtórzony indeks wersji %d\n"
+
+#: src/elflint.c:4266
+#, c-format
+msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"
+msgstr "sekcja .gnu.versym istnieje bez .gnu.versym_d lub .gnu.versym_r\n"
+
+#: src/elflint.c:4315
+#, c-format
+msgid "phdr[%d]: unknown core file note type %<PRIu32> at offset %<PRIu64>\n"
+msgstr ""
+"phdr[%d]: nieznany typ notatki pliku core %<PRIu32> pod offsetem %<PRIu64>\n"
+
+#: src/elflint.c:4319
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown core file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+"sekcja [%2d]: „%s”: nieznany typ notatki pliku core %<PRIu32> pod offsetem "
+"%zu\n"
+
+#: src/elflint.c:4342
+#, c-format
+msgid "phdr[%d]: unknown object file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+"phdr[%d]: nieznany typ notatki pliku obiektu %<PRIu32> pod offsetem %zu\n"
+
+#: src/elflint.c:4346
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown object file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+"sekcja [%2d] „%s”: nieznany typ notatki pliku obiektu %<PRIu32> pod offsetem "
+"%zu\n"
+
+#: src/elflint.c:4363
+#, c-format
+msgid "phdr[%d]: no note entries defined for the type of file\n"
+msgstr "phdr[%d]: brak określonych wpisów notatek dla typu pliku\n"
+
+#: src/elflint.c:4382
+#, c-format
+msgid "phdr[%d]: cannot get content of note section: %s\n"
+msgstr "phdr[%d]: nie można uzyskać zawartości sekcji notatki: %s\n"
+
+#: src/elflint.c:4385
+#, c-format
+msgid "phdr[%d]: extra %<PRIu64> bytes after last note\n"
+msgstr "phdr[%d]: dodatkowe %<PRIu64> bajtów po ostatniej notatce\n"
+
+#: src/elflint.c:4406
+#, c-format
+msgid "section [%2d] '%s': no note entries defined for the type of file\n"
+msgstr "sekcja [%2d] „%s”: brak określonych wpisów notatek dla typu pliku\n"
+
+#: src/elflint.c:4413
+#, c-format
+msgid "section [%2d] '%s': cannot get content of note section\n"
+msgstr "sekcja [%2d] „%s”: nie można uzyskać zawartości sekcji notatek\n"
+
+#: src/elflint.c:4416
+#, c-format
+msgid "section [%2d] '%s': extra %<PRIu64> bytes after last note\n"
+msgstr "sekcja [%2d] „%s”: dodatkowe %<PRIu64> bajtów po ostatniej notatce\n"
+
+#: src/elflint.c:4434
+#, c-format
+msgid ""
+"only executables, shared objects, and core files can have program headers\n"
+msgstr ""
+"tylko pliki wykonywalne, obiekty współdzielone i pliki core mogą mieć "
+"nagłówki programu\n"
+
+#: src/elflint.c:4449
+#, c-format
+msgid "cannot get program header entry %d: %s\n"
+msgstr "nie można uzyskać wpisu nagłówka programu %d: %s\n"
+
+#: src/elflint.c:4458
+#, c-format
+msgid "program header entry %d: unknown program header entry type %#<PRIx64>\n"
+msgstr ""
+"wpis nagłówka programu %d: nieznany typ wpisu nagłówka programu %#<PRIx64>\n"
+
+#: src/elflint.c:4469
+#, c-format
+msgid "more than one INTERP entry in program header\n"
+msgstr "więcej niż jeden wpis INTERP w nagłówku programu\n"
+
+#: src/elflint.c:4477
+#, c-format
+msgid "more than one TLS entry in program header\n"
+msgstr "więcej niż jeden wpis TLS w nagłówku programu\n"
+
+#: src/elflint.c:4484
+#, c-format
+msgid "static executable cannot have dynamic sections\n"
+msgstr "statyczny plik wykonywalny nie może mieć sekcji dynamicznych\n"
+
+#: src/elflint.c:4498
+#, c-format
+msgid "dynamic section reference in program header has wrong offset\n"
+msgstr "odniesienie sekcji dynamicznej w nagłówku programu ma błędny offset\n"
+
+#: src/elflint.c:4501
+#, c-format
+msgid "dynamic section size mismatch in program and section header\n"
+msgstr "różne rozmiary sekcji dynamicznej w nagłówku programu i sekcji\n"
+
+#: src/elflint.c:4511
+#, c-format
+msgid "more than one GNU_RELRO entry in program header\n"
+msgstr "więcej niż jeden wpis GNU_RELRO w nagłówku programu\n"
+
+#: src/elflint.c:4532
+#, c-format
+msgid "loadable segment GNU_RELRO applies to is not writable\n"
+msgstr "wczytywalny segment wskazywany przez GNU_RELRO nie jest zapisywalny\n"
+
+#: src/elflint.c:4543
+#, c-format
+msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"
+msgstr "flagi wczytywalnego segmentu [%u] nie pasują do flag GNU_RELRO [%u]\n"
+
+#: src/elflint.c:4550
+#, c-format
+msgid ""
+"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n"
+msgstr ""
+"flagi GNU_RELRO [%u] nie są podzbiorem flag wczytywalnego segmentu [%u]\n"
+
+#: src/elflint.c:4559 src/elflint.c:4582
+#, c-format
+msgid "%s segment not contained in a loaded segment\n"
+msgstr "segment %s nie zawiera się we wczytywalnym segmencie\n"
+
+#: src/elflint.c:4588
+#, c-format
+msgid "program header offset in ELF header and PHDR entry do not match"
+msgstr ""
+"offsety nagłówka programu w nagłówku ELF i wpisie PHDR nie zgadzają się"
+
+#: src/elflint.c:4613
+#, c-format
+msgid "call frame search table reference in program header has wrong offset\n"
+msgstr ""
+"odniesienie tabeli wyszukiwania ramki wywołania w nagłówku programu ma "
+"błędny offset\n"
+
+#: src/elflint.c:4616
+#, c-format
+msgid "call frame search table size mismatch in program and section header\n"
+msgstr ""
+"różne rozmiary tabel wyszukiwania ramki wywołania w nagłówku programu "
+"i sekcji\n"
+
+#: src/elflint.c:4629
+#, c-format
+msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"
+msgstr "PT_GNU_EH_FRAME jest obecne, ale brak sekcji .eh_frame_hdr\n"
+
+#: src/elflint.c:4637
+#, c-format
+msgid "call frame search table must be allocated\n"
+msgstr "tabela wyszukiwania ramki wywołania musi być przydzielona\n"
+
+#: src/elflint.c:4640
+#, c-format
+msgid "section [%2zu] '%s' must be allocated\n"
+msgstr "sekcja [%2zu] „%s”: musi być przydzielona\n"
+
+#: src/elflint.c:4644
+#, c-format
+msgid "call frame search table must not be writable\n"
+msgstr "tabela wyszukiwania ramki wywołania nie może być zapisywalna\n"
+
+#: src/elflint.c:4647
+#, c-format
+msgid "section [%2zu] '%s' must not be writable\n"
+msgstr "sekcja [%2zu] „%s” nie może być zapisywalna\n"
+
+#: src/elflint.c:4652
+#, c-format
+msgid "call frame search table must not be executable\n"
+msgstr "tabela wyszukiwania ramki wywołania nie może być wykonywalna\n"
+
+#: src/elflint.c:4655
+#, c-format
+msgid "section [%2zu] '%s' must not be executable\n"
+msgstr "sekcja [%2zu] „%s” nie może być wykonywalna\n"
+
+#: src/elflint.c:4666
+#, c-format
+msgid "program header entry %d: file size greater than memory size\n"
+msgstr "wpis nagłówka programu %d: rozmiar pliku większy niż rozmiar pamięci\n"
+
+#: src/elflint.c:4673
+#, c-format
+msgid "program header entry %d: alignment not a power of 2\n"
+msgstr "wpis nagłówka programu %d: wyrównanie nie jest potęgą 2\n"
+
+#: src/elflint.c:4676
+#, c-format
+msgid ""
+"program header entry %d: file offset and virtual address not module of "
+"alignment\n"
+msgstr ""
+"wpis nagłówka programu %d: offset w pliku i adres wirtualny nie są "
+"wielokrotnością wyrównania\n"
+
+#: src/elflint.c:4689
+#, c-format
+msgid ""
+"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME "
+"program header entry"
+msgstr ""
+"plik wykonywalny/DSO z sekcją .eh_frame_hdr nie ma wpisu nagłówka programu "
+"PT_GNU_EH_FRAME"
+
+#: src/elflint.c:4723
+#, c-format
+msgid "cannot read ELF header: %s\n"
+msgstr "nie można odczytać nagłówka ELF: %s\n"
+
+#: src/elflint.c:4749
+#, c-format
+msgid "text relocation flag set but not needed\n"
+msgstr "flaga relokacji tekstu jest ustawiona, ale niepotrzebna\n"
+
+#: src/findtextrel.c:61
+msgid "Input Selection:"
+msgstr "Wybór wejścia:"
+
+#: src/findtextrel.c:62
+msgid "Prepend PATH to all file names"
+msgstr "Dołącza ŚCIEŻKĘ do wszystkich nazw plików"
+
+#: src/findtextrel.c:64
+msgid "Use PATH as root of debuginfo hierarchy"
+msgstr "Używa ŚCIEŻKI jako korzenia dla hierarchii debuginfo"
+
+#. Short description of program.
+#: src/findtextrel.c:71
+msgid "Locate source of text relocations in FILEs (a.out by default)."
+msgstr "Odnajduje źródło relokacji tekstu w PLIKACH (domyślnie a.out)."
+
+#. Strings for arguments in help texts.
+#: src/findtextrel.c:75 src/nm.c:109 src/objdump.c:72 src/size.c:81
+#: src/strings.c:88 src/strip.c:99
+msgid "[FILE...]"
+msgstr "[PLIK…]"
+
+#: src/findtextrel.c:223
+#, c-format
+msgid "cannot get ELF header '%s': %s"
+msgstr "nie można uzyskać nagłówka ELF „%s”: %s"
+
+#: src/findtextrel.c:234
+#, c-format
+msgid "'%s' is not a DSO or PIE"
+msgstr "„%s” nie jest DSO ani PIE"
+
+#: src/findtextrel.c:254
+#, c-format
+msgid "getting get section header of section %zu: %s"
+msgstr "uzyskiwanie nagłówka sekcji dla sekcji %zu: %s"
+
+#: src/findtextrel.c:277
+#, c-format
+msgid "cannot read dynamic section: %s"
+msgstr "nie można odczytać sekcji dynamicznej: %s"
+
+#: src/findtextrel.c:298
+#, c-format
+msgid "no text relocations reported in '%s'"
+msgstr "brak relokacji tekstu w „%s”"
+
+#: src/findtextrel.c:310
+#, c-format
+msgid "while reading ELF file"
+msgstr "podczas odczytywania pliku ELF"
+
+#: src/findtextrel.c:314
+#, c-format
+msgid "cannot get program header count: %s"
+msgstr "nie można uzyskać liczby nagłówków programu: %s"
+
+#: src/findtextrel.c:325 src/findtextrel.c:342
+#, c-format
+msgid "cannot get program header index at offset %zd: %s"
+msgstr "nie można uzyskać indeksu nagłówka programu pod offsetem %zd: %s"
+
+#: src/findtextrel.c:406
+#, c-format
+msgid "cannot get symbol table section %zu in '%s': %s"
+msgstr "nie można uzyskać sekcji tabeli symboli %zu w „%s”: %s"
+
+#: src/findtextrel.c:426 src/findtextrel.c:449
+#, c-format
+msgid "cannot get relocation at index %d in section %zu in '%s': %s"
+msgstr "nie można uzyskać relokacji pod indeksem %d w sekcji %zu w „%s”: %s"
+
+#: src/findtextrel.c:515
+#, c-format
+msgid "%s not compiled with -fpic/-fPIC\n"
+msgstr "%s nie został skompilowany z -fpic/-fPIC\n"
+
+#: src/findtextrel.c:568
+#, c-format
+msgid ""
+"the file containing the function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr "plik zawierający funkcję „%s” nie został skompilowany z -fpic/-fPIC\n"
+
+#: src/findtextrel.c:575 src/findtextrel.c:595
+#, c-format
+msgid ""
+"the file containing the function '%s' might not be compiled with -fpic/-"
+"fPIC\n"
+msgstr ""
+"plik zawierający funkcję „%s” mógł nie zostać skompilowany z -fpic/-fPIC\n"
+
+#: src/findtextrel.c:583
+#, c-format
+msgid ""
+"either the file containing the function '%s' or the file containing the "
+"function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+"plik zawierający funkcję „%s” lub plik zawierający funkcję „%s” nie został "
+"skompilowany z -fpic/-fPIC\n"
+
+#: src/findtextrel.c:603
+#, c-format
+msgid ""
+"a relocation modifies memory at offset %llu in a write-protected segment\n"
+msgstr ""
+"relokacja modyfikuje pamięć pod offsetem %llu w segmencie zabezpieczonym "
+"przed zapisem\n"
+
+#: src/nm.c:67 src/strip.c:70
+msgid "Output selection:"
+msgstr "Wybór wyjścia:"
+
+#: src/nm.c:68
+msgid "Display debugger-only symbols"
+msgstr "Wyświetla symbole wyłącznie debugowania"
+
+#: src/nm.c:69
+msgid "Display only defined symbols"
+msgstr "Wyświetla tylko określone symbole"
+
+#: src/nm.c:72
+msgid "Display dynamic symbols instead of normal symbols"
+msgstr "Wyświetla symbole dynamiczne zamiast zwykłych"
+
+#: src/nm.c:73
+msgid "Display only external symbols"
+msgstr "Wyświetla tylko symbole zewnętrzne"
+
+#: src/nm.c:74
+msgid "Display only undefined symbols"
+msgstr "Wyświetla tylko nieokreślone symbole"
+
+#: src/nm.c:76
+msgid "Include index for symbols from archive members"
+msgstr "Dołącza indeks dla symboli z elementów archiwum"
+
+#: src/nm.c:78 src/size.c:55
+msgid "Output format:"
+msgstr "Format wyjścia:"
+
+#: src/nm.c:80
+msgid "Print name of the input file before every symbol"
+msgstr "Wyświetla nazwę pliku wejściowego przed każdym symbolem"
+
+#: src/nm.c:83
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd', `sysv' or `posix'.  The "
+"default is `sysv'"
+msgstr ""
+"Używa FORMATU wyjściowego. Może to być „bsd”, „sysv” lub „posix”. Domyślny "
+"jest format „sysv”"
+
+#: src/nm.c:85
+msgid "Same as --format=bsd"
+msgstr "To samo, co --format=bsd"
+
+#: src/nm.c:86
+msgid "Same as --format=posix"
+msgstr "To samo co, --format=posix"
+
+#: src/nm.c:87 src/size.c:61
+msgid "Use RADIX for printing symbol values"
+msgstr "Używa BAZY do wypisywania wartości symboli"
+
+#: src/nm.c:88
+msgid "Mark special symbols"
+msgstr "Oznacza specjalne symbole"
+
+#: src/nm.c:90
+msgid "Print size of defined symbols"
+msgstr "Wyświetla rozmiar określonych symboli"
+
+#: src/nm.c:92 src/size.c:69 src/strip.c:75 src/unstrip.c:73
+msgid "Output options:"
+msgstr "Opcje wyjścia:"
+
+#: src/nm.c:93
+msgid "Sort symbols numerically by address"
+msgstr "Porządkuje symbole numerycznie według adresu"
+
+#: src/nm.c:95
+msgid "Do not sort the symbols"
+msgstr "Bez porządkowania symboli"
+
+#: src/nm.c:96
+msgid "Reverse the sense of the sort"
+msgstr "Odwraca kierunek porządkowania"
+
+#: src/nm.c:99
+msgid "Decode low-level symbol names into source code names"
+msgstr "Dekoduje niskopoziomowe nazwy symboli na nazwy kodu źródłowego"
+
+#. Short description of program.
+#: src/nm.c:106
+msgid "List symbols from FILEs (a.out by default)."
+msgstr "Wyświetla listę symboli z PLIKU (domyślnie a.out)."
+
+#: src/nm.c:117 src/objdump.c:80
+msgid "Output formatting"
+msgstr "Formatowanie wyjścia"
+
+#: src/nm.c:141 src/objdump.c:104 src/size.c:106 src/strip.c:131
+#, c-format
+msgid "%s: INTERNAL ERROR %d (%s): %s"
+msgstr "%s: BŁĄD WEWNĘTRZNY %d (%s): %s"
+
+#: src/nm.c:382 src/nm.c:394 src/size.c:289 src/size.c:298 src/size.c:309
+#: src/strip.c:2421
+#, c-format
+msgid "while closing '%s'"
+msgstr "podczas zamykania „%s”"
+
+#: src/nm.c:404 src/objdump.c:281 src/strip.c:443
+#, c-format
+msgid "%s: File format not recognized"
+msgstr "%s: nie rozpoznano formatu pliku"
+
+#. Note: 0 is no valid offset.
+#: src/nm.c:444
+msgid ""
+"\n"
+"Archive index:\n"
+msgstr ""
+"\n"
+"Indeks archiwum:\n"
+
+#: src/nm.c:453
+#, c-format
+msgid "invalid offset %zu for symbol %s"
+msgstr "nieprawidłowy offset %zu dla symbolu %s"
+
+#: src/nm.c:458
+#, c-format
+msgid "%s in %s\n"
+msgstr "%s w %s\n"
+
+#: src/nm.c:466
+#, c-format
+msgid "cannot reset archive offset to beginning"
+msgstr "nie można przywrócić offsetu w archiwum na początek"
+
+#: src/nm.c:491 src/objdump.c:329
+#, c-format
+msgid "%s%s%s: file format not recognized"
+msgstr "%s%s%s: nie rozpoznano formatu pliku"
+
+#: src/nm.c:706
+#, c-format
+msgid "cannot create search tree"
+msgstr "nie można utworzyć drzewa wyszukiwania"
+
+#: src/nm.c:747 src/nm.c:1208 src/objdump.c:778 src/readelf.c:551
+#: src/readelf.c:1129 src/readelf.c:1329 src/readelf.c:1477 src/readelf.c:1678
+#: src/readelf.c:1884 src/readelf.c:2074 src/readelf.c:2252 src/readelf.c:2328
+#: src/readelf.c:2586 src/readelf.c:2662 src/readelf.c:2749 src/readelf.c:3329
+#: src/readelf.c:3379 src/readelf.c:3442 src/readelf.c:8444 src/readelf.c:9544
+#: src/readelf.c:9747 src/readelf.c:9815 src/size.c:397 src/size.c:466
+#: src/strip.c:572
+#, c-format
+msgid "cannot get section header string table index"
+msgstr "nie można uzyskać indeksu tabeli ciągów nagłówków sekcji"
+
+#. We always print this prolog.
+#: src/nm.c:774
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s:\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Symbole z %s:\n"
+"\n"
+
+#. The header line.
+#: src/nm.c:777
+#, c-format
+msgid ""
+"%*s%-*s %-*s Class  Type     %-*s %*s Section\n"
+"\n"
+msgstr ""
+"%*s%-*s %-*s Klasa  Typ      %-*s %*s Sekcja\n"
+"\n"
+
+#: src/nm.c:1219
+#, c-format
+msgid "%s: entry size in section %zd `%s' is not what we expect"
+msgstr "%s: rozmiar wpisu w sekcji %zd „%s” nie jest tym, czego oczekiwano"
+
+#: src/nm.c:1224
+#, c-format
+msgid "%s: size of section %zd `%s' is not multiple of entry size"
+msgstr "%s: rozmiar sekcji %zd „%s” nie jest wielokrotnością rozmiaru wpisu"
+
+#: src/nm.c:1303
+#, c-format
+msgid "%s: entries (%zd) in section %zd `%s' is too large"
+msgstr "%s: wpisy (%zd) w sekcji %zd „%s” są za duże"
+
+#. XXX Add machine specific object file types.
+#: src/nm.c:1529
+#, c-format
+msgid "%s%s%s%s: Invalid operation"
+msgstr "%s%s%s%s: nieprawidłowe działanie"
+
+#: src/nm.c:1586
+#, c-format
+msgid "%s%s%s: no symbols"
+msgstr "%s%s%s: brak symboli"
+
+#: src/objdump.c:53
+msgid "Mode selection:"
+msgstr "Wybór trybu:"
+
+#: src/objdump.c:54
+msgid "Display relocation information."
+msgstr "Wyświetla informacje o relokacji."
+
+#: src/objdump.c:56
+msgid "Display the full contents of all sections requested"
+msgstr "Wyświetla pełną zawartość żądanych sekcji"
+
+#: src/objdump.c:58
+msgid "Display assembler code of executable sections"
+msgstr "Wyświetla kod asemblera sekcji wykonywalnych"
+
+#: src/objdump.c:60
+msgid "Output content selection:"
+msgstr "Wybór zawartości wyjścia:"
+
+#: src/objdump.c:62
+msgid "Only display information for section NAME."
+msgstr "Wyświetla tylko informacje o sekcji NAZWA."
+
+#. Short description of program.
+#: src/objdump.c:68
+msgid "Show information from FILEs (a.out by default)."
+msgstr "Wyświetla informacje z PLIKÓW (domyślnie a.out)."
+
+#: src/objdump.c:219 src/readelf.c:499
+msgid "No operation specified.\n"
+msgstr "Nie podano działania.\n"
+
+#: src/objdump.c:259 src/objdump.c:271
+#, c-format
+msgid "while close `%s'"
+msgstr "podczas zamykania „%s”"
+
+#: src/objdump.c:364 src/readelf.c:1979 src/readelf.c:2171
+msgid "INVALID SYMBOL"
+msgstr "NIEPRAWIDŁOWY SYMBOL"
+
+#: src/objdump.c:379 src/readelf.c:2013 src/readelf.c:2207
+msgid "INVALID SECTION"
+msgstr "NIEPRAWIDŁOWA SEKCJA"
+
+#: src/objdump.c:499
+#, c-format
+msgid ""
+"\n"
+"RELOCATION RECORDS FOR [%s]:\n"
+"%-*s TYPE                 VALUE\n"
+msgstr ""
+"\n"
+"PISY RELOKACJI DLA [%s]:\n"
+"%-*s TYP                  WARTOŚĆ\n"
+
+#: src/objdump.c:502
+msgid "OFFSET"
+msgstr "OFFSET"
+
+#: src/objdump.c:567
+#, c-format
+msgid "Contents of section %s:\n"
+msgstr "Zawartość sekcji %s:\n"
+
+#: src/objdump.c:688
+#, c-format
+msgid "cannot disassemble"
+msgstr "nie można deasemblować"
+
+#. Short description of program.
+#: src/ranlib.c:64
+msgid "Generate an index to speed access to archives."
+msgstr "Tworzenie indeksu w celu przyspieszenia dostępu do archiwów."
+
+#. Strings for arguments in help texts.
+#: src/ranlib.c:67
+msgid "ARCHIVE"
+msgstr "ARCHIWUM"
+
+#: src/ranlib.c:103
+#, c-format
+msgid "Archive name required"
+msgstr "Wymagana jest nazwa archiwum"
+
+#: src/ranlib.c:167
+#, c-format
+msgid "'%s' is no archive"
+msgstr "„%s” nie jest archiwum"
+
+#: src/ranlib.c:202
+#, c-format
+msgid "error while freeing sub-ELF descriptor: %s"
+msgstr "błąd podczas zwalniania deskryptora pod-ELF: %s"
+
+#: src/readelf.c:87
+msgid "ELF input selection:"
+msgstr "Wybór wyjścia ELF:"
+
+#: src/readelf.c:89
+msgid ""
+"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data"
+msgstr ""
+"Używa podanej SEKCJI (domyślnie .gnu_debugdata) jako (skompresowanych) "
+"danych wejściowych ELF"
+
+#: src/readelf.c:91
+msgid "ELF output selection:"
+msgstr "Wybór wyjścia ELF:"
+
+#: src/readelf.c:93
+msgid "All these plus -p .strtab -p .dynstr -p .comment"
+msgstr "Wszystkie te plus -p .strtab -p .dynstr -p .comment"
+
+#: src/readelf.c:94
+msgid "Display the dynamic segment"
+msgstr "Wyświetla segment dynamiczny"
+
+#: src/readelf.c:95
+msgid "Display the ELF file header"
+msgstr "Wyświetla nagłówek pliku ELF"
+
+#: src/readelf.c:97
+msgid "Display histogram of bucket list lengths"
+msgstr "Wyświetla histogram długości list kubełków"
+
+#: src/readelf.c:98
+msgid "Display the program headers"
+msgstr "Wyświetla nagłówki programu"
+
+#: src/readelf.c:100
+msgid "Display relocations"
+msgstr "Wyświetla relokacje"
+
+#: src/readelf.c:101
+msgid "Display the sections' headers"
+msgstr "Wyświetla nagłówki sekcji"
+
+#: src/readelf.c:104
+msgid "Display the symbol table sections"
+msgstr "Wyświetla sekcje tabeli symboli"
+
+#: src/readelf.c:105
+msgid "Display versioning information"
+msgstr "Wyświetla informacje o wersji"
+
+#: src/readelf.c:106
+msgid "Display the ELF notes"
+msgstr "Wyświetla notatki ELF"
+
+#: src/readelf.c:108
+msgid "Display architecture specific information, if any"
+msgstr "Wyświetla informacje dla konkretnej architektury, jeśli są"
+
+#: src/readelf.c:110
+msgid "Display sections for exception handling"
+msgstr "Wyświetla sekcje do obsługi wyjątków"
+
+#: src/readelf.c:112
+msgid "Additional output selection:"
+msgstr "Dodatkowy wybór wyjścia:"
+
+#: src/readelf.c:114
+msgid ""
+"Display DWARF section content.  SECTION can be one of abbrev, aranges, "
+"decodedaranges, frame, gdb_index, info, loc, line, decodedline, ranges, "
+"pubnames, str, macinfo, macro or exception"
+msgstr ""
+"Wyświetla zawartość sekcji DWARF. SEKCJA może być jednym z abbrev, aranges, "
+"decodedaranges, frame, gdb_index, info, loc, line, decodedline, ranges, "
+"pubnames, str, macinfo, macro lub exception"
+
+#: src/readelf.c:118
+msgid "Dump the uninterpreted contents of SECTION, by number or name"
+msgstr "Zrzuca niezinterpretowaną zawartość SEKCJI, według liczny lub nazwy"
+
+#: src/readelf.c:120
+msgid "Print string contents of sections"
+msgstr "Wyświetla zawartość ciągów sekcji"
+
+#: src/readelf.c:123
+msgid "Display the symbol index of an archive"
+msgstr "Wyświetla indeks symboli archiwum"
+
+#: src/readelf.c:125
+msgid "Output control:"
+msgstr "Kontrola wyjścia:"
+
+#: src/readelf.c:127
+msgid "Do not find symbol names for addresses in DWARF data"
+msgstr "Bez odnajdywania nazw symboli dla adresów w danych DWARF"
+
+#: src/readelf.c:129
+msgid ""
+"Display just offsets instead of resolving values to addresses in DWARF data"
+msgstr ""
+"Wyświetla tylko offsety zamiast rozwiązywania wartości na adresy w danych "
+"DWARF"
+
+#: src/readelf.c:131
+msgid "Ignored for compatibility (lines always wide)"
+msgstr "Ignorowane dla zgodności (wiersze są zawsze szerokie)"
+
+#: src/readelf.c:133
+msgid ""
+"Show compression information for compressed sections (when used with -S); "
+"decompress section before dumping data (when used with -p or -x)"
+msgstr ""
+"Wyświetla informacje o kompresji dla skompresowanych sekcji (kiedy jest "
+"używane z opcją -S); dekompresuje sekcję przed zrzuceniem danych (kiedy jest "
+"używane z opcją -p lub -x)"
+
+#. Short description of program.
+#: src/readelf.c:138
+msgid "Print information from ELF file in human-readable form."
+msgstr "Wyświetla informacje z pliku ELF w postaci czytelnej dla człowieka."
+
+#: src/readelf.c:467
+#, c-format
+msgid "Unknown DWARF debug section `%s'.\n"
+msgstr "Nieznana sekcja debugowania DWARF „%s”.\n"
+
+#: src/readelf.c:535 src/readelf.c:646
+#, c-format
+msgid "cannot generate Elf descriptor: %s"
+msgstr "nie można utworzyć deskryptora ELF: %s"
+
+#: src/readelf.c:542 src/readelf.c:858 src/strip.c:641
+#, c-format
+msgid "cannot determine number of sections: %s"
+msgstr "nie można określić liczby sekcji: %s"
+
+#: src/readelf.c:560 src/readelf.c:1151 src/readelf.c:1353
+#, c-format
+msgid "cannot get section: %s"
+msgstr "nie można uzyskać sekcji: %s"
+
+#: src/readelf.c:569 src/readelf.c:1158 src/readelf.c:1361 src/readelf.c:9767
+#: src/unstrip.c:375 src/unstrip.c:406 src/unstrip.c:455 src/unstrip.c:565
+#: src/unstrip.c:582 src/unstrip.c:619 src/unstrip.c:817 src/unstrip.c:1109
+#: src/unstrip.c:1301 src/unstrip.c:1362 src/unstrip.c:1535 src/unstrip.c:1650
+#: src/unstrip.c:1790 src/unstrip.c:1885
+#, c-format
+msgid "cannot get section header: %s"
+msgstr "nie można uzyskać nagłówka sekcji: %s"
+
+#: src/readelf.c:577
+#, c-format
+msgid "cannot get section name"
+msgstr "nie można uzyskać nazwy sekcji"
+
+#: src/readelf.c:586 src/readelf.c:5562 src/readelf.c:7902 src/readelf.c:8004
+#: src/readelf.c:8181
+#, c-format
+msgid "cannot get %s content: %s"
+msgstr "nie można uzyskać zwartości %s: %s"
+
+#: src/readelf.c:602
+#, c-format
+msgid "cannot create temp file '%s'"
+msgstr "nie można utworzyć pliku tymczasowego „%s”"
+
+#: src/readelf.c:611
+#, c-format
+msgid "cannot write section data"
+msgstr "nie można zapisać danych sekcji"
+
+#: src/readelf.c:617 src/readelf.c:634 src/readelf.c:663
+#, c-format
+msgid "error while closing Elf descriptor: %s"
+msgstr "błąd podczas zamykania deskryptora ELF: %s"
+
+#: src/readelf.c:624
+#, c-format
+msgid "error while rewinding file descriptor"
+msgstr "błąd podczas przewijania deskryptora pliku"
+
+#: src/readelf.c:658
+#, c-format
+msgid "'%s' is not an archive, cannot print archive index"
+msgstr "„%s” nie jest archiwum, nie można wyświetlić indeksu archiwum"
+
+#: src/readelf.c:757
+#, c-format
+msgid "No such section '%s' in '%s'"
+msgstr "Brak sekcji „%s” w „%s”"
+
+#: src/readelf.c:784
+#, c-format
+msgid "cannot stat input file"
+msgstr "nie można wykonać stat na pliku wejściowym"
+
+#: src/readelf.c:786
+#, c-format
+msgid "input file is empty"
+msgstr "plik wejściowy jest pusty"
+
+#: src/readelf.c:788
+#, c-format
+msgid "failed reading '%s': %s"
+msgstr "odczytanie „%s” się nie powiodło: %s"
+
+#: src/readelf.c:843
+#, c-format
+msgid "cannot read ELF header: %s"
+msgstr "nie można odczytać nagłówka ELF: %s"
+
+#: src/readelf.c:851
+#, c-format
+msgid "cannot create EBL handle"
+msgstr "nie można utworzyć uchwytu EBL"
+
+#: src/readelf.c:864
+#, c-format
+msgid "cannot determine number of program headers: %s"
+msgstr "nie można określić liczby nagłówków programu: %s"
+
+#: src/readelf.c:954
+msgid "NONE (None)"
+msgstr "NONE (żaden)"
+
+#: src/readelf.c:955
+msgid "REL (Relocatable file)"
+msgstr "REL (plik relokowalny)"
+
+#: src/readelf.c:956
+msgid "EXEC (Executable file)"
+msgstr "EXEC (plik wykonywalny)"
+
+#: src/readelf.c:957
+msgid "DYN (Shared object file)"
+msgstr "DYN (plik obiektu współdzielonego)"
+
+#: src/readelf.c:958
+msgid "CORE (Core file)"
+msgstr "CORE (plik core)"
+
+#: src/readelf.c:963
+#, c-format
+msgid "OS Specific: (%x)\n"
+msgstr "Zależny od systemu: (%x)\n"
+
+#. && e_type <= ET_HIPROC always true
+#: src/readelf.c:965
+#, c-format
+msgid "Processor Specific: (%x)\n"
+msgstr "Zależny od procesora: (%x)\n"
+
+#: src/readelf.c:975
+msgid ""
+"ELF Header:\n"
+"  Magic:  "
+msgstr ""
+"Nagłówek ELF:\n"
+"  Magic:  "
+
+#: src/readelf.c:979
+#, c-format
+msgid ""
+"\n"
+"  Class:                             %s\n"
+msgstr ""
+"\n"
+"  Klasa:                             %s\n"
+
+#: src/readelf.c:984
+#, c-format
+msgid "  Data:                              %s\n"
+msgstr "  Dane:                              %s\n"
+
+#: src/readelf.c:990
+#, c-format
+msgid "  Ident Version:                     %hhd %s\n"
+msgstr "  Wersja Ident:                      %hhd %s\n"
+
+#: src/readelf.c:992 src/readelf.c:1009
+msgid "(current)"
+msgstr "(bieżąca)"
+
+#: src/readelf.c:996
+#, c-format
+msgid "  OS/ABI:                            %s\n"
+msgstr "  System operacyjny/ABI:             %s\n"
+
+#: src/readelf.c:999
+#, c-format
+msgid "  ABI Version:                       %hhd\n"
+msgstr "  Wersja ABI:                        %hhd\n"
+
+#: src/readelf.c:1002
+msgid "  Type:                              "
+msgstr "  Typ:                               "
+
+#: src/readelf.c:1005
+#, c-format
+msgid "  Machine:                           %s\n"
+msgstr "  Komputer:                          %s\n"
+
+#: src/readelf.c:1007
+#, c-format
+msgid "  Version:                           %d %s\n"
+msgstr "  Wersja:                            %d %s\n"
+
+#: src/readelf.c:1011
+#, c-format
+msgid "  Entry point address:               %#<PRIx64>\n"
+msgstr "  Adres punktu wejściowego:          %#<PRIx64>\n"
+
+#: src/readelf.c:1014
+#, c-format
+msgid "  Start of program headers:          %<PRId64> %s\n"
+msgstr "  Początek nagłówków programu:       %<PRId64> %s\n"
+
+#: src/readelf.c:1015 src/readelf.c:1018
+msgid "(bytes into file)"
+msgstr "(bajtów w pliku)"
+
+#: src/readelf.c:1017
+#, c-format
+msgid "  Start of section headers:          %<PRId64> %s\n"
+msgstr "  Początek nagłówków sekcji:         %<PRId64> %s\n"
+
+#: src/readelf.c:1020
+#, c-format
+msgid "  Flags:                             %s\n"
+msgstr "  Flagi:                             %s\n"
+
+#: src/readelf.c:1023
+#, c-format
+msgid "  Size of this header:               %<PRId16> %s\n"
+msgstr "  Rozmiar tego nagłówka:             %<PRId16> %s\n"
+
+#: src/readelf.c:1024 src/readelf.c:1027 src/readelf.c:1044
+msgid "(bytes)"
+msgstr "(bajtów)"
+
+#: src/readelf.c:1026
+#, c-format
+msgid "  Size of program header entries:    %<PRId16> %s\n"
+msgstr "  Rozmiar wpisów nagłówka programu:  %<PRId16> %s\n"
+
+#: src/readelf.c:1029
+#, c-format
+msgid "  Number of program headers entries: %<PRId16>"
+msgstr "  Liczba wpisów nagłówków programu: %<PRId16>"
+
+#: src/readelf.c:1036
+#, c-format
+msgid " (%<PRIu32> in [0].sh_info)"
+msgstr " (%<PRIu32> w [0].sh_info)"
+
+#: src/readelf.c:1039 src/readelf.c:1056 src/readelf.c:1070
+msgid " ([0] not available)"
+msgstr " ([0] niedostępny)"
+
+#: src/readelf.c:1043
+#, c-format
+msgid "  Size of section header entries:    %<PRId16> %s\n"
+msgstr "  Rozmiar wpisów nagłówka sekcji:    %<PRId16> %s\n"
+
+#: src/readelf.c:1046
+#, c-format
+msgid "  Number of section headers entries: %<PRId16>"
+msgstr "  Liczba wpisów nagłówków sekcji:    %<PRId16>"
+
+#: src/readelf.c:1053
+#, c-format
+msgid " (%<PRIu32> in [0].sh_size)"
+msgstr " (%<PRIu32> w [0].sh_size)"
+
+#. We managed to get the zeroth section.
+#: src/readelf.c:1066
+#, c-format
+msgid " (%<PRIu32> in [0].sh_link)"
+msgstr " (%<PRIu32> w [0].sh_link)"
+
+#: src/readelf.c:1074
+#, c-format
+msgid ""
+"  Section header string table index: XINDEX%s\n"
+"\n"
+msgstr ""
+"  Indeks tabeli ciągów nagłówków sekcji: XINDEX%s\n"
+"\n"
+
+#: src/readelf.c:1078
+#, c-format
+msgid ""
+"  Section header string table index: %<PRId16>\n"
+"\n"
+msgstr ""
+"  Indeks tabeli ciągów nagłówków sekcji: %<PRId16>\n"
+"\n"
+
+#: src/readelf.c:1121
+#, c-format
+msgid ""
+"There are %d section headers, starting at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+"Jest %d nagłówków sekcji, rozpoczynających się od offsetu %#<PRIx64>:\n"
+"\n"
+
+#: src/readelf.c:1131
+msgid "Section Headers:"
+msgstr "Nagłówki sekcji:"
+
+#: src/readelf.c:1134
+msgid ""
+"[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
+"Inf Al"
+msgstr ""
+"[Nr] Nazwa                Typ          Adres    Offset Rozm.  ES Flagi Lk "
+"Inf Al"
+
+#: src/readelf.c:1136
+msgid ""
+"[Nr] Name                 Type         Addr             Off      Size     ES "
+"Flags Lk Inf Al"
+msgstr ""
+"[Nr] Nazwa                Typ          Adres            Offset   Rozmiar  ES "
+"Flagi Lk Inf Al"
+
+#: src/readelf.c:1141
+msgid "     [Compression  Size   Al]"
+msgstr "     [Kompresja  Rozmiar   Al]"
+
+#: src/readelf.c:1143
+msgid "     [Compression  Size     Al]"
+msgstr "     [Kompresja  Rozmiar     Al]"
+
+#: src/readelf.c:1219
+#, c-format
+msgid "bad compression header for section %zd: %s"
+msgstr "błędny nagłówek kompresji dla sekcji %zd: %s"
+
+#: src/readelf.c:1230
+#, c-format
+msgid "bad gnu compressed size for section %zd: %s"
+msgstr "błędny rozmiar kompresji gnu dla sekcji %zd: %s"
+
+#: src/readelf.c:1248
+msgid "Program Headers:"
+msgstr "Nagłówki programu:"
+
+#: src/readelf.c:1250
+msgid ""
+"  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
+msgstr ""
+"  Typ            Offset   AdresWirt  AdresFiz   RozmPlik RozmPam  Flg "
+"Wyrównanie"
+
+#: src/readelf.c:1253
+msgid ""
+"  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
+"MemSiz   Flg Align"
+msgstr ""
+"  Typ            Offset   AdresWirtualny     AdresFizyczny      RozmPlik "
+"RozmPam  Flg Wyrównanie"
+
+#: src/readelf.c:1310
+#, c-format
+msgid "\t[Requesting program interpreter: %s]\n"
+msgstr "\t[Wywołanie interpretera programu: %s]\n"
+
+#: src/readelf.c:1331
+msgid ""
+"\n"
+" Section to Segment mapping:\n"
+"  Segment Sections..."
+msgstr ""
+"\n"
+" Mapowanie sekcji do segmentów:\n"
+"  Segment sekcji…"
+
+#: src/readelf.c:1342 src/unstrip.c:1944 src/unstrip.c:1986 src/unstrip.c:1993
+#, c-format
+msgid "cannot get program header: %s"
+msgstr "nie można uzyskać nagłówka programu: %s"
+
+#: src/readelf.c:1485
+#, c-format
+msgid ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"Grupa sekcji COMDAT [%2zu] „%s” z podpisem „%s” zawiera %zu wpis:\n"
+msgstr[1] ""
+"\n"
+"Grupa sekcji COMDAT [%2zu] „%s” z podpisem „%s” zawiera %zu wpisy:\n"
+msgstr[2] ""
+"\n"
+"Grupa sekcji COMDAT [%2zu] „%s” z podpisem „%s” zawiera %zu wpisów:\n"
+
+#: src/readelf.c:1490
+#, c-format
+msgid ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"Grupa sekcji [%2zu] „%s” z podpisem „%s” zawiera %zu wpis:\n"
+msgstr[1] ""
+"\n"
+"Grupa sekcji [%2zu] „%s” z podpisem „%s” zawiera %zu wpisy:\n"
+msgstr[2] ""
+"\n"
+"Grupa sekcji [%2zu] „%s” z podpisem „%s” zawiera %zu wpisów:\n"
+
+#: src/readelf.c:1498
+msgid "<INVALID SYMBOL>"
+msgstr "<NIEPRAWIDŁOWY SYMBOL>"
+
+#: src/readelf.c:1512
+msgid "<INVALID SECTION>"
+msgstr "<NIEPRAWIDŁOWY SEKCJA>"
+
+#: src/readelf.c:1535 src/readelf.c:2262 src/readelf.c:3345 src/readelf.c:9638
+#: src/readelf.c:9645 src/readelf.c:9689 src/readelf.c:9696
+msgid "Couldn't uncompress section"
+msgstr "Nie można dekompresować sekcji"
+
+#: src/readelf.c:1540 src/readelf.c:2267 src/readelf.c:3350
+#, c-format
+msgid "cannot get section [%zd] header: %s"
+msgstr "nie można uzyskać nagłówka sekcji [%zd]: %s"
+
+#: src/readelf.c:1684 src/readelf.c:2334 src/readelf.c:2592 src/readelf.c:2668
+#: src/readelf.c:2972 src/readelf.c:3046 src/readelf.c:4773
+#, c-format
+msgid "invalid sh_link value in section %zu"
+msgstr "nieprawidłowa wartość sh_link w sekcji %zu"
+
+#: src/readelf.c:1687
+#, c-format
+msgid ""
+"\n"
+"Dynamic segment contains %lu entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Dynamic segment contains %lu entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Segment dynamiczny zawiera %lu wpis:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"'%s'\n"
+msgstr[1] ""
+"\n"
+"Segment dynamiczny zawiera %lu wpisy:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"'%s'\n"
+msgstr[2] ""
+"\n"
+"Segment dynamiczny zawiera %lu wpisów:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"'%s'\n"
+
+#: src/readelf.c:1697
+msgid "  Type              Value\n"
+msgstr "  Typ               Wartość\n"
+
+#: src/readelf.c:1721
+#, c-format
+msgid "Shared library: [%s]\n"
+msgstr "Biblioteka współdzielona: [%s]\n"
+
+#: src/readelf.c:1726
+#, c-format
+msgid "Library soname: [%s]\n"
+msgstr "soname biblioteki: [%s]\n"
+
+#: src/readelf.c:1731
+#, c-format
+msgid "Library rpath: [%s]\n"
+msgstr "rpath biblioteki: [%s]\n"
+
+#: src/readelf.c:1736
+#, c-format
+msgid "Library runpath: [%s]\n"
+msgstr "runpath biblioteki: [%s]\n"
+
+#: src/readelf.c:1756
+#, c-format
+msgid "%<PRId64> (bytes)\n"
+msgstr "%<PRId64> (bajtów)\n"
+
+#: src/readelf.c:1869 src/readelf.c:2059
+#, c-format
+msgid ""
+"\n"
+"Invalid symbol table at offset %#0<PRIx64>\n"
+msgstr ""
+"\n"
+"Nieprawidłowa tabela symboli pod offsetem %#0<PRIx64>\n"
+
+#: src/readelf.c:1887 src/readelf.c:2077
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"Sekcja relokacji [%2zu] „%s” dla sekcji [%2u] „%s” pod offsetem %#0<PRIx64> "
+"zawiera %d wpis:\n"
+msgstr[1] ""
+"\n"
+"Sekcja relokacji [%2zu] „%s” dla sekcji [%2u] „%s” pod offsetem %#0<PRIx64> "
+"zawiera %d wpisy:\n"
+msgstr[2] ""
+"\n"
+"Sekcja relokacji [%2zu] „%s” dla sekcji [%2u] „%s” pod offsetem %#0<PRIx64> "
+"zawiera %d wpisów:\n"
+
+#. The .rel.dyn section does not refer to a specific section but
+#. instead of section index zero.  Do not try to print a section
+#. name.
+#. The .rela.dyn section does not refer to a specific section but
+#. instead of section index zero.  Do not try to print a section
+#. name.
+#: src/readelf.c:1902 src/readelf.c:2092
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"Sekcja relokacji [%2u] „%s” pod offsetem %#0<PRIx64> zawiera %d wpis:\n"
+msgstr[1] ""
+"\n"
+"Sekcja relokacji [%2u] „%s” pod offsetem %#0<PRIx64> zawiera %d wpisy:\n"
+msgstr[2] ""
+"\n"
+"Sekcja relokacji [%2u] „%s” pod offsetem %#0<PRIx64> zawiera %d wpisów:\n"
+
+#: src/readelf.c:1912
+msgid "  Offset      Type                 Value       Name\n"
+msgstr "  Offset      Typ                  Wartość     Nazwa\n"
+
+#: src/readelf.c:1914
+msgid "  Offset              Type                 Value               Name\n"
+msgstr "  Offset              Typ                  Wartość             Nazwa\n"
+
+#: src/readelf.c:1967 src/readelf.c:1978 src/readelf.c:1991 src/readelf.c:2012
+#: src/readelf.c:2024 src/readelf.c:2158 src/readelf.c:2170 src/readelf.c:2184
+#: src/readelf.c:2206 src/readelf.c:2219
+msgid "<INVALID RELOC>"
+msgstr "<NIEPRAWIDŁOWA RELOKACJA>"
+
+#: src/readelf.c:2102
+msgid "  Offset      Type            Value       Addend Name\n"
+msgstr "  Offset      Typ             Wartość     Koniec Nazwa\n"
+
+#: src/readelf.c:2104
+msgid "  Offset              Type            Value               Addend Name\n"
+msgstr ""
+"  Offset              Typ             Wartość             Koniec Nazwa\n"
+
+#: src/readelf.c:2342
+#, c-format
+msgid ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entry:\n"
+msgid_plural ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entries:\n"
+msgstr[0] ""
+"\n"
+"Tabela symboli [%2u] „%s” zawiera %u wpis:\n"
+msgstr[1] ""
+"\n"
+"Tabela symboli [%2u] „%s” zawiera %u wpisy:\n"
+msgstr[2] ""
+"\n"
+"Tabela symboli [%2u] „%s” zawiera %u wpisów:\n"
+
+#: src/readelf.c:2347
+#, c-format
+msgid " %lu local symbol  String table: [%2u] '%s'\n"
+msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
+msgstr[0] " %lu symbol lokalny     Tabela ciągów: [%2u] „%s”\n"
+msgstr[1] " %lu symbole lokalne    Tabela ciągów: [%2u] „%s”\n"
+msgstr[2] " %lu symboli lokalnych  Tabela ciągów: [%2u] „%s”\n"
+
+#: src/readelf.c:2355
+msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr "  Numer:  Wartość Rozm Typ     Bind   Widoczność   Ndx Nazwa\n"
+
+#: src/readelf.c:2357
+msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr "  Numer:          Wartość Rozm Typ     Bind   Widoczność   Ndx Nazwa\n"
+
+#: src/readelf.c:2377
+#, c-format
+msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+msgstr "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+
+#: src/readelf.c:2465
+#, c-format
+msgid "bad dynamic symbol"
+msgstr "błędny symbol dynamiczny"
+
+#: src/readelf.c:2547
+msgid "none"
+msgstr "brak"
+
+#: src/readelf.c:2564
+msgid "| <unknown>"
+msgstr "| <nieznany>"
+
+#: src/readelf.c:2595
+#, c-format
+msgid ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Sekcja wymaganych wersji [%2u] „%s” zawiera %d wpis:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"„%s”\n"
+msgstr[1] ""
+"\n"
+"Sekcja wymaganych wersji [%2u] „%s” zawiera %d wpisy:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"„%s”\n"
+msgstr[2] ""
+"\n"
+"Sekcja wymaganych wersji [%2u] „%s” zawiera %d wpisów:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"„%s”\n"
+
+#: src/readelf.c:2616
+#, c-format
+msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
+msgstr "  %#06x: Wersja: %hu  Plik: %s  Licznik: %hu\n"
+
+#: src/readelf.c:2629
+#, c-format
+msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
+msgstr "  %#06x: Nazwa: %s  Flagi: %s  Wersja: %hu\n"
+
+#: src/readelf.c:2672
+#, c-format
+msgid ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Sekcja definicji wersji [%2u] „%s” zawiera %d wpis:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"„%s”\n"
+msgstr[1] ""
+"\n"
+"Sekcja definicji wersji [%2u] „%s” zawiera %d wpisy:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"„%s”\n"
+msgstr[2] ""
+"\n"
+"Sekcja definicji wersji [%2u] „%s” zawiera %d wpisów:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"„%s”\n"
+
+#: src/readelf.c:2700
+#, c-format
+msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
+msgstr ""
+"  %#06x: Wersja: %hd  Flagi: %s  Indeks: %hd  Licznik: %hd  Nazwa: %s\n"
+
+#: src/readelf.c:2715
+#, c-format
+msgid "  %#06x: Parent %d: %s\n"
+msgstr "  %#06x: Rodzic %d: %s\n"
+
+#. Print the header.
+#: src/readelf.c:2976
+#, c-format
+msgid ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgid_plural ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgstr[0] ""
+"\n"
+"Sekcja symboli wersji [%2u] „%s” zawiera %d wpis:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] „%s”"
+msgstr[1] ""
+"\n"
+"Sekcja symboli wersji [%2u] „%s” zawiera %d wpisy:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] „%s”"
+msgstr[2] ""
+"\n"
+"Sekcja symboli wersji [%2u] „%s” zawiera %d wpisów:\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] „%s”"
+
+#: src/readelf.c:3004
+msgid "   0 *local*                     "
+msgstr "   0 *lokalny*                   "
+
+#: src/readelf.c:3009
+msgid "   1 *global*                    "
+msgstr "   1 *globalny*                  "
+
+#: src/readelf.c:3051
+#, c-format
+msgid ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"bucket):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"buckets):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Histogram dla długości listy kubełków w sekcji [%2u] „%s” (w sumie %d "
+"kubełek):\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"„%s”\n"
+msgstr[1] ""
+"\n"
+"Histogram dla długości listy kubełków w sekcji [%2u] „%s” (w sumie %d "
+"kubełki):\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"„%s”\n"
+msgstr[2] ""
+"\n"
+"Histogram dla długości listy kubełków w sekcji [%2u] „%s” (w sumie %d "
+"kubełków):\n"
+" Adres: %#0*<PRIx64>  Offset: %#08<PRIx64>  Dowiązanie do sekcji: [%2u] "
+"„%s”\n"
+
+#: src/readelf.c:3073
+#, no-c-format
+msgid " Length  Number  % of total  Coverage\n"
+msgstr " Długość Liczba  % całości   Pokrycie\n"
+
+#: src/readelf.c:3075
+#, c-format
+msgid "      0  %6<PRIu32>      %5.1f%%\n"
+msgstr "      0  %6<PRIu32>      %5.1f%%\n"
+
+#: src/readelf.c:3082
+#, c-format
+msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+msgstr "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+
+#: src/readelf.c:3095
+#, c-format
+msgid ""
+" Average number of tests:   successful lookup: %f\n"
+"\t\t\t  unsuccessful lookup: %f\n"
+msgstr ""
+" Średnia liczba testów:   udane wyszukania: %f\n"
+"\t\t\t  nieudane wyszukania: %f\n"
+
+#: src/readelf.c:3113 src/readelf.c:3168 src/readelf.c:3225
+#, c-format
+msgid "cannot get data for section %d: %s"
+msgstr "nie można uzyskać danych dla sekcji %d: %s"
+
+#: src/readelf.c:3121
+#, c-format
+msgid "invalid data in sysv.hash section %d"
+msgstr "nieprawidłowe dane w sekcji sysv.hash %d"
+
+#: src/readelf.c:3176
+#, c-format
+msgid "invalid data in sysv.hash64 section %d"
+msgstr "nieprawidłowe dane w sekcji sysv.hash64 %d"
+
+#: src/readelf.c:3234
+#, c-format
+msgid "invalid data in gnu.hash section %d"
+msgstr "nieprawidłowe dane w sekcji gnu.hash %d"
+
+#: src/readelf.c:3301
+#, c-format
+msgid ""
+" Symbol Bias: %u\n"
+" Bitmask Size: %zu bytes  %<PRIuFAST32>%% bits set  2nd hash shift: %u\n"
+msgstr ""
+" Przesunięcie symboli: %u\n"
+" Rozmiar maski bitowej: %zu bajtów  %<PRIuFAST32>%% bitów ustawionych  "
+"drugie przesunięcie skrótu: %u\n"
+
+#: src/readelf.c:3390
+#, c-format
+msgid ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"Sekcja listy bibliotek [%2zu] „%s” pod offsetem %#0<PRIx64> zawiera %d "
+"wpis:\n"
+msgstr[1] ""
+"\n"
+"Sekcja listy bibliotek [%2zu] „%s” pod offsetem %#0<PRIx64> zawiera %d "
+"wpisy:\n"
+msgstr[2] ""
+"\n"
+"Sekcja listy bibliotek [%2zu] „%s” pod offsetem %#0<PRIx64> zawiera %d "
+"wpisów:\n"
+
+#: src/readelf.c:3404
+msgid ""
+"       Library                       Time Stamp          Checksum Version "
+"Flags"
+msgstr ""
+"       Biblioteka                    Oznaczenie czasu    Suma k.  Wersja  "
+"Flagi"
+
+#: src/readelf.c:3454
+#, c-format
+msgid ""
+"\n"
+"Object attributes section [%2zu] '%s' of %<PRIu64> bytes at offset "
+"%#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Sekcja atrybutów obiektu [%2zu] „%s” %<PRIu64> bajtów pod offsetem "
+"%#0<PRIx64>:\n"
+
+#: src/readelf.c:3471
+msgid "  Owner          Size\n"
+msgstr "  Właściciel          Rozmiar\n"
+
+#: src/readelf.c:3500
+#, c-format
+msgid "  %-13s  %4<PRIu32>\n"
+msgstr "  %-13s  %4<PRIu32>\n"
+
+#. Unknown subsection, print and skip.
+#: src/readelf.c:3539
+#, c-format
+msgid "    %-4u %12<PRIu32>\n"
+msgstr "    %-4u %12<PRIu32>\n"
+
+#. Tag_File
+#: src/readelf.c:3544
+#, c-format
+msgid "    File: %11<PRIu32>\n"
+msgstr "    Plik: %11<PRIu32>\n"
+
+#: src/readelf.c:3593
+#, c-format
+msgid "      %s: %<PRId64>, %s\n"
+msgstr "      %s: %<PRId64>, %s\n"
+
+#: src/readelf.c:3596
+#, c-format
+msgid "      %s: %<PRId64>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:3599
+#, c-format
+msgid "      %s: %s\n"
+msgstr "      %s: %s\n"
+
+#: src/readelf.c:3609
+#, c-format
+msgid "      %u: %<PRId64>\n"
+msgstr "      %u: %<PRId64>\n"
+
+#: src/readelf.c:3612
+#, c-format
+msgid "      %u: %s\n"
+msgstr "      %u: %s\n"
+
+#: src/readelf.c:3657
+#, c-format
+msgid "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3660
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3665
+#, c-format
+msgid "%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%#<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3668
+#, c-format
+msgid "%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%#0*<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3674
+#, c-format
+msgid "%s+%#<PRIx64> <%s>"
+msgstr "%s+%#<PRIx64> <%s>"
+
+#: src/readelf.c:3677
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s>"
+msgstr "%s+%#0*<PRIx64> <%s>"
+
+#: src/readelf.c:3681
+#, c-format
+msgid "%#<PRIx64> <%s>"
+msgstr "%#<PRIx64> <%s>"
+
+#: src/readelf.c:3684
+#, c-format
+msgid "%#0*<PRIx64> <%s>"
+msgstr "%#0*<PRIx64> <%s>"
+
+#: src/readelf.c:3689
+#, c-format
+msgid "%s+%#<PRIx64>"
+msgstr "%s+%#<PRIx64>"
+
+#: src/readelf.c:3692
+#, c-format
+msgid "%s+%#0*<PRIx64>"
+msgstr "%s+%#0*<PRIx64>"
+
+#: src/readelf.c:4095
+msgid "empty block"
+msgstr "pusty blok"
+
+#: src/readelf.c:4098
+#, c-format
+msgid "%zu byte block:"
+msgstr "%zu bajtowy blok:"
+
+#: src/readelf.c:4495
+#, c-format
+msgid "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+msgstr "%*s[%4<PRIuMAX>] %s  <SKRÓCONE>\n"
+
+#: src/readelf.c:4552
+#, c-format
+msgid "%s %#<PRIx64> used with different address sizes"
+msgstr "%s %#<PRIx64> zostało użyte z różnymi rozmiarami adresu"
+
+#: src/readelf.c:4559
+#, c-format
+msgid "%s %#<PRIx64> used with different offset sizes"
+msgstr "%s %#<PRIx64> zostało użyte z różnymi rozmiarami offsetu"
+
+#: src/readelf.c:4566
+#, c-format
+msgid "%s %#<PRIx64> used with different base addresses"
+msgstr "%s %#<PRIx64> zostało użyte z różnymi adresami podstawowymi"
+
+#: src/readelf.c:4655
+#, c-format
+msgid " [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"
+msgstr " [%6tx]  <NIEUŻYWANE ŚMIECIE W RESZCIE SEKCJI>\n"
+
+#: src/readelf.c:4663
+#, c-format
+msgid " [%6tx]  <UNUSED GARBAGE> ... %<PRIu64> bytes ...\n"
+msgstr " [%6tx]  <NIEUŻYWANE ŚMIECIE>… %<PRIu64> bajtów…\n"
+
+#: src/readelf.c:4689
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [ Code]\n"
+msgstr ""
+"\n"
+"Sekcja DWARF [%2zu] „%s” pod offsetem %#<PRIx64>:\n"
+" [ Kod]\n"
+
+#: src/readelf.c:4697
+#, c-format
+msgid ""
+"\n"
+"Abbreviation section at offset %<PRIu64>:\n"
+msgstr ""
+"\n"
+"Sekcja skrótów pod offsetem %<PRIu64>:\n"
+
+#: src/readelf.c:4710
+#, c-format
+msgid " *** error while reading abbreviation: %s\n"
+msgstr " *** błąd podczas odczytywania skrótu: %s\n"
+
+#: src/readelf.c:4726
+#, c-format
+msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
+msgstr " [%5u] offset: %<PRId64>, potomek: %s, znacznik: %s\n"
+
+#: src/readelf.c:4729 src/readelf.c:6178 src/readelf.c:6186 src/readelf.c:7759
+msgid "yes"
+msgstr "tak"
+
+#: src/readelf.c:4729 src/readelf.c:6178 src/readelf.c:7759
+msgid "no"
+msgstr "nie"
+
+#: src/readelf.c:4763 src/readelf.c:4836
+#, c-format
+msgid "cannot get .debug_aranges content: %s"
+msgstr "nie można uzyskać zawartości .debug_aranges: %s"
+
+#: src/readelf.c:4778
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"Sekcja DWARF [%2zu] „%s” pod offsetem %#<PRIx64> zawiera %zu wpis:\n"
+msgstr[1] ""
+"\n"
+"Sekcja DWARF [%2zu] „%s” pod offsetem %#<PRIx64> zawiera %zu wpisy:\n"
+msgstr[2] ""
+"\n"
+"Sekcja DWARF [%2zu] „%s” pod offsetem %#<PRIx64> zawiera %zu wpisów:\n"
+
+#: src/readelf.c:4809
+#, c-format
+msgid " [%*zu] ???\n"
+msgstr " [%*zu] ???\n"
+
+#: src/readelf.c:4811
+#, c-format
+msgid ""
+" [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
+msgstr ""
+" [%*zu] początek: %0#*<PRIx64>, długość: %5<PRIu64>, offset CU DIE: "
+"%6<PRId64>\n"
+
+#: src/readelf.c:4841 src/readelf.c:4995 src/readelf.c:5572 src/readelf.c:6529
+#: src/readelf.c:7061 src/readelf.c:7181 src/readelf.c:7345 src/readelf.c:7833
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+"\n"
+"Sekcja DWARF [%2zu] „%s” pod offsetem %#<PRIx64>:\n"
+
+#: src/readelf.c:4854 src/readelf.c:6555
+#, c-format
+msgid ""
+"\n"
+"Table at offset %zu:\n"
+msgstr ""
+"\n"
+"Tabela pod offsetem %zu:\n"
+
+#: src/readelf.c:4858 src/readelf.c:5596 src/readelf.c:6566
+#, c-format
+msgid "invalid data in section [%zu] '%s'"
+msgstr "nieprawidłowe dane w sekcji [%zu] „%s”"
+
+#: src/readelf.c:4874
+#, c-format
+msgid ""
+"\n"
+" Length:        %6<PRIu64>\n"
+msgstr ""
+"\n"
+" Długość:        %6<PRIu64>\n"
+
+#: src/readelf.c:4886
+#, c-format
+msgid " DWARF version: %6<PRIuFAST16>\n"
+msgstr " Wersja DWARF: %6<PRIuFAST16>\n"
+
+#: src/readelf.c:4890
+#, c-format
+msgid "unsupported aranges version"
+msgstr "nieobsługiwana wersja aranges"
+
+#: src/readelf.c:4901
+#, c-format
+msgid " CU offset:     %6<PRIx64>\n"
+msgstr " Offset CU:     %6<PRIx64>\n"
+
+#: src/readelf.c:4907
+#, c-format
+msgid " Address size:  %6<PRIu64>\n"
+msgstr " Offset adresu:  %6<PRIu64>\n"
+
+#: src/readelf.c:4911
+#, c-format
+msgid "unsupported address size"
+msgstr "nieobsługiwany rozmiar adresu"
+
+#: src/readelf.c:4916
+#, c-format
+msgid ""
+" Segment size:  %6<PRIu64>\n"
+"\n"
+msgstr ""
+" Rozmiar segmentu:  %6<PRIu64>\n"
+"\n"
+
+#: src/readelf.c:4920
+#, c-format
+msgid "unsupported segment size"
+msgstr "nieobsługiwany rozmiar segmentu"
+
+#: src/readelf.c:4960
+#, c-format
+msgid "   %s..%s (%<PRIx64>)\n"
+msgstr "   %s..%s (%<PRIx64>)\n"
+
+#: src/readelf.c:4963
+#, c-format
+msgid "   %s..%s\n"
+msgstr "   %s..%s\n"
+
+#: src/readelf.c:4972
+#, c-format
+msgid "   %zu padding bytes\n"
+msgstr "   bajty wypełnienia: %zu\n"
+
+#: src/readelf.c:4990
+#, c-format
+msgid "cannot get .debug_ranges content: %s"
+msgstr "nie można uzyskać zawartości .debug_ranges: %s"
+
+#: src/readelf.c:5020 src/readelf.c:7088
+#, c-format
+msgid " [%6tx]  <INVALID DATA>\n"
+msgstr " [%6tx]  <NIEPRAWIDŁOWE DANE>\n"
+
+#: src/readelf.c:5042 src/readelf.c:7110
+#, c-format
+msgid " [%6tx]  base address %s\n"
+msgstr " [%6tx]  adres podstawowy %s\n"
+
+#: src/readelf.c:5049 src/readelf.c:7117
+#, c-format
+msgid " [%6tx]  empty list\n"
+msgstr " [%6tx]  pusta lista\n"
+
+#. We have an address range entry.
+#. First address range entry in a list.
+#: src/readelf.c:5060
+#, c-format
+msgid " [%6tx]  %s..%s\n"
+msgstr " [%6tx]  %s…%s\n"
+
+#: src/readelf.c:5062
+#, c-format
+msgid "           %s..%s\n"
+msgstr "           %s…%s\n"
+
+#: src/readelf.c:5298
+msgid "         <INVALID DATA>\n"
+msgstr "         <NIEPRAWIDŁOWE DANE>\n"
+
+#: src/readelf.c:5551
+#, c-format
+msgid "cannot get ELF: %s"
+msgstr "nie można uzyskać ELF: %s"
+
+#: src/readelf.c:5568
+#, c-format
+msgid ""
+"\n"
+"Call frame information section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+"\n"
+"Sekcja informacji o ramce wywołania [%2zu] „%s” pod offsetem %#<PRIx64>:\n"
+
+#: src/readelf.c:5618
+#, c-format
+msgid ""
+"\n"
+" [%6tx] Zero terminator\n"
+msgstr ""
+"\n"
+" [%6tx] Zerowy koniec\n"
+
+#: src/readelf.c:5711 src/readelf.c:5866
+#, c-format
+msgid "invalid augmentation length"
+msgstr "nieprawidłowa długość powiększenia"
+
+#: src/readelf.c:5726
+msgid "FDE address encoding: "
+msgstr "Kodowanie adresu FDE: "
+
+#: src/readelf.c:5732
+msgid "LSDA pointer encoding: "
+msgstr "Kodowanie wskaźnika LSDA: "
+
+#: src/readelf.c:5843
+#, c-format
+msgid " (offset: %#<PRIx64>)"
+msgstr " (offset: %#<PRIx64>)"
+
+#: src/readelf.c:5850
+#, c-format
+msgid " (end offset: %#<PRIx64>)"
+msgstr " (kończący offset: %#<PRIx64>)"
+
+#: src/readelf.c:5887
+#, c-format
+msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
+msgstr "   %-26sWskaźnik LSDA: %#<PRIx64>\n"
+
+#: src/readelf.c:5942
+#, c-format
+msgid "cannot get attribute code: %s"
+msgstr "nie można uzyskać kodu atrybutu: %s"
+
+#: src/readelf.c:5951
+#, c-format
+msgid "cannot get attribute form: %s"
+msgstr "nie można uzyskać formy atrybutu: %s"
+
+#: src/readelf.c:5966
+#, c-format
+msgid "cannot get attribute value: %s"
+msgstr "nie można uzyskać wartości atrybutu: %s"
+
+#: src/readelf.c:6268
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [Offset]\n"
+msgstr ""
+"\n"
+"Sekcja DWARF [%2zu] „%s” pod offsetem %#<PRIx64>:\n"
+" [Offset]\n"
+
+#: src/readelf.c:6300
+#, c-format
+msgid ""
+" Type unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: "
+"%<PRIu8>, Offset size: %<PRIu8>\n"
+" Type signature: %#<PRIx64>, Type offset: %#<PRIx64>\n"
+msgstr ""
+" Jednostka typu pod offsetem %<PRIu64>:\n"
+" Wersja: %<PRIu16>, offset sekcji skrótów: %<PRIu64>, rozmiar adresu: "
+"%<PRIu8>, rozmiar offsetu: %<PRIu8>\n"
+" Podpis typu: %#<PRIx64>, offset typu: %#<PRIx64>\n"
+
+#: src/readelf.c:6309
+#, c-format
+msgid ""
+" Compilation unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: "
+"%<PRIu8>, Offset size: %<PRIu8>\n"
+msgstr ""
+" Jednostka kompilacji pod offsetem %<PRIu64>:\n"
+" Wersja: %<PRIu16>, offset sekcji skrótów: %<PRIu64>, rozmiar adresu: "
+"%<PRIu8>, rozmiar offsetu: %<PRIu8>\n"
+
+#: src/readelf.c:6334
+#, c-format
+msgid "cannot get DIE at offset %<PRIu64> in section '%s': %s"
+msgstr "nie można uzyskać DIE pod offsetem %<PRIu64> w sekcji „%s”: %s"
+
+#: src/readelf.c:6348
+#, c-format
+msgid "cannot get DIE offset: %s"
+msgstr "nie można uzyskać offsetu DIE: %s"
+
+#: src/readelf.c:6357
+#, c-format
+msgid "cannot get tag of DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+"nie można uzyskać znacznika DIE pod offsetem %<PRIu64> w sekcji „%s”: %s"
+
+#: src/readelf.c:6389
+#, c-format
+msgid "cannot get next DIE: %s\n"
+msgstr "nie można uzyskać następnego DIE: %s\n"
+
+#: src/readelf.c:6397
+#, c-format
+msgid "cannot get next DIE: %s"
+msgstr "nie można uzyskać następnego DIE: %s"
+
+#: src/readelf.c:6433
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+"\n"
+"Sekcja DWARF [%2zu] „%s” pod offsetem %#<PRIx64>:\n"
+"\n"
+
+#: src/readelf.c:6542
+#, c-format
+msgid "cannot get line data section data: %s"
+msgstr "nie można uzyskać danych sekcji danych wiersza: %s"
+
+#. Print what we got so far.
+#: src/readelf.c:6612
+#, c-format
+msgid ""
+"\n"
+" Length:                     %<PRIu64>\n"
+" DWARF version:              %<PRIuFAST16>\n"
+" Prologue length:            %<PRIu64>\n"
+" Minimum instruction length: %<PRIuFAST8>\n"
+" Maximum operations per instruction: %<PRIuFAST8>\n"
+" Initial value if '%s': %<PRIuFAST8>\n"
+" Line base:                  %<PRIdFAST8>\n"
+" Line range:                 %<PRIuFAST8>\n"
+" Opcode base:                %<PRIuFAST8>\n"
+"\n"
+"Opcodes:\n"
+msgstr ""
+"\n"
+" Długość:                      %<PRIu64>\n"
+" Wersja DWARF:                 %<PRIuFAST16>\n"
+" Długość prologu:              %<PRIu64>\n"
+" Minimalna długość instrukcji: %<PRIuFAST8>\n"
+" Maksymalna liczba działań na instrukcję: %<PRIuFAST8>\n"
+" Początkowa wartość „%s”:      %<PRIuFAST8>\n"
+" Początek wiersza:             %<PRIdFAST8>\n"
+" Przedział wiersza:            %<PRIuFAST8>\n"
+" Początek instrukcji:          %<PRIuFAST8>\n"
+"\n"
+"Instrukcje:\n"
+
+#: src/readelf.c:6633
+#, c-format
+msgid "invalid data at offset %tu in section [%zu] '%s'"
+msgstr "nieprawidłowe dane pod offsetem %tu w sekcji [%zu] „%s”"
+
+#: src/readelf.c:6648
+#, c-format
+msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
+msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
+msgstr[0] "  [%*<PRIuFAST8>]  %hhu parametr\n"
+msgstr[1] "  [%*<PRIuFAST8>]  %hhu parametry\n"
+msgstr[2] "  [%*<PRIuFAST8>]  %hhu parametrów\n"
+
+#: src/readelf.c:6656
+msgid ""
+"\n"
+"Directory table:"
+msgstr ""
+"\n"
+"Tabela katalogu:"
+
+#: src/readelf.c:6672
+msgid ""
+"\n"
+"File name table:\n"
+" Entry Dir   Time      Size      Name"
+msgstr ""
+"\n"
+"Tabela nazw plików:\n"
+" Wpis Kat    Czas      Rozmiar   Nazwa"
+
+#: src/readelf.c:6707
+msgid ""
+"\n"
+"Line number statements:"
+msgstr ""
+"\n"
+"Instrukcje numerów wierszy:"
+
+#: src/readelf.c:6758
+#, c-format
+msgid "invalid maximum operations per instruction is zero"
+msgstr "nieprawidłowe maksimum operacji na instrukcję wynosi zero"
+
+#: src/readelf.c:6794
+#, c-format
+msgid " special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"
+msgstr ""
+" instrukcja specjalna %u: adres+%u = %s, op_index = %u, wiersz%+d = %zu\n"
+
+#: src/readelf.c:6799
+#, c-format
+msgid " special opcode %u: address+%u = %s, line%+d = %zu\n"
+msgstr " instrukcja specjalna %u: adres+%u = %s, wiersz%+d = %zu\n"
+
+#: src/readelf.c:6819
+#, c-format
+msgid " extended opcode %u: "
+msgstr " instrukcja rozszerzona %u: "
+
+#: src/readelf.c:6824
+msgid " end of sequence"
+msgstr " koniec sekwencji"
+
+#: src/readelf.c:6843
+#, c-format
+msgid " set address to %s\n"
+msgstr " ustawienie adresu na %s\n"
+
+#: src/readelf.c:6870
+#, c-format
+msgid " define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
+msgstr ""
+" definicja nowego pliku: dir=%u, mtime=%<PRIu64>, długość=%<PRIu64>, nazwa="
+"%s\n"
+
+#: src/readelf.c:6883
+#, c-format
+msgid " set discriminator to %u\n"
+msgstr " ustawienie dyskryminatora na %u\n"
+
+#. Unknown, ignore it.
+#: src/readelf.c:6888
+msgid " unknown opcode"
+msgstr " nieznana instrukcja"
+
+#. Takes no argument.
+#: src/readelf.c:6900
+msgid " copy"
+msgstr " kopiowanie"
+
+#: src/readelf.c:6911
+#, c-format
+msgid " advance address by %u to %s, op_index to %u\n"
+msgstr " zwiększenie adresu o %u do %s, op_index do %u\n"
+
+#: src/readelf.c:6915
+#, c-format
+msgid " advance address by %u to %s\n"
+msgstr " zwiększenie adresu o %u do %s\n"
+
+#: src/readelf.c:6926
+#, c-format
+msgid " advance line by constant %d to %<PRId64>\n"
+msgstr " zwiększenie wiersza o stałą %d do %<PRId64>\n"
+
+#: src/readelf.c:6934
+#, c-format
+msgid " set file to %<PRIu64>\n"
+msgstr " ustawienie pliku na %<PRIu64>\n"
+
+#: src/readelf.c:6944
+#, c-format
+msgid " set column to %<PRIu64>\n"
+msgstr " ustawienie kolumny na %<PRIu64>\n"
+
+#: src/readelf.c:6951
+#, c-format
+msgid " set '%s' to %<PRIuFAST8>\n"
+msgstr " ustawienie „%s” na %<PRIuFAST8>\n"
+
+#. Takes no argument.
+#: src/readelf.c:6957
+msgid " set basic block flag"
+msgstr " ustawienie podstawowej flagi bloku"
+
+#: src/readelf.c:6970
+#, c-format
+msgid " advance address by constant %u to %s, op_index to %u\n"
+msgstr " zwiększenie adresu o stałą %u do %s, op_index do %u\n"
+
+#: src/readelf.c:6974
+#, c-format
+msgid " advance address by constant %u to %s\n"
+msgstr " zwiększenie adresu o stałą %u do %s\n"
+
+#: src/readelf.c:6992
+#, c-format
+msgid " advance address by fixed value %u to %s\n"
+msgstr " zwiększenie adresu o stałą wartość %u do %s\n"
+
+#. Takes no argument.
+#: src/readelf.c:7001
+msgid " set prologue end flag"
+msgstr " ustawienie flagi końca prologu"
+
+#. Takes no argument.
+#: src/readelf.c:7006
+msgid " set epilogue begin flag"
+msgstr " ustawienie flagi początku epilogu"
+
+#: src/readelf.c:7015
+#, c-format
+msgid " set isa to %u\n"
+msgstr " ustawienie isa na %u\n"
+
+#. This is a new opcode the generator but not we know about.
+#. Read the parameters associated with it but then discard
+#. everything.  Read all the parameters for this opcode.
+#: src/readelf.c:7024
+#, c-format
+msgid " unknown opcode with %<PRIu8> parameter:"
+msgid_plural " unknown opcode with %<PRIu8> parameters:"
+msgstr[0] " nieznana instrukcja z %<PRIu8> parametrem:"
+msgstr[1] " nieznana instrukcja z %<PRIu8> parametrami:"
+msgstr[2] " nieznana instrukcja z %<PRIu8> parametrami:"
+
+#: src/readelf.c:7056
+#, c-format
+msgid "cannot get .debug_loc content: %s"
+msgstr "nie można uzyskać zawartości .debug_log: %s"
+
+#. First entry in a list.
+#: src/readelf.c:7131
+#, c-format
+msgid " [%6tx]  %s..%s"
+msgstr " [%6tx]  %s…%s"
+
+#: src/readelf.c:7133
+#, c-format
+msgid "           %s..%s"
+msgstr "           %s…%s"
+
+#: src/readelf.c:7140 src/readelf.c:8091
+msgid "   <INVALID DATA>\n"
+msgstr "   <NIEPRAWIDŁOWE DANE>\n"
+
+#: src/readelf.c:7192 src/readelf.c:7354
+#, c-format
+msgid "cannot get macro information section data: %s"
+msgstr "nie można uzyskać danych sekcji informacji o makrach: %s"
+
+#: src/readelf.c:7272
+#, c-format
+msgid "%*s*** non-terminated string at end of section"
+msgstr "%*s*** niezakończony ciąg na końcu sekcji"
+
+#: src/readelf.c:7295
+#, c-format
+msgid "%*s*** missing DW_MACINFO_start_file argument at end of section"
+msgstr "%*s*** brak parametru DW_MACINFO_start_file na końcu sekcji"
+
+#: src/readelf.c:7395
+#, c-format
+msgid " Offset:             0x%<PRIx64>\n"
+msgstr " Offset:             0x%<PRIx64>\n"
+
+#: src/readelf.c:7407
+#, c-format
+msgid " Version:            %<PRIu16>\n"
+msgstr " Wersja:             %<PRIu16>\n"
+
+#: src/readelf.c:7413 src/readelf.c:8210
+#, c-format
+msgid "  unknown version, cannot parse section\n"
+msgstr "  nieznana wersja, nie można przetworzyć sekcji\n"
+
+#: src/readelf.c:7420
+#, c-format
+msgid " Flag:               0x%<PRIx8>\n"
+msgstr " Flaga:              0x%<PRIx8>\n"
+
+#: src/readelf.c:7423
+#, c-format
+msgid " Offset length:      %<PRIu8>\n"
+msgstr " Długość offsetu:    %<PRIu8>\n"
+
+#: src/readelf.c:7431
+#, c-format
+msgid " .debug_line offset: 0x%<PRIx64>\n"
+msgstr " Offset .debug_line: 0x%<PRIx64>\n"
+
+#: src/readelf.c:7444
+#, c-format
+msgid "  extension opcode table, %<PRIu8> items:\n"
+msgstr "  tabela instrukcji rozszerzenia, %<PRIu8> elementów:\n"
+
+#: src/readelf.c:7451
+#, c-format
+msgid "    [%<PRIx8>]"
+msgstr "    [%<PRIx8>]"
+
+#: src/readelf.c:7463
+#, c-format
+msgid " %<PRIu8> arguments:"
+msgstr " Parametry %<PRIu8>:"
+
+#: src/readelf.c:7491
+#, c-format
+msgid " no arguments."
+msgstr " brak parametrów."
+
+#: src/readelf.c:7791
+#, c-format
+msgid "vendor opcode not verified?"
+msgstr "instrukcja producenta nie została sprawdzona?"
+
+#: src/readelf.c:7819
+#, c-format
+msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
+msgstr " [%5d] offset DIE: %6<PRId64>, offset CU DIE: %6<PRId64>, nazwa: %s\n"
+
+#: src/readelf.c:7860
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" %*s  String\n"
+msgstr ""
+"\n"
+"Sekcja DWARF [%2zu] „%s” pod offsetem %#<PRIx64>:\n"
+" %*s  Ciąg\n"
+
+#: src/readelf.c:7874
+#, c-format
+msgid " *** error while reading strings: %s\n"
+msgstr " *** błąd podczas odczytywania ciągów: %s\n"
+
+#: src/readelf.c:7894
+#, c-format
+msgid ""
+"\n"
+"Call frame search table section [%2zu] '.eh_frame_hdr':\n"
+msgstr ""
+"\n"
+"Sekcja tabeli wyszukiwania ramki wywołania [%2zu] „.eh_frame_hdr”:\n"
+
+#: src/readelf.c:7996
+#, c-format
+msgid ""
+"\n"
+"Exception handling table section [%2zu] '.gcc_except_table':\n"
+msgstr ""
+"\n"
+"Sekcja tabeli obsługiwania wyjątków [%2zu] „.gcc_except_table”:\n"
+
+#: src/readelf.c:8019
+#, c-format
+msgid " LPStart encoding:    %#x "
+msgstr " Kodowanie LPStart:    %#x "
+
+#: src/readelf.c:8031
+#, c-format
+msgid " TType encoding:      %#x "
+msgstr " Kodowanie TType:      %#x "
+
+#: src/readelf.c:8046
+#, c-format
+msgid " Call site encoding:  %#x "
+msgstr " Kodowanie strony wywołania:  %#x "
+
+#: src/readelf.c:8059
+msgid ""
+"\n"
+" Call site table:"
+msgstr ""
+"\n"
+" Tabela strony wywołania:"
+
+#: src/readelf.c:8073
+#, c-format
+msgid ""
+" [%4u] Call site start:   %#<PRIx64>\n"
+"        Call site length:  %<PRIu64>\n"
+"        Landing pad:       %#<PRIx64>\n"
+"        Action:            %u\n"
+msgstr ""
+" [%4u] Początek strony wywołania: %#<PRIx64>\n"
+"        Długość strony wywołania:  %<PRIu64>\n"
+"        Lądowisko:                 %#<PRIx64>\n"
+"        Działanie:                 %u\n"
+
+#: src/readelf.c:8146
+#, c-format
+msgid "invalid TType encoding"
+msgstr "nieprawidłowe kodowanie TType"
+
+#: src/readelf.c:8172
+#, c-format
+msgid ""
+"\n"
+"GDB section [%2zu] '%s' at offset %#<PRIx64> contains %<PRId64> bytes :\n"
+msgstr ""
+"\n"
+"Sekcja GDB [%2zu] „%s” pod offsetem %#<PRIx64> zawiera %<PRId64> bajtów:\n"
+
+#: src/readelf.c:8201
+#, c-format
+msgid " Version:         %<PRId32>\n"
+msgstr " Wersja:         %<PRId32>\n"
+
+#: src/readelf.c:8219
+#, c-format
+msgid " CU offset:       %#<PRIx32>\n"
+msgstr " offset CU:       %#<PRIx32>\n"
+
+#: src/readelf.c:8226
+#, c-format
+msgid " TU offset:       %#<PRIx32>\n"
+msgstr " offset TU:       %#<PRIx32>\n"
+
+#: src/readelf.c:8233
+#, c-format
+msgid " address offset:  %#<PRIx32>\n"
+msgstr " offset adresu:  %#<PRIx32>\n"
+
+#: src/readelf.c:8240
+#, c-format
+msgid " symbol offset:   %#<PRIx32>\n"
+msgstr " offset symbolu:   %#<PRIx32>\n"
+
+#: src/readelf.c:8247
+#, c-format
+msgid " constant offset: %#<PRIx32>\n"
+msgstr " offset stałej: %#<PRIx32>\n"
+
+#: src/readelf.c:8261
+#, c-format
+msgid ""
+"\n"
+" CU list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+" Lista CU pod offsetem %#<PRIx32> zawiera %zu wpisów:\n"
+
+#: src/readelf.c:8286
+#, c-format
+msgid ""
+"\n"
+" TU list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+" Lista TU pod offsetem %#<PRIx32> zawiera %zu wpisów:\n"
+
+#: src/readelf.c:8315
+#, c-format
+msgid ""
+"\n"
+" Address list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+" Lista adresów pod offsetem %#<PRIx32> zawiera %zu wpisów:\n"
+
+#: src/readelf.c:8348
+#, c-format
+msgid ""
+"\n"
+" Symbol table at offset %#<PRIx32> contains %zu slots:\n"
+msgstr ""
+"\n"
+" Tabela symboli pod offsetem %#<PRIx32> zawiera %zu gniazd:\n"
+
+#: src/readelf.c:8435
+#, c-format
+msgid "cannot get debug context descriptor: %s"
+msgstr "nie można uzyskać deskryptora kontekstu debugowania: %s"
+
+#: src/readelf.c:8591 src/readelf.c:9213 src/readelf.c:9324 src/readelf.c:9382
+#, c-format
+msgid "cannot convert core note data: %s"
+msgstr "nie można konwertować danych notatki core: %s"
+
+#: src/readelf.c:8954
+#, c-format
+msgid ""
+"\n"
+"%*s... <repeats %u more times> ..."
+msgstr ""
+"\n"
+"%*s… <powtarza się jeszcze %u razy>…"
+
+#: src/readelf.c:9461
+msgid "  Owner          Data size  Type\n"
+msgstr "  Właściciel     Rozmiar danych  Typ\n"
+
+#: src/readelf.c:9479
+#, c-format
+msgid "  %-13.*s  %9<PRId32>  %s\n"
+msgstr "  %-13.*s  %9<PRId32>  %s\n"
+
+#: src/readelf.c:9529
+#, c-format
+msgid "cannot get content of note section: %s"
+msgstr "nie można uzyskać zawartości sekcji notatki: %s"
+
+#: src/readelf.c:9556
+#, c-format
+msgid ""
+"\n"
+"Note section [%2zu] '%s' of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Segment notatki [%2zu] „%s” o długości %<PRIu64> bajtów pod offsetem "
+"%#0<PRIx64>:\n"
+
+#: src/readelf.c:9579
+#, c-format
+msgid ""
+"\n"
+"Note segment of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Segment notatki o długości %<PRIu64> bajtów pod offsetem %#0<PRIx64>:\n"
+
+#: src/readelf.c:9625
+#, c-format
+msgid ""
+"\n"
+"Section [%zu] '%s' has no data to dump.\n"
+msgstr ""
+"\n"
+"Sekcja [%zu] „%s” nie ma danych do zrzucenia.\n"
+
+#: src/readelf.c:9652 src/readelf.c:9703
+#, c-format
+msgid "cannot get data for section [%zu] '%s': %s"
+msgstr "nie można uzyskać danych dla sekcji [%zu] „%s”: %s"
+
+#: src/readelf.c:9657
+#, c-format
+msgid ""
+"\n"
+"Hex dump of section [%zu] '%s', %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Segment zrzutu szesnastkowego [%zu] „%s”, %<PRIu64> bajtów pod offsetem "
+"%#0<PRIx64>:\n"
+
+#: src/readelf.c:9662
+#, c-format
+msgid ""
+"\n"
+"Hex dump of section [%zu] '%s', %<PRIu64> bytes (%zd uncompressed) at offset "
+"%#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Zrzut szesnastkowy sekcji [%zu] „%s”, %<PRIu64> bajtów (%zd "
+"nieskompresowanych) pod offsetem %#0<PRIx64>:\n"
+
+#: src/readelf.c:9676
+#, c-format
+msgid ""
+"\n"
+"Section [%zu] '%s' has no strings to dump.\n"
+msgstr ""
+"\n"
+"Sekcja [%zu] „%s” nie ma ciągów do zrzucenia.\n"
+
+#: src/readelf.c:9708
+#, c-format
+msgid ""
+"\n"
+"String section [%zu] '%s' contains %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Sekcja ciągów [%zu] „%s” zawiera %<PRIu64> bajtów pod offsetem %#0<PRIx64>:\n"
+
+#: src/readelf.c:9713
+#, c-format
+msgid ""
+"\n"
+"String section [%zu] '%s' contains %<PRIu64> bytes (%zd uncompressed) at "
+"offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Sekcja ciągów [%zu] „%s” zawiera %<PRIu64> bajtów (%zd nieskompresowanych) "
+"pod offsetem %#0<PRIx64>:\n"
+
+#: src/readelf.c:9762
+#, c-format
+msgid ""
+"\n"
+"section [%lu] does not exist"
+msgstr ""
+"\n"
+"sekcja [%lu] nie istnieje"
+
+#: src/readelf.c:9791
+#, c-format
+msgid ""
+"\n"
+"section '%s' does not exist"
+msgstr ""
+"\n"
+"sekcja „%s” nie istnieje"
+
+#: src/readelf.c:9848
+#, c-format
+msgid "cannot get symbol index of archive '%s': %s"
+msgstr "nie można uzyskać indeksu symboli archiwum „%s”: %s"
+
+#: src/readelf.c:9851
+#, c-format
+msgid ""
+"\n"
+"Archive '%s' has no symbol index\n"
+msgstr ""
+"\n"
+"Archiwum „%s” nie ma indeksu symboli\n"
+
+#: src/readelf.c:9855
+#, c-format
+msgid ""
+"\n"
+"Index of archive '%s' has %zu entries:\n"
+msgstr ""
+"\n"
+"Indeks archiwum „%s” ma %zu wpisów:\n"
+
+#: src/readelf.c:9873
+#, c-format
+msgid "cannot extract member at offset %zu in '%s': %s"
+msgstr "nie można wydobyć elementów pod offsetem %zu w „%s”: %s"
+
+#: src/readelf.c:9878
+#, c-format
+msgid "Archive member '%s' contains:\n"
+msgstr "Element archiwum „%s” zawiera:\n"
+
+#: src/size.c:57
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd' or `sysv'.  The default "
+"is `bsd'"
+msgstr ""
+"Używa FORMATU wyjścia. Może to być „bsd” lub „sysv”. Domyślny jest „bsd”"
+
+#: src/size.c:59
+msgid "Same as `--format=sysv'"
+msgstr "To samo, co „--format=sysv”"
+
+#: src/size.c:60
+msgid "Same as `--format=bsd'"
+msgstr "To samo, co „--format=bsd”"
+
+#: src/size.c:63
+msgid "Same as `--radix=10'"
+msgstr "To samo, co „--radix=10”"
+
+#: src/size.c:64
+msgid "Same as `--radix=8'"
+msgstr "To samo, co „--radix=8”"
+
+#: src/size.c:65
+msgid "Same as `--radix=16'"
+msgstr "To samo, co „--radix=16”"
+
+#: src/size.c:67
+msgid "Similar to `--format=sysv' output but in one line"
+msgstr "Podobne do wyjścia „--format=sysv”, ale w jednym wierszu"
+
+#: src/size.c:71
+msgid "Print size and permission flags for loadable segments"
+msgstr "Wyświetla rozmiar i flagi uprawnień dla segmentów wczytywalnych"
+
+#: src/size.c:72
+msgid "Display the total sizes (bsd only)"
+msgstr "Wyświetla całkowite rozmiary (tylko bsd)"
+
+#. Short description of program.
+#: src/size.c:77
+msgid "List section sizes of FILEs (a.out by default)."
+msgstr "Wyświetla listę rozmiarów sekcji PLIKU (domyślnie a.out)."
+
+#: src/size.c:241
+#, c-format
+msgid "Invalid format: %s"
+msgstr "Nieprawidłowy format: %s"
+
+#: src/size.c:252
+#, c-format
+msgid "Invalid radix: %s"
+msgstr "Nieprawidłowa baza: %s"
+
+#: src/size.c:311
+#, c-format
+msgid "%s: file format not recognized"
+msgstr "%s: nie rozpoznano formatu pliku"
+
+#: src/size.c:417 src/size.c:550
+#, c-format
+msgid " (ex %s)"
+msgstr " (ex %s)"
+
+#: src/size.c:575
+msgid "(TOTALS)\n"
+msgstr "(CAŁKOWITE)\n"
+
+#: src/stack.c:483
+#, c-format
+msgid "-p PID should be a positive process id."
+msgstr "-p PID powinien być dodatnim identyfikatorem procesu."
+
+#: src/stack.c:489
+#, c-format
+msgid "Cannot open core file '%s'"
+msgstr "Nie można otworzyć pliku core „%s”"
+
+#: src/stack.c:549
+#, c-format
+msgid "-n MAXFRAMES should be 0 or higher."
+msgstr "-n MAKSYMALNA_LICZBA_RAMEK powinna wynosić 0 lub więcej."
+
+#: src/stack.c:561
+#, c-format
+msgid "-e EXEC needs a core given by --core."
+msgstr "-e PLIK_WYKONYWALNY wymaga pliku core podanego za pomocą opcji --core."
+
+#: src/stack.c:565
+#, c-format
+msgid "-1 needs a thread id given by -p."
+msgstr "-1 wymaga identyfikatora wątku podanego za pomocą opcji -p."
+
+#: src/stack.c:569
+#, c-format
+msgid "One of -p PID or --core COREFILE should be given."
+msgstr "Tylko jedna z opcji -p PID lub --core PLIK_CORE powinna zostać podana."
+
+#: src/stack.c:641
+msgid "Show stack of process PID"
+msgstr "Wyświetla stos numeru PID procesu"
+
+#: src/stack.c:643
+msgid "Show stack found in COREFILE"
+msgstr "Wyświetla stos odnaleziony w PLIKU_CORE"
+
+#: src/stack.c:644
+msgid "(optional) EXECUTABLE that produced COREFILE"
+msgstr "(opcjonalnie) PLIK_WYKONYWALNY, który utworzył PLIK_CORE"
+
+#: src/stack.c:648
+msgid "Output selection options:"
+msgstr "Opcje wyboru wyjścia:"
+
+#: src/stack.c:650
+msgid "Additionally show frame activation"
+msgstr "Dodatkowo wyświetla aktywację ramki"
+
+#: src/stack.c:652
+msgid "Additionally try to lookup DWARF debuginfo name for frame address"
+msgstr "Dodatkowo próbuje wyszukać nazwy debuginfo DWARF dla adresu ramki"
+
+#: src/stack.c:655
+msgid ""
+"Additionally show inlined function frames using DWARF debuginfo if available "
+"(implies -d)"
+msgstr ""
+"Dodatkowo wyświetla wstawione ramki używając debuginfo DWARF, jeśli jest "
+"dostępne (zakłada opcję -d)"
+
+#: src/stack.c:657
+msgid "Additionally show module file information"
+msgstr "Dodatkowo wyświetla informacje o pliku modułu"
+
+#: src/stack.c:659
+msgid "Additionally show source file information"
+msgstr "Dodatkowo wyświetla informacje o pliku źródłowym"
+
+#: src/stack.c:661
+msgid ""
+"Show all additional information (activation, debugname, inlines, module and "
+"source)"
+msgstr ""
+"Wyświetla wszystkie dodatkowe informacje (aktywację, nazwę debugowania, "
+"wstawki, moduł i źródło)"
+
+#: src/stack.c:663
+msgid "Do not resolve address to function symbol name"
+msgstr "Nie rozwiązuje nazw symboli adresów do funkcji"
+
+#: src/stack.c:665
+msgid "Show raw function symbol names, do not try to demangle names"
+msgstr ""
+"Wyświetla surowe nazwy symboli funkcji, nie próbuje usuwać dekoracji z nazw"
+
+#: src/stack.c:667
+msgid "Show module build-id, load address and pc offset"
+msgstr "Wyświetla identyfikator kopii modułu, wczytuje adres i offset pc"
+
+#: src/stack.c:669
+msgid "Show the backtrace of only one thread"
+msgstr "Wyświetla wyjątek, jeśli jest tylko jeden wątek"
+
+#: src/stack.c:671
+msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)"
+msgstr ""
+"Wyświetla najwyżej MAKSYMALNĄ_LICZBĘ_KLATEK na wątek (domyślnie 256, 0 "
+"oznacza brak ograniczenia)"
+
+#: src/stack.c:673
+msgid "Show module memory map with build-id, elf and debug files detected"
+msgstr ""
+"Wyświetla mapę pamięci modułu z identyfikatorem kopii, wykryte pliki elf "
+"i debug"
+
+#: src/stack.c:681
+#, fuzzy
+msgid ""
+"Print a stack for each thread in a process or core file.\n"
+"\n"
+"Program exits with return code 0 if all frames were shown without any "
+"errors.  If some frames were shown, but there were some non-fatal errors, "
+"possibly causing an incomplete backtrace, the program exits with return code "
+"1.  If no frames could be shown, or a fatal error occured the program exits "
+"with return code 2.  If the program was invoked with bad or missing "
+"arguments it will exit with return code 64."
+msgstr ""
+"Wyświetla stos dla każdego wątku w procesie lub pliku core.\n"
+"\n"
+"Program kończy działanie z kodem zwrotnym 0, jeśli wszystkie ramki zostały "
+"wyświetlone bez żadnych błędów. Jeśli niektóre ramki zostały wyświetlone, "
+"ale wystąpiły niekrytyczne błędy, które mogą spowodować niepełny wyjątek, to "
+"program kończy działanie z kodem zwrotnym 1. Jeśli żadne ramki nie mogły "
+"zostać wyświetlone lub wystąpił krytyczny błąd, to program kończy działanie "
+"z kodem zwrotnym 2. Jeśli program został wywołany za pomocą błędnych lub "
+"brakujących parametrów, to zakończy on działanie z kodem zwrotnym 64."
+
+#: src/stack.c:756
+#, c-format
+msgid "Couldn't show any frames."
+msgstr "Nie można wyświetlić żadnych ramek."
+
+#: src/strings.c:66
+msgid "Output Selection:"
+msgstr "Wybór wyjścia:"
+
+#: src/strings.c:67
+msgid "Scan entire file, not only loaded sections"
+msgstr "Przeszukuje cały plik, nie tylko wczytane sekcje"
+
+#: src/strings.c:69
+msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed"
+msgstr ""
+"Wyświetlane są tylko zakończone NUL sekwencje o MIN-LEN lub większej liczbie "
+"znaków"
+
+#: src/strings.c:70
+msgid ""
+"Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, "
+"{B,L} = 32-bit"
+msgstr ""
+"Wybór rozmiaru i kolejności znaków: s = 7 bitów, S = 8 bitów, {b,l} = 16 "
+"bitów, {B,L} = 32 bity"
+
+#: src/strings.c:74
+msgid "Print name of the file before each string."
+msgstr "Wyświetla nazwę pliku przed każdym ciągiem."
+
+#: src/strings.c:76
+msgid "Print location of the string in base 8, 10, or 16 respectively."
+msgstr "Wyświetla położenie ciągu z podstawą odpowiednio 8, 10 lub 16."
+
+#: src/strings.c:77
+msgid "Alias for --radix=o"
+msgstr "Alias dla --radix=o"
+
+#. Short description of program.
+#: src/strings.c:84
+msgid "Print the strings of printable characters in files."
+msgstr "Wyświetla ciągi znaków drukowalnych w plikach."
+
+#: src/strings.c:257 src/strings.c:292
+#, c-format
+msgid "invalid value '%s' for %s parameter"
+msgstr "nieprawidłowa wartość „%s” dla parametru %s"
+
+#: src/strings.c:303
+#, c-format
+msgid "invalid minimum length of matched string size"
+msgstr "nieprawidłowa minimalna długość dopasowanego rozmiaru ciągu"
+
+#: src/strings.c:586
+#, c-format
+msgid "lseek failed"
+msgstr "lseek się nie powiodło"
+
+#: src/strings.c:603 src/strings.c:667
+#, c-format
+msgid "re-mmap failed"
+msgstr "ponowne mmap się nie powiodło"
+
+#: src/strings.c:640
+#, c-format
+msgid "mprotect failed"
+msgstr "mprotect się nie powiodło"
+
+#: src/strings.c:729
+#, c-format
+msgid "Skipping section %zd '%s' data outside file"
+msgstr "Pomijanie sekcji %zd „%s” dane poza plikiem"
+
+#: src/strip.c:71
+msgid "Place stripped output into FILE"
+msgstr "Umieszcza okrojone wyjście w PLIKU"
+
+#: src/strip.c:72
+msgid "Extract the removed sections into FILE"
+msgstr "Wydobywa usunięte sekcje do PLIKU"
+
+#: src/strip.c:73
+msgid "Embed name FILE instead of -f argument"
+msgstr "Osadza nazwę PLIKU zamiast parametru -f"
+
+#: src/strip.c:77
+msgid "Remove all debugging symbols"
+msgstr "Usuwa wszystkie symbole debugowania"
+
+#: src/strip.c:81
+msgid "Remove section headers (not recommended)"
+msgstr "Usuwa nagłówki sekcji (niezalecane)"
+
+#: src/strip.c:83
+msgid "Copy modified/access timestamps to the output"
+msgstr "Kopiuje czasy modyfikacji/dostępu do wyjścia"
+
+#: src/strip.c:85
+msgid ""
+"Resolve all trivial relocations between debug sections if the removed "
+"sections are placed in a debug file (only relevant for ET_REL files, "
+"operation is not reversable, needs -f)"
+msgstr ""
+"Rozwiązuje wszystkie proste relokacje między sekcjami debugowania, jeśli "
+"usunięte sekcje zostały umieszczone w pliku debugowania (ma znaczenie tylko "
+"dla plików ET_REL, działanie jest nieodwracalne, wymaga użycia opcji -f)"
+
+#: src/strip.c:87
+msgid "Remove .comment section"
+msgstr "Usuwa sekcję .comment"
+
+#: src/strip.c:88
+msgid ""
+"Remove the named section.  SECTION is an extended wildcard pattern.  May be "
+"given more than once.  Only non-allocated sections can be removed."
+msgstr ""
+
+#: src/strip.c:89
+msgid ""
+"Keep the named section.  SECTION is an extended wildcard pattern.  May be "
+"given more than once."
+msgstr ""
+
+#. Short description of program.
+#: src/strip.c:96
+msgid "Discard symbols from object files."
+msgstr "Odrzuca symbole z plików obiektów."
+
+#: src/strip.c:242
+#, c-format
+msgid "--reloc-debug-sections used without -f"
+msgstr "Użyto --reloc-debug-sections bez opcji -f"
+
+#: src/strip.c:256
+#, c-format
+msgid "Only one input file allowed together with '-o' and '-f'"
+msgstr "Tylko jeden plik wejściowy jest dozwolony z „-o” i „-f”"
+
+#: src/strip.c:279
+#, c-format
+msgid "-f option specified twice"
+msgstr "Opcję -f podano dwukrotnie"
+
+#: src/strip.c:288
+#, c-format
+msgid "-F option specified twice"
+msgstr "Opcję -F podano dwukrotnie"
+
+#: src/strip.c:347
+#, fuzzy, c-format
+msgid "cannot both keep and remove .comment section"
+msgstr "Usuwa sekcję .comment"
+
+#: src/strip.c:372 src/strip.c:396
+#, c-format
+msgid "cannot stat input file '%s'"
+msgstr "nie można wykonać stat na pliku wejściowym „%s”"
+
+#: src/strip.c:386
+#, c-format
+msgid "while opening '%s'"
+msgstr "podczas otwierania „%s”"
+
+#: src/strip.c:424
+#, c-format
+msgid "%s: cannot use -o or -f when stripping archive"
+msgstr "%s: nie można używać -o lub -f podczas okrajania archiwum"
+
+#. We would like to support ar archives, but currently it just
+#. doesn't work at all since we call elf_clone on the members
+#. which doesn't really support ar members.
+#. result = handle_ar (fd, elf, NULL, fname,
+#. preserve_dates ? tv : NULL);
+#.
+#: src/strip.c:436
+#, c-format
+msgid "%s: no support for stripping archive"
+msgstr "%s: brak obsługi okrajania archiwum"
+
+#: src/strip.c:535
+#, c-format
+msgid "cannot open EBL backend"
+msgstr "nie można otworzyć zaplecza EBL"
+
+#: src/strip.c:580
+#, c-format
+msgid "cannot get number of phdrs"
+msgstr "nie można uzyskać liczby phdr"
+
+#: src/strip.c:596 src/strip.c:620
+#, c-format
+msgid "cannot create new file '%s': %s"
+msgstr "nie można utworzyć nowego pliku „%s”: %s"
+
+#: src/strip.c:686
+#, c-format
+msgid "illformed file '%s'"
+msgstr "plik „%s” ma błędny format"
+
+#: src/strip.c:696
+#, fuzzy, c-format
+msgid "Cannot remove allocated section '%s'"
+msgstr "nie można przydzielić danych sekcji: %s"
+
+#: src/strip.c:705
+#, fuzzy, c-format
+msgid "Cannot both keep and remove section '%s'"
+msgstr "nie można dodać nowej sekcji: %s"
+
+#: src/strip.c:1061 src/strip.c:1160
+#, c-format
+msgid "while generating output file: %s"
+msgstr "podczas tworzenia pliku wyjściowego: %s"
+
+#: src/strip.c:1126 src/strip.c:2208
+#, c-format
+msgid "%s: error while creating ELF header: %s"
+msgstr "%s: błąd podczas tworzenia nagłówka ELF: %s"
+
+#: src/strip.c:1143
+#, c-format
+msgid "while preparing output for '%s'"
+msgstr "podczas przygotowywania wyjścia dla „%s”"
+
+#: src/strip.c:1205 src/strip.c:1268
+#, c-format
+msgid "while create section header section: %s"
+msgstr "podczas tworzenia sekcji nagłówka sekcji: %s"
+
+#: src/strip.c:1214
+#, c-format
+msgid "cannot allocate section data: %s"
+msgstr "nie można przydzielić danych sekcji: %s"
+
+#: src/strip.c:1280
+#, c-format
+msgid "while create section header string table: %s"
+msgstr "podczas tworzenia tabeli ciągów nagłówka sekcji: %s"
+
+#: src/strip.c:1287
+#, c-format
+msgid "no memory to create section header string table"
+msgstr "brak pamięci do utworzenia tabeli ciągów nagłówka sekcji"
+
+#: src/strip.c:1497
+#, c-format
+msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]"
+msgstr "Nie można usunąć symbolu [%zd] z przydzielonej tabeli symboli [%zd]"
+
+#: src/strip.c:1994
+#, c-format
+msgid "bad relocation"
+msgstr "błędna relokacja"
+
+#: src/strip.c:2119 src/strip.c:2232
+#, c-format
+msgid "while writing '%s': %s"
+msgstr "podczas zapisywania „%s”: %s"
+
+#: src/strip.c:2130
+#, c-format
+msgid "while creating '%s'"
+msgstr "podczas tworzenia „%s”"
+
+#: src/strip.c:2153
+#, c-format
+msgid "while computing checksum for debug information"
+msgstr "podczas obliczania sumy kontrolnej dla informacji debugowania"
+
+#: src/strip.c:2217
+#, c-format
+msgid "%s: error while reading the file: %s"
+msgstr "%s: błąd podczas odczytywania pliku: %s"
+
+#: src/strip.c:2257 src/strip.c:2277
+#, c-format
+msgid "while writing '%s'"
+msgstr "podczas zapisywania „%s”"
+
+#: src/strip.c:2314 src/strip.c:2321
+#, c-format
+msgid "error while finishing '%s': %s"
+msgstr "błąd podczas kończenia „%s”: %s"
+
+#: src/strip.c:2338 src/strip.c:2414
+#, c-format
+msgid "cannot set access and modification date of '%s'"
+msgstr "nie można ustawić czasu dostępu i modyfikacji „%s”"
+
+#: src/unstrip.c:70
+msgid "Match MODULE against file names, not module names"
+msgstr "Dopasowuje MODUŁY do nazw plików, a nie nazwy modułów"
+
+#: src/unstrip.c:71
+msgid "Silently skip unfindable files"
+msgstr "Pomija nieodnalezione pliki bez zgłaszania tego"
+
+#: src/unstrip.c:74
+msgid "Place output into FILE"
+msgstr "Umieszcza wyjście w PLIKU"
+
+#: src/unstrip.c:76
+msgid "Create multiple output files under DIRECTORY"
+msgstr "Tworzy wiele plików wyjściowych w KATALOGU"
+
+#: src/unstrip.c:77
+msgid "Use module rather than file names"
+msgstr "Używa nazw modułów zamiast nazw plików"
+
+#: src/unstrip.c:79
+msgid "Create output for modules that have no separate debug information"
+msgstr ""
+"Tworzy wyjście dla modułów niemających oddzielnych informacji debugowania"
+
+#: src/unstrip.c:82
+msgid "Apply relocations to section contents in ET_REL files"
+msgstr "Zastosowuje relokacje do zawartości sekcji w plikach ET_REL"
+
+#: src/unstrip.c:84
+msgid "Only list module and file names, build IDs"
+msgstr "Wyświetla tylko nazwy modułów i plików, identyfikatory kopii"
+
+#: src/unstrip.c:86
+msgid "Force combining files even if some ELF headers don't seem to match"
+msgstr ""
+"Wymusza łączenie plików nawet, jeśli niektóre nagłówki ELF się nie zgadzają"
+
+#: src/unstrip.c:130
+#, c-format
+msgid "-d option specified twice"
+msgstr "opcję -d podano dwukrotnie"
+
+#: src/unstrip.c:165
+#, c-format
+msgid "only one of -o or -d allowed"
+msgstr "dozwolona jest tylko jedna z opcji -o lub -d"
+
+#: src/unstrip.c:174
+#, c-format
+msgid "-n cannot be used with explicit files or -o or -d"
+msgstr "opcja -n nie może być używana z jawnymi plikami albo z opcją -o lub -d"
+
+#: src/unstrip.c:189
+#, c-format
+msgid "output directory '%s'"
+msgstr "katalog wyjściowy „%s”"
+
+#: src/unstrip.c:198
+#, c-format
+msgid "exactly two file arguments are required"
+msgstr "wymagane są dokładnie dwa parametry plików"
+
+#: src/unstrip.c:204
+#, c-format
+msgid "-m, -a, -R, and -i options not allowed with explicit files"
+msgstr "opcje -m, -a, -R oraz -i nie są dozwolone z jawnymi plikami"
+
+#: src/unstrip.c:217
+#, c-format
+msgid "-o or -d is required when using implicit files"
+msgstr "opcja -o lub -d jest wymagana podczas używania ukrytych plików"
+
+#: src/unstrip.c:240
+#, c-format
+msgid "cannot create ELF header: %s"
+msgstr "nie można utworzyć nagłówka ELF: %s"
+
+#: src/unstrip.c:245
+#, c-format
+msgid "cannot copy ELF header: %s"
+msgstr "nie można skopiować nagłówka ELF: %s"
+
+#: src/unstrip.c:249 src/unstrip.c:1933 src/unstrip.c:1976
+#, c-format
+msgid "cannot get number of program headers: %s"
+msgstr "nie można uzyskać liczby nagłówków programu: %s"
+
+#: src/unstrip.c:254 src/unstrip.c:1937
+#, c-format
+msgid "cannot create program headers: %s"
+msgstr "nie można utworzyć nagłówków programu: %s"
+
+#: src/unstrip.c:260
+#, c-format
+msgid "cannot copy program header: %s"
+msgstr "nie można skopiować nagłówka programu: %s"
+
+#: src/unstrip.c:270
+#, c-format
+msgid "cannot copy section header: %s"
+msgstr "nie można skopiować nagłówka sekcji: %s"
+
+#: src/unstrip.c:273 src/unstrip.c:1568
+#, c-format
+msgid "cannot get section data: %s"
+msgstr "nie można uzyskać danych sekcji: %s"
+
+#: src/unstrip.c:275 src/unstrip.c:1570
+#, c-format
+msgid "cannot copy section data: %s"
+msgstr "nie można skopiować danych sekcji: %s"
+
+#: src/unstrip.c:299
+#, c-format
+msgid "cannot create directory '%s'"
+msgstr "nie można utworzyć katalogu „%s”"
+
+#: src/unstrip.c:371 src/unstrip.c:791 src/unstrip.c:1602
+#, c-format
+msgid "cannot get symbol table entry: %s"
+msgstr "nie można uzyskać wpisu tabeli symboli: %s"
+
+#: src/unstrip.c:387 src/unstrip.c:608 src/unstrip.c:629 src/unstrip.c:641
+#: src/unstrip.c:1623 src/unstrip.c:1799 src/unstrip.c:1823
+#, c-format
+msgid "cannot update symbol table: %s"
+msgstr "nie można zaktualizować tabeli symboli: %s"
+
+#: src/unstrip.c:397
+#, c-format
+msgid "cannot update section header: %s"
+msgstr "nie można zaktualizować nagłówka sekcji: %s"
+
+#: src/unstrip.c:436 src/unstrip.c:447
+#, c-format
+msgid "cannot update relocation: %s"
+msgstr "nie można zaktualizować relokacji: %s"
+
+#: src/unstrip.c:535
+#, c-format
+msgid "cannot get symbol version: %s"
+msgstr "nie można uzyskać wersji symbolu: %s"
+
+#: src/unstrip.c:548
+#, c-format
+msgid "unexpected section type in [%zu] with sh_link to symtab"
+msgstr "nieoczekiwany typ sekcji w [%zu] z sh_link do tabeli symboli"
+
+#: src/unstrip.c:797
+#, c-format
+msgid "invalid string offset in symbol [%zu]"
+msgstr "nieprawidłowy offset ciągu w symbolu [%zu]"
+
+#: src/unstrip.c:955 src/unstrip.c:1305
+#, c-format
+msgid "cannot read section [%zu] name: %s"
+msgstr "nie można odczytać nazwy sekcji [%zu]: %s"
+
+#: src/unstrip.c:996 src/unstrip.c:1015 src/unstrip.c:1053
+#, c-format
+msgid "cannot read '.gnu.prelink_undo' section: %s"
+msgstr "nie można odczytać sekcji „.gnu.prelink_undo”: %s"
+
+#: src/unstrip.c:1033
+#, c-format
+msgid "overflow with shnum = %zu in '%s' section"
+msgstr "przepełnienie z shnum = %zu w sekcji „%s”"
+
+#: src/unstrip.c:1044
+#, c-format
+msgid "invalid contents in '%s' section"
+msgstr "nieprawidłowa zawartość w sekcji „%s”"
+
+#: src/unstrip.c:1099 src/unstrip.c:1427
+#, c-format
+msgid "cannot find matching section for [%zu] '%s'"
+msgstr "nie można odnaleźć pasującej sekcji dla [%zu] „%s”"
+
+#: src/unstrip.c:1224 src/unstrip.c:1239 src/unstrip.c:1506 src/unstrip.c:1758
+#, c-format
+msgid "cannot add section name to string table: %s"
+msgstr "nie można nazwy sekcji do tabeli ciągów: %s"
+
+#: src/unstrip.c:1248
+#, c-format
+msgid "cannot update section header string table data: %s"
+msgstr "nie można zaktualizować danych tabeli ciągów nagłówków sekcji: %s"
+
+#: src/unstrip.c:1276 src/unstrip.c:1280
+#, c-format
+msgid "cannot get section header string table section index: %s"
+msgstr "nie można uzyskać indeksu sekcji tabeli ciągów nagłówków sekcji: %s"
+
+#: src/unstrip.c:1284 src/unstrip.c:1288 src/unstrip.c:1521
+#, c-format
+msgid "cannot get section count: %s"
+msgstr "nie można uzyskać licznika sekcji: %s"
+
+#: src/unstrip.c:1291
+#, c-format
+msgid "more sections in stripped file than debug file -- arguments reversed?"
+msgstr ""
+"więcej sekcji w okrojonym pliku niż w pliku debugowania — odwrócono "
+"parametry?"
+
+#: src/unstrip.c:1350 src/unstrip.c:1442
+#, c-format
+msgid "cannot read section header string table: %s"
+msgstr "nie można odczytać tabeli ciągów nagłówków sekcji: %s"
+
+#: src/unstrip.c:1500
+#, c-format
+msgid "cannot add new section: %s"
+msgstr "nie można dodać nowej sekcji: %s"
+
+#: src/unstrip.c:1610
+#, c-format
+msgid "symbol [%zu] has invalid section index"
+msgstr "symbol [%zu] ma nieprawidłowy indeks sekcji"
+
+#: src/unstrip.c:1894
+#, c-format
+msgid "cannot read section data: %s"
+msgstr "nie można odczytać danych sekcji: %s"
+
+#: src/unstrip.c:1915
+#, c-format
+msgid "cannot get ELF header: %s"
+msgstr "nie można uzyskać nagłówka ELF: %s"
+
+#: src/unstrip.c:1923
+#, c-format
+msgid "cannot update ELF header: %s"
+msgstr "nie można zaktualizować nagłówka ELF: %s"
+
+#: src/unstrip.c:1947
+#, c-format
+msgid "cannot update program header: %s"
+msgstr "nie można zaktualizować nagłówka programu: %s"
+
+#: src/unstrip.c:1952 src/unstrip.c:2034
+#, c-format
+msgid "cannot write output file: %s"
+msgstr "nie można zapisać pliku wyjściowego: %s"
+
+#: src/unstrip.c:2003
+#, c-format
+msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+"Dane DWARF nie zostały dostosowane do przesunięcia wczesnego konsolidowania; "
+"proszę rozważyć polecenie prelink -u"
+
+#: src/unstrip.c:2006
+#, c-format
+msgid ""
+"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+"Dane DWARF w „%s” nie zostały dostosowane do przesunięcia wczesnego "
+"konsolidowania; proszę rozważyć polecenie prelink -u"
+
+#: src/unstrip.c:2025 src/unstrip.c:2076 src/unstrip.c:2088 src/unstrip.c:2174
+#, c-format
+msgid "cannot create ELF descriptor: %s"
+msgstr "nie można utworzyć deskryptora ELF: %s"
+
+#: src/unstrip.c:2067
+msgid "WARNING: "
+msgstr "OSTRZEŻENIE: "
+
+#: src/unstrip.c:2069
+msgid ", use --force"
+msgstr ", należy użyć opcji --force"
+
+#: src/unstrip.c:2092
+msgid "ELF header identification (e_ident) different"
+msgstr "Różna identyfikacja nagłówka ELF (e_ident)"
+
+#: src/unstrip.c:2095
+msgid "ELF header type (e_type) different"
+msgstr "Różne typy nagłówka ELF (e_type)"
+
+#: src/unstrip.c:2098
+msgid "ELF header machine type (e_machine) different"
+msgstr "Różne typy maszyny nagłówka ELF (e_machine)"
+
+#: src/unstrip.c:2101
+msgid "stripped program header (e_phnum) smaller than unstripped"
+msgstr "okrojony nagłówek programu (e_phnum) jest mniejszy niż nieokrojony"
+
+#: src/unstrip.c:2131
+#, c-format
+msgid "cannot find stripped file for module '%s': %s"
+msgstr "nie można odnaleźć okrojonego pliku dla modułu „%s”: %s"
+
+#: src/unstrip.c:2135
+#, c-format
+msgid "cannot open stripped file '%s' for module '%s': %s"
+msgstr "nie można otworzyć okrojonego pliku „%s” dla modułu „%s”: %s"
+
+#: src/unstrip.c:2150
+#, c-format
+msgid "cannot find debug file for module '%s': %s"
+msgstr "nie można odnaleźć pliku debugowania dla modułu „%s”: %s"
+
+#: src/unstrip.c:2154
+#, c-format
+msgid "cannot open debug file '%s' for module '%s': %s"
+msgstr "nie można otworzyć pliku debugowania „%s” dla modułu „%s”: %s"
+
+#: src/unstrip.c:2167
+#, c-format
+msgid "module '%s' file '%s' is not stripped"
+msgstr "moduł „%s” pliku „%s” nie został okrojony"
+
+#: src/unstrip.c:2198
+#, c-format
+msgid "cannot cache section addresses for module '%s': %s"
+msgstr ""
+"nie można utworzyć pamięci podręcznej adresów sekcji dla modułu „%s”: %s"
+
+#: src/unstrip.c:2331
+#, c-format
+msgid "no matching modules found"
+msgstr "nie odnaleziono pasujących modułów"
+
+#: src/unstrip.c:2340
+#, c-format
+msgid "matched more than one module"
+msgstr "pasuje więcej niż jeden moduł"
+
+#: src/unstrip.c:2384
+msgid ""
+"STRIPPED-FILE DEBUG-FILE\n"
+"[MODULE...]"
+msgstr ""
+"OKROJONY-PLIK PLIK-DEBUGOWANIA\n"
+"[MODUŁ…]"
+
+#: src/unstrip.c:2385
+#, fuzzy
+msgid ""
+"Combine stripped files with separate symbols and debug information.\n"
+"\n"
+"The first form puts the result in DEBUG-FILE if -o was not given.\n"
+"\n"
+"MODULE arguments give file name patterns matching modules to process.\n"
+"With -f these match the file name of the main (stripped) file (slashes are "
+"never special), otherwise they match the simple module names.  With no "
+"arguments, process all modules found.\n"
+"\n"
+"Multiple modules are written to files under OUTPUT-DIRECTORY, creating "
+"subdirectories as needed.  With -m these files have simple module names, "
+"otherwise they have the name of the main file complete with directory "
+"underneath OUTPUT-DIRECTORY.\n"
+"\n"
+"With -n no files are written, but one line to standard output for each "
+"module:\n"
+"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n"
+"START and SIZE are hexadecimal giving the address bounds of the module.  "
+"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the "
+"hexadecimal may be followed by @0xADDR giving the address where the ID "
+"resides if that is known.  FILE is the file name found for the module, or - "
+"if none was found, or . if an ELF image is available but not from any named "
+"file.  DEBUGFILE is the separate debuginfo file name, or - if no debuginfo "
+"was found, or . if FILE contains the debug information."
+msgstr ""
+"Łączy okrojone pliki z oddzielnymi symbolami i informacjami debugowania.\n"
+"\n"
+"Pierwsza forma umieszcza wynik w PLIKU-DEBUGOWANIA, jeśli nie podano opcji -"
+"o.\n"
+"\n"
+"Parametr MODUŁ podaje wzorce nazw plików dopasowujące moduły do procesów.\n"
+"Za pomocą opcji -f dopasowuje nazwę głównego (okrojonego) pliku (ukośniki "
+"nigdy nie są specjalne), w innym przypadku dopasowują proste nazwy modułów. "
+"Jeśli nie podano parametrów, przetwarza wszystkie odnalezione moduły.\n"
+"\n"
+"Wiele modułów zostaje zapisanych do plików w KATALOGU-WYJŚCIOWYM, tworząc "
+"podkatalogi, jeśli są wymagane. Używając opcji -m te pliki mające proste "
+"nazwy modułów, w innym przypadku mają nazwy głównego pliku uzupełnione "
+"katalogiem w KATALOGU-WYJŚCIOWYM.\n"
+"\n"
+"Używając opcji -n żadne pliki nie zostają zapisane, a jeden wiersz do "
+"standardowego wyjścia dla każdego modułu:\n"
+"\tPOCZĄTEK+ROZMIAR IDENTYFIKATOR-KOPII PLIK PLIK-DEBUGOWANIA NAZWA-MODUŁU\n"
+"POCZĄTEK i ROZMIAR są liczbami szesnastkowymi podającymi zakres adresów "
+"modułu. IDENTYFIKATOR-KOPII jest liczbą szesnastkową dla bitów "
+"identyfikatora kopii lub „-”, jeśli identyfikator jest nieznany; liczba "
+"szesnastkowa może być uzupełniona @0xADRES podającym adres, gdzie znajduje "
+"się identyfikator, jeśli jest to wiadome. PLIK jest nazwą pliku "
+"odnalezionego dla modułu lub „-”, jeśli go nie odnaleziono lub „.”, jeśli "
+"obraz ELF jest dostępny, ale nie z żadnego nazwanego pliku. PLIK-DEBUGOWANIA "
+"jest nazwą oddzielnego pliku debuginfo lub „-”, jeśli nie odnaleziono "
+"debuginfo lub „.”, jeśli PLIK zawiera informacje debugowania."
+
+#: tests/backtrace.c:442
+msgid "Run executable"
+msgstr "Uruchamia plik wykonywalny"
+
+#: tests/dwflmodtest.c:213
+msgid "Additionally show function names"
+msgstr "Dodatkowo wyświetla nazwy funkcji"
+
+#: tests/dwflmodtest.c:214
+msgid "Show instances of inlined functions"
+msgstr "Wyświetla wystąpienia wstawionych funkcji"
+
+#~ msgid "-R option supports only .comment section"
+#~ msgstr "Opcja -R obsługuje tylko sekcję .comment"
diff --git a/third_party/elfutils/po/quot.sed b/third_party/elfutils/po/quot.sed
new file mode 100644
index 0000000..0122c46
--- /dev/null
+++ b/third_party/elfutils/po/quot.sed
@@ -0,0 +1,6 @@
+s/"\([^"]*\)"/“\1”/g
+s/`\([^`']*\)'/‘\1’/g
+s/ '\([^`']*\)' / ‘\1’ /g
+s/ '\([^`']*\)'$/ ‘\1’/g
+s/^'\([^`']*\)' /‘\1’ /g
+s/“”/""/g
diff --git a/third_party/elfutils/po/remove-potcdate.sin b/third_party/elfutils/po/remove-potcdate.sin
new file mode 100644
index 0000000..2436c49
--- /dev/null
+++ b/third_party/elfutils/po/remove-potcdate.sin
@@ -0,0 +1,19 @@
+# Sed script that remove the POT-Creation-Date line in the header entry
+# from a POT file.
+#
+# The distinction between the first and the following occurrences of the
+# pattern is achieved by looking at the hold space.
+/^"POT-Creation-Date: .*"$/{
+x
+# Test if the hold space is empty.
+s/P/P/
+ta
+# Yes it was empty. First occurrence. Remove the line.
+g
+d
+bb
+:a
+# The hold space was nonempty. Following occurrences. Do nothing.
+x
+:b
+}
diff --git a/third_party/elfutils/po/ru.po b/third_party/elfutils/po/ru.po
new file mode 100644
index 0000000..99505d6
--- /dev/null
+++ b/third_party/elfutils/po/ru.po
@@ -0,0 +1,5665 @@
+# translation of ru.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ru\n"
+"Report-Msgid-Bugs-To: http://bugzilla.redhat.com/\n"
+"POT-Creation-Date: 2010-04-21 07:41-0700\n"
+"PO-Revision-Date: 2009-11-12 10:27+1100\n"
+"Last-Translator: NAME <EMAIL>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: lib/xmalloc.c:51 lib/xmalloc.c:65 lib/xmalloc.c:79 src/readelf.c:2822
+#: src/readelf.c:3161 src/unstrip.c:2087 src/unstrip.c:2295
+#, c-format
+msgid "memory exhausted"
+msgstr ""
+
+#: libasm/asm_error.c:62 libdw/dwarf_error.c:79 libdwfl/libdwflP.h:70
+#: libelf/elf_error.c:81
+msgid "no error"
+msgstr ""
+
+#: libasm/asm_error.c:63 libdw/dwarf_error.c:88 libdwfl/libdwflP.h:72
+#: libelf/elf_error.c:112
+msgid "out of memory"
+msgstr ""
+
+#: libasm/asm_error.c:64 src/ldgeneric.c:2687
+#, c-format
+msgid "cannot create output file"
+msgstr ""
+
+#: libasm/asm_error.c:65
+msgid "invalid parameter"
+msgstr ""
+
+#: libasm/asm_error.c:66
+msgid "cannot change mode of output file"
+msgstr ""
+
+#: libasm/asm_error.c:67 src/ldgeneric.c:7001
+#, c-format
+msgid "cannot rename output file"
+msgstr ""
+
+#: libasm/asm_error.c:68
+msgid "duplicate symbol"
+msgstr ""
+
+#: libasm/asm_error.c:69
+msgid "invalid section type for operation"
+msgstr ""
+
+#: libasm/asm_error.c:70
+msgid "error during output of data"
+msgstr ""
+
+#: libasm/asm_error.c:71
+msgid "no backend support available"
+msgstr ""
+
+#: libasm/asm_error.c:81 libdw/dwarf_error.c:80 libdwfl/libdwflP.h:71
+#: libelf/elf_error.c:84
+msgid "unknown error"
+msgstr ""
+
+#: libdw/dwarf_error.c:81
+msgid "invalid access"
+msgstr ""
+
+#: libdw/dwarf_error.c:82
+msgid "no regular file"
+msgstr ""
+
+#: libdw/dwarf_error.c:83
+msgid "I/O error"
+msgstr ""
+
+#: libdw/dwarf_error.c:84
+msgid "invalid ELF file"
+msgstr ""
+
+#: libdw/dwarf_error.c:85
+msgid "no DWARF information"
+msgstr ""
+
+#: libdw/dwarf_error.c:86
+msgid "no ELF file"
+msgstr ""
+
+#: libdw/dwarf_error.c:87
+msgid "cannot get ELF header"
+msgstr ""
+
+#: libdw/dwarf_error.c:89
+msgid "not implemented"
+msgstr ""
+
+#: libdw/dwarf_error.c:90 libelf/elf_error.c:128 libelf/elf_error.c:176
+msgid "invalid command"
+msgstr ""
+
+#: libdw/dwarf_error.c:91
+msgid "invalid version"
+msgstr ""
+
+#: libdw/dwarf_error.c:92
+msgid "invalid file"
+msgstr ""
+
+#: libdw/dwarf_error.c:93
+msgid "no entries found"
+msgstr ""
+
+#: libdw/dwarf_error.c:94
+msgid "invalid DWARF"
+msgstr ""
+
+#: libdw/dwarf_error.c:95
+msgid "no string data"
+msgstr ""
+
+#: libdw/dwarf_error.c:96
+msgid "no address value"
+msgstr ""
+
+#: libdw/dwarf_error.c:97
+msgid "no constant value"
+msgstr ""
+
+#: libdw/dwarf_error.c:98
+msgid "no reference value"
+msgstr ""
+
+#: libdw/dwarf_error.c:99
+msgid "invalid reference value"
+msgstr ""
+
+#: libdw/dwarf_error.c:100
+msgid ".debug_line section missing"
+msgstr ""
+
+#: libdw/dwarf_error.c:101
+msgid "invalid .debug_line section"
+msgstr ""
+
+#: libdw/dwarf_error.c:102
+msgid "debug information too big"
+msgstr ""
+
+#: libdw/dwarf_error.c:103
+msgid "invalid DWARF version"
+msgstr ""
+
+#: libdw/dwarf_error.c:104
+msgid "invalid directory index"
+msgstr ""
+
+#: libdw/dwarf_error.c:105 libdwfl/libdwflP.h:91
+msgid "address out of range"
+msgstr ""
+
+#: libdw/dwarf_error.c:106
+msgid "no location list value"
+msgstr ""
+
+#: libdw/dwarf_error.c:107
+msgid "no block data"
+msgstr ""
+
+#: libdw/dwarf_error.c:108
+msgid "invalid line index"
+msgstr ""
+
+#: libdw/dwarf_error.c:109
+msgid "invalid address range index"
+msgstr ""
+
+#: libdw/dwarf_error.c:110 libdwfl/libdwflP.h:92
+msgid "no matching address range"
+msgstr ""
+
+#: libdw/dwarf_error.c:111
+msgid "no flag value"
+msgstr ""
+
+#: libdw/dwarf_error.c:112 libelf/elf_error.c:253
+msgid "invalid offset"
+msgstr ""
+
+#: libdw/dwarf_error.c:113
+msgid ".debug_ranges section missing"
+msgstr ""
+
+#: libdw/dwarf_error.c:114
+msgid "invalid CFI section"
+msgstr ""
+
+#: libdwfl/argp-std.c:67 src/unstrip.c:2237
+msgid "Input selection options:"
+msgstr ""
+
+#: libdwfl/argp-std.c:68
+msgid "Find addresses in FILE"
+msgstr ""
+
+#: libdwfl/argp-std.c:70
+msgid "Find addresses from signatures found in COREFILE"
+msgstr ""
+
+#: libdwfl/argp-std.c:72
+msgid "Find addresses in files mapped into process PID"
+msgstr ""
+
+#: libdwfl/argp-std.c:74
+msgid ""
+"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps "
+"format"
+msgstr ""
+
+#: libdwfl/argp-std.c:76
+msgid "Find addresses in the running kernel"
+msgstr ""
+
+#: libdwfl/argp-std.c:78
+msgid "Kernel with all modules"
+msgstr ""
+
+#: libdwfl/argp-std.c:80
+msgid "Search path for separate debuginfo files"
+msgstr ""
+
+#: libdwfl/argp-std.c:163
+msgid "only one of -e, -p, -k, -K, or --core allowed"
+msgstr ""
+
+#: libdwfl/argp-std.c:223
+#, c-format
+msgid "cannot read ELF core file: %s"
+msgstr ""
+
+#: libdwfl/argp-std.c:241
+msgid "No modules recognized in core file"
+msgstr ""
+
+#: libdwfl/argp-std.c:253
+msgid "cannot load kernel symbols"
+msgstr ""
+
+#: libdwfl/argp-std.c:257
+msgid "cannot find kernel modules"
+msgstr ""
+
+#: libdwfl/argp-std.c:271
+msgid "cannot find kernel or modules"
+msgstr ""
+
+#: libdwfl/libdwflP.h:73
+msgid "See errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:74
+msgid "See elf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:75
+msgid "See dwarf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:76
+msgid "See ebl_errno (XXX missing)"
+msgstr ""
+
+#: libdwfl/libdwflP.h:77
+msgid "gzip decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:78
+msgid "bzip2 decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:79
+msgid "LZMA decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:80
+msgid "no support library found for machine"
+msgstr ""
+
+#: libdwfl/libdwflP.h:81
+msgid "Callbacks missing for ET_REL file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:82
+msgid "Unsupported relocation type"
+msgstr ""
+
+#: libdwfl/libdwflP.h:83
+msgid "r_offset is bogus"
+msgstr ""
+
+#: libdwfl/libdwflP.h:84 libelf/elf_error.c:132 libelf/elf_error.c:192
+msgid "offset out of range"
+msgstr ""
+
+#: libdwfl/libdwflP.h:85
+msgid "relocation refers to undefined symbol"
+msgstr ""
+
+#: libdwfl/libdwflP.h:86
+msgid "Callback returned failure"
+msgstr ""
+
+#: libdwfl/libdwflP.h:87
+msgid "No DWARF information found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:88
+msgid "No symbol table found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:89
+msgid "No ELF program headers"
+msgstr ""
+
+#: libdwfl/libdwflP.h:90
+msgid "address range overlaps an existing module"
+msgstr ""
+
+#: libdwfl/libdwflP.h:93
+msgid "image truncated"
+msgstr ""
+
+#: libdwfl/libdwflP.h:94
+msgid "ELF file opened"
+msgstr ""
+
+#: libdwfl/libdwflP.h:95
+msgid "not a valid ELF file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:96
+msgid "cannot handle DWARF type description"
+msgstr ""
+
+#: libebl/eblbackendname.c:63
+msgid "No backend"
+msgstr ""
+
+#: libebl/eblcorenotetypename.c:107 libebl/eblobjecttypename.c:78
+#: libebl/eblobjnotetypename.c:86 libebl/eblosabiname.c:98
+#: libebl/eblsectionname.c:110 libebl/eblsectiontypename.c:140
+#: libebl/eblsegmenttypename.c:104
+msgid "<unknown>"
+msgstr ""
+
+#: libebl/ebldynamictagname.c:126
+#, c-format
+msgid "<unknown>: %#<PRIx64>"
+msgstr ""
+
+#: libebl/eblobjnote.c:76
+#, c-format
+msgid "    Build ID: "
+msgstr ""
+
+#: libebl/eblobjnote.c:87
+#, c-format
+msgid "    Linker version: %.*s\n"
+msgstr ""
+
+#: libebl/eblobjnote.c:136
+#, c-format
+msgid "    OS: %s, ABI: "
+msgstr ""
+
+#: libebl/eblosabiname.c:95
+msgid "Stand alone"
+msgstr ""
+
+#: libebl/eblsymbolbindingname.c:92 libebl/eblsymboltypename.c:98
+#, c-format
+msgid "<unknown>: %d"
+msgstr ""
+
+#: libelf/elf_error.c:88
+msgid "unknown version"
+msgstr ""
+
+#: libelf/elf_error.c:92
+msgid "unknown type"
+msgstr ""
+
+#: libelf/elf_error.c:96
+msgid "invalid `Elf' handle"
+msgstr ""
+
+#: libelf/elf_error.c:100
+msgid "invalid size of source operand"
+msgstr ""
+
+#: libelf/elf_error.c:104
+msgid "invalid size of destination operand"
+msgstr ""
+
+#: libelf/elf_error.c:108 src/readelf.c:4779
+#, c-format
+msgid "invalid encoding"
+msgstr ""
+
+#: libelf/elf_error.c:116
+msgid "invalid file descriptor"
+msgstr ""
+
+#: libelf/elf_error.c:120
+msgid "invalid operation"
+msgstr ""
+
+#: libelf/elf_error.c:124
+msgid "ELF version not set"
+msgstr ""
+
+#: libelf/elf_error.c:136
+msgid "invalid fmag field in archive header"
+msgstr ""
+
+#: libelf/elf_error.c:140
+msgid "invalid archive file"
+msgstr ""
+
+#: libelf/elf_error.c:144
+msgid "descriptor is not for an archive"
+msgstr ""
+
+#: libelf/elf_error.c:148
+msgid "no index available"
+msgstr ""
+
+#: libelf/elf_error.c:152
+msgid "cannot read data from file"
+msgstr ""
+
+#: libelf/elf_error.c:156
+msgid "cannot write data to file"
+msgstr ""
+
+#: libelf/elf_error.c:160
+msgid "invalid binary class"
+msgstr ""
+
+#: libelf/elf_error.c:164
+msgid "invalid section index"
+msgstr ""
+
+#: libelf/elf_error.c:168
+msgid "invalid operand"
+msgstr ""
+
+#: libelf/elf_error.c:172
+msgid "invalid section"
+msgstr ""
+
+#: libelf/elf_error.c:180
+msgid "executable header not created first"
+msgstr ""
+
+#: libelf/elf_error.c:184
+msgid "file descriptor disabled"
+msgstr ""
+
+#: libelf/elf_error.c:188
+msgid "archive/member file descriptor mismatch"
+msgstr ""
+
+#: libelf/elf_error.c:196
+msgid "cannot manipulate null section"
+msgstr ""
+
+#: libelf/elf_error.c:200
+msgid "data/scn mismatch"
+msgstr ""
+
+#: libelf/elf_error.c:204
+msgid "invalid section header"
+msgstr ""
+
+#: libelf/elf_error.c:208 src/readelf.c:6242 src/readelf.c:6343
+#, c-format
+msgid "invalid data"
+msgstr ""
+
+#: libelf/elf_error.c:212
+msgid "unknown data encoding"
+msgstr ""
+
+#: libelf/elf_error.c:216
+msgid "section `sh_size' too small for data"
+msgstr ""
+
+#: libelf/elf_error.c:220
+msgid "invalid section alignment"
+msgstr ""
+
+#: libelf/elf_error.c:224
+msgid "invalid section entry size"
+msgstr ""
+
+#: libelf/elf_error.c:228
+msgid "update() for write on read-only file"
+msgstr ""
+
+#: libelf/elf_error.c:232
+msgid "no such file"
+msgstr ""
+
+#: libelf/elf_error.c:236
+msgid "only relocatable files can contain section groups"
+msgstr ""
+
+#: libelf/elf_error.c:241
+msgid ""
+"program header only allowed in executables, shared objects, and core files"
+msgstr ""
+
+#: libelf/elf_error.c:248
+msgid "file has no program header"
+msgstr ""
+
+#: src/addr2line.c:66
+msgid "Output selection options:"
+msgstr ""
+
+#: src/addr2line.c:67
+msgid "Show only base names of source files"
+msgstr ""
+
+#: src/addr2line.c:69
+msgid "Show absolute file names using compilation directory"
+msgstr ""
+
+#: src/addr2line.c:70
+msgid "Also show function names"
+msgstr ""
+
+#: src/addr2line.c:71
+msgid "Also show symbol or section names"
+msgstr ""
+
+#: src/addr2line.c:73
+msgid "Treat addresses as offsets relative to NAME section."
+msgstr ""
+
+#: src/addr2line.c:75 src/elfcmp.c:75 src/findtextrel.c:75 src/nm.c:103
+#: src/strings.c:83
+msgid "Miscellaneous:"
+msgstr ""
+
+#: src/addr2line.c:84
+msgid ""
+"Locate source files and line information for ADDRs (in a.out by default)."
+msgstr ""
+
+#: src/addr2line.c:88
+msgid "[ADDR...]"
+msgstr ""
+
+#: src/addr2line.c:185 src/ar.c:289 src/elfcmp.c:555 src/elflint.c:239
+#: src/findtextrel.c:170 src/ld.c:957 src/nm.c:253 src/objdump.c:181
+#: src/ranlib.c:136 src/readelf.c:449 src/size.c:219 src/strings.c:227
+#: src/strip.c:204 src/unstrip.c:234
+#, c-format
+msgid ""
+"Copyright (C) %s Red Hat, Inc.\n"
+"This is free software; see the source for copying conditions.  There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+
+#: src/addr2line.c:190 src/ar.c:294 src/elfcmp.c:560 src/elflint.c:244
+#: src/findtextrel.c:175 src/ld.c:962 src/nm.c:258 src/objdump.c:186
+#: src/ranlib.c:141 src/readelf.c:454 src/size.c:224 src/strings.c:232
+#: src/strip.c:209 src/unstrip.c:239
+#, c-format
+msgid "Written by %s.\n"
+msgstr ""
+
+#: src/addr2line.c:405
+#, c-format
+msgid "Section syntax requires exactly one module"
+msgstr ""
+
+#: src/addr2line.c:428
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside section '%s'"
+msgstr ""
+
+#: src/addr2line.c:461
+#, c-format
+msgid "cannot find symbol '%s'"
+msgstr ""
+
+#: src/addr2line.c:466
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside contents of '%s'"
+msgstr ""
+
+#: src/ar.c:76
+msgid "Commands:"
+msgstr ""
+
+#: src/ar.c:77
+msgid "Delete files from archive."
+msgstr ""
+
+#: src/ar.c:78
+msgid "Move files in archive."
+msgstr ""
+
+#: src/ar.c:79
+msgid "Print files in archive."
+msgstr ""
+
+#: src/ar.c:80
+msgid "Quick append files to archive."
+msgstr ""
+
+#: src/ar.c:82
+msgid "Replace existing or insert new file into archive."
+msgstr ""
+
+#: src/ar.c:83
+msgid "Display content of archive."
+msgstr ""
+
+#: src/ar.c:84
+msgid "Extract files from archive."
+msgstr ""
+
+#: src/ar.c:86
+msgid "Command Modifiers:"
+msgstr ""
+
+#: src/ar.c:87
+msgid "Preserve original dates."
+msgstr ""
+
+#: src/ar.c:88
+msgid "Use instance [COUNT] of name."
+msgstr ""
+
+#: src/ar.c:90
+msgid "Do not replace existing files with extracted files."
+msgstr ""
+
+#: src/ar.c:91
+msgid "Allow filename to be truncated if necessary."
+msgstr ""
+
+#: src/ar.c:93
+msgid "Provide verbose output."
+msgstr ""
+
+#: src/ar.c:94
+msgid "Force regeneration of symbol table."
+msgstr ""
+
+#: src/ar.c:95
+msgid "Insert file after [MEMBER]."
+msgstr ""
+
+#: src/ar.c:96
+msgid "Insert file before [MEMBER]."
+msgstr ""
+
+#: src/ar.c:97
+msgid "Same as -b."
+msgstr ""
+
+#: src/ar.c:98
+msgid "Suppress message when library has to be created."
+msgstr ""
+
+#: src/ar.c:100
+msgid "Use full path for file matching."
+msgstr ""
+
+#: src/ar.c:101
+msgid "Update only older files in archive."
+msgstr ""
+
+#: src/ar.c:107
+msgid "Create, modify, and extract from archives."
+msgstr ""
+
+#: src/ar.c:110
+msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]"
+msgstr ""
+
+#: src/ar.c:192
+#, c-format
+msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options"
+msgstr ""
+
+#: src/ar.c:197
+#, c-format
+msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers"
+msgstr ""
+
+#: src/ar.c:213
+#, c-format
+msgid "'N' is only meaningful with the 'x' and 'd' options"
+msgstr ""
+
+#: src/ar.c:218
+#, c-format
+msgid "COUNT parameter required"
+msgstr ""
+
+#: src/ar.c:230
+#, c-format
+msgid "invalid COUNT parameter %s"
+msgstr ""
+
+#: src/ar.c:237
+#, c-format
+msgid "'%c' is only meaningful with the 'x' option"
+msgstr ""
+
+#: src/ar.c:243
+#, c-format
+msgid "archive name required"
+msgstr ""
+
+#: src/ar.c:314
+#, c-format
+msgid "More than one operation specified"
+msgstr ""
+
+#: src/ar.c:404
+#, c-format
+msgid "cannot open archive '%s'"
+msgstr ""
+
+#: src/ar.c:414
+#, c-format
+msgid "cannot open archive '%s': %s"
+msgstr ""
+
+#: src/ar.c:418
+#, c-format
+msgid "%s: not an archive file"
+msgstr ""
+
+#: src/ar.c:422
+#, c-format
+msgid "cannot stat archive '%s'"
+msgstr ""
+
+#: src/ar.c:434
+#, c-format
+msgid "no entry %s in archive\n"
+msgstr ""
+
+#: src/ar.c:487 src/ar.c:929 src/ar.c:1129
+#, c-format
+msgid "cannot create hash table"
+msgstr ""
+
+#: src/ar.c:494 src/ar.c:936 src/ar.c:1138
+#, c-format
+msgid "cannot insert into hash table"
+msgstr ""
+
+#: src/ar.c:502 src/ranlib.c:176
+#, c-format
+msgid "cannot stat '%s'"
+msgstr ""
+
+#: src/ar.c:598
+#, c-format
+msgid "cannot read content of %s: %s"
+msgstr ""
+
+#: src/ar.c:641
+#, c-format
+msgid "cannot open %.*s"
+msgstr ""
+
+#: src/ar.c:663
+#, c-format
+msgid "failed to write %s"
+msgstr ""
+
+#: src/ar.c:675
+#, c-format
+msgid "cannot change mode of %s"
+msgstr ""
+
+#: src/ar.c:691
+#, c-format
+msgid "cannot change modification time of %s"
+msgstr ""
+
+#: src/ar.c:737
+#, c-format
+msgid "cannot rename temporary file to %.*s"
+msgstr ""
+
+#: src/ar.c:773 src/ar.c:1021 src/ar.c:1419 src/ranlib.c:250
+#, c-format
+msgid "cannot create new file"
+msgstr ""
+
+#: src/ar.c:1220
+#, c-format
+msgid "position member %s not found"
+msgstr ""
+
+#: src/ar.c:1230
+#, c-format
+msgid "%s: no entry %s in archive!\n"
+msgstr ""
+
+#: src/ar.c:1259 src/ldgeneric.c:519 src/objdump.c:257
+#, c-format
+msgid "cannot open %s"
+msgstr ""
+
+#: src/ar.c:1264
+#, c-format
+msgid "cannot stat %s"
+msgstr ""
+
+#: src/ar.c:1270
+#, c-format
+msgid "%s is no regular file"
+msgstr ""
+
+#: src/ar.c:1283
+#, c-format
+msgid "cannot get ELF descriptor for %s: %s\n"
+msgstr ""
+
+#: src/ar.c:1302
+#, c-format
+msgid "cannot read %s: %s"
+msgstr ""
+
+#: src/arlib.c:215
+#, c-format
+msgid "the archive '%s' is too large"
+msgstr ""
+
+#: src/arlib.c:228
+#, c-format
+msgid "cannot read ELF header of %s(%s): %s"
+msgstr ""
+
+#: src/elfcmp.c:69
+msgid "Control options:"
+msgstr ""
+
+#: src/elfcmp.c:70
+msgid ""
+"Control treatment of gaps in loadable segments [ignore|match] (default: "
+"ignore)"
+msgstr ""
+
+#: src/elfcmp.c:72
+msgid "Ignore permutation of buckets in SHT_HASH section"
+msgstr ""
+
+#: src/elfcmp.c:73
+msgid "Output nothing; yield exit status only"
+msgstr ""
+
+#: src/elfcmp.c:80
+msgid "Compare relevant parts of two ELF files for equality."
+msgstr ""
+
+#: src/elfcmp.c:84
+msgid "FILE1 FILE2"
+msgstr ""
+
+#: src/elfcmp.c:140
+msgid "Invalid number of parameters.\n"
+msgstr ""
+
+#: src/elfcmp.c:168 src/elfcmp.c:173
+#, c-format
+msgid "cannot get ELF header of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:190
+#, c-format
+msgid "%s %s diff: ELF header"
+msgstr ""
+
+#: src/elfcmp.c:198 src/elfcmp.c:201
+#, c-format
+msgid "cannot get section count of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:206
+#, c-format
+msgid "%s %s diff: section count"
+msgstr ""
+
+#: src/elfcmp.c:214 src/elfcmp.c:217
+#, c-format
+msgid "cannot get program header count of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:222
+#, c-format
+msgid "%s %s diff: program header count"
+msgstr ""
+
+#: src/elfcmp.c:281
+#, c-format
+msgid "%s %s differ: section header"
+msgstr ""
+
+#: src/elfcmp.c:309 src/elfcmp.c:315
+#, c-format
+msgid "cannot get content of section %zu in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:331 src/elfcmp.c:337
+#, c-format
+msgid "cannot get symbol in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:358
+#, c-format
+msgid "%s %s differ: symbol table [%zu]"
+msgstr ""
+
+#: src/elfcmp.c:361
+#, c-format
+msgid "%s %s differ: symbol table [%zu,%zu]"
+msgstr ""
+
+#: src/elfcmp.c:409
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:413
+#, c-format
+msgid "%s %s differ: section [%zu,%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:429
+#, c-format
+msgid "%s %s differ: unequal amount of important sections"
+msgstr ""
+
+#: src/elfcmp.c:463 src/elfcmp.c:468
+#, c-format
+msgid "cannot load data of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:487 src/elfcmp.c:493
+#, c-format
+msgid "cannot get program header entry %d of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:499
+#, c-format
+msgid "%s %s differ: program header %d"
+msgstr ""
+
+#: src/elfcmp.c:524
+#, c-format
+msgid "%s %s differ: gap"
+msgstr ""
+
+#: src/elfcmp.c:583
+#, c-format
+msgid "Invalid value '%s' for --gaps parameter."
+msgstr ""
+
+#: src/elfcmp.c:607 src/findtextrel.c:229 src/ldgeneric.c:1767
+#: src/ldgeneric.c:4257 src/nm.c:363 src/ranlib.c:169 src/size.c:301
+#: src/strings.c:183 src/strip.c:433 src/strip.c:468 src/unstrip.c:1900
+#: src/unstrip.c:1929
+#, c-format
+msgid "cannot open '%s'"
+msgstr ""
+
+#: src/elfcmp.c:611 src/findtextrel.c:236 src/ranlib.c:186
+#, c-format
+msgid "cannot create ELF descriptor for '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:616
+#, c-format
+msgid "cannot create EBL descriptor for '%s'"
+msgstr ""
+
+#: src/elfcmp.c:634
+#, c-format
+msgid "cannot get section header of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:644
+#, c-format
+msgid "cannot get content of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:654 src/elfcmp.c:668
+#, c-format
+msgid "cannot get relocation: %s"
+msgstr ""
+
+#: src/elflint.c:72
+msgid "Be extremely strict, flag level 2 features."
+msgstr ""
+
+#: src/elflint.c:73
+msgid "Do not print anything if successful"
+msgstr ""
+
+#: src/elflint.c:74
+msgid "Binary is a separate debuginfo file"
+msgstr ""
+
+#: src/elflint.c:76
+msgid ""
+"Binary has been created with GNU ld and is therefore known to be broken in "
+"certain ways"
+msgstr ""
+
+#: src/elflint.c:82
+msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
+msgstr ""
+
+#: src/elflint.c:86 src/readelf.c:118
+msgid "FILE..."
+msgstr ""
+
+#: src/elflint.c:159 src/readelf.c:272
+#, c-format
+msgid "cannot open input file"
+msgstr ""
+
+#: src/elflint.c:166
+#, c-format
+msgid "cannot generate Elf descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:185
+#, c-format
+msgid "error while closing Elf descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:189
+msgid "No errors"
+msgstr ""
+
+#: src/elflint.c:223 src/readelf.c:425
+msgid "Missing file name.\n"
+msgstr ""
+
+#: src/elflint.c:302
+#, c-format
+msgid " error while freeing sub-ELF descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:310
+#, c-format
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr ""
+
+#: src/elflint.c:370
+#, c-format
+msgid "e_ident[%d] == %d is no known class\n"
+msgstr ""
+
+#: src/elflint.c:375
+#, c-format
+msgid "e_ident[%d] == %d is no known data encoding\n"
+msgstr ""
+
+#: src/elflint.c:379
+#, c-format
+msgid "unknown ELF header version number e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:385
+#, c-format
+msgid "unsupported OS ABI e_ident[%d] == '%s'\n"
+msgstr ""
+
+#: src/elflint.c:391
+#, c-format
+msgid "unsupport ABI version e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:396
+#, c-format
+msgid "e_ident[%zu] is not zero\n"
+msgstr ""
+
+#: src/elflint.c:401
+#, c-format
+msgid "unknown object file type %d\n"
+msgstr ""
+
+#: src/elflint.c:408
+#, c-format
+msgid "unknown machine type %d\n"
+msgstr ""
+
+#: src/elflint.c:412
+#, c-format
+msgid "unknown object file version\n"
+msgstr ""
+
+#: src/elflint.c:418
+#, c-format
+msgid "invalid program header offset\n"
+msgstr ""
+
+#: src/elflint.c:420
+#, c-format
+msgid "executables and DSOs cannot have zero program header offset\n"
+msgstr ""
+
+#: src/elflint.c:424
+#, c-format
+msgid "invalid number of program header entries\n"
+msgstr ""
+
+#: src/elflint.c:432
+#, c-format
+msgid "invalid section header table offset\n"
+msgstr ""
+
+#: src/elflint.c:435
+#, c-format
+msgid "section header table must be present\n"
+msgstr ""
+
+#: src/elflint.c:449
+#, c-format
+msgid "invalid number of section header table entries\n"
+msgstr ""
+
+#: src/elflint.c:466
+#, c-format
+msgid "invalid section header index\n"
+msgstr ""
+
+#: src/elflint.c:480
+#, c-format
+msgid "invalid number of program header table entries\n"
+msgstr ""
+
+#: src/elflint.c:489
+#, c-format
+msgid "invalid machine flags: %s\n"
+msgstr ""
+
+#: src/elflint.c:496 src/elflint.c:513
+#, c-format
+msgid "invalid ELF header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:499 src/elflint.c:516
+#, c-format
+msgid "invalid program header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:502 src/elflint.c:519
+#, c-format
+msgid "invalid program header position or size\n"
+msgstr ""
+
+#: src/elflint.c:505 src/elflint.c:522
+#, c-format
+msgid "invalid section header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:508 src/elflint.c:525
+#, c-format
+msgid "invalid section header position or size\n"
+msgstr ""
+
+#: src/elflint.c:569
+#, c-format
+msgid ""
+"section [%2d] '%s': section with SHF_GROUP flag set not part of a section "
+"group\n"
+msgstr ""
+
+#: src/elflint.c:573
+#, c-format
+msgid ""
+"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"
+msgstr ""
+
+#: src/elflint.c:589 src/elflint.c:1432 src/elflint.c:1482 src/elflint.c:1591
+#: src/elflint.c:2185 src/elflint.c:2699 src/elflint.c:2860 src/elflint.c:2990
+#: src/elflint.c:3162 src/elflint.c:4062
+#, c-format
+msgid "section [%2d] '%s': cannot get section data\n"
+msgstr ""
+
+#: src/elflint.c:602 src/elflint.c:1598
+#, c-format
+msgid ""
+"section [%2d] '%s': referenced as string table for section [%2d] '%s' but "
+"type is not SHT_STRTAB\n"
+msgstr ""
+
+#: src/elflint.c:625
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol table cannot have more than one extended index "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:636
+#, c-format
+msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n"
+msgstr ""
+
+#: src/elflint.c:645
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:650 src/elflint.c:653 src/elflint.c:656 src/elflint.c:659
+#: src/elflint.c:662 src/elflint.c:665
+#, c-format
+msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:668
+#, c-format
+msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:678
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:687
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid name value\n"
+msgstr ""
+
+#: src/elflint.c:700
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: too large section index but no extended "
+"section index section\n"
+msgstr ""
+
+#: src/elflint.c:706
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in "
+"st_shndx (%<PRIu32>)\n"
+msgstr ""
+
+#: src/elflint.c:718
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid section index\n"
+msgstr ""
+
+#: src/elflint.c:726
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown type\n"
+msgstr ""
+
+#: src/elflint.c:732
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown symbol binding\n"
+msgstr ""
+
+#: src/elflint.c:737
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unique symbol not of object type\n"
+msgstr ""
+
+#: src/elflint.c:745
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"
+msgstr ""
+
+#: src/elflint.c:749
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"
+msgstr ""
+
+#: src/elflint.c:753
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"
+msgstr ""
+
+#: src/elflint.c:785
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: st_value out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:791 src/elflint.c:816 src/elflint.c:859
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu does not fit completely in referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:800
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have "
+"SHF_TLS flag set\n"
+msgstr ""
+
+#: src/elflint.c:810 src/elflint.c:852
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:837
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"
+msgstr ""
+
+#: src/elflint.c:845
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:872
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:879
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: non-local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:886
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: non-local section symbol\n"
+msgstr ""
+
+#: src/elflint.c:936
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section [%"
+"2d]\n"
+msgstr ""
+
+#: src/elflint.c:943
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:959
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#<PRIx64> does not "
+"match %s section address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:966
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %<PRIu64> does not "
+"match %s section size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:974
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:990
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC_ symbol value %#<PRIx64> does not match dynamic "
+"segment address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:997
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC symbol size %<PRIu64> does not match dynamic "
+"segment size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:1010
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-"
+"default visibility\n"
+msgstr ""
+
+#: src/elflint.c:1014
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"
+msgstr ""
+
+#: src/elflint.c:1059
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"
+msgstr ""
+
+#: src/elflint.c:1068 src/elflint.c:1120
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"
+msgstr ""
+
+#: src/elflint.c:1093 src/elflint.c:1145
+#, c-format
+msgid ""
+"section [%2d] '%s': relative relocations after index %d as specified by "
+"DT_RELCOUNT\n"
+msgstr ""
+
+#: src/elflint.c:1099 src/elflint.c:1151
+#, c-format
+msgid ""
+"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT "
+"specified %d relative relocations\n"
+msgstr ""
+
+#: src/elflint.c:1111
+#, c-format
+msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n"
+msgstr ""
+
+#: src/elflint.c:1193
+#, c-format
+msgid "section [%2d] '%s': invalid destination section index\n"
+msgstr ""
+
+#: src/elflint.c:1206
+#, c-format
+msgid "section [%2d] '%s': invalid destination section type\n"
+msgstr ""
+
+#: src/elflint.c:1214
+#, c-format
+msgid "section [%2d] '%s': sh_info should be zero\n"
+msgstr ""
+
+#: src/elflint.c:1221
+#, c-format
+msgid "section [%2d] '%s': no relocations for merge-able sections possible\n"
+msgstr ""
+
+#: src/elflint.c:1228
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n"
+msgstr ""
+
+#: src/elflint.c:1288
+#, c-format
+msgid "text relocation flag set but there is no read-only segment\n"
+msgstr ""
+
+#: src/elflint.c:1315
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid type\n"
+msgstr ""
+
+#: src/elflint.c:1323
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: relocation type invalid for the file "
+"type\n"
+msgstr ""
+
+#: src/elflint.c:1331
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n"
+msgstr ""
+
+#: src/elflint.c:1349
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can "
+"be used with %s\n"
+msgstr ""
+
+#: src/elflint.c:1366
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:1381
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: copy relocation against symbol of type %"
+"s\n"
+msgstr ""
+
+#: src/elflint.c:1402
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: read-only section modified but text "
+"relocation flag not set\n"
+msgstr ""
+
+#: src/elflint.c:1417
+#, c-format
+msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n"
+msgstr ""
+
+#: src/elflint.c:1456 src/elflint.c:1506
+#, c-format
+msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1586
+#, c-format
+msgid "more than one dynamic section present\n"
+msgstr ""
+
+#: src/elflint.c:1604
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"
+msgstr ""
+
+#: src/elflint.c:1609 src/elflint.c:1901
+#, c-format
+msgid "section [%2d] '%s': sh_info not zero\n"
+msgstr ""
+
+#: src/elflint.c:1619
+#, c-format
+msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1627
+#, c-format
+msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"
+msgstr ""
+
+#: src/elflint.c:1634
+#, c-format
+msgid "section [%2d] '%s': entry %zu: unknown tag\n"
+msgstr ""
+
+#: src/elflint.c:1645
+#, c-format
+msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n"
+msgstr ""
+
+#: src/elflint.c:1655
+#, c-format
+msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n"
+msgstr ""
+
+#: src/elflint.c:1673
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"
+msgstr ""
+
+#: src/elflint.c:1695
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: pointer does not match address of section [%"
+"2d] '%s' referenced by sh_link\n"
+msgstr ""
+
+#: src/elflint.c:1738
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:1753
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must be valid offset in section [%"
+"2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:1773 src/elflint.c:1801
+#, c-format
+msgid "section [%2d] '%s': contains %s entry but not %s\n"
+msgstr ""
+
+#: src/elflint.c:1785
+#, c-format
+msgid "section [%2d] '%s': mandatory tag %s not present\n"
+msgstr ""
+
+#: src/elflint.c:1794
+#, c-format
+msgid "section [%2d] '%s': no hash section present\n"
+msgstr ""
+
+#: src/elflint.c:1809 src/elflint.c:1816
+#, c-format
+msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n"
+msgstr ""
+
+#: src/elflint.c:1826 src/elflint.c:1830
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"
+msgstr ""
+
+#: src/elflint.c:1836
+#, c-format
+msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n"
+msgstr ""
+
+#: src/elflint.c:1847 src/elflint.c:1851 src/elflint.c:1855 src/elflint.c:1859
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in prelinked executable\n"
+msgstr ""
+
+#: src/elflint.c:1871
+#, c-format
+msgid ""
+"section [%2d] '%s': only relocatable files can have extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1881
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index section not for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1886
+#, c-format
+msgid "cannot get data for symbol section\n"
+msgstr ""
+
+#: src/elflint.c:1889
+#, c-format
+msgid "section [%2d] '%s': entry size does not match Elf32_Word\n"
+msgstr ""
+
+#: src/elflint.c:1896
+#, c-format
+msgid "section [%2d] '%s': extended index table too small for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1911
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to "
+"same symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1922
+#, c-format
+msgid "symbol 0 should have zero extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1934
+#, c-format
+msgid "cannot get data for symbol %zu\n"
+msgstr ""
+
+#: src/elflint.c:1939
+#, c-format
+msgid "extended section index is %<PRIu32> but symbol index is not XINDEX\n"
+msgstr ""
+
+#: src/elflint.c:1955 src/elflint.c:1996
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"
+msgstr ""
+
+#: src/elflint.c:1967 src/elflint.c:2008
+#, c-format
+msgid "section [%2d] '%s': chain array too large\n"
+msgstr ""
+
+#: src/elflint.c:1976 src/elflint.c:2017
+#, c-format
+msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:1982
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2023
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %<PRIu64> out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2038
+#, c-format
+msgid "section [%2d] '%s': bitmask size not power of 2: %u\n"
+msgstr ""
+
+#: src/elflint.c:2049
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected at "
+"least%ld)\n"
+msgstr ""
+
+#: src/elflint.c:2057
+#, c-format
+msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n"
+msgstr ""
+
+#: src/elflint.c:2089
+#, c-format
+msgid ""
+"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"
+msgstr ""
+
+#: src/elflint.c:2110
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is "
+"undefined\n"
+msgstr ""
+
+#: src/elflint.c:2121
+#, c-format
+msgid ""
+"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+
+#: src/elflint.c:2152
+#, c-format
+msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2157
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2163
+#, c-format
+msgid "section [%2d] '%s': bitmask does not match names in the hash table\n"
+msgstr ""
+
+#: src/elflint.c:2176
+#, c-format
+msgid "section [%2d] '%s': relocatable files cannot have hash tables\n"
+msgstr ""
+
+#: src/elflint.c:2194
+#, c-format
+msgid "section [%2d] '%s': hash table not for dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2202
+#, c-format
+msgid "section [%2d] '%s': hash table entry size incorrect\n"
+msgstr ""
+
+#: src/elflint.c:2207
+#, c-format
+msgid "section [%2d] '%s': not marked to be allocated\n"
+msgstr ""
+
+#: src/elflint.c:2212
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table has not even room for initial administrative "
+"entries\n"
+msgstr ""
+
+#: src/elflint.c:2260
+#, c-format
+msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"
+msgstr ""
+
+#: src/elflint.c:2338 src/elflint.c:2342
+#, c-format
+msgid "section [%2zu] '%s': reference to symbol index 0\n"
+msgstr ""
+
+#: src/elflint.c:2349
+#, c-format
+msgid ""
+"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2361
+#, c-format
+msgid ""
+"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2377
+#, c-format
+msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n"
+msgstr ""
+
+#: src/elflint.c:2397
+#, c-format
+msgid ""
+"section [%2d] '%s': section groups only allowed in relocatable object files\n"
+msgstr ""
+
+#: src/elflint.c:2408
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol table: %s\n"
+msgstr ""
+
+#: src/elflint.c:2413
+#, c-format
+msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2419
+#, c-format
+msgid "section [%2d] '%s': invalid symbol index in sh_info\n"
+msgstr ""
+
+#: src/elflint.c:2424
+#, c-format
+msgid "section [%2d] '%s': sh_flags not zero\n"
+msgstr ""
+
+#: src/elflint.c:2431
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol for signature\n"
+msgstr ""
+
+#: src/elflint.c:2436
+#, c-format
+msgid "section [%2d] '%s': signature symbol cannot be empty string\n"
+msgstr ""
+
+#: src/elflint.c:2442
+#, c-format
+msgid "section [%2d] '%s': sh_flags not set correctly\n"
+msgstr ""
+
+#: src/elflint.c:2448
+#, c-format
+msgid "section [%2d] '%s': cannot get data: %s\n"
+msgstr ""
+
+#: src/elflint.c:2457
+#, c-format
+msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"
+msgstr ""
+
+#: src/elflint.c:2462
+#, c-format
+msgid "section [%2d] '%s': section group without flags word\n"
+msgstr ""
+
+#: src/elflint.c:2468
+#, c-format
+msgid "section [%2d] '%s': section group without member\n"
+msgstr ""
+
+#: src/elflint.c:2472
+#, c-format
+msgid "section [%2d] '%s': section group with only one member\n"
+msgstr ""
+
+#: src/elflint.c:2483
+#, c-format
+msgid "section [%2d] '%s': unknown section group flags\n"
+msgstr ""
+
+#: src/elflint.c:2495
+#, c-format
+msgid "section [%2d] '%s': section index %Zu out of range\n"
+msgstr ""
+
+#: src/elflint.c:2504
+#, c-format
+msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:2511
+#, c-format
+msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2517
+#, c-format
+msgid ""
+"section [%2d] '%s': element %Zu references section [%2d] '%s' without "
+"SHF_GROUP flag set\n"
+msgstr ""
+
+#: src/elflint.c:2524
+#, c-format
+msgid "section [%2d] '%s' is contained in more than one section group\n"
+msgstr ""
+
+#: src/elflint.c:2713
+#, c-format
+msgid ""
+"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no "
+"dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2724
+#, c-format
+msgid ""
+"section [%2d] '%s' has different number of entries than symbol table [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:2740
+#, c-format
+msgid "section [%2d] '%s': symbol %d: cannot read version data\n"
+msgstr ""
+
+#: src/elflint.c:2756
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n"
+msgstr ""
+
+#: src/elflint.c:2764
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with version\n"
+msgstr ""
+
+#: src/elflint.c:2778
+#, c-format
+msgid "section [%2d] '%s': symbol %d: invalid version index %d\n"
+msgstr ""
+
+#: src/elflint.c:2783
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for defined version\n"
+msgstr ""
+
+#: src/elflint.c:2793
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for requested version\n"
+msgstr ""
+
+#: src/elflint.c:2845
+#, c-format
+msgid "more than one version reference section present\n"
+msgstr ""
+
+#: src/elflint.c:2853 src/elflint.c:2982
+#, c-format
+msgid "section [%2d] '%s': sh_link does not link to string table\n"
+msgstr ""
+
+#: src/elflint.c:2876 src/elflint.c:3034
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong version %d\n"
+msgstr ""
+
+#: src/elflint.c:2882 src/elflint.c:3040
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:2890
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid file reference\n"
+msgstr ""
+
+#: src/elflint.c:2898
+#, c-format
+msgid "section [%2d] '%s': entry %d references unknown dependency\n"
+msgstr ""
+
+#: src/elflint.c:2910
+#, c-format
+msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:2917
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name "
+"reference\n"
+msgstr ""
+
+#: src/elflint.c:2924
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %"
+"#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:2934
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version "
+"name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2945
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"
+msgstr ""
+
+#: src/elflint.c:2961 src/elflint.c:3119
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n"
+msgstr ""
+
+#: src/elflint.c:2974
+#, c-format
+msgid "more than one version definition section present\n"
+msgstr ""
+
+#: src/elflint.c:3019
+#, c-format
+msgid "section [%2d] '%s': more than one BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3023
+#, c-format
+msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"
+msgstr ""
+
+#: src/elflint.c:3029
+#, c-format
+msgid "section [%2d] '%s': entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:3053
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid name reference\n"
+msgstr ""
+
+#: src/elflint.c:3060
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:3069
+#, c-format
+msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3088
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3103
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3125
+#, c-format
+msgid "section [%2d] '%s': no BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3141
+#, c-format
+msgid "section [%2d] '%s': unknown parent version '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3154
+#, c-format
+msgid "section [%2d] '%s': empty object attributes section\n"
+msgstr ""
+
+#: src/elflint.c:3175
+#, c-format
+msgid "section [%2d] '%s': unrecognized attribute format\n"
+msgstr ""
+
+#: src/elflint.c:3191
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3200
+#, c-format
+msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3212
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n"
+msgstr ""
+
+#: src/elflint.c:3229
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"
+msgstr ""
+
+#: src/elflint.c:3238
+#, c-format
+msgid "section [%2d] '%s': offset %zu: truncated attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3247
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3260
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3271
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3289
+#, c-format
+msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"
+msgstr ""
+
+#: src/elflint.c:3300
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n"
+msgstr ""
+
+#: src/elflint.c:3313
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3317
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: unrecognized %s attribute value %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3327
+#, c-format
+msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n"
+msgstr ""
+
+#: src/elflint.c:3333
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3422
+#, c-format
+msgid "cannot get section header of zeroth section\n"
+msgstr ""
+
+#: src/elflint.c:3426
+#, c-format
+msgid "zeroth section has nonzero name\n"
+msgstr ""
+
+#: src/elflint.c:3428
+#, c-format
+msgid "zeroth section has nonzero type\n"
+msgstr ""
+
+#: src/elflint.c:3430
+#, c-format
+msgid "zeroth section has nonzero flags\n"
+msgstr ""
+
+#: src/elflint.c:3432
+#, c-format
+msgid "zeroth section has nonzero address\n"
+msgstr ""
+
+#: src/elflint.c:3434
+#, c-format
+msgid "zeroth section has nonzero offset\n"
+msgstr ""
+
+#: src/elflint.c:3436
+#, c-format
+msgid "zeroth section has nonzero align value\n"
+msgstr ""
+
+#: src/elflint.c:3438
+#, c-format
+msgid "zeroth section has nonzero entry size value\n"
+msgstr ""
+
+#: src/elflint.c:3441
+#, c-format
+msgid ""
+"zeroth section has nonzero size value while ELF header has nonzero shnum "
+"value\n"
+msgstr ""
+
+#: src/elflint.c:3445
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in shstrndx\n"
+msgstr ""
+
+#: src/elflint.c:3449
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in phnum\n"
+msgstr ""
+
+#: src/elflint.c:3466
+#, c-format
+msgid "cannot get section header for section [%2zu] '%s': %s\n"
+msgstr ""
+
+#: src/elflint.c:3475
+#, c-format
+msgid "section [%2zu]: invalid name\n"
+msgstr ""
+
+#: src/elflint.c:3502
+#, c-format
+msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3518
+#, c-format
+msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3535
+#, c-format
+msgid ""
+"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3553
+#, c-format
+msgid "section [%2zu] '%s' present in object file\n"
+msgstr ""
+
+#: src/elflint.c:3559 src/elflint.c:3591
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"
+msgstr ""
+
+#: src/elflint.c:3564 src/elflint.c:3596
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable "
+"segments\n"
+msgstr ""
+
+#: src/elflint.c:3572
+#, c-format
+msgid ""
+"section [%2zu] '%s' is extension section index table in non-object file\n"
+msgstr ""
+
+#: src/elflint.c:3615
+#, c-format
+msgid "section [%2zu] '%s': size not multiple of entry size\n"
+msgstr ""
+
+#: src/elflint.c:3620
+#, c-format
+msgid "cannot get section header\n"
+msgstr ""
+
+#: src/elflint.c:3630
+#, c-format
+msgid "section [%2zu] '%s' has unsupported type %d\n"
+msgstr ""
+
+#: src/elflint.c:3644
+#, c-format
+msgid ""
+"section [%2zu] '%s' contains invalid processor-specific flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3651
+#, c-format
+msgid "section [%2zu] '%s' contains unknown flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3659
+#, c-format
+msgid "section [%2zu] '%s': thread-local data sections address not zero\n"
+msgstr ""
+
+#: src/elflint.c:3667
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in link value\n"
+msgstr ""
+
+#: src/elflint.c:3672
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in info value\n"
+msgstr ""
+
+#: src/elflint.c:3679
+#, c-format
+msgid "section [%2zu] '%s': strings flag set without merge flag\n"
+msgstr ""
+
+#: src/elflint.c:3684
+#, c-format
+msgid "section [%2zu] '%s': merge flag set but entry size is zero\n"
+msgstr ""
+
+#: src/elflint.c:3702
+#, c-format
+msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n"
+msgstr ""
+
+#: src/elflint.c:3711
+#, c-format
+msgid "section [%2zu] '%s' is both executable and writable\n"
+msgstr ""
+
+#: src/elflint.c:3738
+#, c-format
+msgid ""
+"section [%2zu] '%s' not fully contained in segment of program header entry %"
+"d\n"
+msgstr ""
+
+#: src/elflint.c:3746
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:3755
+#, c-format
+msgid ""
+"section [%2zu] '%s' has not type NOBITS but is not read from the file in "
+"segment of program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:3766
+#, c-format
+msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:3776
+#, c-format
+msgid "section [%2zu] '%s' is writable in unwritable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:3786
+#, c-format
+msgid ""
+"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:3792
+#, c-format
+msgid ""
+"section [%2zu] '%s': ELF header says this is the section header string table "
+"but type is not SHT_TYPE\n"
+msgstr ""
+
+#: src/elflint.c:3800
+#, c-format
+msgid ""
+"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"
+msgstr ""
+
+#: src/elflint.c:3851
+#, c-format
+msgid "more than one version symbol table present\n"
+msgstr ""
+
+#: src/elflint.c:3874
+#, c-format
+msgid "INTERP program header entry but no .interp section\n"
+msgstr ""
+
+#: src/elflint.c:3885
+#, c-format
+msgid ""
+"loadable segment [%u] is executable but contains no executable sections\n"
+msgstr ""
+
+#: src/elflint.c:3891
+#, c-format
+msgid "loadable segment [%u] is writable but contains no writable sections\n"
+msgstr ""
+
+#: src/elflint.c:3902
+#, c-format
+msgid ""
+"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section "
+"exist\n"
+msgstr ""
+
+#: src/elflint.c:3915
+#, c-format
+msgid "duplicate version index %d\n"
+msgstr ""
+
+#: src/elflint.c:3929
+#, c-format
+msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"
+msgstr ""
+
+#: src/elflint.c:3978
+#, c-format
+msgid "phdr[%d]: unknown core file note type %<PRIu32> at offset %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3982
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown core file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4005
+#, c-format
+msgid "phdr[%d]: unknown object file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4009
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown object file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4026
+#, c-format
+msgid "phdr[%d]: no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4045
+#, c-format
+msgid "phdr[%d]: cannot get content of note section: %s\n"
+msgstr ""
+
+#: src/elflint.c:4048
+#, c-format
+msgid "phdr[%d]: extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4069
+#, c-format
+msgid "section [%2d] '%s': no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4076
+#, c-format
+msgid "section [%2d] '%s': cannot get content of note section\n"
+msgstr ""
+
+#: src/elflint.c:4079
+#, c-format
+msgid "section [%2d] '%s': extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4097
+#, c-format
+msgid ""
+"only executables, shared objects, and core files can have program headers\n"
+msgstr ""
+
+#: src/elflint.c:4112
+#, c-format
+msgid "cannot get program header entry %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:4121
+#, c-format
+msgid "program header entry %d: unknown program header entry type %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:4132
+#, c-format
+msgid "more than one INTERP entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4140
+#, c-format
+msgid "more than one TLS entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4147
+#, c-format
+msgid "static executable cannot have dynamic sections\n"
+msgstr ""
+
+#: src/elflint.c:4161
+#, c-format
+msgid "dynamic section reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4164
+#, c-format
+msgid "dynamic section size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4174
+#, c-format
+msgid "more than one GNU_RELRO entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4195
+#, c-format
+msgid "loadable segment GNU_RELRO applies to is not writable\n"
+msgstr ""
+
+#: src/elflint.c:4198
+#, c-format
+msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"
+msgstr ""
+
+#: src/elflint.c:4206 src/elflint.c:4229
+#, c-format
+msgid "%s segment not contained in a loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:4235
+#, c-format
+msgid "program header offset in ELF header and PHDR entry do not match"
+msgstr ""
+
+#: src/elflint.c:4259
+#, c-format
+msgid "call frame search table reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4262
+#, c-format
+msgid "call frame search table size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4275
+#, c-format
+msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"
+msgstr ""
+
+#: src/elflint.c:4283
+#, c-format
+msgid "call frame search table must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4286
+#, c-format
+msgid "section [%2zu] '%s' must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4290
+#, c-format
+msgid "call frame search table must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4293
+#, c-format
+msgid "section [%2zu] '%s' must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4298
+#, c-format
+msgid "call frame search table must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4301
+#, c-format
+msgid "section [%2zu] '%s' must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4312
+#, c-format
+msgid "program header entry %d: file size greater than memory size\n"
+msgstr ""
+
+#: src/elflint.c:4319
+#, c-format
+msgid "program header entry %d: alignment not a power of 2\n"
+msgstr ""
+
+#: src/elflint.c:4322
+#, c-format
+msgid ""
+"program header entry %d: file offset and virtual address not module of "
+"alignment\n"
+msgstr ""
+
+#: src/elflint.c:4335
+#, c-format
+msgid ""
+"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME "
+"program header entry"
+msgstr ""
+
+#: src/elflint.c:4369
+#, c-format
+msgid "cannot read ELF header: %s\n"
+msgstr ""
+
+#: src/elflint.c:4395
+#, c-format
+msgid "text relocation flag set but not needed\n"
+msgstr ""
+
+#: src/findtextrel.c:70
+msgid "Input Selection:"
+msgstr ""
+
+#: src/findtextrel.c:71
+msgid "Prepend PATH to all file names"
+msgstr ""
+
+#: src/findtextrel.c:73
+msgid "Use PATH as root of debuginfo hierarchy"
+msgstr ""
+
+#: src/findtextrel.c:80
+msgid "Locate source of text relocations in FILEs (a.out by default)."
+msgstr ""
+
+#: src/findtextrel.c:84 src/nm.c:111 src/objdump.c:80 src/size.c:92
+#: src/strings.c:92 src/strip.c:97
+msgid "[FILE...]"
+msgstr ""
+
+#: src/findtextrel.c:246
+#, c-format
+msgid "cannot get ELF header '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:257
+#, c-format
+msgid "'%s' is not a DSO or PIE"
+msgstr ""
+
+#: src/findtextrel.c:274
+#, c-format
+msgid "getting get section header of section %zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:292
+#, c-format
+msgid "cannot read dynamic section: %s"
+msgstr ""
+
+#: src/findtextrel.c:307
+#, c-format
+msgid "no text relocations reported in '%s'"
+msgstr ""
+
+#: src/findtextrel.c:319
+#, c-format
+msgid "while reading ELF file"
+msgstr ""
+
+#: src/findtextrel.c:328 src/findtextrel.c:345
+#, c-format
+msgid "cannot get program header index at offset %d: %s"
+msgstr ""
+
+#: src/findtextrel.c:397
+#, c-format
+msgid "cannot get section header of section %Zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:409
+#, c-format
+msgid "cannot get symbol table section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:429 src/findtextrel.c:452
+#, c-format
+msgid "cannot get relocation at index %d in section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:517
+#, c-format
+msgid "%s not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:570
+#, c-format
+msgid ""
+"the file containing the function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:577 src/findtextrel.c:597
+#, c-format
+msgid ""
+"the file containing the function '%s' might not be compiled with -fpic/-"
+"fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:585
+#, c-format
+msgid ""
+"either the file containing the function '%s' or the file containing the "
+"function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:605
+#, c-format
+msgid ""
+"a relocation modifies memory at offset %llu in a write-protected segment\n"
+msgstr ""
+
+#: src/i386_ld.c:210
+#, c-format
+msgid "cannot allocate PLT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:232
+#, c-format
+msgid "cannot allocate PLTREL section: %s"
+msgstr ""
+
+#: src/i386_ld.c:253
+#, c-format
+msgid "cannot allocate GOT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:274
+#, c-format
+msgid "cannot allocate GOTPLT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:661
+#, c-format
+msgid "initial-executable TLS relocation cannot be used "
+msgstr ""
+
+#: src/ld.c:87
+msgid "Input File Control:"
+msgstr ""
+
+#: src/ld.c:89
+msgid "Include whole archives in the output from now on."
+msgstr ""
+
+#: src/ld.c:91
+msgid "Stop including the whole archives in the output."
+msgstr ""
+
+#: src/ld.c:92 src/ld.c:106 src/ld.c:184
+msgid "FILE"
+msgstr ""
+
+#: src/ld.c:93
+msgid "Start a group."
+msgstr ""
+
+#: src/ld.c:94
+msgid "End a group."
+msgstr ""
+
+#: src/ld.c:95
+msgid "PATH"
+msgstr ""
+
+#: src/ld.c:96
+msgid "Add PATH to list of directories files are searched in."
+msgstr ""
+
+#: src/ld.c:98
+msgid "Only set DT_NEEDED for following dynamic libs if actually used"
+msgstr ""
+
+#: src/ld.c:100
+msgid "Always set DT_NEEDED for following dynamic libs"
+msgstr ""
+
+#: src/ld.c:102
+msgid "Ignore LD_LIBRARY_PATH environment variable."
+msgstr ""
+
+#: src/ld.c:105
+msgid "Output File Control:"
+msgstr ""
+
+#: src/ld.c:106
+msgid "Place output in FILE."
+msgstr ""
+
+#: src/ld.c:109
+msgid "Object is marked to not use default search path at runtime."
+msgstr ""
+
+#: src/ld.c:111
+msgid "Same as --whole-archive."
+msgstr ""
+
+#: src/ld.c:112
+msgid ""
+"Default rules of extracting from archive; weak references are not enough."
+msgstr ""
+
+#: src/ld.c:116
+msgid "Weak references cause extraction from archive."
+msgstr ""
+
+#: src/ld.c:118
+msgid "Allow multiple definitions; first is used."
+msgstr ""
+
+#: src/ld.c:120
+msgid "Disallow/allow undefined symbols in DSOs."
+msgstr ""
+
+#: src/ld.c:123
+msgid "Object requires immediate handling of $ORIGIN."
+msgstr ""
+
+#: src/ld.c:125
+msgid "Relocation will not be processed lazily."
+msgstr ""
+
+#: src/ld.c:127
+msgid "Object cannot be unloaded at runtime."
+msgstr ""
+
+#: src/ld.c:129
+msgid "Mark object to be initialized first."
+msgstr ""
+
+#: src/ld.c:131
+msgid "Enable/disable lazy-loading flag for following dependencies."
+msgstr ""
+
+#: src/ld.c:133
+msgid "Mark object as not loadable with 'dlopen'."
+msgstr ""
+
+#: src/ld.c:135
+msgid "Ignore/record dependencies on unused DSOs."
+msgstr ""
+
+#: src/ld.c:137
+msgid "Generated DSO will be a system library."
+msgstr ""
+
+#: src/ld.c:138
+msgid "ADDRESS"
+msgstr ""
+
+#: src/ld.c:138
+msgid "Set entry point address."
+msgstr ""
+
+#: src/ld.c:141
+msgid "Do not link against shared libraries."
+msgstr ""
+
+#: src/ld.c:144
+msgid "Prefer linking against shared libraries."
+msgstr ""
+
+#: src/ld.c:145
+msgid "Export all dynamic symbols."
+msgstr ""
+
+#: src/ld.c:146
+msgid "Strip all symbols."
+msgstr ""
+
+#: src/ld.c:147
+msgid "Strip debugging symbols."
+msgstr ""
+
+#: src/ld.c:149
+msgid "Assume pagesize for the target system to be SIZE."
+msgstr ""
+
+#: src/ld.c:151
+msgid "Set runtime DSO search path."
+msgstr ""
+
+#: src/ld.c:154
+msgid "Set link time DSO search path."
+msgstr ""
+
+#: src/ld.c:155
+msgid "Generate dynamic shared object."
+msgstr ""
+
+#: src/ld.c:156
+msgid "Generate relocatable object."
+msgstr ""
+
+#: src/ld.c:159
+msgid "Causes symbol not assigned to a version be reduced to local."
+msgstr ""
+
+#: src/ld.c:160
+msgid "Remove unused sections."
+msgstr ""
+
+#: src/ld.c:163
+msgid "Don't remove unused sections."
+msgstr ""
+
+#: src/ld.c:164
+msgid "Set soname of shared object."
+msgstr ""
+
+#: src/ld.c:165
+msgid "Set the dynamic linker name."
+msgstr ""
+
+#: src/ld.c:168
+msgid "Add/suppress addition indentifying link-editor to .comment section."
+msgstr ""
+
+#: src/ld.c:171
+msgid "Create .eh_frame_hdr section"
+msgstr ""
+
+#: src/ld.c:173
+msgid "Set hash style to sysv, gnu or both."
+msgstr ""
+
+#: src/ld.c:175
+msgid "Generate build ID note (md5, sha1 (default), uuid)."
+msgstr ""
+
+#: src/ld.c:177
+msgid "Linker Operation Control:"
+msgstr ""
+
+#: src/ld.c:178
+msgid "Verbose messages."
+msgstr ""
+
+#: src/ld.c:179
+msgid "Trace file opens."
+msgstr ""
+
+#: src/ld.c:181
+msgid "Trade speed for less memory usage"
+msgstr ""
+
+#: src/ld.c:182
+msgid "LEVEL"
+msgstr ""
+
+#: src/ld.c:183
+msgid "Set optimization level to LEVEL."
+msgstr ""
+
+#: src/ld.c:184
+msgid "Use linker script in FILE."
+msgstr ""
+
+#: src/ld.c:187
+msgid "Select to get parser debug information"
+msgstr ""
+
+#: src/ld.c:190
+msgid "Read version information from FILE."
+msgstr ""
+
+#: src/ld.c:191
+msgid "Set emulation to NAME."
+msgstr ""
+
+#: src/ld.c:197
+msgid "Combine object and archive files."
+msgstr ""
+
+#: src/ld.c:200
+msgid "[FILE]..."
+msgstr ""
+
+#: src/ld.c:333
+#, c-format
+msgid "At least one input file needed"
+msgstr ""
+
+#: src/ld.c:349
+#, c-format
+msgid "error while preparing linking"
+msgstr ""
+
+#: src/ld.c:356
+#, c-format
+msgid "cannot open linker script '%s'"
+msgstr ""
+
+#: src/ld.c:397
+#, c-format
+msgid "-( without matching -)"
+msgstr ""
+
+#: src/ld.c:572 src/ld.c:610
+#, c-format
+msgid "only one option of -G and -r is allowed"
+msgstr ""
+
+#: src/ld.c:594
+#, c-format
+msgid "more than one '-m' parameter"
+msgstr ""
+
+#: src/ld.c:604 src/ld.c:1013
+#, c-format
+msgid "unknown option `-%c %s'"
+msgstr ""
+
+#: src/ld.c:646
+#, c-format
+msgid "invalid page size value '%s': ignored"
+msgstr ""
+
+#: src/ld.c:687
+#, c-format
+msgid "invalid hash style '%s'"
+msgstr ""
+
+#: src/ld.c:697
+#, c-format
+msgid "invalid build-ID style '%s'"
+msgstr ""
+
+#: src/ld.c:785
+#, c-format
+msgid "More than one output file name given."
+msgstr ""
+
+#: src/ld.c:802
+#, c-format
+msgid "Invalid optimization level `%s'"
+msgstr ""
+
+#: src/ld.c:850
+#, c-format
+msgid "nested -( -) groups are not allowed"
+msgstr ""
+
+#: src/ld.c:869
+#, c-format
+msgid "-) without matching -("
+msgstr ""
+
+#: src/ld.c:1046
+#, c-format
+msgid "unknown option '-%c %s'"
+msgstr ""
+
+#: src/ld.c:1150
+#, c-format
+msgid "could not find input file to determine output file format"
+msgstr ""
+
+#: src/ld.c:1152
+#, c-format
+msgid "try again with an appropriate '-m' parameter"
+msgstr ""
+
+#: src/ld.c:1446
+#, c-format
+msgid "cannot read version script '%s'"
+msgstr ""
+
+#: src/ld.c:1512 src/ld.c:1551
+#, c-format
+msgid "duplicate definition of '%s' in linker script"
+msgstr ""
+
+#: src/ldgeneric.c:209 src/ldgeneric.c:5151
+#, c-format
+msgid "cannot create string table"
+msgstr ""
+
+#: src/ldgeneric.c:255
+#, c-format
+msgid "cannot load ld backend library '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:265
+#, c-format
+msgid "cannot find init function in ld backend library '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:310
+#, c-format
+msgid "%s listed more than once as input"
+msgstr ""
+
+#: src/ldgeneric.c:424
+#, c-format
+msgid "%s (for -l%s)\n"
+msgstr ""
+
+#: src/ldgeneric.c:425
+#, c-format
+msgid "%s (for DT_NEEDED %s)\n"
+msgstr ""
+
+#: src/ldgeneric.c:573
+#, c-format
+msgid "Warning: type of `%s' changed from %s in %s to %s in %s"
+msgstr ""
+
+#: src/ldgeneric.c:586
+#, c-format
+msgid "Warning: size of `%s' changed from %<PRIu64> in %s to %<PRIu64> in %s"
+msgstr ""
+
+#: src/ldgeneric.c:661 src/ldgeneric.c:1122 src/readelf.c:629 src/strip.c:543
+#, c-format
+msgid "cannot determine number of sections: %s"
+msgstr ""
+
+#: src/ldgeneric.c:677
+#, c-format
+msgid "(%s+%#<PRIx64>): multiple definition of %s `%s'\n"
+msgstr ""
+
+#: src/ldgeneric.c:700
+#, c-format
+msgid "(%s+%#<PRIx64>): first defined here\n"
+msgstr ""
+
+#: src/ldgeneric.c:819
+#, c-format
+msgid "%s: cannot get section group data: %s"
+msgstr ""
+
+#: src/ldgeneric.c:840
+#, c-format
+msgid "%s: section '%s' with group flag set does not belong to any group"
+msgstr ""
+
+#: src/ldgeneric.c:885
+#, c-format
+msgid "%s: section [%2d] '%s' is not in the correct section group"
+msgstr ""
+
+#: src/ldgeneric.c:1156 src/ldgeneric.c:1413 src/ldgeneric.c:1422
+#: src/ldgeneric.c:1481 src/ldgeneric.c:1490 src/ldgeneric.c:1753
+#: src/ldgeneric.c:2005
+#, c-format
+msgid "%s: invalid ELF file (%s:%d)\n"
+msgstr ""
+
+#: src/ldgeneric.c:1250
+#, c-format
+msgid "%s: only files of type ET_REL might contain section groups"
+msgstr ""
+
+#: src/ldgeneric.c:1302
+#, c-format
+msgid "%s: cannot determine signature of section group [%2zd] '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:1314
+#, c-format
+msgid "%s: cannot get content of section group [%2zd] '%s': %s'"
+msgstr ""
+
+#: src/ldgeneric.c:1328
+#, c-format
+msgid ""
+"%s: group member %zu of section group [%2zd] '%s' has too high index: %"
+"<PRIu32>"
+msgstr ""
+
+#: src/ldgeneric.c:1350
+#, c-format
+msgid "%s: section '%s' has unknown type: %d"
+msgstr ""
+
+#: src/ldgeneric.c:1729
+#, c-format
+msgid "cannot get descriptor for ELF file (%s:%d): %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:1899
+#, c-format
+msgid "cannot read archive `%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:2020
+#, c-format
+msgid "file of type %s cannot be linked in\n"
+msgstr ""
+
+#: src/ldgeneric.c:2032
+#, c-format
+msgid "%s: input file incompatible with ELF machine type %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:2044
+#, c-format
+msgid "%s: cannot get section header string table index: %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:2073
+#, c-format
+msgid "cannot use DSO '%s' when generating relocatable object file"
+msgstr ""
+
+#: src/ldgeneric.c:2158
+#, c-format
+msgid "input file '%s' ignored"
+msgstr ""
+
+#: src/ldgeneric.c:2372
+#, c-format
+msgid "undefined symbol `%s' in %s"
+msgstr ""
+
+#: src/ldgeneric.c:2702
+#, c-format
+msgid "cannot create ELF descriptor for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:2709
+#, c-format
+msgid "could not create ELF header for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:3224 src/ldgeneric.c:3294 src/ldgeneric.c:3330
+#: src/ldgeneric.c:4457 src/ldgeneric.c:4506 src/ldgeneric.c:4538
+#: src/ldgeneric.c:4773 src/ldgeneric.c:4828 src/ldgeneric.c:5075
+#: src/ldgeneric.c:5131 src/ldgeneric.c:5600 src/ldgeneric.c:5612
+#, c-format
+msgid "cannot create section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:3444
+#, c-format
+msgid "address computation expression contains variable '%s'"
+msgstr ""
+
+#: src/ldgeneric.c:3489
+#, c-format
+msgid ""
+"argument '%<PRIuMAX>' of ALIGN in address computation expression is no power "
+"of two"
+msgstr ""
+
+#: src/ldgeneric.c:3684
+#, c-format
+msgid "cannot find entry symbol '%s': defaulting to %#0*<PRIx64>"
+msgstr ""
+
+#: src/ldgeneric.c:3690
+#, c-format
+msgid "no entry symbol specified: defaulting to %#0*<PRIx64>"
+msgstr ""
+
+#: src/ldgeneric.c:3920
+#, c-format
+msgid "cannot create GNU hash table section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4071
+#, c-format
+msgid "cannot create hash table section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4114
+#, c-format
+msgid "cannot create build ID section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4191
+#, c-format
+msgid "cannot convert section data to file format: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4200
+#, c-format
+msgid "cannot convert section data to memory format: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4261
+#, c-format
+msgid "cannot read enough data for UUID"
+msgstr ""
+
+#: src/ldgeneric.c:4358 src/ldgeneric.c:4379 src/ldgeneric.c:4408
+#: src/ldgeneric.c:6062
+#, c-format
+msgid "cannot create symbol table for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5300 src/ldgeneric.c:5852
+#, c-format
+msgid "section index too large in dynamic symbol table"
+msgstr ""
+
+#: src/ldgeneric.c:5745
+#, c-format
+msgid "cannot create versioning section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5818
+#, c-format
+msgid "cannot create dynamic symbol table for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5994
+#, c-format
+msgid "cannot create versioning data: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6094 src/ldgeneric.c:6107 src/ldgeneric.c:6171
+#: src/ldgeneric.c:6179
+#, c-format
+msgid "cannot create section header string section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6101
+#, c-format
+msgid "cannot create section header string section"
+msgstr ""
+
+#: src/ldgeneric.c:6259
+#, c-format
+msgid "cannot create program header: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6267
+#, c-format
+msgid "while determining file layout: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6388
+#, c-format
+msgid "internal error: non-nobits section follows nobits section"
+msgstr ""
+
+#: src/ldgeneric.c:6925
+#, c-format
+msgid "cannot get header of 0th section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6941 src/unstrip.c:1808
+#, c-format
+msgid "cannot update ELF header: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6972
+#, c-format
+msgid "linker backend didn't specify function to relocate section"
+msgstr ""
+
+#: src/ldgeneric.c:6984
+#, c-format
+msgid "while writing output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6989
+#, c-format
+msgid "while finishing output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6995
+#, c-format
+msgid "cannot stat output file"
+msgstr ""
+
+#: src/ldgeneric.c:7011
+#, c-format
+msgid "WARNING: temporary output file overwritten before linking finished"
+msgstr ""
+
+#: src/ldgeneric.c:7064 src/ldgeneric.c:7075 src/ldgeneric.c:7086
+#: src/ldgeneric.c:7097 src/ldgeneric.c:7116 src/ldgeneric.c:7129
+#: src/ldgeneric.c:7141
+#, c-format
+msgid "no machine specific '%s' implementation"
+msgstr ""
+
+#: src/ldscript.y:178
+msgid "mode for segment invalid\n"
+msgstr ""
+
+#: src/ldscript.y:465
+#, c-format
+msgid "while reading version script '%s': %s at line %d"
+msgstr ""
+
+#: src/ldscript.y:466
+#, c-format
+msgid "while reading linker script '%s': %s at line %d"
+msgstr ""
+
+#: src/ldscript.y:745
+#, c-format
+msgid "symbol '%s' is declared both local and global for unnamed version"
+msgstr ""
+
+#: src/ldscript.y:747
+#, c-format
+msgid "symbol '%s' is declared both local and global for version '%s'"
+msgstr ""
+
+#: src/ldscript.y:767 src/ldscript.y:774
+#, c-format
+msgid "default visibility set as local and global"
+msgstr ""
+
+#: src/nm.c:74 src/strip.c:73
+msgid "Output selection:"
+msgstr ""
+
+#: src/nm.c:75
+msgid "Display debugger-only symbols"
+msgstr ""
+
+#: src/nm.c:76
+msgid "Display only defined symbols"
+msgstr ""
+
+#: src/nm.c:79
+msgid "Display dynamic symbols instead of normal symbols"
+msgstr ""
+
+#: src/nm.c:80
+msgid "Display only external symbols"
+msgstr ""
+
+#: src/nm.c:81
+msgid "Display only undefined symbols"
+msgstr ""
+
+#: src/nm.c:83
+msgid "Include index for symbols from archive members"
+msgstr ""
+
+#: src/nm.c:85 src/size.c:66
+msgid "Output format:"
+msgstr ""
+
+#: src/nm.c:87
+msgid "Print name of the input file before every symbol"
+msgstr ""
+
+#: src/nm.c:90
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd', `sysv' or `posix'.  The "
+"default is `sysv'"
+msgstr ""
+
+#: src/nm.c:92
+msgid "Same as --format=bsd"
+msgstr ""
+
+#: src/nm.c:93
+msgid "Same as --format=posix"
+msgstr ""
+
+#: src/nm.c:94 src/size.c:72
+msgid "Use RADIX for printing symbol values"
+msgstr ""
+
+#: src/nm.c:95
+msgid "Mark weak symbols"
+msgstr ""
+
+#: src/nm.c:96
+msgid "Print size of defined symbols"
+msgstr ""
+
+#: src/nm.c:98 src/size.c:80 src/strip.c:78 src/unstrip.c:81
+msgid "Output options:"
+msgstr ""
+
+#: src/nm.c:99
+msgid "Sort symbols numerically by address"
+msgstr ""
+
+#: src/nm.c:101
+msgid "Do not sort the symbols"
+msgstr ""
+
+#: src/nm.c:102
+msgid "Reverse the sense of the sort"
+msgstr ""
+
+#: src/nm.c:108
+msgid "List symbols from FILEs (a.out by default)."
+msgstr ""
+
+#: src/nm.c:136 src/objdump.c:105 src/size.c:117 src/strip.c:121
+#, c-format
+msgid "%s: INTERNAL ERROR %d (%s-%s): %s"
+msgstr ""
+
+#: src/nm.c:380 src/nm.c:392 src/size.c:317 src/size.c:326 src/size.c:337
+#: src/strip.c:1816
+#, c-format
+msgid "while closing '%s'"
+msgstr ""
+
+#: src/nm.c:402 src/objdump.c:296 src/strip.c:359
+#, c-format
+msgid "%s: File format not recognized"
+msgstr ""
+
+#: src/nm.c:442
+msgid ""
+"\n"
+"Archive index:"
+msgstr ""
+
+#: src/nm.c:451
+#, c-format
+msgid "invalid offset %zu for symbol %s"
+msgstr ""
+
+#: src/nm.c:456
+#, c-format
+msgid "%s in %s\n"
+msgstr ""
+
+#: src/nm.c:464
+#, c-format
+msgid "cannot reset archive offset to beginning"
+msgstr ""
+
+#: src/nm.c:488 src/objdump.c:344
+#, c-format
+msgid "%s%s%s: file format not recognized"
+msgstr ""
+
+#: src/nm.c:700
+#, c-format
+msgid "cannot create search tree"
+msgstr ""
+
+#: src/nm.c:740 src/nm.c:1002 src/objdump.c:744 src/readelf.c:885
+#: src/readelf.c:1028 src/readelf.c:1169 src/readelf.c:1351 src/readelf.c:1549
+#: src/readelf.c:1735 src/readelf.c:1945 src/readelf.c:2199 src/readelf.c:2265
+#: src/readelf.c:2343 src/readelf.c:2841 src/readelf.c:2877 src/readelf.c:2939
+#: src/readelf.c:6493 src/readelf.c:7387 src/readelf.c:7534 src/readelf.c:7604
+#: src/size.c:425 src/size.c:499 src/strip.c:483
+#, c-format
+msgid "cannot get section header string table index"
+msgstr ""
+
+#: src/nm.c:766
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s:\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:768
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s[%s]:\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:771
+#, c-format
+msgid ""
+"%*s%-*s %-*s Class  Type     %-*s %*s Section\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:1012
+#, c-format
+msgid "%s: entry size in section `%s' is not what we expect"
+msgstr ""
+
+#: src/nm.c:1016
+#, c-format
+msgid "%s: size of section `%s' is not multiple of entry size"
+msgstr ""
+
+#: src/nm.c:1255
+#, c-format
+msgid "%s%s%s%s: Invalid operation"
+msgstr ""
+
+#: src/nm.c:1312
+#, c-format
+msgid "%s%s%s: no symbols"
+msgstr ""
+
+#: src/objdump.c:61
+msgid "Mode selection:"
+msgstr ""
+
+#: src/objdump.c:62
+msgid "Display relocation information."
+msgstr ""
+
+#: src/objdump.c:64
+msgid "Display the full contents of all sections requested"
+msgstr ""
+
+#: src/objdump.c:66
+msgid "Display assembler code of executable sections"
+msgstr ""
+
+#: src/objdump.c:68
+msgid "Output option selection:"
+msgstr ""
+
+#: src/objdump.c:70
+msgid "Only display information for section NAME."
+msgstr ""
+
+#: src/objdump.c:76
+msgid "Show information from FILEs (a.out by default)."
+msgstr ""
+
+#: src/objdump.c:236 src/readelf.c:430
+msgid "No operation specified.\n"
+msgstr ""
+
+#: src/objdump.c:274 src/objdump.c:286
+#, c-format
+msgid "while close `%s'"
+msgstr ""
+
+#: src/objdump.c:379 src/readelf.c:1644 src/readelf.c:1818
+msgid "INVALID SYMBOL"
+msgstr ""
+
+#: src/objdump.c:394 src/readelf.c:1675 src/readelf.c:1851
+msgid "INVALID SECTION"
+msgstr ""
+
+#: src/objdump.c:510
+#, c-format
+msgid ""
+"\n"
+"RELOCATION RECORDS FOR [%s]:\n"
+"%-*s TYPE                 VALUE\n"
+msgstr ""
+
+#: src/objdump.c:513
+msgid "OFFSET"
+msgstr ""
+
+#: src/objdump.c:576
+#, c-format
+msgid "Contents of section %s:\n"
+msgstr ""
+
+#: src/objdump.c:676
+#, c-format
+msgid "cannot disassemble"
+msgstr ""
+
+#: src/ranlib.c:74
+msgid "Generate an index to speed access to archives."
+msgstr ""
+
+#: src/ranlib.c:77
+msgid "ARCHIVE"
+msgstr ""
+
+#: src/ranlib.c:116
+#, c-format
+msgid "Archive name required"
+msgstr ""
+
+#: src/ranlib.c:194
+#, c-format
+msgid "'%s' is no archive"
+msgstr ""
+
+#: src/ranlib.c:229
+#, c-format
+msgid "error while freeing sub-ELF descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:73
+msgid "ELF output selection:"
+msgstr ""
+
+#: src/readelf.c:75
+msgid "All these plus -p .strtab -p .dynstr -p .comment"
+msgstr ""
+
+#: src/readelf.c:76
+msgid "Display the dynamic segment"
+msgstr ""
+
+#: src/readelf.c:77
+msgid "Display the ELF file header"
+msgstr ""
+
+#: src/readelf.c:79
+msgid "Display histogram of bucket list lengths"
+msgstr ""
+
+#: src/readelf.c:80
+msgid "Display the program headers"
+msgstr ""
+
+#: src/readelf.c:82
+msgid "Display relocations"
+msgstr ""
+
+#: src/readelf.c:83
+msgid "Display the sections' headers"
+msgstr ""
+
+#: src/readelf.c:85
+msgid "Display the symbol table"
+msgstr ""
+
+#: src/readelf.c:86
+msgid "Display versioning information"
+msgstr ""
+
+#: src/readelf.c:87
+msgid "Display the ELF notes"
+msgstr ""
+
+#: src/readelf.c:89
+msgid "Display architecture specific information, if any"
+msgstr ""
+
+#: src/readelf.c:91
+msgid "Display sections for exception handling"
+msgstr ""
+
+#: src/readelf.c:93
+msgid "Additional output selection:"
+msgstr ""
+
+#: src/readelf.c:95
+msgid ""
+"Display DWARF section content.  SECTION can be one of abbrev, aranges, "
+"frame, info, loc, line, ranges, pubnames, str, macinfo, or exception"
+msgstr ""
+
+#: src/readelf.c:99
+msgid "Dump the uninterpreted contents of SECTION, by number or name"
+msgstr ""
+
+#: src/readelf.c:101
+msgid "Print string contents of sections"
+msgstr ""
+
+#: src/readelf.c:104
+msgid "Display the symbol index of an archive"
+msgstr ""
+
+#: src/readelf.c:106
+msgid "Output control:"
+msgstr ""
+
+#: src/readelf.c:108
+msgid "Do not find symbol names for addresses in DWARF data"
+msgstr ""
+
+#: src/readelf.c:114
+msgid "Print information from ELF file in human-readable form."
+msgstr ""
+
+#: src/readelf.c:401
+#, c-format
+msgid "Unknown DWARF debug section `%s'.\n"
+msgstr ""
+
+#: src/readelf.c:465
+#, c-format
+msgid "cannot generate Elf descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:477
+#, c-format
+msgid "'%s' is not an archive, cannot print archive index"
+msgstr ""
+
+#: src/readelf.c:482
+#, c-format
+msgid "error while closing Elf descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:574
+#, c-format
+msgid "cannot stat input file"
+msgstr ""
+
+#: src/readelf.c:576
+#, c-format
+msgid "input file is empty"
+msgstr ""
+
+#: src/readelf.c:578
+#, c-format
+msgid "failed reading '%s': %s"
+msgstr ""
+
+#: src/readelf.c:614
+#, c-format
+msgid "cannot read ELF header: %s"
+msgstr ""
+
+#: src/readelf.c:622
+#, c-format
+msgid "cannot create EBL handle"
+msgstr ""
+
+#: src/readelf.c:635
+#, c-format
+msgid "cannot determine number of program headers: %s"
+msgstr ""
+
+#: src/readelf.c:721
+msgid "NONE (None)"
+msgstr ""
+
+#: src/readelf.c:722
+msgid "REL (Relocatable file)"
+msgstr ""
+
+#: src/readelf.c:723
+msgid "EXEC (Executable file)"
+msgstr ""
+
+#: src/readelf.c:724
+msgid "DYN (Shared object file)"
+msgstr ""
+
+#: src/readelf.c:725
+msgid "CORE (Core file)"
+msgstr ""
+
+#: src/readelf.c:730
+#, c-format
+msgid "OS Specific: (%x)\n"
+msgstr ""
+
+#: src/readelf.c:732
+#, c-format
+msgid "Processor Specific: (%x)\n"
+msgstr ""
+
+#: src/readelf.c:742
+msgid ""
+"ELF Header:\n"
+"  Magic:  "
+msgstr ""
+
+#: src/readelf.c:746
+#, c-format
+msgid ""
+"\n"
+"  Class:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:751
+#, c-format
+msgid "  Data:                              %s\n"
+msgstr ""
+
+#: src/readelf.c:757
+#, c-format
+msgid "  Ident Version:                     %hhd %s\n"
+msgstr ""
+
+#: src/readelf.c:759 src/readelf.c:776
+msgid "(current)"
+msgstr ""
+
+#: src/readelf.c:763
+#, c-format
+msgid "  OS/ABI:                            %s\n"
+msgstr ""
+
+#: src/readelf.c:766
+#, c-format
+msgid "  ABI Version:                       %hhd\n"
+msgstr ""
+
+#: src/readelf.c:769
+msgid "  Type:                              "
+msgstr ""
+
+#: src/readelf.c:772
+#, c-format
+msgid "  Machine:                           %s\n"
+msgstr ""
+
+#: src/readelf.c:774
+#, c-format
+msgid "  Version:                           %d %s\n"
+msgstr ""
+
+#: src/readelf.c:778
+#, c-format
+msgid "  Entry point address:               %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:781
+#, c-format
+msgid "  Start of program headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:782 src/readelf.c:785
+msgid "(bytes into file)"
+msgstr ""
+
+#: src/readelf.c:784
+#, c-format
+msgid "  Start of section headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:787
+#, c-format
+msgid "  Flags:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:790
+#, c-format
+msgid "  Size of this header:               %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:791 src/readelf.c:794 src/readelf.c:811
+msgid "(bytes)"
+msgstr ""
+
+#: src/readelf.c:793
+#, c-format
+msgid "  Size of program header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:796
+#, c-format
+msgid "  Number of program headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:803
+#, c-format
+msgid " (%<PRIu32> in [0].sh_info)"
+msgstr ""
+
+#: src/readelf.c:806 src/readelf.c:823 src/readelf.c:837
+msgid " ([0] not available)"
+msgstr ""
+
+#: src/readelf.c:810
+#, c-format
+msgid "  Size of section header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:813
+#, c-format
+msgid "  Number of section headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:820
+#, c-format
+msgid " (%<PRIu32> in [0].sh_size)"
+msgstr ""
+
+#: src/readelf.c:833
+#, c-format
+msgid " (%<PRIu32> in [0].sh_link)"
+msgstr ""
+
+#: src/readelf.c:841
+#, c-format
+msgid ""
+"  Section header string table index: XINDEX%s\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:845
+#, c-format
+msgid ""
+"  Section header string table index: %<PRId16>\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:877
+#, c-format
+msgid ""
+"There are %d section headers, starting at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:887
+msgid "Section Headers:"
+msgstr ""
+
+#: src/readelf.c:890
+msgid ""
+"[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
+"Inf Al"
+msgstr ""
+
+#: src/readelf.c:892
+msgid ""
+"[Nr] Name                 Type         Addr             Off      Size     ES "
+"Flags Lk Inf Al"
+msgstr ""
+
+#: src/readelf.c:899 src/readelf.c:1052
+#, c-format
+msgid "cannot get section: %s"
+msgstr ""
+
+#: src/readelf.c:906 src/readelf.c:1060 src/readelf.c:7554 src/unstrip.c:353
+#: src/unstrip.c:377 src/unstrip.c:427 src/unstrip.c:536 src/unstrip.c:553
+#: src/unstrip.c:591 src/unstrip.c:789 src/unstrip.c:1057 src/unstrip.c:1244
+#: src/unstrip.c:1305 src/unstrip.c:1427 src/unstrip.c:1480 src/unstrip.c:1588
+#: src/unstrip.c:1778
+#, c-format
+msgid "cannot get section header: %s"
+msgstr ""
+
+#: src/readelf.c:964
+msgid "Program Headers:"
+msgstr ""
+
+#: src/readelf.c:966
+msgid ""
+"  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:969
+msgid ""
+"  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
+"MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:1009
+#, c-format
+msgid "\t[Requesting program interpreter: %s]\n"
+msgstr ""
+
+#: src/readelf.c:1030
+msgid ""
+"\n"
+" Section to Segment mapping:\n"
+"  Segment Sections..."
+msgstr ""
+
+#: src/readelf.c:1041 src/unstrip.c:1824 src/unstrip.c:1863 src/unstrip.c:1870
+#, c-format
+msgid "cannot get program header: %s"
+msgstr ""
+
+#: src/readelf.c:1175
+#, c-format
+msgid ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1180
+#, c-format
+msgid ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1188
+msgid "<INVALID SYMBOL>"
+msgstr ""
+
+#: src/readelf.c:1202
+msgid "<INVALID SECTION>"
+msgstr ""
+
+#: src/readelf.c:1353
+#, c-format
+msgid ""
+"\n"
+"Dynamic segment contains %lu entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Dynamic segment contains %lu entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1365
+msgid "  Type              Value\n"
+msgstr ""
+
+#: src/readelf.c:1389
+#, c-format
+msgid "Shared library: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1394
+#, c-format
+msgid "Library soname: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1399
+#, c-format
+msgid "Library rpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1404
+#, c-format
+msgid "Library runpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1424
+#, c-format
+msgid "%<PRId64> (bytes)\n"
+msgstr ""
+
+#: src/readelf.c:1534 src/readelf.c:1720
+#, c-format
+msgid ""
+"\n"
+"Invalid symbol table at offset %#0<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:1552 src/readelf.c:1737
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1567
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1577
+msgid "  Offset      Type                 Value       Name\n"
+msgstr ""
+
+#: src/readelf.c:1579
+msgid "  Offset              Type                 Value               Name\n"
+msgstr ""
+
+#: src/readelf.c:1632 src/readelf.c:1643 src/readelf.c:1656 src/readelf.c:1674
+#: src/readelf.c:1686 src/readelf.c:1805 src/readelf.c:1817 src/readelf.c:1831
+#: src/readelf.c:1850 src/readelf.c:1863
+msgid "<INVALID RELOC>"
+msgstr ""
+
+#: src/readelf.c:1749
+msgid "  Offset      Type            Value       Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:1751
+msgid "  Offset              Type            Value               Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:1952
+#, c-format
+msgid ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entry:\n"
+msgid_plural ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1958
+#, c-format
+msgid " %lu local symbol  String table: [%2u] '%s'\n"
+msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1968
+msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:1970
+msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:1990
+#, c-format
+msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+msgstr ""
+
+#: src/readelf.c:2078
+#, c-format
+msgid "bad dynamic symbol"
+msgstr ""
+
+#: src/readelf.c:2160
+msgid "none"
+msgstr ""
+
+#: src/readelf.c:2177
+msgid "| <unknown>"
+msgstr ""
+
+#: src/readelf.c:2202
+#, c-format
+msgid ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2225
+#, c-format
+msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
+msgstr ""
+
+#: src/readelf.c:2238
+#, c-format
+msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
+msgstr ""
+
+#: src/readelf.c:2269
+#, c-format
+msgid ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2299
+#, c-format
+msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
+msgstr ""
+
+#: src/readelf.c:2314
+#, c-format
+msgid "  %#06x: Parent %d: %s\n"
+msgstr ""
+
+#: src/readelf.c:2546
+#, c-format
+msgid ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgid_plural ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2576
+msgid "   0 *local*                     "
+msgstr ""
+
+#: src/readelf.c:2581
+msgid "   1 *global*                    "
+msgstr ""
+
+#: src/readelf.c:2612
+#, c-format
+msgid ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"bucket):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"buckets):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2636
+#, no-c-format
+msgid " Length  Number  % of total  Coverage\n"
+msgstr ""
+
+#: src/readelf.c:2638
+#, c-format
+msgid "      0  %6<PRIu32>      %5.1f%%\n"
+msgstr ""
+
+#: src/readelf.c:2645
+#, c-format
+msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+msgstr ""
+
+#: src/readelf.c:2658
+#, c-format
+msgid ""
+" Average number of tests:   successful lookup: %f\n"
+"                          unsuccessful lookup: %f\n"
+msgstr ""
+
+#: src/readelf.c:2676 src/readelf.c:2718 src/readelf.c:2759
+#, c-format
+msgid "cannot get data for section %d: %s"
+msgstr ""
+
+#: src/readelf.c:2813
+#, c-format
+msgid ""
+" Symbol Bias: %u\n"
+" Bitmask Size: %zu bytes  %<PRIuFAST32>%% bits set  2nd hash shift: %u\n"
+msgstr ""
+
+#: src/readelf.c:2887
+#, c-format
+msgid ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2901
+msgid ""
+"       Library                       Time Stamp          Checksum Version "
+"Flags"
+msgstr ""
+
+#: src/readelf.c:2951
+#, c-format
+msgid ""
+"\n"
+"Object attributes section [%2zu] '%s' of %<PRIu64> bytes at offset %"
+"#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:2967
+msgid "  Owner          Size\n"
+msgstr ""
+
+#: src/readelf.c:2993
+#, c-format
+msgid "  %-13s  %4<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3025
+#, c-format
+msgid "    %-4u %12<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3030
+#, c-format
+msgid "    File: %11<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3065
+#, c-format
+msgid "      %s: %<PRId64>, %s\n"
+msgstr ""
+
+#: src/readelf.c:3068
+#, c-format
+msgid "      %s: %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:3071
+#, c-format
+msgid "      %s: %s\n"
+msgstr ""
+
+#: src/readelf.c:3078
+#, c-format
+msgid "      %u: %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:3081
+#, c-format
+msgid "      %u: %s\n"
+msgstr ""
+
+#: src/readelf.c:3117
+#, c-format
+msgid "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3120
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3125
+#, c-format
+msgid "%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3128
+#, c-format
+msgid "%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3134
+#, c-format
+msgid "%s+%#<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3137
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3141
+#, c-format
+msgid "%#<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3144
+#, c-format
+msgid "%#0*<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3149
+#, c-format
+msgid "%s+%#<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3152
+#, c-format
+msgid "%s+%#0*<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3260
+#, c-format
+msgid "unknown tag %hx"
+msgstr ""
+
+#: src/readelf.c:3262
+#, c-format
+msgid "unknown user tag %hx"
+msgstr ""
+
+#: src/readelf.c:3480
+#, c-format
+msgid "unknown attribute %hx"
+msgstr ""
+
+#: src/readelf.c:3483
+#, c-format
+msgid "unknown user attribute %hx"
+msgstr ""
+
+#: src/readelf.c:3529
+#, c-format
+msgid "unknown form %<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3763
+msgid "empty block"
+msgstr ""
+
+#: src/readelf.c:3766
+#, c-format
+msgid "%zu byte block:"
+msgstr ""
+
+#: src/readelf.c:4175
+#, c-format
+msgid "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+msgstr ""
+
+#: src/readelf.c:4188
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [ Code]\n"
+msgstr ""
+
+#: src/readelf.c:4195
+#, c-format
+msgid ""
+"\n"
+"Abbreviation section at offset %<PRIu64>:\n"
+msgstr ""
+
+#: src/readelf.c:4208
+#, c-format
+msgid " *** error while reading abbreviation: %s\n"
+msgstr ""
+
+#: src/readelf.c:4224
+#, c-format
+msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
+msgstr ""
+
+#: src/readelf.c:4227
+msgid "yes"
+msgstr ""
+
+#: src/readelf.c:4227
+msgid "no"
+msgstr ""
+
+#: src/readelf.c:4263
+#, c-format
+msgid "cannot get .debug_aranges content: %s"
+msgstr ""
+
+#: src/readelf.c:4268
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:4298
+#, c-format
+msgid " [%*zu] ???\n"
+msgstr ""
+
+#: src/readelf.c:4300
+#, c-format
+msgid ""
+" [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:4319
+#, c-format
+msgid "cannot get .debug_ranges content: %s"
+msgstr ""
+
+#: src/readelf.c:4324 src/readelf.c:4810 src/readelf.c:5452 src/readelf.c:5897
+#: src/readelf.c:5992 src/readelf.c:6164
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:4338 src/readelf.c:5911
+#, c-format
+msgid " [%6tx]  <INVALID DATA>\n"
+msgstr ""
+
+#: src/readelf.c:4360 src/readelf.c:5933
+#, c-format
+msgid " [%6tx]  base address %s\n"
+msgstr ""
+
+#: src/readelf.c:4371
+#, c-format
+msgid " [%6tx]  %s..%s\n"
+msgstr ""
+
+#: src/readelf.c:4373
+#, c-format
+msgid "           %s..%s\n"
+msgstr ""
+
+#: src/readelf.c:4799 src/readelf.c:6230 src/readelf.c:6332
+#, c-format
+msgid "cannot get %s content: %s"
+msgstr ""
+
+#: src/readelf.c:4806
+#, c-format
+msgid ""
+"\n"
+"Call frame information section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:4833 src/readelf.c:5486
+#, c-format
+msgid "invalid data in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:4855
+#, c-format
+msgid ""
+"\n"
+" [%6tx] Zero terminator\n"
+msgstr ""
+
+#: src/readelf.c:4924
+#, c-format
+msgid "invalid augmentation length"
+msgstr ""
+
+#: src/readelf.c:4936
+msgid "FDE address encoding: "
+msgstr ""
+
+#: src/readelf.c:4942
+msgid "LSDA pointer encoding: "
+msgstr ""
+
+#: src/readelf.c:5034
+#, c-format
+msgid " (offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5041
+#, c-format
+msgid " (end offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5068
+#, c-format
+msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:5114
+#, c-format
+msgid "cannot get attribute code: %s"
+msgstr ""
+
+#: src/readelf.c:5122
+#, c-format
+msgid "cannot get attribute form: %s"
+msgstr ""
+
+#: src/readelf.c:5135
+#, c-format
+msgid "cannot get attribute value: %s"
+msgstr ""
+
+#: src/readelf.c:5331
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [Offset]\n"
+msgstr ""
+
+#: src/readelf.c:5356
+#, c-format
+msgid ""
+" Compilation unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: %"
+"<PRIu8>, Offset size: %<PRIu8>\n"
+msgstr ""
+
+#: src/readelf.c:5374
+#, c-format
+msgid "cannot get DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:5385
+#, c-format
+msgid "cannot get DIE offset: %s"
+msgstr ""
+
+#: src/readelf.c:5393
+#, c-format
+msgid "cannot get tag of DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:5422
+#, c-format
+msgid "cannot get next DIE: %s\n"
+msgstr ""
+
+#: src/readelf.c:5429
+#, c-format
+msgid "cannot get next DIE: %s"
+msgstr ""
+
+#: src/readelf.c:5464
+#, c-format
+msgid "cannot get line data section data: %s"
+msgstr ""
+
+#: src/readelf.c:5477
+#, c-format
+msgid ""
+"\n"
+"Table at offset %Zu:\n"
+msgstr ""
+
+#: src/readelf.c:5529
+#, c-format
+msgid ""
+"\n"
+" Length:                     %<PRIu64>\n"
+" DWARF version:              %<PRIuFAST16>\n"
+" Prologue length:            %<PRIu64>\n"
+" Minimum instruction length: %<PRIuFAST8>\n"
+" Initial value if '%s': %<PRIuFAST8>\n"
+" Line base:                  %<PRIdFAST8>\n"
+" Line range:                 %<PRIuFAST8>\n"
+" Opcode base:                %<PRIuFAST8>\n"
+"\n"
+"Opcodes:\n"
+msgstr ""
+
+#: src/readelf.c:5548
+#, c-format
+msgid "invalid data at offset %tu in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:5563
+#, c-format
+msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
+msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:5571
+msgid ""
+"\n"
+"Directory table:"
+msgstr ""
+
+#: src/readelf.c:5587
+msgid ""
+"\n"
+"File name table:\n"
+" Entry Dir   Time      Size      Name"
+msgstr ""
+
+#: src/readelf.c:5616
+msgid ""
+"\n"
+"Line number statements:"
+msgstr ""
+
+#: src/readelf.c:5677
+#, c-format
+msgid " special opcode %u: address+%u = %s, line%+d = %zu\n"
+msgstr ""
+
+#: src/readelf.c:5697
+#, c-format
+msgid " extended opcode %u: "
+msgstr ""
+
+#: src/readelf.c:5702
+msgid "end of sequence"
+msgstr ""
+
+#: src/readelf.c:5717
+#, c-format
+msgid "set address to %s\n"
+msgstr ""
+
+#: src/readelf.c:5738
+#, c-format
+msgid "define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
+msgstr ""
+
+#: src/readelf.c:5747
+msgid "unknown opcode"
+msgstr ""
+
+#: src/readelf.c:5759
+msgid " copy"
+msgstr ""
+
+#: src/readelf.c:5769
+#, c-format
+msgid "advance address by %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5780
+#, c-format
+msgid " advance line by constant %d to %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:5788
+#, c-format
+msgid " set file to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:5798
+#, c-format
+msgid " set column to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:5805
+#, c-format
+msgid " set '%s' to %<PRIuFAST8>\n"
+msgstr ""
+
+#: src/readelf.c:5811
+msgid " set basic block flag"
+msgstr ""
+
+#: src/readelf.c:5821
+#, c-format
+msgid "advance address by constant %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5837
+#, c-format
+msgid "advance address by fixed value %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5846
+msgid " set prologue end flag"
+msgstr ""
+
+#: src/readelf.c:5851
+msgid " set epilogue begin flag"
+msgstr ""
+
+#: src/readelf.c:5860
+#, c-format
+msgid " unknown opcode with %<PRIu8> parameter:"
+msgid_plural " unknown opcode with %<PRIu8> parameters:"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:5892
+#, c-format
+msgid "cannot get .debug_loc content: %s"
+msgstr ""
+
+#: src/readelf.c:5947
+#, c-format
+msgid " [%6tx]  %s..%s"
+msgstr ""
+
+#: src/readelf.c:5949
+#, c-format
+msgid "           %s..%s"
+msgstr ""
+
+#: src/readelf.c:6002
+#, c-format
+msgid "cannot get macro information section data: %s"
+msgstr ""
+
+#: src/readelf.c:6081
+#, c-format
+msgid "%*s*** non-terminated string at end of section"
+msgstr ""
+
+#: src/readelf.c:6149
+#, c-format
+msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
+msgstr ""
+
+#: src/readelf.c:6188
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" %*s  String\n"
+msgstr ""
+
+#: src/readelf.c:6202
+#, c-format
+msgid " *** error while reading strings: %s\n"
+msgstr ""
+
+#: src/readelf.c:6222
+#, c-format
+msgid ""
+"\n"
+"Call frame search table section [%2zu] '.eh_frame_hdr':\n"
+msgstr ""
+
+#: src/readelf.c:6324
+#, c-format
+msgid ""
+"\n"
+"Exception handling table section [%2zu] '.gcc_except_table':\n"
+msgstr ""
+
+#: src/readelf.c:6347
+#, c-format
+msgid " LPStart encoding:    %#x "
+msgstr ""
+
+#: src/readelf.c:6359
+#, c-format
+msgid " TType encoding:      %#x "
+msgstr ""
+
+#: src/readelf.c:6373
+#, c-format
+msgid " Call site encoding:  %#x "
+msgstr ""
+
+#: src/readelf.c:6386
+msgid ""
+"\n"
+" Call site table:"
+msgstr ""
+
+#: src/readelf.c:6400
+#, c-format
+msgid ""
+" [%4u] Call site start:   %#<PRIx64>\n"
+"        Call site length:  %<PRIu64>\n"
+"        Landing pad:       %#<PRIx64>\n"
+"        Action:            %u\n"
+msgstr ""
+
+#: src/readelf.c:6460
+#, c-format
+msgid "invalid TType encoding"
+msgstr ""
+
+#: src/readelf.c:6484
+#, c-format
+msgid "cannot get debug context descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:6620 src/readelf.c:7221
+#, c-format
+msgid "cannot convert core note data: %s"
+msgstr ""
+
+#: src/readelf.c:6961
+#, c-format
+msgid ""
+"\n"
+"%*s... <repeats %u more times> ..."
+msgstr ""
+
+#: src/readelf.c:7320
+msgid "  Owner          Data size  Type\n"
+msgstr ""
+
+#: src/readelf.c:7338
+#, c-format
+msgid "  %-13.*s  %9<PRId32>  %s\n"
+msgstr ""
+
+#: src/readelf.c:7372
+#, c-format
+msgid "cannot get content of note section: %s"
+msgstr ""
+
+#: src/readelf.c:7399
+#, c-format
+msgid ""
+"\n"
+"Note section [%2zu] '%s' of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7422
+#, c-format
+msgid ""
+"\n"
+"Note segment of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7468
+#, c-format
+msgid ""
+"\n"
+"Section [%Zu] '%s' has no data to dump.\n"
+msgstr ""
+
+#: src/readelf.c:7474 src/readelf.c:7497
+#, c-format
+msgid "cannot get data for section [%Zu] '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7478
+#, c-format
+msgid ""
+"\n"
+"Hex dump of section [%Zu] '%s', %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7491
+#, c-format
+msgid ""
+"\n"
+"Section [%Zu] '%s' has no strings to dump.\n"
+msgstr ""
+
+#: src/readelf.c:7501
+#, c-format
+msgid ""
+"\n"
+"String section [%Zu] '%s' contains %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7549
+#, c-format
+msgid ""
+"\n"
+"section [%lu] does not exist"
+msgstr ""
+
+#: src/readelf.c:7576
+#, c-format
+msgid ""
+"\n"
+"section '%s' does not exist"
+msgstr ""
+
+#: src/readelf.c:7637
+#, c-format
+msgid "cannot get symbol index of archive '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7640
+#, c-format
+msgid ""
+"\n"
+"Archive '%s' has no symbol index\n"
+msgstr ""
+
+#: src/readelf.c:7644
+#, c-format
+msgid ""
+"\n"
+"Index of archive '%s' has %Zu entries:\n"
+msgstr ""
+
+#: src/readelf.c:7662
+#, c-format
+msgid "cannot extract member at offset %Zu in '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7667
+#, c-format
+msgid "Archive member '%s' contains:\n"
+msgstr ""
+
+#: src/size.c:68
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd' or `sysv'.  The default "
+"is `bsd'"
+msgstr ""
+
+#: src/size.c:70
+msgid "Same as `--format=sysv'"
+msgstr ""
+
+#: src/size.c:71
+msgid "Same as `--format=bsd'"
+msgstr ""
+
+#: src/size.c:74
+msgid "Same as `--radix=10'"
+msgstr ""
+
+#: src/size.c:75
+msgid "Same as `--radix=8'"
+msgstr ""
+
+#: src/size.c:76
+msgid "Same as `--radix=16'"
+msgstr ""
+
+#: src/size.c:78
+msgid "Similar to `--format=sysv' output but in one line"
+msgstr ""
+
+#: src/size.c:82
+msgid "Print size and permission flags for loadable segments"
+msgstr ""
+
+#: src/size.c:83
+msgid "Display the total sizes (bsd only)"
+msgstr ""
+
+#: src/size.c:88
+msgid "List section sizes of FILEs (a.out by default)."
+msgstr ""
+
+#: src/size.c:269
+#, c-format
+msgid "Invalid format: %s"
+msgstr ""
+
+#: src/size.c:280
+#, c-format
+msgid "Invalid radix: %s"
+msgstr ""
+
+#: src/size.c:339
+#, c-format
+msgid "%s: file format not recognized"
+msgstr ""
+
+#: src/size.c:446 src/size.c:589
+#, c-format
+msgid " (ex %s)"
+msgstr ""
+
+#: src/size.c:614
+msgid "(TOTALS)\n"
+msgstr ""
+
+#: src/strings.c:70
+msgid "Output Selection:"
+msgstr ""
+
+#: src/strings.c:71
+msgid "Scan entire file, not only loaded sections"
+msgstr ""
+
+#: src/strings.c:73
+msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed"
+msgstr ""
+
+#: src/strings.c:74
+msgid ""
+"Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, "
+"{B,L} = 32-bit"
+msgstr ""
+
+#: src/strings.c:78
+msgid "Print name of the file before each string."
+msgstr ""
+
+#: src/strings.c:80
+msgid "Print location of the string in base 8, 10, or 16 respectively."
+msgstr ""
+
+#: src/strings.c:81
+msgid "Alias for --radix=o"
+msgstr ""
+
+#: src/strings.c:88
+msgid "Print the strings of printable characters in files."
+msgstr ""
+
+#: src/strings.c:268 src/strings.c:303
+#, c-format
+msgid "invalid value '%s' for %s parameter"
+msgstr ""
+
+#: src/strings.c:314
+#, c-format
+msgid "invalid minimum length of matched string size"
+msgstr ""
+
+#: src/strings.c:601
+#, c-format
+msgid "lseek64 failed"
+msgstr ""
+
+#: src/strings.c:616 src/strings.c:680
+#, c-format
+msgid "re-mmap failed"
+msgstr ""
+
+#: src/strings.c:653
+#, c-format
+msgid "mprotect failed"
+msgstr ""
+
+#: src/strip.c:74
+msgid "Place stripped output into FILE"
+msgstr ""
+
+#: src/strip.c:75
+msgid "Extract the removed sections into FILE"
+msgstr ""
+
+#: src/strip.c:76
+msgid "Embed name FILE instead of -f argument"
+msgstr ""
+
+#: src/strip.c:80
+msgid "Remove all debugging symbols"
+msgstr ""
+
+#: src/strip.c:84
+msgid "Copy modified/access timestamps to the output"
+msgstr ""
+
+#: src/strip.c:86
+msgid "Remove .comment section"
+msgstr ""
+
+#: src/strip.c:89
+msgid "Relax a few rules to handle slightly broken ELF files"
+msgstr ""
+
+#: src/strip.c:94
+msgid "Discard symbols from object files."
+msgstr ""
+
+#: src/strip.c:186
+#, c-format
+msgid "Only one input file allowed together with '-o' and '-f'"
+msgstr ""
+
+#: src/strip.c:222
+#, c-format
+msgid "-f option specified twice"
+msgstr ""
+
+#: src/strip.c:231
+#, c-format
+msgid "-F option specified twice"
+msgstr ""
+
+#: src/strip.c:240 src/unstrip.c:125
+#, c-format
+msgid "-o option specified twice"
+msgstr ""
+
+#: src/strip.c:260
+#, c-format
+msgid "-R option supports only .comment section"
+msgstr ""
+
+#: src/strip.c:298 src/strip.c:322
+#, c-format
+msgid "cannot stat input file '%s'"
+msgstr ""
+
+#: src/strip.c:312
+#, c-format
+msgid "while opening '%s'"
+msgstr ""
+
+#: src/strip.c:350
+#, c-format
+msgid "%s: cannot use -o or -f when stripping archive"
+msgstr ""
+
+#: src/strip.c:448
+#, c-format
+msgid "cannot open EBL backend"
+msgstr ""
+
+#: src/strip.c:498 src/strip.c:522
+#, c-format
+msgid "cannot create new file '%s': %s"
+msgstr ""
+
+#: src/strip.c:582
+#, c-format
+msgid "illformed file '%s'"
+msgstr ""
+
+#: src/strip.c:869 src/strip.c:956
+#, c-format
+msgid "while generating output file: %s"
+msgstr ""
+
+#: src/strip.c:929 src/strip.c:1668
+#, c-format
+msgid "%s: error while creating ELF header: %s"
+msgstr ""
+
+#: src/strip.c:943
+#, c-format
+msgid "while preparing output for '%s'"
+msgstr ""
+
+#: src/strip.c:994 src/strip.c:1050
+#, c-format
+msgid "while create section header section: %s"
+msgstr ""
+
+#: src/strip.c:1000
+#, c-format
+msgid "cannot allocate section data: %s"
+msgstr ""
+
+#: src/strip.c:1059
+#, c-format
+msgid "while create section header string table: %s"
+msgstr ""
+
+#: src/strip.c:1593 src/strip.c:1690
+#, c-format
+msgid "while writing '%s': %s"
+msgstr ""
+
+#: src/strip.c:1604
+#, c-format
+msgid "while creating '%s'"
+msgstr ""
+
+#: src/strip.c:1616
+#, c-format
+msgid "while computing checksum for debug information"
+msgstr ""
+
+#: src/strip.c:1676
+#, c-format
+msgid "%s: error while reading the file: %s"
+msgstr ""
+
+#: src/strip.c:1722 src/strip.c:1729
+#, c-format
+msgid "error while finishing '%s': %s"
+msgstr ""
+
+#: src/strip.c:1752 src/strip.c:1809
+#, c-format
+msgid "cannot set access and modification date of '%s'"
+msgstr ""
+
+#: src/unstrip.c:78
+msgid "Match MODULE against file names, not module names"
+msgstr ""
+
+#: src/unstrip.c:79
+msgid "Silently skip unfindable files"
+msgstr ""
+
+#: src/unstrip.c:82
+msgid "Place output into FILE"
+msgstr ""
+
+#: src/unstrip.c:84
+msgid "Create multiple output files under DIRECTORY"
+msgstr ""
+
+#: src/unstrip.c:85
+msgid "Use module rather than file names"
+msgstr ""
+
+#: src/unstrip.c:87
+msgid "Create output for modules that have no separate debug information"
+msgstr ""
+
+#: src/unstrip.c:90
+msgid "Apply relocations to section contents in ET_REL files"
+msgstr ""
+
+#: src/unstrip.c:92
+msgid "Only list module and file names, build IDs"
+msgstr ""
+
+#: src/unstrip.c:134
+#, c-format
+msgid "-d option specified twice"
+msgstr ""
+
+#: src/unstrip.c:166
+#, c-format
+msgid "only one of -o or -d allowed"
+msgstr ""
+
+#: src/unstrip.c:175
+#, c-format
+msgid "-n cannot be used with explicit files or -o or -d"
+msgstr ""
+
+#: src/unstrip.c:190
+#, c-format
+msgid "output directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:199
+#, c-format
+msgid "exactly two file arguments are required"
+msgstr ""
+
+#: src/unstrip.c:205
+#, c-format
+msgid "-m, -a, -R, and -i options not allowed with explicit files"
+msgstr ""
+
+#: src/unstrip.c:218
+#, c-format
+msgid "-o or -d is required when using implicit files"
+msgstr ""
+
+#: src/unstrip.c:254
+#, c-format
+msgid "cannot create ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:259
+#, c-format
+msgid "cannot copy ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:264 src/unstrip.c:1817
+#, c-format
+msgid "cannot create program headers: %s"
+msgstr ""
+
+#: src/unstrip.c:270
+#, c-format
+msgid "cannot copy program header: %s"
+msgstr ""
+
+#: src/unstrip.c:280
+#, c-format
+msgid "cannot copy section header: %s"
+msgstr ""
+
+#: src/unstrip.c:283 src/unstrip.c:1505
+#, c-format
+msgid "cannot get section data: %s"
+msgstr ""
+
+#: src/unstrip.c:285 src/unstrip.c:1507
+#, c-format
+msgid "cannot copy section data: %s"
+msgstr ""
+
+#: src/unstrip.c:309
+#, c-format
+msgid "cannot create directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:349 src/unstrip.c:763 src/unstrip.c:1540
+#, c-format
+msgid "cannot get symbol table entry: %s"
+msgstr ""
+
+#: src/unstrip.c:365 src/unstrip.c:580 src/unstrip.c:601 src/unstrip.c:613
+#: src/unstrip.c:1561 src/unstrip.c:1691 src/unstrip.c:1715
+#, c-format
+msgid "cannot update symbol table: %s"
+msgstr ""
+
+#: src/unstrip.c:382 src/unstrip.c:432 src/unstrip.c:562 src/unstrip.c:1209
+#: src/unstrip.c:1525 src/unstrip.c:1720 src/unstrip.c:1791
+#, c-format
+msgid "cannot update section header: %s"
+msgstr ""
+
+#: src/unstrip.c:408 src/unstrip.c:419
+#, c-format
+msgid "cannot update relocation: %s"
+msgstr ""
+
+#: src/unstrip.c:507
+#, c-format
+msgid "cannot get symbol version: %s"
+msgstr ""
+
+#: src/unstrip.c:519
+#, c-format
+msgid "unexpected section type in [%Zu] with sh_link to symtab"
+msgstr ""
+
+#: src/unstrip.c:769
+#, c-format
+msgid "invalid string offset in symbol [%Zu]"
+msgstr ""
+
+#: src/unstrip.c:911 src/unstrip.c:1248
+#, c-format
+msgid "cannot read section [%Zu] name: %s"
+msgstr ""
+
+#: src/unstrip.c:952 src/unstrip.c:971 src/unstrip.c:1004
+#, c-format
+msgid "cannot read '.gnu.prelink_undo' section: %s"
+msgstr ""
+
+#: src/unstrip.c:992
+#, c-format
+msgid "invalid contents in '%s' section"
+msgstr ""
+
+#: src/unstrip.c:1047 src/unstrip.c:1370
+#, c-format
+msgid "cannot find matching section for [%Zu] '%s'"
+msgstr ""
+
+#: src/unstrip.c:1171 src/unstrip.c:1186 src/unstrip.c:1451
+#, c-format
+msgid "cannot add section name to string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1195
+#, c-format
+msgid "cannot update section header string table data: %s"
+msgstr ""
+
+#: src/unstrip.c:1223 src/unstrip.c:1227
+#, c-format
+msgid "cannot get section header string table section index: %s"
+msgstr ""
+
+#: src/unstrip.c:1231 src/unstrip.c:1235 src/unstrip.c:1466
+#, c-format
+msgid "cannot get section count: %s"
+msgstr ""
+
+#: src/unstrip.c:1293 src/unstrip.c:1385
+#, c-format
+msgid "cannot read section header string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1445
+#, c-format
+msgid "cannot add new section: %s"
+msgstr ""
+
+#: src/unstrip.c:1548
+#, c-format
+msgid "symbol [%Zu] has invalid section index"
+msgstr ""
+
+#: src/unstrip.c:1800
+#, c-format
+msgid "cannot get ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:1827
+#, c-format
+msgid "cannot update program header: %s"
+msgstr ""
+
+#: src/unstrip.c:1832 src/unstrip.c:1911
+#, c-format
+msgid "cannot write output file: %s"
+msgstr ""
+
+#: src/unstrip.c:1880
+#, c-format
+msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:1883
+#, c-format
+msgid ""
+"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:1902 src/unstrip.c:1942 src/unstrip.c:1954 src/unstrip.c:2034
+#, c-format
+msgid "cannot create ELF descriptor: %s"
+msgstr ""
+
+#: src/unstrip.c:1960
+#, c-format
+msgid "'%s' and '%s' do not seem to match"
+msgstr ""
+
+#: src/unstrip.c:1991
+#, c-format
+msgid "cannot find stripped file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:1995
+#, c-format
+msgid "cannot open stripped file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2010
+#, c-format
+msgid "cannot find debug file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2014
+#, c-format
+msgid "cannot open debug file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2027
+#, c-format
+msgid "module '%s' file '%s' is not stripped"
+msgstr ""
+
+#: src/unstrip.c:2058
+#, c-format
+msgid "cannot cache section addresses for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2191
+#, c-format
+msgid "no matching modules found"
+msgstr ""
+
+#: src/unstrip.c:2200
+#, c-format
+msgid "matched more than one module"
+msgstr ""
+
+#: src/unstrip.c:2247
+msgid ""
+"STRIPPED-FILE DEBUG-FILE\n"
+"[MODULE...]"
+msgstr ""
+
+#: src/unstrip.c:2248
+msgid ""
+"Combine stripped files with separate symbols and debug information.\n\nThe "
+"first form puts the result in DEBUG-FILE if -o was not given.\n"
+"\n"
+"MODULE arguments give file name patterns matching modules to process.\n"
+"With -f these match the file name of the main (stripped) file (slashes are "
+"never special), otherwise they match the simple module names.  With no "
+"arguments, process all modules found.\n"
+"\n"
+"Multiple modules are written to files under OUTPUT-DIRECTORY, creating "
+"subdirectories as needed.  With -m these files have simple module names, "
+"otherwise they have the name of the main file complete with directory "
+"underneath OUTPUT-DIRECTORY.\n"
+"\n"
+"With -n no files are written, but one line to standard output for each "
+"module:\n"
+"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n"
+"START and SIZE are hexadecimal giving the address bounds of the module.  "
+"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the "
+"hexadecimal may be followed by @0xADDR giving the address where the ID "
+"resides if that is known.  FILE is the file name found for the module, or - "
+"if none was found, or . if an ELF image is available but not from any named "
+"file.  DEBUGFILE is the separate debuginfo file name, or - if no debuginfo "
+"was found, or . if FILE contains the debug information."
+msgstr ""
diff --git a/third_party/elfutils/po/uk.po b/third_party/elfutils/po/uk.po
new file mode 100644
index 0000000..8c72356
--- /dev/null
+++ b/third_party/elfutils/po/uk.po
@@ -0,0 +1,7291 @@
+# Ukrainian translation of elfutils
+# Copyright (C) 2010 Free Software Foundation, Inc.
+# This file is distributed under the same license as the elfutils package.
+#
+# Yuri Chornoivan <yurchor@ukr.net>, 2010, 2011, 2012, 2013, 2014, 2015.
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"Report-Msgid-Bugs-To: https://sourceware.org/bugzilla/\n"
+"POT-Creation-Date: 2017-09-01 12:27+0200\n"
+"PO-Revision-Date: 2015-09-26 16:41+0300\n"
+"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
+"Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n"
+"Language: uk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+"X-Generator: Lokalize 1.5\n"
+
+#: lib/color.c:53
+msgid ""
+"colorize the output.  WHEN defaults to 'always' or can be 'auto' or 'never'"
+msgstr ""
+"розфарбовувати виведене. Типові значення «always» (завжди), «auto» (авто) "
+"або «never» (ніколи)"
+
+#: lib/color.c:127
+#, c-format
+msgid ""
+"%s: invalid argument '%s' for '--color'\n"
+"valid arguments are:\n"
+"  - 'always', 'yes', 'force'\n"
+"  - 'never', 'no', 'none'\n"
+"  - 'auto', 'tty', 'if-tty'\n"
+msgstr ""
+"%s: некоректний аргумент «%s» до «--color»\n"
+"коректними аргументами є такі:\n"
+"  - «always», «yes», «force»\n"
+"  - «never», «no», «none»\n"
+"  - «auto», «tty», «if-tty»\n"
+
+#: lib/color.c:190 src/objdump.c:727
+#, c-format
+msgid "cannot allocate memory"
+msgstr "не вдалося розподілити пам’ять"
+
+#: lib/printversion.c:40
+#, fuzzy, c-format
+msgid ""
+"Copyright (C) %s The elfutils developers <%s>.\n"
+"This is free software; see the source for copying conditions.  There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+"© Red Hat, Inc., %s\n"
+"Це програмне забезпечення є вільним, умови копіювання викладено у його "
+"початкових кодах. Умовами ліцензування програми НЕ передбачено жодних "
+"гарантій, зокрема гарантій працездатності або придатності для певної мети.\n"
+
+#: lib/xmalloc.c:53 lib/xmalloc.c:66 lib/xmalloc.c:78 src/readelf.c:3310
+#: src/readelf.c:3701 src/readelf.c:8540 src/unstrip.c:2227 src/unstrip.c:2433
+#, c-format
+msgid "memory exhausted"
+msgstr "пам’ять вичерпано"
+
+#: libasm/asm_error.c:65 libdw/dwarf_error.c:58 libdwfl/libdwflP.h:50
+#: libelf/elf_error.c:60
+msgid "no error"
+msgstr "без помилок"
+
+#: libasm/asm_error.c:66 libdw/dwarf_error.c:68 libdwfl/libdwflP.h:52
+#: libelf/elf_error.c:91
+msgid "out of memory"
+msgstr "нестача пам'яті"
+
+#: libasm/asm_error.c:67
+msgid "cannot create output file"
+msgstr "не вдалося створити файл виводу даних"
+
+#: libasm/asm_error.c:68
+msgid "invalid parameter"
+msgstr "некоректний параметр"
+
+#: libasm/asm_error.c:69
+msgid "cannot change mode of output file"
+msgstr "не вдалося змінити права доступу до файла виводу даних"
+
+#: libasm/asm_error.c:70
+msgid "cannot rename output file"
+msgstr "не вдалося перейменувати файл виводу даних"
+
+#: libasm/asm_error.c:71
+msgid "duplicate symbol"
+msgstr "дублювання символів"
+
+#: libasm/asm_error.c:72
+msgid "invalid section type for operation"
+msgstr "некоректний тип розділу для дії"
+
+#: libasm/asm_error.c:73
+msgid "error during output of data"
+msgstr "помилка під час спроби виведення даних"
+
+#: libasm/asm_error.c:74
+msgid "no backend support available"
+msgstr "підтримки серверів не передбачено"
+
+#: libasm/asm_error.c:83 libdw/dwarf_error.c:59 libdwfl/libdwflP.h:51
+#: libelf/elf_error.c:63
+msgid "unknown error"
+msgstr "невідома помилка"
+
+#: libdw/dwarf_error.c:60
+msgid "invalid access"
+msgstr "некоректний доступ"
+
+#: libdw/dwarf_error.c:61
+msgid "no regular file"
+msgstr "не є звичайним файлом"
+
+#: libdw/dwarf_error.c:62
+msgid "I/O error"
+msgstr "помилка вводу/виводу"
+
+#: libdw/dwarf_error.c:63
+msgid "invalid ELF file"
+msgstr "некоректний файл ELF"
+
+#: libdw/dwarf_error.c:64
+msgid "no DWARF information"
+msgstr "немає відомостей DWARF"
+
+#: libdw/dwarf_error.c:65
+msgid "cannot decompress DWARF"
+msgstr "не вдалося розпакувати DWARF"
+
+#: libdw/dwarf_error.c:66
+msgid "no ELF file"
+msgstr "немає файла ELF"
+
+#: libdw/dwarf_error.c:67
+msgid "cannot get ELF header"
+msgstr "не вдалося отримати заголовок ELF"
+
+#: libdw/dwarf_error.c:69
+msgid "not implemented"
+msgstr "не реалізовано"
+
+#: libdw/dwarf_error.c:70 libelf/elf_error.c:107 libelf/elf_error.c:155
+msgid "invalid command"
+msgstr "некоректна команда"
+
+#: libdw/dwarf_error.c:71
+msgid "invalid version"
+msgstr "некоректна версія"
+
+#: libdw/dwarf_error.c:72
+msgid "invalid file"
+msgstr "некоректний файл"
+
+#: libdw/dwarf_error.c:73
+msgid "no entries found"
+msgstr "запис не знайдено"
+
+#: libdw/dwarf_error.c:74
+msgid "invalid DWARF"
+msgstr "некоректний запис DWARF"
+
+#: libdw/dwarf_error.c:75
+msgid "no string data"
+msgstr "немає рядкових даних"
+
+#: libdw/dwarf_error.c:76
+msgid "no address value"
+msgstr "немає значення адреси"
+
+#: libdw/dwarf_error.c:77
+msgid "no constant value"
+msgstr "немає значення сталої"
+
+#: libdw/dwarf_error.c:78
+msgid "no reference value"
+msgstr "немає значення для порівняння"
+
+#: libdw/dwarf_error.c:79
+msgid "invalid reference value"
+msgstr "некоректне значення для порівняння"
+
+#: libdw/dwarf_error.c:80
+msgid ".debug_line section missing"
+msgstr "немає розділу .debug_line"
+
+#: libdw/dwarf_error.c:81
+msgid "invalid .debug_line section"
+msgstr "некоректний розділ .debug_line"
+
+#: libdw/dwarf_error.c:82
+msgid "debug information too big"
+msgstr "занадто великі відомості для діагностики"
+
+#: libdw/dwarf_error.c:83
+msgid "invalid DWARF version"
+msgstr "некоректна версія DWARF"
+
+#: libdw/dwarf_error.c:84
+msgid "invalid directory index"
+msgstr "некоректний покажчик каталогу"
+
+#: libdw/dwarf_error.c:85 libdwfl/libdwflP.h:71
+msgid "address out of range"
+msgstr "некоректна адреса"
+
+#: libdw/dwarf_error.c:86
+msgid "no location list value"
+msgstr "немає значення списку адрес"
+
+#: libdw/dwarf_error.c:87
+msgid "no block data"
+msgstr "немає блокових даних"
+
+#: libdw/dwarf_error.c:88
+msgid "invalid line index"
+msgstr "некоректний номер рядка"
+
+#: libdw/dwarf_error.c:89
+msgid "invalid address range index"
+msgstr "некоректний індекс діапазону адрес"
+
+#: libdw/dwarf_error.c:90 libdwfl/libdwflP.h:72
+msgid "no matching address range"
+msgstr "не виявлено відповідного діапазону адрес"
+
+#: libdw/dwarf_error.c:91
+msgid "no flag value"
+msgstr "немає значення прапорця"
+
+#: libdw/dwarf_error.c:92 libelf/elf_error.c:232
+msgid "invalid offset"
+msgstr "некоректне значення зміщення"
+
+#: libdw/dwarf_error.c:93
+msgid ".debug_ranges section missing"
+msgstr "немає розділу .debug_ranges"
+
+#: libdw/dwarf_error.c:94
+msgid "invalid CFI section"
+msgstr "некоректний розділ CFI"
+
+#: libdw/dwarf_error.c:95
+msgid "no alternative debug link found"
+msgstr "альтернативного діагностичного посилання не знайдено"
+
+#: libdw/dwarf_error.c:96
+msgid "invalid opcode"
+msgstr "некоректний код операції"
+
+#: libdw/dwarf_error.c:97
+msgid "not a CU (unit) DIE"
+msgstr "не є DIE CU (модуля)"
+
+#: libdw/dwarf_error.c:98
+#, fuzzy
+msgid "unknown language code"
+msgstr " невідомий код операції"
+
+#: libdwfl/argp-std.c:50 src/stack.c:639 src/unstrip.c:2374
+msgid "Input selection options:"
+msgstr "Вибір параметрів виведення даних:"
+
+#: libdwfl/argp-std.c:51
+msgid "Find addresses in FILE"
+msgstr "Знайти адреси у ФАЙЛІ"
+
+#: libdwfl/argp-std.c:53
+msgid "Find addresses from signatures found in COREFILE"
+msgstr "Знайти адреси за сигнатурами з файла COREFILE"
+
+#: libdwfl/argp-std.c:55
+msgid "Find addresses in files mapped into process PID"
+msgstr "Знайти адреси у файлах, відображених на процес з PID"
+
+#: libdwfl/argp-std.c:57
+msgid ""
+"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps "
+"format"
+msgstr ""
+"Знайти адреси у файлах, відображених як read за ФАЙЛОМ у форматі /proc/PID/"
+"maps Linux"
+
+#: libdwfl/argp-std.c:59
+msgid "Find addresses in the running kernel"
+msgstr "Знайти адреси у запущеному ядрі"
+
+#: libdwfl/argp-std.c:61
+msgid "Kernel with all modules"
+msgstr "Ядро з усіма модулями"
+
+#: libdwfl/argp-std.c:63 src/stack.c:646
+msgid "Search path for separate debuginfo files"
+msgstr "Шукати у вказаному каталозі окремі файли debuginfo"
+
+#: libdwfl/argp-std.c:164
+msgid "only one of -e, -p, -k, -K, or --core allowed"
+msgstr ""
+"можна використовувати лише один за параметрів: -e, -p, -k, -K або --core"
+
+#: libdwfl/argp-std.c:237
+msgid "cannot load kernel symbols"
+msgstr "не вдалося завантажити символи ядра"
+
+#. Non-fatal to have no modules since we do have the kernel.
+#: libdwfl/argp-std.c:241
+msgid "cannot find kernel modules"
+msgstr "не вдалося виявити модулі ядра"
+
+#: libdwfl/argp-std.c:258
+msgid "cannot find kernel or modules"
+msgstr "не вдалося виявити ядро або модулі"
+
+#: libdwfl/argp-std.c:297
+#, c-format
+msgid "cannot read ELF core file: %s"
+msgstr "не вдалося прочитати файл core ELF: %s"
+
+#: libdwfl/argp-std.c:320
+#, fuzzy
+msgid "Not enough memory"
+msgstr "нестача пам'яті"
+
+#: libdwfl/argp-std.c:330
+msgid "No modules recognized in core file"
+msgstr "Не вдалося виявити модулі у файлі core"
+
+#: libdwfl/libdwflP.h:53
+msgid "See errno"
+msgstr "Див. errno"
+
+#: libdwfl/libdwflP.h:54
+msgid "See elf_errno"
+msgstr "Див. elf_errno"
+
+#: libdwfl/libdwflP.h:55
+msgid "See dwarf_errno"
+msgstr "Див. dwarf_errno"
+
+#: libdwfl/libdwflP.h:56
+msgid "See ebl_errno (XXX missing)"
+msgstr "Див. ebl_errno (не виявлено XXX)"
+
+#: libdwfl/libdwflP.h:57
+msgid "gzip decompression failed"
+msgstr "Помилка під час спроби видобування з gzip"
+
+#: libdwfl/libdwflP.h:58
+msgid "bzip2 decompression failed"
+msgstr "Помилка під час спроби видобування з bzip2"
+
+#: libdwfl/libdwflP.h:59
+msgid "LZMA decompression failed"
+msgstr "Помилка під час спроби видобування з LZMA"
+
+#: libdwfl/libdwflP.h:60
+msgid "no support library found for machine"
+msgstr "у системі не виявлено бібліотеки підтримки"
+
+#: libdwfl/libdwflP.h:61
+msgid "Callbacks missing for ET_REL file"
+msgstr "Немає зворотних викликів для файла ET_REL"
+
+#: libdwfl/libdwflP.h:62
+msgid "Unsupported relocation type"
+msgstr "Непідтримуваний тип пересування"
+
+#: libdwfl/libdwflP.h:63
+msgid "r_offset is bogus"
+msgstr "r_offset є фіктивним"
+
+#: libdwfl/libdwflP.h:64 libelf/elf_error.c:111 libelf/elf_error.c:171
+msgid "offset out of range"
+msgstr "перевищення можливого зміщення"
+
+#: libdwfl/libdwflP.h:65
+msgid "relocation refers to undefined symbol"
+msgstr "пересування посилається на невизначений символ."
+
+#: libdwfl/libdwflP.h:66
+msgid "Callback returned failure"
+msgstr "Зворотним викликом повернуто помилку"
+
+#: libdwfl/libdwflP.h:67
+msgid "No DWARF information found"
+msgstr "Не виявлено відомостей DWARF"
+
+#: libdwfl/libdwflP.h:68
+msgid "No symbol table found"
+msgstr "Не виявлено таблиці символів"
+
+#: libdwfl/libdwflP.h:69
+msgid "No ELF program headers"
+msgstr "Немає заголовків програми ELF"
+
+#: libdwfl/libdwflP.h:70
+msgid "address range overlaps an existing module"
+msgstr "діапазон адрес перекриває існуючий модуль"
+
+#: libdwfl/libdwflP.h:73
+msgid "image truncated"
+msgstr "образ обрізано"
+
+#: libdwfl/libdwflP.h:74
+msgid "ELF file opened"
+msgstr "Відкритий файл ELF"
+
+#: libdwfl/libdwflP.h:75
+msgid "not a valid ELF file"
+msgstr "не є коректним файлом ELF"
+
+#: libdwfl/libdwflP.h:76
+msgid "cannot handle DWARF type description"
+msgstr "не вдалося обробити опис типу DWARF"
+
+#: libdwfl/libdwflP.h:77
+msgid "ELF file does not match build ID"
+msgstr "Файл ELF не відповідає ідентифікатору збирання"
+
+#: libdwfl/libdwflP.h:78
+msgid "corrupt .gnu.prelink_undo section data"
+msgstr "дані розділу «.gnu.prelink_undo» пошкоджено"
+
+#: libdwfl/libdwflP.h:79
+msgid "Internal error due to ebl"
+msgstr "Внутрішня помилка через ebl"
+
+#: libdwfl/libdwflP.h:80
+msgid "Missing data in core file"
+msgstr "У файлі ядра не вистачає даних"
+
+#: libdwfl/libdwflP.h:81
+msgid "Invalid register"
+msgstr "Некоректний регістр"
+
+#: libdwfl/libdwflP.h:82
+msgid "Error reading process memory"
+msgstr "Помилка під час спроби читання пам’яті процесу"
+
+#: libdwfl/libdwflP.h:83
+msgid "Couldn't find architecture of any ELF"
+msgstr "Не вдалося знайти хоч якусь архітектуру ELF"
+
+#: libdwfl/libdwflP.h:84
+msgid "Error parsing /proc filesystem"
+msgstr "Помилка під час спроби обробки файлової системи /proc"
+
+#: libdwfl/libdwflP.h:85
+msgid "Invalid DWARF"
+msgstr "Некоректний запис DWARF"
+
+#: libdwfl/libdwflP.h:86
+msgid "Unsupported DWARF"
+msgstr "Непідтримуваний запис DWARF"
+
+#: libdwfl/libdwflP.h:87
+msgid "Unable to find more threads"
+msgstr "Не вдалося знайти додаткові потоки"
+
+#: libdwfl/libdwflP.h:88
+msgid "Dwfl already has attached state"
+msgstr "Dwfl уже перебуває у стані долучення до процесу"
+
+#: libdwfl/libdwflP.h:89
+msgid "Dwfl has no attached state"
+msgstr "Dwfl не перебуває у стані долучення до процесу"
+
+#: libdwfl/libdwflP.h:90
+msgid "Unwinding not supported for this architecture"
+msgstr "Для цієї архітектури розгортання не передбачено"
+
+#: libdwfl/libdwflP.h:91
+msgid "Invalid argument"
+msgstr "Некоректний аргумент"
+
+#: libdwfl/libdwflP.h:92
+msgid "Not an ET_CORE ELF file"
+msgstr "Не є файлом ET_CORE ELF"
+
+#: libebl/eblbackendname.c:41
+msgid "No backend"
+msgstr "Немає сервера"
+
+#: libebl/eblcorenotetypename.c:100 libebl/eblobjnotetypename.c:76
+#: libebl/eblobjnotetypename.c:83 libebl/eblobjnotetypename.c:102
+#: libebl/eblosabiname.c:73 libebl/eblsectionname.c:83
+#: libebl/eblsectiontypename.c:115 libebl/eblsegmenttypename.c:79
+msgid "<unknown>"
+msgstr "<невідомо>"
+
+#: libebl/ebldynamictagname.c:101
+#, c-format
+msgid "<unknown>: %#<PRIx64>"
+msgstr "<невідомо>: %#<PRIx64>"
+
+#: libebl/eblobjnote.c:53
+#, c-format
+msgid "unknown SDT version %u\n"
+msgstr "невідома версія SDT, %u\n"
+
+#: libebl/eblobjnote.c:71
+#, c-format
+msgid "invalid SDT probe descriptor\n"
+msgstr "некоректний дескриптор зондування SDT\n"
+
+#: libebl/eblobjnote.c:121
+#, c-format
+msgid "    PC: "
+msgstr "    PC: "
+
+#: libebl/eblobjnote.c:123
+#, c-format
+msgid " Base: "
+msgstr "Основа: "
+
+#: libebl/eblobjnote.c:125
+#, c-format
+msgid " Semaphore: "
+msgstr " Семафор:   "
+
+#: libebl/eblobjnote.c:127
+#, c-format
+msgid "    Provider: "
+msgstr " Постачальник: "
+
+#: libebl/eblobjnote.c:129
+#, c-format
+msgid " Name: "
+msgstr "Назва: "
+
+#: libebl/eblobjnote.c:131
+#, c-format
+msgid " Args: "
+msgstr " Арг.: "
+
+#: libebl/eblobjnote.c:141
+#, c-format
+msgid "    Build ID: "
+msgstr "    Ід. збирання: "
+
+#. A non-null terminated version string.
+#: libebl/eblobjnote.c:152
+#, c-format
+msgid "    Linker version: %.*s\n"
+msgstr "    Версія компонувальника: %.*s\n"
+
+#: libebl/eblobjnote.c:213
+#, c-format
+msgid "    OS: %s, ABI: "
+msgstr "    ОС: %s, ABI: "
+
+#: libebl/eblosabiname.c:70
+msgid "Stand alone"
+msgstr "Окремий"
+
+#: libebl/eblsymbolbindingname.c:67 libebl/eblsymboltypename.c:73
+#, c-format
+msgid "<unknown>: %d"
+msgstr "<невідомий>: %d"
+
+#: libelf/elf_error.c:67
+msgid "unknown version"
+msgstr "невідома версія"
+
+#: libelf/elf_error.c:71
+msgid "unknown type"
+msgstr "невизначений тип"
+
+#: libelf/elf_error.c:75
+msgid "invalid `Elf' handle"
+msgstr "некоректний дескриптор «Elf»"
+
+#: libelf/elf_error.c:79
+msgid "invalid size of source operand"
+msgstr "некоректна розмірність вхідного параметра"
+
+#: libelf/elf_error.c:83
+msgid "invalid size of destination operand"
+msgstr "некоректна розмірність вихідного параметра"
+
+#: libelf/elf_error.c:87 src/readelf.c:5153
+#, c-format
+msgid "invalid encoding"
+msgstr "некоректне кодування"
+
+#: libelf/elf_error.c:95
+msgid "invalid file descriptor"
+msgstr "некоректний дескриптор файла"
+
+#: libelf/elf_error.c:99
+msgid "invalid operation"
+msgstr "недійсна дія"
+
+#: libelf/elf_error.c:103
+msgid "ELF version not set"
+msgstr "версію ELF не вказано"
+
+#: libelf/elf_error.c:115
+msgid "invalid fmag field in archive header"
+msgstr "некоректне поле fmag у заголовку архіву"
+
+#: libelf/elf_error.c:119
+msgid "invalid archive file"
+msgstr "некоректний файл архіву"
+
+#: libelf/elf_error.c:123
+msgid "descriptor is not for an archive"
+msgstr "дескриптор не належить архіву"
+
+#: libelf/elf_error.c:127
+msgid "no index available"
+msgstr "такого номера немає"
+
+#: libelf/elf_error.c:131
+msgid "cannot read data from file"
+msgstr "не вдалося прочитати дані з файла"
+
+#: libelf/elf_error.c:135
+msgid "cannot write data to file"
+msgstr "не вдалося записати дані до файла"
+
+#: libelf/elf_error.c:139
+msgid "invalid binary class"
+msgstr "некоректний бінарний клас"
+
+#: libelf/elf_error.c:143
+msgid "invalid section index"
+msgstr "некоректний номер розділу"
+
+#: libelf/elf_error.c:147
+msgid "invalid operand"
+msgstr "некоректний параметр"
+
+#: libelf/elf_error.c:151
+msgid "invalid section"
+msgstr "некоректний розділ"
+
+#: libelf/elf_error.c:159
+msgid "executable header not created first"
+msgstr "заголовок виконуваного файла не було створено першим"
+
+#: libelf/elf_error.c:163
+msgid "file descriptor disabled"
+msgstr "дескриптор файла вимкнено"
+
+#: libelf/elf_error.c:167
+msgid "archive/member file descriptor mismatch"
+msgstr "невідповідність дескрипторів файлів архіву/елемента"
+
+#: libelf/elf_error.c:175
+msgid "cannot manipulate null section"
+msgstr "не можна оперувати нульовим розділом"
+
+#: libelf/elf_error.c:179
+msgid "data/scn mismatch"
+msgstr "невідповідність полів data/scn"
+
+#: libelf/elf_error.c:183
+msgid "invalid section header"
+msgstr "некоректний заголовок розділу"
+
+#: libelf/elf_error.c:187 src/readelf.c:7403 src/readelf.c:7914
+#: src/readelf.c:8015 src/readelf.c:8196
+#, c-format
+msgid "invalid data"
+msgstr "некоректні дані"
+
+#: libelf/elf_error.c:191
+msgid "unknown data encoding"
+msgstr "невідоме кодування даних"
+
+#: libelf/elf_error.c:195
+msgid "section `sh_size' too small for data"
+msgstr "розділ «sh_size» є замалим для даних"
+
+#: libelf/elf_error.c:199
+msgid "invalid section alignment"
+msgstr "некоректне вирівнювання розділу"
+
+#: libelf/elf_error.c:203
+msgid "invalid section entry size"
+msgstr "некоректна розмірність запису розділу"
+
+#: libelf/elf_error.c:207
+msgid "update() for write on read-only file"
+msgstr "update() для запису придатного лише для читання файла"
+
+#: libelf/elf_error.c:211
+msgid "no such file"
+msgstr "такого файла не виявлено"
+
+#: libelf/elf_error.c:215
+msgid "only relocatable files can contain section groups"
+msgstr "містити групи розділів можуть лише придатні до пересування файли"
+
+#: libelf/elf_error.c:220
+msgid ""
+"program header only allowed in executables, shared objects, and core files"
+msgstr ""
+"заголовок програми можна використовувати лише у виконуваних файлах, об’єктах "
+"спільного використання та файлах ядра"
+
+#: libelf/elf_error.c:227
+msgid "file has no program header"
+msgstr "у файлі немає заголовка програми"
+
+#: libelf/elf_error.c:237
+#, fuzzy
+msgid "invalid section type"
+msgstr "некоректний розділ"
+
+#: libelf/elf_error.c:242
+#, fuzzy
+msgid "invalid section flags"
+msgstr "некоректний розділ"
+
+#: libelf/elf_error.c:247
+#, fuzzy
+msgid "section does not contain compressed data"
+msgstr "розділ хешу [%2zu] «%s» містить недостатньо даних\n"
+
+#: libelf/elf_error.c:252
+msgid "section contains compressed data"
+msgstr ""
+
+#: libelf/elf_error.c:257
+#, fuzzy
+msgid "unknown compression type"
+msgstr "невизначений тип"
+
+#: libelf/elf_error.c:262
+#, fuzzy
+msgid "cannot compress data"
+msgstr "не вдалося розпакувати DWARF"
+
+#: libelf/elf_error.c:267
+#, fuzzy
+msgid "cannot decompress data"
+msgstr "не вдалося розпакувати DWARF"
+
+#: src/addr2line.c:58
+msgid "Input format options:"
+msgstr "Параметри форматування вхідних даних:"
+
+#: src/addr2line.c:60
+msgid "Treat addresses as offsets relative to NAME section."
+msgstr "Вважати адреси зміщеннями відносно розділу НАЗВА."
+
+#: src/addr2line.c:62
+msgid "Output format options:"
+msgstr "Параметри форматування результатів:"
+
+#: src/addr2line.c:63
+msgid "Print address before each entry"
+msgstr "Виводити адресу перед кожним записом"
+
+#: src/addr2line.c:64
+msgid "Show only base names of source files"
+msgstr "Показувати лише базові назви файлів коду програми"
+
+#: src/addr2line.c:66
+msgid "Show absolute file names using compilation directory"
+msgstr "Показувати абсолютні назви файлів з використанням каталогу збирання"
+
+#: src/addr2line.c:67
+msgid "Also show function names"
+msgstr "Показувати також назви функцій"
+
+#: src/addr2line.c:68
+msgid "Also show symbol or section names"
+msgstr "Показувати також назви символів та розділів"
+
+#: src/addr2line.c:69
+msgid "Also show symbol and the section names"
+msgstr "Показувати також назви символів та розділів"
+
+#: src/addr2line.c:70
+msgid "Also show line table flags"
+msgstr "Показувати також прапорці рядків таблиці"
+
+#: src/addr2line.c:72
+msgid ""
+"Show all source locations that caused inline expansion of subroutines at the "
+"address."
+msgstr ""
+"Показати усі місця у початковому коді, у яких було виявлено вбудоване "
+"розгортання підпрограм за вказаною адресою."
+
+#: src/addr2line.c:75
+msgid "Show demangled symbols (ARG is always ignored)"
+msgstr "Виводити розшифровані символи (АРГ завжди ігнорується)"
+
+#: src/addr2line.c:77
+msgid "Print all information on one line, and indent inlines"
+msgstr "Вивести усі дані у один рядок і додати відступи до перенесених рядків"
+
+#: src/addr2line.c:79 src/elfcmp.c:71 src/findtextrel.c:66 src/nm.c:101
+#: src/strings.c:79
+msgid "Miscellaneous:"
+msgstr "Інше:"
+
+#. Short description of program.
+#: src/addr2line.c:87
+msgid ""
+"Locate source files and line information for ADDRs (in a.out by default)."
+msgstr "Шукати АДРЕСИ у файлах кодів та даних про рядки (типово, у a.out)."
+
+#. Strings for arguments in help texts.
+#: src/addr2line.c:91
+msgid "[ADDR...]"
+msgstr "[АДРЕСА...]"
+
+#: src/addr2line.c:519
+#, c-format
+msgid "Section syntax requires exactly one module"
+msgstr "Синтаксис розділів вимагає точного одного модуля"
+
+#: src/addr2line.c:542
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside section '%s'"
+msgstr "зміщення %#<PRIxMAX> розташовано поза межами розділу «%s»"
+
+#: src/addr2line.c:632
+#, c-format
+msgid "cannot find symbol '%s'"
+msgstr "не вдалося знайти символ «%s»"
+
+#: src/addr2line.c:637
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside contents of '%s'"
+msgstr "зміщення %#<PRIxMAX> розташовано поза межами вмісту «%s»"
+
+#: src/ar.c:68
+msgid "Commands:"
+msgstr "Команди:"
+
+#: src/ar.c:69
+msgid "Delete files from archive."
+msgstr "Вилучити файли з архіву."
+
+#: src/ar.c:70
+msgid "Move files in archive."
+msgstr "Пересунути файли до архіву."
+
+#: src/ar.c:71
+msgid "Print files in archive."
+msgstr "Надрукувати список файлів у архіві."
+
+#: src/ar.c:72
+msgid "Quick append files to archive."
+msgstr "Швидко додати файли до архіву."
+
+#: src/ar.c:74
+msgid "Replace existing or insert new file into archive."
+msgstr "Замінити поточний або вставити новий файл до архіву."
+
+#: src/ar.c:75
+msgid "Display content of archive."
+msgstr "Показати вміст архіву."
+
+#: src/ar.c:76
+msgid "Extract files from archive."
+msgstr "Видобути файли з архіву."
+
+#: src/ar.c:78
+msgid "Command Modifiers:"
+msgstr "Модифікатори команд:"
+
+#: src/ar.c:79
+msgid "Preserve original dates."
+msgstr "Зберігати початкові часові мітки."
+
+#: src/ar.c:80
+msgid "Use instance [COUNT] of name."
+msgstr "Використовувати екземпляр [НОМЕР] назви."
+
+#: src/ar.c:82
+msgid "Do not replace existing files with extracted files."
+msgstr "Не замінювати поточні файли видобутими."
+
+#: src/ar.c:83
+msgid "Allow filename to be truncated if necessary."
+msgstr "Уможливити, за потреби, обрізання назв файлів."
+
+#: src/ar.c:85
+msgid "Provide verbose output."
+msgstr "Докладний вивід даних."
+
+#: src/ar.c:86
+msgid "Force regeneration of symbol table."
+msgstr "Примусове повторне створення таблиці символів."
+
+#: src/ar.c:87
+msgid "Insert file after [MEMBER]."
+msgstr "Вставити файл після [ЕЛЕМЕНТ]."
+
+#: src/ar.c:88
+msgid "Insert file before [MEMBER]."
+msgstr "Вставити файл перед [ЕЛЕМЕНТ]."
+
+#: src/ar.c:89
+msgid "Same as -b."
+msgstr "Те саме, що і -b."
+
+#: src/ar.c:90
+msgid "Suppress message when library has to be created."
+msgstr "Придушити повідомлення, якщо має бути створено бібліотеку."
+
+#: src/ar.c:92
+msgid "Use full path for file matching."
+msgstr "Використовувати для порівняння повний шлях до файла."
+
+#: src/ar.c:93
+msgid "Update only older files in archive."
+msgstr "Оновлювати у архіві лише старіші файли."
+
+#. Short description of program.
+#: src/ar.c:99
+msgid "Create, modify, and extract from archives."
+msgstr "Створення, зміна архівів і видобування даних з архівів."
+
+#. Strings for arguments in help texts.
+#: src/ar.c:102
+msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]"
+msgstr "[ЕЛЕМЕНТ] [НОМЕР] АРХІВ [ФАЙЛ...]"
+
+#: src/ar.c:181
+#, c-format
+msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options"
+msgstr ""
+"модифікатори «a», «b» і «i» можна використовувати лише разом з параметрами "
+"«m» і «r»"
+
+#: src/ar.c:186
+#, c-format
+msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers"
+msgstr ""
+"Для модифікаторів «a», «b» та «i» слід використовувати параметр ЕЛЕМЕНТ"
+
+#: src/ar.c:202
+#, c-format
+msgid "'N' is only meaningful with the 'x' and 'd' options"
+msgstr "«N» має значення лише разом з параметрами «x» і «d»"
+
+#: src/ar.c:207
+#, c-format
+msgid "COUNT parameter required"
+msgstr "потрібен параметр НОМЕР"
+
+#: src/ar.c:219
+#, c-format
+msgid "invalid COUNT parameter %s"
+msgstr "некоректний параметр НОМЕР %s"
+
+#: src/ar.c:226
+#, c-format
+msgid "'%c' is only meaningful with the 'x' option"
+msgstr "«%c» має сенс лише у разі використання параметра «x»"
+
+#: src/ar.c:232
+#, c-format
+msgid "archive name required"
+msgstr "слід вказати назву архіву"
+
+#: src/ar.c:245
+#, c-format
+msgid "command option required"
+msgstr "має бути вказано параметр команди"
+
+#: src/ar.c:296
+#, c-format
+msgid "More than one operation specified"
+msgstr "Вказано більше за одну дію"
+
+#: src/ar.c:390
+#, c-format
+msgid "cannot open archive '%s'"
+msgstr "не вдалося відкрити архів «%s»"
+
+#: src/ar.c:400
+#, c-format
+msgid "cannot open archive '%s': %s"
+msgstr "не вдалося відкрити архів «%s»: %s"
+
+#: src/ar.c:404
+#, c-format
+msgid "%s: not an archive file"
+msgstr "%s: не є файлом архіву"
+
+#: src/ar.c:408
+#, c-format
+msgid "cannot stat archive '%s'"
+msgstr "не вдалося отримати дані архіву «%s» за допомогою stat"
+
+#: src/ar.c:420
+#, c-format
+msgid "no entry %s in archive\n"
+msgstr "у архіві немає запису %s\n"
+
+#: src/ar.c:473 src/ar.c:918 src/ar.c:1118
+#, c-format
+msgid "cannot create hash table"
+msgstr "не вдалося створити таблицю хешів"
+
+#: src/ar.c:480 src/ar.c:925 src/ar.c:1127
+#, c-format
+msgid "cannot insert into hash table"
+msgstr "не вдалося вставити запис до таблиці хешів"
+
+#: src/ar.c:488 src/ranlib.c:149
+#, c-format
+msgid "cannot stat '%s'"
+msgstr "не вдалося отримати дані з «%s» за допомогою stat"
+
+#: src/ar.c:584
+#, c-format
+msgid "cannot read content of %s: %s"
+msgstr "не вдалося прочитати вміст з %s: %s"
+
+#: src/ar.c:627
+#, c-format
+msgid "cannot open %.*s"
+msgstr "не вдалося відкрити %.*s"
+
+#: src/ar.c:649
+#, c-format
+msgid "failed to write %s"
+msgstr "не вдалося записати %s"
+
+#: src/ar.c:661
+#, c-format
+msgid "cannot change mode of %s"
+msgstr "не вдалося змінити права доступу до %s"
+
+#: src/ar.c:677
+#, c-format
+msgid "cannot change modification time of %s"
+msgstr "не вдалося змінити часову мітку зміни %s"
+
+#: src/ar.c:723
+#, c-format
+msgid "cannot rename temporary file to %.*s"
+msgstr "не вдалося перейменувати файл тимчасових даних на %.*s"
+
+#: src/ar.c:759 src/ar.c:1010 src/ar.c:1409 src/ranlib.c:223
+#, c-format
+msgid "cannot create new file"
+msgstr "не вдалося створити файл"
+
+#: src/ar.c:1209
+#, c-format
+msgid "position member %s not found"
+msgstr "не виявлено елемента позиції %s"
+
+#: src/ar.c:1219
+#, c-format
+msgid "%s: no entry %s in archive!\n"
+msgstr "%s: у архіві немає запису %s!\n"
+
+#: src/ar.c:1248 src/objdump.c:242
+#, c-format
+msgid "cannot open %s"
+msgstr "не вдалося відкрити %s"
+
+#: src/ar.c:1253
+#, c-format
+msgid "cannot stat %s"
+msgstr "не вдалося отримати дані %s за допомогою stat"
+
+#: src/ar.c:1259
+#, c-format
+msgid "%s is no regular file"
+msgstr "%s не є звичайним файлом"
+
+#: src/ar.c:1272
+#, c-format
+msgid "cannot get ELF descriptor for %s: %s\n"
+msgstr "не вдалося отримати дескриптор ELF для %s: %s\n"
+
+#: src/ar.c:1292
+#, c-format
+msgid "cannot read %s: %s"
+msgstr "не вдалося прочитати %s: %s"
+
+#: src/arlib-argp.c:32
+msgid "Use zero for uid, gid, and date in archive members."
+msgstr ""
+"Використовувати нульове значення для uid, gid, та дати у елементах архіву."
+
+#: src/arlib-argp.c:34
+msgid "Use actual uid, gid, and date in archive members."
+msgstr ""
+"Використовувати поточні значення для uid, gid, та дати у елементах архіву."
+
+#: src/arlib-argp.c:65
+#, c-format
+msgid "%s (default)"
+msgstr "%s (типово)"
+
+#. The archive is too big.
+#: src/arlib.c:213
+#, c-format
+msgid "the archive '%s' is too large"
+msgstr "розмір архіву «%s» є занадто великим"
+
+#: src/arlib.c:226
+#, c-format
+msgid "cannot read ELF header of %s(%s): %s"
+msgstr "не вдалося прочитати заголовок ELF з %s(%s): %s"
+
+#: src/elfcmp.c:61
+msgid "Control options:"
+msgstr "Параметри керування:"
+
+#: src/elfcmp.c:63
+msgid "Output all differences, not just the first"
+msgstr "Показати всі відмінності, не лише першу з них"
+
+#: src/elfcmp.c:64
+msgid ""
+"Control treatment of gaps in loadable segments [ignore|match] (default: "
+"ignore)"
+msgstr ""
+"Керування обробкою проміжків у придатних до завантаження сегментах [ignore|"
+"match] (типово, ignore)"
+
+#: src/elfcmp.c:66
+msgid "Ignore permutation of buckets in SHT_HASH section"
+msgstr "Ігнорувати переставляння блоків у розділі SHT_HASH"
+
+#: src/elfcmp.c:68
+msgid "Ignore differences in build ID"
+msgstr "Ігнорувати відмінності у ідентифікаторі збирання"
+
+#: src/elfcmp.c:69
+msgid "Output nothing; yield exit status only"
+msgstr "Нічого не виводити; визначити лише стан виходу"
+
+#. Short description of program.
+#: src/elfcmp.c:76
+msgid "Compare relevant parts of two ELF files for equality."
+msgstr "Порівнює відповідні частини двох файлів ELF."
+
+#. Strings for arguments in help texts.
+#: src/elfcmp.c:80
+msgid "FILE1 FILE2"
+msgstr "ФАЙЛ1 ФАЙЛ2"
+
+#: src/elfcmp.c:142
+msgid "Invalid number of parameters.\n"
+msgstr "Некоректна кількість параметрів.\n"
+
+#: src/elfcmp.c:173 src/elfcmp.c:178
+#, c-format
+msgid "cannot get ELF header of '%s': %s"
+msgstr "не вдалося отримати заголовок ELF «%s»: %s"
+
+#: src/elfcmp.c:204
+#, c-format
+msgid "%s %s diff: ELF header"
+msgstr "%s %s diff: заголовок ELF"
+
+#: src/elfcmp.c:211 src/elfcmp.c:214
+#, c-format
+msgid "cannot get section count of '%s': %s"
+msgstr "не вдалося отримати даних щодо кількості розділів «%s»: %s"
+
+#: src/elfcmp.c:219
+#, c-format
+msgid "%s %s diff: section count"
+msgstr "%s %s diff: кількість розділів"
+
+#: src/elfcmp.c:226 src/elfcmp.c:229
+#, c-format
+msgid "cannot get program header count of '%s': %s"
+msgstr ""
+"не вдалося отримати даних щодо кількості заголовків програми у «%s»: %s"
+
+#: src/elfcmp.c:234
+#, c-format
+msgid "%s %s diff: program header count"
+msgstr "%s %s diff: кількість заголовків програми"
+
+#: src/elfcmp.c:292
+#, c-format
+msgid "%s %s differ: section [%zu], [%zu] name"
+msgstr "%s %s diff: розділ [%zu], назва [%zu]"
+
+#: src/elfcmp.c:315
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' header"
+msgstr "%s %s diff: розділ [%zu] заголовок «%s»"
+
+#: src/elfcmp.c:323 src/elfcmp.c:329
+#, c-format
+msgid "cannot get content of section %zu in '%s': %s"
+msgstr "не вдалося отримати вміст розділу %zu у «%s»: %s"
+
+#: src/elfcmp.c:338
+#, c-format
+msgid "symbol table [%zu] in '%s' has zero sh_entsize"
+msgstr "таблиця символів [%zu] у «%s» містить нульове значення sh_entsize"
+
+#: src/elfcmp.c:350 src/elfcmp.c:356
+#, c-format
+msgid "cannot get symbol in '%s': %s"
+msgstr "не вдалося отримати символ у «%s»: %s"
+
+#: src/elfcmp.c:378
+#, c-format
+msgid "%s %s differ: symbol table [%zu]"
+msgstr "%s %s diff: таблиця символів [%zu]"
+
+#: src/elfcmp.c:381
+#, c-format
+msgid "%s %s differ: symbol table [%zu,%zu]"
+msgstr "%s %s diff: таблиця символів [%zu,%zu]"
+
+#: src/elfcmp.c:428 src/elfcmp.c:498
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' number of notes"
+msgstr "%s %s diff: розділ [%zu] кількість нотаток «%s»"
+
+#: src/elfcmp.c:436
+#, c-format
+msgid "cannot read note section [%zu] '%s' in '%s': %s"
+msgstr "не вдалося прочитати розділ нотаток [%zu] «%s» у «%s»: %s"
+
+#: src/elfcmp.c:447
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note name"
+msgstr "%s %s diff: розділ [%zu] назва нотатки «%s»"
+
+#: src/elfcmp.c:455
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note '%s' type"
+msgstr "%s %s diff: розділ [%zu] нотатка «%s» тип «%s»"
+
+#: src/elfcmp.c:470
+#, c-format
+msgid "%s %s differ: build ID length"
+msgstr "%s %s diff: довжина ідентифікатора збирання"
+
+#: src/elfcmp.c:478
+#, c-format
+msgid "%s %s differ: build ID content"
+msgstr "%s %s diff: вміст ідентифікатора збирання"
+
+#: src/elfcmp.c:487
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' note '%s' content"
+msgstr "%s %s diff: розділ [%zu] нотатка «%s» вміст «%s»"
+
+#: src/elfcmp.c:528
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' content"
+msgstr "%s %s diff: розділ [%zu] «%s», вміст"
+
+#: src/elfcmp.c:532
+#, c-format
+msgid "%s %s differ: section [%zu,%zu] '%s' content"
+msgstr "%s %s diff: розділ [%zu,%zu] «%s», вміст"
+
+#: src/elfcmp.c:547
+#, c-format
+msgid "%s %s differ: unequal amount of important sections"
+msgstr "%s %s diff: невідповідність об’ємів важливих розділів"
+
+#: src/elfcmp.c:580 src/elfcmp.c:585
+#, c-format
+msgid "cannot load data of '%s': %s"
+msgstr "не вдалося завантажити дані «%s»: %s"
+
+#: src/elfcmp.c:604 src/elfcmp.c:610
+#, c-format
+msgid "cannot get program header entry %d of '%s': %s"
+msgstr "не вдалося отримати запис заголовка програми %d «%s»: %s"
+
+#: src/elfcmp.c:616
+#, c-format
+msgid "%s %s differ: program header %d"
+msgstr "%s %s diff: заголовок програми %d"
+
+#: src/elfcmp.c:640
+#, c-format
+msgid "%s %s differ: gap"
+msgstr "%s %s diff: проміжок"
+
+#: src/elfcmp.c:691
+#, c-format
+msgid "Invalid value '%s' for --gaps parameter."
+msgstr "Некоректне значення «%s» параметра --gaps."
+
+#: src/elfcmp.c:719 src/findtextrel.c:206 src/nm.c:365 src/ranlib.c:142
+#: src/size.c:273 src/strings.c:186 src/strip.c:518 src/strip.c:555
+#: src/unstrip.c:2023 src/unstrip.c:2052
+#, c-format
+msgid "cannot open '%s'"
+msgstr "не вдалося відкрити «%s»"
+
+#: src/elfcmp.c:723 src/findtextrel.c:213 src/ranlib.c:159
+#, c-format
+msgid "cannot create ELF descriptor for '%s': %s"
+msgstr "не вдалося створити дескриптор ELF для «%s»: %s"
+
+#: src/elfcmp.c:728
+#, c-format
+msgid "cannot create EBL descriptor for '%s'"
+msgstr "не вдалося створити дескриптор EBL для «%s»"
+
+#: src/elfcmp.c:746 src/findtextrel.c:394
+#, c-format
+msgid "cannot get section header of section %zu: %s"
+msgstr "не вдалося отримати заголовок розділу %zu: %s"
+
+#: src/elfcmp.c:756
+#, c-format
+msgid "cannot get content of section %zu: %s"
+msgstr "не вдалося отримати вміст розділу %zu: %s"
+
+#: src/elfcmp.c:766 src/elfcmp.c:780
+#, c-format
+msgid "cannot get relocation: %s"
+msgstr "не вдалося отримати пересування: %s"
+
+#: src/elfcompress.c:115 src/strip.c:297 src/unstrip.c:121
+#, c-format
+msgid "-o option specified twice"
+msgstr "параметр -o вказано двічі"
+
+#: src/elfcompress.c:122
+#, fuzzy, c-format
+msgid "-t option specified twice"
+msgstr "параметр -f вказано двічі"
+
+#: src/elfcompress.c:131
+#, fuzzy, c-format
+msgid "unknown compression type '%s'"
+msgstr "невизначений тип"
+
+#. We need at least one input file.
+#: src/elfcompress.c:143 src/elfcompress.c:1305
+#, fuzzy, c-format
+msgid "No input file given"
+msgstr "вхідний файл є порожнім"
+
+#: src/elfcompress.c:149 src/elfcompress.c:1310
+#, fuzzy, c-format
+msgid "Only one input file allowed together with '-o'"
+msgstr ""
+"Разом з «-o» або «-f» можна використовувати лише один файл вхідних даних"
+
+#: src/elfcompress.c:1267
+#, fuzzy
+msgid "Place (de)compressed output into FILE"
+msgstr "Вивести дані після вилучення до ФАЙЛа"
+
+#: src/elfcompress.c:1270
+msgid ""
+"What type of compression to apply. TYPE can be 'none' (decompress), "
+"'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-"
+"gnu' (.zdebug GNU style compression, 'gnu' is an alias)"
+msgstr ""
+
+#: src/elfcompress.c:1273
+msgid ""
+"SECTION name to (de)compress, SECTION is an extended wildcard pattern "
+"(defaults to '.?(z)debug*')"
+msgstr ""
+
+#: src/elfcompress.c:1276
+msgid "Print a message for each section being (de)compressed"
+msgstr ""
+
+#: src/elfcompress.c:1279
+msgid "Force compression of section even if it would become larger"
+msgstr ""
+
+#: src/elfcompress.c:1282 src/strip.c:91
+msgid "Relax a few rules to handle slightly broken ELF files"
+msgstr ""
+"Знехтувати декількома правилами для обробки трохи пошкоджених файлів ELF"
+
+#: src/elfcompress.c:1285
+#, fuzzy
+msgid "Be silent when a section cannot be compressed"
+msgstr ""
+"розділ [%2zu] «%s»: адреса розділів локальних даних потоків не є нульовою\n"
+
+#. Strings for arguments in help texts.
+#: src/elfcompress.c:1294 src/elflint.c:78 src/readelf.c:142
+msgid "FILE..."
+msgstr "ФАЙЛ..."
+
+#: src/elfcompress.c:1295
+msgid "Compress or decompress sections in an ELF file."
+msgstr ""
+
+#: src/elflint.c:64
+msgid "Be extremely strict, flag level 2 features."
+msgstr "Висока строгість, увімкнути можливості рівня 2."
+
+#: src/elflint.c:65
+msgid "Do not print anything if successful"
+msgstr "Не виводити ніяких даних у разі успіху"
+
+#: src/elflint.c:66
+msgid "Binary is a separate debuginfo file"
+msgstr "Бінарний файл є окремим файлом debuginfo"
+
+#: src/elflint.c:68
+msgid ""
+"Binary has been created with GNU ld and is therefore known to be broken in "
+"certain ways"
+msgstr ""
+"Бінарний файл було створено за допомогою GNU ld, тому він, очевидно, є до "
+"певної міри неправильним"
+
+#. Short description of program.
+#: src/elflint.c:74
+msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
+msgstr ""
+"Педантична перевірка файлів ELF на сумісність зі специфікаціями gABI/psABI."
+
+#: src/elflint.c:155 src/readelf.c:317
+#, c-format
+msgid "cannot open input file"
+msgstr "не вдалося відкрити вхідний файл."
+
+#: src/elflint.c:162
+#, c-format
+msgid "cannot generate Elf descriptor: %s\n"
+msgstr "не вдалося створити дескриптор Elf: %s\n"
+
+#: src/elflint.c:181
+#, c-format
+msgid "error while closing Elf descriptor: %s\n"
+msgstr "помилка під час спроби закриття дескриптора Elf: %s\n"
+
+#: src/elflint.c:185
+msgid "No errors"
+msgstr "Без помилок"
+
+#: src/elflint.c:220 src/readelf.c:494
+msgid "Missing file name.\n"
+msgstr "Не вказано назви файла.\n"
+
+#: src/elflint.c:285
+#, c-format
+msgid " error while freeing sub-ELF descriptor: %s\n"
+msgstr " помилка під час спроби вивільнення дескриптора суб-ELF: %s\n"
+
+#. We cannot do anything.
+#: src/elflint.c:293
+#, c-format
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr "Не є файлом ELF. Виявлено помилкові магічні байти на початку файла\n"
+
+#: src/elflint.c:358
+#, c-format
+msgid "e_ident[%d] == %d is no known class\n"
+msgstr "e_ident[%d] == %d не є відомим класом\n"
+
+#: src/elflint.c:363
+#, c-format
+msgid "e_ident[%d] == %d is no known data encoding\n"
+msgstr "e_ident[%d] == %d не є відомим кодуванням даних\n"
+
+#: src/elflint.c:367
+#, c-format
+msgid "unknown ELF header version number e_ident[%d] == %d\n"
+msgstr "невідомий номер версії заголовка ELF e_ident[%d] == %d\n"
+
+#: src/elflint.c:375
+#, c-format
+msgid "unsupported OS ABI e_ident[%d] == '%s'\n"
+msgstr "непідтримуване ABI ОС e_ident[%d] == «%s»\n"
+
+#: src/elflint.c:381
+#, c-format
+msgid "unsupport ABI version e_ident[%d] == %d\n"
+msgstr "непідтримувана версія ABI e_ident[%d] == %d\n"
+
+#: src/elflint.c:386
+#, c-format
+msgid "e_ident[%zu] is not zero\n"
+msgstr "e_ident[%zu] не дорівнює нулеві\n"
+
+#: src/elflint.c:391
+#, c-format
+msgid "unknown object file type %d\n"
+msgstr "невідомий тип об’єктних файлів %d\n"
+
+#: src/elflint.c:398
+#, c-format
+msgid "unknown machine type %d\n"
+msgstr "невідомий тип архітектури %d\n"
+
+#: src/elflint.c:402
+#, c-format
+msgid "unknown object file version\n"
+msgstr "невідома версія об’єктних файлів\n"
+
+#: src/elflint.c:408
+#, c-format
+msgid "invalid program header offset\n"
+msgstr "некоректне зміщення заголовка програми\n"
+
+#: src/elflint.c:410
+#, c-format
+msgid "executables and DSOs cannot have zero program header offset\n"
+msgstr ""
+"виконувані файли і DSO не можуть містити заголовка програми з нульовим "
+"зміщенням\n"
+
+#: src/elflint.c:414
+#, c-format
+msgid "invalid number of program header entries\n"
+msgstr "некоректна кількість записів заголовків програми\n"
+
+#: src/elflint.c:422
+#, c-format
+msgid "invalid section header table offset\n"
+msgstr "некоректне зміщення таблиці заголовків розділів\n"
+
+#: src/elflint.c:425
+#, c-format
+msgid "section header table must be present\n"
+msgstr "має бути вказано таблицю заголовків розділів\n"
+
+#: src/elflint.c:439
+#, c-format
+msgid "invalid number of section header table entries\n"
+msgstr "некоректна кількість записів таблиці заголовків розділів\n"
+
+#: src/elflint.c:456
+#, c-format
+msgid "invalid section header index\n"
+msgstr "некоректний індекс заголовка розділу\n"
+
+#: src/elflint.c:474
+#, c-format
+msgid "Can only check %u headers, shnum was %u\n"
+msgstr ""
+
+#: src/elflint.c:488
+#, c-format
+msgid "invalid number of program header table entries\n"
+msgstr "некоректна кількість записів таблиці заголовків програми\n"
+
+#: src/elflint.c:505
+#, c-format
+msgid "Can only check %u headers, phnum was %u\n"
+msgstr ""
+
+#: src/elflint.c:510
+#, c-format
+msgid "invalid machine flags: %s\n"
+msgstr "некоректні прапорці архітектури: %s\n"
+
+#: src/elflint.c:517 src/elflint.c:534
+#, c-format
+msgid "invalid ELF header size: %hd\n"
+msgstr "некоректний розмір заголовка ELF: %hd\n"
+
+#: src/elflint.c:520 src/elflint.c:537
+#, c-format
+msgid "invalid program header size: %hd\n"
+msgstr "некоректний розмір заголовка програми: %hd\n"
+
+#: src/elflint.c:523 src/elflint.c:540
+#, c-format
+msgid "invalid program header position or size\n"
+msgstr "некоректне розташування або розмір заголовка програми\n"
+
+#: src/elflint.c:526 src/elflint.c:543
+#, c-format
+msgid "invalid section header size: %hd\n"
+msgstr "некоректний розмір заголовка розділу: %hd\n"
+
+#: src/elflint.c:529 src/elflint.c:546
+#, c-format
+msgid "invalid section header position or size\n"
+msgstr "некоректне розташування або розмір заголовка розділу\n"
+
+#: src/elflint.c:591
+#, c-format
+msgid ""
+"section [%2d] '%s': section with SHF_GROUP flag set not part of a section "
+"group\n"
+msgstr ""
+"розділ [%2d] «%s»: розділ з встановленим прапорцем SHF_GROUP не є частиною "
+"групи розділів\n"
+
+#: src/elflint.c:595
+#, c-format
+msgid ""
+"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"
+msgstr ""
+"розділ [%2d] «%s»: групу розділів [%2zu] «%s» мало бути визначено до розділу-"
+"елемента цієї групи\n"
+
+#: src/elflint.c:611 src/elflint.c:1495 src/elflint.c:1546 src/elflint.c:1652
+#: src/elflint.c:1988 src/elflint.c:2311 src/elflint.c:2930 src/elflint.c:3093
+#: src/elflint.c:3241 src/elflint.c:3431 src/elflint.c:4399
+#, c-format
+msgid "section [%2d] '%s': cannot get section data\n"
+msgstr "розділ [%2d] «%s»: не вдалося отримати дані розділу\n"
+
+#: src/elflint.c:624 src/elflint.c:1659
+#, c-format
+msgid ""
+"section [%2d] '%s': referenced as string table for section [%2d] '%s' but "
+"type is not SHT_STRTAB\n"
+msgstr ""
+"розділ [%2d] «%s»: надано посилання на таблицю рядків розділу [%2d] «%s», "
+"але типом даних не є SHT_STRTAB\n"
+
+#: src/elflint.c:647
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol table cannot have more than one extended index "
+"section\n"
+msgstr ""
+"розділ [%2d] «%s»: у таблиці символів не може бути більше одного розширеного "
+"розділу покажчика\n"
+
+#: src/elflint.c:659
+#, c-format
+msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n"
+msgstr "розділ [%2u] «%s»: розмірність запису не відповідає ElfXX_Sym\n"
+
+#: src/elflint.c:668
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %d: %s\n"
+msgstr "розділ [%2d] «%s»: не вдалося отримати символ %d: %s\n"
+
+#: src/elflint.c:673 src/elflint.c:676 src/elflint.c:679 src/elflint.c:682
+#: src/elflint.c:685 src/elflint.c:688
+#, c-format
+msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n"
+msgstr "розділ [%2d] «%s»: «%s» у нульовому записі не є нулем\n"
+
+#: src/elflint.c:691
+#, c-format
+msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n"
+msgstr "розділ [%2d] «%s»: XINDEX для нульового запису не є нулем\n"
+
+#: src/elflint.c:701
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %zu: %s\n"
+msgstr "розділ [%2d] «%s»: не вдалося отримати символ %zu: %s\n"
+
+#: src/elflint.c:710
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid name value\n"
+msgstr "розділ [%2d] «%s»: символ %zu: некоректне значення назви\n"
+
+#: src/elflint.c:725
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: too large section index but no extended "
+"section index section\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: занадто великий покажчик розділу за умови, що "
+"не визначено розділу розширеного покажчика розділів\n"
+
+#: src/elflint.c:731
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in "
+"st_shndx (%<PRIu32>)\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: XINDEX використано для індексування, яке не "
+"відповідає st_shndx (%<PRIu32>)\n"
+
+#. || sym->st_shndx > SHN_HIRESERVE  always false
+#: src/elflint.c:743
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid section index\n"
+msgstr "розділ [%2d] «%s»: символ %zu: некоректний індекс розділу\n"
+
+#: src/elflint.c:751
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown type\n"
+msgstr "розділ [%2d] «%s»: символ %zu: невідомий тип\n"
+
+#: src/elflint.c:757
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown symbol binding\n"
+msgstr "розділ [%2d] «%s»: символ %zu: невідома прив’язка символу\n"
+
+#: src/elflint.c:762
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unique symbol not of object type\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: унікальний символ, що не належить до типу "
+"об’єктів\n"
+
+#: src/elflint.c:770
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: COMMON можна використовувати лише у файлах, "
+"придатних до пересування\n"
+
+#: src/elflint.c:774
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: використання локальних символів COMMON "
+"позбавлене сенсу\n"
+
+#: src/elflint.c:778
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: використання функції у розділі COMMON "
+"позбавлене сенсу\n"
+
+#: src/elflint.c:829
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: st_value out of bounds\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: значення st_value поза можливим діапазоном\n"
+
+#: src/elflint.c:835 src/elflint.c:860 src/elflint.c:909
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu does not fit completely in referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu не повністю відповідає розділу, на який "
+"посилається, [%2d] «%s»\n"
+
+#: src/elflint.c:844
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have "
+"SHF_TLS flag set\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: для розділу посилання [%2d] «%s» не "
+"встановлено прапорець SHF_TLS\n"
+
+#: src/elflint.c:854 src/elflint.c:902
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: значення st_value поза межами розділу "
+"посилання, [%2d] «%s»\n"
+
+#: src/elflint.c:881
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: символ TLS без запису заголовка програми TLS\n"
+
+#: src/elflint.c:887
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but couldn't get TLS program "
+"header entry\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: маємо символ TLS, але не вдалося отримати "
+"запис заголовка програми TLS\n"
+
+#: src/elflint.c:895
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] "
+"'%s'\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: значення st_value перед розділом посилання, "
+"[%2d] «%s»\n"
+
+#: src/elflint.c:922
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: у sh_info описано локальний символ поза "
+"діапазоном\n"
+
+#: src/elflint.c:929
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: non-local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: у sh_info описано нелокальний символ поза "
+"діапазоном\n"
+
+#: src/elflint.c:936
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: non-local section symbol\n"
+msgstr "розділ [%2d] «%s»: символ %zu: нелокальний символ розділу\n"
+
+#: src/elflint.c:986
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section "
+"[%2d]\n"
+msgstr ""
+"розділ [%2d] «%s»: символ _GLOBAL_OFFSET_TABLE_  посилається на помилковий "
+"розділ, [%2d]\n"
+
+#: src/elflint.c:993
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] "
+"'%s'\n"
+msgstr ""
+"розділ [%2d] «%s»: символ _GLOBAL_OFFSET_TABLE_  посилається на розділ [%2d] "
+"'%s'\n"
+
+#. This test is more strict than the psABIs which
+#. usually allow the symbol to be in the middle of
+#. the .got section, allowing negative offsets.
+#: src/elflint.c:1009
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#<PRIx64> does not "
+"match %s section address %#<PRIx64>\n"
+msgstr ""
+"розділ [%2d] «%s»: значення символу _GLOBAL_OFFSET_TABLE_ %#<PRIx64> не "
+"відповідає адресі розділу %s %#<PRIx64>\n"
+
+#: src/elflint.c:1016
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %<PRIu64> does not "
+"match %s section size %<PRIu64>\n"
+msgstr ""
+"розділ [%2d] «%s»: розмір символу _GLOBAL_OFFSET_TABLE_ %<PRIu64> не "
+"відповідає розміру розділу %s %<PRIu64>\n"
+
+#: src/elflint.c:1024
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got "
+"section\n"
+msgstr ""
+"розділ [%2d] «%s»: виявлено символ _GLOBAL_OFFSET_TABLE_, але не виявлено "
+"розділу .got\n"
+
+#: src/elflint.c:1040
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC_ symbol value %#<PRIx64> does not match dynamic "
+"segment address %#<PRIx64>\n"
+msgstr ""
+"розділ [%2d] «%s»: значення символу _DYNAMIC_ %#<PRIx64> не відповідає "
+"адресі динамічного сегмента %#<PRIx64>\n"
+
+#: src/elflint.c:1047
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC symbol size %<PRIu64> does not match dynamic "
+"segment size %<PRIu64>\n"
+msgstr ""
+"розділ [%2d] «%s»: розмір символу _DYNAMIC %<PRIu64> не відповідає розміру "
+"динамічного сегмента %<PRIu64>\n"
+
+#: src/elflint.c:1060
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-"
+"default visibility\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %zu: символ у динамічній таблиці символів з "
+"нетиповою видимістю\n"
+
+#: src/elflint.c:1064
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"
+msgstr "розділ [%2d] «%s»: символ %zu: невідомий набір бітів у st_other\n"
+
+#: src/elflint.c:1102
+#, c-format
+msgid "section [%2d] '%s': cannot get section data.\n"
+msgstr "розділ [%2d] «%s»: не вдалося отримати дані розділу.\n"
+
+#: src/elflint.c:1118
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"
+msgstr "розділ [%2d] «%s»: для цього розділу RELA використано DT_RELCOUNT\n"
+
+#: src/elflint.c:1129 src/elflint.c:1182
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"
+msgstr ""
+"розділ [%2d] «%s»: значення DT_RELCOUNT %d є занадто високим для цього "
+"розділу\n"
+
+#: src/elflint.c:1154 src/elflint.c:1207
+#, c-format
+msgid ""
+"section [%2d] '%s': relative relocations after index %d as specified by "
+"DT_RELCOUNT\n"
+msgstr ""
+"розділ [%2d] «%s»: відносні пересування після позиції %d, вказаної за "
+"допомогою DT_RELCOUNT\n"
+
+#: src/elflint.c:1160 src/elflint.c:1213
+#, c-format
+msgid ""
+"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT "
+"specified %d relative relocations\n"
+msgstr ""
+"розділ [%2d] «%s»: безвідносне пересування на позиції %zu; DT_RELCOUNT "
+"визначено %d відносних пересування\n"
+
+#: src/elflint.c:1172
+#, c-format
+msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n"
+msgstr "розділ [%2d] «%s»: для цього розділу REL використано DT_RELACOUNT\n"
+
+#: src/elflint.c:1255
+#, c-format
+msgid "section [%2d] '%s': invalid destination section index\n"
+msgstr "розділ [%2d] «%s»: некоректний індекс розділу призначення\n"
+
+#: src/elflint.c:1267
+#, c-format
+msgid "section [%2d] '%s': invalid destination section type\n"
+msgstr "розділ [%2d] «%s»: некоректний тип розділу призначення\n"
+
+#: src/elflint.c:1275
+#, c-format
+msgid "section [%2d] '%s': sh_info should be zero\n"
+msgstr "розділ [%2d] «%s»: sh_info має бути нульовим\n"
+
+#: src/elflint.c:1283
+#, fuzzy, c-format
+msgid ""
+"section [%2d] '%s': no relocations for merge-able string sections possible\n"
+msgstr ""
+"розділ [%2d] «%s»: пересування у придатних до об’єднання розділах неможливе\n"
+
+#: src/elflint.c:1291
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n"
+msgstr ""
+"розділ [%2d] «%s»: розмірність запису розділу не відповідає ElfXX_Rela\n"
+
+#: src/elflint.c:1351
+#, c-format
+msgid "text relocation flag set but there is no read-only segment\n"
+msgstr ""
+"встановлено прапорець пересування тексту, але сегмент придатний лише до "
+"читання\n"
+
+#: src/elflint.c:1378
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid type\n"
+msgstr "розділ [%2d] «%s»: пересування %zu: некоректний тип\n"
+
+#: src/elflint.c:1386
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: relocation type invalid for the file "
+"type\n"
+msgstr ""
+"розділ [%2d] «%s»: пересування %zu: некоректний тип пересування для типу "
+"файла\n"
+
+#: src/elflint.c:1394
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n"
+msgstr "розділ [%2d] «%s»: пересування %zu: некоректний індекс символу\n"
+
+#: src/elflint.c:1412
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can "
+"be used with %s\n"
+msgstr ""
+"розділ [%2d] «%s»: пересування %zu: з %s можна використовувати лише символ "
+"«_GLOBAL_OFFSET_TABLE_»\n"
+
+#: src/elflint.c:1429
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n"
+msgstr "розділ [%2d] «%s»: пересування %zu: зміщення за межі діапазону\n"
+
+#: src/elflint.c:1444
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: copy relocation against symbol of type "
+"%s\n"
+msgstr ""
+"розділ [%2d] «%s»: пересування %zu: пересування копіювання для символу типу "
+"%s\n"
+
+#: src/elflint.c:1465
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: read-only section modified but text "
+"relocation flag not set\n"
+msgstr ""
+"розділ [%2d] «%s»: пересування %zu: змінено придатний лише для читання "
+"розділ, але не встановлено прапорець пересування тексту\n"
+
+#: src/elflint.c:1480
+#, c-format
+msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n"
+msgstr "розділ [%2d] «%s»: пересування завантажених і незавантажених даних\n"
+
+#: src/elflint.c:1520 src/elflint.c:1571
+#, c-format
+msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
+msgstr "розділ [%2d] «%s»: не вдалося отримати зміщення %zu: %s\n"
+
+#: src/elflint.c:1647
+#, c-format
+msgid "more than one dynamic section present\n"
+msgstr "вказано більше одного динамічного розділу\n"
+
+#: src/elflint.c:1665
+#, c-format
+msgid ""
+"section [%2d]: referenced as string table for section [%2d] '%s' but section "
+"link value is invalid\n"
+msgstr ""
+"розділ [%2d]: надано посилання на таблицю рядків розділу [%2d] «%s», але "
+"значення посилання на розділ є некоректним\n"
+
+#: src/elflint.c:1673
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"
+msgstr ""
+"розділ [%2d] «%s»: розмірність запису розділу не відповідає ElfXX_Dyn\n"
+
+#: src/elflint.c:1678 src/elflint.c:1967
+#, c-format
+msgid "section [%2d] '%s': sh_info not zero\n"
+msgstr "розділ [%2d] «%s»: sh_info не є нульовим\n"
+
+#: src/elflint.c:1688
+#, c-format
+msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"
+msgstr ""
+"розділ [%2d] «%s»: не вдалося отримати запис динамічного розділу %zu: %s\n"
+
+#: src/elflint.c:1696
+#, c-format
+msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"
+msgstr ""
+"розділ [%2d] «%s»: за записом DT_NULL вказано записи, що не належать до "
+"DT_NULL\n"
+
+#: src/elflint.c:1703
+#, c-format
+msgid "section [%2d] '%s': entry %zu: unknown tag\n"
+msgstr "розділ [%2d] «%s»: запис %zu: невідома мітка\n"
+
+#: src/elflint.c:1714
+#, c-format
+msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n"
+msgstr "розділ [%2d] «%s»: запис %zu: декілька записів з міткою %s\n"
+
+#: src/elflint.c:1724
+#, c-format
+msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n"
+msgstr "розділ [%2d] «%s»: запис %zu: використано мітку рівня 2 %s\n"
+
+#: src/elflint.c:1742
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"
+msgstr ""
+"розділ [%2d] «%s»: запис %zu: значенням DT_PLTREL має бути DT_REL або "
+"DT_RELA\n"
+
+#: src/elflint.c:1755
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: pointer does not match address of section "
+"[%2d] '%s' referenced by sh_link\n"
+msgstr ""
+"розділ [%2d] «%s»: розділ %zu: вказівник не відповідає адресі розділу [%2d] "
+"«%s», на яку посилається sh_link\n"
+
+#: src/elflint.c:1798
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"
+msgstr ""
+"розділ [%2d] «%s»: запис %zu: значення %s має вказувати на завантажений "
+"сегмент\n"
+
+#: src/elflint.c:1813
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must be valid offset in section "
+"[%2d] '%s'\n"
+msgstr ""
+"розділ [%2d] «%s»: запис %zu: значенням %s має бути коректне зміщення у "
+"розділі [%2d] «%s»\n"
+
+#: src/elflint.c:1833 src/elflint.c:1861
+#, c-format
+msgid "section [%2d] '%s': contains %s entry but not %s\n"
+msgstr "розділ [%2d] «%s»: містить запис %s, але не %s\n"
+
+#: src/elflint.c:1845
+#, c-format
+msgid "section [%2d] '%s': mandatory tag %s not present\n"
+msgstr "розділ [%2d] «%s»: немає обов’язкової мітки %s\n"
+
+#: src/elflint.c:1854
+#, c-format
+msgid "section [%2d] '%s': no hash section present\n"
+msgstr "розділ [%2d] «%s»: не виявлено розділу хешів\n"
+
+#: src/elflint.c:1869 src/elflint.c:1876
+#, c-format
+msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n"
+msgstr "розділ [%2d] «%s»: вказано не всі зі значень %s, %s і %s\n"
+
+#: src/elflint.c:1886 src/elflint.c:1890
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"
+msgstr ""
+"розділ [%2d] «%s»: у DSO, позначеному на кроці попереднього компонування, "
+"немає мітки %s\n"
+
+#: src/elflint.c:1896
+#, c-format
+msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n"
+msgstr ""
+"розділ [%2d] «%s»: під час попереднього компонування як залежність позначено "
+"файл, який не є файлом DSO\n"
+
+#: src/elflint.c:1907 src/elflint.c:1911 src/elflint.c:1915 src/elflint.c:1919
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in prelinked executable\n"
+msgstr ""
+"розділ [%2d] «%s»: у попередньо скомпонованому виконуваному файлі не "
+"міститься мітки %s\n"
+
+#: src/elflint.c:1931
+#, c-format
+msgid ""
+"section [%2d] '%s': only relocatable files can have extended section index\n"
+msgstr ""
+"розділ [%2d] «%s»: розширений розділ покажчика можуть мати лише файли, "
+"придатні до пересування\n"
+
+#: src/elflint.c:1941
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index section not for symbol table\n"
+msgstr ""
+"розділ [%2d] «%s»: розділ розширеного покажчика розділів не призначено для "
+"таблиць символів\n"
+
+#: src/elflint.c:1945
+#, c-format
+msgid "section [%2d] '%s': sh_link extended section index [%2d] is invalid\n"
+msgstr ""
+"розділ [%2d] «%s»: індекс розширеного розділу sh_link [%2d] є некоректним\n"
+
+#: src/elflint.c:1950
+#, c-format
+msgid "cannot get data for symbol section\n"
+msgstr "не вдалося отримати дані для розділу символів\n"
+
+#: src/elflint.c:1953
+#, c-format
+msgid "section [%2d] '%s': entry size does not match Elf32_Word\n"
+msgstr "розділ [%2d] «%s»: розмірність запису не відповідає Elf32_Word\n"
+
+#: src/elflint.c:1962
+#, c-format
+msgid "section [%2d] '%s': extended index table too small for symbol table\n"
+msgstr ""
+"розділ [%2d] «%s»: розширена таблиця покажчика замала для таблиці символів\n"
+
+#: src/elflint.c:1977
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to "
+"same symbol table\n"
+msgstr ""
+"розділ [%2d] «%s»: розширений покажчик розділів у розділі [%2zu] «%s» "
+"посилається на ту саму таблицю розділів\n"
+
+#: src/elflint.c:1995
+#, c-format
+msgid "symbol 0 should have zero extended section index\n"
+msgstr "символу 0 має відповідати нульовий індекс розширеного розділу\n"
+
+#: src/elflint.c:2007
+#, c-format
+msgid "cannot get data for symbol %zu\n"
+msgstr "не вдалося отримати дані для символу %zu\n"
+
+#: src/elflint.c:2012
+#, c-format
+msgid "extended section index is %<PRIu32> but symbol index is not XINDEX\n"
+msgstr ""
+"індекс розширеного розділу дорівнює %<PRIu32>, але індекс символу не є "
+"XINDEX\n"
+
+#: src/elflint.c:2029 src/elflint.c:2083
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"
+msgstr ""
+"розділ [%2d] «%s»: розділ таблиці хешів занадто малий (розмір %ld, мало бути "
+"— %ld)\n"
+
+#: src/elflint.c:2043 src/elflint.c:2097
+#, c-format
+msgid "section [%2d] '%s': chain array too large\n"
+msgstr "розділ [%2d] «%s»: масив ланцюжка занадто великий\n"
+
+#: src/elflint.c:2057 src/elflint.c:2111
+#, c-format
+msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n"
+msgstr ""
+"розділ [%2d] «%s»: посилання на хеш блоку %zu лежить поза межами діапазону\n"
+
+#: src/elflint.c:2067
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n"
+msgstr ""
+"розділ [%2d] «%s»: посилання ланцюжка хешів %zu лежить поза межами "
+"діапазону\n"
+
+#: src/elflint.c:2121
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %<PRIu64> out of bounds\n"
+msgstr ""
+"розділ [%2d] «%s»: посилання ланцюжка хешів %<PRIu64> лежить поза межами "
+"діапазону\n"
+
+#: src/elflint.c:2134
+#, c-format
+msgid "section [%2d] '%s': not enough data\n"
+msgstr "розділ [%2d] «%s»: недостатньо даних\n"
+
+#: src/elflint.c:2146
+#, c-format
+msgid "section [%2d] '%s': bitmask size zero or not power of 2: %u\n"
+msgstr ""
+"розділ [%2d] «%s»: розмір бітової маски є нульовим або не є степенем 2: %u\n"
+
+#: src/elflint.c:2162
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected at "
+"least %ld)\n"
+msgstr ""
+"розділ [%2d] «%s»: розділ таблиці хешів є надто малим (маємо %ld, мало бути "
+"принаймні %ld)\n"
+
+#: src/elflint.c:2171
+#, c-format
+msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n"
+msgstr "розділ [%2d] «%s»: зсув 2-ої функції хешування занадто великий: %u\n"
+
+#: src/elflint.c:2205
+#, c-format
+msgid ""
+"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"
+msgstr ""
+"розділ [%2d] '%s': ланцюжок хешів для блоку %zu розташовано нижче за позицію "
+"відхилення індексу символу\n"
+
+#: src/elflint.c:2226
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is "
+"undefined\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %u, на який посилається ланцюжок у блоці %zu не "
+"визначено\n"
+
+#: src/elflint.c:2239
+#, c-format
+msgid ""
+"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+"розділ [%2d] «%s»: значення хешу для символу %u у ланцюжку для блоку %zu є "
+"помилковим\n"
+
+#: src/elflint.c:2248
+#, c-format
+msgid ""
+"section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+"розділ [%2d] «%s»: індекс маски для символу %u у ланцюжку для блоку %zu є "
+"помилковим\n"
+
+#: src/elflint.c:2278
+#, c-format
+msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n"
+msgstr ""
+"розділ [%2d] «%s»: ланцюжок хешів для блоку %zu лежить поза межами "
+"діапазону\n"
+
+#: src/elflint.c:2283
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"
+msgstr ""
+"розділ [%2d] «%s»: посилання на символ у ланцюжку для блоку %zu лежить поза "
+"межами діапазону\n"
+
+#: src/elflint.c:2289
+#, c-format
+msgid "section [%2d] '%s': bitmask does not match names in the hash table\n"
+msgstr "розділ [%2d] «%s»: бітова маска не відповідає назвам у таблиці хешів\n"
+
+#: src/elflint.c:2302
+#, c-format
+msgid "section [%2d] '%s': relocatable files cannot have hash tables\n"
+msgstr ""
+"розділ [%2d] «%s»: придатні до пересування файли не можуть містити таблиць "
+"хешів\n"
+
+#: src/elflint.c:2320
+#, c-format
+msgid "section [%2d] '%s': hash table not for dynamic symbol table\n"
+msgstr ""
+"розділ [%2d] «%s»: таблицю хешів не призначено для зберігання таблиці "
+"динамічних символів\n"
+
+#: src/elflint.c:2324
+#, c-format
+msgid "section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n"
+msgstr ""
+"розділ [%2d] «%s»: некоректний індекс розділу таблиці символів sh_link "
+"[%2d]\n"
+
+#: src/elflint.c:2334
+#, c-format
+msgid "section [%2d] '%s': hash table entry size incorrect\n"
+msgstr "розділ [%2d] «%s»: розмірність запису таблиці хешів є некоректною\n"
+
+#: src/elflint.c:2339
+#, c-format
+msgid "section [%2d] '%s': not marked to be allocated\n"
+msgstr "розділ [%2d] «%s»: не позначено для пересування\n"
+
+#: src/elflint.c:2344
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table has not even room for initial administrative "
+"entries\n"
+msgstr ""
+"розділ [%2d] «%s»: у таблиці хешів виявлено незвичайне розташування "
+"початкових адміністративних записів\n"
+
+#: src/elflint.c:2393
+#, c-format
+msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"
+msgstr "sh_link у розділах хешів [%2zu] «%s» і [%2zu] «%s» не збігаються\n"
+
+#: src/elflint.c:2417 src/elflint.c:2482 src/elflint.c:2517
+#, c-format
+msgid "hash section [%2zu] '%s' does not contain enough data\n"
+msgstr "розділ хешу [%2zu] «%s» містить недостатньо даних\n"
+
+#: src/elflint.c:2438
+#, c-format
+msgid "hash section [%2zu] '%s' has zero bit mask words\n"
+msgstr "розділ хешу [%2zu] «%s» містить нульові слова бітової маски\n"
+
+#: src/elflint.c:2449 src/elflint.c:2493 src/elflint.c:2530
+#, c-format
+msgid "hash section [%2zu] '%s' uses too much data\n"
+msgstr "розділ хешу [%2zu] «%s» використовує надто багато даних\n"
+
+#: src/elflint.c:2464
+#, c-format
+msgid ""
+"hash section [%2zu] '%s' invalid symbol index %<PRIu32> (max_nsyms: "
+"%<PRIu32>, nentries: %<PRIu32>\n"
+msgstr ""
+"розділ хешу [%2zu] «%s» некоректний індекс символу %<PRIu32> (макс. к-ть "
+"символів: %<PRIu32>, кількість записів: %<PRIu32>\n"
+
+#: src/elflint.c:2551
+#, c-format
+msgid "hash section [%2zu] '%s' invalid sh_entsize\n"
+msgstr "розділ хешу [%2zu] «%s» некоректне значення sh_entsize\n"
+
+#: src/elflint.c:2561 src/elflint.c:2565
+#, c-format
+msgid "section [%2zu] '%s': reference to symbol index 0\n"
+msgstr "розділ [%2zu] «%s»: посилання на індекс символів 0\n"
+
+#: src/elflint.c:2572
+#, c-format
+msgid ""
+"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+"виявлено посилання на символ %d у новій таблиці хешів у [%2zu] «%s», але "
+"його немає у старій таблиці хешів у [%2zu] «%s»\n"
+
+#: src/elflint.c:2584
+#, c-format
+msgid ""
+"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+"виявлено посилання на символ %d у старій таблиці хешів у [%2zu] «%s», але "
+"його немає у новій таблиці хешів у [%2zu] «%s»\n"
+
+#: src/elflint.c:2600
+#, c-format
+msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n"
+msgstr "розділ [%2d] «%s»: ненульове значення sh_%s для розділу NULL\n"
+
+#: src/elflint.c:2620
+#, c-format
+msgid ""
+"section [%2d] '%s': section groups only allowed in relocatable object files\n"
+msgstr ""
+"розділ [%2d] «%s»: групи розділів передбачено лише для придатних до "
+"пересування об’єктних файлах\n"
+
+#: src/elflint.c:2631
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol table: %s\n"
+msgstr "розділ [%2d] «%s»: не вдалося отримати таблицю символів: %s\n"
+
+#: src/elflint.c:2636
+#, c-format
+msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n"
+msgstr ""
+"розділ [%2d] «%s»: посилання на розділ у sh_link не має таблиці символів\n"
+
+#: src/elflint.c:2642
+#, c-format
+msgid "section [%2d] '%s': invalid symbol index in sh_info\n"
+msgstr "розділ [%2d] «%s»: некоректний індекс символу у sh_info\n"
+
+#: src/elflint.c:2647
+#, c-format
+msgid "section [%2d] '%s': sh_flags not zero\n"
+msgstr "розділ [%2d] «%s»: sh_flags не є нульовим\n"
+
+#: src/elflint.c:2654
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol for signature\n"
+msgstr "розділ [%2d] «%s»: не вдалося отримати символ для підпису\n"
+
+#: src/elflint.c:2658
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol name for signature\n"
+msgstr "розділ [%2d] «%s»: не вдалося отримати назву символу для підпису\n"
+
+#: src/elflint.c:2663
+#, c-format
+msgid "section [%2d] '%s': signature symbol cannot be empty string\n"
+msgstr "розділ [%2d] «%s»: символ підпису не може бути порожнім рядком\n"
+
+#: src/elflint.c:2669
+#, c-format
+msgid "section [%2d] '%s': sh_flags not set correctly\n"
+msgstr "розділ [%2d] «%s»: для sh_flags встановлено помилкове значення\n"
+
+#: src/elflint.c:2675
+#, c-format
+msgid "section [%2d] '%s': cannot get data: %s\n"
+msgstr "розділ [%2d] «%s»: не вдалося отримати дані: %s\n"
+
+#: src/elflint.c:2684
+#, c-format
+msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"
+msgstr "розділ [%2d] «%s»: розмір розділу не є кратним до sizeof(Elf32_Word)\n"
+
+#: src/elflint.c:2690
+#, c-format
+msgid "section [%2d] '%s': section group without flags word\n"
+msgstr "розділ [%2d] «%s»: група розділів без значення типу word прапорців\n"
+
+#: src/elflint.c:2698
+#, c-format
+msgid "section [%2d] '%s': section group without member\n"
+msgstr "розділ [%2d] «%s»: група розділів без елементів\n"
+
+#: src/elflint.c:2702
+#, c-format
+msgid "section [%2d] '%s': section group with only one member\n"
+msgstr "розділ [%2d] «%s»: група розділів, що містить лише один елемент\n"
+
+#: src/elflint.c:2713
+#, c-format
+msgid "section [%2d] '%s': unknown section group flags\n"
+msgstr "розділ [%2d] «%s»: невідомі прапорці групи розділів\n"
+
+#: src/elflint.c:2725
+#, c-format
+msgid "section [%2d] '%s': section index %zu out of range\n"
+msgstr "розділ [%2d] «%s»: індекс розділу %zu поза межами діапазону\n"
+
+#: src/elflint.c:2734
+#, c-format
+msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n"
+msgstr ""
+"розділ [%2d] «%s»: не вдалося отримати заголовок розділу для елемента %zu: "
+"%s\n"
+
+#: src/elflint.c:2741
+#, c-format
+msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n"
+msgstr "розділ [%2d] «%s»: група розділів містить іншу групу [%2d] «%s»\n"
+
+#: src/elflint.c:2747
+#, c-format
+msgid ""
+"section [%2d] '%s': element %zu references section [%2d] '%s' without "
+"SHF_GROUP flag set\n"
+msgstr ""
+"розділ [%2d] «%s»: елемент %zu посилається на розділ [%2d] «%s» без "
+"встановленого прапорця SHF_GROUP\n"
+
+#: src/elflint.c:2754
+#, c-format
+msgid "section [%2d] '%s' is contained in more than one section group\n"
+msgstr "розділ [%2d] «%s» міститься у більше ніж одній групі розділів\n"
+
+#: src/elflint.c:2944
+#, c-format
+msgid ""
+"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no "
+"dynamic symbol table\n"
+msgstr ""
+"розділ [%2d] «%s» посилається у sh_link на розділ [%2d] «%s», який не має "
+"динамічної таблиці символів\n"
+
+#: src/elflint.c:2956
+#, c-format
+msgid ""
+"section [%2d] '%s' has different number of entries than symbol table [%2d] "
+"'%s'\n"
+msgstr ""
+"кількість записів у розділі [%2d] «%s» відрізняється від кількості у таблиці "
+"символів [%2d] «%s»\n"
+
+#: src/elflint.c:2972
+#, c-format
+msgid "section [%2d] '%s': symbol %d: cannot read version data\n"
+msgstr "розділ [%2d] «%s»: символ %d: не вдалося прочитати дані щодо версії\n"
+
+#: src/elflint.c:2988
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %d: локальний символ у загальному контексті\n"
+
+#: src/elflint.c:2996
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with version\n"
+msgstr "розділ [%2d] «%s»: символ %d: локальний символ з версією\n"
+
+#: src/elflint.c:3010
+#, c-format
+msgid "section [%2d] '%s': symbol %d: invalid version index %d\n"
+msgstr "розділ [%2d] «%s»: символ %d: некоректний індекс версії %d\n"
+
+#: src/elflint.c:3015
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for defined version\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %d: індекси версії %d призначено до визначеної "
+"версії\n"
+
+#: src/elflint.c:3025
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for requested version\n"
+msgstr ""
+"розділ [%2d] «%s»: символ %d: індекс версії %d призначено для версії, на яку "
+"надійшов запит\n"
+
+#: src/elflint.c:3078
+#, c-format
+msgid "more than one version reference section present\n"
+msgstr "виявлено більше за один розділ посилань на версії\n"
+
+#: src/elflint.c:3086 src/elflint.c:3233
+#, c-format
+msgid "section [%2d] '%s': sh_link does not link to string table\n"
+msgstr "розділ [%2d] «%s»: sh_link не посилається на таблицю рядків\n"
+
+#: src/elflint.c:3111 src/elflint.c:3287
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong version %d\n"
+msgstr "розділ [%2d] «%s»: запис %d має помилкову версію %d\n"
+
+#: src/elflint.c:3118 src/elflint.c:3294
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"
+msgstr ""
+"розділ [%2d] «%s»: запис %d містить помилкове зміщення у допоміжних даних\n"
+
+#: src/elflint.c:3128
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid file reference\n"
+msgstr "розділ [%2d] «%s»: запис %d містить некоректне посилання на файл\n"
+
+#: src/elflint.c:3136
+#, c-format
+msgid "section [%2d] '%s': entry %d references unknown dependency\n"
+msgstr "розділ [%2d] «%s»: запис %d посилається на невідому залежність\n"
+
+#: src/elflint.c:3148
+#, c-format
+msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"
+msgstr ""
+"розділ [%2d] «%s»: допоміжний запис %d запису %d позначено невідомим "
+"прапорцем\n"
+
+#: src/elflint.c:3156
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name "
+"reference\n"
+msgstr ""
+"розділ [%2d] «%s»: допоміжний запис %d запису %d містить некоректне "
+"посилання на назву\n"
+
+#: src/elflint.c:3165
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: "
+"%#x, expected %#x\n"
+msgstr ""
+"розділ [%2d] «%s»: допоміжний запис %d запису %d має помилкове значення "
+"хешу: %#x, мало бути %#x\n"
+
+#: src/elflint.c:3174
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version "
+"name '%s'\n"
+msgstr ""
+"розділ [%2d] «%s»: допоміжний запис %d запису %d містить дублікати назви "
+"версії «%s»\n"
+
+#: src/elflint.c:3185
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"
+msgstr ""
+"розділ [%2d] «%s»: допоміжний запис %d запису %d має помилкове наступне "
+"поле\n"
+
+#: src/elflint.c:3202 src/elflint.c:3378
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n"
+msgstr ""
+"розділ [%2d] «%s»: запис %d має некоректне зміщення щодо наступного запису\n"
+
+#: src/elflint.c:3210 src/elflint.c:3386
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says "
+"there are more entries\n"
+msgstr ""
+"розділ [%2d] «%s»: запис %d має нульове зміщення щодо наступного запису, але "
+"за sh_info можна зрозуміти, що записів більше\n"
+
+#: src/elflint.c:3225
+#, c-format
+msgid "more than one version definition section present\n"
+msgstr "виявлено більше за один розділ визначення версій\n"
+
+#: src/elflint.c:3272
+#, c-format
+msgid "section [%2d] '%s': more than one BASE definition\n"
+msgstr "розділ [%2d] «%s»: повторне визначення BASE\n"
+
+#: src/elflint.c:3276
+#, c-format
+msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"
+msgstr ""
+"розділ [%2d] «%s»: визначення BASE повинно мати індекс VER_NDX_GLOBAL\n"
+
+#: src/elflint.c:3282
+#, c-format
+msgid "section [%2d] '%s': entry %d has unknown flag\n"
+msgstr "розділ [%2d] «%s»: невідомий прапорець запису %d\n"
+
+#: src/elflint.c:3309
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid name reference\n"
+msgstr "розділ [%2d] «%s»: запис %d містить некоректне посилання на назву\n"
+
+#: src/elflint.c:3316
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"
+msgstr ""
+"розділ [%2d] «%s»: запис %d має помилкове значення хешу: %#x, мало бути %#x\n"
+
+#: src/elflint.c:3324
+#, c-format
+msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n"
+msgstr "розділ [%2d] «%s»: запис %d містить дублікати назви версії «%s»\n"
+
+#: src/elflint.c:3344
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"
+msgstr ""
+"розділ [%2d] «%s»: запис %d містить некоректне посилання на назву у "
+"допоміжних даних\n"
+
+#: src/elflint.c:3361
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"
+msgstr ""
+"розділ [%2d] «%s»: у допоміжних даних запису %d міститься помилкове поле "
+"наступного запису\n"
+
+#: src/elflint.c:3394
+#, c-format
+msgid "section [%2d] '%s': no BASE definition\n"
+msgstr "розділ [%2d] «%s»: немає визначення BASE\n"
+
+#: src/elflint.c:3410
+#, c-format
+msgid "section [%2d] '%s': unknown parent version '%s'\n"
+msgstr "розділ [%2d] «%s»: невідома основна версія «%s»\n"
+
+#: src/elflint.c:3423
+#, c-format
+msgid "section [%2d] '%s': empty object attributes section\n"
+msgstr "розділ [%2d] «%s»: порожній розділ атрибутів об’єкта\n"
+
+#: src/elflint.c:3444
+#, c-format
+msgid "section [%2d] '%s': unrecognized attribute format\n"
+msgstr "розділ [%2d] «%s»: не вдалося визначити формат атрибутів\n"
+
+#: src/elflint.c:3460
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute section\n"
+msgstr ""
+"розділ [%2d] «%s»: зміщення %zu: поле нульового розміру у розділі атрибутів\n"
+
+#: src/elflint.c:3469
+#, c-format
+msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n"
+msgstr ""
+"розділ [%2d] «%s»: зміщення %zu: некоректна довжина у розділі атрибутів\n"
+
+#: src/elflint.c:3481
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n"
+msgstr ""
+"розділ [%2d] «%s»: зміщення %zu: незавершений рядок назви постачальника\n"
+
+#: src/elflint.c:3498
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"
+msgstr ""
+"розділ [%2d] «%s»: зміщення %zu: незавершене поле ULEB128 у тезі підрозділу "
+"атрибутів\n"
+
+#: src/elflint.c:3507
+#, c-format
+msgid "section [%2d] '%s': offset %zu: truncated attribute section\n"
+msgstr "розділ [%2d] «%s»: зміщення %zu: обрізаний розділ атрибутів\n"
+
+#: src/elflint.c:3516
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"
+msgstr ""
+"розділ [%2d] «%s»: зміщення %zu: поле нульового розміру у підрозділі "
+"атрибутів\n"
+
+#: src/elflint.c:3531
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"
+msgstr ""
+"розділ [%2d] «%s»: зміщення %zu: некоректна довжина у підрозділі атрибутів\n"
+
+#. Tag_File
+#: src/elflint.c:3542
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"
+msgstr ""
+"розділ [%2d] «%s»: зміщення %zu: підрозділ атрибутів містить неочікуваний "
+"теґ %u\n"
+
+#: src/elflint.c:3560
+#, c-format
+msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"
+msgstr ""
+"розділ [%2d] «%s»: зміщення %zu: незавершене поле ULEB128 у тезі атрибуту\n"
+
+#: src/elflint.c:3571
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n"
+msgstr "розділ [%2d] «%s»: зміщення %zu: незавершений рядок у атрибуті\n"
+
+#: src/elflint.c:3584
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"
+msgstr "розділ [%2d] «%s»: зміщення %zu: незавершений теґ атрибуту %u\n"
+
+#: src/elflint.c:3588
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: unrecognized %s attribute value %<PRIu64>\n"
+msgstr ""
+"розділ [%2d] «%s»: зміщення %zu: невідоме значення %s атрибуту %<PRIu64>\n"
+
+#: src/elflint.c:3598
+#, c-format
+msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n"
+msgstr "розділ [%2d] «%s»: зміщення %zu: невідомий постачальник «%s»\n"
+
+#: src/elflint.c:3604
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"
+msgstr ""
+"розділ [%2d] «%s»: зміщення %zu: зайві байти після останнього розділу "
+"атрибутів\n"
+
+#: src/elflint.c:3693
+#, c-format
+msgid "cannot get section header of zeroth section\n"
+msgstr "не вдалося отримати заголовок нульового розділу\n"
+
+#: src/elflint.c:3697
+#, c-format
+msgid "zeroth section has nonzero name\n"
+msgstr "нульовий розділ має ненульову назву\n"
+
+#: src/elflint.c:3699
+#, c-format
+msgid "zeroth section has nonzero type\n"
+msgstr "нульовий розділ має ненульовий тип\n"
+
+#: src/elflint.c:3701
+#, c-format
+msgid "zeroth section has nonzero flags\n"
+msgstr "нульовий розділ має ненульові прапорці\n"
+
+#: src/elflint.c:3703
+#, c-format
+msgid "zeroth section has nonzero address\n"
+msgstr "нульовий розділ має ненульову адресу\n"
+
+#: src/elflint.c:3705
+#, c-format
+msgid "zeroth section has nonzero offset\n"
+msgstr "нульовий розділ має ненульове зміщення\n"
+
+#: src/elflint.c:3707
+#, c-format
+msgid "zeroth section has nonzero align value\n"
+msgstr "нульовий розділ має ненульове значення вирівнювання\n"
+
+#: src/elflint.c:3709
+#, c-format
+msgid "zeroth section has nonzero entry size value\n"
+msgstr "нульовий розділ має ненульове значення розміру запису\n"
+
+#: src/elflint.c:3712
+#, c-format
+msgid ""
+"zeroth section has nonzero size value while ELF header has nonzero shnum "
+"value\n"
+msgstr ""
+"нульовий розділ має ненульове значення розміру, хоча заголовок ELF ман "
+"ненульове значення shnum\n"
+
+#: src/elflint.c:3716
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in shstrndx\n"
+msgstr ""
+"нульовий розділ має ненульове значення компонування, хоча у заголовку ELF "
+"немає сигналу переповнення у shstrndx\n"
+
+#: src/elflint.c:3720
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in phnum\n"
+msgstr ""
+"нульовий розділ має ненульове значення компонування, хоча у заголовку ELF "
+"немає сигналу переповнення у phnum\n"
+
+#: src/elflint.c:3738
+#, c-format
+msgid "cannot get section header for section [%2zu] '%s': %s\n"
+msgstr "не вдалося отримати заголовок розділу [%2zu] «%s»: %s\n"
+
+#: src/elflint.c:3747
+#, c-format
+msgid "section [%2zu]: invalid name\n"
+msgstr "розділ [%2zu]: некоректна назва\n"
+
+#: src/elflint.c:3774
+#, c-format
+msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n"
+msgstr ""
+"розділ [%2d] «%s» належить до помилкового типу: мав бути %s, маємо %s\n"
+
+#: src/elflint.c:3792
+#, c-format
+msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n"
+msgstr "розділ [%2zu] «%s» має помилкові прапорці: мало бути %s, маємо %s\n"
+
+#: src/elflint.c:3810
+#, c-format
+msgid ""
+"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"
+msgstr ""
+"розділ [%2zu] «%s» має помилкові прапорці: мало бути %s, можливо, %s, але "
+"маємо %s\n"
+
+#: src/elflint.c:3828
+#, c-format
+msgid "section [%2zu] '%s' present in object file\n"
+msgstr "у об’єктному файлі виявлено розділ [%2zu] «%s»\n"
+
+#: src/elflint.c:3834 src/elflint.c:3866
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"
+msgstr ""
+"у розділ [%2zu] «%s» встановлено прапорець SHF_ALLOC, але немає придатного "
+"до завантаження сегмента\n"
+
+#: src/elflint.c:3839 src/elflint.c:3871
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable "
+"segments\n"
+msgstr ""
+"у розділі [%2zu] «%s» не встановлено прапорець SHF_ALLOC, але є придатні до "
+"завантаження сегменти\n"
+
+#: src/elflint.c:3847
+#, c-format
+msgid ""
+"section [%2zu] '%s' is extension section index table in non-object file\n"
+msgstr ""
+"розділ [%2zu] «%s» є таблицею-покажчиком розділу розширень у файлі, який не "
+"є об’єктним\n"
+
+#: src/elflint.c:3890
+#, c-format
+msgid "section [%2zu] '%s': size not multiple of entry size\n"
+msgstr "розділ [%2zu] «%s»: розмір не є кратним до розміру запису\n"
+
+#: src/elflint.c:3895
+#, c-format
+msgid "cannot get section header\n"
+msgstr "не вдалося отримати заголовок розділу\n"
+
+#: src/elflint.c:3905
+#, c-format
+msgid "section [%2zu] '%s' has unsupported type %d\n"
+msgstr "розділ [%2zu] «%s» належить до непідтримуваного типу %d\n"
+
+#: src/elflint.c:3920
+#, c-format
+msgid ""
+"section [%2zu] '%s' contains invalid processor-specific flag(s) %#<PRIx64>\n"
+msgstr ""
+"розділ [%2zu] «%s» містить некоректні специфічні для процесора прапорці "
+"%#<PRIx64>\n"
+
+#: src/elflint.c:3927
+#, c-format
+msgid "section [%2zu] '%s' contains unknown flag(s) %#<PRIx64>\n"
+msgstr "розділ [%2zu] «%s» містить невідомі прапорці %#<PRIx64>\n"
+
+#: src/elflint.c:3935
+#, c-format
+msgid "section [%2zu] '%s': thread-local data sections address not zero\n"
+msgstr ""
+"розділ [%2zu] «%s»: адреса розділів локальних даних потоків не є нульовою\n"
+
+#: src/elflint.c:3945
+#, fuzzy, c-format
+msgid "section [%2zu] '%s': allocated section cannot be compressed\n"
+msgstr ""
+"розділ [%2zu] «%s»: адреса розділів локальних даних потоків не є нульовою\n"
+
+#: src/elflint.c:3950
+#, fuzzy, c-format
+msgid "section [%2zu] '%s': nobits section cannot be compressed\n"
+msgstr "розділ [%2d] «%s»: не виявлено розділу хешів\n"
+
+#: src/elflint.c:3956
+#, fuzzy, c-format
+msgid ""
+"section [%2zu] '%s': compressed section with no compression header: %s\n"
+msgstr "розділ [%2d] «%s»: група розділів, що містить лише один елемент\n"
+
+#: src/elflint.c:3962
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in link value\n"
+msgstr ""
+"розділ [%2zu] «%s»: некоректне посилання на розділ у значенні компонування\n"
+
+#: src/elflint.c:3967
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in info value\n"
+msgstr ""
+"розділ [%2zu] «%s»: некоректне посилання на розділ у значенні відомостей\n"
+
+#: src/elflint.c:3974
+#, c-format
+msgid "section [%2zu] '%s': strings flag set without merge flag\n"
+msgstr "розділ [%2zu] «%s»: встановлено прапорець strings без прапорця merge\n"
+
+#: src/elflint.c:3979
+#, c-format
+msgid "section [%2zu] '%s': merge flag set but entry size is zero\n"
+msgstr ""
+"розділ [%2zu] «%s»: встановлено прапорець merge, але розмір запису є "
+"нульовим\n"
+
+#: src/elflint.c:3998
+#, c-format
+msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n"
+msgstr "розділ [%2zu] «%s» має неочікуваний тип %d для виконуваного розділу\n"
+
+#: src/elflint.c:4007
+#, fuzzy, c-format
+msgid "section [%2zu] '%s' must be of type NOBITS in debuginfo files\n"
+msgstr "розділ [%2zu] «%s» не повинен бути придатним до запису\n"
+
+#: src/elflint.c:4014
+#, c-format
+msgid "section [%2zu] '%s' is both executable and writable\n"
+msgstr "розділ [%2zu] «%s» є одночасно виконуваним і придатним до запису\n"
+
+#: src/elflint.c:4045
+#, c-format
+msgid ""
+"section [%2zu] '%s' not fully contained in segment of program header entry "
+"%d\n"
+msgstr ""
+"розділ [%2zu] «%s» не повністю міститься у сегменті запису заголовка "
+"програми %d\n"
+
+#: src/elflint.c:4055
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d\n"
+msgstr ""
+"розділ [%2zu] «%s» належить до типу NOBITS, але його читання виконується з "
+"файла у сегментів запису заголовка програми %d\n"
+
+#: src/elflint.c:4081
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d and file contents is non-zero\n"
+msgstr ""
+"розділ [%2zu] «%s» належить до типу NOBITS, але його читання виконується з "
+"файла у сегментів запису заголовка програми %d, а вміст файла є ненульовим\n"
+
+#: src/elflint.c:4092
+#, c-format
+msgid ""
+"section [%2zu] '%s' has not type NOBITS but is not read from the file in "
+"segment of program header entry %d\n"
+msgstr ""
+"розділ [%2zu] «%s» не належить до типу NOBITS, але його читання не "
+"виконується з файла у сегментів запису заголовка програми %d\n"
+
+#: src/elflint.c:4103
+#, c-format
+msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n"
+msgstr "розділ [%2zu] «%s» є виконуваним у невиконуваному сегменті %d\n"
+
+#: src/elflint.c:4113
+#, c-format
+msgid "section [%2zu] '%s' is writable in unwritable segment %d\n"
+msgstr ""
+"розділ [%2zu] «%s» є придатним до запису у непридатному до запису сегменті "
+"%d\n"
+
+#: src/elflint.c:4123
+#, c-format
+msgid ""
+"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"
+msgstr ""
+"розділ [%2zu] «%s»: встановлено прапорець alloc, але розділ не перебуває у "
+"жодному завантаженому сегменті\n"
+
+#: src/elflint.c:4129
+#, c-format
+msgid ""
+"section [%2zu] '%s': ELF header says this is the section header string table "
+"but type is not SHT_TYPE\n"
+msgstr ""
+"розділ [%2zu] «%s»: заголовок ELF повідомляє про те, що це таблиця рядків "
+"заголовка розділу, але ця таблиця не належить до типу SHT_TYPE\n"
+
+#: src/elflint.c:4137
+#, c-format
+msgid ""
+"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"
+msgstr ""
+"розділ [%2zu] «%s»: придатні до пересування файли не можуть містити "
+"динамічних таблиць символів\n"
+
+#: src/elflint.c:4188
+#, c-format
+msgid "more than one version symbol table present\n"
+msgstr "виявлено більше за одну таблицю символів версій\n"
+
+#: src/elflint.c:4211
+#, c-format
+msgid "INTERP program header entry but no .interp section\n"
+msgstr "існує запис заголовка програми INTERP, але не розділ .interp\n"
+
+#: src/elflint.c:4222
+#, c-format
+msgid ""
+"loadable segment [%u] is executable but contains no executable sections\n"
+msgstr ""
+"придатний до завантаження сегмент [%u] є виконуваним, але не містить "
+"виконуваних розділів\n"
+
+#: src/elflint.c:4228
+#, c-format
+msgid "loadable segment [%u] is writable but contains no writable sections\n"
+msgstr ""
+"придатний до завантаження розділ [%u] є придатним до запису, але не містить "
+"придатних до запису розділів\n"
+
+#: src/elflint.c:4239
+#, c-format
+msgid ""
+"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section "
+"exist\n"
+msgstr ""
+"немає розділу .gnu.versym, хоча існує розділ .gnu.versym_d або .gnu."
+"versym_r\n"
+
+#: src/elflint.c:4252
+#, c-format
+msgid "duplicate version index %d\n"
+msgstr "дублікат індексу версії %d\n"
+
+#: src/elflint.c:4266
+#, c-format
+msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"
+msgstr ""
+"існує розділ .gnu.versym, але немає розділу .gnu.versym_d або .gnu.versym_r\n"
+
+#: src/elflint.c:4315
+#, c-format
+msgid "phdr[%d]: unknown core file note type %<PRIu32> at offset %<PRIu64>\n"
+msgstr ""
+"phdr[%d]: невідомий тип нотатки файла core %<PRIu32> за зміщенням %<PRIu64>\n"
+
+#: src/elflint.c:4319
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown core file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+"розділ [%2d] «%s»: невідомий тип нотатки файла core %<PRIu32> за зміщенням "
+"%zu\n"
+
+#: src/elflint.c:4342
+#, c-format
+msgid "phdr[%d]: unknown object file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+"phdr[%d]: невідомий тип нотатки об’єктного файла %<PRIu32> за зміщенням %zu\n"
+
+#: src/elflint.c:4346
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown object file note type %<PRIu32> at offset %zu\n"
+msgstr ""
+"розділ [%2d] «%s»: невідомий тип нотатки об’єктного файла %<PRIu32> за "
+"зміщенням %zu\n"
+
+#: src/elflint.c:4363
+#, c-format
+msgid "phdr[%d]: no note entries defined for the type of file\n"
+msgstr "phdr[%d]: для цього типу файлів не визначено записів нотаток\n"
+
+#: src/elflint.c:4382
+#, c-format
+msgid "phdr[%d]: cannot get content of note section: %s\n"
+msgstr "phdr[%d]: не вдалося отримати вміст розділу нотаток: %s\n"
+
+#: src/elflint.c:4385
+#, c-format
+msgid "phdr[%d]: extra %<PRIu64> bytes after last note\n"
+msgstr "phdr[%d]: зайві %<PRIu64> байтів після останнього запису нотатки\n"
+
+#: src/elflint.c:4406
+#, c-format
+msgid "section [%2d] '%s': no note entries defined for the type of file\n"
+msgstr ""
+"розділ [%2d] «%s»: для цього типу файлів не визначено записів нотаток\n"
+
+#: src/elflint.c:4413
+#, c-format
+msgid "section [%2d] '%s': cannot get content of note section\n"
+msgstr "розділ [%2d] «%s»: не вдалося отримати вміст розділу нотаток\n"
+
+#: src/elflint.c:4416
+#, c-format
+msgid "section [%2d] '%s': extra %<PRIu64> bytes after last note\n"
+msgstr ""
+"розділ [%2d] «%s»: додаткові %<PRIu64> байтів після останньої нотатки\n"
+
+#: src/elflint.c:4434
+#, c-format
+msgid ""
+"only executables, shared objects, and core files can have program headers\n"
+msgstr ""
+"заголовки програм можуть бути лише у виконуваних файлів, об’єктних файлів "
+"спільного використання або файлів core\n"
+
+#: src/elflint.c:4449
+#, c-format
+msgid "cannot get program header entry %d: %s\n"
+msgstr "не вдалося отримати запис заголовка програми %d: %s\n"
+
+#: src/elflint.c:4458
+#, c-format
+msgid "program header entry %d: unknown program header entry type %#<PRIx64>\n"
+msgstr ""
+"запис заголовка програми %d: невідомий тип запису заголовка програми "
+"%#<PRIx64>\n"
+
+#: src/elflint.c:4469
+#, c-format
+msgid "more than one INTERP entry in program header\n"
+msgstr "більше за один запис INTERP у заголовку програми\n"
+
+#: src/elflint.c:4477
+#, c-format
+msgid "more than one TLS entry in program header\n"
+msgstr "більше за один запис TLS у заголовку програми\n"
+
+#: src/elflint.c:4484
+#, c-format
+msgid "static executable cannot have dynamic sections\n"
+msgstr "у статичному виконуваному файлі не може бути динамічних розділів\n"
+
+#: src/elflint.c:4498
+#, c-format
+msgid "dynamic section reference in program header has wrong offset\n"
+msgstr ""
+"посилання на динамічний розділ у заголовку програми має помилкове зміщення\n"
+
+#: src/elflint.c:4501
+#, c-format
+msgid "dynamic section size mismatch in program and section header\n"
+msgstr ""
+"розміри динамічного розділу у заголовку програми та у заголовку розділу не "
+"збігаються\n"
+
+#: src/elflint.c:4511
+#, c-format
+msgid "more than one GNU_RELRO entry in program header\n"
+msgstr "більше за один запис GNU_RELRO у заголовку програми\n"
+
+#: src/elflint.c:4532
+#, c-format
+msgid "loadable segment GNU_RELRO applies to is not writable\n"
+msgstr ""
+"придатний до завантаження сегмент, до якого звертається GNU_RELRO, "
+"непридатний до запису\n"
+
+#: src/elflint.c:4543
+#, c-format
+msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"
+msgstr ""
+"прапорці придатного до завантаження сегмента [%u] не відповідають прапорцям "
+"GNU_RELRO [%u]\n"
+
+#: src/elflint.c:4550
+#, c-format
+msgid ""
+"GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n"
+msgstr ""
+
+#: src/elflint.c:4559 src/elflint.c:4582
+#, c-format
+msgid "%s segment not contained in a loaded segment\n"
+msgstr "сегмент %s не міститься у завантаженому сегменті\n"
+
+#: src/elflint.c:4588
+#, c-format
+msgid "program header offset in ELF header and PHDR entry do not match"
+msgstr "зміщення заголовка програми у заголовку ELF і запис PHDR не збігаються"
+
+#: src/elflint.c:4613
+#, c-format
+msgid "call frame search table reference in program header has wrong offset\n"
+msgstr ""
+"посилання на таблицю вікон викликів у заголовку програми має помилкове "
+"зміщення\n"
+
+#: src/elflint.c:4616
+#, c-format
+msgid "call frame search table size mismatch in program and section header\n"
+msgstr ""
+"розміри таблиці пошуку вікон виклику у заголовку програми та у заголовку "
+"розділу не збігаються\n"
+
+#: src/elflint.c:4629
+#, c-format
+msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"
+msgstr "існує PT_GNU_EH_FRAME, хоча немає розділу .eh_frame_hdr\n"
+
+#: src/elflint.c:4637
+#, c-format
+msgid "call frame search table must be allocated\n"
+msgstr "таблицю пошуку вікон викликів має бути розміщено у пам’яті\n"
+
+#: src/elflint.c:4640
+#, c-format
+msgid "section [%2zu] '%s' must be allocated\n"
+msgstr "розділ [%2zu] «%s» має бути розміщено у пам’яті\n"
+
+#: src/elflint.c:4644
+#, c-format
+msgid "call frame search table must not be writable\n"
+msgstr "таблиця пошуку вікон викликів не повинна бути придатною до запису\n"
+
+#: src/elflint.c:4647
+#, c-format
+msgid "section [%2zu] '%s' must not be writable\n"
+msgstr "розділ [%2zu] «%s» не повинен бути придатним до запису\n"
+
+#: src/elflint.c:4652
+#, c-format
+msgid "call frame search table must not be executable\n"
+msgstr "таблиця пошуку вікон викликів не повинна бути придатною до виконання\n"
+
+#: src/elflint.c:4655
+#, c-format
+msgid "section [%2zu] '%s' must not be executable\n"
+msgstr "розділ [%2zu] «%s» не повинен бути придатним до виконання\n"
+
+#: src/elflint.c:4666
+#, c-format
+msgid "program header entry %d: file size greater than memory size\n"
+msgstr "запис заголовка програми %d: розмір файла перевищує об’єм пам’яті\n"
+
+#: src/elflint.c:4673
+#, c-format
+msgid "program header entry %d: alignment not a power of 2\n"
+msgstr "запис заголовка програми %d: значення вирівнювання не є степенем 2\n"
+
+#: src/elflint.c:4676
+#, c-format
+msgid ""
+"program header entry %d: file offset and virtual address not module of "
+"alignment\n"
+msgstr ""
+"запис заголовка програми %d: зміщення у файлі і віртуальна адреса не "
+"співвідносяться з вирівнюванням\n"
+
+#: src/elflint.c:4689
+#, c-format
+msgid ""
+"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME "
+"program header entry"
+msgstr ""
+"виконуваний модуль/DSO з розділом .eh_frame_hdr не містить запису заголовка "
+"програми PT_GNU_EH_FRAME"
+
+#: src/elflint.c:4723
+#, c-format
+msgid "cannot read ELF header: %s\n"
+msgstr "не вдалося прочитати заголовок ELF: %s\n"
+
+#: src/elflint.c:4749
+#, c-format
+msgid "text relocation flag set but not needed\n"
+msgstr ""
+"встановлено прапорець пересування тексту, але такий прапорець не потрібен\n"
+
+#: src/findtextrel.c:61
+msgid "Input Selection:"
+msgstr "Вибір параметрів виводу даних:"
+
+#: src/findtextrel.c:62
+msgid "Prepend PATH to all file names"
+msgstr "Додавати ШЛЯХ до всіх назв файлів"
+
+#: src/findtextrel.c:64
+msgid "Use PATH as root of debuginfo hierarchy"
+msgstr "Використовувати ШЛЯХ як кореневий каталог для ієрархії debuginfo"
+
+#. Short description of program.
+#: src/findtextrel.c:71
+msgid "Locate source of text relocations in FILEs (a.out by default)."
+msgstr "Шукає джерело пересуваного тексту у ФАЙЛАХ (типово, a.out)."
+
+#. Strings for arguments in help texts.
+#: src/findtextrel.c:75 src/nm.c:109 src/objdump.c:72 src/size.c:81
+#: src/strings.c:88 src/strip.c:99
+msgid "[FILE...]"
+msgstr "[ФАЙЛ...]"
+
+#: src/findtextrel.c:223
+#, c-format
+msgid "cannot get ELF header '%s': %s"
+msgstr "не вдалося отримати заголовок ELF «%s»: %s"
+
+#: src/findtextrel.c:234
+#, c-format
+msgid "'%s' is not a DSO or PIE"
+msgstr "«%s» не є DSO або PIE"
+
+#: src/findtextrel.c:254
+#, c-format
+msgid "getting get section header of section %zu: %s"
+msgstr "отримання заголовка розділу get розділу %zu: %s"
+
+#: src/findtextrel.c:277
+#, c-format
+msgid "cannot read dynamic section: %s"
+msgstr "не вдалося прочитати динамічний розділ: %s"
+
+#: src/findtextrel.c:298
+#, c-format
+msgid "no text relocations reported in '%s'"
+msgstr "у «%s» не виявлено пересувань тексту"
+
+#: src/findtextrel.c:310
+#, c-format
+msgid "while reading ELF file"
+msgstr "під час спроби читання файла ELF"
+
+#: src/findtextrel.c:314
+#, c-format
+msgid "cannot get program header count: %s"
+msgstr "не вдалося отримати кількість заголовків програми: %s"
+
+#: src/findtextrel.c:325 src/findtextrel.c:342
+#, c-format
+msgid "cannot get program header index at offset %zd: %s"
+msgstr "не вдалося отримати індекс заголовка програми за зміщенням %zd: %s"
+
+#: src/findtextrel.c:406
+#, c-format
+msgid "cannot get symbol table section %zu in '%s': %s"
+msgstr "не вдалося отримати таблицю символів розділу %zu у «%s»: %s"
+
+#: src/findtextrel.c:426 src/findtextrel.c:449
+#, c-format
+msgid "cannot get relocation at index %d in section %zu in '%s': %s"
+msgstr ""
+"не вдалося отримати пересування за індексом %d у розділі %zu у «%s»: %s"
+
+#: src/findtextrel.c:515
+#, c-format
+msgid "%s not compiled with -fpic/-fPIC\n"
+msgstr "%s не зібрано з -fpic/-fPIC\n"
+
+#: src/findtextrel.c:568
+#, c-format
+msgid ""
+"the file containing the function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+"файл, що містить функцію «%s», не було зібрано з параметрами -fpic/-fPIC\n"
+
+#: src/findtextrel.c:575 src/findtextrel.c:595
+#, c-format
+msgid ""
+"the file containing the function '%s' might not be compiled with -fpic/-"
+"fPIC\n"
+msgstr ""
+"файл, що містить функцію «%s», ймовірно, не було зібрано з параметрами -"
+"fpic/-fPIC\n"
+
+#: src/findtextrel.c:583
+#, c-format
+msgid ""
+"either the file containing the function '%s' or the file containing the "
+"function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+"файл, що містить функцію «%s», або файл, що містить функцію «%s», зібрано "
+"без параметрів -fpic/-fPIC\n"
+
+#: src/findtextrel.c:603
+#, c-format
+msgid ""
+"a relocation modifies memory at offset %llu in a write-protected segment\n"
+msgstr ""
+"пересування призводить до зміни запису пам’яті за зміщенням %llu у "
+"захищеному від запису сегменті\n"
+
+#: src/nm.c:67 src/strip.c:70
+msgid "Output selection:"
+msgstr "Вибір виводу:"
+
+#: src/nm.c:68
+msgid "Display debugger-only symbols"
+msgstr "Показувати лише діагностичні символи"
+
+#: src/nm.c:69
+msgid "Display only defined symbols"
+msgstr "Показувати лише визначені символи"
+
+#: src/nm.c:72
+msgid "Display dynamic symbols instead of normal symbols"
+msgstr "Показувати динамічні символи замість звичайних символів"
+
+#: src/nm.c:73
+msgid "Display only external symbols"
+msgstr "Показувати лише зовнішні символи"
+
+#: src/nm.c:74
+msgid "Display only undefined symbols"
+msgstr "Показувати лише невизначені символи"
+
+#: src/nm.c:76
+msgid "Include index for symbols from archive members"
+msgstr "Включити покажчик для символів з елементів архіву"
+
+#: src/nm.c:78 src/size.c:55
+msgid "Output format:"
+msgstr "Формат виводу:"
+
+#: src/nm.c:80
+msgid "Print name of the input file before every symbol"
+msgstr "Виводити перед кожним символом назву вхідного файла"
+
+#: src/nm.c:83
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd', `sysv' or `posix'.  The "
+"default is `sysv'"
+msgstr ""
+"Використовувати формат виводу ФОРМАТ. ФОРМАТом може бути «bsd», «sysv» або "
+"«posix». Типовим форматом є «sysv»"
+
+#: src/nm.c:85
+msgid "Same as --format=bsd"
+msgstr "Те саме, що і --format=bsd"
+
+#: src/nm.c:86
+msgid "Same as --format=posix"
+msgstr "Те саме, що і --format=posix"
+
+#: src/nm.c:87 src/size.c:61
+msgid "Use RADIX for printing symbol values"
+msgstr "Використовувати ОСНОВУ числення для виводу символьних значень"
+
+#: src/nm.c:88
+msgid "Mark special symbols"
+msgstr "Позначати спеціальні символи"
+
+#: src/nm.c:90
+msgid "Print size of defined symbols"
+msgstr "Вивести розмір визначених символів"
+
+#: src/nm.c:92 src/size.c:69 src/strip.c:75 src/unstrip.c:73
+msgid "Output options:"
+msgstr "Параметри виводу:"
+
+#: src/nm.c:93
+msgid "Sort symbols numerically by address"
+msgstr "Числове впорядкування символів за адресою"
+
+#: src/nm.c:95
+msgid "Do not sort the symbols"
+msgstr "Не впорядковувати символи"
+
+#: src/nm.c:96
+msgid "Reverse the sense of the sort"
+msgstr "Змінити порядок на протилежний"
+
+#: src/nm.c:99
+msgid "Decode low-level symbol names into source code names"
+msgstr "Визначати за низькорівневими назвами символів назви у початковому коді"
+
+#. Short description of program.
+#: src/nm.c:106
+msgid "List symbols from FILEs (a.out by default)."
+msgstr "Показати список символів з ФАЙЛів (типово з a.out)."
+
+#: src/nm.c:117 src/objdump.c:80
+msgid "Output formatting"
+msgstr "Форматування виводу"
+
+#: src/nm.c:141 src/objdump.c:104 src/size.c:106 src/strip.c:131
+#, c-format
+msgid "%s: INTERNAL ERROR %d (%s): %s"
+msgstr "%s: ВНУТРІШНЯ ПОМИЛКА %d (%s): %s"
+
+#: src/nm.c:382 src/nm.c:394 src/size.c:289 src/size.c:298 src/size.c:309
+#: src/strip.c:2421
+#, c-format
+msgid "while closing '%s'"
+msgstr "під час закриття «%s»"
+
+#: src/nm.c:404 src/objdump.c:281 src/strip.c:443
+#, c-format
+msgid "%s: File format not recognized"
+msgstr "%s: не вдалося розпізнати формат файла"
+
+#. Note: 0 is no valid offset.
+#: src/nm.c:444
+msgid ""
+"\n"
+"Archive index:\n"
+msgstr ""
+"\n"
+"Покажчик архіву:\n"
+
+#: src/nm.c:453
+#, c-format
+msgid "invalid offset %zu for symbol %s"
+msgstr "некоректне зміщення %zu для символу %s"
+
+#: src/nm.c:458
+#, c-format
+msgid "%s in %s\n"
+msgstr "%s у %s\n"
+
+#: src/nm.c:466
+#, c-format
+msgid "cannot reset archive offset to beginning"
+msgstr "не вдалося відновити зміщення початку архіву"
+
+#: src/nm.c:491 src/objdump.c:329
+#, c-format
+msgid "%s%s%s: file format not recognized"
+msgstr "%s%s%s: не вдалося розпізнати формат файла"
+
+#: src/nm.c:706
+#, c-format
+msgid "cannot create search tree"
+msgstr "не вдалося створити дерево пошуку"
+
+#: src/nm.c:747 src/nm.c:1208 src/objdump.c:778 src/readelf.c:551
+#: src/readelf.c:1129 src/readelf.c:1329 src/readelf.c:1477 src/readelf.c:1678
+#: src/readelf.c:1884 src/readelf.c:2074 src/readelf.c:2252 src/readelf.c:2328
+#: src/readelf.c:2586 src/readelf.c:2662 src/readelf.c:2749 src/readelf.c:3329
+#: src/readelf.c:3379 src/readelf.c:3442 src/readelf.c:8444 src/readelf.c:9544
+#: src/readelf.c:9747 src/readelf.c:9815 src/size.c:397 src/size.c:466
+#: src/strip.c:572
+#, c-format
+msgid "cannot get section header string table index"
+msgstr "не вдалося визначити індекс заголовка розділу у таблиці рядків"
+
+#. We always print this prolog.
+#: src/nm.c:774
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s:\n"
+"\n"
+msgstr ""
+"\n"
+"\n"
+"Символи з %s:\n"
+"\n"
+
+#. The header line.
+#: src/nm.c:777
+#, c-format
+msgid ""
+"%*s%-*s %-*s Class  Type     %-*s %*s Section\n"
+"\n"
+msgstr ""
+"%*s%-*s %-*s Клас   Тип      %-*s %*s Розділ\n"
+"\n"
+
+#: src/nm.c:1219
+#, c-format
+msgid "%s: entry size in section %zd `%s' is not what we expect"
+msgstr "%s: розмір запису у розділі %zd «%s» не є очікуваним"
+
+#: src/nm.c:1224
+#, c-format
+msgid "%s: size of section %zd `%s' is not multiple of entry size"
+msgstr "%s: розмір розділу %zd «%s» не є кратним до розміру запису"
+
+#: src/nm.c:1303
+#, fuzzy, c-format
+msgid "%s: entries (%zd) in section %zd `%s' is too large"
+msgstr "%s: розмір запису у розділі %zd «%s» не є очікуваним"
+
+#. XXX Add machine specific object file types.
+#: src/nm.c:1529
+#, c-format
+msgid "%s%s%s%s: Invalid operation"
+msgstr "%s%s%s%s: некоректна дія"
+
+#: src/nm.c:1586
+#, c-format
+msgid "%s%s%s: no symbols"
+msgstr "%s%s%s: немає символів"
+
+#: src/objdump.c:53
+msgid "Mode selection:"
+msgstr "Вибір режиму:"
+
+#: src/objdump.c:54
+msgid "Display relocation information."
+msgstr "Показати інформацію про пересування."
+
+#: src/objdump.c:56
+msgid "Display the full contents of all sections requested"
+msgstr "Показати весь вміст всіх вказаних розділів"
+
+#: src/objdump.c:58
+msgid "Display assembler code of executable sections"
+msgstr "Показати код асемблера виконуваних розділів"
+
+#: src/objdump.c:60
+msgid "Output content selection:"
+msgstr "Вибір виведених даних:"
+
+#: src/objdump.c:62
+msgid "Only display information for section NAME."
+msgstr "Показати інформацію лише з розділу НАЗВА."
+
+#. Short description of program.
+#: src/objdump.c:68
+msgid "Show information from FILEs (a.out by default)."
+msgstr "Показати інформацію з ФАЙЛів (типово a.out)."
+
+#: src/objdump.c:219 src/readelf.c:499
+msgid "No operation specified.\n"
+msgstr "Не вказано дії.\n"
+
+#: src/objdump.c:259 src/objdump.c:271
+#, c-format
+msgid "while close `%s'"
+msgstr "під час закриття «%s»"
+
+#: src/objdump.c:364 src/readelf.c:1979 src/readelf.c:2171
+msgid "INVALID SYMBOL"
+msgstr "НЕКОРЕКТНИЙ СИМВОЛ"
+
+#: src/objdump.c:379 src/readelf.c:2013 src/readelf.c:2207
+msgid "INVALID SECTION"
+msgstr "НЕКОРЕКТНИЙ РОЗДІЛ"
+
+#: src/objdump.c:499
+#, c-format
+msgid ""
+"\n"
+"RELOCATION RECORDS FOR [%s]:\n"
+"%-*s TYPE                 VALUE\n"
+msgstr ""
+"\n"
+"ЗАПИСИ ПЕРЕМІЩЕННЯ ДЛЯ [%s]:\n"
+"%-*s ТИП                  ЗНАЧЕННЯ\n"
+
+#: src/objdump.c:502
+msgid "OFFSET"
+msgstr "ЗМІЩЕННЯ"
+
+#: src/objdump.c:567
+#, c-format
+msgid "Contents of section %s:\n"
+msgstr "Вміст розділу %s:\n"
+
+#: src/objdump.c:688
+#, c-format
+msgid "cannot disassemble"
+msgstr "не вдалося дизасемблювати"
+
+#. Short description of program.
+#: src/ranlib.c:64
+msgid "Generate an index to speed access to archives."
+msgstr "Створювати покажчик для пришвидшення доступу до архівів."
+
+#. Strings for arguments in help texts.
+#: src/ranlib.c:67
+msgid "ARCHIVE"
+msgstr "АРХІВ"
+
+#: src/ranlib.c:103
+#, c-format
+msgid "Archive name required"
+msgstr "Слід вказати назву архіву"
+
+#: src/ranlib.c:167
+#, c-format
+msgid "'%s' is no archive"
+msgstr "«%s» не є архівом"
+
+#: src/ranlib.c:202
+#, c-format
+msgid "error while freeing sub-ELF descriptor: %s"
+msgstr "помилка під час спроби вивільнення дескриптора під-ELF: %s"
+
+#: src/readelf.c:87
+msgid "ELF input selection:"
+msgstr "Вибір вихідних даних ELF:"
+
+#: src/readelf.c:89
+msgid ""
+"Use the named SECTION (default .gnu_debugdata) as (compressed) ELF input data"
+msgstr ""
+"Використовувати вказаний за іменем РОЗДІЛ (типово .gnu_debugdata) як "
+"(стиснені) вхідні дані ELF"
+
+#: src/readelf.c:91
+msgid "ELF output selection:"
+msgstr "Вибір виводу ELF:"
+
+#: src/readelf.c:93
+msgid "All these plus -p .strtab -p .dynstr -p .comment"
+msgstr "Все це плюс -p .strtab -p .dynstr -p .comment"
+
+#: src/readelf.c:94
+msgid "Display the dynamic segment"
+msgstr "Показувати динамічний сегмент"
+
+#: src/readelf.c:95
+msgid "Display the ELF file header"
+msgstr "Показувати заголовок файла ELF"
+
+#: src/readelf.c:97
+msgid "Display histogram of bucket list lengths"
+msgstr "Показати гістограму довжин списку блоків"
+
+#: src/readelf.c:98
+msgid "Display the program headers"
+msgstr "Показувати заголовки програми"
+
+#: src/readelf.c:100
+msgid "Display relocations"
+msgstr "Показувати пересування"
+
+#: src/readelf.c:101
+msgid "Display the sections' headers"
+msgstr "Показувати заголовки розділів"
+
+#: src/readelf.c:104
+#, fuzzy
+msgid "Display the symbol table sections"
+msgstr "Показувати таблицю символів"
+
+#: src/readelf.c:105
+msgid "Display versioning information"
+msgstr "Показувати відомості щодо версії"
+
+#: src/readelf.c:106
+msgid "Display the ELF notes"
+msgstr "Показувати нотатки ELF"
+
+#: src/readelf.c:108
+msgid "Display architecture specific information, if any"
+msgstr "Показувати специфічні для архітектури дані, якщо такі буде виявлено"
+
+#: src/readelf.c:110
+msgid "Display sections for exception handling"
+msgstr "Показувати розділи для обробки виключень"
+
+#: src/readelf.c:112
+msgid "Additional output selection:"
+msgstr "Додатковий вибір виводу:"
+
+#: src/readelf.c:114
+msgid ""
+"Display DWARF section content.  SECTION can be one of abbrev, aranges, "
+"decodedaranges, frame, gdb_index, info, loc, line, decodedline, ranges, "
+"pubnames, str, macinfo, macro or exception"
+msgstr ""
+"Показати вміст розділу DWARF. Значенням РОЗДІЛ може бути abbrev, aranges, "
+"decodedaranges, frame, gdb_index, info, loc, line, decodedline, ranges, "
+"pubnames, str, macinfo, macro або exception"
+
+#: src/readelf.c:118
+msgid "Dump the uninterpreted contents of SECTION, by number or name"
+msgstr ""
+"Створити дамп даних РОЗДІЛ, які не вдалося інтерпретувати, за номером або "
+"назвами"
+
+#: src/readelf.c:120
+msgid "Print string contents of sections"
+msgstr "Виводити вміст рядків розділів"
+
+#: src/readelf.c:123
+msgid "Display the symbol index of an archive"
+msgstr "Показувати покажчик символів архіву"
+
+#: src/readelf.c:125
+msgid "Output control:"
+msgstr "Керування виводом:"
+
+#: src/readelf.c:127
+msgid "Do not find symbol names for addresses in DWARF data"
+msgstr "Не шукати назви символів для адрес у даних DWARF"
+
+#: src/readelf.c:129
+msgid ""
+"Display just offsets instead of resolving values to addresses in DWARF data"
+msgstr "Показати лише зміщення, а не визначені значення адреси у даних DWARF"
+
+#: src/readelf.c:131
+msgid "Ignored for compatibility (lines always wide)"
+msgstr "Ігнорується з міркувань сумісності (рядки завжди широкі)"
+
+#: src/readelf.c:133
+msgid ""
+"Show compression information for compressed sections (when used with -S); "
+"decompress section before dumping data (when used with -p or -x)"
+msgstr ""
+
+#. Short description of program.
+#: src/readelf.c:138
+msgid "Print information from ELF file in human-readable form."
+msgstr "Виводити відомості з файла ELF у придатному для читання форматі."
+
+#: src/readelf.c:467
+#, c-format
+msgid "Unknown DWARF debug section `%s'.\n"
+msgstr "Невідомий діагностичний розділ DWARF «%s».\n"
+
+#: src/readelf.c:535 src/readelf.c:646
+#, c-format
+msgid "cannot generate Elf descriptor: %s"
+msgstr "не вдалося створити дескриптор Elf: %s"
+
+#: src/readelf.c:542 src/readelf.c:858 src/strip.c:641
+#, c-format
+msgid "cannot determine number of sections: %s"
+msgstr "не вдалося визначити кількість розділів: %s"
+
+#: src/readelf.c:560 src/readelf.c:1151 src/readelf.c:1353
+#, c-format
+msgid "cannot get section: %s"
+msgstr "не вдалося отримати розділ: %s"
+
+#: src/readelf.c:569 src/readelf.c:1158 src/readelf.c:1361 src/readelf.c:9767
+#: src/unstrip.c:375 src/unstrip.c:406 src/unstrip.c:455 src/unstrip.c:565
+#: src/unstrip.c:582 src/unstrip.c:619 src/unstrip.c:817 src/unstrip.c:1109
+#: src/unstrip.c:1301 src/unstrip.c:1362 src/unstrip.c:1535 src/unstrip.c:1650
+#: src/unstrip.c:1790 src/unstrip.c:1885
+#, c-format
+msgid "cannot get section header: %s"
+msgstr "не вдалося отримати заголовок розділу: %s"
+
+#: src/readelf.c:577
+#, c-format
+msgid "cannot get section name"
+msgstr "не вдалося отримати назву розділу"
+
+#: src/readelf.c:586 src/readelf.c:5562 src/readelf.c:7902 src/readelf.c:8004
+#: src/readelf.c:8181
+#, c-format
+msgid "cannot get %s content: %s"
+msgstr "не вдалося отримати дані %s: %s"
+
+#: src/readelf.c:602
+#, c-format
+msgid "cannot create temp file '%s'"
+msgstr "не вдалося створити файл тимчасових даних «%s»"
+
+#: src/readelf.c:611
+#, c-format
+msgid "cannot write section data"
+msgstr "не вдалося записати дані розділу"
+
+#: src/readelf.c:617 src/readelf.c:634 src/readelf.c:663
+#, c-format
+msgid "error while closing Elf descriptor: %s"
+msgstr "помилка під час спроби закриття дескриптора Elf: %s"
+
+#: src/readelf.c:624
+#, c-format
+msgid "error while rewinding file descriptor"
+msgstr "помилка під час повернення до початкового значення дескриптора файла"
+
+#: src/readelf.c:658
+#, c-format
+msgid "'%s' is not an archive, cannot print archive index"
+msgstr "«%s» не є архівом, виведення покажчика архіву неможливе"
+
+#: src/readelf.c:757
+#, c-format
+msgid "No such section '%s' in '%s'"
+msgstr "У «%2$s» немає розділу «%1$s»"
+
+#: src/readelf.c:784
+#, c-format
+msgid "cannot stat input file"
+msgstr "не вдалося отримати дані з вхідного файла за допомогою stat"
+
+#: src/readelf.c:786
+#, c-format
+msgid "input file is empty"
+msgstr "вхідний файл є порожнім"
+
+#: src/readelf.c:788
+#, c-format
+msgid "failed reading '%s': %s"
+msgstr "не вдалося прочитати «%s»: %s"
+
+#: src/readelf.c:843
+#, c-format
+msgid "cannot read ELF header: %s"
+msgstr "не вдалося прочитати заголовок ELF: %s"
+
+#: src/readelf.c:851
+#, c-format
+msgid "cannot create EBL handle"
+msgstr "не вдалося створити дескриптор EBL"
+
+#: src/readelf.c:864
+#, c-format
+msgid "cannot determine number of program headers: %s"
+msgstr "не вдалося визначити кількість заголовків програми: %s"
+
+#: src/readelf.c:954
+msgid "NONE (None)"
+msgstr "NONE (Немає)"
+
+#: src/readelf.c:955
+msgid "REL (Relocatable file)"
+msgstr "REL (Придатний до пересування файл)"
+
+#: src/readelf.c:956
+msgid "EXEC (Executable file)"
+msgstr "EXEC (Виконуваний файл)"
+
+#: src/readelf.c:957
+msgid "DYN (Shared object file)"
+msgstr "DYN (Файл об’єктів спільного використання)"
+
+#: src/readelf.c:958
+msgid "CORE (Core file)"
+msgstr "CORE (Файл ядра)"
+
+#: src/readelf.c:963
+#, c-format
+msgid "OS Specific: (%x)\n"
+msgstr "ОС-специфічне: (%x)\n"
+
+#. && e_type <= ET_HIPROC always true
+#: src/readelf.c:965
+#, c-format
+msgid "Processor Specific: (%x)\n"
+msgstr "Специфічне для процесора: (%x)\n"
+
+#: src/readelf.c:975
+msgid ""
+"ELF Header:\n"
+"  Magic:  "
+msgstr ""
+"Заголовок ELF:\n"
+"  Magic:  "
+
+#: src/readelf.c:979
+#, c-format
+msgid ""
+"\n"
+"  Class:                             %s\n"
+msgstr ""
+"\n"
+"  Клас:                              %s\n"
+
+#: src/readelf.c:984
+#, c-format
+msgid "  Data:                              %s\n"
+msgstr "  Дані:                              %s\n"
+
+#: src/readelf.c:990
+#, c-format
+msgid "  Ident Version:                     %hhd %s\n"
+msgstr "   Версія Ident:                     %hhd %s\n"
+
+#: src/readelf.c:992 src/readelf.c:1009
+msgid "(current)"
+msgstr "(поточний)"
+
+#: src/readelf.c:996
+#, c-format
+msgid "  OS/ABI:                            %s\n"
+msgstr "  ОС/ABI:                            %s\n"
+
+#: src/readelf.c:999
+#, c-format
+msgid "  ABI Version:                       %hhd\n"
+msgstr "  Версія ABI:                       %hhd\n"
+
+#: src/readelf.c:1002
+msgid "  Type:                              "
+msgstr "  Тип:                                "
+
+#: src/readelf.c:1005
+#, c-format
+msgid "  Machine:                           %s\n"
+msgstr "  Архітектура:                       %s\n"
+
+#: src/readelf.c:1007
+#, c-format
+msgid "  Version:                           %d %s\n"
+msgstr "  Версія:                            %d %s\n"
+
+#: src/readelf.c:1011
+#, c-format
+msgid "  Entry point address:               %#<PRIx64>\n"
+msgstr "  Адреса вхідної точки:              %#<PRIx64>\n"
+
+#: src/readelf.c:1014
+#, c-format
+msgid "  Start of program headers:          %<PRId64> %s\n"
+msgstr "  Початок заголовків програм:      %<PRId64> %s\n"
+
+#: src/readelf.c:1015 src/readelf.c:1018
+msgid "(bytes into file)"
+msgstr "(байтів у файл)"
+
+#: src/readelf.c:1017
+#, c-format
+msgid "  Start of section headers:          %<PRId64> %s\n"
+msgstr "  Початок заголовків розділів:     %<PRId64> %s\n"
+
+#: src/readelf.c:1020
+#, c-format
+msgid "  Flags:                             %s\n"
+msgstr "  Прапорці:                          %s\n"
+
+#: src/readelf.c:1023
+#, c-format
+msgid "  Size of this header:               %<PRId16> %s\n"
+msgstr "  Розмір цього заголовка:            %<PRId16> %s\n"
+
+#: src/readelf.c:1024 src/readelf.c:1027 src/readelf.c:1044
+msgid "(bytes)"
+msgstr "(байтів)"
+
+#: src/readelf.c:1026
+#, c-format
+msgid "  Size of program header entries:    %<PRId16> %s\n"
+msgstr "  Розмір записів заголовка програми:  %<PRId16> %s\n"
+
+#: src/readelf.c:1029
+#, c-format
+msgid "  Number of program headers entries: %<PRId16>"
+msgstr "  Кількість записів заголовків програми: %<PRId16>"
+
+#: src/readelf.c:1036
+#, c-format
+msgid " (%<PRIu32> in [0].sh_info)"
+msgstr " (%<PRIu32> у [0].sh_info)"
+
+#: src/readelf.c:1039 src/readelf.c:1056 src/readelf.c:1070
+msgid " ([0] not available)"
+msgstr " ([0] недоступний)"
+
+#: src/readelf.c:1043
+#, c-format
+msgid "  Size of section header entries:    %<PRId16> %s\n"
+msgstr "  Розмір записів заголовків розділів:  %<PRId16> %s\n"
+
+#: src/readelf.c:1046
+#, c-format
+msgid "  Number of section headers entries: %<PRId16>"
+msgstr "  Кількість записів заголовків розділів: %<PRId16>"
+
+#: src/readelf.c:1053
+#, c-format
+msgid " (%<PRIu32> in [0].sh_size)"
+msgstr " (%<PRIu32> у [0].sh_size)"
+
+#. We managed to get the zeroth section.
+#: src/readelf.c:1066
+#, c-format
+msgid " (%<PRIu32> in [0].sh_link)"
+msgstr " (%<PRIu32> у [0].sh_link)"
+
+#: src/readelf.c:1074
+#, c-format
+msgid ""
+"  Section header string table index: XINDEX%s\n"
+"\n"
+msgstr ""
+"  Індекс заголовка розділу у таблиці рядків: XINDEX%s\n"
+"\n"
+
+#: src/readelf.c:1078
+#, c-format
+msgid ""
+"  Section header string table index: %<PRId16>\n"
+"\n"
+msgstr ""
+"  Індекс заголовка розділу у таблиці рядків: %<PRId16>\n"
+"\n"
+
+#: src/readelf.c:1121
+#, c-format
+msgid ""
+"There are %d section headers, starting at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+"Виявлено %d заголовків розділів, зміщення початку — %#<PRIx64>:\n"
+"\n"
+
+#: src/readelf.c:1131
+msgid "Section Headers:"
+msgstr "Заголовки розділів:"
+
+#: src/readelf.c:1134
+msgid ""
+"[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
+"Inf Al"
+msgstr ""
+"[№ ] Назва                Тип          Адр      Змі    Розмір ES Прап  Lk "
+"Інф Al"
+
+#: src/readelf.c:1136
+msgid ""
+"[Nr] Name                 Type         Addr             Off      Size     ES "
+"Flags Lk Inf Al"
+msgstr ""
+"[№ ] Назва                Тип          Адр              Змі      Розмір   ES "
+"Прап  Lk Інф Al"
+
+#: src/readelf.c:1141
+msgid "     [Compression  Size   Al]"
+msgstr ""
+
+#: src/readelf.c:1143
+msgid "     [Compression  Size     Al]"
+msgstr ""
+
+#: src/readelf.c:1219
+#, fuzzy, c-format
+msgid "bad compression header for section %zd: %s"
+msgstr "не вдалося отримати заголовок розділу %zu: %s"
+
+#: src/readelf.c:1230
+#, fuzzy, c-format
+msgid "bad gnu compressed size for section %zd: %s"
+msgstr "не вдалося отримати дані для розділу %d: %s"
+
+#: src/readelf.c:1248
+msgid "Program Headers:"
+msgstr "Заголовки програми:"
+
+#: src/readelf.c:1250
+msgid ""
+"  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
+msgstr ""
+"  Тип            Зміщен   ВіртАдр    ФізАдр     РозмФайл РозмПам  Пра Вирів"
+
+#: src/readelf.c:1253
+msgid ""
+"  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
+"MemSiz   Flg Align"
+msgstr ""
+"  Тип           Зміщен   ВіртАдр            ФізАдр             "
+"РозмФайлРозмПам  Пра Вирів"
+
+#: src/readelf.c:1310
+#, c-format
+msgid "\t[Requesting program interpreter: %s]\n"
+msgstr "\t[Запит щодо інтерпретатора програми: %s]\n"
+
+#: src/readelf.c:1331
+msgid ""
+"\n"
+" Section to Segment mapping:\n"
+"  Segment Sections..."
+msgstr ""
+"\n"
+" Відображення розділів на сегмент:\n"
+"  Розділи сегмента..."
+
+#: src/readelf.c:1342 src/unstrip.c:1944 src/unstrip.c:1986 src/unstrip.c:1993
+#, c-format
+msgid "cannot get program header: %s"
+msgstr "не вдалося отримати заголовок програми: %s"
+
+#: src/readelf.c:1485
+#, c-format
+msgid ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"Група розділів COMDAT [%2zu] «%s» з підписом «%s» містить %zu запис:\n"
+msgstr[1] ""
+"\n"
+"Група розділів COMDAT [%2zu] «%s» з підписом «%s» містить %zu записи:\n"
+msgstr[2] ""
+"\n"
+"Група розділів COMDAT [%2zu] «%s» з підписом «%s» містить %zu записів:\n"
+
+#: src/readelf.c:1490
+#, c-format
+msgid ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"Група розділів [%2zu] «%s» з підписом «%s» містить %zu запис:\n"
+msgstr[1] ""
+"\n"
+"Група розділів [%2zu] «%s» з підписом «%s» містить %zu записи:\n"
+msgstr[2] ""
+"\n"
+"Група розділів [%2zu] «%s» з підписом «%s» містить %zu записів:\n"
+
+#: src/readelf.c:1498
+msgid "<INVALID SYMBOL>"
+msgstr "<НЕКОРЕКТНИЙ СИМВОЛ>"
+
+#: src/readelf.c:1512
+msgid "<INVALID SECTION>"
+msgstr "<НЕКОРЕКТНИЙ РОЗДІЛ>"
+
+#: src/readelf.c:1535 src/readelf.c:2262 src/readelf.c:3345 src/readelf.c:9638
+#: src/readelf.c:9645 src/readelf.c:9689 src/readelf.c:9696
+msgid "Couldn't uncompress section"
+msgstr ""
+
+#: src/readelf.c:1540 src/readelf.c:2267 src/readelf.c:3350
+#, fuzzy, c-format
+msgid "cannot get section [%zd] header: %s"
+msgstr "не вдалося отримати заголовок розділу: %s"
+
+#: src/readelf.c:1684 src/readelf.c:2334 src/readelf.c:2592 src/readelf.c:2668
+#: src/readelf.c:2972 src/readelf.c:3046 src/readelf.c:4773
+#, c-format
+msgid "invalid sh_link value in section %zu"
+msgstr "некоректне значення sh_link у розділі %zu"
+
+#: src/readelf.c:1687
+#, c-format
+msgid ""
+"\n"
+"Dynamic segment contains %lu entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Dynamic segment contains %lu entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Динамічний сегмент містить %lu запис:\n"
+" Адр: %#0*<PRIx64>  Зміщення: %#08<PRIx64>  Пос. на розділ: [%2u] '%s'\n"
+msgstr[1] ""
+"\n"
+"Динамічний сегмент містить %lu записи:\n"
+" Адр: %#0*<PRIx64>  Зміщення: %#08<PRIx64>  Пос. на розділ: [%2u] '%s'\n"
+msgstr[2] ""
+"\n"
+"Динамічний сегмент містить %lu записів:\n"
+" Адр: %#0*<PRIx64>  Зміщення: %#08<PRIx64>  Пос. на розділ: [%2u] '%s'\n"
+
+#: src/readelf.c:1697
+msgid "  Type              Value\n"
+msgstr "  Тип              Значення\n"
+
+#: src/readelf.c:1721
+#, c-format
+msgid "Shared library: [%s]\n"
+msgstr "Спільна бібліотека: [%s]\n"
+
+#: src/readelf.c:1726
+#, c-format
+msgid "Library soname: [%s]\n"
+msgstr "Назва so бібліотеки: [%s]\n"
+
+#: src/readelf.c:1731
+#, c-format
+msgid "Library rpath: [%s]\n"
+msgstr "Rpath бібліотеки: [%s]\n"
+
+#: src/readelf.c:1736
+#, c-format
+msgid "Library runpath: [%s]\n"
+msgstr "Runpath бібліотеки: [%s]\n"
+
+#: src/readelf.c:1756
+#, c-format
+msgid "%<PRId64> (bytes)\n"
+msgstr "%<PRId64> (байт)\n"
+
+#: src/readelf.c:1869 src/readelf.c:2059
+#, c-format
+msgid ""
+"\n"
+"Invalid symbol table at offset %#0<PRIx64>\n"
+msgstr ""
+"\n"
+"Некоректна таблиця символів за зміщенням %#0<PRIx64>\n"
+
+#: src/readelf.c:1887 src/readelf.c:2077
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"Розділ пересування [%2zu] «%s» для розділу [%2u] «%s» за зміщенням "
+"%#0<PRIx64> містить %d запис:\n"
+msgstr[1] ""
+"\n"
+"Розділ пересування [%2zu] «%s» для розділу [%2u] «%s» за зміщенням "
+"%#0<PRIx64> містить %d записи:\n"
+msgstr[2] ""
+"\n"
+"Розділ пересування [%2zu] «%s» для розділу [%2u] «%s» за зміщенням "
+"%#0<PRIx64> містить %d записів:\n"
+
+#. The .rel.dyn section does not refer to a specific section but
+#. instead of section index zero.  Do not try to print a section
+#. name.
+#. The .rela.dyn section does not refer to a specific section but
+#. instead of section index zero.  Do not try to print a section
+#. name.
+#: src/readelf.c:1902 src/readelf.c:2092
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"Розділ пересування [%2u] «%s» за зміщенням %#0<PRIx64> містить %d запис:\n"
+msgstr[1] ""
+"\n"
+"Розділ пересування [%2u] «%s» за зміщенням %#0<PRIx64> містить %d записи:\n"
+msgstr[2] ""
+"\n"
+"Розділ пересування [%2u] «%s» за зміщенням %#0<PRIx64> містить %d записів:\n"
+
+#: src/readelf.c:1912
+msgid "  Offset      Type                 Value       Name\n"
+msgstr "  Зміщення     Тип                  Значення    Назва\n"
+
+#: src/readelf.c:1914
+msgid "  Offset              Type                 Value               Name\n"
+msgstr "  Зміщення            Тип                  Значення            Назва\n"
+
+#: src/readelf.c:1967 src/readelf.c:1978 src/readelf.c:1991 src/readelf.c:2012
+#: src/readelf.c:2024 src/readelf.c:2158 src/readelf.c:2170 src/readelf.c:2184
+#: src/readelf.c:2206 src/readelf.c:2219
+msgid "<INVALID RELOC>"
+msgstr "<НЕКОРЕКТНЕ ПЕРЕМІЩЕННЯ>"
+
+#: src/readelf.c:2102
+msgid "  Offset      Type            Value       Addend Name\n"
+msgstr "  Зміщення    Тип             Значення    Назва додатка\n"
+
+#: src/readelf.c:2104
+msgid "  Offset              Type            Value               Addend Name\n"
+msgstr ""
+"  Зміщення            Тип             Значення            Назва додатка\n"
+
+#: src/readelf.c:2342
+#, c-format
+msgid ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entry:\n"
+msgid_plural ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entries:\n"
+msgstr[0] ""
+"\n"
+"Таблиця символів [%2u] «%s» містить %u запис:\n"
+msgstr[1] ""
+"\n"
+"Таблиця символів [%2u] «%s» містить %u записи:\n"
+msgstr[2] ""
+"\n"
+"Таблиця символів [%2u] «%s» містить %u записів:\n"
+
+#: src/readelf.c:2347
+#, c-format
+msgid " %lu local symbol  String table: [%2u] '%s'\n"
+msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
+msgstr[0] " %lu лок. символ   Таблиця символів: [%2u] «%s»\n"
+msgstr[1] " %lu лок. символи  Таблиця символів: [%2u] «%s»\n"
+msgstr[2] " %lu лок. символів Таблиця символів: [%2u] «%s»\n"
+
+#: src/readelf.c:2355
+msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr "  №№      Знач.   Роз. Тип     Зв’яз  Вид.         Інд Назва\n"
+
+#: src/readelf.c:2357
+msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr "  №№              Знач.   Роз. Тип     Зв’яз  Вид.         Інд Назва\n"
+
+#: src/readelf.c:2377
+#, c-format
+msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+msgstr "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+
+#: src/readelf.c:2465
+#, c-format
+msgid "bad dynamic symbol"
+msgstr "помилковий динамічний символ"
+
+#: src/readelf.c:2547
+msgid "none"
+msgstr "немає"
+
+#: src/readelf.c:2564
+msgid "| <unknown>"
+msgstr "| <невідомо>"
+
+#: src/readelf.c:2595
+#, c-format
+msgid ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Розділ потреби у версіях [%2u] «%s», що містить %d запис:\n"
+" Адр.: %#0*<PRIx64>  Зміщ.:  %#08<PRIx64>  Посилання на розділ: [%2u] «%s»\n"
+msgstr[1] ""
+"\n"
+"Розділ потреби у версіях [%2u] «%s», що містить %d записи:\n"
+" Адр.: %#0*<PRIx64>  Зміщ.:  %#08<PRIx64>  Посилання на розділ: [%2u] «%s»\n"
+msgstr[2] ""
+"\n"
+"Розділ потреби у версіях [%2u] «%s», що містить %d записів:\n"
+" Адр.: %#0*<PRIx64>  Зміщ.:  %#08<PRIx64>  Посилання на розділ: [%2u] «%s»\n"
+
+#: src/readelf.c:2616
+#, c-format
+msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
+msgstr "  %#06x: Версія: %hu  Файл: %s  Кть: %hu\n"
+
+#: src/readelf.c:2629
+#, c-format
+msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
+msgstr "  %#06x: Назва: %s  Прап: %s  Версія: %hu\n"
+
+#: src/readelf.c:2672
+#, c-format
+msgid ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Розділ визначення версії [%2u] «%s», що містить %d запис:\n"
+" Адр.: %#0*<PRIx64>  Зміщ.:  %#08<PRIx64>  Посилання на розділ: [%2u] «%s»\n"
+msgstr[1] ""
+"\n"
+"Розділ визначення версії [%2u] «%s», що містить %d записи:\n"
+" Адр.: %#0*<PRIx64>  Зміщ.:  %#08<PRIx64>  Посилання на розділ: [%2u] «%s»\n"
+msgstr[2] ""
+"\n"
+"Розділ визначення версії [%2u] «%s», що містить %d записів:\n"
+" Адр.: %#0*<PRIx64>  Зміщ.:  %#08<PRIx64>  Посилання на розділ: [%2u] «%s»\n"
+
+#: src/readelf.c:2700
+#, c-format
+msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
+msgstr "  %#06x: Версія:  %hd  Прап.: %s  Індекс: %hd К-ть: %hd Назва: %s\n"
+
+#: src/readelf.c:2715
+#, c-format
+msgid "  %#06x: Parent %d: %s\n"
+msgstr "  %#06x: батьківський %d: %s\n"
+
+#. Print the header.
+#: src/readelf.c:2976
+#, c-format
+msgid ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgid_plural ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgstr[0] ""
+"\n"
+"Розділ символів версій [%2u] «%s», що містить %d запис:\n"
+" Адр.: %#0*<PRIx64>  Зміщ.:  %#08<PRIx64>  Посилання на розділ: [%2u] «%s»"
+msgstr[1] ""
+"\n"
+"Розділ символів версій [%2u] «%s», що містить %d записи:\n"
+" Адр.: %#0*<PRIx64>  Зміщ.:  %#08<PRIx64>  Посилання на розділ: [%2u] «%s»"
+msgstr[2] ""
+"\n"
+"Розділ символів версій [%2u] «%s», що містить %d записів:\n"
+" Адр.: %#0*<PRIx64>  Зміщ.:  %#08<PRIx64>  Посилання на розділ: [%2u] «%s»"
+
+#: src/readelf.c:3004
+msgid "   0 *local*                     "
+msgstr "   0 *локальний*                 "
+
+#: src/readelf.c:3009
+msgid "   1 *global*                    "
+msgstr "   1 *загальний*                 "
+
+#: src/readelf.c:3051
+#, c-format
+msgid ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"bucket):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"buckets):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+"\n"
+"Гістограма довжин списків блоків у розділі [%2u] «%s» (загальні дані за %d "
+"блоком):\n"
+" Адр.: %#0*<PRIx64>  Зміщ.: %#08<PRIx64>  Посилання на розділ: [%2u] «%s»\n"
+msgstr[1] ""
+"\n"
+"Гістограма довжин списків блоків у розділі [%2u] «%s» (загальні дані за %d "
+"блоками):\n"
+" Адр.: %#0*<PRIx64>  Зміщ.: %#08<PRIx64>  Посилання на розділ: [%2u] «%s»\n"
+msgstr[2] ""
+"\n"
+"Гістограма довжин списків блоків у розділі [%2u] «%s» (загальні дані за %d "
+"блоками):\n"
+" Адр.: %#0*<PRIx64>  Зміщ.: %#08<PRIx64>  Посилання на розділ: [%2u] «%s»\n"
+
+#: src/readelf.c:3073
+#, no-c-format
+msgid " Length  Number  % of total  Coverage\n"
+msgstr " Довжина Номер   % від загал. Покриття\n"
+
+#: src/readelf.c:3075
+#, c-format
+msgid "      0  %6<PRIu32>      %5.1f%%\n"
+msgstr "      0  %6<PRIu32>      %5.1f%%\n"
+
+#: src/readelf.c:3082
+#, c-format
+msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+msgstr "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+
+#: src/readelf.c:3095
+#, c-format
+msgid ""
+" Average number of tests:   successful lookup: %f\n"
+"\t\t\t  unsuccessful lookup: %f\n"
+msgstr ""
+" Середня кількість тестів:   успішний пошук: %f\n"
+"\t\t\t  неуспішний пошук: %f\n"
+
+#: src/readelf.c:3113 src/readelf.c:3168 src/readelf.c:3225
+#, c-format
+msgid "cannot get data for section %d: %s"
+msgstr "не вдалося отримати дані для розділу %d: %s"
+
+#: src/readelf.c:3121
+#, c-format
+msgid "invalid data in sysv.hash section %d"
+msgstr "некоректні дані у розділі sysv.hash %d"
+
+#: src/readelf.c:3176
+#, c-format
+msgid "invalid data in sysv.hash64 section %d"
+msgstr "некоректні дані у розділі sysv.hash64 %d"
+
+#: src/readelf.c:3234
+#, c-format
+msgid "invalid data in gnu.hash section %d"
+msgstr "некоректні дані у розділі gnu.hash %d"
+
+#: src/readelf.c:3301
+#, c-format
+msgid ""
+" Symbol Bias: %u\n"
+" Bitmask Size: %zu bytes  %<PRIuFAST32>%% bits set  2nd hash shift: %u\n"
+msgstr ""
+" Відхилення символу: %u\n"
+" Розмір бітової маски: %zu байтів  %<PRIuFAST32>%% встановлених бітів  зсув "
+"2-го хешу: %u\n"
+
+#: src/readelf.c:3390
+#, c-format
+msgid ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+"\n"
+"Розділ списку бібліотек [%2zu] «%s» за зміщенням %#0<PRIx64> містить %d "
+"запис:\n"
+msgstr[1] ""
+"\n"
+"Розділ списку бібліотек [%2zu] «%s» за зміщенням %#0<PRIx64> містить %d "
+"записи:\n"
+msgstr[2] ""
+"\n"
+"Розділ списку бібліотек [%2zu] «%s» за зміщенням %#0<PRIx64> містить %d "
+"записів:\n"
+
+#: src/readelf.c:3404
+msgid ""
+"       Library                       Time Stamp          Checksum Version "
+"Flags"
+msgstr ""
+"       Бібліотека                    Часовий штамп       Версія суми      "
+"Прапорці"
+
+#: src/readelf.c:3454
+#, c-format
+msgid ""
+"\n"
+"Object attributes section [%2zu] '%s' of %<PRIu64> bytes at offset "
+"%#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Розділ атрибутів об’єктів [%2zu] «%s» з %<PRIu64> байтів за зміщенням "
+"%#0<PRIx64>:\n"
+
+#: src/readelf.c:3471
+msgid "  Owner          Size\n"
+msgstr "  Власник        Розмір\n"
+
+#: src/readelf.c:3500
+#, c-format
+msgid "  %-13s  %4<PRIu32>\n"
+msgstr "  %-13s  %4<PRIu32>\n"
+
+#. Unknown subsection, print and skip.
+#: src/readelf.c:3539
+#, c-format
+msgid "    %-4u %12<PRIu32>\n"
+msgstr "    %-4u %12<PRIu32>\n"
+
+#. Tag_File
+#: src/readelf.c:3544
+#, c-format
+msgid "    File: %11<PRIu32>\n"
+msgstr "    Файл: %11<PRIu32>\n"
+
+#: src/readelf.c:3593
+#, c-format
+msgid "      %s: %<PRId64>, %s\n"
+msgstr "      %s: %<PRId64>, %s\n"
+
+#: src/readelf.c:3596
+#, c-format
+msgid "      %s: %<PRId64>\n"
+msgstr "      %s: %<PRId64>\n"
+
+#: src/readelf.c:3599
+#, c-format
+msgid "      %s: %s\n"
+msgstr "      %s: %s\n"
+
+#: src/readelf.c:3609
+#, c-format
+msgid "      %u: %<PRId64>\n"
+msgstr "      %u: %<PRId64>\n"
+
+#: src/readelf.c:3612
+#, c-format
+msgid "      %u: %s\n"
+msgstr "      %u: %s\n"
+
+#: src/readelf.c:3657
+#, c-format
+msgid "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3660
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3665
+#, c-format
+msgid "%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%#<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3668
+#, c-format
+msgid "%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr "%#0*<PRIx64> <%s+%#<PRIx64>>"
+
+#: src/readelf.c:3674
+#, c-format
+msgid "%s+%#<PRIx64> <%s>"
+msgstr "%s+%#<PRIx64> <%s>"
+
+#: src/readelf.c:3677
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s>"
+msgstr "%s+%#0*<PRIx64> <%s>"
+
+#: src/readelf.c:3681
+#, c-format
+msgid "%#<PRIx64> <%s>"
+msgstr "%#<PRIx64> <%s>"
+
+#: src/readelf.c:3684
+#, c-format
+msgid "%#0*<PRIx64> <%s>"
+msgstr "%#0*<PRIx64> <%s>"
+
+#: src/readelf.c:3689
+#, c-format
+msgid "%s+%#<PRIx64>"
+msgstr "%s+%#<PRIx64>"
+
+#: src/readelf.c:3692
+#, c-format
+msgid "%s+%#0*<PRIx64>"
+msgstr "%s+%#0*<PRIx64>"
+
+#: src/readelf.c:4095
+msgid "empty block"
+msgstr "порожній блок"
+
+#: src/readelf.c:4098
+#, c-format
+msgid "%zu byte block:"
+msgstr "%zu-байтовий блок:"
+
+#: src/readelf.c:4495
+#, c-format
+msgid "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+msgstr "%*s[%4<PRIuMAX>] %s  <ОБРІЗАНО>\n"
+
+#: src/readelf.c:4552
+#, c-format
+msgid "%s %#<PRIx64> used with different address sizes"
+msgstr "%s %#<PRIx64> використано з різними розмірами адрес"
+
+#: src/readelf.c:4559
+#, c-format
+msgid "%s %#<PRIx64> used with different offset sizes"
+msgstr "%s %#<PRIx64> використано з різними розмірами зміщень"
+
+#: src/readelf.c:4566
+#, c-format
+msgid "%s %#<PRIx64> used with different base addresses"
+msgstr "%s %#<PRIx64> використано з різними базовими адресами"
+
+#: src/readelf.c:4655
+#, c-format
+msgid " [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"
+msgstr " [%6tx]  <НЕВИКОРИСТОВУВАНІ ДАНІ У РЕШТІ РОЗДІЛУ>\n"
+
+#: src/readelf.c:4663
+#, c-format
+msgid " [%6tx]  <UNUSED GARBAGE> ... %<PRIu64> bytes ...\n"
+msgstr " [%6tx]  <НЕВИКОРИСТОВУВАНІ ДАНІ> ... %<PRIu64> байтів ...\n"
+
+#: src/readelf.c:4689
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [ Code]\n"
+msgstr ""
+"\n"
+"Розділ DWARF [%2zu] «%s» зі зміщенням %#<PRIx64>:\n"
+" [ Код]\n"
+
+#: src/readelf.c:4697
+#, c-format
+msgid ""
+"\n"
+"Abbreviation section at offset %<PRIu64>:\n"
+msgstr ""
+"\n"
+"Розділ скорочень за зміщенням %<PRIu64>:\n"
+
+#: src/readelf.c:4710
+#, c-format
+msgid " *** error while reading abbreviation: %s\n"
+msgstr " *** помилка під час читання скорочення: %s\n"
+
+#: src/readelf.c:4726
+#, c-format
+msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
+msgstr " [%5u] зміщення: %<PRId64>, дочірній: %s, мітка: %s\n"
+
+#: src/readelf.c:4729 src/readelf.c:6178 src/readelf.c:6186 src/readelf.c:7759
+msgid "yes"
+msgstr "так"
+
+#: src/readelf.c:4729 src/readelf.c:6178 src/readelf.c:7759
+msgid "no"
+msgstr "ні"
+
+#: src/readelf.c:4763 src/readelf.c:4836
+#, c-format
+msgid "cannot get .debug_aranges content: %s"
+msgstr "не вдалося отримати дані get .debug_aranges: %s"
+
+#: src/readelf.c:4778
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entries:\n"
+msgstr[0] ""
+"\n"
+"Розділ DWARF [%2zu] «%s» за зміщенням %#<PRIx64> містить %zu запис:\n"
+msgstr[1] ""
+"\n"
+"Розділ DWARF [%2zu] «%s» за зміщенням %#<PRIx64> містить %zu записи:\n"
+msgstr[2] ""
+"\n"
+"Розділ DWARF [%2zu] «%s» за зміщенням %#<PRIx64> містить %zu записів:\n"
+
+#: src/readelf.c:4809
+#, c-format
+msgid " [%*zu] ???\n"
+msgstr " [%*zu] ???\n"
+
+#: src/readelf.c:4811
+#, c-format
+msgid ""
+" [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
+msgstr ""
+" [%*zu] початок: %0#*<PRIx64>, довжина: %5<PRIu64>, зміщення CU DIE: "
+"%6<PRId64>\n"
+
+#: src/readelf.c:4841 src/readelf.c:4995 src/readelf.c:5572 src/readelf.c:6529
+#: src/readelf.c:7061 src/readelf.c:7181 src/readelf.c:7345 src/readelf.c:7833
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+"\n"
+"Розділ DWARF [%2zu] «%s» зі зміщенням %#<PRIx64>:\n"
+
+#: src/readelf.c:4854 src/readelf.c:6555
+#, c-format
+msgid ""
+"\n"
+"Table at offset %zu:\n"
+msgstr ""
+"\n"
+"Таблиця за зміщенням %zu:\n"
+
+#: src/readelf.c:4858 src/readelf.c:5596 src/readelf.c:6566
+#, c-format
+msgid "invalid data in section [%zu] '%s'"
+msgstr "некоректні дані у розділі [%zu] «%s»"
+
+#: src/readelf.c:4874
+#, c-format
+msgid ""
+"\n"
+" Length:        %6<PRIu64>\n"
+msgstr ""
+"\n"
+" Довжина:       %6<PRIu64>\n"
+
+#: src/readelf.c:4886
+#, c-format
+msgid " DWARF version: %6<PRIuFAST16>\n"
+msgstr " версія DWARF:  %6<PRIuFAST16>\n"
+
+#: src/readelf.c:4890
+#, c-format
+msgid "unsupported aranges version"
+msgstr "непідтримувана версія aranges"
+
+#: src/readelf.c:4901
+#, c-format
+msgid " CU offset:     %6<PRIx64>\n"
+msgstr " зміщення CU:     %6<PRIx64>\n"
+
+#: src/readelf.c:4907
+#, c-format
+msgid " Address size:  %6<PRIu64>\n"
+msgstr " Розмір адреси:  %6<PRIu64>\n"
+
+#: src/readelf.c:4911
+#, c-format
+msgid "unsupported address size"
+msgstr "непідтримуваний розмір адреси"
+
+#: src/readelf.c:4916
+#, c-format
+msgid ""
+" Segment size:  %6<PRIu64>\n"
+"\n"
+msgstr ""
+" Розмір сегмента:  %6<PRIu64>\n"
+"\n"
+
+#: src/readelf.c:4920
+#, c-format
+msgid "unsupported segment size"
+msgstr "непідтримуваний розмір сегмента"
+
+#: src/readelf.c:4960
+#, c-format
+msgid "   %s..%s (%<PRIx64>)\n"
+msgstr "   %s..%s (%<PRIx64>)\n"
+
+#: src/readelf.c:4963
+#, c-format
+msgid "   %s..%s\n"
+msgstr "   %s..%s\n"
+
+#: src/readelf.c:4972
+#, c-format
+msgid "   %zu padding bytes\n"
+msgstr "   %zu байтів доповнення\n"
+
+#: src/readelf.c:4990
+#, c-format
+msgid "cannot get .debug_ranges content: %s"
+msgstr "не вдалося отримати дані .debug_ranges: %s"
+
+#: src/readelf.c:5020 src/readelf.c:7088
+#, c-format
+msgid " [%6tx]  <INVALID DATA>\n"
+msgstr " [%6tx]  <НЕКОРЕКТНІ ДАНІ>\n"
+
+#: src/readelf.c:5042 src/readelf.c:7110
+#, c-format
+msgid " [%6tx]  base address %s\n"
+msgstr " [%6tx]  базова адреса %s\n"
+
+#: src/readelf.c:5049 src/readelf.c:7117
+#, c-format
+msgid " [%6tx]  empty list\n"
+msgstr " [%6tx]  порожній список\n"
+
+#. We have an address range entry.
+#. First address range entry in a list.
+#: src/readelf.c:5060
+#, c-format
+msgid " [%6tx]  %s..%s\n"
+msgstr " [%6tx]  %s..%s\n"
+
+#: src/readelf.c:5062
+#, c-format
+msgid "           %s..%s\n"
+msgstr "           %s..%s\n"
+
+#: src/readelf.c:5298
+msgid "         <INVALID DATA>\n"
+msgstr "         <НЕКОРЕКТНІ ДАНІ>\n"
+
+#: src/readelf.c:5551
+#, c-format
+msgid "cannot get ELF: %s"
+msgstr "не вдалося отримати ELF: %s"
+
+#: src/readelf.c:5568
+#, c-format
+msgid ""
+"\n"
+"Call frame information section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+"\n"
+"Розділ відомостей щодо вікна викликів [%2zu] «%s» за зміщенням %#<PRIx64>:\n"
+
+#: src/readelf.c:5618
+#, c-format
+msgid ""
+"\n"
+" [%6tx] Zero terminator\n"
+msgstr ""
+"\n"
+" [%6tx] нульовий переривач\n"
+
+#: src/readelf.c:5711 src/readelf.c:5866
+#, c-format
+msgid "invalid augmentation length"
+msgstr "некоректна довжина збільшення"
+
+#: src/readelf.c:5726
+msgid "FDE address encoding: "
+msgstr "Кодування адреси FDE: "
+
+#: src/readelf.c:5732
+msgid "LSDA pointer encoding: "
+msgstr "Кодування вказівника LSDA: "
+
+#: src/readelf.c:5843
+#, c-format
+msgid " (offset: %#<PRIx64>)"
+msgstr " (зміщення: %#<PRIx64>)"
+
+#: src/readelf.c:5850
+#, c-format
+msgid " (end offset: %#<PRIx64>)"
+msgstr " (зміщення від кінця: %#<PRIx64>)"
+
+#: src/readelf.c:5887
+#, c-format
+msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
+msgstr "   %-26sвказівник LSDA: %#<PRIx64>\n"
+
+#: src/readelf.c:5942
+#, c-format
+msgid "cannot get attribute code: %s"
+msgstr "не вдалося отримати код атрибута: %s"
+
+#: src/readelf.c:5951
+#, c-format
+msgid "cannot get attribute form: %s"
+msgstr "не вдалося отримати форму атрибута: %s"
+
+#: src/readelf.c:5966
+#, c-format
+msgid "cannot get attribute value: %s"
+msgstr "не вдалося отримати значення атрибута: %s"
+
+#: src/readelf.c:6268
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [Offset]\n"
+msgstr ""
+"\n"
+"Розділ DWARF [%2zu] «%s» за зміщенням %#<PRIx64>:\n"
+" [Зміщення]\n"
+
+#: src/readelf.c:6300
+#, c-format
+msgid ""
+" Type unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: "
+"%<PRIu8>, Offset size: %<PRIu8>\n"
+" Type signature: %#<PRIx64>, Type offset: %#<PRIx64>\n"
+msgstr ""
+" Модуль типів за зміщенням %<PRIu64>:\n"
+" Версія: %<PRIu16>, Зміщення розділу скорочень: %<PRIu64>, Адреса: %<PRIu8>, "
+"Зміщення: %<PRIu8>\n"
+" Підпис типу: %#<PRIx64>, Зміщення типу: %#<PRIx64>\n"
+
+#: src/readelf.c:6309
+#, c-format
+msgid ""
+" Compilation unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: "
+"%<PRIu8>, Offset size: %<PRIu8>\n"
+msgstr ""
+" Модуль компіляції за зміщенням %<PRIu64>:\n"
+" Версія: %<PRIu16>, Зміщення розділу скорочень: %<PRIu64>, Адреса: %<PRIu8>, "
+"Зміщення: %<PRIu8>\n"
+
+#: src/readelf.c:6334
+#, c-format
+msgid "cannot get DIE at offset %<PRIu64> in section '%s': %s"
+msgstr "не вдалося отримати DIE за зміщенням %<PRIu64> у розділі «%s»: %s"
+
+#: src/readelf.c:6348
+#, c-format
+msgid "cannot get DIE offset: %s"
+msgstr "не вдалося отримати зміщення DIE: %s"
+
+#: src/readelf.c:6357
+#, c-format
+msgid "cannot get tag of DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+"не вдалося отримати мітку DIE за зміщенням %<PRIu64> у розділі «%s»: %s"
+
+#: src/readelf.c:6389
+#, c-format
+msgid "cannot get next DIE: %s\n"
+msgstr "не вдалося визначити наступний DIE: %s\n"
+
+#: src/readelf.c:6397
+#, c-format
+msgid "cannot get next DIE: %s"
+msgstr "не вдалося визначити наступний DIE: %s"
+
+#: src/readelf.c:6433
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+"\n"
+"Розділ DWARF [%2zu] «%s» зі зміщенням %#<PRIx64>:\n"
+"\n"
+
+#: src/readelf.c:6542
+#, c-format
+msgid "cannot get line data section data: %s"
+msgstr "не вдалося отримати дані розділу лінійних даних: %s"
+
+#. Print what we got so far.
+#: src/readelf.c:6612
+#, c-format
+msgid ""
+"\n"
+" Length:                     %<PRIu64>\n"
+" DWARF version:              %<PRIuFAST16>\n"
+" Prologue length:            %<PRIu64>\n"
+" Minimum instruction length: %<PRIuFAST8>\n"
+" Maximum operations per instruction: %<PRIuFAST8>\n"
+" Initial value if '%s': %<PRIuFAST8>\n"
+" Line base:                  %<PRIdFAST8>\n"
+" Line range:                 %<PRIuFAST8>\n"
+" Opcode base:                %<PRIuFAST8>\n"
+"\n"
+"Opcodes:\n"
+msgstr ""
+"\n"
+" Довжина:                    %<PRIu64>\n"
+" Версія DWARF:               %<PRIuFAST16>\n"
+" Довжина вступу:             %<PRIu64>\n"
+" Мінімальна довж. інстр.:    %<PRIuFAST8>\n"
+" Макс. к-ть операцій на інструкцію: %<PRIuFAST8>\n"
+" Поч. значення, якщо «%s»:   %<PRIuFAST8>\n"
+" Основа рядків:              %<PRIdFAST8>\n"
+" Діапазон рядків:            %<PRIuFAST8>\n"
+" Основа кодів операцій:      %<PRIuFAST8>\n"
+"\n"
+"Коди операцій:\n"
+
+#: src/readelf.c:6633
+#, c-format
+msgid "invalid data at offset %tu in section [%zu] '%s'"
+msgstr "некоректні дані зі зміщенням %tu у розділі [%zu] «%s»"
+
+#: src/readelf.c:6648
+#, c-format
+msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
+msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
+msgstr[0] "  [%*<PRIuFAST8>]  %hhu аргумент\n"
+msgstr[1] "  [%*<PRIuFAST8>]  %hhu аргументи\n"
+msgstr[2] "  [%*<PRIuFAST8>]  %hhu аргументів\n"
+
+#: src/readelf.c:6656
+msgid ""
+"\n"
+"Directory table:"
+msgstr ""
+"\n"
+"Таблиця каталогу:"
+
+#: src/readelf.c:6672
+msgid ""
+"\n"
+"File name table:\n"
+" Entry Dir   Time      Size      Name"
+msgstr ""
+"\n"
+"Таблиця назв файлів:\n"
+" Запис Кат   Час       Розмір    Назва"
+
+#: src/readelf.c:6707
+msgid ""
+"\n"
+"Line number statements:"
+msgstr ""
+"\n"
+"Оператори номерів рядків:"
+
+#: src/readelf.c:6758
+#, c-format
+msgid "invalid maximum operations per instruction is zero"
+msgstr "некоректну кількість операцій на інструкцію прирівняно до нуля"
+
+#: src/readelf.c:6794
+#, c-format
+msgid " special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"
+msgstr ""
+" спеціальний код операції %u: адреса+%u = %s, індекс_оп = %u, рядок%+d = "
+"%zu\n"
+
+#: src/readelf.c:6799
+#, c-format
+msgid " special opcode %u: address+%u = %s, line%+d = %zu\n"
+msgstr " спеціальний код операції %u: адреса+%u = %s, рядок%+d = %zu\n"
+
+#: src/readelf.c:6819
+#, c-format
+msgid " extended opcode %u: "
+msgstr " розширений код операції %u: "
+
+#: src/readelf.c:6824
+msgid " end of sequence"
+msgstr " кінець послідовності"
+
+#: src/readelf.c:6843
+#, c-format
+msgid " set address to %s\n"
+msgstr " встановити адресу у значення %s\n"
+
+#: src/readelf.c:6870
+#, c-format
+msgid " define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
+msgstr ""
+" визначення нового файла: dir=%u, mtime=%<PRIu64>, довжина=%<PRIu64>, назва="
+"%s\n"
+
+#: src/readelf.c:6883
+#, c-format
+msgid " set discriminator to %u\n"
+msgstr " встановити розрізнення для %u\n"
+
+#. Unknown, ignore it.
+#: src/readelf.c:6888
+msgid " unknown opcode"
+msgstr " невідомий код операції"
+
+#. Takes no argument.
+#: src/readelf.c:6900
+msgid " copy"
+msgstr " копія"
+
+#: src/readelf.c:6911
+#, c-format
+msgid " advance address by %u to %s, op_index to %u\n"
+msgstr " збільшення адреси на %u до %s, індекс_оп до %u\n"
+
+#: src/readelf.c:6915
+#, c-format
+msgid " advance address by %u to %s\n"
+msgstr " збільшення адреси на %u до %s\n"
+
+#: src/readelf.c:6926
+#, c-format
+msgid " advance line by constant %d to %<PRId64>\n"
+msgstr " просувати рядок на сталу %d до %<PRId64>\n"
+
+#: src/readelf.c:6934
+#, c-format
+msgid " set file to %<PRIu64>\n"
+msgstr " встановити файл у %<PRIu64>\n"
+
+#: src/readelf.c:6944
+#, c-format
+msgid " set column to %<PRIu64>\n"
+msgstr " встановити значення стовпчика %<PRIu64>\n"
+
+#: src/readelf.c:6951
+#, c-format
+msgid " set '%s' to %<PRIuFAST8>\n"
+msgstr " встановити «%s» у %<PRIuFAST8>\n"
+
+#. Takes no argument.
+#: src/readelf.c:6957
+msgid " set basic block flag"
+msgstr " встановити прапорець базового блоку"
+
+#: src/readelf.c:6970
+#, c-format
+msgid " advance address by constant %u to %s, op_index to %u\n"
+msgstr " збільшити адресу на сталу величину %u до %s, індекс_оп до %u\n"
+
+#: src/readelf.c:6974
+#, c-format
+msgid " advance address by constant %u to %s\n"
+msgstr " збільшити адресу на сталу величину %u до %s\n"
+
+#: src/readelf.c:6992
+#, c-format
+msgid " advance address by fixed value %u to %s\n"
+msgstr " збільшити адресу на фіксовану величину %u до %s\n"
+
+#. Takes no argument.
+#: src/readelf.c:7001
+msgid " set prologue end flag"
+msgstr " встановити прапорець кінця вступу"
+
+#. Takes no argument.
+#: src/readelf.c:7006
+msgid " set epilogue begin flag"
+msgstr " встановити прапорець початку епілогу"
+
+#: src/readelf.c:7015
+#, c-format
+msgid " set isa to %u\n"
+msgstr " встановити isa у %u\n"
+
+#. This is a new opcode the generator but not we know about.
+#. Read the parameters associated with it but then discard
+#. everything.  Read all the parameters for this opcode.
+#: src/readelf.c:7024
+#, c-format
+msgid " unknown opcode with %<PRIu8> parameter:"
+msgid_plural " unknown opcode with %<PRIu8> parameters:"
+msgstr[0] " невідомий код операції з %<PRIu8> параметром:"
+msgstr[1] " невідомий код операції з %<PRIu8> параметрами:"
+msgstr[2] " невідомий код операції з %<PRIu8> параметрами:"
+
+#: src/readelf.c:7056
+#, c-format
+msgid "cannot get .debug_loc content: %s"
+msgstr "не вдалося отримати вміст .debug_loc: %s"
+
+#. First entry in a list.
+#: src/readelf.c:7131
+#, c-format
+msgid " [%6tx]  %s..%s"
+msgstr " [%6tx]  %s..%s"
+
+#: src/readelf.c:7133
+#, c-format
+msgid "           %s..%s"
+msgstr "           %s..%s"
+
+#: src/readelf.c:7140 src/readelf.c:8091
+msgid "   <INVALID DATA>\n"
+msgstr "   <НЕКОРЕКТНІ ДАНІ>\n"
+
+#: src/readelf.c:7192 src/readelf.c:7354
+#, c-format
+msgid "cannot get macro information section data: %s"
+msgstr "не вдалося отримати дані розділу відомостей щодо макросів: %s"
+
+#: src/readelf.c:7272
+#, c-format
+msgid "%*s*** non-terminated string at end of section"
+msgstr "%*s*** незавершений рядок наприкінці розділу"
+
+#: src/readelf.c:7295
+#, c-format
+msgid "%*s*** missing DW_MACINFO_start_file argument at end of section"
+msgstr "%*s*** пропущено аргумент DW_MACINFO_start_file наприкінці розділу"
+
+#: src/readelf.c:7395
+#, c-format
+msgid " Offset:             0x%<PRIx64>\n"
+msgstr " Зміщення:           0x%<PRIx64>\n"
+
+#: src/readelf.c:7407
+#, c-format
+msgid " Version:            %<PRIu16>\n"
+msgstr " Версія:             %<PRIu16>\n"
+
+#: src/readelf.c:7413 src/readelf.c:8210
+#, c-format
+msgid "  unknown version, cannot parse section\n"
+msgstr "  невідома версія, не вдалося обробити розділ\n"
+
+#: src/readelf.c:7420
+#, c-format
+msgid " Flag:               0x%<PRIx8>\n"
+msgstr " Прапорець:          0x%<PRIx8>\n"
+
+#: src/readelf.c:7423
+#, c-format
+msgid " Offset length:      %<PRIu8>\n"
+msgstr " Довжина зміщення:   %<PRIu8>\n"
+
+#: src/readelf.c:7431
+#, c-format
+msgid " .debug_line offset: 0x%<PRIx64>\n"
+msgstr " зміщення .debug_line: 0x%<PRIx64>\n"
+
+#: src/readelf.c:7444
+#, c-format
+msgid "  extension opcode table, %<PRIu8> items:\n"
+msgstr "  таблиця кодів операцій розширень, записів — %<PRIu8>:\n"
+
+#: src/readelf.c:7451
+#, c-format
+msgid "    [%<PRIx8>]"
+msgstr "    [%<PRIx8>]"
+
+#: src/readelf.c:7463
+#, c-format
+msgid " %<PRIu8> arguments:"
+msgstr " %<PRIu8> аргументів:"
+
+#: src/readelf.c:7491
+#, c-format
+msgid " no arguments."
+msgstr " немає аргументів."
+
+#: src/readelf.c:7791
+#, c-format
+msgid "vendor opcode not verified?"
+msgstr "код операції постачальника не перевірено?"
+
+#: src/readelf.c:7819
+#, c-format
+msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
+msgstr ""
+" [%5d] зміщення DIE: %6<PRId64>, зміщення CU DIE: %6<PRId64>, назва: %s\n"
+
+#: src/readelf.c:7860
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" %*s  String\n"
+msgstr ""
+"\n"
+"Розділ DWARF [%2zu] «%s» зі зміщенням %#<PRIx64>:\n"
+" %*s  Рядок\n"
+
+#: src/readelf.c:7874
+#, c-format
+msgid " *** error while reading strings: %s\n"
+msgstr " *** помилка під час читання рядків: %s\n"
+
+#: src/readelf.c:7894
+#, c-format
+msgid ""
+"\n"
+"Call frame search table section [%2zu] '.eh_frame_hdr':\n"
+msgstr ""
+"\n"
+"Розділ таблиці пошуку вікон виклику [%2zu] '.eh_frame_hdr':\n"
+
+#: src/readelf.c:7996
+#, c-format
+msgid ""
+"\n"
+"Exception handling table section [%2zu] '.gcc_except_table':\n"
+msgstr ""
+"\n"
+"Розділ таблиці обробки виключень [%2zu] '.gcc_except_table':\n"
+
+#: src/readelf.c:8019
+#, c-format
+msgid " LPStart encoding:    %#x "
+msgstr " Кодування LPStart:   %#x "
+
+#: src/readelf.c:8031
+#, c-format
+msgid " TType encoding:      %#x "
+msgstr " Кодування TType:     %#x "
+
+#: src/readelf.c:8046
+#, c-format
+msgid " Call site encoding:  %#x "
+msgstr " Кодування місця виклику:%#x "
+
+#: src/readelf.c:8059
+msgid ""
+"\n"
+" Call site table:"
+msgstr ""
+"\n"
+" Таблиця місця виклику:"
+
+#: src/readelf.c:8073
+#, c-format
+msgid ""
+" [%4u] Call site start:   %#<PRIx64>\n"
+"        Call site length:  %<PRIu64>\n"
+"        Landing pad:       %#<PRIx64>\n"
+"        Action:            %u\n"
+msgstr ""
+" [%4u] Поч. місця виклику:   %#<PRIx64>\n"
+"        Довж. місця виклику:  %<PRIu64>\n"
+"        Місце застосування:   %#<PRIx64>\n"
+"        Дія:                  %u\n"
+
+#: src/readelf.c:8146
+#, c-format
+msgid "invalid TType encoding"
+msgstr "некоректне кодування TType"
+
+#: src/readelf.c:8172
+#, c-format
+msgid ""
+"\n"
+"GDB section [%2zu] '%s' at offset %#<PRIx64> contains %<PRId64> bytes :\n"
+msgstr ""
+"\n"
+"Розділ GDB [%2zu] «%s» за зміщенням %#<PRIx64> містить %<PRId64> байтів:\n"
+
+#: src/readelf.c:8201
+#, c-format
+msgid " Version:         %<PRId32>\n"
+msgstr " Версія:          %<PRId32>\n"
+
+#: src/readelf.c:8219
+#, c-format
+msgid " CU offset:       %#<PRIx32>\n"
+msgstr " зміщення CU:     %#<PRIx32>\n"
+
+#: src/readelf.c:8226
+#, c-format
+msgid " TU offset:       %#<PRIx32>\n"
+msgstr " зміщення TU:      %#<PRIx32>\n"
+
+#: src/readelf.c:8233
+#, c-format
+msgid " address offset:  %#<PRIx32>\n"
+msgstr " зміщення адреси: %#<PRIx32>\n"
+
+#: src/readelf.c:8240
+#, c-format
+msgid " symbol offset:   %#<PRIx32>\n"
+msgstr " зміщення символу: %#<PRIx32>\n"
+
+#: src/readelf.c:8247
+#, c-format
+msgid " constant offset: %#<PRIx32>\n"
+msgstr " стале зміщення:  %#<PRIx32>\n"
+
+#: src/readelf.c:8261
+#, c-format
+msgid ""
+"\n"
+" CU list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+" Список CU зі зміщенням %#<PRIx32> містить %zu записів:\n"
+
+#: src/readelf.c:8286
+#, c-format
+msgid ""
+"\n"
+" TU list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+" Список TU зі зміщенням %#<PRIx32> містить %zu записів:\n"
+
+#: src/readelf.c:8315
+#, c-format
+msgid ""
+"\n"
+" Address list at offset %#<PRIx32> contains %zu entries:\n"
+msgstr ""
+"\n"
+" Список адрес зі зміщенням %#<PRIx32> містить %zu записів:\n"
+
+#: src/readelf.c:8348
+#, c-format
+msgid ""
+"\n"
+" Symbol table at offset %#<PRIx32> contains %zu slots:\n"
+msgstr ""
+"\n"
+" Таблиця символів за зміщенням %#<PRIx32> містить %zu позицій:\n"
+
+#: src/readelf.c:8435
+#, c-format
+msgid "cannot get debug context descriptor: %s"
+msgstr "не вдалося отримати дескриптор контексту зневаджування: %s"
+
+#: src/readelf.c:8591 src/readelf.c:9213 src/readelf.c:9324 src/readelf.c:9382
+#, c-format
+msgid "cannot convert core note data: %s"
+msgstr "не вдалося перетворити дані запису ядра: %s"
+
+#: src/readelf.c:8954
+#, c-format
+msgid ""
+"\n"
+"%*s... <repeats %u more times> ..."
+msgstr ""
+"\n"
+"%*s... <повторюється %u разів> ..."
+
+#: src/readelf.c:9461
+msgid "  Owner          Data size  Type\n"
+msgstr "  Власник        Розм. даних Тип\n"
+
+#: src/readelf.c:9479
+#, c-format
+msgid "  %-13.*s  %9<PRId32>  %s\n"
+msgstr "  %-13.*s  %9<PRId32>  %s\n"
+
+#: src/readelf.c:9529
+#, c-format
+msgid "cannot get content of note section: %s"
+msgstr "не вдалося отримати вміст розділу записів: %s"
+
+#: src/readelf.c:9556
+#, c-format
+msgid ""
+"\n"
+"Note section [%2zu] '%s' of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Розділ записів (note) [%2zu] «%s» з %<PRIu64> байтів за зміщенням "
+"%#0<PRIx64>:\n"
+
+#: src/readelf.c:9579
+#, c-format
+msgid ""
+"\n"
+"Note segment of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Сегмент записів з %<PRIu64> байтів за зміщенням %#0<PRIx64>:\n"
+
+#: src/readelf.c:9625
+#, c-format
+msgid ""
+"\n"
+"Section [%zu] '%s' has no data to dump.\n"
+msgstr ""
+"\n"
+"У розділі [%zu] «%s» не міститься даних для створення дампу.\n"
+
+#: src/readelf.c:9652 src/readelf.c:9703
+#, c-format
+msgid "cannot get data for section [%zu] '%s': %s"
+msgstr "не вдалося отримати дані для розділу [%zu] «%s»: %s"
+
+#: src/readelf.c:9657
+#, c-format
+msgid ""
+"\n"
+"Hex dump of section [%zu] '%s', %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Шіст. дамп розділу [%zu] «%s», %<PRIu64> байтів за зміщенням %#0<PRIx64>:\n"
+
+#: src/readelf.c:9662
+#, fuzzy, c-format
+msgid ""
+"\n"
+"Hex dump of section [%zu] '%s', %<PRIu64> bytes (%zd uncompressed) at offset "
+"%#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Шіст. дамп розділу [%zu] «%s», %<PRIu64> байтів за зміщенням %#0<PRIx64>:\n"
+
+#: src/readelf.c:9676
+#, c-format
+msgid ""
+"\n"
+"Section [%zu] '%s' has no strings to dump.\n"
+msgstr ""
+"\n"
+"У розділі [%zu] «%s» не міститься рядків для створення дампу.\n"
+
+#: src/readelf.c:9708
+#, c-format
+msgid ""
+"\n"
+"String section [%zu] '%s' contains %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Розділ рядків [%zu] «%s» містить %<PRIu64> байтів за зміщенням %#0<PRIx64>:\n"
+
+#: src/readelf.c:9713
+#, fuzzy, c-format
+msgid ""
+"\n"
+"String section [%zu] '%s' contains %<PRIu64> bytes (%zd uncompressed) at "
+"offset %#0<PRIx64>:\n"
+msgstr ""
+"\n"
+"Розділ рядків [%zu] «%s» містить %<PRIu64> байтів за зміщенням %#0<PRIx64>:\n"
+
+#: src/readelf.c:9762
+#, c-format
+msgid ""
+"\n"
+"section [%lu] does not exist"
+msgstr ""
+"\n"
+"розділу [%lu] не існує"
+
+#: src/readelf.c:9791
+#, c-format
+msgid ""
+"\n"
+"section '%s' does not exist"
+msgstr ""
+"\n"
+"розділу «%s» не існує"
+
+#: src/readelf.c:9848
+#, c-format
+msgid "cannot get symbol index of archive '%s': %s"
+msgstr "не вдалося отримати покажчик символів архіву «%s»: %s"
+
+#: src/readelf.c:9851
+#, c-format
+msgid ""
+"\n"
+"Archive '%s' has no symbol index\n"
+msgstr ""
+"\n"
+"У архіві «%s» немає покажчика символів\n"
+
+#: src/readelf.c:9855
+#, c-format
+msgid ""
+"\n"
+"Index of archive '%s' has %zu entries:\n"
+msgstr ""
+"\n"
+"Покажчик архіву «%s» містить %zu записів:\n"
+
+#: src/readelf.c:9873
+#, c-format
+msgid "cannot extract member at offset %zu in '%s': %s"
+msgstr "не вдалося видобути елемент за зміщенням %zu у «%s»: %s"
+
+#: src/readelf.c:9878
+#, c-format
+msgid "Archive member '%s' contains:\n"
+msgstr "Елемент архіву «%s» містить:\n"
+
+#: src/size.c:57
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd' or `sysv'.  The default "
+"is `bsd'"
+msgstr ""
+"Використовувати формат виводу ФОРМАТ. ФОРМАТом може бути «bsd» або «sysv». "
+"Типовим є значення «bsd»"
+
+#: src/size.c:59
+msgid "Same as `--format=sysv'"
+msgstr "Те саме, що і «--format=sysv»"
+
+#: src/size.c:60
+msgid "Same as `--format=bsd'"
+msgstr "Те саме, що і «--format=bsd»"
+
+#: src/size.c:63
+msgid "Same as `--radix=10'"
+msgstr "Те саме, що і «--radix=10»"
+
+#: src/size.c:64
+msgid "Same as `--radix=8'"
+msgstr "Те саме, що і «--radix=8»"
+
+#: src/size.c:65
+msgid "Same as `--radix=16'"
+msgstr "Те саме, що і «--radix=16»"
+
+#: src/size.c:67
+msgid "Similar to `--format=sysv' output but in one line"
+msgstr "Вивід даних у форматі, подібному до «--format=sysv», але у один рядок"
+
+#: src/size.c:71
+msgid "Print size and permission flags for loadable segments"
+msgstr ""
+"Вивести розмір і прапорці прав доступу для придатних до завантаження "
+"сегментів"
+
+#: src/size.c:72
+msgid "Display the total sizes (bsd only)"
+msgstr "Показувати загальні розміри (лише bsd)"
+
+#. Short description of program.
+#: src/size.c:77
+msgid "List section sizes of FILEs (a.out by default)."
+msgstr "Показати розміри розділів ФАЙЛів (типово a.out)."
+
+#: src/size.c:241
+#, c-format
+msgid "Invalid format: %s"
+msgstr "Некоректний формат: %s"
+
+#: src/size.c:252
+#, c-format
+msgid "Invalid radix: %s"
+msgstr "Некоректна основа числення: %s"
+
+#: src/size.c:311
+#, c-format
+msgid "%s: file format not recognized"
+msgstr "%s: не вдалося розпізнати формат файла"
+
+#: src/size.c:417 src/size.c:550
+#, c-format
+msgid " (ex %s)"
+msgstr " (прикл. %s)"
+
+#: src/size.c:575
+msgid "(TOTALS)\n"
+msgstr "(ЗАГАЛОМ)\n"
+
+#: src/stack.c:483
+#, c-format
+msgid "-p PID should be a positive process id."
+msgstr "PID у -p PID має бути додатним значенням ідентифікатора процесу."
+
+#: src/stack.c:489
+#, c-format
+msgid "Cannot open core file '%s'"
+msgstr "Не вдалося відкрити файл дампу ядра «%s»"
+
+#: src/stack.c:549
+#, c-format
+msgid "-n MAXFRAMES should be 0 or higher."
+msgstr "MAXFRAMES у -n має бути значенням рівним 0 або більшим."
+
+#: src/stack.c:561
+#, c-format
+msgid "-e EXEC needs a core given by --core."
+msgstr "Для -e EXEC слід вказати ядро за допомогою --core."
+
+#: src/stack.c:565
+#, c-format
+msgid "-1 needs a thread id given by -p."
+msgstr "-1 слід передати ідентифікатор потоку виконання, заданого -p."
+
+#: src/stack.c:569
+#, c-format
+msgid "One of -p PID or --core COREFILE should be given."
+msgstr "Слід вказати -p PID або --core COREFILE."
+
+#: src/stack.c:641
+msgid "Show stack of process PID"
+msgstr "Вивести стек PID процесу"
+
+#: src/stack.c:643
+msgid "Show stack found in COREFILE"
+msgstr "Вивести стек, знайдений у COREFILE"
+
+#: src/stack.c:644
+msgid "(optional) EXECUTABLE that produced COREFILE"
+msgstr "(необов’язковий) EXECUTABLE, яким створено COREFILE"
+
+#: src/stack.c:648
+msgid "Output selection options:"
+msgstr "Параметри вибору виведених даних:"
+
+#: src/stack.c:650
+msgid "Additionally show frame activation"
+msgstr "Додатково вивести активацію вікна"
+
+#: src/stack.c:652
+msgid "Additionally try to lookup DWARF debuginfo name for frame address"
+msgstr ""
+"Додатково спробувати визначити назву файла даних діагностики DWARF для "
+"адреси вікна"
+
+#: src/stack.c:655
+msgid ""
+"Additionally show inlined function frames using DWARF debuginfo if available "
+"(implies -d)"
+msgstr ""
+"Додатково вивести вікна вбудованих функцій за допомогою даних діагностики "
+"DWARF, якщо такі є (використовується і -d)"
+
+#: src/stack.c:657
+msgid "Additionally show module file information"
+msgstr "Додатково вивести дані щодо файла модуля"
+
+#: src/stack.c:659
+msgid "Additionally show source file information"
+msgstr "Додатково вивести дані щодо файла початкового коду"
+
+#: src/stack.c:661
+msgid ""
+"Show all additional information (activation, debugname, inlines, module and "
+"source)"
+msgstr ""
+"Вивести усі додаткові дані (активацію, назву у системі діагностики, "
+"вбудовані функції, модуль і початковий файл)"
+
+#: src/stack.c:663
+msgid "Do not resolve address to function symbol name"
+msgstr "Не розгортати адресу до назви символу функції"
+
+#: src/stack.c:665
+msgid "Show raw function symbol names, do not try to demangle names"
+msgstr ""
+"Вивести назви символів функцій без обробки, не намагатися розшифрувати назви"
+
+#: src/stack.c:667
+msgid "Show module build-id, load address and pc offset"
+msgstr "Виводити ідентифікатор збирання, адресу завантаження та зсув модуля"
+
+#: src/stack.c:669
+msgid "Show the backtrace of only one thread"
+msgstr "Виводити зворотне трасування лише одного потоку"
+
+#: src/stack.c:671
+msgid "Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)"
+msgstr ""
+"Виводити не більше MAXFRAMES на потік виконання (типове значення 256, 0 — не "
+"обмежувати)"
+
+#: src/stack.c:673
+msgid "Show module memory map with build-id, elf and debug files detected"
+msgstr ""
+"Вивести карту пам’яті модуля із виявленими ідентифікатором збирання, elf та "
+"файлами діагностичних даних"
+
+#: src/stack.c:681
+#, fuzzy
+msgid ""
+"Print a stack for each thread in a process or core file.\n"
+"\n"
+"Program exits with return code 0 if all frames were shown without any "
+"errors.  If some frames were shown, but there were some non-fatal errors, "
+"possibly causing an incomplete backtrace, the program exits with return code "
+"1.  If no frames could be shown, or a fatal error occured the program exits "
+"with return code 2.  If the program was invoked with bad or missing "
+"arguments it will exit with return code 64."
+msgstr ""
+"Вивести стек для кожного потоку у процесі або файлі дампу ядра.\n"
+"\n"
+"Програма завершує роботу з кодом виходу 0, якщо усі вікна було виведено без "
+"помилок. Якщо деякі вікна було показано, але сталися некритичні помилки, "
+"ймовірно спричинені неповними даними зворотного трасування, програма "
+"завершує роботу з кодом повернення 1. Якщо не вдалося вивести жодного вікна "
+"або сталася критична помилка, програма виходить з кодом повернення 2. Якщо "
+"програму було викликано з помилковими або пропущеними аргументами, програма "
+"завершить роботу з кодом виходу 64."
+
+#: src/stack.c:756
+#, c-format
+msgid "Couldn't show any frames."
+msgstr "Не вдалося вивести жодного вікна."
+
+#: src/strings.c:66
+msgid "Output Selection:"
+msgstr "Вибір виводу:"
+
+#: src/strings.c:67
+msgid "Scan entire file, not only loaded sections"
+msgstr "Шукати у всьому файлі, а не лише у завантажених розділах"
+
+#: src/strings.c:69
+msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed"
+msgstr ""
+"Буде виведено лише послідовності з не менше, ніж MIN-LEN символів, що "
+"завершуються на NUL"
+
+#: src/strings.c:70
+msgid ""
+"Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, "
+"{B,L} = 32-bit"
+msgstr ""
+"Визначення розмірності та порядку бітів символів: s = 7-бітові, S = 8-"
+"бітові, {b,l} = 16-бітові, {B,L} = 32-бітові"
+
+#: src/strings.c:74
+msgid "Print name of the file before each string."
+msgstr "Виводити назву файла перед кожним рядком."
+
+#: src/strings.c:76
+msgid "Print location of the string in base 8, 10, or 16 respectively."
+msgstr "Виводити адресу рядка за основами 8, 10 та 16, відповідно."
+
+#: src/strings.c:77
+msgid "Alias for --radix=o"
+msgstr "Замінник --radix=o"
+
+#. Short description of program.
+#: src/strings.c:84
+msgid "Print the strings of printable characters in files."
+msgstr "Вивести рядки файлів з символів, придатних для друку."
+
+#: src/strings.c:257 src/strings.c:292
+#, c-format
+msgid "invalid value '%s' for %s parameter"
+msgstr "некоректне значення «%s» параметра %s"
+
+#: src/strings.c:303
+#, c-format
+msgid "invalid minimum length of matched string size"
+msgstr "некоректна мінімальна довжина розмірності рядка для порівняння"
+
+#: src/strings.c:586
+#, fuzzy, c-format
+msgid "lseek failed"
+msgstr "помилка lseek64"
+
+#: src/strings.c:603 src/strings.c:667
+#, c-format
+msgid "re-mmap failed"
+msgstr "помилка повторного використання mmap"
+
+#: src/strings.c:640
+#, c-format
+msgid "mprotect failed"
+msgstr "помилка mprotect"
+
+#: src/strings.c:729
+#, c-format
+msgid "Skipping section %zd '%s' data outside file"
+msgstr "Пропускаємо дані %zd «%s» поза файлом"
+
+#: src/strip.c:71
+msgid "Place stripped output into FILE"
+msgstr "Вивести дані після вилучення до ФАЙЛа"
+
+#: src/strip.c:72
+msgid "Extract the removed sections into FILE"
+msgstr "Видобути вилучені розділи до ФАЙЛа"
+
+#: src/strip.c:73
+msgid "Embed name FILE instead of -f argument"
+msgstr "Вбудувати назву ФАЙЛа замість аргументу -f"
+
+#: src/strip.c:77
+msgid "Remove all debugging symbols"
+msgstr "Вилучити всі символи зневаджування"
+
+#: src/strip.c:81
+msgid "Remove section headers (not recommended)"
+msgstr "Вилучити заголовки розділів (не рекомендовано)"
+
+#: src/strip.c:83
+msgid "Copy modified/access timestamps to the output"
+msgstr "Скопіювати часові позначки зміни/доступу до виведених даних"
+
+#: src/strip.c:85
+msgid ""
+"Resolve all trivial relocations between debug sections if the removed "
+"sections are placed in a debug file (only relevant for ET_REL files, "
+"operation is not reversable, needs -f)"
+msgstr ""
+"Розв’язати всі очевидні пересування між діагностичними розділами, якщо "
+"вилучені розділи було розташовано у діагностичному файлі (стосується лише "
+"файлів ET_REL, скасувати дію неможливо, потребує параметра -f)"
+
+#: src/strip.c:87
+msgid "Remove .comment section"
+msgstr "Вилучити розділ .comment"
+
+#: src/strip.c:88
+msgid ""
+"Remove the named section.  SECTION is an extended wildcard pattern.  May be "
+"given more than once.  Only non-allocated sections can be removed."
+msgstr ""
+
+#: src/strip.c:89
+msgid ""
+"Keep the named section.  SECTION is an extended wildcard pattern.  May be "
+"given more than once."
+msgstr ""
+
+#. Short description of program.
+#: src/strip.c:96
+msgid "Discard symbols from object files."
+msgstr "Відкинути символи з об’єктних файлів"
+
+#: src/strip.c:242
+#, c-format
+msgid "--reloc-debug-sections used without -f"
+msgstr "--reloc-debug-sections використано без -f"
+
+#: src/strip.c:256
+#, c-format
+msgid "Only one input file allowed together with '-o' and '-f'"
+msgstr ""
+"Разом з «-o» або «-f» можна використовувати лише один файл вхідних даних"
+
+#: src/strip.c:279
+#, c-format
+msgid "-f option specified twice"
+msgstr "параметр -f вказано двічі"
+
+#: src/strip.c:288
+#, c-format
+msgid "-F option specified twice"
+msgstr "параметр -F вказано двічі"
+
+#: src/strip.c:347
+#, fuzzy, c-format
+msgid "cannot both keep and remove .comment section"
+msgstr "Вилучити розділ .comment"
+
+#: src/strip.c:372 src/strip.c:396
+#, c-format
+msgid "cannot stat input file '%s'"
+msgstr "не вдалося отримати дані з вхідного файла «%s» за допомогою stat"
+
+#: src/strip.c:386
+#, c-format
+msgid "while opening '%s'"
+msgstr "під час спроби відкриття «%s»"
+
+#: src/strip.c:424
+#, c-format
+msgid "%s: cannot use -o or -f when stripping archive"
+msgstr ""
+"%s: не можна використовувати -o або -f під час вилучення додаткового вмісту "
+"архіву"
+
+#. We would like to support ar archives, but currently it just
+#. doesn't work at all since we call elf_clone on the members
+#. which doesn't really support ar members.
+#. result = handle_ar (fd, elf, NULL, fname,
+#. preserve_dates ? tv : NULL);
+#.
+#: src/strip.c:436
+#, c-format
+msgid "%s: no support for stripping archive"
+msgstr "%s: підтримки вилучення додаткового вмісту з архіву не передбачено"
+
+#: src/strip.c:535
+#, c-format
+msgid "cannot open EBL backend"
+msgstr "не вдалося відкрити канал сервера EBL"
+
+#: src/strip.c:580
+#, c-format
+msgid "cannot get number of phdrs"
+msgstr "не вдалося отримати кількість phdr"
+
+#: src/strip.c:596 src/strip.c:620
+#, c-format
+msgid "cannot create new file '%s': %s"
+msgstr "не вдалося створити файл «%s»: %s"
+
+#: src/strip.c:686
+#, c-format
+msgid "illformed file '%s'"
+msgstr "помилкове форматування файла «%s»"
+
+#: src/strip.c:696
+#, fuzzy, c-format
+msgid "Cannot remove allocated section '%s'"
+msgstr "не вдалося розмістити PLT-розділ: %s"
+
+#: src/strip.c:705
+#, fuzzy, c-format
+msgid "Cannot both keep and remove section '%s'"
+msgstr "не вдалося додати новий розділ: %s"
+
+#: src/strip.c:1061 src/strip.c:1160
+#, c-format
+msgid "while generating output file: %s"
+msgstr "під час спроби створення файла з виведеними даними: %s"
+
+#: src/strip.c:1126 src/strip.c:2208
+#, c-format
+msgid "%s: error while creating ELF header: %s"
+msgstr "%s: помилка під час створення заголовка ELF: %s"
+
+#: src/strip.c:1143
+#, c-format
+msgid "while preparing output for '%s'"
+msgstr "під час приготування виведених даних для «%s»"
+
+#: src/strip.c:1205 src/strip.c:1268
+#, c-format
+msgid "while create section header section: %s"
+msgstr "під час створення розділу заголовка розділу: %s"
+
+#: src/strip.c:1214
+#, c-format
+msgid "cannot allocate section data: %s"
+msgstr "не вдалося розмістити дані розділу: %s"
+
+#: src/strip.c:1280
+#, c-format
+msgid "while create section header string table: %s"
+msgstr "під час створення таблиці рядків заголовка розділу: %s"
+
+#: src/strip.c:1287
+#, fuzzy, c-format
+msgid "no memory to create section header string table"
+msgstr "під час створення таблиці рядків заголовка розділу: %s"
+
+#: src/strip.c:1497
+#, c-format
+msgid "Cannot remove symbol [%zd] from allocated symbol table [%zd]"
+msgstr ""
+
+#: src/strip.c:1994
+#, c-format
+msgid "bad relocation"
+msgstr "помилкове пересування"
+
+#: src/strip.c:2119 src/strip.c:2232
+#, c-format
+msgid "while writing '%s': %s"
+msgstr "під час запису «%s»: %s"
+
+#: src/strip.c:2130
+#, c-format
+msgid "while creating '%s'"
+msgstr "під час спроби створення «%s»"
+
+#: src/strip.c:2153
+#, c-format
+msgid "while computing checksum for debug information"
+msgstr "під час обчислення контрольної суми для діагностичних даних"
+
+#: src/strip.c:2217
+#, c-format
+msgid "%s: error while reading the file: %s"
+msgstr "%s: помилка під час читання файла: %s"
+
+#: src/strip.c:2257 src/strip.c:2277
+#, c-format
+msgid "while writing '%s'"
+msgstr "під час спроби запису «%s»"
+
+#: src/strip.c:2314 src/strip.c:2321
+#, c-format
+msgid "error while finishing '%s': %s"
+msgstr "помилка під час завершення «%s»: %s"
+
+#: src/strip.c:2338 src/strip.c:2414
+#, c-format
+msgid "cannot set access and modification date of '%s'"
+msgstr "не вдалося встановити права доступу та дату зміни «%s»"
+
+#: src/unstrip.c:70
+msgid "Match MODULE against file names, not module names"
+msgstr ""
+"Встановити відповідність МОДУЛЯ назвам файлів, а не назвам модулів names"
+
+#: src/unstrip.c:71
+msgid "Silently skip unfindable files"
+msgstr "Пропустити незнайдені файли без додаткових повідомлень"
+
+#: src/unstrip.c:74
+msgid "Place output into FILE"
+msgstr "Вивести дані у ФАЙЛ"
+
+#: src/unstrip.c:76
+msgid "Create multiple output files under DIRECTORY"
+msgstr "Створити декілька файлів виведених даних у КАТАЛОЗІ"
+
+#: src/unstrip.c:77
+msgid "Use module rather than file names"
+msgstr "Використовувати назви модулів, а не файлів"
+
+#: src/unstrip.c:79
+msgid "Create output for modules that have no separate debug information"
+msgstr ""
+"Вивести дані для модулів, які не містять окремих діагностичних відомостей"
+
+#: src/unstrip.c:82
+msgid "Apply relocations to section contents in ET_REL files"
+msgstr "Застосувати пересування до вмісту розділів у файлах ET_REL"
+
+#: src/unstrip.c:84
+msgid "Only list module and file names, build IDs"
+msgstr "Вивести лише список назв модулів, файлів, побудувати ідентифікатори"
+
+#: src/unstrip.c:86
+msgid "Force combining files even if some ELF headers don't seem to match"
+msgstr ""
+"Примусово поєднати файли, навіть якщо буде встановлено невідповідність "
+"якихось із заголовків ELF"
+
+#: src/unstrip.c:130
+#, c-format
+msgid "-d option specified twice"
+msgstr "параметр -d вказано двічі"
+
+#: src/unstrip.c:165
+#, c-format
+msgid "only one of -o or -d allowed"
+msgstr "можна використовувати лише один з параметрів: -o або -d"
+
+#: src/unstrip.c:174
+#, c-format
+msgid "-n cannot be used with explicit files or -o or -d"
+msgstr ""
+"-n не можна використовувати з файлами, заданими явно, або параметрами -o і -d"
+
+#: src/unstrip.c:189
+#, c-format
+msgid "output directory '%s'"
+msgstr "каталог виведення даних «%s»"
+
+#: src/unstrip.c:198
+#, c-format
+msgid "exactly two file arguments are required"
+msgstr "як аргументи має бути вказано точно два файла"
+
+#: src/unstrip.c:204
+#, c-format
+msgid "-m, -a, -R, and -i options not allowed with explicit files"
+msgstr ""
+"для файлів, заданих явно, не можна використовувати параметри -m, -a, -R і -i"
+
+#: src/unstrip.c:217
+#, c-format
+msgid "-o or -d is required when using implicit files"
+msgstr ""
+"якщо використовуються файли, задані неявно, слід додавати параметр -o або -d"
+
+#: src/unstrip.c:240
+#, c-format
+msgid "cannot create ELF header: %s"
+msgstr "не вдалося створити заголовок ELF: %s"
+
+#: src/unstrip.c:245
+#, c-format
+msgid "cannot copy ELF header: %s"
+msgstr "не вдалося скопіювати заголовок ELF: %s"
+
+#: src/unstrip.c:249 src/unstrip.c:1933 src/unstrip.c:1976
+#, c-format
+msgid "cannot get number of program headers: %s"
+msgstr "не вдалося отримати кількість заголовків програми: %s"
+
+#: src/unstrip.c:254 src/unstrip.c:1937
+#, c-format
+msgid "cannot create program headers: %s"
+msgstr "не вдалося створити заголовки програми: %s"
+
+#: src/unstrip.c:260
+#, c-format
+msgid "cannot copy program header: %s"
+msgstr "не вдалося скопіювати заголовок програми: %s"
+
+#: src/unstrip.c:270
+#, c-format
+msgid "cannot copy section header: %s"
+msgstr "не вдалося скопіювати заголовок розділу: %s"
+
+#: src/unstrip.c:273 src/unstrip.c:1568
+#, c-format
+msgid "cannot get section data: %s"
+msgstr "не вдалося отримати дані розділу: %s"
+
+#: src/unstrip.c:275 src/unstrip.c:1570
+#, c-format
+msgid "cannot copy section data: %s"
+msgstr "не вдалося скопіювати дані розділу: %s"
+
+#: src/unstrip.c:299
+#, c-format
+msgid "cannot create directory '%s'"
+msgstr "не вдалося створити каталог «%s»"
+
+#: src/unstrip.c:371 src/unstrip.c:791 src/unstrip.c:1602
+#, c-format
+msgid "cannot get symbol table entry: %s"
+msgstr "не вдалося отримати запис таблиці символів: %s"
+
+#: src/unstrip.c:387 src/unstrip.c:608 src/unstrip.c:629 src/unstrip.c:641
+#: src/unstrip.c:1623 src/unstrip.c:1799 src/unstrip.c:1823
+#, c-format
+msgid "cannot update symbol table: %s"
+msgstr "не вдалося оновити таблицю символів: %s"
+
+#: src/unstrip.c:397
+#, c-format
+msgid "cannot update section header: %s"
+msgstr "не вдалося оновити заголовок розділу: %s"
+
+#: src/unstrip.c:436 src/unstrip.c:447
+#, c-format
+msgid "cannot update relocation: %s"
+msgstr "не вдалося оновити пересування: %s"
+
+#: src/unstrip.c:535
+#, c-format
+msgid "cannot get symbol version: %s"
+msgstr "не вдалося отримати версію символу: %s"
+
+#: src/unstrip.c:548
+#, c-format
+msgid "unexpected section type in [%zu] with sh_link to symtab"
+msgstr "неочікуваний тип розділу у [%zu] з посиланням sh_link на symtab"
+
+#: src/unstrip.c:797
+#, c-format
+msgid "invalid string offset in symbol [%zu]"
+msgstr "некоректне зміщення рядка у символі [%zu]"
+
+#: src/unstrip.c:955 src/unstrip.c:1305
+#, c-format
+msgid "cannot read section [%zu] name: %s"
+msgstr "не вдалося прочитати назву розділу [%zu]: %s"
+
+#: src/unstrip.c:996 src/unstrip.c:1015 src/unstrip.c:1053
+#, c-format
+msgid "cannot read '.gnu.prelink_undo' section: %s"
+msgstr "не вдалося прочитати розділ «.gnu.prelink_undo»: %s"
+
+#: src/unstrip.c:1033
+#, c-format
+msgid "overflow with shnum = %zu in '%s' section"
+msgstr ""
+
+#: src/unstrip.c:1044
+#, c-format
+msgid "invalid contents in '%s' section"
+msgstr "некоректний вміст розділу «%s»"
+
+#: src/unstrip.c:1099 src/unstrip.c:1427
+#, c-format
+msgid "cannot find matching section for [%zu] '%s'"
+msgstr "не вдалося знайти відповідний розділ для [%zu] «%s»"
+
+#: src/unstrip.c:1224 src/unstrip.c:1239 src/unstrip.c:1506 src/unstrip.c:1758
+#, c-format
+msgid "cannot add section name to string table: %s"
+msgstr "не вдалося додати назву розділу до таблиці рядків: %s"
+
+#: src/unstrip.c:1248
+#, c-format
+msgid "cannot update section header string table data: %s"
+msgstr "не вдалося оновити дані заголовка розділу у таблиці рядків: %s"
+
+#: src/unstrip.c:1276 src/unstrip.c:1280
+#, c-format
+msgid "cannot get section header string table section index: %s"
+msgstr ""
+"не вдалося визначити індекс розділу заголовка розділу у таблиці рядків: %s"
+
+#: src/unstrip.c:1284 src/unstrip.c:1288 src/unstrip.c:1521
+#, c-format
+msgid "cannot get section count: %s"
+msgstr "не вдалося отримати кількість розділів: %s"
+
+#: src/unstrip.c:1291
+#, c-format
+msgid "more sections in stripped file than debug file -- arguments reversed?"
+msgstr ""
+"у очищеному файлі більше розділів ніж у файлі з даними для зневаджування — "
+"помилковий порядок параметрів?"
+
+#: src/unstrip.c:1350 src/unstrip.c:1442
+#, c-format
+msgid "cannot read section header string table: %s"
+msgstr "не вдалося прочитати таблицю рядків заголовка розділу: %s"
+
+#: src/unstrip.c:1500
+#, c-format
+msgid "cannot add new section: %s"
+msgstr "не вдалося додати новий розділ: %s"
+
+#: src/unstrip.c:1610
+#, c-format
+msgid "symbol [%zu] has invalid section index"
+msgstr "символ [%zu] має некоректний індекс розділу"
+
+#: src/unstrip.c:1894
+#, c-format
+msgid "cannot read section data: %s"
+msgstr "не вдалося прочитати дані розділу: %s"
+
+#: src/unstrip.c:1915
+#, c-format
+msgid "cannot get ELF header: %s"
+msgstr "не вдалося отримати заголовок ELF: %s"
+
+#: src/unstrip.c:1923
+#, c-format
+msgid "cannot update ELF header: %s"
+msgstr "не вдалося оновити заголовок ELF: %s"
+
+#: src/unstrip.c:1947
+#, c-format
+msgid "cannot update program header: %s"
+msgstr "не вдалося оновити заголовок програми: %s"
+
+#: src/unstrip.c:1952 src/unstrip.c:2034
+#, c-format
+msgid "cannot write output file: %s"
+msgstr "не вдалося записати файл виведених даних: %s"
+
+#: src/unstrip.c:2003
+#, c-format
+msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+"Дані DWARF не скориговано відповідно до відхилення перед компонуванням; "
+"спробуйте виправити це командою prelink -u"
+
+#: src/unstrip.c:2006
+#, c-format
+msgid ""
+"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+"Дані DWARF у «%s» не скориговано відповідно до відхилення перед "
+"компонуванням; спробуйте виправити це командою prelink -u"
+
+#: src/unstrip.c:2025 src/unstrip.c:2076 src/unstrip.c:2088 src/unstrip.c:2174
+#, c-format
+msgid "cannot create ELF descriptor: %s"
+msgstr "не вдалося створити дескриптор ELF: %s"
+
+#: src/unstrip.c:2067
+msgid "WARNING: "
+msgstr "УВАГА: "
+
+#: src/unstrip.c:2069
+msgid ", use --force"
+msgstr ", скористайтеся --force"
+
+#: src/unstrip.c:2092
+msgid "ELF header identification (e_ident) different"
+msgstr "Різні ідентифікатори заголовків ELF (e_ident)"
+
+#: src/unstrip.c:2095
+msgid "ELF header type (e_type) different"
+msgstr "Різні типи заголовків ELF (e_type)"
+
+#: src/unstrip.c:2098
+msgid "ELF header machine type (e_machine) different"
+msgstr "Різні типи архітектур заголовків ELF (e_machine)"
+
+#: src/unstrip.c:2101
+msgid "stripped program header (e_phnum) smaller than unstripped"
+msgstr "очищений заголовок програми (e_phnum) є меншим за неочищений"
+
+#: src/unstrip.c:2131
+#, c-format
+msgid "cannot find stripped file for module '%s': %s"
+msgstr "не вдалося знайти очищений файл для модуля «%s»: %s"
+
+#: src/unstrip.c:2135
+#, c-format
+msgid "cannot open stripped file '%s' for module '%s': %s"
+msgstr "не вдалося відкрити очищений файл «%s» для модуля «%s»: %s"
+
+#: src/unstrip.c:2150
+#, c-format
+msgid "cannot find debug file for module '%s': %s"
+msgstr "не вдалося знайти файл діагностичних даних для модуля «%s»: %s"
+
+#: src/unstrip.c:2154
+#, c-format
+msgid "cannot open debug file '%s' for module '%s': %s"
+msgstr "не вдалося відкрити файл діагностичних даних «%s» для модуля «%s»: %s"
+
+#: src/unstrip.c:2167
+#, c-format
+msgid "module '%s' file '%s' is not stripped"
+msgstr "у модулі «%s» файл «%s» не очищено strip"
+
+#: src/unstrip.c:2198
+#, c-format
+msgid "cannot cache section addresses for module '%s': %s"
+msgstr "не вдалося кешувати адреси розділів для модуля «%s»: %s"
+
+#: src/unstrip.c:2331
+#, c-format
+msgid "no matching modules found"
+msgstr "відповідних модулів не виявлено"
+
+#: src/unstrip.c:2340
+#, c-format
+msgid "matched more than one module"
+msgstr "встановлено відповідність декількох модулів"
+
+#: src/unstrip.c:2384
+msgid ""
+"STRIPPED-FILE DEBUG-FILE\n"
+"[MODULE...]"
+msgstr ""
+"ОЧИЩЕНИЙ-ФАЙЛ ФАЙЛ-DEBUG\n"
+"[МОДУЛЬ...]"
+
+#: src/unstrip.c:2385
+#, fuzzy
+msgid ""
+"Combine stripped files with separate symbols and debug information.\n"
+"\n"
+"The first form puts the result in DEBUG-FILE if -o was not given.\n"
+"\n"
+"MODULE arguments give file name patterns matching modules to process.\n"
+"With -f these match the file name of the main (stripped) file (slashes are "
+"never special), otherwise they match the simple module names.  With no "
+"arguments, process all modules found.\n"
+"\n"
+"Multiple modules are written to files under OUTPUT-DIRECTORY, creating "
+"subdirectories as needed.  With -m these files have simple module names, "
+"otherwise they have the name of the main file complete with directory "
+"underneath OUTPUT-DIRECTORY.\n"
+"\n"
+"With -n no files are written, but one line to standard output for each "
+"module:\n"
+"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n"
+"START and SIZE are hexadecimal giving the address bounds of the module.  "
+"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the "
+"hexadecimal may be followed by @0xADDR giving the address where the ID "
+"resides if that is known.  FILE is the file name found for the module, or - "
+"if none was found, or . if an ELF image is available but not from any named "
+"file.  DEBUGFILE is the separate debuginfo file name, or - if no debuginfo "
+"was found, or . if FILE contains the debug information."
+msgstr ""
+"Комбінувати очищені файли з окремими даними щодо символів та діагностичними "
+"даними.\n"
+"\n"
+"За використання першої форми команди, результати буде виведено до ФАЙЛА-"
+"DEBUG, якщо не файл виведених даних не вказано параметром -o.\n"
+"\n"
+"За допомогою аргументів МОДУЛЬ можна вказати шаблони назв файлів модулів, "
+"які слід обробити.\n"
+"З -f ці назви модулів відповідатимуть назві основного (очищеного strip) "
+"файла (похилі риски не є спеціальними символами), якщо ж -f не вказано, "
+"назви вважатимуться простими назвами модулів. Якщо аргументів не буде "
+"вказано, програма обробить всі знайдені модулі.\n"
+"\n"
+"Вказані модулі буде записано до файлів у КАТАЛОЗІ-ВИВОДУ, зі створенням, за "
+"потреби, підкаталогів. З параметром -m файли виведених даних "
+"створюватимуться за назвами модулів, якщо ж цього параметра вказано не буде, "
+"програма створюватиме файл з назвою основного файла у основному КАТАЛОЗІ-"
+"ВИВОДУ.\n"
+"\n"
+"Якщо буде вказано параметр -n, дані до файлів не виводитимуться, програма "
+"виведе для кожного модуля до стандартного виводу такі дані:\n"
+"\tПОЧАТОК+РОЗМІР ІДЕНТИФІКАТОР-ЗБИРАННЯ ФАЙЛ ФАЙЛ-DEBUG НАЗВА-МОДУЛЯ\n"
+"ПОЧАТОК і РОЗМІР буде виведено як шістнадцяткові числа у межах адресного "
+"простору модуля. ІДЕНТИФІКАТОР-ЗБИРАННЯ — це шістнадцяткове число, що "
+"відповідає бітам ідентифікатора збирання, або «-», якщо ідентифікатор "
+"невідомий; за шістнадцятковим числом може слідувати @0xАДРЕСА, яка вказує "
+"місце розташування ідентифікатора, якщо воно відоме. ФАЙЛ відповідає назві "
+"файла, знайденого для модуля, або «-», якщо файл не знайдено, і «.», якщо "
+"вдалося знайти образ ELF, але без жодного файла з назвою. ФАЙЛ-DEBUG — назва "
+"окремого файла діагностичних даних або «-», якщо файла діагностичних даних "
+"не вдалося знайти, і «.», якщо ФАЙЛ сам містить діагностичні дані."
+
+#: tests/backtrace.c:442
+msgid "Run executable"
+msgstr "Запустити виконуваний файл"
+
+#: tests/dwflmodtest.c:213
+msgid "Additionally show function names"
+msgstr "Додатково вивести назви функцій"
+
+#: tests/dwflmodtest.c:214
+msgid "Show instances of inlined functions"
+msgstr "Вивести екземпляри вбудованих функцій"
+
+#~ msgid "-R option supports only .comment section"
+#~ msgstr "Для параметра -R передбачено підтримку лише розділу .comment"
+
+#~ msgid "Written by %s.\n"
+#~ msgstr "Автор — %s.\n"
+
+#~ msgid "cannot allocate PLTREL section: %s"
+#~ msgstr "не вдалося розмістити розділ PLTREL: %s"
+
+#~ msgid "cannot allocate GOT section: %s"
+#~ msgstr "не вдалося розмістити розділ GOT: %s"
+
+#~ msgid "cannot allocate GOTPLT section: %s"
+#~ msgstr "не вдалося розмістити розділ GOTPLT: %s"
+
+#~ msgid "initial-executable TLS relocation cannot be used "
+#~ msgstr ""
+#~ "не можна використовувати пересування TLS у початковому виконуваному файлі"
+
+#~ msgid "Input File Control:"
+#~ msgstr "Керування файлом вхідних даних:"
+
+#~ msgid "Include whole archives in the output from now on."
+#~ msgstr "Відтепер включати цілі архіви до виведених даних."
+
+#~ msgid "Stop including the whole archives in the output."
+#~ msgstr "Припинити включення цілих архівів до вихідних даних."
+
+#~ msgid "FILE"
+#~ msgstr "ФАЙЛ"
+
+#~ msgid "Start a group."
+#~ msgstr "Почати групу."
+
+#~ msgid "End a group."
+#~ msgstr "Завершити групу."
+
+#~ msgid "PATH"
+#~ msgstr "ШЛЯХ"
+
+#~ msgid "Add PATH to list of directories files are searched in."
+#~ msgstr "Додати ШЛЯХ до списку каталогів, у яких слід шукати файли."
+
+#~ msgid "Only set DT_NEEDED for following dynamic libs if actually used"
+#~ msgstr ""
+#~ "Встановлювати DT_NEEDED лише для наступних динамічних бібліотек, якщо він "
+#~ "справді використовується"
+
+#~ msgid "Always set DT_NEEDED for following dynamic libs"
+#~ msgstr "Завжди встановлювати DT_NEEDED для наступних динамічних бібліотек"
+
+#~ msgid "Ignore LD_LIBRARY_PATH environment variable."
+#~ msgstr "Ігнорувати змінну середовища LD_LIBRARY_PATH."
+
+#~ msgid "Output File Control:"
+#~ msgstr "Керування файлом виведених даних:"
+
+#~ msgid "Place output in FILE."
+#~ msgstr "Вивести дані до ФАЙЛА."
+
+#~ msgid "Object is marked to not use default search path at runtime."
+#~ msgstr ""
+#~ "Об’єкт позначено, як таких, який не використовує типовий шлях пошуку під "
+#~ "час запуску."
+
+#~ msgid "Same as --whole-archive."
+#~ msgstr "Те саме, що --whole-archive."
+
+#~ msgid ""
+#~ "Default rules of extracting from archive; weak references are not enough."
+#~ msgstr ""
+#~ "Типові правила видобування з архівів; слабкого посилання недостатньо."
+
+#~ msgid "Weak references cause extraction from archive."
+#~ msgstr "Слабкі посилання спричиняють видобування з архіву."
+
+#~ msgid "Allow multiple definitions; first is used."
+#~ msgstr "Дозволити декілька визначень. Використовуватиметься лише перше."
+
+#~ msgid "Disallow/allow undefined symbols in DSOs."
+#~ msgstr "Заборонити/Дозволити невизначені символи у DSO."
+
+#~ msgid "Object requires immediate handling of $ORIGIN."
+#~ msgstr "Об’єкт вимагає негайної обробки $ORIGIN."
+
+#~ msgid "Relocation will not be processed lazily."
+#~ msgstr "Переміщення не буде оброблятися у лінивому режимі."
+
+#~ msgid "Object cannot be unloaded at runtime."
+#~ msgstr "Об’єкт не можна вивантажувати під час запуску."
+
+#~ msgid "Mark object to be initialized first."
+#~ msgstr "Позначити об’єкт, як такий, що потребує ініціалізації."
+
+#~ msgid "Enable/disable lazy-loading flag for following dependencies."
+#~ msgstr ""
+#~ "Увімкнути/Вимкнути прапорець лінивого завантаження для наведених нижче "
+#~ "залежностей."
+
+#~ msgid "Mark object as not loadable with 'dlopen'."
+#~ msgstr ""
+#~ "Позначити об’єкт, як непридатний для завантаження за допомогою «dlopen»."
+
+#~ msgid "Ignore/record dependencies on unused DSOs."
+#~ msgstr "Ігнорувати/Записувати залежності невикористаних DSO."
+
+#~ msgid "Generated DSO will be a system library."
+#~ msgstr "Створена DSO буде системною бібліотекою."
+
+#~ msgid "ADDRESS"
+#~ msgstr "АДРЕСА"
+
+#~ msgid "Set entry point address."
+#~ msgstr "Встановити адресу точки входу."
+
+#~ msgid "Do not link against shared libraries."
+#~ msgstr "Не компонувати з бібліотеками спільного використання."
+
+#~ msgid "Prefer linking against shared libraries."
+#~ msgstr ""
+#~ "Надавати перевагу компонуванню з бібліотеками спільного використання."
+
+#~ msgid "Export all dynamic symbols."
+#~ msgstr "Експортувати всі динамічні символи."
+
+#~ msgid "Strip all symbols."
+#~ msgstr "Вилучити всі символи."
+
+#~ msgid "Strip debugging symbols."
+#~ msgstr "Вилучити символи зневаджування."
+
+#~ msgid "Assume pagesize for the target system to be SIZE."
+#~ msgstr ""
+#~ "Вважати розмір сторінки для системи призначення рівним значенню РОЗМІР."
+
+#~ msgid "Set runtime DSO search path."
+#~ msgstr "Встановити шлях пошуку DSO під час запуску."
+
+#~ msgid "Set link time DSO search path."
+#~ msgstr "Встановити шлях пошуку DSO під час компонування."
+
+#~ msgid "Generate dynamic shared object."
+#~ msgstr "Створити динамічний об’єкт спільного використання."
+
+#~ msgid "Generate relocatable object."
+#~ msgstr "Створити придатний для пересування об’єкт."
+
+#~ msgid "Causes symbol not assigned to a version be reduced to local."
+#~ msgstr ""
+#~ "Спричиняє перетворення символів, не прив’язаних до версії, на локальні."
+
+#~ msgid "Remove unused sections."
+#~ msgstr "Вилучити невикористані розділи."
+
+#~ msgid "Don't remove unused sections."
+#~ msgstr "Не вилучати невикористані розділи."
+
+#~ msgid "Set soname of shared object."
+#~ msgstr "Встановити soname об’єкта спільного використання."
+
+#~ msgid "Set the dynamic linker name."
+#~ msgstr "Встановити назву динамічного компонувальника."
+
+#~ msgid "Add/suppress addition indentifying link-editor to .comment section."
+#~ msgstr ""
+#~ "Додати/Придушити додавання ідентифікації редактора компонування до "
+#~ "розділу .comment."
+
+#~ msgid "Create .eh_frame_hdr section"
+#~ msgstr "Створити розділ .eh_frame_hdr"
+
+#~ msgid "Set hash style to sysv, gnu or both."
+#~ msgstr "Встановити формат хешування у значення sysv, gnu або both."
+
+#~ msgid "Generate build ID note (md5, sha1 (default), uuid)."
+#~ msgstr ""
+#~ "Створити запису ідентифікатора збирання (md5, sha1 (типовий), uuid)."
+
+#~ msgid "Linker Operation Control:"
+#~ msgstr "Керування роботою компонувальника:"
+
+#~ msgid "Verbose messages."
+#~ msgstr "Докладні повідомлення."
+
+#~ msgid "Trace file opens."
+#~ msgstr "Спостерігати за відкриттями файлів."
+
+#~ msgid "Trade speed for less memory usage"
+#~ msgstr "Зменшити споживання пам’яті за рахунок швидкості"
+
+#~ msgid "LEVEL"
+#~ msgstr "РІВЕНЬ"
+
+#~ msgid "Set optimization level to LEVEL."
+#~ msgstr "Встановити рівень оптимізації РІВЕНЬ."
+
+#~ msgid "Use linker script in FILE."
+#~ msgstr "Використати скрипт компонування у ФАЙЛі."
+
+#~ msgid "Select to get parser debug information"
+#~ msgstr "Позначте, щоб отримати діагностичні дані обробника"
+
+#~ msgid "Read version information from FILE."
+#~ msgstr "Прочитати відомості щодо версії з ФАЙЛа."
+
+#~ msgid "Set emulation to NAME."
+#~ msgstr "Встановити режим емуляції на основі НАЗВИ."
+
+#~ msgid "Combine object and archive files."
+#~ msgstr "Комбінує об’єктні файли і файли архівів."
+
+#~ msgid "[FILE]..."
+#~ msgstr "[ФАЙЛ]..."
+
+#~ msgid "At least one input file needed"
+#~ msgstr "Потрібен принаймні один файл вхідних даних"
+
+#~ msgid "error while preparing linking"
+#~ msgstr "помилка під час приготування до компонування"
+
+#~ msgid "cannot open linker script '%s'"
+#~ msgstr "не вдалося відкрити скрипт компонування «%s»"
+
+#~ msgid "-( without matching -)"
+#~ msgstr "-( без відповідника -)"
+
+#~ msgid "only one option of -G and -r is allowed"
+#~ msgstr "можна використовувати лише один з параметрів -G або -r"
+
+#~ msgid "more than one '-m' parameter"
+#~ msgstr "декілька параметрів «-m»"
+
+#~ msgid "unknown option `-%c %s'"
+#~ msgstr "невідомий параметр «-%c %s»"
+
+#~ msgid "invalid page size value '%s': ignored"
+#~ msgstr "некоректне значення розміру сторінки «%s»: проігноровано"
+
+#~ msgid "invalid hash style '%s'"
+#~ msgstr "некоректний формат хешування «%s»"
+
+#~ msgid "invalid build-ID style '%s'"
+#~ msgstr "некоректний формат ідентифікатора збирання «%s»"
+
+#~ msgid "More than one output file name given."
+#~ msgstr "Вказано декілька назв файлів виведення даних."
+
+#~ msgid "Invalid optimization level `%s'"
+#~ msgstr "Некоректний рівень оптимізації «%s»"
+
+#~ msgid "nested -( -) groups are not allowed"
+#~ msgstr "підтримки вкладених груп -( -) не передбачено"
+
+#~ msgid "-) without matching -("
+#~ msgstr "-) без відповідника -("
+
+#~ msgid "unknown option '-%c %s'"
+#~ msgstr "невідомий параметр «-%c %s»"
+
+#~ msgid "could not find input file to determine output file format"
+#~ msgstr ""
+#~ "не вдалося виявити файл вхідних даних для визначення формату файла "
+#~ "вихідних даних"
+
+#~ msgid "try again with an appropriate '-m' parameter"
+#~ msgstr "повторіть спробу з належним параметром «-m»"
+
+#~ msgid "cannot read version script '%s'"
+#~ msgstr "не вдалося прочитати скрипт версій «%s»"
+
+#~ msgid "duplicate definition of '%s' in linker script"
+#~ msgstr "повторне визначення «%s» у скрипті компонування"
+
+#~ msgid "cannot create string table"
+#~ msgstr "не вдалося створити таблицю рядків"
+
+#~ msgid "cannot load ld backend library '%s': %s"
+#~ msgstr "не вдалося завантажити бібліотеку сервера ld «%s»: %s"
+
+#~ msgid "cannot find init function in ld backend library '%s': %s"
+#~ msgstr "не вдалося виявити функцію init у бібліотеці сервера ld «%s»: %s"
+
+#~ msgid "%s listed more than once as input"
+#~ msgstr "%s вказано декілька разів як джерело даних"
+
+#~ msgid "%s (for -l%s)\n"
+#~ msgstr "%s (для -l%s)\n"
+
+#~ msgid "%s (for DT_NEEDED %s)\n"
+#~ msgstr "%s (для DT_NEEDED %s)\n"
+
+#~ msgid "Warning: type of `%s' changed from %s in %s to %s in %s"
+#~ msgstr "Попередження: тип «%s» змінився з %s у %s на %s у %s"
+
+#~ msgid ""
+#~ "Warning: size of `%s' changed from %<PRIu64> in %s to %<PRIu64> in %s"
+#~ msgstr ""
+#~ "Попередження: розмір «%s» змінено з %<PRIu64> у %s на %<PRIu64> у %s"
+
+#~ msgid "(%s+%#<PRIx64>): multiple definition of %s `%s'\n"
+#~ msgstr "(%s+%#<PRIx64>): повторне визначення %s «%s»\n"
+
+#~ msgid "(%s+%#<PRIx64>): first defined here\n"
+#~ msgstr "(%s+%#<PRIx64>): вперше визначено тут\n"
+
+#~ msgid "%s: cannot get section group data: %s"
+#~ msgstr "%s: не вдалося отримати дані групи розділів: %s"
+
+#~ msgid "%s: section '%s' with group flag set does not belong to any group"
+#~ msgstr ""
+#~ "%s: розділ «%s» з встановленим прапорцем групи не належить жодній групі"
+
+#~ msgid "%s: section [%2d] '%s' is not in the correct section group"
+#~ msgstr "%s: розділ [%2d] «%s» не належить до відповідної групи розділів"
+
+#~ msgid "%s: invalid ELF file (%s:%d)\n"
+#~ msgstr "%s: некоректний файл ELF (%s:%d)\n"
+
+#~ msgid "%s: only files of type ET_REL might contain section groups"
+#~ msgstr "%s: групи розділів можуть містити лише файли типу ET_REL"
+
+#~ msgid "%s: cannot determine signature of section group [%2zd] '%s': %s"
+#~ msgstr "%s: не вдалося визначити підпис групи розділів [%2zd] «%s»: %s"
+
+#~ msgid "%s: cannot get content of section group [%2zd] '%s': %s'"
+#~ msgstr "%s: не вдалося отримати вміст групи розділів [%2zd] «%s»: %s'"
+
+#~ msgid ""
+#~ "%s: group member %zu of section group [%2zd] '%s' has too high index: "
+#~ "%<PRIu32>"
+#~ msgstr ""
+#~ "%s: елемент групи %zu групи розділів [%2zd] «%s» має надто високий "
+#~ "індекс: %<PRIu32>"
+
+#~ msgid "%s: section '%s' has unknown type: %d"
+#~ msgstr "%s: розділ «%s» належить до невідомого типу: %d"
+
+#~ msgid "cannot get descriptor for ELF file (%s:%d): %s\n"
+#~ msgstr "не вдалося отримати дескриптор файла ELF (%s:%d): %s\n"
+
+#~ msgid "cannot read archive `%s': %s"
+#~ msgstr "не вдалося прочитати архів «%s»: %s"
+
+#~ msgid "file of type %s cannot be linked in\n"
+#~ msgstr "файл типу %s не можна скомпонувати у\n"
+
+#~ msgid "%s: input file incompatible with ELF machine type %s\n"
+#~ msgstr "%s: файл вхідних даних несумісний з типом архітектури ELF %s\n"
+
+#~ msgid "%s: cannot get section header string table index: %s\n"
+#~ msgstr ""
+#~ "%s: не вдалося отримати покажчик таблиці рядків заголовка розділу: %s\n"
+
+#~ msgid "cannot use DSO '%s' when generating relocatable object file"
+#~ msgstr ""
+#~ "не вдалося використати DSO «%s» під час створення придатного до "
+#~ "пересування об’єктного файла"
+
+#~ msgid "input file '%s' ignored"
+#~ msgstr "файл вхідних даних «%s» проігноровано"
+
+#~ msgid "undefined symbol `%s' in %s"
+#~ msgstr "невизначений символ «%s» у %s"
+
+#~ msgid "cannot create ELF descriptor for output file: %s"
+#~ msgstr "не вдалося створити дескриптор ELF для файла вихідних даних: %s"
+
+#~ msgid "could not create ELF header for output file: %s"
+#~ msgstr "не вдалося створити заголовок ELF для файла виведених даних: %s"
+
+#~ msgid "cannot create section for output file: %s"
+#~ msgstr "не вдалося створити розділ для файла вихідних даних: %s"
+
+#~ msgid "address computation expression contains variable '%s'"
+#~ msgstr "вираз обчислення адреси містить змінну «%s»"
+
+#~ msgid ""
+#~ "argument '%<PRIuMAX>' of ALIGN in address computation expression is no "
+#~ "power of two"
+#~ msgstr ""
+#~ "значення «%<PRIuMAX>» ALIGN у виразі обчислення адреси не є степенем "
+#~ "двійки"
+
+#~ msgid "cannot find entry symbol '%s': defaulting to %#0*<PRIx64>"
+#~ msgstr ""
+#~ "не вдалося знайти символ запису «%s»: встановлено типове значення "
+#~ "%#0*<PRIx64>"
+
+#~ msgid "no entry symbol specified: defaulting to %#0*<PRIx64>"
+#~ msgstr "не вказано символу запису: встановлено типове значення %#0*<PRIx64>"
+
+#~ msgid "cannot create GNU hash table section for output file: %s"
+#~ msgstr ""
+#~ "не вдалося створити розділ таблиці хешів GNU для файла вихідних даних: %s"
+
+#~ msgid "cannot create hash table section for output file: %s"
+#~ msgstr ""
+#~ "не вдалося створити розділ таблиці хешів для файла вихідних даних: %s"
+
+#~ msgid "cannot create build ID section: %s"
+#~ msgstr "не вдалося створити розділу ідентифікатора збирання: %s"
+
+#~ msgid "cannot convert section data to file format: %s"
+#~ msgstr "не вдалося перетворити дані розділу у формат файла: %s"
+
+#~ msgid "cannot convert section data to memory format: %s"
+#~ msgstr "не вдалося перетворити дані розділу у формат вмісту пам’яті: %s"
+
+#~ msgid "cannot read enough data for UUID"
+#~ msgstr "не вдалося прочитати достатньо даних для встановлення UUID"
+
+#~ msgid "cannot create symbol table for output file: %s"
+#~ msgstr "не вдалося створити таблицю символів для файла вихідних даних: %s"
+
+#~ msgid "section index too large in dynamic symbol table"
+#~ msgstr "у таблиці динамічних символів покажчик є занадто великим"
+
+#~ msgid "cannot create versioning section: %s"
+#~ msgstr "не вдалося створити розділ версій: %s"
+
+#~ msgid "cannot create dynamic symbol table for output file: %s"
+#~ msgstr ""
+#~ "не вдалося створити динамічну таблицю символів для файла вихідних даних: "
+#~ "%s"
+
+#~ msgid "cannot create versioning data: %s"
+#~ msgstr "не вдалося створити даних версії: %s"
+
+#~ msgid "cannot create section header string section: %s"
+#~ msgstr "не вдалося створити розділ рядків заголовка розділу: %s"
+
+#~ msgid "cannot create section header string section"
+#~ msgstr "не вдалося створити розділ рядків заголовка розділу"
+
+#~ msgid "cannot create program header: %s"
+#~ msgstr "не вдалося створити заголовок програми: %s"
+
+#~ msgid "while determining file layout: %s"
+#~ msgstr "під час визначення компонування файла: %s"
+
+#~ msgid "internal error: non-nobits section follows nobits section"
+#~ msgstr ""
+#~ "внутрішня помилка: небезбітовий розділ слідом за безбітовим розділом"
+
+#~ msgid "cannot get header of 0th section: %s"
+#~ msgstr "не вдалося отримати заголовок 0-го розділу: %s"
+
+#~ msgid "linker backend didn't specify function to relocate section"
+#~ msgstr "у сервері компонування не визначено функції для розділу пересування"
+
+#~ msgid "while writing output file: %s"
+#~ msgstr "під час запису файла вихідних даних: %s"
+
+#~ msgid "while finishing output file: %s"
+#~ msgstr "під час закриття файла вихідних даних: %s"
+
+#~ msgid "cannot stat output file"
+#~ msgstr "не вдалося обробити stat файл виводу даних"
+
+#~ msgid "WARNING: temporary output file overwritten before linking finished"
+#~ msgstr ""
+#~ "ПОПЕРЕДЖЕННЯ: файл тимчасового виводу даних було перезаписано до "
+#~ "завершення компонування"
+
+#~ msgid "no machine specific '%s' implementation"
+#~ msgstr "не специфічна для архітектури реалізація «%s»"
+
+#~ msgid "mode for segment invalid\n"
+#~ msgstr "режим сегмента є некоректним\n"
+
+#~ msgid "while reading version script '%s': %s at line %d"
+#~ msgstr "під час читання скрипту версій «%s»: %s у рядку %d"
+
+#~ msgid "while reading linker script '%s': %s at line %d"
+#~ msgstr "під час читання скрипту компонування «%s»: %s у рядку %d"
+
+#~ msgid ""
+#~ "symbol '%s' is declared both local and global for unnamed version '%s'"
+#~ msgstr ""
+#~ "символ «%s» оголошено локально і на загальному рівні для версії без назви "
+#~ "«%s»"
+
+#~ msgid "symbol '%s' is declared both local and global for version '%s'"
+#~ msgstr ""
+#~ "символ «%s» оголошено локально і на загальному рівні для версії «%s»"
+
+#~ msgid "default visibility set as local and global"
+#~ msgstr "типову видимість визначено як локальну і загальну"
+
+#~ msgid "cannot get section header of section %Zu: %s"
+#~ msgstr "не вдалося отримати заголовок розділу %Zu: %s"
+
+#, fuzzy
+#~ msgid "cannot attach to core"
+#~ msgstr "не вдалося створити дерево пошуку"
+
+#~ msgid "'%s' and '%s' do not seem to match"
+#~ msgstr "«%s» і «%s» не відповідають одне одному"
+
+#~ msgid "unknown tag %hx"
+#~ msgstr "невідомий теґ %hx"
+
+#~ msgid "unknown user tag %hx"
+#~ msgstr "невідомий теґ користувача %hx"
+
+#~ msgid "unknown attribute %hx"
+#~ msgstr "невідомий атрибут %hx"
+
+#~ msgid "unknown user attribute %hx"
+#~ msgstr "невідомий атрибут користувача %hx"
+
+#~ msgid "unknown form %#<PRIx64>"
+#~ msgstr "невідома форма %#<PRIx64>"
+
+#~ msgid ""
+#~ "\n"
+#~ "\n"
+#~ "Symbols from %s[%s]:\n"
+#~ "\n"
+#~ msgstr ""
+#~ "\n"
+#~ "\n"
+#~ "Символи з %s[%s]:\n"
+#~ "\n"
+
+#~ msgid "%s %s differ: section header"
+#~ msgstr "%s %s diff: заголовок розділу"
diff --git a/third_party/elfutils/po/zh_CN.po b/third_party/elfutils/po/zh_CN.po
new file mode 100644
index 0000000..0c6ec56
--- /dev/null
+++ b/third_party/elfutils/po/zh_CN.po
@@ -0,0 +1,5666 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: http://bugzilla.redhat.com/\n"
+"POT-Creation-Date: 2010-04-21 07:41-0700\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: lib/xmalloc.c:51 lib/xmalloc.c:65 lib/xmalloc.c:79 src/readelf.c:2822
+#: src/readelf.c:3161 src/unstrip.c:2087 src/unstrip.c:2295
+#, c-format
+msgid "memory exhausted"
+msgstr ""
+
+#: libasm/asm_error.c:62 libdw/dwarf_error.c:79 libdwfl/libdwflP.h:70
+#: libelf/elf_error.c:81
+msgid "no error"
+msgstr ""
+
+#: libasm/asm_error.c:63 libdw/dwarf_error.c:88 libdwfl/libdwflP.h:72
+#: libelf/elf_error.c:112
+msgid "out of memory"
+msgstr ""
+
+#: libasm/asm_error.c:64 src/ldgeneric.c:2687
+#, c-format
+msgid "cannot create output file"
+msgstr ""
+
+#: libasm/asm_error.c:65
+msgid "invalid parameter"
+msgstr ""
+
+#: libasm/asm_error.c:66
+msgid "cannot change mode of output file"
+msgstr ""
+
+#: libasm/asm_error.c:67 src/ldgeneric.c:7001
+#, c-format
+msgid "cannot rename output file"
+msgstr ""
+
+#: libasm/asm_error.c:68
+msgid "duplicate symbol"
+msgstr ""
+
+#: libasm/asm_error.c:69
+msgid "invalid section type for operation"
+msgstr ""
+
+#: libasm/asm_error.c:70
+msgid "error during output of data"
+msgstr ""
+
+#: libasm/asm_error.c:71
+msgid "no backend support available"
+msgstr ""
+
+#: libasm/asm_error.c:81 libdw/dwarf_error.c:80 libdwfl/libdwflP.h:71
+#: libelf/elf_error.c:84
+msgid "unknown error"
+msgstr ""
+
+#: libdw/dwarf_error.c:81
+msgid "invalid access"
+msgstr ""
+
+#: libdw/dwarf_error.c:82
+msgid "no regular file"
+msgstr ""
+
+#: libdw/dwarf_error.c:83
+msgid "I/O error"
+msgstr ""
+
+#: libdw/dwarf_error.c:84
+msgid "invalid ELF file"
+msgstr ""
+
+#: libdw/dwarf_error.c:85
+msgid "no DWARF information"
+msgstr ""
+
+#: libdw/dwarf_error.c:86
+msgid "no ELF file"
+msgstr ""
+
+#: libdw/dwarf_error.c:87
+msgid "cannot get ELF header"
+msgstr ""
+
+#: libdw/dwarf_error.c:89
+msgid "not implemented"
+msgstr ""
+
+#: libdw/dwarf_error.c:90 libelf/elf_error.c:128 libelf/elf_error.c:176
+msgid "invalid command"
+msgstr ""
+
+#: libdw/dwarf_error.c:91
+msgid "invalid version"
+msgstr ""
+
+#: libdw/dwarf_error.c:92
+msgid "invalid file"
+msgstr ""
+
+#: libdw/dwarf_error.c:93
+msgid "no entries found"
+msgstr ""
+
+#: libdw/dwarf_error.c:94
+msgid "invalid DWARF"
+msgstr ""
+
+#: libdw/dwarf_error.c:95
+msgid "no string data"
+msgstr ""
+
+#: libdw/dwarf_error.c:96
+msgid "no address value"
+msgstr ""
+
+#: libdw/dwarf_error.c:97
+msgid "no constant value"
+msgstr ""
+
+#: libdw/dwarf_error.c:98
+msgid "no reference value"
+msgstr ""
+
+#: libdw/dwarf_error.c:99
+msgid "invalid reference value"
+msgstr ""
+
+#: libdw/dwarf_error.c:100
+msgid ".debug_line section missing"
+msgstr ""
+
+#: libdw/dwarf_error.c:101
+msgid "invalid .debug_line section"
+msgstr ""
+
+#: libdw/dwarf_error.c:102
+msgid "debug information too big"
+msgstr ""
+
+#: libdw/dwarf_error.c:103
+msgid "invalid DWARF version"
+msgstr ""
+
+#: libdw/dwarf_error.c:104
+msgid "invalid directory index"
+msgstr ""
+
+#: libdw/dwarf_error.c:105 libdwfl/libdwflP.h:91
+msgid "address out of range"
+msgstr ""
+
+#: libdw/dwarf_error.c:106
+msgid "no location list value"
+msgstr ""
+
+#: libdw/dwarf_error.c:107
+msgid "no block data"
+msgstr ""
+
+#: libdw/dwarf_error.c:108
+msgid "invalid line index"
+msgstr ""
+
+#: libdw/dwarf_error.c:109
+msgid "invalid address range index"
+msgstr ""
+
+#: libdw/dwarf_error.c:110 libdwfl/libdwflP.h:92
+msgid "no matching address range"
+msgstr ""
+
+#: libdw/dwarf_error.c:111
+msgid "no flag value"
+msgstr ""
+
+#: libdw/dwarf_error.c:112 libelf/elf_error.c:253
+msgid "invalid offset"
+msgstr ""
+
+#: libdw/dwarf_error.c:113
+msgid ".debug_ranges section missing"
+msgstr ""
+
+#: libdw/dwarf_error.c:114
+msgid "invalid CFI section"
+msgstr ""
+
+#: libdwfl/argp-std.c:67 src/unstrip.c:2237
+msgid "Input selection options:"
+msgstr ""
+
+#: libdwfl/argp-std.c:68
+msgid "Find addresses in FILE"
+msgstr ""
+
+#: libdwfl/argp-std.c:70
+msgid "Find addresses from signatures found in COREFILE"
+msgstr ""
+
+#: libdwfl/argp-std.c:72
+msgid "Find addresses in files mapped into process PID"
+msgstr ""
+
+#: libdwfl/argp-std.c:74
+msgid ""
+"Find addresses in files mapped as read from FILE in Linux /proc/PID/maps "
+"format"
+msgstr ""
+
+#: libdwfl/argp-std.c:76
+msgid "Find addresses in the running kernel"
+msgstr ""
+
+#: libdwfl/argp-std.c:78
+msgid "Kernel with all modules"
+msgstr ""
+
+#: libdwfl/argp-std.c:80
+msgid "Search path for separate debuginfo files"
+msgstr ""
+
+#: libdwfl/argp-std.c:163
+msgid "only one of -e, -p, -k, -K, or --core allowed"
+msgstr ""
+
+#: libdwfl/argp-std.c:223
+#, c-format
+msgid "cannot read ELF core file: %s"
+msgstr ""
+
+#: libdwfl/argp-std.c:241
+msgid "No modules recognized in core file"
+msgstr ""
+
+#: libdwfl/argp-std.c:253
+msgid "cannot load kernel symbols"
+msgstr ""
+
+#: libdwfl/argp-std.c:257
+msgid "cannot find kernel modules"
+msgstr ""
+
+#: libdwfl/argp-std.c:271
+msgid "cannot find kernel or modules"
+msgstr ""
+
+#: libdwfl/libdwflP.h:73
+msgid "See errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:74
+msgid "See elf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:75
+msgid "See dwarf_errno"
+msgstr ""
+
+#: libdwfl/libdwflP.h:76
+msgid "See ebl_errno (XXX missing)"
+msgstr ""
+
+#: libdwfl/libdwflP.h:77
+msgid "gzip decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:78
+msgid "bzip2 decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:79
+msgid "LZMA decompression failed"
+msgstr ""
+
+#: libdwfl/libdwflP.h:80
+msgid "no support library found for machine"
+msgstr ""
+
+#: libdwfl/libdwflP.h:81
+msgid "Callbacks missing for ET_REL file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:82
+msgid "Unsupported relocation type"
+msgstr ""
+
+#: libdwfl/libdwflP.h:83
+msgid "r_offset is bogus"
+msgstr ""
+
+#: libdwfl/libdwflP.h:84 libelf/elf_error.c:132 libelf/elf_error.c:192
+msgid "offset out of range"
+msgstr ""
+
+#: libdwfl/libdwflP.h:85
+msgid "relocation refers to undefined symbol"
+msgstr ""
+
+#: libdwfl/libdwflP.h:86
+msgid "Callback returned failure"
+msgstr ""
+
+#: libdwfl/libdwflP.h:87
+msgid "No DWARF information found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:88
+msgid "No symbol table found"
+msgstr ""
+
+#: libdwfl/libdwflP.h:89
+msgid "No ELF program headers"
+msgstr ""
+
+#: libdwfl/libdwflP.h:90
+msgid "address range overlaps an existing module"
+msgstr ""
+
+#: libdwfl/libdwflP.h:93
+msgid "image truncated"
+msgstr ""
+
+#: libdwfl/libdwflP.h:94
+msgid "ELF file opened"
+msgstr ""
+
+#: libdwfl/libdwflP.h:95
+msgid "not a valid ELF file"
+msgstr ""
+
+#: libdwfl/libdwflP.h:96
+msgid "cannot handle DWARF type description"
+msgstr ""
+
+#: libebl/eblbackendname.c:63
+msgid "No backend"
+msgstr ""
+
+#: libebl/eblcorenotetypename.c:107 libebl/eblobjecttypename.c:78
+#: libebl/eblobjnotetypename.c:86 libebl/eblosabiname.c:98
+#: libebl/eblsectionname.c:110 libebl/eblsectiontypename.c:140
+#: libebl/eblsegmenttypename.c:104
+msgid "<unknown>"
+msgstr ""
+
+#: libebl/ebldynamictagname.c:126
+#, c-format
+msgid "<unknown>: %#<PRIx64>"
+msgstr ""
+
+#: libebl/eblobjnote.c:76
+#, c-format
+msgid "    Build ID: "
+msgstr ""
+
+#: libebl/eblobjnote.c:87
+#, c-format
+msgid "    Linker version: %.*s\n"
+msgstr ""
+
+#: libebl/eblobjnote.c:136
+#, c-format
+msgid "    OS: %s, ABI: "
+msgstr ""
+
+#: libebl/eblosabiname.c:95
+msgid "Stand alone"
+msgstr ""
+
+#: libebl/eblsymbolbindingname.c:92 libebl/eblsymboltypename.c:98
+#, c-format
+msgid "<unknown>: %d"
+msgstr ""
+
+#: libelf/elf_error.c:88
+msgid "unknown version"
+msgstr ""
+
+#: libelf/elf_error.c:92
+msgid "unknown type"
+msgstr ""
+
+#: libelf/elf_error.c:96
+msgid "invalid `Elf' handle"
+msgstr ""
+
+#: libelf/elf_error.c:100
+msgid "invalid size of source operand"
+msgstr ""
+
+#: libelf/elf_error.c:104
+msgid "invalid size of destination operand"
+msgstr ""
+
+#: libelf/elf_error.c:108 src/readelf.c:4779
+#, c-format
+msgid "invalid encoding"
+msgstr ""
+
+#: libelf/elf_error.c:116
+msgid "invalid file descriptor"
+msgstr ""
+
+#: libelf/elf_error.c:120
+msgid "invalid operation"
+msgstr ""
+
+#: libelf/elf_error.c:124
+msgid "ELF version not set"
+msgstr ""
+
+#: libelf/elf_error.c:136
+msgid "invalid fmag field in archive header"
+msgstr ""
+
+#: libelf/elf_error.c:140
+msgid "invalid archive file"
+msgstr ""
+
+#: libelf/elf_error.c:144
+msgid "descriptor is not for an archive"
+msgstr ""
+
+#: libelf/elf_error.c:148
+msgid "no index available"
+msgstr ""
+
+#: libelf/elf_error.c:152
+msgid "cannot read data from file"
+msgstr ""
+
+#: libelf/elf_error.c:156
+msgid "cannot write data to file"
+msgstr ""
+
+#: libelf/elf_error.c:160
+msgid "invalid binary class"
+msgstr ""
+
+#: libelf/elf_error.c:164
+msgid "invalid section index"
+msgstr ""
+
+#: libelf/elf_error.c:168
+msgid "invalid operand"
+msgstr ""
+
+#: libelf/elf_error.c:172
+msgid "invalid section"
+msgstr ""
+
+#: libelf/elf_error.c:180
+msgid "executable header not created first"
+msgstr ""
+
+#: libelf/elf_error.c:184
+msgid "file descriptor disabled"
+msgstr ""
+
+#: libelf/elf_error.c:188
+msgid "archive/member file descriptor mismatch"
+msgstr ""
+
+#: libelf/elf_error.c:196
+msgid "cannot manipulate null section"
+msgstr ""
+
+#: libelf/elf_error.c:200
+msgid "data/scn mismatch"
+msgstr ""
+
+#: libelf/elf_error.c:204
+msgid "invalid section header"
+msgstr ""
+
+#: libelf/elf_error.c:208 src/readelf.c:6242 src/readelf.c:6343
+#, c-format
+msgid "invalid data"
+msgstr ""
+
+#: libelf/elf_error.c:212
+msgid "unknown data encoding"
+msgstr ""
+
+#: libelf/elf_error.c:216
+msgid "section `sh_size' too small for data"
+msgstr ""
+
+#: libelf/elf_error.c:220
+msgid "invalid section alignment"
+msgstr ""
+
+#: libelf/elf_error.c:224
+msgid "invalid section entry size"
+msgstr ""
+
+#: libelf/elf_error.c:228
+msgid "update() for write on read-only file"
+msgstr ""
+
+#: libelf/elf_error.c:232
+msgid "no such file"
+msgstr ""
+
+#: libelf/elf_error.c:236
+msgid "only relocatable files can contain section groups"
+msgstr ""
+
+#: libelf/elf_error.c:241
+msgid ""
+"program header only allowed in executables, shared objects, and core files"
+msgstr ""
+
+#: libelf/elf_error.c:248
+msgid "file has no program header"
+msgstr ""
+
+#: src/addr2line.c:66
+msgid "Output selection options:"
+msgstr ""
+
+#: src/addr2line.c:67
+msgid "Show only base names of source files"
+msgstr ""
+
+#: src/addr2line.c:69
+msgid "Show absolute file names using compilation directory"
+msgstr ""
+
+#: src/addr2line.c:70
+msgid "Also show function names"
+msgstr ""
+
+#: src/addr2line.c:71
+msgid "Also show symbol or section names"
+msgstr ""
+
+#: src/addr2line.c:73
+msgid "Treat addresses as offsets relative to NAME section."
+msgstr ""
+
+#: src/addr2line.c:75 src/elfcmp.c:75 src/findtextrel.c:75 src/nm.c:103
+#: src/strings.c:83
+msgid "Miscellaneous:"
+msgstr ""
+
+#: src/addr2line.c:84
+msgid ""
+"Locate source files and line information for ADDRs (in a.out by default)."
+msgstr ""
+
+#: src/addr2line.c:88
+msgid "[ADDR...]"
+msgstr ""
+
+#: src/addr2line.c:185 src/ar.c:289 src/elfcmp.c:555 src/elflint.c:239
+#: src/findtextrel.c:170 src/ld.c:957 src/nm.c:253 src/objdump.c:181
+#: src/ranlib.c:136 src/readelf.c:449 src/size.c:219 src/strings.c:227
+#: src/strip.c:204 src/unstrip.c:234
+#, c-format
+msgid ""
+"Copyright (C) %s Red Hat, Inc.\n"
+"This is free software; see the source for copying conditions.  There is NO\n"
+"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+msgstr ""
+
+#: src/addr2line.c:190 src/ar.c:294 src/elfcmp.c:560 src/elflint.c:244
+#: src/findtextrel.c:175 src/ld.c:962 src/nm.c:258 src/objdump.c:186
+#: src/ranlib.c:141 src/readelf.c:454 src/size.c:224 src/strings.c:232
+#: src/strip.c:209 src/unstrip.c:239
+#, c-format
+msgid "Written by %s.\n"
+msgstr ""
+
+#: src/addr2line.c:405
+#, c-format
+msgid "Section syntax requires exactly one module"
+msgstr ""
+
+#: src/addr2line.c:428
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside section '%s'"
+msgstr ""
+
+#: src/addr2line.c:461
+#, c-format
+msgid "cannot find symbol '%s'"
+msgstr ""
+
+#: src/addr2line.c:466
+#, c-format
+msgid "offset %#<PRIxMAX> lies outside contents of '%s'"
+msgstr ""
+
+#: src/ar.c:76
+msgid "Commands:"
+msgstr ""
+
+#: src/ar.c:77
+msgid "Delete files from archive."
+msgstr ""
+
+#: src/ar.c:78
+msgid "Move files in archive."
+msgstr ""
+
+#: src/ar.c:79
+msgid "Print files in archive."
+msgstr ""
+
+#: src/ar.c:80
+msgid "Quick append files to archive."
+msgstr ""
+
+#: src/ar.c:82
+msgid "Replace existing or insert new file into archive."
+msgstr ""
+
+#: src/ar.c:83
+msgid "Display content of archive."
+msgstr ""
+
+#: src/ar.c:84
+msgid "Extract files from archive."
+msgstr ""
+
+#: src/ar.c:86
+msgid "Command Modifiers:"
+msgstr ""
+
+#: src/ar.c:87
+msgid "Preserve original dates."
+msgstr ""
+
+#: src/ar.c:88
+msgid "Use instance [COUNT] of name."
+msgstr ""
+
+#: src/ar.c:90
+msgid "Do not replace existing files with extracted files."
+msgstr ""
+
+#: src/ar.c:91
+msgid "Allow filename to be truncated if necessary."
+msgstr ""
+
+#: src/ar.c:93
+msgid "Provide verbose output."
+msgstr ""
+
+#: src/ar.c:94
+msgid "Force regeneration of symbol table."
+msgstr ""
+
+#: src/ar.c:95
+msgid "Insert file after [MEMBER]."
+msgstr ""
+
+#: src/ar.c:96
+msgid "Insert file before [MEMBER]."
+msgstr ""
+
+#: src/ar.c:97
+msgid "Same as -b."
+msgstr ""
+
+#: src/ar.c:98
+msgid "Suppress message when library has to be created."
+msgstr ""
+
+#: src/ar.c:100
+msgid "Use full path for file matching."
+msgstr ""
+
+#: src/ar.c:101
+msgid "Update only older files in archive."
+msgstr ""
+
+#: src/ar.c:107
+msgid "Create, modify, and extract from archives."
+msgstr ""
+
+#: src/ar.c:110
+msgid "[MEMBER] [COUNT] ARCHIVE [FILE...]"
+msgstr ""
+
+#: src/ar.c:192
+#, c-format
+msgid "'a', 'b', and 'i' are only allowed with the 'm' and 'r' options"
+msgstr ""
+
+#: src/ar.c:197
+#, c-format
+msgid "MEMBER parameter required for 'a', 'b', and 'i' modifiers"
+msgstr ""
+
+#: src/ar.c:213
+#, c-format
+msgid "'N' is only meaningful with the 'x' and 'd' options"
+msgstr ""
+
+#: src/ar.c:218
+#, c-format
+msgid "COUNT parameter required"
+msgstr ""
+
+#: src/ar.c:230
+#, c-format
+msgid "invalid COUNT parameter %s"
+msgstr ""
+
+#: src/ar.c:237
+#, c-format
+msgid "'%c' is only meaningful with the 'x' option"
+msgstr ""
+
+#: src/ar.c:243
+#, c-format
+msgid "archive name required"
+msgstr ""
+
+#: src/ar.c:314
+#, c-format
+msgid "More than one operation specified"
+msgstr ""
+
+#: src/ar.c:404
+#, c-format
+msgid "cannot open archive '%s'"
+msgstr ""
+
+#: src/ar.c:414
+#, c-format
+msgid "cannot open archive '%s': %s"
+msgstr ""
+
+#: src/ar.c:418
+#, c-format
+msgid "%s: not an archive file"
+msgstr ""
+
+#: src/ar.c:422
+#, c-format
+msgid "cannot stat archive '%s'"
+msgstr ""
+
+#: src/ar.c:434
+#, c-format
+msgid "no entry %s in archive\n"
+msgstr ""
+
+#: src/ar.c:487 src/ar.c:929 src/ar.c:1129
+#, c-format
+msgid "cannot create hash table"
+msgstr ""
+
+#: src/ar.c:494 src/ar.c:936 src/ar.c:1138
+#, c-format
+msgid "cannot insert into hash table"
+msgstr ""
+
+#: src/ar.c:502 src/ranlib.c:176
+#, c-format
+msgid "cannot stat '%s'"
+msgstr ""
+
+#: src/ar.c:598
+#, c-format
+msgid "cannot read content of %s: %s"
+msgstr ""
+
+#: src/ar.c:641
+#, c-format
+msgid "cannot open %.*s"
+msgstr ""
+
+#: src/ar.c:663
+#, c-format
+msgid "failed to write %s"
+msgstr ""
+
+#: src/ar.c:675
+#, c-format
+msgid "cannot change mode of %s"
+msgstr ""
+
+#: src/ar.c:691
+#, c-format
+msgid "cannot change modification time of %s"
+msgstr ""
+
+#: src/ar.c:737
+#, c-format
+msgid "cannot rename temporary file to %.*s"
+msgstr ""
+
+#: src/ar.c:773 src/ar.c:1021 src/ar.c:1419 src/ranlib.c:250
+#, c-format
+msgid "cannot create new file"
+msgstr ""
+
+#: src/ar.c:1220
+#, c-format
+msgid "position member %s not found"
+msgstr ""
+
+#: src/ar.c:1230
+#, c-format
+msgid "%s: no entry %s in archive!\n"
+msgstr ""
+
+#: src/ar.c:1259 src/ldgeneric.c:519 src/objdump.c:257
+#, c-format
+msgid "cannot open %s"
+msgstr ""
+
+#: src/ar.c:1264
+#, c-format
+msgid "cannot stat %s"
+msgstr ""
+
+#: src/ar.c:1270
+#, c-format
+msgid "%s is no regular file"
+msgstr ""
+
+#: src/ar.c:1283
+#, c-format
+msgid "cannot get ELF descriptor for %s: %s\n"
+msgstr ""
+
+#: src/ar.c:1302
+#, c-format
+msgid "cannot read %s: %s"
+msgstr ""
+
+#: src/arlib.c:215
+#, c-format
+msgid "the archive '%s' is too large"
+msgstr ""
+
+#: src/arlib.c:228
+#, c-format
+msgid "cannot read ELF header of %s(%s): %s"
+msgstr ""
+
+#: src/elfcmp.c:69
+msgid "Control options:"
+msgstr ""
+
+#: src/elfcmp.c:70
+msgid ""
+"Control treatment of gaps in loadable segments [ignore|match] (default: "
+"ignore)"
+msgstr ""
+
+#: src/elfcmp.c:72
+msgid "Ignore permutation of buckets in SHT_HASH section"
+msgstr ""
+
+#: src/elfcmp.c:73
+msgid "Output nothing; yield exit status only"
+msgstr ""
+
+#: src/elfcmp.c:80
+msgid "Compare relevant parts of two ELF files for equality."
+msgstr ""
+
+#: src/elfcmp.c:84
+msgid "FILE1 FILE2"
+msgstr ""
+
+#: src/elfcmp.c:140
+msgid "Invalid number of parameters.\n"
+msgstr ""
+
+#: src/elfcmp.c:168 src/elfcmp.c:173
+#, c-format
+msgid "cannot get ELF header of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:190
+#, c-format
+msgid "%s %s diff: ELF header"
+msgstr ""
+
+#: src/elfcmp.c:198 src/elfcmp.c:201
+#, c-format
+msgid "cannot get section count of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:206
+#, c-format
+msgid "%s %s diff: section count"
+msgstr ""
+
+#: src/elfcmp.c:214 src/elfcmp.c:217
+#, c-format
+msgid "cannot get program header count of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:222
+#, c-format
+msgid "%s %s diff: program header count"
+msgstr ""
+
+#: src/elfcmp.c:281
+#, c-format
+msgid "%s %s differ: section header"
+msgstr ""
+
+#: src/elfcmp.c:309 src/elfcmp.c:315
+#, c-format
+msgid "cannot get content of section %zu in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:331 src/elfcmp.c:337
+#, c-format
+msgid "cannot get symbol in '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:358
+#, c-format
+msgid "%s %s differ: symbol table [%zu]"
+msgstr ""
+
+#: src/elfcmp.c:361
+#, c-format
+msgid "%s %s differ: symbol table [%zu,%zu]"
+msgstr ""
+
+#: src/elfcmp.c:409
+#, c-format
+msgid "%s %s differ: section [%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:413
+#, c-format
+msgid "%s %s differ: section [%zu,%zu] '%s' content"
+msgstr ""
+
+#: src/elfcmp.c:429
+#, c-format
+msgid "%s %s differ: unequal amount of important sections"
+msgstr ""
+
+#: src/elfcmp.c:463 src/elfcmp.c:468
+#, c-format
+msgid "cannot load data of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:487 src/elfcmp.c:493
+#, c-format
+msgid "cannot get program header entry %d of '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:499
+#, c-format
+msgid "%s %s differ: program header %d"
+msgstr ""
+
+#: src/elfcmp.c:524
+#, c-format
+msgid "%s %s differ: gap"
+msgstr ""
+
+#: src/elfcmp.c:583
+#, c-format
+msgid "Invalid value '%s' for --gaps parameter."
+msgstr ""
+
+#: src/elfcmp.c:607 src/findtextrel.c:229 src/ldgeneric.c:1767
+#: src/ldgeneric.c:4257 src/nm.c:363 src/ranlib.c:169 src/size.c:301
+#: src/strings.c:183 src/strip.c:433 src/strip.c:468 src/unstrip.c:1900
+#: src/unstrip.c:1929
+#, c-format
+msgid "cannot open '%s'"
+msgstr ""
+
+#: src/elfcmp.c:611 src/findtextrel.c:236 src/ranlib.c:186
+#, c-format
+msgid "cannot create ELF descriptor for '%s': %s"
+msgstr ""
+
+#: src/elfcmp.c:616
+#, c-format
+msgid "cannot create EBL descriptor for '%s'"
+msgstr ""
+
+#: src/elfcmp.c:634
+#, c-format
+msgid "cannot get section header of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:644
+#, c-format
+msgid "cannot get content of section %zu: %s"
+msgstr ""
+
+#: src/elfcmp.c:654 src/elfcmp.c:668
+#, c-format
+msgid "cannot get relocation: %s"
+msgstr ""
+
+#: src/elflint.c:72
+msgid "Be extremely strict, flag level 2 features."
+msgstr ""
+
+#: src/elflint.c:73
+msgid "Do not print anything if successful"
+msgstr ""
+
+#: src/elflint.c:74
+msgid "Binary is a separate debuginfo file"
+msgstr ""
+
+#: src/elflint.c:76
+msgid ""
+"Binary has been created with GNU ld and is therefore known to be broken in "
+"certain ways"
+msgstr ""
+
+#: src/elflint.c:82
+msgid "Pedantic checking of ELF files compliance with gABI/psABI spec."
+msgstr ""
+
+#: src/elflint.c:86 src/readelf.c:118
+msgid "FILE..."
+msgstr ""
+
+#: src/elflint.c:159 src/readelf.c:272
+#, c-format
+msgid "cannot open input file"
+msgstr ""
+
+#: src/elflint.c:166
+#, c-format
+msgid "cannot generate Elf descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:185
+#, c-format
+msgid "error while closing Elf descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:189
+msgid "No errors"
+msgstr ""
+
+#: src/elflint.c:223 src/readelf.c:425
+msgid "Missing file name.\n"
+msgstr ""
+
+#: src/elflint.c:302
+#, c-format
+msgid " error while freeing sub-ELF descriptor: %s\n"
+msgstr ""
+
+#: src/elflint.c:310
+#, c-format
+msgid "Not an ELF file - it has the wrong magic bytes at the start\n"
+msgstr ""
+
+#: src/elflint.c:370
+#, c-format
+msgid "e_ident[%d] == %d is no known class\n"
+msgstr ""
+
+#: src/elflint.c:375
+#, c-format
+msgid "e_ident[%d] == %d is no known data encoding\n"
+msgstr ""
+
+#: src/elflint.c:379
+#, c-format
+msgid "unknown ELF header version number e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:385
+#, c-format
+msgid "unsupported OS ABI e_ident[%d] == '%s'\n"
+msgstr ""
+
+#: src/elflint.c:391
+#, c-format
+msgid "unsupport ABI version e_ident[%d] == %d\n"
+msgstr ""
+
+#: src/elflint.c:396
+#, c-format
+msgid "e_ident[%zu] is not zero\n"
+msgstr ""
+
+#: src/elflint.c:401
+#, c-format
+msgid "unknown object file type %d\n"
+msgstr ""
+
+#: src/elflint.c:408
+#, c-format
+msgid "unknown machine type %d\n"
+msgstr ""
+
+#: src/elflint.c:412
+#, c-format
+msgid "unknown object file version\n"
+msgstr ""
+
+#: src/elflint.c:418
+#, c-format
+msgid "invalid program header offset\n"
+msgstr ""
+
+#: src/elflint.c:420
+#, c-format
+msgid "executables and DSOs cannot have zero program header offset\n"
+msgstr ""
+
+#: src/elflint.c:424
+#, c-format
+msgid "invalid number of program header entries\n"
+msgstr ""
+
+#: src/elflint.c:432
+#, c-format
+msgid "invalid section header table offset\n"
+msgstr ""
+
+#: src/elflint.c:435
+#, c-format
+msgid "section header table must be present\n"
+msgstr ""
+
+#: src/elflint.c:449
+#, c-format
+msgid "invalid number of section header table entries\n"
+msgstr ""
+
+#: src/elflint.c:466
+#, c-format
+msgid "invalid section header index\n"
+msgstr ""
+
+#: src/elflint.c:480
+#, c-format
+msgid "invalid number of program header table entries\n"
+msgstr ""
+
+#: src/elflint.c:489
+#, c-format
+msgid "invalid machine flags: %s\n"
+msgstr ""
+
+#: src/elflint.c:496 src/elflint.c:513
+#, c-format
+msgid "invalid ELF header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:499 src/elflint.c:516
+#, c-format
+msgid "invalid program header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:502 src/elflint.c:519
+#, c-format
+msgid "invalid program header position or size\n"
+msgstr ""
+
+#: src/elflint.c:505 src/elflint.c:522
+#, c-format
+msgid "invalid section header size: %hd\n"
+msgstr ""
+
+#: src/elflint.c:508 src/elflint.c:525
+#, c-format
+msgid "invalid section header position or size\n"
+msgstr ""
+
+#: src/elflint.c:569
+#, c-format
+msgid ""
+"section [%2d] '%s': section with SHF_GROUP flag set not part of a section "
+"group\n"
+msgstr ""
+
+#: src/elflint.c:573
+#, c-format
+msgid ""
+"section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"
+msgstr ""
+
+#: src/elflint.c:589 src/elflint.c:1432 src/elflint.c:1482 src/elflint.c:1591
+#: src/elflint.c:2185 src/elflint.c:2699 src/elflint.c:2860 src/elflint.c:2990
+#: src/elflint.c:3162 src/elflint.c:4062
+#, c-format
+msgid "section [%2d] '%s': cannot get section data\n"
+msgstr ""
+
+#: src/elflint.c:602 src/elflint.c:1598
+#, c-format
+msgid ""
+"section [%2d] '%s': referenced as string table for section [%2d] '%s' but "
+"type is not SHT_STRTAB\n"
+msgstr ""
+
+#: src/elflint.c:625
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol table cannot have more than one extended index "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:636
+#, c-format
+msgid "section [%2u] '%s': entry size is does not match ElfXX_Sym\n"
+msgstr ""
+
+#: src/elflint.c:645
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:650 src/elflint.c:653 src/elflint.c:656 src/elflint.c:659
+#: src/elflint.c:662 src/elflint.c:665
+#, c-format
+msgid "section [%2d] '%s': '%s' in zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:668
+#, c-format
+msgid "section [%2d] '%s': XINDEX for zeroth entry not zero\n"
+msgstr ""
+
+#: src/elflint.c:678
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:687
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid name value\n"
+msgstr ""
+
+#: src/elflint.c:700
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: too large section index but no extended "
+"section index section\n"
+msgstr ""
+
+#: src/elflint.c:706
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in "
+"st_shndx (%<PRIu32>)\n"
+msgstr ""
+
+#: src/elflint.c:718
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: invalid section index\n"
+msgstr ""
+
+#: src/elflint.c:726
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown type\n"
+msgstr ""
+
+#: src/elflint.c:732
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown symbol binding\n"
+msgstr ""
+
+#: src/elflint.c:737
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unique symbol not of object type\n"
+msgstr ""
+
+#: src/elflint.c:745
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"
+msgstr ""
+
+#: src/elflint.c:749
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"
+msgstr ""
+
+#: src/elflint.c:753
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"
+msgstr ""
+
+#: src/elflint.c:785
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: st_value out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:791 src/elflint.c:816 src/elflint.c:859
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu does not fit completely in referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:800
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have "
+"SHF_TLS flag set\n"
+msgstr ""
+
+#: src/elflint.c:810 src/elflint.c:852
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section "
+"[%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:837
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"
+msgstr ""
+
+#: src/elflint.c:845
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:872
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:879
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: non-local symbol outside range described in "
+"sh_info\n"
+msgstr ""
+
+#: src/elflint.c:886
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: non-local section symbol\n"
+msgstr ""
+
+#: src/elflint.c:936
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to bad section [%"
+"2d]\n"
+msgstr ""
+
+#: src/elflint.c:943
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to section [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:959
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#<PRIx64> does not "
+"match %s section address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:966
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %<PRIu64> does not "
+"match %s section size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:974
+#, c-format
+msgid ""
+"section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got "
+"section\n"
+msgstr ""
+
+#: src/elflint.c:990
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC_ symbol value %#<PRIx64> does not match dynamic "
+"segment address %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:997
+#, c-format
+msgid ""
+"section [%2d] '%s': _DYNAMIC symbol size %<PRIu64> does not match dynamic "
+"segment size %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:1010
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-"
+"default visibility\n"
+msgstr ""
+
+#: src/elflint.c:1014
+#, c-format
+msgid "section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"
+msgstr ""
+
+#: src/elflint.c:1059
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"
+msgstr ""
+
+#: src/elflint.c:1068 src/elflint.c:1120
+#, c-format
+msgid "section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"
+msgstr ""
+
+#: src/elflint.c:1093 src/elflint.c:1145
+#, c-format
+msgid ""
+"section [%2d] '%s': relative relocations after index %d as specified by "
+"DT_RELCOUNT\n"
+msgstr ""
+
+#: src/elflint.c:1099 src/elflint.c:1151
+#, c-format
+msgid ""
+"section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT "
+"specified %d relative relocations\n"
+msgstr ""
+
+#: src/elflint.c:1111
+#, c-format
+msgid "section [%2d] '%s': DT_RELACOUNT used for this REL section\n"
+msgstr ""
+
+#: src/elflint.c:1193
+#, c-format
+msgid "section [%2d] '%s': invalid destination section index\n"
+msgstr ""
+
+#: src/elflint.c:1206
+#, c-format
+msgid "section [%2d] '%s': invalid destination section type\n"
+msgstr ""
+
+#: src/elflint.c:1214
+#, c-format
+msgid "section [%2d] '%s': sh_info should be zero\n"
+msgstr ""
+
+#: src/elflint.c:1221
+#, c-format
+msgid "section [%2d] '%s': no relocations for merge-able sections possible\n"
+msgstr ""
+
+#: src/elflint.c:1228
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Rela\n"
+msgstr ""
+
+#: src/elflint.c:1288
+#, c-format
+msgid "text relocation flag set but there is no read-only segment\n"
+msgstr ""
+
+#: src/elflint.c:1315
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid type\n"
+msgstr ""
+
+#: src/elflint.c:1323
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: relocation type invalid for the file "
+"type\n"
+msgstr ""
+
+#: src/elflint.c:1331
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: invalid symbol index\n"
+msgstr ""
+
+#: src/elflint.c:1349
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can "
+"be used with %s\n"
+msgstr ""
+
+#: src/elflint.c:1366
+#, c-format
+msgid "section [%2d] '%s': relocation %zu: offset out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:1381
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: copy relocation against symbol of type %"
+"s\n"
+msgstr ""
+
+#: src/elflint.c:1402
+#, c-format
+msgid ""
+"section [%2d] '%s': relocation %zu: read-only section modified but text "
+"relocation flag not set\n"
+msgstr ""
+
+#: src/elflint.c:1417
+#, c-format
+msgid "section [%2d] '%s': relocations are against loaded and unloaded data\n"
+msgstr ""
+
+#: src/elflint.c:1456 src/elflint.c:1506
+#, c-format
+msgid "section [%2d] '%s': cannot get relocation %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1586
+#, c-format
+msgid "more than one dynamic section present\n"
+msgstr ""
+
+#: src/elflint.c:1604
+#, c-format
+msgid "section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"
+msgstr ""
+
+#: src/elflint.c:1609 src/elflint.c:1901
+#, c-format
+msgid "section [%2d] '%s': sh_info not zero\n"
+msgstr ""
+
+#: src/elflint.c:1619
+#, c-format
+msgid "section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:1627
+#, c-format
+msgid "section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"
+msgstr ""
+
+#: src/elflint.c:1634
+#, c-format
+msgid "section [%2d] '%s': entry %zu: unknown tag\n"
+msgstr ""
+
+#: src/elflint.c:1645
+#, c-format
+msgid "section [%2d] '%s': entry %zu: more than one entry with tag %s\n"
+msgstr ""
+
+#: src/elflint.c:1655
+#, c-format
+msgid "section [%2d] '%s': entry %zu: level 2 tag %s used\n"
+msgstr ""
+
+#: src/elflint.c:1673
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"
+msgstr ""
+
+#: src/elflint.c:1695
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: pointer does not match address of section [%"
+"2d] '%s' referenced by sh_link\n"
+msgstr ""
+
+#: src/elflint.c:1738
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:1753
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %zu: %s value must be valid offset in section [%"
+"2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:1773 src/elflint.c:1801
+#, c-format
+msgid "section [%2d] '%s': contains %s entry but not %s\n"
+msgstr ""
+
+#: src/elflint.c:1785
+#, c-format
+msgid "section [%2d] '%s': mandatory tag %s not present\n"
+msgstr ""
+
+#: src/elflint.c:1794
+#, c-format
+msgid "section [%2d] '%s': no hash section present\n"
+msgstr ""
+
+#: src/elflint.c:1809 src/elflint.c:1816
+#, c-format
+msgid "section [%2d] '%s': not all of %s, %s, and %s are present\n"
+msgstr ""
+
+#: src/elflint.c:1826 src/elflint.c:1830
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"
+msgstr ""
+
+#: src/elflint.c:1836
+#, c-format
+msgid "section [%2d] '%s': non-DSO file marked as dependency during prelink\n"
+msgstr ""
+
+#: src/elflint.c:1847 src/elflint.c:1851 src/elflint.c:1855 src/elflint.c:1859
+#, c-format
+msgid "section [%2d] '%s': %s tag missing in prelinked executable\n"
+msgstr ""
+
+#: src/elflint.c:1871
+#, c-format
+msgid ""
+"section [%2d] '%s': only relocatable files can have extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1881
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index section not for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1886
+#, c-format
+msgid "cannot get data for symbol section\n"
+msgstr ""
+
+#: src/elflint.c:1889
+#, c-format
+msgid "section [%2d] '%s': entry size does not match Elf32_Word\n"
+msgstr ""
+
+#: src/elflint.c:1896
+#, c-format
+msgid "section [%2d] '%s': extended index table too small for symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1911
+#, c-format
+msgid ""
+"section [%2d] '%s': extended section index in section [%2zu] '%s' refers to "
+"same symbol table\n"
+msgstr ""
+
+#: src/elflint.c:1922
+#, c-format
+msgid "symbol 0 should have zero extended section index\n"
+msgstr ""
+
+#: src/elflint.c:1934
+#, c-format
+msgid "cannot get data for symbol %zu\n"
+msgstr ""
+
+#: src/elflint.c:1939
+#, c-format
+msgid "extended section index is %<PRIu32> but symbol index is not XINDEX\n"
+msgstr ""
+
+#: src/elflint.c:1955 src/elflint.c:1996
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"
+msgstr ""
+
+#: src/elflint.c:1967 src/elflint.c:2008
+#, c-format
+msgid "section [%2d] '%s': chain array too large\n"
+msgstr ""
+
+#: src/elflint.c:1976 src/elflint.c:2017
+#, c-format
+msgid "section [%2d] '%s': hash bucket reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:1982
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2023
+#, c-format
+msgid "section [%2d] '%s': hash chain reference %<PRIu64> out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2038
+#, c-format
+msgid "section [%2d] '%s': bitmask size not power of 2: %u\n"
+msgstr ""
+
+#: src/elflint.c:2049
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table section is too small (is %ld, expected at "
+"least%ld)\n"
+msgstr ""
+
+#: src/elflint.c:2057
+#, c-format
+msgid "section [%2d] '%s': 2nd hash function shift too big: %u\n"
+msgstr ""
+
+#: src/elflint.c:2089
+#, c-format
+msgid ""
+"section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"
+msgstr ""
+
+#: src/elflint.c:2110
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %u referenced in chain for bucket %zu is "
+"undefined\n"
+msgstr ""
+
+#: src/elflint.c:2121
+#, c-format
+msgid ""
+"section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"
+msgstr ""
+
+#: src/elflint.c:2152
+#, c-format
+msgid "section [%2d] '%s': hash chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2157
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"
+msgstr ""
+
+#: src/elflint.c:2163
+#, c-format
+msgid "section [%2d] '%s': bitmask does not match names in the hash table\n"
+msgstr ""
+
+#: src/elflint.c:2176
+#, c-format
+msgid "section [%2d] '%s': relocatable files cannot have hash tables\n"
+msgstr ""
+
+#: src/elflint.c:2194
+#, c-format
+msgid "section [%2d] '%s': hash table not for dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2202
+#, c-format
+msgid "section [%2d] '%s': hash table entry size incorrect\n"
+msgstr ""
+
+#: src/elflint.c:2207
+#, c-format
+msgid "section [%2d] '%s': not marked to be allocated\n"
+msgstr ""
+
+#: src/elflint.c:2212
+#, c-format
+msgid ""
+"section [%2d] '%s': hash table has not even room for initial administrative "
+"entries\n"
+msgstr ""
+
+#: src/elflint.c:2260
+#, c-format
+msgid "sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"
+msgstr ""
+
+#: src/elflint.c:2338 src/elflint.c:2342
+#, c-format
+msgid "section [%2zu] '%s': reference to symbol index 0\n"
+msgstr ""
+
+#: src/elflint.c:2349
+#, c-format
+msgid ""
+"symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2361
+#, c-format
+msgid ""
+"symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash "
+"table in [%2zu] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2377
+#, c-format
+msgid "section [%2d] '%s': nonzero sh_%s for NULL section\n"
+msgstr ""
+
+#: src/elflint.c:2397
+#, c-format
+msgid ""
+"section [%2d] '%s': section groups only allowed in relocatable object files\n"
+msgstr ""
+
+#: src/elflint.c:2408
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol table: %s\n"
+msgstr ""
+
+#: src/elflint.c:2413
+#, c-format
+msgid "section [%2d] '%s': section reference in sh_link is no symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2419
+#, c-format
+msgid "section [%2d] '%s': invalid symbol index in sh_info\n"
+msgstr ""
+
+#: src/elflint.c:2424
+#, c-format
+msgid "section [%2d] '%s': sh_flags not zero\n"
+msgstr ""
+
+#: src/elflint.c:2431
+#, c-format
+msgid "section [%2d] '%s': cannot get symbol for signature\n"
+msgstr ""
+
+#: src/elflint.c:2436
+#, c-format
+msgid "section [%2d] '%s': signature symbol cannot be empty string\n"
+msgstr ""
+
+#: src/elflint.c:2442
+#, c-format
+msgid "section [%2d] '%s': sh_flags not set correctly\n"
+msgstr ""
+
+#: src/elflint.c:2448
+#, c-format
+msgid "section [%2d] '%s': cannot get data: %s\n"
+msgstr ""
+
+#: src/elflint.c:2457
+#, c-format
+msgid "section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"
+msgstr ""
+
+#: src/elflint.c:2462
+#, c-format
+msgid "section [%2d] '%s': section group without flags word\n"
+msgstr ""
+
+#: src/elflint.c:2468
+#, c-format
+msgid "section [%2d] '%s': section group without member\n"
+msgstr ""
+
+#: src/elflint.c:2472
+#, c-format
+msgid "section [%2d] '%s': section group with only one member\n"
+msgstr ""
+
+#: src/elflint.c:2483
+#, c-format
+msgid "section [%2d] '%s': unknown section group flags\n"
+msgstr ""
+
+#: src/elflint.c:2495
+#, c-format
+msgid "section [%2d] '%s': section index %Zu out of range\n"
+msgstr ""
+
+#: src/elflint.c:2504
+#, c-format
+msgid "section [%2d] '%s': cannot get section header for element %zu: %s\n"
+msgstr ""
+
+#: src/elflint.c:2511
+#, c-format
+msgid "section [%2d] '%s': section group contains another group [%2d] '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2517
+#, c-format
+msgid ""
+"section [%2d] '%s': element %Zu references section [%2d] '%s' without "
+"SHF_GROUP flag set\n"
+msgstr ""
+
+#: src/elflint.c:2524
+#, c-format
+msgid "section [%2d] '%s' is contained in more than one section group\n"
+msgstr ""
+
+#: src/elflint.c:2713
+#, c-format
+msgid ""
+"section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no "
+"dynamic symbol table\n"
+msgstr ""
+
+#: src/elflint.c:2724
+#, c-format
+msgid ""
+"section [%2d] '%s' has different number of entries than symbol table [%2d] '%"
+"s'\n"
+msgstr ""
+
+#: src/elflint.c:2740
+#, c-format
+msgid "section [%2d] '%s': symbol %d: cannot read version data\n"
+msgstr ""
+
+#: src/elflint.c:2756
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with global scope\n"
+msgstr ""
+
+#: src/elflint.c:2764
+#, c-format
+msgid "section [%2d] '%s': symbol %d: local symbol with version\n"
+msgstr ""
+
+#: src/elflint.c:2778
+#, c-format
+msgid "section [%2d] '%s': symbol %d: invalid version index %d\n"
+msgstr ""
+
+#: src/elflint.c:2783
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for defined version\n"
+msgstr ""
+
+#: src/elflint.c:2793
+#, c-format
+msgid ""
+"section [%2d] '%s': symbol %d: version index %d is for requested version\n"
+msgstr ""
+
+#: src/elflint.c:2845
+#, c-format
+msgid "more than one version reference section present\n"
+msgstr ""
+
+#: src/elflint.c:2853 src/elflint.c:2982
+#, c-format
+msgid "section [%2d] '%s': sh_link does not link to string table\n"
+msgstr ""
+
+#: src/elflint.c:2876 src/elflint.c:3034
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong version %d\n"
+msgstr ""
+
+#: src/elflint.c:2882 src/elflint.c:3040
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:2890
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid file reference\n"
+msgstr ""
+
+#: src/elflint.c:2898
+#, c-format
+msgid "section [%2d] '%s': entry %d references unknown dependency\n"
+msgstr ""
+
+#: src/elflint.c:2910
+#, c-format
+msgid "section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:2917
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has invalid name "
+"reference\n"
+msgstr ""
+
+#: src/elflint.c:2924
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %"
+"#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:2934
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version "
+"name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:2945
+#, c-format
+msgid ""
+"section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"
+msgstr ""
+
+#: src/elflint.c:2961 src/elflint.c:3119
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid offset to next entry\n"
+msgstr ""
+
+#: src/elflint.c:2974
+#, c-format
+msgid "more than one version definition section present\n"
+msgstr ""
+
+#: src/elflint.c:3019
+#, c-format
+msgid "section [%2d] '%s': more than one BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3023
+#, c-format
+msgid "section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"
+msgstr ""
+
+#: src/elflint.c:3029
+#, c-format
+msgid "section [%2d] '%s': entry %d has unknown flag\n"
+msgstr ""
+
+#: src/elflint.c:3053
+#, c-format
+msgid "section [%2d] '%s': entry %d has invalid name reference\n"
+msgstr ""
+
+#: src/elflint.c:3060
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"
+msgstr ""
+
+#: src/elflint.c:3069
+#, c-format
+msgid "section [%2d] '%s': entry %d has duplicate version name '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3088
+#, c-format
+msgid ""
+"section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3103
+#, c-format
+msgid "section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"
+msgstr ""
+
+#: src/elflint.c:3125
+#, c-format
+msgid "section [%2d] '%s': no BASE definition\n"
+msgstr ""
+
+#: src/elflint.c:3141
+#, c-format
+msgid "section [%2d] '%s': unknown parent version '%s'\n"
+msgstr ""
+
+#: src/elflint.c:3154
+#, c-format
+msgid "section [%2d] '%s': empty object attributes section\n"
+msgstr ""
+
+#: src/elflint.c:3175
+#, c-format
+msgid "section [%2d] '%s': unrecognized attribute format\n"
+msgstr ""
+
+#: src/elflint.c:3191
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3200
+#, c-format
+msgid "section [%2d] '%s': offset %zu: invalid length in attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3212
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated vendor name string\n"
+msgstr ""
+
+#: src/elflint.c:3229
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"
+msgstr ""
+
+#: src/elflint.c:3238
+#, c-format
+msgid "section [%2d] '%s': offset %zu: truncated attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3247
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3260
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"
+msgstr ""
+
+#: src/elflint.c:3271
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3289
+#, c-format
+msgid "section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"
+msgstr ""
+
+#: src/elflint.c:3300
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unterminated string in attribute\n"
+msgstr ""
+
+#: src/elflint.c:3313
+#, c-format
+msgid "section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"
+msgstr ""
+
+#: src/elflint.c:3317
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: unrecognized %s attribute value %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3327
+#, c-format
+msgid "section [%2d] '%s': offset %zu: vendor '%s' unknown\n"
+msgstr ""
+
+#: src/elflint.c:3333
+#, c-format
+msgid ""
+"section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"
+msgstr ""
+
+#: src/elflint.c:3422
+#, c-format
+msgid "cannot get section header of zeroth section\n"
+msgstr ""
+
+#: src/elflint.c:3426
+#, c-format
+msgid "zeroth section has nonzero name\n"
+msgstr ""
+
+#: src/elflint.c:3428
+#, c-format
+msgid "zeroth section has nonzero type\n"
+msgstr ""
+
+#: src/elflint.c:3430
+#, c-format
+msgid "zeroth section has nonzero flags\n"
+msgstr ""
+
+#: src/elflint.c:3432
+#, c-format
+msgid "zeroth section has nonzero address\n"
+msgstr ""
+
+#: src/elflint.c:3434
+#, c-format
+msgid "zeroth section has nonzero offset\n"
+msgstr ""
+
+#: src/elflint.c:3436
+#, c-format
+msgid "zeroth section has nonzero align value\n"
+msgstr ""
+
+#: src/elflint.c:3438
+#, c-format
+msgid "zeroth section has nonzero entry size value\n"
+msgstr ""
+
+#: src/elflint.c:3441
+#, c-format
+msgid ""
+"zeroth section has nonzero size value while ELF header has nonzero shnum "
+"value\n"
+msgstr ""
+
+#: src/elflint.c:3445
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in shstrndx\n"
+msgstr ""
+
+#: src/elflint.c:3449
+#, c-format
+msgid ""
+"zeroth section has nonzero link value while ELF header does not signal "
+"overflow in phnum\n"
+msgstr ""
+
+#: src/elflint.c:3466
+#, c-format
+msgid "cannot get section header for section [%2zu] '%s': %s\n"
+msgstr ""
+
+#: src/elflint.c:3475
+#, c-format
+msgid "section [%2zu]: invalid name\n"
+msgstr ""
+
+#: src/elflint.c:3502
+#, c-format
+msgid "section [%2d] '%s' has wrong type: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3518
+#, c-format
+msgid "section [%2zu] '%s' has wrong flags: expected %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3535
+#, c-format
+msgid ""
+"section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"
+msgstr ""
+
+#: src/elflint.c:3553
+#, c-format
+msgid "section [%2zu] '%s' present in object file\n"
+msgstr ""
+
+#: src/elflint.c:3559 src/elflint.c:3591
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"
+msgstr ""
+
+#: src/elflint.c:3564 src/elflint.c:3596
+#, c-format
+msgid ""
+"section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable "
+"segments\n"
+msgstr ""
+
+#: src/elflint.c:3572
+#, c-format
+msgid ""
+"section [%2zu] '%s' is extension section index table in non-object file\n"
+msgstr ""
+
+#: src/elflint.c:3615
+#, c-format
+msgid "section [%2zu] '%s': size not multiple of entry size\n"
+msgstr ""
+
+#: src/elflint.c:3620
+#, c-format
+msgid "cannot get section header\n"
+msgstr ""
+
+#: src/elflint.c:3630
+#, c-format
+msgid "section [%2zu] '%s' has unsupported type %d\n"
+msgstr ""
+
+#: src/elflint.c:3644
+#, c-format
+msgid ""
+"section [%2zu] '%s' contains invalid processor-specific flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3651
+#, c-format
+msgid "section [%2zu] '%s' contains unknown flag(s) %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:3659
+#, c-format
+msgid "section [%2zu] '%s': thread-local data sections address not zero\n"
+msgstr ""
+
+#: src/elflint.c:3667
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in link value\n"
+msgstr ""
+
+#: src/elflint.c:3672
+#, c-format
+msgid "section [%2zu] '%s': invalid section reference in info value\n"
+msgstr ""
+
+#: src/elflint.c:3679
+#, c-format
+msgid "section [%2zu] '%s': strings flag set without merge flag\n"
+msgstr ""
+
+#: src/elflint.c:3684
+#, c-format
+msgid "section [%2zu] '%s': merge flag set but entry size is zero\n"
+msgstr ""
+
+#: src/elflint.c:3702
+#, c-format
+msgid "section [%2zu] '%s' has unexpected type %d for an executable section\n"
+msgstr ""
+
+#: src/elflint.c:3711
+#, c-format
+msgid "section [%2zu] '%s' is both executable and writable\n"
+msgstr ""
+
+#: src/elflint.c:3738
+#, c-format
+msgid ""
+"section [%2zu] '%s' not fully contained in segment of program header entry %"
+"d\n"
+msgstr ""
+
+#: src/elflint.c:3746
+#, c-format
+msgid ""
+"section [%2zu] '%s' has type NOBITS but is read from the file in segment of "
+"program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:3755
+#, c-format
+msgid ""
+"section [%2zu] '%s' has not type NOBITS but is not read from the file in "
+"segment of program header entry %d\n"
+msgstr ""
+
+#: src/elflint.c:3766
+#, c-format
+msgid "section [%2zu] '%s' is executable in nonexecutable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:3776
+#, c-format
+msgid "section [%2zu] '%s' is writable in unwritable segment %d\n"
+msgstr ""
+
+#: src/elflint.c:3786
+#, c-format
+msgid ""
+"section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:3792
+#, c-format
+msgid ""
+"section [%2zu] '%s': ELF header says this is the section header string table "
+"but type is not SHT_TYPE\n"
+msgstr ""
+
+#: src/elflint.c:3800
+#, c-format
+msgid ""
+"section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"
+msgstr ""
+
+#: src/elflint.c:3851
+#, c-format
+msgid "more than one version symbol table present\n"
+msgstr ""
+
+#: src/elflint.c:3874
+#, c-format
+msgid "INTERP program header entry but no .interp section\n"
+msgstr ""
+
+#: src/elflint.c:3885
+#, c-format
+msgid ""
+"loadable segment [%u] is executable but contains no executable sections\n"
+msgstr ""
+
+#: src/elflint.c:3891
+#, c-format
+msgid "loadable segment [%u] is writable but contains no writable sections\n"
+msgstr ""
+
+#: src/elflint.c:3902
+#, c-format
+msgid ""
+"no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section "
+"exist\n"
+msgstr ""
+
+#: src/elflint.c:3915
+#, c-format
+msgid "duplicate version index %d\n"
+msgstr ""
+
+#: src/elflint.c:3929
+#, c-format
+msgid ".gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"
+msgstr ""
+
+#: src/elflint.c:3978
+#, c-format
+msgid "phdr[%d]: unknown core file note type %<PRIu32> at offset %<PRIu64>\n"
+msgstr ""
+
+#: src/elflint.c:3982
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown core file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4005
+#, c-format
+msgid "phdr[%d]: unknown object file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4009
+#, c-format
+msgid ""
+"section [%2d] '%s': unknown object file note type %<PRIu32> at offset %Zu\n"
+msgstr ""
+
+#: src/elflint.c:4026
+#, c-format
+msgid "phdr[%d]: no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4045
+#, c-format
+msgid "phdr[%d]: cannot get content of note section: %s\n"
+msgstr ""
+
+#: src/elflint.c:4048
+#, c-format
+msgid "phdr[%d]: extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4069
+#, c-format
+msgid "section [%2d] '%s': no note entries defined for the type of file\n"
+msgstr ""
+
+#: src/elflint.c:4076
+#, c-format
+msgid "section [%2d] '%s': cannot get content of note section\n"
+msgstr ""
+
+#: src/elflint.c:4079
+#, c-format
+msgid "section [%2d] '%s': extra %<PRIu64> bytes after last note\n"
+msgstr ""
+
+#: src/elflint.c:4097
+#, c-format
+msgid ""
+"only executables, shared objects, and core files can have program headers\n"
+msgstr ""
+
+#: src/elflint.c:4112
+#, c-format
+msgid "cannot get program header entry %d: %s\n"
+msgstr ""
+
+#: src/elflint.c:4121
+#, c-format
+msgid "program header entry %d: unknown program header entry type %#<PRIx64>\n"
+msgstr ""
+
+#: src/elflint.c:4132
+#, c-format
+msgid "more than one INTERP entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4140
+#, c-format
+msgid "more than one TLS entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4147
+#, c-format
+msgid "static executable cannot have dynamic sections\n"
+msgstr ""
+
+#: src/elflint.c:4161
+#, c-format
+msgid "dynamic section reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4164
+#, c-format
+msgid "dynamic section size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4174
+#, c-format
+msgid "more than one GNU_RELRO entry in program header\n"
+msgstr ""
+
+#: src/elflint.c:4195
+#, c-format
+msgid "loadable segment GNU_RELRO applies to is not writable\n"
+msgstr ""
+
+#: src/elflint.c:4198
+#, c-format
+msgid "loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"
+msgstr ""
+
+#: src/elflint.c:4206 src/elflint.c:4229
+#, c-format
+msgid "%s segment not contained in a loaded segment\n"
+msgstr ""
+
+#: src/elflint.c:4235
+#, c-format
+msgid "program header offset in ELF header and PHDR entry do not match"
+msgstr ""
+
+#: src/elflint.c:4259
+#, c-format
+msgid "call frame search table reference in program header has wrong offset\n"
+msgstr ""
+
+#: src/elflint.c:4262
+#, c-format
+msgid "call frame search table size mismatch in program and section header\n"
+msgstr ""
+
+#: src/elflint.c:4275
+#, c-format
+msgid "PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"
+msgstr ""
+
+#: src/elflint.c:4283
+#, c-format
+msgid "call frame search table must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4286
+#, c-format
+msgid "section [%2zu] '%s' must be allocated\n"
+msgstr ""
+
+#: src/elflint.c:4290
+#, c-format
+msgid "call frame search table must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4293
+#, c-format
+msgid "section [%2zu] '%s' must not be writable\n"
+msgstr ""
+
+#: src/elflint.c:4298
+#, c-format
+msgid "call frame search table must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4301
+#, c-format
+msgid "section [%2zu] '%s' must not be executable\n"
+msgstr ""
+
+#: src/elflint.c:4312
+#, c-format
+msgid "program header entry %d: file size greater than memory size\n"
+msgstr ""
+
+#: src/elflint.c:4319
+#, c-format
+msgid "program header entry %d: alignment not a power of 2\n"
+msgstr ""
+
+#: src/elflint.c:4322
+#, c-format
+msgid ""
+"program header entry %d: file offset and virtual address not module of "
+"alignment\n"
+msgstr ""
+
+#: src/elflint.c:4335
+#, c-format
+msgid ""
+"executable/DSO with .eh_frame_hdr section does not have a PT_GNU_EH_FRAME "
+"program header entry"
+msgstr ""
+
+#: src/elflint.c:4369
+#, c-format
+msgid "cannot read ELF header: %s\n"
+msgstr ""
+
+#: src/elflint.c:4395
+#, c-format
+msgid "text relocation flag set but not needed\n"
+msgstr ""
+
+#: src/findtextrel.c:70
+msgid "Input Selection:"
+msgstr ""
+
+#: src/findtextrel.c:71
+msgid "Prepend PATH to all file names"
+msgstr ""
+
+#: src/findtextrel.c:73
+msgid "Use PATH as root of debuginfo hierarchy"
+msgstr ""
+
+#: src/findtextrel.c:80
+msgid "Locate source of text relocations in FILEs (a.out by default)."
+msgstr ""
+
+#: src/findtextrel.c:84 src/nm.c:111 src/objdump.c:80 src/size.c:92
+#: src/strings.c:92 src/strip.c:97
+msgid "[FILE...]"
+msgstr ""
+
+#: src/findtextrel.c:246
+#, c-format
+msgid "cannot get ELF header '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:257
+#, c-format
+msgid "'%s' is not a DSO or PIE"
+msgstr ""
+
+#: src/findtextrel.c:274
+#, c-format
+msgid "getting get section header of section %zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:292
+#, c-format
+msgid "cannot read dynamic section: %s"
+msgstr ""
+
+#: src/findtextrel.c:307
+#, c-format
+msgid "no text relocations reported in '%s'"
+msgstr ""
+
+#: src/findtextrel.c:319
+#, c-format
+msgid "while reading ELF file"
+msgstr ""
+
+#: src/findtextrel.c:328 src/findtextrel.c:345
+#, c-format
+msgid "cannot get program header index at offset %d: %s"
+msgstr ""
+
+#: src/findtextrel.c:397
+#, c-format
+msgid "cannot get section header of section %Zu: %s"
+msgstr ""
+
+#: src/findtextrel.c:409
+#, c-format
+msgid "cannot get symbol table section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:429 src/findtextrel.c:452
+#, c-format
+msgid "cannot get relocation at index %d in section %zu in '%s': %s"
+msgstr ""
+
+#: src/findtextrel.c:517
+#, c-format
+msgid "%s not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:570
+#, c-format
+msgid ""
+"the file containing the function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:577 src/findtextrel.c:597
+#, c-format
+msgid ""
+"the file containing the function '%s' might not be compiled with -fpic/-"
+"fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:585
+#, c-format
+msgid ""
+"either the file containing the function '%s' or the file containing the "
+"function '%s' is not compiled with -fpic/-fPIC\n"
+msgstr ""
+
+#: src/findtextrel.c:605
+#, c-format
+msgid ""
+"a relocation modifies memory at offset %llu in a write-protected segment\n"
+msgstr ""
+
+#: src/i386_ld.c:210
+#, c-format
+msgid "cannot allocate PLT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:232
+#, c-format
+msgid "cannot allocate PLTREL section: %s"
+msgstr ""
+
+#: src/i386_ld.c:253
+#, c-format
+msgid "cannot allocate GOT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:274
+#, c-format
+msgid "cannot allocate GOTPLT section: %s"
+msgstr ""
+
+#: src/i386_ld.c:661
+#, c-format
+msgid "initial-executable TLS relocation cannot be used "
+msgstr ""
+
+#: src/ld.c:87
+msgid "Input File Control:"
+msgstr ""
+
+#: src/ld.c:89
+msgid "Include whole archives in the output from now on."
+msgstr ""
+
+#: src/ld.c:91
+msgid "Stop including the whole archives in the output."
+msgstr ""
+
+#: src/ld.c:92 src/ld.c:106 src/ld.c:184
+msgid "FILE"
+msgstr ""
+
+#: src/ld.c:93
+msgid "Start a group."
+msgstr ""
+
+#: src/ld.c:94
+msgid "End a group."
+msgstr ""
+
+#: src/ld.c:95
+msgid "PATH"
+msgstr ""
+
+#: src/ld.c:96
+msgid "Add PATH to list of directories files are searched in."
+msgstr ""
+
+#: src/ld.c:98
+msgid "Only set DT_NEEDED for following dynamic libs if actually used"
+msgstr ""
+
+#: src/ld.c:100
+msgid "Always set DT_NEEDED for following dynamic libs"
+msgstr ""
+
+#: src/ld.c:102
+msgid "Ignore LD_LIBRARY_PATH environment variable."
+msgstr ""
+
+#: src/ld.c:105
+msgid "Output File Control:"
+msgstr ""
+
+#: src/ld.c:106
+msgid "Place output in FILE."
+msgstr ""
+
+#: src/ld.c:109
+msgid "Object is marked to not use default search path at runtime."
+msgstr ""
+
+#: src/ld.c:111
+msgid "Same as --whole-archive."
+msgstr ""
+
+#: src/ld.c:112
+msgid ""
+"Default rules of extracting from archive; weak references are not enough."
+msgstr ""
+
+#: src/ld.c:116
+msgid "Weak references cause extraction from archive."
+msgstr ""
+
+#: src/ld.c:118
+msgid "Allow multiple definitions; first is used."
+msgstr ""
+
+#: src/ld.c:120
+msgid "Disallow/allow undefined symbols in DSOs."
+msgstr ""
+
+#: src/ld.c:123
+msgid "Object requires immediate handling of $ORIGIN."
+msgstr ""
+
+#: src/ld.c:125
+msgid "Relocation will not be processed lazily."
+msgstr ""
+
+#: src/ld.c:127
+msgid "Object cannot be unloaded at runtime."
+msgstr ""
+
+#: src/ld.c:129
+msgid "Mark object to be initialized first."
+msgstr ""
+
+#: src/ld.c:131
+msgid "Enable/disable lazy-loading flag for following dependencies."
+msgstr ""
+
+#: src/ld.c:133
+msgid "Mark object as not loadable with 'dlopen'."
+msgstr ""
+
+#: src/ld.c:135
+msgid "Ignore/record dependencies on unused DSOs."
+msgstr ""
+
+#: src/ld.c:137
+msgid "Generated DSO will be a system library."
+msgstr ""
+
+#: src/ld.c:138
+msgid "ADDRESS"
+msgstr ""
+
+#: src/ld.c:138
+msgid "Set entry point address."
+msgstr ""
+
+#: src/ld.c:141
+msgid "Do not link against shared libraries."
+msgstr ""
+
+#: src/ld.c:144
+msgid "Prefer linking against shared libraries."
+msgstr ""
+
+#: src/ld.c:145
+msgid "Export all dynamic symbols."
+msgstr ""
+
+#: src/ld.c:146
+msgid "Strip all symbols."
+msgstr ""
+
+#: src/ld.c:147
+msgid "Strip debugging symbols."
+msgstr ""
+
+#: src/ld.c:149
+msgid "Assume pagesize for the target system to be SIZE."
+msgstr ""
+
+#: src/ld.c:151
+msgid "Set runtime DSO search path."
+msgstr ""
+
+#: src/ld.c:154
+msgid "Set link time DSO search path."
+msgstr ""
+
+#: src/ld.c:155
+msgid "Generate dynamic shared object."
+msgstr ""
+
+#: src/ld.c:156
+msgid "Generate relocatable object."
+msgstr ""
+
+#: src/ld.c:159
+msgid "Causes symbol not assigned to a version be reduced to local."
+msgstr ""
+
+#: src/ld.c:160
+msgid "Remove unused sections."
+msgstr ""
+
+#: src/ld.c:163
+msgid "Don't remove unused sections."
+msgstr ""
+
+#: src/ld.c:164
+msgid "Set soname of shared object."
+msgstr ""
+
+#: src/ld.c:165
+msgid "Set the dynamic linker name."
+msgstr ""
+
+#: src/ld.c:168
+msgid "Add/suppress addition indentifying link-editor to .comment section."
+msgstr ""
+
+#: src/ld.c:171
+msgid "Create .eh_frame_hdr section"
+msgstr ""
+
+#: src/ld.c:173
+msgid "Set hash style to sysv, gnu or both."
+msgstr ""
+
+#: src/ld.c:175
+msgid "Generate build ID note (md5, sha1 (default), uuid)."
+msgstr ""
+
+#: src/ld.c:177
+msgid "Linker Operation Control:"
+msgstr ""
+
+#: src/ld.c:178
+msgid "Verbose messages."
+msgstr ""
+
+#: src/ld.c:179
+msgid "Trace file opens."
+msgstr ""
+
+#: src/ld.c:181
+msgid "Trade speed for less memory usage"
+msgstr ""
+
+#: src/ld.c:182
+msgid "LEVEL"
+msgstr ""
+
+#: src/ld.c:183
+msgid "Set optimization level to LEVEL."
+msgstr ""
+
+#: src/ld.c:184
+msgid "Use linker script in FILE."
+msgstr ""
+
+#: src/ld.c:187
+msgid "Select to get parser debug information"
+msgstr ""
+
+#: src/ld.c:190
+msgid "Read version information from FILE."
+msgstr ""
+
+#: src/ld.c:191
+msgid "Set emulation to NAME."
+msgstr ""
+
+#: src/ld.c:197
+msgid "Combine object and archive files."
+msgstr ""
+
+#: src/ld.c:200
+msgid "[FILE]..."
+msgstr ""
+
+#: src/ld.c:333
+#, c-format
+msgid "At least one input file needed"
+msgstr ""
+
+#: src/ld.c:349
+#, c-format
+msgid "error while preparing linking"
+msgstr ""
+
+#: src/ld.c:356
+#, c-format
+msgid "cannot open linker script '%s'"
+msgstr ""
+
+#: src/ld.c:397
+#, c-format
+msgid "-( without matching -)"
+msgstr ""
+
+#: src/ld.c:572 src/ld.c:610
+#, c-format
+msgid "only one option of -G and -r is allowed"
+msgstr ""
+
+#: src/ld.c:594
+#, c-format
+msgid "more than one '-m' parameter"
+msgstr ""
+
+#: src/ld.c:604 src/ld.c:1013
+#, c-format
+msgid "unknown option `-%c %s'"
+msgstr ""
+
+#: src/ld.c:646
+#, c-format
+msgid "invalid page size value '%s': ignored"
+msgstr ""
+
+#: src/ld.c:687
+#, c-format
+msgid "invalid hash style '%s'"
+msgstr ""
+
+#: src/ld.c:697
+#, c-format
+msgid "invalid build-ID style '%s'"
+msgstr ""
+
+#: src/ld.c:785
+#, c-format
+msgid "More than one output file name given."
+msgstr ""
+
+#: src/ld.c:802
+#, c-format
+msgid "Invalid optimization level `%s'"
+msgstr ""
+
+#: src/ld.c:850
+#, c-format
+msgid "nested -( -) groups are not allowed"
+msgstr ""
+
+#: src/ld.c:869
+#, c-format
+msgid "-) without matching -("
+msgstr ""
+
+#: src/ld.c:1046
+#, c-format
+msgid "unknown option '-%c %s'"
+msgstr ""
+
+#: src/ld.c:1150
+#, c-format
+msgid "could not find input file to determine output file format"
+msgstr ""
+
+#: src/ld.c:1152
+#, c-format
+msgid "try again with an appropriate '-m' parameter"
+msgstr ""
+
+#: src/ld.c:1446
+#, c-format
+msgid "cannot read version script '%s'"
+msgstr ""
+
+#: src/ld.c:1512 src/ld.c:1551
+#, c-format
+msgid "duplicate definition of '%s' in linker script"
+msgstr ""
+
+#: src/ldgeneric.c:209 src/ldgeneric.c:5151
+#, c-format
+msgid "cannot create string table"
+msgstr ""
+
+#: src/ldgeneric.c:255
+#, c-format
+msgid "cannot load ld backend library '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:265
+#, c-format
+msgid "cannot find init function in ld backend library '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:310
+#, c-format
+msgid "%s listed more than once as input"
+msgstr ""
+
+#: src/ldgeneric.c:424
+#, c-format
+msgid "%s (for -l%s)\n"
+msgstr ""
+
+#: src/ldgeneric.c:425
+#, c-format
+msgid "%s (for DT_NEEDED %s)\n"
+msgstr ""
+
+#: src/ldgeneric.c:573
+#, c-format
+msgid "Warning: type of `%s' changed from %s in %s to %s in %s"
+msgstr ""
+
+#: src/ldgeneric.c:586
+#, c-format
+msgid "Warning: size of `%s' changed from %<PRIu64> in %s to %<PRIu64> in %s"
+msgstr ""
+
+#: src/ldgeneric.c:661 src/ldgeneric.c:1122 src/readelf.c:629 src/strip.c:543
+#, c-format
+msgid "cannot determine number of sections: %s"
+msgstr ""
+
+#: src/ldgeneric.c:677
+#, c-format
+msgid "(%s+%#<PRIx64>): multiple definition of %s `%s'\n"
+msgstr ""
+
+#: src/ldgeneric.c:700
+#, c-format
+msgid "(%s+%#<PRIx64>): first defined here\n"
+msgstr ""
+
+#: src/ldgeneric.c:819
+#, c-format
+msgid "%s: cannot get section group data: %s"
+msgstr ""
+
+#: src/ldgeneric.c:840
+#, c-format
+msgid "%s: section '%s' with group flag set does not belong to any group"
+msgstr ""
+
+#: src/ldgeneric.c:885
+#, c-format
+msgid "%s: section [%2d] '%s' is not in the correct section group"
+msgstr ""
+
+#: src/ldgeneric.c:1156 src/ldgeneric.c:1413 src/ldgeneric.c:1422
+#: src/ldgeneric.c:1481 src/ldgeneric.c:1490 src/ldgeneric.c:1753
+#: src/ldgeneric.c:2005
+#, c-format
+msgid "%s: invalid ELF file (%s:%d)\n"
+msgstr ""
+
+#: src/ldgeneric.c:1250
+#, c-format
+msgid "%s: only files of type ET_REL might contain section groups"
+msgstr ""
+
+#: src/ldgeneric.c:1302
+#, c-format
+msgid "%s: cannot determine signature of section group [%2zd] '%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:1314
+#, c-format
+msgid "%s: cannot get content of section group [%2zd] '%s': %s'"
+msgstr ""
+
+#: src/ldgeneric.c:1328
+#, c-format
+msgid ""
+"%s: group member %zu of section group [%2zd] '%s' has too high index: %"
+"<PRIu32>"
+msgstr ""
+
+#: src/ldgeneric.c:1350
+#, c-format
+msgid "%s: section '%s' has unknown type: %d"
+msgstr ""
+
+#: src/ldgeneric.c:1729
+#, c-format
+msgid "cannot get descriptor for ELF file (%s:%d): %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:1899
+#, c-format
+msgid "cannot read archive `%s': %s"
+msgstr ""
+
+#: src/ldgeneric.c:2020
+#, c-format
+msgid "file of type %s cannot be linked in\n"
+msgstr ""
+
+#: src/ldgeneric.c:2032
+#, c-format
+msgid "%s: input file incompatible with ELF machine type %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:2044
+#, c-format
+msgid "%s: cannot get section header string table index: %s\n"
+msgstr ""
+
+#: src/ldgeneric.c:2073
+#, c-format
+msgid "cannot use DSO '%s' when generating relocatable object file"
+msgstr ""
+
+#: src/ldgeneric.c:2158
+#, c-format
+msgid "input file '%s' ignored"
+msgstr ""
+
+#: src/ldgeneric.c:2372
+#, c-format
+msgid "undefined symbol `%s' in %s"
+msgstr ""
+
+#: src/ldgeneric.c:2702
+#, c-format
+msgid "cannot create ELF descriptor for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:2709
+#, c-format
+msgid "could not create ELF header for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:3224 src/ldgeneric.c:3294 src/ldgeneric.c:3330
+#: src/ldgeneric.c:4457 src/ldgeneric.c:4506 src/ldgeneric.c:4538
+#: src/ldgeneric.c:4773 src/ldgeneric.c:4828 src/ldgeneric.c:5075
+#: src/ldgeneric.c:5131 src/ldgeneric.c:5600 src/ldgeneric.c:5612
+#, c-format
+msgid "cannot create section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:3444
+#, c-format
+msgid "address computation expression contains variable '%s'"
+msgstr ""
+
+#: src/ldgeneric.c:3489
+#, c-format
+msgid ""
+"argument '%<PRIuMAX>' of ALIGN in address computation expression is no power "
+"of two"
+msgstr ""
+
+#: src/ldgeneric.c:3684
+#, c-format
+msgid "cannot find entry symbol '%s': defaulting to %#0*<PRIx64>"
+msgstr ""
+
+#: src/ldgeneric.c:3690
+#, c-format
+msgid "no entry symbol specified: defaulting to %#0*<PRIx64>"
+msgstr ""
+
+#: src/ldgeneric.c:3920
+#, c-format
+msgid "cannot create GNU hash table section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4071
+#, c-format
+msgid "cannot create hash table section for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4114
+#, c-format
+msgid "cannot create build ID section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4191
+#, c-format
+msgid "cannot convert section data to file format: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4200
+#, c-format
+msgid "cannot convert section data to memory format: %s"
+msgstr ""
+
+#: src/ldgeneric.c:4261
+#, c-format
+msgid "cannot read enough data for UUID"
+msgstr ""
+
+#: src/ldgeneric.c:4358 src/ldgeneric.c:4379 src/ldgeneric.c:4408
+#: src/ldgeneric.c:6062
+#, c-format
+msgid "cannot create symbol table for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5300 src/ldgeneric.c:5852
+#, c-format
+msgid "section index too large in dynamic symbol table"
+msgstr ""
+
+#: src/ldgeneric.c:5745
+#, c-format
+msgid "cannot create versioning section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5818
+#, c-format
+msgid "cannot create dynamic symbol table for output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:5994
+#, c-format
+msgid "cannot create versioning data: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6094 src/ldgeneric.c:6107 src/ldgeneric.c:6171
+#: src/ldgeneric.c:6179
+#, c-format
+msgid "cannot create section header string section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6101
+#, c-format
+msgid "cannot create section header string section"
+msgstr ""
+
+#: src/ldgeneric.c:6259
+#, c-format
+msgid "cannot create program header: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6267
+#, c-format
+msgid "while determining file layout: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6388
+#, c-format
+msgid "internal error: non-nobits section follows nobits section"
+msgstr ""
+
+#: src/ldgeneric.c:6925
+#, c-format
+msgid "cannot get header of 0th section: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6941 src/unstrip.c:1808
+#, c-format
+msgid "cannot update ELF header: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6972
+#, c-format
+msgid "linker backend didn't specify function to relocate section"
+msgstr ""
+
+#: src/ldgeneric.c:6984
+#, c-format
+msgid "while writing output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6989
+#, c-format
+msgid "while finishing output file: %s"
+msgstr ""
+
+#: src/ldgeneric.c:6995
+#, c-format
+msgid "cannot stat output file"
+msgstr ""
+
+#: src/ldgeneric.c:7011
+#, c-format
+msgid "WARNING: temporary output file overwritten before linking finished"
+msgstr ""
+
+#: src/ldgeneric.c:7064 src/ldgeneric.c:7075 src/ldgeneric.c:7086
+#: src/ldgeneric.c:7097 src/ldgeneric.c:7116 src/ldgeneric.c:7129
+#: src/ldgeneric.c:7141
+#, c-format
+msgid "no machine specific '%s' implementation"
+msgstr ""
+
+#: src/ldscript.y:178
+msgid "mode for segment invalid\n"
+msgstr ""
+
+#: src/ldscript.y:465
+#, c-format
+msgid "while reading version script '%s': %s at line %d"
+msgstr ""
+
+#: src/ldscript.y:466
+#, c-format
+msgid "while reading linker script '%s': %s at line %d"
+msgstr ""
+
+#: src/ldscript.y:745
+#, c-format
+msgid "symbol '%s' is declared both local and global for unnamed version"
+msgstr ""
+
+#: src/ldscript.y:747
+#, c-format
+msgid "symbol '%s' is declared both local and global for version '%s'"
+msgstr ""
+
+#: src/ldscript.y:767 src/ldscript.y:774
+#, c-format
+msgid "default visibility set as local and global"
+msgstr ""
+
+#: src/nm.c:74 src/strip.c:73
+msgid "Output selection:"
+msgstr ""
+
+#: src/nm.c:75
+msgid "Display debugger-only symbols"
+msgstr ""
+
+#: src/nm.c:76
+msgid "Display only defined symbols"
+msgstr ""
+
+#: src/nm.c:79
+msgid "Display dynamic symbols instead of normal symbols"
+msgstr ""
+
+#: src/nm.c:80
+msgid "Display only external symbols"
+msgstr ""
+
+#: src/nm.c:81
+msgid "Display only undefined symbols"
+msgstr ""
+
+#: src/nm.c:83
+msgid "Include index for symbols from archive members"
+msgstr ""
+
+#: src/nm.c:85 src/size.c:66
+msgid "Output format:"
+msgstr ""
+
+#: src/nm.c:87
+msgid "Print name of the input file before every symbol"
+msgstr ""
+
+#: src/nm.c:90
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd', `sysv' or `posix'.  The "
+"default is `sysv'"
+msgstr ""
+
+#: src/nm.c:92
+msgid "Same as --format=bsd"
+msgstr ""
+
+#: src/nm.c:93
+msgid "Same as --format=posix"
+msgstr ""
+
+#: src/nm.c:94 src/size.c:72
+msgid "Use RADIX for printing symbol values"
+msgstr ""
+
+#: src/nm.c:95
+msgid "Mark weak symbols"
+msgstr ""
+
+#: src/nm.c:96
+msgid "Print size of defined symbols"
+msgstr ""
+
+#: src/nm.c:98 src/size.c:80 src/strip.c:78 src/unstrip.c:81
+msgid "Output options:"
+msgstr ""
+
+#: src/nm.c:99
+msgid "Sort symbols numerically by address"
+msgstr ""
+
+#: src/nm.c:101
+msgid "Do not sort the symbols"
+msgstr ""
+
+#: src/nm.c:102
+msgid "Reverse the sense of the sort"
+msgstr ""
+
+#: src/nm.c:108
+msgid "List symbols from FILEs (a.out by default)."
+msgstr ""
+
+#: src/nm.c:136 src/objdump.c:105 src/size.c:117 src/strip.c:121
+#, c-format
+msgid "%s: INTERNAL ERROR %d (%s-%s): %s"
+msgstr ""
+
+#: src/nm.c:380 src/nm.c:392 src/size.c:317 src/size.c:326 src/size.c:337
+#: src/strip.c:1816
+#, c-format
+msgid "while closing '%s'"
+msgstr ""
+
+#: src/nm.c:402 src/objdump.c:296 src/strip.c:359
+#, c-format
+msgid "%s: File format not recognized"
+msgstr ""
+
+#: src/nm.c:442
+msgid ""
+"\n"
+"Archive index:"
+msgstr ""
+
+#: src/nm.c:451
+#, c-format
+msgid "invalid offset %zu for symbol %s"
+msgstr ""
+
+#: src/nm.c:456
+#, c-format
+msgid "%s in %s\n"
+msgstr ""
+
+#: src/nm.c:464
+#, c-format
+msgid "cannot reset archive offset to beginning"
+msgstr ""
+
+#: src/nm.c:488 src/objdump.c:344
+#, c-format
+msgid "%s%s%s: file format not recognized"
+msgstr ""
+
+#: src/nm.c:700
+#, c-format
+msgid "cannot create search tree"
+msgstr ""
+
+#: src/nm.c:740 src/nm.c:1002 src/objdump.c:744 src/readelf.c:885
+#: src/readelf.c:1028 src/readelf.c:1169 src/readelf.c:1351 src/readelf.c:1549
+#: src/readelf.c:1735 src/readelf.c:1945 src/readelf.c:2199 src/readelf.c:2265
+#: src/readelf.c:2343 src/readelf.c:2841 src/readelf.c:2877 src/readelf.c:2939
+#: src/readelf.c:6493 src/readelf.c:7387 src/readelf.c:7534 src/readelf.c:7604
+#: src/size.c:425 src/size.c:499 src/strip.c:483
+#, c-format
+msgid "cannot get section header string table index"
+msgstr ""
+
+#: src/nm.c:766
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s:\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:768
+#, c-format
+msgid ""
+"\n"
+"\n"
+"Symbols from %s[%s]:\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:771
+#, c-format
+msgid ""
+"%*s%-*s %-*s Class  Type     %-*s %*s Section\n"
+"\n"
+msgstr ""
+
+#: src/nm.c:1012
+#, c-format
+msgid "%s: entry size in section `%s' is not what we expect"
+msgstr ""
+
+#: src/nm.c:1016
+#, c-format
+msgid "%s: size of section `%s' is not multiple of entry size"
+msgstr ""
+
+#: src/nm.c:1255
+#, c-format
+msgid "%s%s%s%s: Invalid operation"
+msgstr ""
+
+#: src/nm.c:1312
+#, c-format
+msgid "%s%s%s: no symbols"
+msgstr ""
+
+#: src/objdump.c:61
+msgid "Mode selection:"
+msgstr ""
+
+#: src/objdump.c:62
+msgid "Display relocation information."
+msgstr ""
+
+#: src/objdump.c:64
+msgid "Display the full contents of all sections requested"
+msgstr ""
+
+#: src/objdump.c:66
+msgid "Display assembler code of executable sections"
+msgstr ""
+
+#: src/objdump.c:68
+msgid "Output option selection:"
+msgstr ""
+
+#: src/objdump.c:70
+msgid "Only display information for section NAME."
+msgstr ""
+
+#: src/objdump.c:76
+msgid "Show information from FILEs (a.out by default)."
+msgstr ""
+
+#: src/objdump.c:236 src/readelf.c:430
+msgid "No operation specified.\n"
+msgstr ""
+
+#: src/objdump.c:274 src/objdump.c:286
+#, c-format
+msgid "while close `%s'"
+msgstr ""
+
+#: src/objdump.c:379 src/readelf.c:1644 src/readelf.c:1818
+msgid "INVALID SYMBOL"
+msgstr ""
+
+#: src/objdump.c:394 src/readelf.c:1675 src/readelf.c:1851
+msgid "INVALID SECTION"
+msgstr ""
+
+#: src/objdump.c:510
+#, c-format
+msgid ""
+"\n"
+"RELOCATION RECORDS FOR [%s]:\n"
+"%-*s TYPE                 VALUE\n"
+msgstr ""
+
+#: src/objdump.c:513
+msgid "OFFSET"
+msgstr ""
+
+#: src/objdump.c:576
+#, c-format
+msgid "Contents of section %s:\n"
+msgstr ""
+
+#: src/objdump.c:676
+#, c-format
+msgid "cannot disassemble"
+msgstr ""
+
+#: src/ranlib.c:74
+msgid "Generate an index to speed access to archives."
+msgstr ""
+
+#: src/ranlib.c:77
+msgid "ARCHIVE"
+msgstr ""
+
+#: src/ranlib.c:116
+#, c-format
+msgid "Archive name required"
+msgstr ""
+
+#: src/ranlib.c:194
+#, c-format
+msgid "'%s' is no archive"
+msgstr ""
+
+#: src/ranlib.c:229
+#, c-format
+msgid "error while freeing sub-ELF descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:73
+msgid "ELF output selection:"
+msgstr ""
+
+#: src/readelf.c:75
+msgid "All these plus -p .strtab -p .dynstr -p .comment"
+msgstr ""
+
+#: src/readelf.c:76
+msgid "Display the dynamic segment"
+msgstr ""
+
+#: src/readelf.c:77
+msgid "Display the ELF file header"
+msgstr ""
+
+#: src/readelf.c:79
+msgid "Display histogram of bucket list lengths"
+msgstr ""
+
+#: src/readelf.c:80
+msgid "Display the program headers"
+msgstr ""
+
+#: src/readelf.c:82
+msgid "Display relocations"
+msgstr ""
+
+#: src/readelf.c:83
+msgid "Display the sections' headers"
+msgstr ""
+
+#: src/readelf.c:85
+msgid "Display the symbol table"
+msgstr ""
+
+#: src/readelf.c:86
+msgid "Display versioning information"
+msgstr ""
+
+#: src/readelf.c:87
+msgid "Display the ELF notes"
+msgstr ""
+
+#: src/readelf.c:89
+msgid "Display architecture specific information, if any"
+msgstr ""
+
+#: src/readelf.c:91
+msgid "Display sections for exception handling"
+msgstr ""
+
+#: src/readelf.c:93
+msgid "Additional output selection:"
+msgstr ""
+
+#: src/readelf.c:95
+msgid ""
+"Display DWARF section content.  SECTION can be one of abbrev, aranges, "
+"frame, info, loc, line, ranges, pubnames, str, macinfo, or exception"
+msgstr ""
+
+#: src/readelf.c:99
+msgid "Dump the uninterpreted contents of SECTION, by number or name"
+msgstr ""
+
+#: src/readelf.c:101
+msgid "Print string contents of sections"
+msgstr ""
+
+#: src/readelf.c:104
+msgid "Display the symbol index of an archive"
+msgstr ""
+
+#: src/readelf.c:106
+msgid "Output control:"
+msgstr ""
+
+#: src/readelf.c:108
+msgid "Do not find symbol names for addresses in DWARF data"
+msgstr ""
+
+#: src/readelf.c:114
+msgid "Print information from ELF file in human-readable form."
+msgstr ""
+
+#: src/readelf.c:401
+#, c-format
+msgid "Unknown DWARF debug section `%s'.\n"
+msgstr ""
+
+#: src/readelf.c:465
+#, c-format
+msgid "cannot generate Elf descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:477
+#, c-format
+msgid "'%s' is not an archive, cannot print archive index"
+msgstr ""
+
+#: src/readelf.c:482
+#, c-format
+msgid "error while closing Elf descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:574
+#, c-format
+msgid "cannot stat input file"
+msgstr ""
+
+#: src/readelf.c:576
+#, c-format
+msgid "input file is empty"
+msgstr ""
+
+#: src/readelf.c:578
+#, c-format
+msgid "failed reading '%s': %s"
+msgstr ""
+
+#: src/readelf.c:614
+#, c-format
+msgid "cannot read ELF header: %s"
+msgstr ""
+
+#: src/readelf.c:622
+#, c-format
+msgid "cannot create EBL handle"
+msgstr ""
+
+#: src/readelf.c:635
+#, c-format
+msgid "cannot determine number of program headers: %s"
+msgstr ""
+
+#: src/readelf.c:721
+msgid "NONE (None)"
+msgstr ""
+
+#: src/readelf.c:722
+msgid "REL (Relocatable file)"
+msgstr ""
+
+#: src/readelf.c:723
+msgid "EXEC (Executable file)"
+msgstr ""
+
+#: src/readelf.c:724
+msgid "DYN (Shared object file)"
+msgstr ""
+
+#: src/readelf.c:725
+msgid "CORE (Core file)"
+msgstr ""
+
+#: src/readelf.c:730
+#, c-format
+msgid "OS Specific: (%x)\n"
+msgstr ""
+
+#: src/readelf.c:732
+#, c-format
+msgid "Processor Specific: (%x)\n"
+msgstr ""
+
+#: src/readelf.c:742
+msgid ""
+"ELF Header:\n"
+"  Magic:  "
+msgstr ""
+
+#: src/readelf.c:746
+#, c-format
+msgid ""
+"\n"
+"  Class:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:751
+#, c-format
+msgid "  Data:                              %s\n"
+msgstr ""
+
+#: src/readelf.c:757
+#, c-format
+msgid "  Ident Version:                     %hhd %s\n"
+msgstr ""
+
+#: src/readelf.c:759 src/readelf.c:776
+msgid "(current)"
+msgstr ""
+
+#: src/readelf.c:763
+#, c-format
+msgid "  OS/ABI:                            %s\n"
+msgstr ""
+
+#: src/readelf.c:766
+#, c-format
+msgid "  ABI Version:                       %hhd\n"
+msgstr ""
+
+#: src/readelf.c:769
+msgid "  Type:                              "
+msgstr ""
+
+#: src/readelf.c:772
+#, c-format
+msgid "  Machine:                           %s\n"
+msgstr ""
+
+#: src/readelf.c:774
+#, c-format
+msgid "  Version:                           %d %s\n"
+msgstr ""
+
+#: src/readelf.c:778
+#, c-format
+msgid "  Entry point address:               %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:781
+#, c-format
+msgid "  Start of program headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:782 src/readelf.c:785
+msgid "(bytes into file)"
+msgstr ""
+
+#: src/readelf.c:784
+#, c-format
+msgid "  Start of section headers:          %<PRId64> %s\n"
+msgstr ""
+
+#: src/readelf.c:787
+#, c-format
+msgid "  Flags:                             %s\n"
+msgstr ""
+
+#: src/readelf.c:790
+#, c-format
+msgid "  Size of this header:               %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:791 src/readelf.c:794 src/readelf.c:811
+msgid "(bytes)"
+msgstr ""
+
+#: src/readelf.c:793
+#, c-format
+msgid "  Size of program header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:796
+#, c-format
+msgid "  Number of program headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:803
+#, c-format
+msgid " (%<PRIu32> in [0].sh_info)"
+msgstr ""
+
+#: src/readelf.c:806 src/readelf.c:823 src/readelf.c:837
+msgid " ([0] not available)"
+msgstr ""
+
+#: src/readelf.c:810
+#, c-format
+msgid "  Size of section header entries:    %<PRId16> %s\n"
+msgstr ""
+
+#: src/readelf.c:813
+#, c-format
+msgid "  Number of section headers entries: %<PRId16>"
+msgstr ""
+
+#: src/readelf.c:820
+#, c-format
+msgid " (%<PRIu32> in [0].sh_size)"
+msgstr ""
+
+#: src/readelf.c:833
+#, c-format
+msgid " (%<PRIu32> in [0].sh_link)"
+msgstr ""
+
+#: src/readelf.c:841
+#, c-format
+msgid ""
+"  Section header string table index: XINDEX%s\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:845
+#, c-format
+msgid ""
+"  Section header string table index: %<PRId16>\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:877
+#, c-format
+msgid ""
+"There are %d section headers, starting at offset %#<PRIx64>:\n"
+"\n"
+msgstr ""
+
+#: src/readelf.c:887
+msgid "Section Headers:"
+msgstr ""
+
+#: src/readelf.c:890
+msgid ""
+"[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk "
+"Inf Al"
+msgstr ""
+
+#: src/readelf.c:892
+msgid ""
+"[Nr] Name                 Type         Addr             Off      Size     ES "
+"Flags Lk Inf Al"
+msgstr ""
+
+#: src/readelf.c:899 src/readelf.c:1052
+#, c-format
+msgid "cannot get section: %s"
+msgstr ""
+
+#: src/readelf.c:906 src/readelf.c:1060 src/readelf.c:7554 src/unstrip.c:353
+#: src/unstrip.c:377 src/unstrip.c:427 src/unstrip.c:536 src/unstrip.c:553
+#: src/unstrip.c:591 src/unstrip.c:789 src/unstrip.c:1057 src/unstrip.c:1244
+#: src/unstrip.c:1305 src/unstrip.c:1427 src/unstrip.c:1480 src/unstrip.c:1588
+#: src/unstrip.c:1778
+#, c-format
+msgid "cannot get section header: %s"
+msgstr ""
+
+#: src/readelf.c:964
+msgid "Program Headers:"
+msgstr ""
+
+#: src/readelf.c:966
+msgid ""
+"  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:969
+msgid ""
+"  Type           Offset   VirtAddr           PhysAddr           FileSiz  "
+"MemSiz   Flg Align"
+msgstr ""
+
+#: src/readelf.c:1009
+#, c-format
+msgid "\t[Requesting program interpreter: %s]\n"
+msgstr ""
+
+#: src/readelf.c:1030
+msgid ""
+"\n"
+" Section to Segment mapping:\n"
+"  Segment Sections..."
+msgstr ""
+
+#: src/readelf.c:1041 src/unstrip.c:1824 src/unstrip.c:1863 src/unstrip.c:1870
+#, c-format
+msgid "cannot get program header: %s"
+msgstr ""
+
+#: src/readelf.c:1175
+#, c-format
+msgid ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"COMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1180
+#, c-format
+msgid ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"Section group [%2zu] '%s' with signature '%s' contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1188
+msgid "<INVALID SYMBOL>"
+msgstr ""
+
+#: src/readelf.c:1202
+msgid "<INVALID SECTION>"
+msgstr ""
+
+#: src/readelf.c:1353
+#, c-format
+msgid ""
+"\n"
+"Dynamic segment contains %lu entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Dynamic segment contains %lu entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1365
+msgid "  Type              Value\n"
+msgstr ""
+
+#: src/readelf.c:1389
+#, c-format
+msgid "Shared library: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1394
+#, c-format
+msgid "Library soname: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1399
+#, c-format
+msgid "Library rpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1404
+#, c-format
+msgid "Library runpath: [%s]\n"
+msgstr ""
+
+#: src/readelf.c:1424
+#, c-format
+msgid "%<PRId64> (bytes)\n"
+msgstr ""
+
+#: src/readelf.c:1534 src/readelf.c:1720
+#, c-format
+msgid ""
+"\n"
+"Invalid symbol table at offset %#0<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:1552 src/readelf.c:1737
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0<PRIx64> "
+"contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1567
+#, c-format
+msgid ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Relocation section [%2u] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1577
+msgid "  Offset      Type                 Value       Name\n"
+msgstr ""
+
+#: src/readelf.c:1579
+msgid "  Offset              Type                 Value               Name\n"
+msgstr ""
+
+#: src/readelf.c:1632 src/readelf.c:1643 src/readelf.c:1656 src/readelf.c:1674
+#: src/readelf.c:1686 src/readelf.c:1805 src/readelf.c:1817 src/readelf.c:1831
+#: src/readelf.c:1850 src/readelf.c:1863
+msgid "<INVALID RELOC>"
+msgstr ""
+
+#: src/readelf.c:1749
+msgid "  Offset      Type            Value       Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:1751
+msgid "  Offset              Type            Value               Addend Name\n"
+msgstr ""
+
+#: src/readelf.c:1952
+#, c-format
+msgid ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entry:\n"
+msgid_plural ""
+"\n"
+"Symbol table [%2u] '%s' contains %u entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1958
+#, c-format
+msgid " %lu local symbol  String table: [%2u] '%s'\n"
+msgid_plural " %lu local symbols  String table: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:1968
+msgid "  Num:    Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:1970
+msgid "  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"
+msgstr ""
+
+#: src/readelf.c:1990
+#, c-format
+msgid "%5u: %0*<PRIx64> %6<PRId64> %-7s %-6s %-9s %6s %s"
+msgstr ""
+
+#: src/readelf.c:2078
+#, c-format
+msgid "bad dynamic symbol"
+msgstr ""
+
+#: src/readelf.c:2160
+msgid "none"
+msgstr ""
+
+#: src/readelf.c:2177
+msgid "| <unknown>"
+msgstr ""
+
+#: src/readelf.c:2202
+#, c-format
+msgid ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version needs section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2225
+#, c-format
+msgid "  %#06x: Version: %hu  File: %s  Cnt: %hu\n"
+msgstr ""
+
+#: src/readelf.c:2238
+#, c-format
+msgid "  %#06x: Name: %s  Flags: %s  Version: %hu\n"
+msgstr ""
+
+#: src/readelf.c:2269
+#, c-format
+msgid ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Version definition section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2299
+#, c-format
+msgid "  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"
+msgstr ""
+
+#: src/readelf.c:2314
+#, c-format
+msgid "  %#06x: Parent %d: %s\n"
+msgstr ""
+
+#: src/readelf.c:2546
+#, c-format
+msgid ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entry:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgid_plural ""
+"\n"
+"Version symbols section [%2u] '%s' contains %d entries:\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2576
+msgid "   0 *local*                     "
+msgstr ""
+
+#: src/readelf.c:2581
+msgid "   1 *global*                    "
+msgstr ""
+
+#: src/readelf.c:2612
+#, c-format
+msgid ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"bucket):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgid_plural ""
+"\n"
+"Histogram for bucket list length in section [%2u] '%s' (total of %d "
+"buckets):\n"
+" Addr: %#0*<PRIx64>  Offset: %#08<PRIx64>  Link to section: [%2u] '%s'\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2636
+#, no-c-format
+msgid " Length  Number  % of total  Coverage\n"
+msgstr ""
+
+#: src/readelf.c:2638
+#, c-format
+msgid "      0  %6<PRIu32>      %5.1f%%\n"
+msgstr ""
+
+#: src/readelf.c:2645
+#, c-format
+msgid "%7d  %6<PRIu32>      %5.1f%%    %5.1f%%\n"
+msgstr ""
+
+#: src/readelf.c:2658
+#, c-format
+msgid ""
+" Average number of tests:   successful lookup: %f\n"
+"                          unsuccessful lookup: %f\n"
+msgstr ""
+
+#: src/readelf.c:2676 src/readelf.c:2718 src/readelf.c:2759
+#, c-format
+msgid "cannot get data for section %d: %s"
+msgstr ""
+
+#: src/readelf.c:2813
+#, c-format
+msgid ""
+" Symbol Bias: %u\n"
+" Bitmask Size: %zu bytes  %<PRIuFAST32>%% bits set  2nd hash shift: %u\n"
+msgstr ""
+
+#: src/readelf.c:2887
+#, c-format
+msgid ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entry:\n"
+msgid_plural ""
+"\n"
+"Library list section [%2zu] '%s' at offset %#0<PRIx64> contains %d entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:2901
+msgid ""
+"       Library                       Time Stamp          Checksum Version "
+"Flags"
+msgstr ""
+
+#: src/readelf.c:2951
+#, c-format
+msgid ""
+"\n"
+"Object attributes section [%2zu] '%s' of %<PRIu64> bytes at offset %"
+"#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:2967
+msgid "  Owner          Size\n"
+msgstr ""
+
+#: src/readelf.c:2993
+#, c-format
+msgid "  %-13s  %4<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3025
+#, c-format
+msgid "    %-4u %12<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3030
+#, c-format
+msgid "    File: %11<PRIu32>\n"
+msgstr ""
+
+#: src/readelf.c:3065
+#, c-format
+msgid "      %s: %<PRId64>, %s\n"
+msgstr ""
+
+#: src/readelf.c:3068
+#, c-format
+msgid "      %s: %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:3071
+#, c-format
+msgid "      %s: %s\n"
+msgstr ""
+
+#: src/readelf.c:3078
+#, c-format
+msgid "      %u: %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:3081
+#, c-format
+msgid "      %u: %s\n"
+msgstr ""
+
+#: src/readelf.c:3117
+#, c-format
+msgid "%s+%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3120
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3125
+#, c-format
+msgid "%#<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3128
+#, c-format
+msgid "%#0*<PRIx64> <%s+%#<PRIx64>>"
+msgstr ""
+
+#: src/readelf.c:3134
+#, c-format
+msgid "%s+%#<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3137
+#, c-format
+msgid "%s+%#0*<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3141
+#, c-format
+msgid "%#<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3144
+#, c-format
+msgid "%#0*<PRIx64> <%s>"
+msgstr ""
+
+#: src/readelf.c:3149
+#, c-format
+msgid "%s+%#<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3152
+#, c-format
+msgid "%s+%#0*<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3260
+#, c-format
+msgid "unknown tag %hx"
+msgstr ""
+
+#: src/readelf.c:3262
+#, c-format
+msgid "unknown user tag %hx"
+msgstr ""
+
+#: src/readelf.c:3480
+#, c-format
+msgid "unknown attribute %hx"
+msgstr ""
+
+#: src/readelf.c:3483
+#, c-format
+msgid "unknown user attribute %hx"
+msgstr ""
+
+#: src/readelf.c:3529
+#, c-format
+msgid "unknown form %<PRIx64>"
+msgstr ""
+
+#: src/readelf.c:3763
+msgid "empty block"
+msgstr ""
+
+#: src/readelf.c:3766
+#, c-format
+msgid "%zu byte block:"
+msgstr ""
+
+#: src/readelf.c:4175
+#, c-format
+msgid "%*s[%4<PRIuMAX>] %s  <TRUNCATED>\n"
+msgstr ""
+
+#: src/readelf.c:4188
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [ Code]\n"
+msgstr ""
+
+#: src/readelf.c:4195
+#, c-format
+msgid ""
+"\n"
+"Abbreviation section at offset %<PRIu64>:\n"
+msgstr ""
+
+#: src/readelf.c:4208
+#, c-format
+msgid " *** error while reading abbreviation: %s\n"
+msgstr ""
+
+#: src/readelf.c:4224
+#, c-format
+msgid " [%5u] offset: %<PRId64>, children: %s, tag: %s\n"
+msgstr ""
+
+#: src/readelf.c:4227
+msgid "yes"
+msgstr ""
+
+#: src/readelf.c:4227
+msgid "no"
+msgstr ""
+
+#: src/readelf.c:4263
+#, c-format
+msgid "cannot get .debug_aranges content: %s"
+msgstr ""
+
+#: src/readelf.c:4268
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entry:\n"
+msgid_plural ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64> contains %zu entries:\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:4298
+#, c-format
+msgid " [%*zu] ???\n"
+msgstr ""
+
+#: src/readelf.c:4300
+#, c-format
+msgid ""
+" [%*zu] start: %0#*<PRIx64>, length: %5<PRIu64>, CU DIE offset: %6<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:4319
+#, c-format
+msgid "cannot get .debug_ranges content: %s"
+msgstr ""
+
+#: src/readelf.c:4324 src/readelf.c:4810 src/readelf.c:5452 src/readelf.c:5897
+#: src/readelf.c:5992 src/readelf.c:6164
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:4338 src/readelf.c:5911
+#, c-format
+msgid " [%6tx]  <INVALID DATA>\n"
+msgstr ""
+
+#: src/readelf.c:4360 src/readelf.c:5933
+#, c-format
+msgid " [%6tx]  base address %s\n"
+msgstr ""
+
+#: src/readelf.c:4371
+#, c-format
+msgid " [%6tx]  %s..%s\n"
+msgstr ""
+
+#: src/readelf.c:4373
+#, c-format
+msgid "           %s..%s\n"
+msgstr ""
+
+#: src/readelf.c:4799 src/readelf.c:6230 src/readelf.c:6332
+#, c-format
+msgid "cannot get %s content: %s"
+msgstr ""
+
+#: src/readelf.c:4806
+#, c-format
+msgid ""
+"\n"
+"Call frame information section [%2zu] '%s' at offset %#<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:4833 src/readelf.c:5486
+#, c-format
+msgid "invalid data in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:4855
+#, c-format
+msgid ""
+"\n"
+" [%6tx] Zero terminator\n"
+msgstr ""
+
+#: src/readelf.c:4924
+#, c-format
+msgid "invalid augmentation length"
+msgstr ""
+
+#: src/readelf.c:4936
+msgid "FDE address encoding: "
+msgstr ""
+
+#: src/readelf.c:4942
+msgid "LSDA pointer encoding: "
+msgstr ""
+
+#: src/readelf.c:5034
+#, c-format
+msgid " (offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5041
+#, c-format
+msgid " (end offset: %#<PRIx64>)"
+msgstr ""
+
+#: src/readelf.c:5068
+#, c-format
+msgid "   %-26sLSDA pointer: %#<PRIx64>\n"
+msgstr ""
+
+#: src/readelf.c:5114
+#, c-format
+msgid "cannot get attribute code: %s"
+msgstr ""
+
+#: src/readelf.c:5122
+#, c-format
+msgid "cannot get attribute form: %s"
+msgstr ""
+
+#: src/readelf.c:5135
+#, c-format
+msgid "cannot get attribute value: %s"
+msgstr ""
+
+#: src/readelf.c:5331
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" [Offset]\n"
+msgstr ""
+
+#: src/readelf.c:5356
+#, c-format
+msgid ""
+" Compilation unit at offset %<PRIu64>:\n"
+" Version: %<PRIu16>, Abbreviation section offset: %<PRIu64>, Address size: %"
+"<PRIu8>, Offset size: %<PRIu8>\n"
+msgstr ""
+
+#: src/readelf.c:5374
+#, c-format
+msgid "cannot get DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:5385
+#, c-format
+msgid "cannot get DIE offset: %s"
+msgstr ""
+
+#: src/readelf.c:5393
+#, c-format
+msgid "cannot get tag of DIE at offset %<PRIu64> in section '%s': %s"
+msgstr ""
+
+#: src/readelf.c:5422
+#, c-format
+msgid "cannot get next DIE: %s\n"
+msgstr ""
+
+#: src/readelf.c:5429
+#, c-format
+msgid "cannot get next DIE: %s"
+msgstr ""
+
+#: src/readelf.c:5464
+#, c-format
+msgid "cannot get line data section data: %s"
+msgstr ""
+
+#: src/readelf.c:5477
+#, c-format
+msgid ""
+"\n"
+"Table at offset %Zu:\n"
+msgstr ""
+
+#: src/readelf.c:5529
+#, c-format
+msgid ""
+"\n"
+" Length:                     %<PRIu64>\n"
+" DWARF version:              %<PRIuFAST16>\n"
+" Prologue length:            %<PRIu64>\n"
+" Minimum instruction length: %<PRIuFAST8>\n"
+" Initial value if '%s': %<PRIuFAST8>\n"
+" Line base:                  %<PRIdFAST8>\n"
+" Line range:                 %<PRIuFAST8>\n"
+" Opcode base:                %<PRIuFAST8>\n"
+"\n"
+"Opcodes:\n"
+msgstr ""
+
+#: src/readelf.c:5548
+#, c-format
+msgid "invalid data at offset %tu in section [%zu] '%s'"
+msgstr ""
+
+#: src/readelf.c:5563
+#, c-format
+msgid "  [%*<PRIuFAST8>]  %hhu argument\n"
+msgid_plural "  [%*<PRIuFAST8>]  %hhu arguments\n"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:5571
+msgid ""
+"\n"
+"Directory table:"
+msgstr ""
+
+#: src/readelf.c:5587
+msgid ""
+"\n"
+"File name table:\n"
+" Entry Dir   Time      Size      Name"
+msgstr ""
+
+#: src/readelf.c:5616
+msgid ""
+"\n"
+"Line number statements:"
+msgstr ""
+
+#: src/readelf.c:5677
+#, c-format
+msgid " special opcode %u: address+%u = %s, line%+d = %zu\n"
+msgstr ""
+
+#: src/readelf.c:5697
+#, c-format
+msgid " extended opcode %u: "
+msgstr ""
+
+#: src/readelf.c:5702
+msgid "end of sequence"
+msgstr ""
+
+#: src/readelf.c:5717
+#, c-format
+msgid "set address to %s\n"
+msgstr ""
+
+#: src/readelf.c:5738
+#, c-format
+msgid "define new file: dir=%u, mtime=%<PRIu64>, length=%<PRIu64>, name=%s\n"
+msgstr ""
+
+#: src/readelf.c:5747
+msgid "unknown opcode"
+msgstr ""
+
+#: src/readelf.c:5759
+msgid " copy"
+msgstr ""
+
+#: src/readelf.c:5769
+#, c-format
+msgid "advance address by %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5780
+#, c-format
+msgid " advance line by constant %d to %<PRId64>\n"
+msgstr ""
+
+#: src/readelf.c:5788
+#, c-format
+msgid " set file to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:5798
+#, c-format
+msgid " set column to %<PRIu64>\n"
+msgstr ""
+
+#: src/readelf.c:5805
+#, c-format
+msgid " set '%s' to %<PRIuFAST8>\n"
+msgstr ""
+
+#: src/readelf.c:5811
+msgid " set basic block flag"
+msgstr ""
+
+#: src/readelf.c:5821
+#, c-format
+msgid "advance address by constant %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5837
+#, c-format
+msgid "advance address by fixed value %u to %s\n"
+msgstr ""
+
+#: src/readelf.c:5846
+msgid " set prologue end flag"
+msgstr ""
+
+#: src/readelf.c:5851
+msgid " set epilogue begin flag"
+msgstr ""
+
+#: src/readelf.c:5860
+#, c-format
+msgid " unknown opcode with %<PRIu8> parameter:"
+msgid_plural " unknown opcode with %<PRIu8> parameters:"
+msgstr[0] ""
+msgstr[1] ""
+
+#: src/readelf.c:5892
+#, c-format
+msgid "cannot get .debug_loc content: %s"
+msgstr ""
+
+#: src/readelf.c:5947
+#, c-format
+msgid " [%6tx]  %s..%s"
+msgstr ""
+
+#: src/readelf.c:5949
+#, c-format
+msgid "           %s..%s"
+msgstr ""
+
+#: src/readelf.c:6002
+#, c-format
+msgid "cannot get macro information section data: %s"
+msgstr ""
+
+#: src/readelf.c:6081
+#, c-format
+msgid "%*s*** non-terminated string at end of section"
+msgstr ""
+
+#: src/readelf.c:6149
+#, c-format
+msgid " [%5d] DIE offset: %6<PRId64>, CU DIE offset: %6<PRId64>, name: %s\n"
+msgstr ""
+
+#: src/readelf.c:6188
+#, c-format
+msgid ""
+"\n"
+"DWARF section [%2zu] '%s' at offset %#<PRIx64>:\n"
+" %*s  String\n"
+msgstr ""
+
+#: src/readelf.c:6202
+#, c-format
+msgid " *** error while reading strings: %s\n"
+msgstr ""
+
+#: src/readelf.c:6222
+#, c-format
+msgid ""
+"\n"
+"Call frame search table section [%2zu] '.eh_frame_hdr':\n"
+msgstr ""
+
+#: src/readelf.c:6324
+#, c-format
+msgid ""
+"\n"
+"Exception handling table section [%2zu] '.gcc_except_table':\n"
+msgstr ""
+
+#: src/readelf.c:6347
+#, c-format
+msgid " LPStart encoding:    %#x "
+msgstr ""
+
+#: src/readelf.c:6359
+#, c-format
+msgid " TType encoding:      %#x "
+msgstr ""
+
+#: src/readelf.c:6373
+#, c-format
+msgid " Call site encoding:  %#x "
+msgstr ""
+
+#: src/readelf.c:6386
+msgid ""
+"\n"
+" Call site table:"
+msgstr ""
+
+#: src/readelf.c:6400
+#, c-format
+msgid ""
+" [%4u] Call site start:   %#<PRIx64>\n"
+"        Call site length:  %<PRIu64>\n"
+"        Landing pad:       %#<PRIx64>\n"
+"        Action:            %u\n"
+msgstr ""
+
+#: src/readelf.c:6460
+#, c-format
+msgid "invalid TType encoding"
+msgstr ""
+
+#: src/readelf.c:6484
+#, c-format
+msgid "cannot get debug context descriptor: %s"
+msgstr ""
+
+#: src/readelf.c:6620 src/readelf.c:7221
+#, c-format
+msgid "cannot convert core note data: %s"
+msgstr ""
+
+#: src/readelf.c:6961
+#, c-format
+msgid ""
+"\n"
+"%*s... <repeats %u more times> ..."
+msgstr ""
+
+#: src/readelf.c:7320
+msgid "  Owner          Data size  Type\n"
+msgstr ""
+
+#: src/readelf.c:7338
+#, c-format
+msgid "  %-13.*s  %9<PRId32>  %s\n"
+msgstr ""
+
+#: src/readelf.c:7372
+#, c-format
+msgid "cannot get content of note section: %s"
+msgstr ""
+
+#: src/readelf.c:7399
+#, c-format
+msgid ""
+"\n"
+"Note section [%2zu] '%s' of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7422
+#, c-format
+msgid ""
+"\n"
+"Note segment of %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7468
+#, c-format
+msgid ""
+"\n"
+"Section [%Zu] '%s' has no data to dump.\n"
+msgstr ""
+
+#: src/readelf.c:7474 src/readelf.c:7497
+#, c-format
+msgid "cannot get data for section [%Zu] '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7478
+#, c-format
+msgid ""
+"\n"
+"Hex dump of section [%Zu] '%s', %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7491
+#, c-format
+msgid ""
+"\n"
+"Section [%Zu] '%s' has no strings to dump.\n"
+msgstr ""
+
+#: src/readelf.c:7501
+#, c-format
+msgid ""
+"\n"
+"String section [%Zu] '%s' contains %<PRIu64> bytes at offset %#0<PRIx64>:\n"
+msgstr ""
+
+#: src/readelf.c:7549
+#, c-format
+msgid ""
+"\n"
+"section [%lu] does not exist"
+msgstr ""
+
+#: src/readelf.c:7576
+#, c-format
+msgid ""
+"\n"
+"section '%s' does not exist"
+msgstr ""
+
+#: src/readelf.c:7637
+#, c-format
+msgid "cannot get symbol index of archive '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7640
+#, c-format
+msgid ""
+"\n"
+"Archive '%s' has no symbol index\n"
+msgstr ""
+
+#: src/readelf.c:7644
+#, c-format
+msgid ""
+"\n"
+"Index of archive '%s' has %Zu entries:\n"
+msgstr ""
+
+#: src/readelf.c:7662
+#, c-format
+msgid "cannot extract member at offset %Zu in '%s': %s"
+msgstr ""
+
+#: src/readelf.c:7667
+#, c-format
+msgid "Archive member '%s' contains:\n"
+msgstr ""
+
+#: src/size.c:68
+msgid ""
+"Use the output format FORMAT.  FORMAT can be `bsd' or `sysv'.  The default "
+"is `bsd'"
+msgstr ""
+
+#: src/size.c:70
+msgid "Same as `--format=sysv'"
+msgstr ""
+
+#: src/size.c:71
+msgid "Same as `--format=bsd'"
+msgstr ""
+
+#: src/size.c:74
+msgid "Same as `--radix=10'"
+msgstr ""
+
+#: src/size.c:75
+msgid "Same as `--radix=8'"
+msgstr ""
+
+#: src/size.c:76
+msgid "Same as `--radix=16'"
+msgstr ""
+
+#: src/size.c:78
+msgid "Similar to `--format=sysv' output but in one line"
+msgstr ""
+
+#: src/size.c:82
+msgid "Print size and permission flags for loadable segments"
+msgstr ""
+
+#: src/size.c:83
+msgid "Display the total sizes (bsd only)"
+msgstr ""
+
+#: src/size.c:88
+msgid "List section sizes of FILEs (a.out by default)."
+msgstr ""
+
+#: src/size.c:269
+#, c-format
+msgid "Invalid format: %s"
+msgstr ""
+
+#: src/size.c:280
+#, c-format
+msgid "Invalid radix: %s"
+msgstr ""
+
+#: src/size.c:339
+#, c-format
+msgid "%s: file format not recognized"
+msgstr ""
+
+#: src/size.c:446 src/size.c:589
+#, c-format
+msgid " (ex %s)"
+msgstr ""
+
+#: src/size.c:614
+msgid "(TOTALS)\n"
+msgstr ""
+
+#: src/strings.c:70
+msgid "Output Selection:"
+msgstr ""
+
+#: src/strings.c:71
+msgid "Scan entire file, not only loaded sections"
+msgstr ""
+
+#: src/strings.c:73
+msgid "Only NUL-terminated sequences of MIN-LEN characters or more are printed"
+msgstr ""
+
+#: src/strings.c:74
+msgid ""
+"Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, "
+"{B,L} = 32-bit"
+msgstr ""
+
+#: src/strings.c:78
+msgid "Print name of the file before each string."
+msgstr ""
+
+#: src/strings.c:80
+msgid "Print location of the string in base 8, 10, or 16 respectively."
+msgstr ""
+
+#: src/strings.c:81
+msgid "Alias for --radix=o"
+msgstr ""
+
+#: src/strings.c:88
+msgid "Print the strings of printable characters in files."
+msgstr ""
+
+#: src/strings.c:268 src/strings.c:303
+#, c-format
+msgid "invalid value '%s' for %s parameter"
+msgstr ""
+
+#: src/strings.c:314
+#, c-format
+msgid "invalid minimum length of matched string size"
+msgstr ""
+
+#: src/strings.c:601
+#, c-format
+msgid "lseek64 failed"
+msgstr ""
+
+#: src/strings.c:616 src/strings.c:680
+#, c-format
+msgid "re-mmap failed"
+msgstr ""
+
+#: src/strings.c:653
+#, c-format
+msgid "mprotect failed"
+msgstr ""
+
+#: src/strip.c:74
+msgid "Place stripped output into FILE"
+msgstr ""
+
+#: src/strip.c:75
+msgid "Extract the removed sections into FILE"
+msgstr ""
+
+#: src/strip.c:76
+msgid "Embed name FILE instead of -f argument"
+msgstr ""
+
+#: src/strip.c:80
+msgid "Remove all debugging symbols"
+msgstr ""
+
+#: src/strip.c:84
+msgid "Copy modified/access timestamps to the output"
+msgstr ""
+
+#: src/strip.c:86
+msgid "Remove .comment section"
+msgstr ""
+
+#: src/strip.c:89
+msgid "Relax a few rules to handle slightly broken ELF files"
+msgstr ""
+
+#: src/strip.c:94
+msgid "Discard symbols from object files."
+msgstr ""
+
+#: src/strip.c:186
+#, c-format
+msgid "Only one input file allowed together with '-o' and '-f'"
+msgstr ""
+
+#: src/strip.c:222
+#, c-format
+msgid "-f option specified twice"
+msgstr ""
+
+#: src/strip.c:231
+#, c-format
+msgid "-F option specified twice"
+msgstr ""
+
+#: src/strip.c:240 src/unstrip.c:125
+#, c-format
+msgid "-o option specified twice"
+msgstr ""
+
+#: src/strip.c:260
+#, c-format
+msgid "-R option supports only .comment section"
+msgstr ""
+
+#: src/strip.c:298 src/strip.c:322
+#, c-format
+msgid "cannot stat input file '%s'"
+msgstr ""
+
+#: src/strip.c:312
+#, c-format
+msgid "while opening '%s'"
+msgstr ""
+
+#: src/strip.c:350
+#, c-format
+msgid "%s: cannot use -o or -f when stripping archive"
+msgstr ""
+
+#: src/strip.c:448
+#, c-format
+msgid "cannot open EBL backend"
+msgstr ""
+
+#: src/strip.c:498 src/strip.c:522
+#, c-format
+msgid "cannot create new file '%s': %s"
+msgstr ""
+
+#: src/strip.c:582
+#, c-format
+msgid "illformed file '%s'"
+msgstr ""
+
+#: src/strip.c:869 src/strip.c:956
+#, c-format
+msgid "while generating output file: %s"
+msgstr ""
+
+#: src/strip.c:929 src/strip.c:1668
+#, c-format
+msgid "%s: error while creating ELF header: %s"
+msgstr ""
+
+#: src/strip.c:943
+#, c-format
+msgid "while preparing output for '%s'"
+msgstr ""
+
+#: src/strip.c:994 src/strip.c:1050
+#, c-format
+msgid "while create section header section: %s"
+msgstr ""
+
+#: src/strip.c:1000
+#, c-format
+msgid "cannot allocate section data: %s"
+msgstr ""
+
+#: src/strip.c:1059
+#, c-format
+msgid "while create section header string table: %s"
+msgstr ""
+
+#: src/strip.c:1593 src/strip.c:1690
+#, c-format
+msgid "while writing '%s': %s"
+msgstr ""
+
+#: src/strip.c:1604
+#, c-format
+msgid "while creating '%s'"
+msgstr ""
+
+#: src/strip.c:1616
+#, c-format
+msgid "while computing checksum for debug information"
+msgstr ""
+
+#: src/strip.c:1676
+#, c-format
+msgid "%s: error while reading the file: %s"
+msgstr ""
+
+#: src/strip.c:1722 src/strip.c:1729
+#, c-format
+msgid "error while finishing '%s': %s"
+msgstr ""
+
+#: src/strip.c:1752 src/strip.c:1809
+#, c-format
+msgid "cannot set access and modification date of '%s'"
+msgstr ""
+
+#: src/unstrip.c:78
+msgid "Match MODULE against file names, not module names"
+msgstr ""
+
+#: src/unstrip.c:79
+msgid "Silently skip unfindable files"
+msgstr ""
+
+#: src/unstrip.c:82
+msgid "Place output into FILE"
+msgstr ""
+
+#: src/unstrip.c:84
+msgid "Create multiple output files under DIRECTORY"
+msgstr ""
+
+#: src/unstrip.c:85
+msgid "Use module rather than file names"
+msgstr ""
+
+#: src/unstrip.c:87
+msgid "Create output for modules that have no separate debug information"
+msgstr ""
+
+#: src/unstrip.c:90
+msgid "Apply relocations to section contents in ET_REL files"
+msgstr ""
+
+#: src/unstrip.c:92
+msgid "Only list module and file names, build IDs"
+msgstr ""
+
+#: src/unstrip.c:134
+#, c-format
+msgid "-d option specified twice"
+msgstr ""
+
+#: src/unstrip.c:166
+#, c-format
+msgid "only one of -o or -d allowed"
+msgstr ""
+
+#: src/unstrip.c:175
+#, c-format
+msgid "-n cannot be used with explicit files or -o or -d"
+msgstr ""
+
+#: src/unstrip.c:190
+#, c-format
+msgid "output directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:199
+#, c-format
+msgid "exactly two file arguments are required"
+msgstr ""
+
+#: src/unstrip.c:205
+#, c-format
+msgid "-m, -a, -R, and -i options not allowed with explicit files"
+msgstr ""
+
+#: src/unstrip.c:218
+#, c-format
+msgid "-o or -d is required when using implicit files"
+msgstr ""
+
+#: src/unstrip.c:254
+#, c-format
+msgid "cannot create ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:259
+#, c-format
+msgid "cannot copy ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:264 src/unstrip.c:1817
+#, c-format
+msgid "cannot create program headers: %s"
+msgstr ""
+
+#: src/unstrip.c:270
+#, c-format
+msgid "cannot copy program header: %s"
+msgstr ""
+
+#: src/unstrip.c:280
+#, c-format
+msgid "cannot copy section header: %s"
+msgstr ""
+
+#: src/unstrip.c:283 src/unstrip.c:1505
+#, c-format
+msgid "cannot get section data: %s"
+msgstr ""
+
+#: src/unstrip.c:285 src/unstrip.c:1507
+#, c-format
+msgid "cannot copy section data: %s"
+msgstr ""
+
+#: src/unstrip.c:309
+#, c-format
+msgid "cannot create directory '%s'"
+msgstr ""
+
+#: src/unstrip.c:349 src/unstrip.c:763 src/unstrip.c:1540
+#, c-format
+msgid "cannot get symbol table entry: %s"
+msgstr ""
+
+#: src/unstrip.c:365 src/unstrip.c:580 src/unstrip.c:601 src/unstrip.c:613
+#: src/unstrip.c:1561 src/unstrip.c:1691 src/unstrip.c:1715
+#, c-format
+msgid "cannot update symbol table: %s"
+msgstr ""
+
+#: src/unstrip.c:382 src/unstrip.c:432 src/unstrip.c:562 src/unstrip.c:1209
+#: src/unstrip.c:1525 src/unstrip.c:1720 src/unstrip.c:1791
+#, c-format
+msgid "cannot update section header: %s"
+msgstr ""
+
+#: src/unstrip.c:408 src/unstrip.c:419
+#, c-format
+msgid "cannot update relocation: %s"
+msgstr ""
+
+#: src/unstrip.c:507
+#, c-format
+msgid "cannot get symbol version: %s"
+msgstr ""
+
+#: src/unstrip.c:519
+#, c-format
+msgid "unexpected section type in [%Zu] with sh_link to symtab"
+msgstr ""
+
+#: src/unstrip.c:769
+#, c-format
+msgid "invalid string offset in symbol [%Zu]"
+msgstr ""
+
+#: src/unstrip.c:911 src/unstrip.c:1248
+#, c-format
+msgid "cannot read section [%Zu] name: %s"
+msgstr ""
+
+#: src/unstrip.c:952 src/unstrip.c:971 src/unstrip.c:1004
+#, c-format
+msgid "cannot read '.gnu.prelink_undo' section: %s"
+msgstr ""
+
+#: src/unstrip.c:992
+#, c-format
+msgid "invalid contents in '%s' section"
+msgstr ""
+
+#: src/unstrip.c:1047 src/unstrip.c:1370
+#, c-format
+msgid "cannot find matching section for [%Zu] '%s'"
+msgstr ""
+
+#: src/unstrip.c:1171 src/unstrip.c:1186 src/unstrip.c:1451
+#, c-format
+msgid "cannot add section name to string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1195
+#, c-format
+msgid "cannot update section header string table data: %s"
+msgstr ""
+
+#: src/unstrip.c:1223 src/unstrip.c:1227
+#, c-format
+msgid "cannot get section header string table section index: %s"
+msgstr ""
+
+#: src/unstrip.c:1231 src/unstrip.c:1235 src/unstrip.c:1466
+#, c-format
+msgid "cannot get section count: %s"
+msgstr ""
+
+#: src/unstrip.c:1293 src/unstrip.c:1385
+#, c-format
+msgid "cannot read section header string table: %s"
+msgstr ""
+
+#: src/unstrip.c:1445
+#, c-format
+msgid "cannot add new section: %s"
+msgstr ""
+
+#: src/unstrip.c:1548
+#, c-format
+msgid "symbol [%Zu] has invalid section index"
+msgstr ""
+
+#: src/unstrip.c:1800
+#, c-format
+msgid "cannot get ELF header: %s"
+msgstr ""
+
+#: src/unstrip.c:1827
+#, c-format
+msgid "cannot update program header: %s"
+msgstr ""
+
+#: src/unstrip.c:1832 src/unstrip.c:1911
+#, c-format
+msgid "cannot write output file: %s"
+msgstr ""
+
+#: src/unstrip.c:1880
+#, c-format
+msgid "DWARF data not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:1883
+#, c-format
+msgid ""
+"DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"
+msgstr ""
+
+#: src/unstrip.c:1902 src/unstrip.c:1942 src/unstrip.c:1954 src/unstrip.c:2034
+#, c-format
+msgid "cannot create ELF descriptor: %s"
+msgstr ""
+
+#: src/unstrip.c:1960
+#, c-format
+msgid "'%s' and '%s' do not seem to match"
+msgstr ""
+
+#: src/unstrip.c:1991
+#, c-format
+msgid "cannot find stripped file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:1995
+#, c-format
+msgid "cannot open stripped file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2010
+#, c-format
+msgid "cannot find debug file for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2014
+#, c-format
+msgid "cannot open debug file '%s' for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2027
+#, c-format
+msgid "module '%s' file '%s' is not stripped"
+msgstr ""
+
+#: src/unstrip.c:2058
+#, c-format
+msgid "cannot cache section addresses for module '%s': %s"
+msgstr ""
+
+#: src/unstrip.c:2191
+#, c-format
+msgid "no matching modules found"
+msgstr ""
+
+#: src/unstrip.c:2200
+#, c-format
+msgid "matched more than one module"
+msgstr ""
+
+#: src/unstrip.c:2247
+msgid ""
+"STRIPPED-FILE DEBUG-FILE\n"
+"[MODULE...]"
+msgstr ""
+
+#: src/unstrip.c:2248
+msgid ""
+"Combine stripped files with separate symbols and debug information.\n\nThe "
+"first form puts the result in DEBUG-FILE if -o was not given.\n"
+"\n"
+"MODULE arguments give file name patterns matching modules to process.\n"
+"With -f these match the file name of the main (stripped) file (slashes are "
+"never special), otherwise they match the simple module names.  With no "
+"arguments, process all modules found.\n"
+"\n"
+"Multiple modules are written to files under OUTPUT-DIRECTORY, creating "
+"subdirectories as needed.  With -m these files have simple module names, "
+"otherwise they have the name of the main file complete with directory "
+"underneath OUTPUT-DIRECTORY.\n"
+"\n"
+"With -n no files are written, but one line to standard output for each "
+"module:\n"
+"\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n"
+"START and SIZE are hexadecimal giving the address bounds of the module.  "
+"BUILDID is hexadecimal for the build ID bits, or - if no ID is known; the "
+"hexadecimal may be followed by @0xADDR giving the address where the ID "
+"resides if that is known.  FILE is the file name found for the module, or - "
+"if none was found, or . if an ELF image is available but not from any named "
+"file.  DEBUGFILE is the separate debuginfo file name, or - if no debuginfo "
+"was found, or . if FILE contains the debug information."
+msgstr ""
diff --git a/third_party/elfutils/src/ChangeLog b/third_party/elfutils/src/ChangeLog
new file mode 100644
index 0000000..a490705
--- /dev/null
+++ b/third_party/elfutils/src/ChangeLog
@@ -0,0 +1,4058 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* addr2line.c (handle_address): Use FALLTHROUGH macro instead of
+	comment.
+	* elfcompress.c (parse_opt): Likewise.
+	* elflint.c (check_dynamic): Likewise.
+	(check_sections): Likewise.
+	(check_note_data): Likewise.
+	* objdump.c (parse_opt): Likewise.
+	* readelf.c (parse_opt): Likewise.
+	(attr_callback): Likewise.
+	(handle_auxv_note): Likewise.
+	* strings.c (parse_opt): Likewise.
+	* backtrace.c (callback_verify): Likewise.
+
+2018-01-25  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (print_debug_ranges_section): Initialize cu to last_cu.
+	(print_debug_loc_section): Likewise.
+
+2018-01-01  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (attr_callback): Use dwarf_form_name for unknown forms.
+	(print_debug_macro_section): Print form using dwarf_form_name.
+
+2017-12-28  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (print_debug_units): Print DIE offset in error message
+	as hex.
+
+2017-12-18  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (handle_notes_data): Don't use EXIT_FAILURE in error.
+	Adjust error message depending on whether or not we got data.
+
+2017-12-07  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (print_ops): Update data pointer and print arguments
+	to DW_OP_call2 and DW_OP_call4 as DIE offsets.
+
+2017-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (argp_options): Add "section-groups", 'g'.
+
+2017-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (print_debug_loc_section): Print CU base and unresolved
+	addresses. Adjust formatting.
+
+2017-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (print_debug_ranges_section): Print CU base and unresolved
+	addresses. Adjust formatting.
+
+2017-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (attr_callback): Set valuestr to resolved file name
+	for DW_AT_decl_file and DW_AT_call_file.
+
+2017-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (print_debug_units): Print abbrev code after DIE tag.
+
+2017-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (print_ops): Use only2 space for index. re-indent +5
+	for DW_OP_GNU_entry_value.
+
+2017-11-21  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (attr_callback): Print attribute name and form in error
+	message. If only the value cannot be retrieved/resolved don't abort.
+
+2017-10-03  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (attr_callback): Print DIE offset in error messages.
+
+2017-11-03  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (print_ops): Handle DW_OP_GNU_variable_value. Print
+	referenced DIE as offset.
+
+2017-09-10  Mark Wielaard  <mark@klomp.org>
+
+	* ar.c (do_oper_delete): Remove DEBUG conditional check.
+	(no0print): Return bool. Check snprintf return value.
+	(do_oper_insert): Initialize elf. Remove DEBUG conditional check.
+	Check no0print calls succeed. Explicitly elf_end found elfs.
+	(do_oper_extract): Make sure we don't create an empty variable
+	length array.
+
+2017-09-01  Mark Wielaard  <mark@klomp.org>
+
+	* stack.c (main): Replace \v in doc string with \n\n.
+	* unstrip.c (main): Likewise.
+
+2017-05-04  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* stack.c: Print pid_t using %lld.
+
+2017-08-18  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* readelf.c: Hardcode the signal numbers for non-linux systems.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (print_debug_macro_section): Accept either version 4 or
+	version 5. Use DW_MACRO names instead of DW_MACRO_GNU names. Add
+	minimal support for DW_MACRO_define_sup, DW_MACRO_undef_sup,
+	DW_MACRO_import_sup, DW_MACRO_define_strx and DW_MACRO_undef_strx.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* readelf.c (dwarf_defaulted_string): New function.
+	(dwarf_defaulted_name): Likewise.
+	(attr_callback): Use dwarf_defaulted_name to get value of
+	DW_AT_defaulted.
+
+2017-07-20  Mark Wielaard  <mark@klomp.org>
+
+	* strip.c (handle_elf): Deal with data marker symbols pointing to
+	debug sections (they can be removed).
+
+2017-07-14  Mark Wielaard  <mark@klomp.org>
+
+	* strip (OPT_KEEP_SECTION): New define.
+	(options): Add documentation for remove-section. Add keep-section.
+	(struct section_pattern): New data type.
+	(keep_secs, remove_secs): New globals.
+	(add_pattern, free_sec_patterns, free_patterns, section_name_matches):
+	New functions.
+	(main): Call free_patterns.
+	(parse_opt): Handle 'R' and OPT_KEEP_SECTION. Check remove_comment
+	on ARGP_KEY_SUCCESS.
+	(handle_elf): Handle and sanity check keep_secs and remove_secs.
+
+2017-06-07  Mark Wielaard  <mark@klomp.org>
+
+	* strip.c (handle_elf): Introduce new handle_elf boolean. Use it to
+	determine whether to create an output and/or debug file. Remove new
+	output file on error.
+
+2017-06-06  Mark Wielaard  <mark@klomp.org>
+
+	* strip.c (handle_elf): Assume e_shstrndx section can be removed.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* readelf.c: Include strings.h.
+
+2017-04-20  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* unstrip.c: Check shnum for 0 before subtracting from it.
+
+2017-04-20  Ulf Hermann <ulf.hermann@qt.io>
+
+	* readelf.c: Replace YESSTR and NOSTR with gettext ("yes") and
+	gettext ("no"), respectively.
+
+2017-04-05  Mark Wielaard  <mark@klomp.org>
+
+	* elflint.c (check_elf_header): Decompress all sections.
+
+2017-03-28  Mark Wielaard  <mark@klomp.org>
+
+	* elflint (check_group): Don't check if there is no flag word.
+
+2017-03-27  Mark Wielaard  <mark@klomp.org>
+
+	* elflint.c (check_elf_header): Sanity check phnum and shnum.
+
+2017-03-27  Mark Wielaard  <mark@klomp.org>
+
+	* elflint.c (check_sysv_hash): Return early if section size is
+	too small.
+	(check_sysv_hash64): Likewise.
+	(check_hash): Calculate expect_entsize to check section size.
+
+2017-03-27  Mark Wielaard  <mark@klomp.org>
+
+	* elflint.c (check_symtab_shndx): Check data->d_size.
+
+2017-03-24  Mark Wielaard  <mjw@redhat.com>
+
+	* elfcmp.c (main): If n_namesz == 0 then the note name data is the
+	empty string.
+	* readelf.c (handle_notes_data): Likewise.
+
+2017-03-24  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_gnu_hash): Check inner < max_nsyms before
+	indexing into chain array.
+
+2017-02-16  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* addr2line.c: Include printversion.h
+	* ar.c: Likewise.
+	* elflint.c: Likewise.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c: Likewise.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* stack.c: Likewise.
+	* strings.c: Likewise.
+	* strip.c: Likewise.
+	* elfcmp.c: Include printversion.h, remove system.h include.
+	* elfcompress.c: Likewise.
+	* findtextrel.c: Likewise.
+	* unstrip.c: Likewise.
+
+2017-02-14  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* nm.c: Include color.h.
+	* objdump.c: Likewise.
+
+2016-12-24  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am (findtextrel_LDADD): Add $(libeu).
+	(addr2line_LDADD): Likewise.
+	(elfcmp_LDADD): Likewise.
+	* addr2line.c (print_version): Removed.
+	* ar.c (print_version): Likewise.
+	* elfcmp.c (print_version): Likewise.
+	* elfcompress.c (print_version): Likewise.
+	* elflint.c (print_version): Likewise.
+	* findtextrel.c (print_version): Likewise.
+	* nm.c (print_version): Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c: Likewise.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* stack.c: Likewise.
+	* strings.c: Likewise.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise.
+
+2016-11-17  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (options): Add optional arg SECTION for symbols.
+	(symbol_table_section): New static variable.
+	(parse_opt): Set symbol_table_section on 's'.
+	(print_symtab): Filter on symbol_table_section name is set.
+
+2016-11-10  Mark Wielaard  <mjw@redhat.com>
+
+	* ar.c (write_member): Make sure tmpbuf is large enough to contain
+	a starting '/' and ending '\0' char.
+	(do_oper_insert): Likewise.
+	* arlib.c (arlib_finalize): Format tmpbuf as PRId32 decimal.
+
+2016-11-02  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (handle_address): Add fallthrough comment.
+	* elfcompress.c (parse_opt): Adjust fallthrough comment.
+	* elflint.c (parse_opt): Add missing break after 'd' case.
+	(check_sections): Add fallthrough comments.
+	* objdump.c (parse_opt): Add explantion for fallthrough comment.
+
+2016-10-22  Kevin Cernekee  <cernekee@chromium.org>
+
+	* unstrip.c: Fix "invalid string offset" error caused by using the
+	  unstripped .symtab with the stripped .strtab.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* arlib.c: Remove system.h include, add libeu.h include.
+	* arlib2.c: Remove sys/param.h include.
+	* elfcompress.c: Add libeu.h include.
+	* elflint.c: Remove sys/param.h include, add libeu.h include.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c: Likewise.
+	* readelf.c: Likewise.
+	* size.c: Remove sys/param.h include.
+	* strings.c: Likewise, add libeu.h include.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise.
+
+2016-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (handle_elf): Don't remove real symbols from allocated
+	symbol tables.
+
+2016-08-25  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (handle_elf): Recompress with ELF_CHF_FORCE.
+
+2016-08-06  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (handle_elf): Uncompress and recompress relocation target
+	section if necessary.
+
+2016-07-08  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (strip_LDADD): Add libdw.
+	* elfcompress.c (process_file): Use dwelf_strtab functions instead of
+	ebl_strtab.
+	* strip.c (handle_elf): Likewise.
+	* unstrip.c (new_shstrtab): Likewise.
+
+2016-07-06  Mark Wielaard  <mjw@redhat.com>
+
+	* elf32-i386.script, i386_ld.c, ld.c, ld.h, ldgeneric.c, ldlex.l,
+	ldscript.y, libld_elf_i386.map, none_ld.c, sectionhash.c,
+	sectionhash.h, symbolhash.c, symbolhash.h, unaligned.h,
+	versionhash.c, versionhash.h, xelf.h: Removed.
+	* Makefile.am (YACC): Removed.
+	(AM_YFLAGS): Removed.
+	(AM_LFLAGS): Removed.
+	(native_ld): Removed.
+	(base_cpu): Removed.
+	(bin_PROGRAMS): Removed ld.
+	(ld_dsos): Removed.
+	(ld_SOURCES): Removed.
+	(noinst_LIBRARIES): Only libar.a.
+	(EXTRA_DIST): Just arlib.h and debugpred.h.
+	(ld_LDADD): Removed.
+	(ld_LDFLAGS): Removed.
+	(ldlex.o): Removed.
+	(ldscript.h): Removed.
+	(libld*): Removed.
+	(CLEANFILES): Just *.gconv.
+	(MAINTAINERCLEANFILES): Removed.
+
+2016-07-06  Mark Wielaard  <mjw@redhat.com>
+
+	* unstrip.c (copy_elided_sections): Use unstripped_strent[] from
+	index zero, instead of one.
+
+2016-06-28  Richard Henderson <rth@redhat.com>
+
+	* elflint.c (valid_e_machine): Add EM_BPF.
+
+2016-04-11  David Abdurachmanov  <davidlt@cern.ch>
+
+	* elfcmp.c (main): Fix self-comparison error with GCC 6.
+
+2016-03-21  Mark Wielaard  <mjw@redhat.com>
+
+	* nm.c (show_symbols): Check for malloc size argument overflow.
+
+2016-02-13  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_scngrp): Call error when gelf_getshdr fails.
+	(print_symtab): Likewise.
+	(handle_hash): Likewise.
+	(dump_data_section): Print a warning if decompressing fails.
+	(print_string_section): Likewise.
+
+2016-02-13  Mark Wielaard  <mjw@redhat.com>
+
+	* elfcompress.c (parse_opt): Don't fallthrough after processing -q.
+
+2016-02-12  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (handle_elf): Correct elf_assert shndxdata check.
+
+2016-02-09  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (read_encoded): Move up.
+	(print_cfa_program): Add encoding argument. Use it for read_encoded
+	when reading DW_CFA_set_loc op.
+	(print_debug_frame_section): Pass fde_encoding to print_cfa_program.
+
+2016-02-09  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (compare_hash_gnu_hash): Check hash sh_entsize against
+	sizeof (Elf64_Xword). Correct invalid sh_entsize error message
+	section idx and name.
+
+2016-01-13  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_elf_header): Recognize ELFOSABI_FREEBSD.
+
+2016-01-08  Mark Wielaard  <mjw@redhat.com>
+
+	* elfcompress.c (compress_section): Use %zu to print size_t.
+	* readelf.c (print_shdr): Use %zx to print size_t.
+
+2015-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elfcompress.c: New file.
+	* Makefile.am (bin_PROGRAMS): Add elfcompress.
+	(elfcompress_LDADD): New variable.
+
+2015-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (section_flags_string): Add NEWFLAG COMPRESSED.
+	(check_sections): SHF_COMPRESSED can be on any special section.
+	SHF_COMPRESSED is a valid section flag. SHF_COMPRESSED cannot
+	be used together with SHF_ALLOC or with SHT_NOBITS. Should have
+	a valid Chdr.
+
+2015-10-20  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (options): Expand -z help text.
+	(dump_data_section): Check whether we need and can decompress section
+	data and call elf_rawzdata if so,
+	(print_string_section): Likewise.
+	(elf_contains_chdrs): New function.
+	(process_elf_file): Rename print_unrelocated to print_unchanged,
+	use elf_contains_chdrs.
+	(print_scngrp): Check whether section is compressed before use.
+	(print_symtab): Likewise.
+	(handle_hash): Likewise.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (argp_option): Describe --decompress,-z.
+	(print_decompress): New bool.
+	(parse_opt): Handle -z.
+	(elf_ch_type_name): New function.
+	(print_shdr): Print section compress information.
+
+2015-12-31  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_symtab): Add _edata and _end (plus extra underscore
+	variants) to to the list of possibly dangling symbols.
+
+2015-12-02  Mark Wielaard  <mjw@redhat.com>
+
+	* nm.c (process_file): Accept fd and pass it on.
+	(handle_elf): Likewise.
+	(find_no_debuginfo): New.
+	(struct getdbg): Likewise.
+	(getdbg_dwflmod): Likewise.
+	(show_symbols): Take fd. If the file is ET_REL use libdwfl to get
+	the relocated Dwarf.
+
+2015-12-02  Mark Wielaard  <mjw@redhat.com>
+
+	* nm.c (get_local_names): Check for duplicates in local_root tree.
+
+2015-12-02  Mark Wielaard  <mjw@redhat.com>
+
+	* unstrip.c (struct data_list): New.
+	(new_data_list): Likewise.
+	(record_new_data): Likewise.
+	(free_new_data): Likewise.
+	(adjust_relocs): Call record_new_data.
+	(add_new_section_symbols): Likewise.
+	(copy_elided_sections): Call free_new_data.
+
+2015-12-01  Mark Wielaard  <mjw@redhat.com>
+
+	* elfcmp.c (main): Close ebl1 and ebl2 backends.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am [BUILD_STATIC](libdw): Add -lz.
+	[BUILD_STATIC](libelf): Likewise.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_symtab): Don't check TLS symbol value against TLS
+	phdr offset in debuginfo files.
+	(check_sections): Don't try to match section offsets to phdrs offsets
+	in debuginfo files.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_reloc_shdr): Reject only desthdrs if they have both
+	SHF_MERGE and SHF_STRINGS set.
+
+2015-10-13  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* elflint.c (check_sections): Do not rely on
+	ebl_check_special_section when checking debuginfo files.  Also
+	check that the type of WE sections in debuginfo files is NOBITS.
+
+2015-10-13  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_program_header): Check relro flags are a subset
+	of the load segment if they don't fully overlap.
+
+2015-10-07  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (ldlex_no_Wstack_usage): New.
+	* ldlex.l ([RWX]): Make cnt unsigned.
+
+2015-10-09  Josh Stone  <jistone@redhat.com>
+
+	* elflint.c (main): Replace stat64 and fstat64 with stat and fstat.
+	* readelf.c (process_file): Likewise.
+	(process_elf_file): Replace off64_t with off_t.
+	* findtextrel.c (process_file): Replace open64 with open.
+	* ld.c (main): Replace sizeof (off64_t) with 8.
+	* strings.c: Replace off64_t with off_t throughout.
+	(main): Replace stat64 and fstat64 with stat and fstat.
+	(map_file): Replace mmap64 with mmap.
+	(read_block): Likewise, and replace lseek64 with lseek.
+	* strip.c (handle_elf): Replace ftruncate64 with ftruncate.
+	(process_file): Replace stat64 and fstat64 with stat and fstat.
+	* unstrip.c (parse_opt): Replace stat64 with stat.
+	(handle_file): Replace open64 with open.
+	(open_file): Likewise.
+
+2015-10-08  Chih-Hung Hsieh  <chh@google.com>
+
+	* ld.c (determine_output_format): Move recursive nested
+	function "try" to file scope.
+
+2015-10-04  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (handle_elf): Only sanity check section symbols to not
+	kept discarded sections if we are creating a debug file.
+
+2015-10-07  Mark Wielaard  <mjw@redhat.com>
+
+	* unstrip.c (MAX): Removed.
+	(find_alloc_sections_prelink): Allocate exact amount of bytes for
+	shdrs.
+
+2015-10-05  Chih-Hung Hsieh <chh@google.com>
+
+	* unstrip.c (find_alloc_sections_prelink): Do not allocate
+	on stack union types with variable length arrays; use xmalloc
+	for such dynamic sized objects.
+	* readelf.c (handle_core_item): Likewise, but use alloca
+	for small variable size data object and add assert(count < 128).
+
+2015-10-05  Josh Stone  <jistone@redhat.com>
+
+	* Makefile.am (libld_elf_i386.so): Add AM_V_CCLD silencer.
+	(.deps/none_ld.Po): Always silence the dummy command.
+	(make-debug-archive): Add AM_V_GEN and AM_V_at silencers.
+
+2015-10-02  Mark Wielaard  <mjw@redhat.com>
+
+	* unstrip.c (copy_elided_sections): Use SH_INFO_LINK_P, not just
+	SHF_INFO_LINK.
+
+2015-10-02  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (handle_elf): Don't move around allocated NOBITS sections.
+	Don't just mark the section header string table as unused.
+	* unstrip.c (copy_elided_sections): Add header names to strtab if
+	shstrndx equals the symtab strtabndx.
+
+2015-09-22  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (cleanup_debug): Remove old-style function definitions.
+
+2015-09-09  Chih-Hung Hsieh  <chh@google.com>
+
+	* readelf.c (print_debug_exception_table): Initialize variable before
+	it is used, because compiler does not know that error never returns.
+	(dump_arhive_index): Likewise.
+
+2015-09-04  Chih-Hung Hsieh  <chh@google.com>
+
+	* elflint.c (check_group): Replace %Z length modifier with %z.
+	(check_note_data): Likewise.
+	* findtextrel.c (process_file): Likewise.
+	* readelf.c (handle_dynamic): Likewise.
+	(handle_symtab): Likewise.
+	(handle_verneed): Likewise.
+	(handle_verdef): Likewise.
+	(handle_versym): Likewise.
+	(print_hash_info): Likewise.
+	(print_decoded_aranges_section): Likewise.
+	(print_debug_aranges_section): Likewise.
+	(print_debug_line_section): Likewise.
+	(hex_dump): Likewise.
+	(dump_data_section): Likewise.
+	(print_string_section): Likewise.
+	(dump_archive_index): Likewise.
+	* unstrip.c (adjust_relocs): Likewise.
+	(collect_symbols): likewise.
+	(get_section_name): Likewise.
+	(find_alloc_sections_prelink): Likewise.
+	(copy_elided_sections): Likewise.
+	* ldscript.y (add_id_list): Add missing '%s'.
+
+2015-09-03  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_core_item): Handle right shift >= 32 bits.
+
+2015-08-11  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_sections): When gnuld and a NOBITS section falls
+	inside a segment make sure any ELF file contents is zero.
+
+2015-07-29  Mark Wielaard  <mjw@redhat.com>
+
+	* unstrip.c (sections_flags_match): New function.
+	(sections_match): Use sections_flags_match.
+	(find_alloc_sections_prelink): Only clear matched sections if there
+	is an undo section.
+	(copy_elided_sections): Add SHF_INFO_LINK to shdr_mem.sh_flags if
+	necessary.
+
+2015-06-27  Pino Toscano  <toscano.pino@tiscali.it>
+
+	* src/strings.c: Define MAP_POPULATE if not defined already.
+
+2015-06-27  Mark Wielaard  <mjw@redhat.com>
+
+	* nm.c (show_symbols): First call elf_getdata, then allocate memory.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* findtextrel.c (process_file): Free segments after use.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_phdr): Make sure phdr2_mem lifetime/scope equals
+	phdr2 pointer.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_gnu_hash): Free lengths on invalid_data.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_symtab): Only check the PT_TLS phdr if it actually
+	exists. Warn otherwise.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* nm.c (show_symbols): Check sizeof (sym_mem[0]), not GElf_Sym to
+	known whether or not we stack allocated memory.
+
+2015-06-18  Mark Wielaard  <mjw@redhat.com>
+
+	* strings.c (readelf): Use "<unknown>" if we cannot retrieve section
+	name.
+
+2015-06-09  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (print_dwarf_function): Always free scopes before
+	returning.
+
+2015-06-09  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (handle_ar): Mark as unused.
+	(process_file): Produce an error when trying to handle an ar.
+
+2015-05-30  Mark Wielaard  <mjw@redhat.com>
+
+	* elfcmp.c (main): Only call memcmp when d_size != 0.
+
+2015-05-23  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Define ldgeneric, readelf, nm, size, strip, elflint,
+	findtextrel, elfcmp objdump, ranlib, ar and unstrip no_Wstack_usage.
+
+2015-05-21  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (handle_address): Set scopes to NULL after free.
+
+2015-05-20  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (OPT_PRETTY): New constant define.
+	(argp_option): Add "pretty-print".
+	(pretty): New static bool.
+	(parse_opt): Set pretty.
+	(print_dwarf_function): Adjust output when pretty is set.
+	(print_addrsym): Likewise.
+	(handle_address): Likewise.
+
+2015-05-20  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (addr2line_LDADD): Add demanglelib.
+	* addr2line.c (argp_option): Move demangle under output format.
+	(demangle): New static bool.
+	(demangle_buffer_len): New static size_t.
+	(demangle_buffer): New static char *.
+	(main): free demangle_buffer.
+	(parse_opt): Set demangle.
+	(symname): New static function.
+	(get_diename): Use symname.
+	(print_dwarf_function): Likewise.
+	(print_addrsym): Likewise.
+	(handle_address): Likewise.
+
+2015-05-20  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (argp_option): Add "addresses", 'a'.
+	(print_addresses): New static bool.
+	(parse_opt): Set print_addresses.
+	(get_addr_width): New static function.
+	(handle_address): Print address if print_addresses is true.
+
+2015-05-20  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (handle_address): Call strtoumax with base 16. Make
+	sure all input has been processed.
+
+2015-05-20  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line (argp_option): Group 'section' under "Input format
+	options".
+
+2015-05-12  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (debug_fd): New static variable.
+	(tmp_debug_fname): Likewise.
+	(cleanup_debug): New function using the above to clean up temporary
+	debug file.
+	(INTERNAL_ERROR): Call cleanup_debug.
+	(handle_elf): Use debug_fd and tmp_debug_fname statics and call
+	cleanup_debug before any error. Use output_fname instead of fname in
+	error messages when it exists (-o was given). SHT_NOBITS sections
+	can also be moved freely even if SHF_ALLOC is set. Add various
+	sanity checks. Use elf_assert instead of plain assert.
+
+2015-05-08  Mark Wielaard  <mjw@redhat.com>
+
+	* nm.c (show_symbols): Call gelf_fsize with EV_CURRENT.
+	* strip.c (handle_elf): Likewise.
+
+2015-05-06  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_gnu_hash): Return early when 2nd hash function
+	shift too big. Check there is enough data available. Make sure
+	bitmask_words is not zero.
+	(check_verdef): Use Elf64_Word for shdr->sh_info cnt.
+	(check_verneed): Likewise.
+	(check_attributes): Break when vendor name isn't terminated.
+	Add overflow check for subsection_len.
+
+2015-05-05  Mark Wielaard  <mjw@redhat.com>
+
+	* nm.c (show_symbols): Handle dwarf_linesrc returning NULL.
+
+2015-05-04  Max Filippov  <jcmvbkbc@gmail.com>
+
+	* ar.c (do_oper_extract): Replace struct timeval with struct timespec
+	and futimes with futimens.
+	* strip.c (process_file): Replace struct timeval with struct timespec.
+	(handle_elf, handle_ar): Replace struct timeval with struct timespec
+	in prototype. Replace futimes with futimens.
+
+2015-05-04  Max Filippov  <jcmvbkbc@gmail.com>
+
+	* addr2line.c (main): Drop mtrace() call and #include <mcheck.h>.
+	* ar.c: Likewise.
+	* ld.c: Likewise.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c: Likewise.
+	* size.c: Likewise.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise.
+
+2015-05-04  Anthony G. Basile  <blueness@gentoo.org>
+
+	* Makefile.am (readelf_LDADD, nm_LDADD, size_LDADD, strip_LDADD)
+	(ld_LDADD, elflint_LDADD, findtextrel_LDADD, addr2line_LDADD)
+	(elfcmp_LDADD, objdump_LDADD, ranlib_LDADD, strings_LDADD)
+	(ar_LDADD, unstrip_LDADD, stack_LDADD): Append $(argp_LDADD).
+
+2015-03-22  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_frame_section): Cast start to Dwarf_Off
+	before subtracting cie_id. And cast cie_offset to Dwarf_Off before
+	comparison.
+
+2015-03-22  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_gdb_index_section): Check all offsets used
+	against section d_size.
+
+2015-03-17  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug): Don't return, but always use dummy_dbg.
+
+2015-03-17  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_gdb_index_section): Add overflow checking for
+	dataend checks.
+
+2015-03-14  Mark Wielaard  <mjw@redhat.com>
+
+	* nm.c (INTERNAL_ERROR): Remove __DATE__.
+	* objdump.c (INTERNAL_ERROR): Likewise.
+	* size.c (INTERNAL_ERROR): Likewise.
+	* strip.c (INTERNAL_ERROR): Likewise.
+
+2015-03-18  Petr Machata  <pmachata@redhat.com>
+
+	* readelf.c (dwarf_tag_string, dwarf_attr_string)
+	(dwarf_form_string, dwarf_lang_string, dwarf_inline_string)
+	(dwarf_encoding_string, dwarf_access_string)
+	(dwarf_visibility_string, dwarf_virtuality_string)
+	(dwarf_identifier_case_string, dwarf_calling_convention_string)
+	(dwarf_ordering_string, dwarf_discr_list_string)
+	(dwarf_locexpr_opcode_string): Adjust uses of know-dwarf.h macros
+	to match the API changes.
+
+2015-03-09  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (compare_hash_gnu_hash): Correct gnu_symbias usage.
+
+2015-01-03  Mark Wielaard  <mjw@redhat.com>
+
+	* elfcmp (main): Check section name is not NULL. Check sh_entsize
+	is not zero for symbol tables. Check phdrs are not NULL.
+	(search_for_copy_reloc): Check sh_entsize is not zero.
+
+2014-12-30  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_scn_group): Check d_buf and name are not NULL.
+	(is_rel_dyn): Check d is not NULL. Check shdr->sh_entsize is not
+	zero.
+	(check_dynamic): Check strshdr is not NULL. Check d_tag is positive.
+	(check_symtab_shndx): Check symshdr and data->d_buf are not NULL.
+	Check shdr and symshdr sh_entsize are not zero.
+	(check_gnu_hash): Make sure maskidx is smaller than bitmask_words.
+	Check symshdr->sh_entsize is not zero. Check data->d_buf is not
+	NULL.
+	(compare_hash_gnu_hash): Check sections d_buf are not NULL.
+	Check section data is large enough. Use gnu_symbias.
+	(check_group): Check section val is valid.
+	(has_copy_reloc): Check sh_entsize is not zero.
+	(check_versym): Likewise.
+	(unknown_dependency_p): Likewise.
+	(check_verneed): Break on invalid ref or offset. Don't assert.
+	Report error when next offset is zero, but more vers expected.
+	(check_verdef): Likewise.
+	(check_attributes): Make sure d_buf is not NULL.
+	(check_note): Likewise.
+	(check_note_section): Likewise.
+	(check_program_header): Make sure section name is not NULL.
+
+2014-12-26  Mark Wielaard  <mjw@redhat.com>
+
+	* strings.c (read_elf): Produce error when section data falls outside
+	file.
+
+2014-12-26  Mark Wielaard  <mjw@redhat.com>
+
+	* nm.c (show_symbols): Guard against divide by zero in error check.
+	Add section index number in error message.
+
+2014-12-26  Mark Wielaard  <mjw@redhat.com>
+
+	* nm.c (handle_ar): Skip over /SYM64/ entries.
+
+2014-12-26  Mark Wielaard  <mjw@redhat.com>
+
+	* nm.c (handle_ar): Break on arsym with invalid offset.
+
+2014-12-20  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_macinfo_section): Mark cus sentinel files
+	as -1 non-existent. Check macoff against sentinel cus.
+
+2014-12-20  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_exception_table): Add max_action overflow
+	check. Check action_table_end before reading slib128. Check
+	max_ar_filter underflow.
+
+2014-12-18  Ulrich Drepper  <drepper@gmail.com>
+
+	* Makefile.am: Suppress output of textrel_check command.
+
+2014-12-17  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_cfa_program): Add bounds check before each op that
+	takes at least one argument.
+
+2014-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_decoded_line_section): Print dwarf_errmsg if
+	dwarf_onesrcline or dwarf_linesrc fails.
+
+2014-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_line_section): Correct overflow check for
+	unit_length.
+	(print_debug_aranges_section): Correct overflow check for length.
+
+2014-12-15  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (notice_listptr): Return false if offset doesn't fit
+	in 61-bits.
+	(attr_callback): Warn if loclist or rangelist offset doesn't fit.
+
+2014-12-15  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_ops): Don't assert when addr_size or ref_size
+	is not 4 or 8, just report invalid data.
+
+2014-12-15  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_gdb_index_section): Add more bounds checks.
+
+2014-12-15  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_line_section): Check there is enough room
+	for DW_LNE_set_address argument. Make sure there is enough room
+	for the the initial unit_length.
+
+2014-12-14  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_attributes): Call get_uleb128 with end pointer.
+	* readelf.c (print_attributes): Likewise.
+	(print_ops): Likewise and also for get_sleb128.
+	(print_cfa_program): Likewise and add more readp bounds checks.
+	(read_encoded): Likewise.
+	(print_debug_frame_section): Likewise.
+	(print_debug_line_section): Likewise.
+	(print_debug_macinfo_section): Likewise.
+	(print_debug_macro_section): Likewise.
+	(print_debug_exception_table): Likewise.
+
+2014-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* elfcmp.c (compare_Elf32_Word): Make sure (unsigned) Elf32_Word
+	difference doesn't wrap around before returning as int.
+
+2014-12-11  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_exception_table): Check TType base offset
+	and Action table are sane.
+
+2014-12-11  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_frame_section): Check number of augmentation
+	chars to print.
+
+2014-12-09  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_file_note): Check count fits data section and
+	doesn't overflow fptr.
+
+2014-12-08  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_exception_table): Report invalid data if
+	action table doesn't immediately follow call site table.
+
+2014-12-10  Josh Stone  <jistone@redhat.com>
+
+	* addr2line.c (get_diename): New, get linkage_name or name.
+	* addr2line.c (print_dwarf_function): Use get_diename.
+	* addr2line.c (handle_address): Likewise.
+	* addr2line.c (print_diesym): Removed.
+
+2014-12-10  Josh Stone  <jistone@redhat.com>
+
+	* addr2line.c (handle_address): Find the proper inline parents.
+
+2014-12-07  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_line_section): max_ops_per_instr cannot
+	be zero.
+
+2014-12-07  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_ops): Handle zero ref_size for DW_OP_call_ref
+	and DW_OP_GNU_implicit_pointer.
+
+2014-12-04  Mark Wielaard  <mjw@redhat.com>
+
+	* objdump.c (show_relocs_x): Make sure destshdr exists.
+	(show_relocs_rel): Don't rely on shdr->sh_entsize, use gelf_fsize.
+	(show_relocs_rela): Likewise.
+	(show_relocs): Make sure destshdr, symshdr and symdata exists.
+
+2014-11-30  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_sysv_hash64): Fix overflow check.
+
+2014-11-28  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_relocs_rel): Don't reuse destshdr to store
+	section header of a relocation against a STT_SECTION symbol. Use
+	a new local variable secshdr.
+	(handle_relocs_rela): Likewise.
+
+2014-11-26  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_aranges_section): Cast Dwarf_Word length
+	to ptrdiff_t for comparison.
+
+2014-11-24  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_line_section): Check line_range is not zero
+	before usage.
+
+2014-11-23  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_aranges_section): Check length to catch
+	nexthdr overflow.
+
+2014-11-21  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_attributes): Guard against empty section.
+	Document attribute format. Break when vendor name isn't terminated.
+	Add overflow check for subsection_len. Handle both gnu and non-gnu
+	attribute tags.
+
+2014-11-22  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_sections): Call ebl_bss_plt_p without ehdr.
+	* findtextrel.c (process_file): Use elf_getphdrnum.
+	* readelf.c (process_elf_file): Remove redundant ehdr->e_phoff check.
+	(print_phdr): Check phnum.
+	* size.c (show_segments): Use elf_getphdrnum.
+	* strip.c (handle_elf): Likewise.
+	* unstrip.c (copy_elf): Likewise.
+	(copy_elided_sections): Likewise.
+	(handle_file): Likewise.
+
+2014-11-18  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_cfa_program): Fix sanity check of DW_FORM_block
+	length.
+
+2014-11-17  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_verneed): Check vna_next and vn_next exist.
+	(handle_verdef): Check vda_next and vd_next exist.
+	(handle_versym): Check vd_next, vna_next and vn_next exist.
+	Check vername and filename are not NULL before use.
+
+2014-11-17  Mark Wielaard  <mjw@redhat.com>
+
+	* elfcmp.c (main): Check section names are NULL before use.
+	* objdump.c (section_match): Likewise.
+	* size.c (show_sysv): Likewise.
+
+2014-11-17  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_frame_section): Warn if ptr_size is not 4
+	or 8 instead of just calling print_cfa_program.
+
+2014-11-16  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf (process_elf_file): Set phnum to zero if there aren't
+	actually any pheaders.
+	(print_phdr): Check there actually is a phdr.
+
+2014-11-16  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_cfa_program): Check block len before calling
+	print_ops.
+
+2014-11-14  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_frame_section): Sanity Check CIE
+	unit_length and augmentationlen.
+
+2014-11-14  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_versym): Check def == NULL before use.
+
+2014-11-08  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_versym): Initialize vername and filename array
+	elements.
+
+2014-11-07  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_sysv_hash): Sanity check section contents.
+	(handle_sysv_hash64): Likewise.
+	(handle_gnu_hash): Likewise.
+
+2014-09-14  Petr Machata  <pmachata@redhat.com>
+
+	* readelf.c (handle_relocs_rela): Typo fix, test DESTSHDR properly.
+
+2014-09-12  Petr Machata  <pmachata@redhat.com>
+
+	* readelf.c (encoded_ptr_size): In the switch statement, change
+	magic constants 3 and 4 to DW_EH_PE_* counterparts.  Still accept
+	0.  Print diagnostic for anything else.
+
+2014-08-25  Josh Stone  <jistone@redhat.com>
+
+	* Makefile.am: Prevent premature @AR@ replacement in a sed expression.
+
+2014-07-04  Menanteau Guy  <menantea@linux.vnet.ibm.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* elflint (check_symtab): Add ".TOC." to the list of possibly
+	dangling symbols because of sourceware PR13621.
+
+2014-06-14  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint (check_symtab): Use ebl_func_addr_mask on st_value.
+
+2014-05-27  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug): Skip section if name is NULL.
+
+2014-05-26  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_relocs_rela): Print header like handle_relocs_rel
+	does, when sh_info == 0.
+
+2014-05-26  Mark Wielaard  <mjw@redhat.com>
+
+	* unstrip.c (find_alloc_sections_prelink): Allow non-split .bss
+	section when sh_size of the original and undo .bss section are equal.
+
+2014-05-26  Mark Wielaard  <mjw@redhat.com>
+
+	* unstrip.c (options): Add --force, -F.
+	(struct arg_info): Add bool force.
+	(parse_opt): Handle 'F', set force.
+	(handle_explicit_files): Add force argument, add warn function,
+	separate check ehdr field checks, use warn.
+	(handle_dwfl_module): Add force argument, pass on to
+	handle_explicit_files.
+	(handle_output_dir_module): Add force argument, pass on to
+	handle_dwfl_module.
+	(handle_implicit_modules): Pass info->force to handle_dwfl_module and
+	handle_output_dir_module.
+	(main): Pass info.force to handle_explicit_files.
+
+2014-05-19  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_reloc_shdr): Check ebl_check_reloc_target_type.
+
+2014-05-01  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (find_no_debuginfo): Call dwfl_standard_find_debuginfo
+	if looking for alternate debug file.
+
+2014-04-11  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (AM_CPPFLAGS): Add -I libdwelf.
+
+2014-04-22  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_core_item): Make sure variable length array
+	contains at least enough space for terminating zero char.
+
+2014-04-22  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_gdb_index_section): Use unsigned int for 31 bits
+	left shift.
+
+2014-03-13  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Remove no_mudflap.os. Remove libmudflap from all
+	LDADD lines.
+	* strings.c (process_chunk): Remove _MUDFLAP condition.
+
+2014-04-09  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_aranges_section): Don't get the raw section
+	data, use the possibly decompressed .[z]debug sectiondata.
+	(print_debug_ranges_section): Likewise.
+	(print_debug_frame_section): Likewise.
+	(print_debug_line_section): Likewise.
+	(print_debug_loc_section): Likewise.
+	(print_debug_macinfo_section): Likewise.
+	(print_debug_macro_section): Likewise.
+
+2014-04-10  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (buf_read_ulong): Pass actual long size to convert.
+
+2014-03-05  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (attr_callback): Print DW_FORM_sdata values as signed
+	numbers.
+
+2014-02-24  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf (print_phdr): Check there is a SHT_PROGBITS section at the
+	offset given by p_offsets for a PT_INTERP segment before trying to
+	display the interpreter string.
+
+2014-02-07  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_phdr): Check phdr->p_filesz and make sure
+	interpreter string is zero terminated before calling printf.
+
+2014-01-22  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (nm_no_Wformat): Removed.
+	(size_no_Wformat): Likewise.
+	(strings_no_Wformat): Likewise.
+	(addr2line_no_Wformat): Likewise.
+	* size.c (show_sysv): Use fmtstr directly as literal in printf.
+	(show_sysv_one_line): Likewise.
+	* strings.c (locfmt): Removed.
+	(radix): New static enum.
+	(parse_opt): Set radix, not locfmt.
+	(process_chunk_mb): Use fmtstr directly as literal in printf based
+	on radix.
+	(process_chunk): Likewise.
+	* nm.c (show_symbols_sysv): Use fmtstr directly as literal in printf.
+	(show_symbols_bsd): Likewise.
+	(show_symbols_posix): Likewise.
+
+2014-01-21  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (show_inlines): New static boolean.
+	(print_frame): New function split out from...
+	(print_frames): ..here. If show_inlines is true and we found a
+	DIE for the frame address, call print_inline_frames otherwise
+	call print_frame. Keep track of and track frame_nr.
+	(print_inline_frames): New function.
+	(parse_opt): Handle '-i'.
+	(main): Add 'i' to options.
+
+2014-01-27  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (maxframes): Initialize to 256.
+	(main): Document new default in options. Document magic number
+	used in frames.allocated initialization.
+
+2014-01-20  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (show_debugname): New static boolean.
+	(die_name): New function.
+	(print_frames): If show_debugname is true set symname to the
+	first function-like DIE with a name in scope for the address in
+	the debuginfo.
+	(parse_opt): Handle '-d'.
+	(main): Add 'd' to options.
+
+2014-01-20  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (handle_address): Initialize scopes to NULL.
+
+2014-01-17  Roland McGrath  <roland@redhat.com>
+
+	* strip.c (handle_elf): Check for bogus values in sh_link, sh_info,
+	st_shndx, e_shstrndx, and SHT_GROUP or SHT_SYMTAB_SHNDX data.
+	Don't use assert on input values, instead bail with "illformed" error.
+
+2014-01-17  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (handle_dynamic, handle_symtab): Check for bogus sh_link.
+	(handle_verneed, handle_verdef, handle_versym, handle_hash): Likewise.
+	(handle_scngrp): Check for bogus sh_info.
+
+2014-01-17  Jakub Jelinek  <jakub@redhat.com>
+
+	* elflint.c (section_name): Return "<invalid>" instead of
+	crashing on invalid section name.
+	(check_symtab, is_rel_dyn, check_rela, check_rel, check_dynamic,
+	check_symtab_shndx, check_hash, check_versym): Robustify.
+	(check_hash): Don't check entries beyond end of section.
+	(check_note): Don't crash if gelf_rawchunk fails.
+
+2014-01-17  Petr Machata  <pmachata@redhat.com>
+
+	* readelf.c (handle_dynamic, handle_relocs_rel)
+	(handle_relocs_rela, handle_versym, print_liblist):
+	Use gelf_fsize instead of relying on shdr->sh_entsize.
+
+2014-01-14  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_macro_section): Clear vendor array before
+	use.
+
+2014-01-15  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Fix corruption of non-C++ symbols by the demangler.
+	* nm.c (show_symbols_sysv, show_symbols_bsd, show_symbols_posix)
+	(show_symbols): Check for _Z.
+	* stack.c (print_frames) <USE_DEMANGLE>: Check for _Z.
+
+2014-01-02  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (show_raw): Declare unconditionally.
+	(parse_opt): Handle '-r' unconditionally.
+	(main): Show "raw" option even without USE_DEMANGLE.
+
+2014-01-02  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (print_frames): Print 0x before build-id hex-offset.
+
+2014-01-02  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (maxframes): Increase to 2048.
+	(struct frames): Add allocated field.
+	(frame_callback): If frames used is frames allocated, realloc.
+	(print_frames): Show an error if maxframes has been reached.
+	(parse_opt): Allow -n 0 for unlimited frames.
+	(main): Document -n 0 and new default 2048 frames. Allocate initial
+	number of frames with malloc.
+
+2013-12-30  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (parse_opt): Explicitly call dwfl_linux_proc_attach
+	or dwfl_core_file_attach and check for errors.
+
+2013-12-28  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (print_frames): Remove address width code and use...
+	(get_addr_width): ...this new function.
+	(show_modules): New static boolean.
+	(module_callback): New static function.
+	(parse_opt): Handle '-l'.
+	(main): Add 'l' to options. If show_modules then use dwfl_getmodules
+	with module_callback to show all detected modules and possible
+	build_id, elf and dwarf files.
+
+2013-12-27  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (frames_shown): New static boolean.
+	(EXIT_OK,EXIT_ERROR,EXIT_BAD,EXIT_USAGES): New defines.
+	(frame_callback): Return -1 on error. Don't print error.
+	(print_frames): Add arguments, tid, dwflerr and what. Print tid.
+	If there was an error report it with address and module if possible.
+	Record whether any frames were actually printed.
+	(thread_callback): Collect tid and err, pass it to print_frames.
+	(parse_opt): Use EXIT_BAD for errors. On ARGP_KEY_END print errno
+	if dwfl_linux_proc_report returned it. Check whether we are properly
+	attached with dwfl_pid.
+	(main): Document exit status. Don't report DWARF_CB_ABORT from
+	callbacks as error. Pass real errors to print_frames. Return
+	EXIT_BAD if no frames could be shown. Return EXIT_ERROR if there
+	were any non-fatal errors.
+
+2013-12-23  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (stack_LDADD): Add demanglelib.
+	* stack.c (show_quiet): New static boolean, default false.
+	(show_raw): Likewise.
+	(demangle_buffer_len): New static size_t.
+	(demangle_buffer): New static char *.
+	(print_frames): Don't resolve pc name if show_quiet. Demangle name
+	unless show_raw.
+	(parse_opt): Handle '-q' and '-r'.
+	(main): Add 'q' and 'r' to options. Free demangle_buffer.
+
+2013-12-23  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (OPT_DEBUGINFO): New define.
+	(OPT_COREFILE): Likewise.
+	(pid): New static.
+	(core_fd): Likewise.
+	(core): Likewise.
+	(exec): Likewise.
+	(debuginfo_path): Likewise.
+	(parse_opt): Handle '-p', '--core', '-e' and '--debuginfo-path'.
+	Do argument sanity checking. Setup Dwfl.
+	(main): Add 'p', 'core', 'e' and 'debuginfo-path' to options.
+	Remove argp_child children, simplify argp doc, remove custom
+	usage message and construction of dwfl with dwfl_standard_argp.
+	Use pid directly as tid. close core and core_fd if opened. Print
+	pid of process or core.
+
+2013-12-23  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (show_build_id): New static boolean.
+	(print_frames): Print module build-id, load address and pc offset
+	if show_build_id is true.
+	(parse_opt): Handle '-b'.
+	(main): Add -b to options.
+
+2013-12-22  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (maxframes): New static unsigned. Initialize to 64.
+	(struct frame): New struct.
+	(struct frames): Likewise.
+	(dwfl): New static Dwfl pointer.
+	(frame_callback): Use arg as struct frames and fill it next frame.
+	Return DWARF_CB_ABORT when maxframes has been reached. Move
+	printing of frame to...
+	(print_frames): ...here. New function.
+	(thread_callback): Use arg as struct frames and set frames to zero.
+	Call print_frames.
+	(parse_opt): Handle '-n'.
+	(main): Add -n to options. Allocate frames using maxframes. Pass
+	frames to frame_callback and thread_callback.
+
+2013-12-20  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (show_one_tid): New static boolean.
+	(parse_opt): Handle '-1'.
+	(main): Add -1 to options. Call dwfl_getthread_frames when
+	show_one_tid is true.
+
+2013-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (options): Add symbol-sections, 'x'.
+	(show_symbol_sections): New static bool.
+	(parse_opt): Handle 'x'.
+	(print_addrsym): Use dwfl_module_addrinfo value.r
+	Also show section of address with show_symbol_sections.
+	(find_symbol): Use dwfl_module_getsym_info and set value.
+	(handle_address): Request value and use it instead of sym.st_value.
+	* readelf.c (format_dwarf_addr): Use dwfl_module_addrinfo to get
+	name and offset.
+
+2013-12-17  Masatake YAMATO  <yamato@redhat.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c (show_activation, show_module, show_source): New variables.
+	(parse_opt): Set show_activation if -a option is given.
+	Set show_module if -m option is given. Set show_source if -s option
+	is given. Set all show booleans when -v option is given.
+	(main): Added `-a', `-m', `-s', and `-v' to the help message.
+	(frame_callback): Print module and source file information.
+
+2013-11-25  Petr Machata  <pmachata@redhat.com>
+
+	* elflint.c (valid_e_machine): Add EM_AARCH64.
+
+2013-11-14  Petr Machata  <pmachata@redhat.com>
+
+	* readelf.c (handle_core_item) <'h'>: New branch for handling
+	fields that shouldn't be displayed.
+
+2013-11-10  Mark Wielaard  <mjw@redhat.com>
+
+	* stack.c: Use ARGP_PROGRAM_VERSION_HOOK_DEF and
+	ARGP_PROGRAM_BUG_ADDRESS_DEF.
+	(print_version): New function.
+
+2013-11-09  Mark Wielaard  <mjw@redhat.com>
+
+	* arlib.c (arlib_init): Call snprintf before using the result
+	with memcpy.
+	(arlib_finalize): Likewise.
+	* nm.c (show_symbols_sysv): Don't modify cnt inside assert.
+
+2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* Makefile.am (bin_PROGRAMS): Add stack.
+	(stack_LDADD): New.
+	* stack.c: New file.
+
+2013-11-05  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_ranges_section): Cast address to size_t
+	before comparison.
+	(print_debug_loc_section): Likewise.
+
+2013-10-18  Mark Wielaard  <mjw@redhat.com>
+
+	* ar.c (main): Correct operation check when instance_specifed is set.
+
+2013-09-26  Petr Machata  <pmachata@redhat.com>
+
+	* readelf.c (handle_file_note): New function.
+	(handle_notes_data): Call it to handle NT_FILE notes.
+
+2013-09-26  Petr Machata  <pmachata@redhat.com>
+
+	* readelf.c (handle_siginfo_note): New function.
+	(handle_notes_data): Call it to handle NT_SIGINFO notes.
+	(buf_read_int, buf_read_ulong, buf_has_data): New functions.
+
+2013-08-13  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (options): Add "inlines", 'i'.
+	(show_inlines): New bool.
+	(parse_opt): Handle 'i'.
+	(print_diesym): New static function.
+	(print_src): New function taking code from...
+	(handle_address): here. Call print_src. Print inlines.
+
+2013-08-12  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (main): If there is a newline char at end of buf,
+	then remove it.
+
+2013-07-05  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_ops): Take CU as argument, use it to print
+	parameter_ref DIE offset.
+	(struct listptr): Replace base field with cu.
+	(listptr_base): New function.
+	(compare_listptr): Use listptr_base.
+	(notice_listptr): Take CU as argument.
+	(skip_listptr_hole): Likewise.
+	(print_debug_ranges_section): Pass NULL as CU to skip_listptr_hole.
+	(print_cfa_program): Pass NULL as CU to print_ops.
+	(struct attrcb_args): Replace cu_base field with cu.
+	(attr_callback): Pass cu not cu_base to notice_listptr.
+	(print_debug_units): Don't calculate base, just set cu.
+	(print_debug_loc_section): Pass cu to skip_listptr_hole and
+	print_ops.
+
+2013-05-06  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_ops): Format first DW_OP_GNU_implicit_pointer
+	argument as DIE offset.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+
+2013-03-25  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (argp_options): Add decodedline.
+	(decodedline): New boolean initialized to false.
+	(parse_opt): Set decodedline when arg is decodedline.
+	(print_decoded_line_section): New function.
+	(print_debug_line_section): Call print_decoded_line_section when
+	decodedline is true.
+
+2013-03-25  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (argp_option): Add decodedaranges.
+	(decodedaranges): New boolean initialized to false.
+	(parse_opt): Set decodedaranges when arg is decodedaranges.
+	(print_debug_aranges_section): Reimplemented and original
+	implementation renamed to...
+	(print_decoded_aranges_section): this.
+
+2013-03-25  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (attrcb_args): Add Dwarf_Die.
+	(attr_callback): When highpc is in constant form also print as
+	address.
+	(print_debug_units): Set args.die.
+
+2013-03-19  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_gdb_index_section): Free format_dwarf_addr results.
+
+2013-03-18  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_gdb_index_section): Accept version 8.
+
+2013-03-01  Mark Wielaard  <mjw@redhat.com>
+
+	* findtextrel.c (process_file): Release ELF and close file when not
+	text relocations are found.
+	* strip.c (handle_elf): Track memory used for .debuglink section data
+	and free when done.
+
+2013-02-24  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_symtab): Add __bss_start__ to the list of symbols
+	allowed to have out of section values because of GNU ld bugs.
+
+2013-02-06  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_symtab): Add __bss_start and __TMC_END__ to the
+	list of symbols allowed to have out of section values because of
+	GNU ld bugs in either .symtab or .dynsym, but only when they are
+	zero sized.
+
+2013-01-24  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (argp_option): Add unresolved-address-offsets, U.
+	(print_unresolved_addresses): New static.
+	(parse_opt): Handle 'U', set print_unprocessed_values.
+	(format_dwarf_addr): Take and handle new raw argument.
+	(print_ops): Call format_dwarf_addr with raw offset values.
+	(print_debug_ranges_section): Likewise.
+	(print_debug_frame_section): Likewise.
+	(attr_callback): Likewise.
+	(print_debug_line_section): Likewise.
+	(print_debug_loc_section): Likewise.
+	(print_gdb_index_section): Likewise.
+
+2013-01-18  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (struct listptr): Add base Dwarf_Addr field.
+	(compare_listptr): Warn for same offset with different base.
+	(notice_listptr): Take base argument and set it.
+	(skip_listptr_hole): Likewise.
+	(struct attrcb_args): Removed unused cu_offset field.
+	Add cu_base Dwarf_Addr field.
+	(attr_callback): Call notice_listptr with cbargs->cu_base.
+	(print_debug_units): Set args.cu_base.
+	(print_debug_ranges_section): Get base and use for format_dwarf_addr.
+	(print_debug_loc_section): Likewise.
+
+2013-01-29  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* readelf.c (handle_core_items): Limit special repeated items handling
+	to single-item formats '\n', 'b' and 'B', assert OFFSET 0 there.
+
+2012-12-18  Mark Wielaard  <mark@bordewijk.wildebeest.org>
+
+	* readelf.c (ELF_INPUT_SECTION): New argp key value.
+	(argp_option): Add elf-section.
+	(elf_input_section): New static.
+	(parse_opt): Handle ELF_INPUT_SECTION and set elf_input_section.
+	(open_input_section): New function.
+	(process_file): Call open_input_section if elf_input_section set.
+
+2013-01-13  David Abdurachmanov  <David.Abdurachmanov@cern.ch>
+
+	ar.c (do_oper_delete): Fix num passed to memset.
+
+2012-12-21  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_frame_section): Adjust FDE start address
+	if pcrel before feeding it to format_dwarf_addr.
+
+2012-12-21  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (main): Call dwfl_end.
+
+2012-12-11  Roland McGrath  <roland@hack.frob.com>
+
+	* nm.c (show_symbols_sysv): Fix size passed to snprintf for invalid
+	sh_name case.
+	Reported by David Abdurachmanov <David.Abdurachmanov@cern.ch>.
+
+2012-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_ops): DW_OP_skip and DW_OP_bra targets are
+	calculated beginning after the operand and 2-byte constant.
+
+2012-10-12  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* readelf.c (ITEM_WRAP_COLUMN, REGISTER_WRAP_COLUMN): Merge to ...
+	(WRAP_COLUMN): ... here.
+	(print_core_item): Remove parameter format_max.  Update function
+	comment.  Replace FORMAT_MAX by the real output width.
+	(handle_core_item): Remove the FORMAT_MAX values in TYPES, DO_TYPE,
+	calls of print_core_item, remove variable maxfmt, change
+	ITEM_WRAP_COLUMN to WRAP_COLUMN.
+	(handle_core_register): Remove the FORMAT_MAX values in TYPES, BITS,
+	calls of print_core_item, change REGISTER_WRAP_COLUMN to WRAP_COLUMN.
+
+2012-10-11  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* readelf.c (handle_core_item) <b>: Make run an outer block variable.
+	Increase run only if LASTBIT != 0.  Print last element only if RUN > 0.
+
+2012-08-27  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_macro_section): Print offset as PRIx64.
+
+2012-08-27  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (register_info): Handle loc == NULL.
+
+2012-08-22  Jeff Kenton  <jkenton@tilera.com>
+
+	* elflint.c (valid_e_machine): Add EM_TILEGX and EM_TILEPRO.
+
+2012-08-16  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (dwarf_tag_name): Renamed from dwarf_tag_string.
+	Uses new dwarf_tag_string or adds ??? or lo_user+%#x when
+	appropriate.
+	(dwarf_attr_name): Likewise.
+	(dwarf_form_name): Likewise.
+	(dwarf_lang_name): Likewise.
+	(dwarf_inline_name): Likewise.
+	(dwarf_encoding_name): Likewise.
+	(dwarf_access_name): Likewise.
+	(dwarf_visibility_name): Likewise.
+	(dwarf_virtuality_name): Likewise.
+	(dwarf_identifier_case_name): Likewise.
+	(dwarf_calling_convention_name): Likewise.
+	(dwarf_ordering_name): Likewise.
+	(dwarf_discr_list_name): Likewise.
+	(print_ops): Remove KNOWN.  Use dwarf_locexpr_opcode_string.
+	(attr_callback): Call new dwarf_foobar_name instead of old
+	dwarf_foobar_string functions.
+	(dwarf_tag_string): New function using known-dwarf.h macros.
+	(dwarf_attr_string): Likewise.
+	(dwarf_form_string): Likewise.
+	(dwarf_lang_string): Likewise.
+	(dwarf_inline_string): Likewise.
+	(dwarf_encoding_string): Likewise.
+	(dwarf_access_string): Likewise.
+	(dwarf_visibility_string): Likewise.
+	(dwarf_virtuality_string): Likewise.
+	(dwarf_identifier_case_string): Likewise.
+	(dwarf_calling_convention_string): Likewise.
+	(dwarf_ordering_string): Likewise.
+	(dwarf_discr_list_string): Likewise.
+	(dwarf_locexpr_opcode_string): Likewise.
+
+2012-06-27  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (dwarf_form_string): Handle DW_FORM_GNU_ref_alt and
+	DW_FORM_GNU_strp_alt.
+	(attr_callback): Likewise.
+
+2012-07-30  Petr Machata  <pmachata@redhat.com>
+
+	* nm.c (show_symbols_bsd): Reorder arguments in {S,}FMTSTRS (and
+	corresponding printf) so that those that are referenced by only
+	one of the formatting strings are at the end.
+
+2012-07-29  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (dwarf_lang_string): Use DW_LANG_ObjC, not DW_LANG_Objc.
+	(print_ops): Use known[op], not op_name, for DW_OP_GNU_parameter_ref.
+
+2012-07-19  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_ops): Handle DW_OP_GNU_parameter_ref.
+
+2012-07-11  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (options): Add macro to help of debug-dump.
+	(section_e): Add section_macro.
+	(section_all): Add section_macro.
+	(parse_opt): Handle macro.
+	(print_debug_macro_section): New function.
+	(print_debug): Add NEW_SECTION (macro).
+
+2012-07-10  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_gdb_index_section): Add version 7 support.
+	Keep track of cu_nr. Print kind and static/global flag for each
+	symbol. When a symbol is in the TU list add 'T'.
+
+2012-06-26  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (dwarf_attr_string): Add DW_AT_GNU_macros.
+
+2012-06-22  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_ops): Cast printf PRIu/x64 arguments to uint64_t
+	for gcc 4.7 -Wformat.
+
+2012-05-09  Roland McGrath  <roland@hack.frob.com>
+
+	* elflint (check_sections): Allow zero sized sections at (filesz) end
+	of segment. And make check overflow-proofed.
+
+2012-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_ops): Add DW_OP_GNU_push_tls_address,
+	DW_OP_GNU_uinit and DW_OP_GNU_encoded_addr.
+
+2012-03-28  Roland McGrath  <roland@hack.frob.com>
+
+	* elflint.c (special_sections): Accept SHF_INFO_LINK for reloc sections.
+
+2012-03-28  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_debug_abbrev_section): Check there is Dwarf
+	section data.
+	(print_debug_str_section): Likewise.
+
+2012-03-21  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_gdb_index_section): Accept version 6.
+
+2012-01-31  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (attr_callback): Don't special case DW_FORM_sec_offset.
+
+2012-01-21  Ulrich Drepper  <drepper@gmail.com>
+
+	* addr2line.c: Update copyright year.
+	* ar.c: Likewise.
+	* elfcmp.c: Likewise.
+	* elflint.c: Likewise.
+	* findtextrel.c: Likewise.
+	* ld.c: Likewise.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c: Likewise.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* strings.c: Likewise.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise.
+
+	* nm.c (argp_children): Define.
+	(argp): Hook up argp_children.
+	(handle_ar): Optimize puts call.
+	(show_symbols_bsd): Use positional parameters to also print color
+	codes.  Don't print STT_FILE symbols.
+	* objdump.c (options): Improve help text.
+	(argp_children): Define.
+	(argp): Hook up argp_children.
+	(disasm_info): Add elements for color codes.
+	(disasm_output): Print color codes as well.
+	(show_disasm): Set up disasm_info data for callback.
+
+2012-01-20  Roland McGrath  <roland@hack.frob.com>
+
+	* arlib-argp.c (arlib_deterministic_output): Initialize from
+	configured value.
+	(help_filter): New function.
+	(argp): Use it.
+
+	* ar.c (main): Handle oper_none as usage error.
+
+	* arlib-argp.c (options, parse_opt): Grok -U as inverse of -D.
+
+	* ranlib.c (argp): Use arlib_argp_children.
+
+	* arlib.c (arlib_init): Obey arlib_deterministic_output.
+
+	* arlib-argp.c: New file.
+	* Makefile.am (libar_a_SOURCES): Add it.
+	* arlib.h (arlib_deterministic_output, arlib_argp_children):
+	Declare new variables.
+	* ar.c (deterministic_output): Variable removed.
+	(do_oper_insert): Use arlib_deterministic_output instead.
+	(options, parse_opt): Don't handle -D here.  Add group numbers.
+	(argp): Use arlib_argp_children.
+
+2011-12-20  Roland McGrath  <roland@hack.frob.com>
+
+	* readelf.c (print_debug): Initialize DUMMY_DBG.elf.
+	Reported by Karel Klic <kklic@redhat.com>.
+
+2011-11-05  Roland McGrath  <roland@hack.frob.com>
+
+	* ar.c (deterministic_output): New flag variable.
+	(options, parse_opt): Grok -D to set it.
+	(do_oper_insert): When set, use zero from mtime, uid, and gid.
+
+	* ar.c (do_oper_insert): Fix check on elf_rawfile return value.
+
+2011-10-04  Marek Polacek  <mpolacek@redhat.com>
+
+	* readelf.c (register_info): Assume the right size of an array.
+
+2011-10-03  Ulrich Drepper  <drepper@gmail.com>
+
+	* nm.c: Recognize option --mark-special.  Still recognize --mark-weak
+	but don't show it in help anymore.
+	(mark_special): Renamed from mark_weak.
+	(parse_opt): Adjust.
+	(class_type_char): Take additional parameters for ELF file and ELF
+	header.  Treat TLS symbols like objects.
+	In case of D symbols, show u for unique symbols, R for symbols in
+	read-only sections, B for symbols in BSS sections.
+	(show_symbols_bsd): Take additional parameters for ELF file and ELF
+	header.  Adjust for class_type_char change.  Show TLS symbols with
+	@ after them in case --mark-special is selected.
+	(show_symbols_posix): Likewise.
+	(show_symbols): Adjust calls to show_symbols_bsd and
+	show_symbols_posix.
+	(show_symbols_sysv): Avoid printing adress and size for undefined
+	symbols.  Don't print initial special entry and section entries.
+
+2011-10-02  Ulrich Drepper  <drepper@gmail.com>
+
+	* Makefile.am (demanglelib): Define.
+	(nm_LDADD): Add demanglelib.
+	* nm.c (options): Add -C option.
+	(demangle): Define as global variable.
+	(parse_opt): Recognize -C.
+	(show_symbols_sysv): Handle demangling.
+	(show_symbols_bad): Likewise.
+	(show_symbols_posix): Likewise.
+	(show_symbols): Likewise.
+
+2011-07-09  Roland McGrath  <roland@hack.frob.com>
+
+	* readelf.c (options, parse_opt): Grok -W/--wide and ignore it.
+
+	* ar.c (parse_opt): Grok -u.
+
+2011-05-30  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (relocate): Make offset check overflow-proof.
+
+2011-05-23  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (relocate): Take new arguments is_rela to indicate
+	whether the relocation is from a SHT_REL or SHT_RELA section.
+	Relocate against any debug section symbol, not just STT_SECTION
+	symbols. For SHT_REL relocations, fetch addend from offset and
+	add it to symbol value if not zero.
+
+2011-05-23  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (OPT_RELOC_DEBUG): New option.
+	(argp_option): Add new --reloc-debug-sections option.
+	(main): Check new option.
+	(parse_opt): Likewise.
+	(handle_elf): Remove any relocations between debug sections
+	in ET_REL for the debug file when requested.
+
+2011-05-18  Mark Wielaard  <mjw@redhat.com>
+
+	* strip.c (handle_elf): Make sure all sections of a removed group
+	section are removed too. Don't discard SHT_GROUP sections, copy
+	section table before it gets modified. Section group signature
+	symbols don't have to be retained.
+
+2011-05-16  Jakub Jelinek  <jakub@redhat.com>
+
+	* readelf.c (print_ops): Handle DW_OP_GNU_const_type,
+	DW_OP_GNU_regval_type, DW_OP_GNU_deref_type, DW_OP_GNU_convert
+	and DW_OP_GNU_reinterpret.
+
+2011-05-17  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (dwarf_tag_string): Fixup DW_TAG_GNU_call_site and
+	DW_TAG_GNU_call_site_parameter return strings.
+
+2011-05-11  Marek Polacek  <mpolacek@redhat.com>
+
+	* nm.c (show_symbols_sysv): Remove unused if/else, remove
+	unused `prefix' and `fname' parameters.
+
+2011-05-07  Marek Polacek  <mpolacek@redhat.com>
+
+	* unstrip.c (compare_sections_nonrel): Mark this function as static.
+
+2011-04-26  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (handle_notes_data): Call ebl_object_note_type_name
+	with note name.
+
+2011-04-14  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (options): Add gdb_index.
+	(section_e): Define section_gdb_index.
+	(parse_opt): Recognize gdb_index debug-dump argument.
+	(print_gdb_index_section): New function.
+	(print_debug): Add gdb_index to debug_sections.
+
+2011-03-24  Petr Machata  <pmachata@redhat.com>
+
+	* readelf.c (print_debug_line_section): Emit initial space for all
+	opcode lines.  Print offset in front of each opcode.
+
+2011-03-22  Marek Polacek  <mpolacek@redhat.com>
+
+	* readelf.c (handle_dynamic): Don't segfault at DT_PLTREL case.
+
+2011-03-22  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (dwarf_tag_string): Support DW_TAG_GNU_call_site
+	and DW_TAG_GNU_call_site_parameter.
+	(dwarf_attr_string): Support DW_AT_GNU_call_site_value,
+	DW_AT_GNU_call_site_data_value,
+	DW_AT_GNU_call_site_target,
+	DW_AT_GNU_call_site_target_clobbered,
+	DW_AT_GNU_tail_call,
+	DW_AT_GNU_all_tail_call_sites,
+	DW_AT_GNU_all_call_sites,
+	and DW_AT_GNU_all_source_call_sites.
+	(print_ops): Handle DW_OP_GNU_entry_value.
+	(attr_callback): Handle DW_AT_GNU_call_site_value,
+	DW_AT_GNU_call_site_data_value,
+	DW_AT_GNU_call_site_target,
+	and DW_AT_GNU_call_site_target_clobbered.
+
+2011-03-10  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_symtab): Use ebl_check_st_other_bits.
+
+2011-02-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* readelf.c (reset_listptr): Clear TABLE->TABLE.
+
+2011-02-25  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (dwarf_attr_string): Add DW_AT_GNU_* handling.
+	(dwarf_form_string): Properly format and return unknown form.
+
+2011-02-23  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (section_name): New function.
+	(print_debug_abbrev_section): Use it instead of constant.
+	(print_debug_aranges_section): Likewise.
+	(print_debug_ranges_section): Likewise.
+	(print_debug_units): Likewise.
+	(print_debug_line_section): Likewise.
+	(print_debug_loc_section): Likewise.
+	(print_debug_macinfo_section): Likewise.
+	(print_debug_pubnames_section): Likewise.
+	(print_debug_str_section): Likewise.
+	(print_debug) [USE_ZLIB]: Match .zdebug_* sections too.
+	(print_debug_abbrev_section): Use decoded d_size, not sh_size.
+	(print_debug_str_section): Likewise.
+
+	* readelf.c (dwarf_attr_string): Grok DW_AT_GNU_odr_signature.
+
+2011-02-11  Roland McGrath  <roland@redhat.com>
+
+	* elfcmp.c (verbose): New variable.
+	(options, parse_opt): Grok -l/--verbose to set it.
+	(main): Under -l, keep going after first difference.
+
+	* elfcmp.c (ignore_build_id): New variable.
+	(options, parse_opt): Grok --ignore-build-id to set it.
+	(main): For SHT_NOTE sections, compare note details rather than raw
+	bytes.  Under --ignore-build-id, don't complain about differing build
+	ID contents if lengths match.
+
+2011-02-08  Roland McGrath  <roland@redhat.com>
+
+	* ldscript.y (filename_id_star): Remove unused variable.
+
+	* unstrip.c (copy_elided_sections): Remove unused variable.
+
+	* elflint.c (check_dynamic): Remove unused variables.
+
+	* elflint.c (check_symtab): Warn about missing xndx section only once.
+
+	* ldgeneric.c (check_for_duplicate2): Remove unused variable.
+
+2011-01-06  Roland McGrath  <roland@redhat.com>
+
+	* strip.c (handle_elf): Under --strip-sections, remove all
+	non-allocated sections and never generate .gnu_debuglink.
+
+2011-01-04  Roland McGrath  <roland@redhat.com>
+
+	* strip.c (remove_shdrs): New variable.
+	(options, parse_opt): Grok --strip-sections to set it.
+	(handle_elf): When that's set, truncate off .shstrtab and shdrs.
+
+2010-11-10  Roland McGrath  <roland@redhat.com>
+
+	* findtextrel.c (process_file): Don't assume order of sections.
+	Reported by Mike Hommey <mh@glandium.org>.
+
+2010-07-26  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_ops): Handle DW_OP_GNU_implicit_pointer.
+
+2010-08-30  Roland McGrath  <roland@redhat.com>
+
+	Print .debug_loc/.debug_ranges with cognizance of actual DIE uses.
+	* readelf.c (parse_opt): Add section_info to implicit_debug_sections
+	for ranges, loc.
+	(struct listptr, struct listptr_table): New types.
+	(compare_listptr, reset_listptr, sort_listptr): New functions.
+	(notice_listptr, skip_listptr_hole): New functions.
+	(struct attrcb_args): Add silent member.
+	(attr_callback): Call notice_listptr for loclistptr and rangelistptr.
+	Suppress output if silent, but still call notice_listptr.
+	(print_debug_units): Suppress output if section_info not requested.
+	(print_debug_loc_section): Call sort_listptr, skip_listptr_hole.
+	(print_debug_ranges_section): Likewise.
+	(print_debug): Call reset_listptr on both tables.
+
+	* readelf.c (print_debug_ranges_section): Print empty list.
+	(print_debug_loc_section): Likewise.
+
+	* readelf.c (print_debug_loc_section): Check for bogus length
+	before calling print_ops.
+	(print_ops): Check harder for bogus data that would read off end.
+
+2010-08-11  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (for_each_section_argument): Process all sections with
+	matching name, not just the first.
+
+2010-07-26  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_ops): Take new argument for CU version.
+	Fix DW_OP_call_ref decoding to depend on it.
+	(print_debug_loc_section): Update caller.
+	(print_cfa_program): Take new argument, pass it down.
+	(print_debug_frame_section): Update caller.
+	(struct attrcb_args): New member version.
+	(print_debug_units): Initialize it.
+
+2010-07-02  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_debug_frame_section): Use format_dwarf_addr for
+	initial_location.
+
+2010-06-30  Roland McGrath  <roland@redhat.com>
+
+	* strings.c (main): Use STDIN_FILENO, not STDOUT_FILENO.
+	Ignore st_size for a non-S_ISREG file descriptor.
+	(read_block): Move assert after no-mmap bail-out.
+	(read_block_no_mmap): Fix size calculations for moving buffer remnant.
+
+2010-06-22  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_debug_line_section): Fix braino in DW_LNS_set_isa.
+
+2010-06-21  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (dwarf_tag_string): Handle new v4 tags.
+	(dwarf_attr_string): Add new attributes.
+	(dwarf_tag_string): Handle DW_TAG_GNU_*.
+
+	* readelf.c (print_ops): Use 64-bit types for LEB128 operands.
+	(print_cfa_program): Likewise.
+
+2010-06-20  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_debug_units): New function, broken out of ...
+	(print_debug_info_section): ... here.  Call it.
+	(print_debug_types_section): New function.
+	(enum section_e): Add section_types alias for section_info.
+	(print_debug): Add types to the sections table.
+
+	* readelf.c (print_debug_frame_section): Handle version 4 format.
+
+	* readelf.c (print_debug_line_section): Handle version 4 format.
+
+2010-06-14  Roland McGrath  <roland@redhat.com>
+
+	* unstrip.c (copy_elided_sections): Make sure all sections' data have
+	been read in before we write anything out.
+
+2010-06-04  Roland McGrath  <roland@redhat.com>
+
+	* unstrip.c (update_shdr): New function.
+	(update_sh_size): Call it instead of gelf_update_shdr.
+	(adjust_relocs, add_new_section_symbols): Likewise.
+	(new_shstrtab, copy_elided_sections): Likewise.
+
+	* unstrip.c (copy_elided_sections): Bail if stripped file has more
+	sections than unstripped file, rather than getting confused later.
+
+2010-06-01  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (dwarf_form_string): Handle DWARF 4 forms.
+	(attr_callback): Handle DW_FORM_flag_present, DW_FORM_exprloc,
+	DW_FORM_sec_offset, DW_FORM_ref_sig8.
+
+	* readelf.c (print_debug): Don't bail if libdw setup fails.
+	Suppress complaint if we only want .eh_frame anyway.
+
+2010-05-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (attr_callback): Also print form information.
+
+2010-05-19  Roland McGrath  <roland@redhat.com>
+
+	* addr2line.c (find_symbol): Short-circuit on empty name.
+	(handle_address): Handle SYMBOL with no +OFFSET.
+
+2010-05-08  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_ops): Take new arg OFFSET_SIZE.
+	Use that for DW_OP_call_ref, not ADDRSIZE.
+	(print_cfa_program): Update caller.
+	(struct attrcb_args): Add offset_size field.
+	(attr_callback): Use it for print_ops call.
+	(print_debug_info_section): Initialize it.
+	(print_ops): Likewise.
+
+2010-04-14  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (handle_core_item): Fix bitmask printing.
+
+2010-04-06  Roland McGrath  <roland@redhat.com>
+
+	* ld.c (options): Fix some typos in messages.
+	* elflint.c (check_scn_group, check_group): Likewise.
+	* ldscript.y (add_id_list): Likewise.
+	* readelf.c (print_hash_info): Add xgettext:no-c-format magic comment
+	before translated string containing a literal %.
+
+2010-02-26  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (process_file): Don't leak an fd in failure case.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Use config/eu.am for common stuff.
+
+	* readelf.c (print_debug_frame_section): Add a cast to avoid sign
+	mismatch in comparison.
+
+2010-02-02  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_encoding_base): Handle DW_EH_PE_absptr (zero).
+	(read_encoded): Likewise.
+	(print_debug_frame_section): Check for bogus augmentation length.
+	For P augmentation, use read_encoded, print the encoding description,
+	and use hex for unsigned values.
+
+2010-01-15  Roland McGrath  <roland@redhat.com>
+
+	* ar.c: Include <sys/stat.h>.
+	* elflint.c: Likewise.
+	* readelf.c: Likewise.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise
+
+2010-01-07  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_ehdr): Handle PN_XNUM.
+	(phnum): New static variable.
+	(process_elf_file): Set it with elf_getphdrnum.
+	(print_phdr): Use phnum instead of EHDR->e_phnum.
+	(print_dynamic, handle_notes): Likewise.
+	(handle_relocs_rel, handle_relocs_rela): Likewise.
+
+	* elfcmp.c (main): Use elf_getshdrnum and elf_getphdrnum.
+
+	* elflint.c (phnum): New static variable.
+	(check_elf_header): Set it, handling PN_XNUM.
+	Use that in place of EHDR->e_phnum throughout.
+	(check_symtab, check_reloc_shdr, check_dynamic): Likewise.
+	(unknown_dependency_p, check_sections, check_program_header): Likewise.
+
+2010-01-05  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (dwarf_attr_string): Match DW_AT_GNU_vector and
+	DW_AT_GNU_template_name.
+
+2010-01-04  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (handle_notes_data): Grab NT_AUXV only for name "CORE".
+	(handle_core_note): Pass NHDR and NAME to ebl_core_note.
+	(handle_core_item): Handle .format of '\n' as \n-separated strings.
+
+	* readelf.c (implicit_debug_sections): New variable.
+	(parse_opt): Set it instead of print_debug_sections for -a.
+	OR them together for print_debug check.
+	(print_debug): OR them together for section check.
+
+	* readelf.c (options): Repartition into set implied by -a and others.
+	Correct -a text to match reality.
+
+	* readelf.c (struct section_argument): Add bool member 'implicit'.
+	(parse_opt): Set it for -a cases, clear it for -x args.
+	(for_each_section_argument): Don't complain about a missing section by
+	name if it's implicit.
+
+2009-11-16  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_string_section): Punt SHT_NOBITS like empty
+	sections, just as dump_data_section already does.
+
+2009-09-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (special_sections): Allow MERGE and STRINGS flags to be
+	set for .comment section.
+	Patch by Mark Wielaard <mjw@redhat.com>.
+
+2009-09-08  Roland McGrath  <roland@redhat.com>
+
+	* ar.c (main): Fix typo in message format.
+
+2009-08-21  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (attr_callback): Use print_block only when we don't use
+	print_ops.
+
+2009-08-14  Roland McGrath  <roland@redhat.com>
+
+	* ar.c (do_oper_extract): Use pathconf instead of statfs.
+
+2009-08-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* debugpred.h: Add two most const.
+
+2009-07-26  Mark Wielaard  <mjw@redhat.com>
+
+	* elflint.c (check_note_data): Recognize NT_GNU_GOLD_VERSION.
+
+2009-07-25  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (addr2line_LDADD): Add $(libelf).
+
+2009-07-24  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_block): New function.
+	(print_ops): Use it.
+	(attr_callback): Use it for DW_FORM_block* forms.
+
+2009-07-20  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (print_ops): Add handling of DW_OP_implicit_value
+	and DW_OP_stack_value.
+
+2009-07-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_elf_header): Allow Linux ABI.
+	(check_symtab): Handle STB_GNU_UNIQUE.
+
+2009-07-08  Mark Wielaard  <mjw@redhat.com>
+
+	* readelf.c (attr_callback): Handle DW_Form constants for
+	DW_AT_data_member_location.
+
+2009-07-06  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (register_info): New function.  Handle unknown register #s.
+	(print_cfa_program): Use it.
+	(handle_core_register, handle_core_registers): Likewise.
+
+2009-06-28  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_address_names): New static variable.
+	(options, parse_opt): Grok -N/--numeric-addresses to clear it.
+	(format_dwarf_addr): Don't look up name if !print_address_names.
+
+2009-06-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* ldgeneric.c: Don't use deprecated libelf functions.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise.
+	* ld.h: Fix up comment.
+
+2009-06-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (print_relocs): Expect ELF header argument and pass on
+	to handle_relocs_rel* functions. Adjust caller.
+	(handle_relocs_rel): Add ELF header argument.  Add special case for
+	the IRELATIVE relocations in statically linked executables.
+	(handle_relocs_rela): Likewise.
+
+2009-04-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_symtab): Add tests of st_other field.
+
+2009-04-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile [BUILD_STATIC] (libdw): Add $(zip_LIBS).
+
+2009-04-20  Roland McGrath  <roland@redhat.com>
+
+	* addr2line.c (print_dwarf_function): Honor -s and -A for file names
+	of inline call sites.
+
+	* addr2line.c (just_section): New variable.
+	(adjust_to_section): New function, broken out of ...
+	(handle_address): ... here.
+	(options, parse_opt): Add -j/--section=NAME to set it.
+
+2009-04-15  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_debug_frame_section): Check for DW_CIE_ID_64 in
+	64-bit format header, DW_CIE_ID_32 in 32-bit format header.
+
+2009-04-14  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_attributes): Treat SHT_ARM_ATTRIBUTES on EM_ARM
+	like SHT_GNU_ATTRIBUTES.
+
+	* readelf.c (handle_core_registers): Fix error message.
+
+	* strip.c (handle_elf: check_preserved): Don't note any change when
+	.debug_data is already filled from a previous pass.
+
+2009-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* objdump.c (show_relocs_x): Minor cleanups.
+
+	* readelf.c (print_cfa_program): Correct a few labels.
+	Print first DW_CFA_expression and DW_CFA_val_expression parameter
+	as register.
+
+2009-02-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* objdump.c (show_relocs_rel, show_relocs_rela): Split common parts
+	into ...
+	(show_relocs_x): ...here.  New function.
+	(show_relocs): Better spacing in output.
+
+	* objdump.c (show_relocs_rela): Show offsets as signed values.
+
+	* ar.c (main): Fix recognition of invalid modes for a, b, i modifiers.
+	Improve some error messages.
+	Use program_invocation_short_name instead of AR macro.
+	* Makefile.am (CFLAGS_ar): Remove.
+	* elflint.c (parse_opt): ARGP_HELP_EXIT_ERR does nothing for argp_help.
+	* objdump.c (parse_opt): Likewise.
+	* readelf.c (parse_opt): Likewise.
+
+2009-01-27  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_ops): Notice short length, don't overrun buffer
+	(still need to fix LEB128).
+
+	* readelf.c (print_ops): Fix DW_OP_call[24] decoding.
+
+	* readelf.c (print_ops): Print (empty)\n when LEN == 0.
+
+2009-01-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (print_debug_frame_section): Fix computation of vma_base
+	for PC-relative mode.
+
+2009-01-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* size.c (process_file): When handling archive, close file descriptor
+	here.  For unknown file format also close file descriptor.
+	(handle_ar): Don't close file descriptor here.
+
+	* readelf.c (parse_opt): Move code to add to dump_data_sections and
+	string_sections list in local function add_dump_section.  Adjust 'x'
+	key handling.  For 'a' key add .strtab, .dynstr, and .comment section
+	to string_sections list.
+
+2009-01-22  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_phdr): Don't print section mapping when no sections.
+
+	* Makefile.am (AM_CFLAGS): Pass -Wno-format for *_no_Wformat.
+
+	* readelf.c (print_debug_frame_section): Initialize IS_SIGNED to false
+	and reset it only for the 'true' cases.
+
+	* Makefile.am (addr2line_no_Wformat): New variable.
+
+	* readelf.c (print_debug_frame_section): Use t instead of j formats
+	for ptrdiff_t OFFSET.
+
+2009-01-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_program_header): Fix typo in .eh_frame_hdr section
+	test.  Handle debuginfo files.
+	(check_exception_data): First sanity test.
+
+2009-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (print_debug_exception_table): Show target of ar_disp
+	field.
+
+	* elflint.c (check_program_header): Add most consistency checks for
+	PT_GNU_EH_FRAME entry.
+
+	* addr2line.c: Use ARGP_PROGRAM_VERSION_HOOK_DEF and
+	ARGP_PROGRAM_BUG_ADDRESS_DEF.
+	* ar.c: Likewise.
+	* elfcmp.c: Likewise.
+	* elflint.c: Likewise.
+	* findtextrel.c: Likewise.
+	* ld.c: Likewise.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c: Likewise.
+	* readelf.c: Likewise.
+
+	* size.c: Likewise.
+	* strings.c: Likewise.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise.
+
+2009-01-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_program_header): Check that PT_GNU_EH_FRAME entry
+	matches .eh_frame_hdr section, if it is available.  Also check that
+	the segment is allocated, not writable, not executable.
+
+	* readelf.c: Add -e option.  Dump exception and unwind related
+	sections.  Add -e to -a.
+	(print_encoding_base): Handle DW_EH_PE_omit.
+	(print_debug_exception_table): Beginning of support.
+	(print_debug): Hook up print_debug_exception_table for
+	.gcc_except_table sections.
+
+	* readelf.c (print_debug_frame_section): Some fixes for last change.
+
+2009-01-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (print_encoding): Now a toplevel function.
+	(print_relinfo): Likewise.
+	(print_encoding_base): Broken out of print_debug_frame_section.
+	(print_debug_frame_section): Print different header for .eh_frame
+	sections.  Fix recognition of matching CIEs in .debug_frame sections.
+	Print absolute offset for PC-relative FDE locations.  Don't print
+	table header for FDEs if the table is empty.
+	(read_encoded): New function.
+	(print_debug_frame_hdr_section): New function.
+	(print_debug): Hook up print_debug_frame_hdr_section for .eh_frame_hdr
+	sections.
+
+	* readelf.c (handle_relocs_rel): Print section number.
+	(print_debug_abbrev_section): Likewise.
+	(print_debug_aranges_section): Likewise.
+	(print_debug_ranges_section): Likewise.
+	(print_debug_info_section): Likewise.
+	(print_debug_line_section): Likewise.
+	(print_debug_loc_section): Likewise.
+	(print_debug_macinfo_section): Likewise.
+	(print_debug_pubnames_section): Likewise.
+	(print_debug_str_section): Likewise.
+
+2009-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* strings.c (read_block): Fix typo in error message string.
+
+2009-01-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* ld.c (ld_new_searchdir): Fix adding to search path list.
+
+2009-01-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c: Implement call frame debug section dumping.
+
+2009-01-05  Roland McGrath  <roland@redhat.com>
+
+	* elfcmp.c: Exit with status 2 for errors (like cmp, diff, grep).
+	Status 1 (aka EXIT_FAILURE) is only for completed OK but not equal.
+
+2009-01-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* addr2line.c: Update copyright year.
+	* ar.c: Likewise.
+	* elfcmp.c: Likewise.
+	* elflint.c: Likewise.
+	* findtextrel.c: Likewise.
+	* ld.c: Likewise.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c: Likewise.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* strings.c: Likewise.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise.
+
+2008-12-11  Roland McGrath  <roland@redhat.com>
+
+	* nm.c (sym_name): New function.
+	(show_symbols_sysv): Use it in place of elf_strptr.
+	(show_symbols_bsd, show_symbols_posix): Likewise.
+	Fixes RHBZ#476136.
+
+	* nm.c (show_symbols_sysv): Use an alloca'd backup section name when
+	elf_strptr fails.
+
+2008-12-02  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (count_dwflmod, process_file): Don't presume encoding of
+	nonzero OFFSET argument to dwfl_getmodules.
+
+2008-08-07  Roland McGrath  <roland@redhat.com>
+
+	* addr2line.c (main): Pass string to handle_address.
+	(see_one_module): New function, subroutine of handle_address.
+	(find_symbol): Likewise.
+	(handle_address): Take string argument rather than address.
+	Convert plain number, or handle strings like "(section)+offset"
+	or "symbol+offset".
+
+2008-08-01  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (handle_core_item): Handle 'B' type for 1-origin bitset.
+	For 'b' and 'B', print <x-y,z> or ~<x,y-z> rather than 1/0 string.
+
+	* readelf.c (convert): Take new argument SIZE.
+	(handle_core_register, handle_core_item): Update callers.
+	(handle_core_item): Take new arg REPEATED_SIZE.
+	(handle_core_items): Special case for a singleton item,
+	let handle_core_item handle repeats if it wants to.
+
+	* readelf.c (handle_core_items): Give abridged output
+	for identical groups repeated more than twice.
+
+2008-07-04  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (handle_core_items): Handle ELF_T_ADDR.
+
+2008-04-10  Roland McGrath  <roland@redhat.com>
+
+	* strip.c (handle_elf): Don't keep sections that kept symbol tables
+	refer to.  Instead, just be sure to preserve the original symbol
+	table in the debug file so those symbols go with their sections and
+	can be elided from the stripped version of the symbol table.
+
+	* strip.c (handle_elf): When a discarded section kept in the debug
+	file refers to a nondiscard section via sh_link/sh_info, preserve
+	that nondiscarded section unmodified in the debug file as well.
+	Skip adjustment of discarded sections symbol table references when
+	that symbol table is copied in this way.
+
+	* elflint.c (check_symtab): Don't crash from missing symbol names
+	after diagnosing bogus strtab.
+
+	* strip.c (handle_elf): Cosmetic cleanup in special section contents
+	adjustment for symtab changes.
+
+2008-03-31  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_sections): Add checks on SHF_EXECINSTR sections:
+	must be SHT_PROGBITS, must not be SHF_WRITE.  Let backend hook
+	excuse a special section.
+
+2008-03-27  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_sections): Check that executability and writability
+	of sections is reflected in segment p_flags.
+
+2008-03-26  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_program_header): Accept PT_GNU_RELRO p_flags
+	that matches its PT_LOAD's p_flags &~ PF_W.  On sparc, PF_X really
+	is valid in RELRO.
+
+2008-02-29  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_attributes): Add a cast.
+	* elflint.c (check_attributes): Likewise.
+
+	* unaligned.h (add_8ubyte_unaligned): Cast PTR argument for parity
+	with [UNALIGNED_ACCESS_CLASS == BYTE_ORDER] definition.
+	(add_4ubyte_unaligned, add_2ubyte_unaligned): Likewise.
+
+2008-02-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_ld.c (elf_i386_count_relocations): Implement R_386_TLS_GD
+	when linked into executable.
+	(elf_i386_create_relocations): Likewise.
+
+2008-02-20  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_attributes): New function.
+	(process_elf_file): Call it under -A.
+
+	* elflint.c (check_attributes): Implement it for real.
+
+2008-02-19  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (special_sections): Handle .gnu.attributes section.
+	(check_sections): Likewise.
+	(check_attributes): New function.
+
+2008-02-10  Roland McGrath  <roland@redhat.com>
+
+	* elfcmp.c (main): Ignore sh_offset differences in non-SHF_ALLOC
+	sections and ET_REL files.
+
+2008-02-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32-i386.script: Add .eh_frame_hdr, .tdata, and .tbss sections.
+	* i386_ld.c (elf_i386_count_relocations): Handle R_386_TLS_LDO_32
+	and R_386_TLS_LE.
+	(elf_i386_create_relocations): Likewise.
+	* ld.h (struct ld_state): Add need_tls, tls_start, and tls_tcb
+	elements.
+	* ldgeneric.c (add_section): If TLS section is used, set need_tls flag.
+	(ld_generic_create_outfile): Add PT_TLS entry to program  header.
+	Fix generation of PT_GNU_STACK entry.
+
+2008-02-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* ld.c (replace_args): Prevent loop over replacements if the parameter
+	is only two characters long.
+
+	* ld.c: Recognize sha1 argument for --build-id parameter.
+	* ldgeneric.c (create_build_id_section): Handle sha1.
+	(compute_hash_sum): New function.  Broken out of compute_build_id.
+	Take hash function and context as parameters.
+	(compute_build_id): Use compute_hash_sum for md5 and the new sha1
+	implementation.
+
+2008-01-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf32-i386.script: Add .note.ABI-tag and .note.gnu.build-id sections.
+	* ld.c: Recognize --build-id command line parameter.
+	* ld.h: Define scn_dot_note_gnu_build_id.
+	(struct ld_state): Add build_id and buildidscnidx elements.
+	* ldgeneric.c: Implement --build-id command line parameter.
+	* ldlex.l (ID): Recognize - as valid character after the first one.
+
+2008-01-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* ld.c (replace_args): New function.
+	(main): Use it to rewrite old-style parameters.
+
+	* elf32-i386.script: Add .gnu.hash section.
+	* ldgeneric.c (optimal_bucket_size): A tiny bit more efficient.
+	(fillin_special_symbol): Initialize st_size.
+	(sortfct_hashval): New function.
+	(create_gnu_hash): New function.
+	(create_hash): New function.
+	(ld_generic_create_outfile): Use the new functions to create the
+	hash tables.
+
+	* elflint.c (check_gnu_hash): Fix index value printed in error message.
+
+2008-01-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_group): Check that signature symbol for section
+	group is not an empty string.
+	* ldgeneric.c: Remove magic assignment of indeces in the dynsym
+	section.  Start implementation of --hash-style.
+	* i386_ld.c: Likewise.
+	* ld.c: Recognize --hash-style.
+	* ld.h (struct scninfo): Add comdat_group.
+	Add additional parameter to finalize_plt callback.
+
+2008-01-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* ld.h (struct callbacks): Add initialize_gotplt.
+	(struct scnhead): Add scn_dot_gotplt.
+	(struct ld_state): Add gotpltscnidx.
+	* i386_ld.c (elf_i386_initialize_plt): Minor optimization.
+	(elf_i386_initialize_pltrel): Likewise.
+	(elf_i386_initialize_got): There is now a separate .got.plt, so
+	don't do the PLT-related work here.  Initialize d_type.
+	(elf_i386_initialize_gotplt): New function.
+	(elf_i386_plt0): Use ud2a after indirect jump.
+	(elf_i386_pic_plt0_entry): Likewise.
+	(elf_i386_finalize_plt): Reference now .got.plt.
+	(elf_i386_count_relocations): For GOT entries which need no relocation
+	don't bump nrel_got.
+	(elf_i386_create_relocations): Also get .got.plt.  Rewrite R-386_GOT32
+	handling for split .got/.got.plt.
+	(elf_i386_ld_init): Initialize callbacks.initialize_gotplt.
+	* elf32-i386.script: Sort sections for security.  There are no .got
+	input sections.  Add .got.plt.
+	* ldgeneric.c (ld_generic_generate_sections): Add .got.plt section.
+	(ld_generic_create_outfile): Initialize .got.plt section.
+	Use .got.plt address for _GLOBAL_OFFSET_TABLE_ symbol and DT_PLTGOT.
+
+2008-01-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_ld.c (elf_i386_count_relocations): PLT relocations for undefined
+	symbols are not carried over into statically linked output files.
+	Add dummy entries for more TLS relocations.
+
+	* ld.c (options): Add long names for -( and -).
+
+	* ldgeneric.c (check_definition): For newly found definitions don't
+	mark section as used if symbol is absolute.
+	(extract_from_archive): Only assign archive sequence number the first
+	time the archive is handled.  Update ld_state.last_archive_used
+	if any symbol was used.  Remove nround variable.
+	(file_process2): When using symbol from an archive, update
+	ld_state.group_start_archive, ld_state.archives, and
+	ld_state.tailarchives.
+	(ld_generic_file_process): If group is not handled anymore, after
+	freeing ELF handles for the archives, clear ld_state.archives and
+	*nextp.  Fix wrong logic in recognizing first iteration of group
+	loop.  When clearing flags, also clear ld_state.group_start_archive.
+
+2008-01-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* objdump.c (show_disasm): Adjust disassembler format string for
+	removal of %e.
+
+2008-01-04  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (handle_core_items): Take new arg DESCSZ; if nonzero,
+	a size greater than the items cover means multiple sets of items.
+	(handle_core_note): Update caller.
+
+2008-01-04  Roland McGrath  <roland@redhat.com>
+
+	* strip.c (handle_elf): Move SHDRIDX defn to silence gcc warning.
+
+2008-01-03  Roland McGrath  <roland@redhat.com>
+
+	* ld.h (linked_from_dso_p): Use __attribute__ ((__gnu_inline__)).
+
+	* elflint.c (check_dynamic): Remove duplicate initializer.
+
+2008-01-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* addr2line.c: Update copyright year.
+	* ar.c: Likewise.
+	* elfcmp.c: Likewise.
+	* elflint.c: Likewise.
+	* findtextrel.c: Likewise.
+	* ld.c: Likewise.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c: Likewise.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* strings.c: Likewise.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise.
+
+2007-12-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* objdump (show_disasm): Use %e after third parameter.
+
+2007-12-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* strip.c: Fix wrong parenthesis in a few branch predictions.
+	* strings.c: Likewise.
+
+2007-12-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (DEFS): Add DEBUGPRED.
+	* addr2line.c: Include debugpred.h.
+	* ar.c: Likewise.
+	* elfcmp.c: Likewise.
+	* elflint.c: Likewise.
+	* findtextrel.c: Likewise.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c: Likewise.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* strings.c: Likewise.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise.
+	* debugpred.h: New file.
+
+	* readelf.c (handle_relocs_rel): Use elf_scnshndx.
+	(handle_relocs_rela): Likewise.
+
+	* readelf.c: Add lots of likely/unlikely.
+
+	* elflint.c: Minor cleanups.
+
+2007-11-19  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_ops): Handle all bad op codes gracefully.
+	Print their numbers instead of just ???.
+
+2007-11-09  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (attr_callback): Handle DW_AT_data_location.
+	Handle block forms to mean a DWARF expression for DW_AT_allocated,
+	DW_AT_associated, DW_AT_bit_size, DW_AT_bit_offset, DW_AT_bit_stride,
+	DW_AT_byte_size, DW_AT_byte_stride, DW_AT_count, DW_AT_lower_bound,
+	DW_AT_upper_bound.
+
+2007-10-20  Roland McGrath  <roland@redhat.com>
+
+	* unstrip.c (options): Update -R description.
+	(struct symbol): Put symbol details a union with a size_t pointer
+	`duplicate'.
+	(compare_symbols_output): Use null ->name as marker for discard
+	symbols, not zero *->map.
+	(copy_elided_sections): Record forwarding pointers for discarded
+	duplicates and fill SYMNDX_MAP elements through them.
+
+	* readelf.c (process_file): Set offline_next_address to 0 at start.
+	(struct process_dwflmod_args): New type.
+	(process_dwflmod): Take args in it, pass fd to process_elf_file.
+	(process_file): Update caller; dup FD for passing to libdwfl.
+	(process_elf_file): Take new arg FD.  For ET_REL file when
+	displaying data affected by libdwfl relocation, open a new Elf handle.
+
+2007-10-17  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_debug_line_section): For invalid data inside a
+	unit with plausible length, keep printing at the next unit boundary.
+
+	* readelf.c (attr_callback): Use dwarf_formref_die, not dwarf_formref.
+
+2007-10-16  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (hex_dump): Fix rounding error in whitespace calculation.
+
+2007-10-15  Roland McGrath  <roland@redhat.com>
+
+	* make-debug-archive.in: New file.
+	* Makefile.am (EXTRA_DIST): Add it.
+	(make-debug-archive): New target.
+	(bin_SCRIPTS, CLEANFILES): Add it.
+
+2007-10-10  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (special_sections): Add new attrflag value exact_or_gnuld.
+	Use it to check MERGE|STRINGS for .debug_str.
+	(check_sections): Handle exact_or_gnuld.
+
+2007-10-08  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (handle_core_item): Handle 'T'|0x80 to indicate
+	64-bit struct timeval with 32-bit tv_usec.
+
+2007-10-07  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (check_archive_index): New function.
+	(process_file): Call it.  Change signature to take only fd and name.
+	Use libdwfl to open the file, then iterate on its modules (multiple
+	for an archive) to print file name and call process_elf_file.
+	(main): Update caller.  Let process_file do elf_begin.
+	(count_dwflmod, process_dwflmod, find_no_debuginfo): New functions.
+	(process_elf_file): Take only Dwfl_Module * argument.
+	Don't print the file name here.
+	(print_debug_*_section): Take Dwfl_Module * argument.
+	(print_debug): Likewise.  Update caller.
+	(format_dwarf_addr): New function.
+	(print_debug_ranges_section): Use it.
+	(attr_callback): Likewise.
+	(print_debug_line_section, print_debug_loc_section): Likewise.
+
+	* readelf.c (print_debug_ranges_section): Translate all strings.
+	(print_debug_loc_section): Likewise.
+
+	* unstrip.c (copy_elided_sections): Initialize SEC.
+
+	* ar.c (do_oper_insert): Put trailing / on short names.
+
+	* arlib.h (MAX_AR_NAME_LEN): Decrease by one.
+
+	* arlib2.c (arlib_add_long_name): Adjust for header size.
+
+	* arlib.c (arlib_finalize): Pad long name table to keep size even.
+
+	* ar.c (do_oper_insert): Use write_retry for padding write.
+
+	* ar.c (do_oper_insert): Initialize CUR_OFF in no_old case.
+	Unconditionally set FOUND[CNT]->elf when setting ->mem.
+	(remember_long_name): New function.
+	(do_oper_insert): Call it.  Correctly use length of basename,
+	not original name.  Don't store long name twice for new member.
+
+2007-10-06  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_note): Skip empty segment.
+	(check_note_section): Skip empty section.
+
+	* unstrip.c (options, parse_opt, struct arg_info): Grok -R/--relocate.
+	(handle_output_dir_module, handle_implicit_modules): Pass it down.
+	(handle_dwfl_module): When set, use ET_REL already loaded by Dwfl.
+	(compare_alloc_sections): Take new arg REL, ignore address if true.
+	(compare_sections): Likewise, pass it down.
+	(compare_sections_rel, compare_sections_nonrel): New functions.
+	(find_alloc_sections_prelink, copy_elided_sections): Use them
+	instead of compare_sections.
+	(sections_match): New function, broken out of ...
+	(find_alloc_section): ... here.
+	(copy_elided_sections): Reorganize section match-up logic.
+	Use sections_match for SHF_ALLOC in ET_REL.
+	For ET_REL, let the nonzero sh_addr from the debug file dominate.
+
+	* unstrip.c (add_new_section_symbols): Take new arg REL.
+	When true, do not update section symbol values.
+	(collect_symbols): Likewise.  Update section symbols with address
+	of chosen output section, not original section.
+	(check_symtab_section_symbols, copy_elided_sections): Update callers.
+
+	* unstrip.c (compare_alloc_sections): At the same address, preserve
+	original section order.
+
+	* elflint.c (special_sections): Don't require MERGE|STRINGS for
+	.debug_str, it didn't always have them with older tools.
+
+	* elflint.c (check_symtab, check_one_reloc): Ignore sh_addr in ET_REL.
+
+2007-10-05  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_symtab): Allow SHN_UNDEF _GLOBAL_OFFSET_TABLE_ in
+	ET_REL file.
+
+	* elflint.c (check_symtab): For _GLOBAL_OFFSET_TABLE_, diagnose
+	SHN_UNDEF as "bad section".  Use shndx value in messages.
+
+	* elflint.c (special_sections): Add ".debug_str".  Decrement namelen
+	for ".debug" so it matches as a prefix.
+	(IS_KNOWN_SPECIAL): New macro.
+	(check_sections): Use it for ".plt" match.  Cite wrong SHT_NOBITS
+	type even under -d, for a .debug* or .shstrtab section.
+
+	* readelf.c (print_ops): Use hex for address operand.
+
+2007-10-04  Roland McGrath  <roland@redhat.com>
+
+	* unstrip.c (copy_elided_sections): Initialize NDX_SECTION element for
+	.gnu_debuglink section to SHN_UNDEF.  Drop STT_SECTION symbols for
+	sections mapped to SHN_UNDEF.
+
+2007-10-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (dump_archive_index): Avoid warning about uninitialized
+	variable with older glibc versions.
+	Add some branch prediction.
+
+2007-10-04  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_archive_index): New variable.
+	(options, parse_opt): Accept -c/--archive-index to set it.
+	(dump_archive_index): New function.
+	(process_file): Take new arg WILL_PRINT_ARCHIVE_INDEX.
+	Call dump_archive_index on archives if set.
+	(main): Update caller.
+	(any_control_option): Give it file scope, moved out of ...
+	(parse_opt): ... here.
+
+2007-10-03  Roland McGrath  <roland@redhat.com>
+
+	* unstrip.c (struct arg_info): Add `list' flag.
+	(options, parse_opt): Grok -n/--list to set it.
+	(list_module): New function.
+	(handle_implicit_modules): Call it under -n.
+
+	* elflint.c (check_note_section): New function.
+	(check_sections): Call it for SHT_NOTE.
+
+	* readelf.c (handle_notes): Use sections when available.
+
+	* elflint.c (check_note_data): New function, broken out of ...
+	(check_note): ... here.  Call it and elf_getdata_rawchunk.
+
+	* readelf.c (handle_auxv_note): Take offset as argument, not buffer.
+	Use elf_getdata_rawchunk and gelf_getauxv.
+	(handle_notes_data): New function, broken out of ...
+	(handle_notes): ... here.  Call it and elf_getdata_rawchunk.
+
+2007-10-01  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (hex_dump): Fix transposed subtraction generating spaces.
+
+	* readelf.c (hex_dump): Fix line header to be hex instead of decimal.
+
+2007-09-10  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (options): Give -p optional argument, alias --string-dump.
+	(string_sections, string_sections_tail): New static variables.
+	(parse_opt): Set them when -p has an argument.
+	(print_string_section): New function, broken out of ...
+	(print_strings): ... here.  Call it.
+	(dump_data_section): New function, broken out of ...
+	(dump_data): ... here.  Call it.
+	(for_each_section_argument): New function, broken out of ...
+	(dump_data): ... here.  Call it.
+	(dump_strings): New function.
+
+2007-08-31  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_strings): Typo fix.
+
+2007-08-23  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (printf_with_wrap): Function removed.
+	(REGISTER_WRAP_COLUMN): New macro.
+	(handle_core_register): Use print_core_item instead.
+	(struct register_info): New type.
+	(compare_registers, compare_register_sets): New functions.
+	(register_bitpos, compare_sets_by_info): New functions.
+	(handle_core_registers): Use those to segregate and sort registers
+	for display.
+
+	* readelf.c (ITEM_WRAP_COLUMN): New macro.
+	(print_core_item): New function.
+	(handle_core_item): Use it instead of printf_with_wrap.
+	(compare_core_items, compare_core_item_groups): New functions.
+	(handle_core_items): Use them.  Sort by group and force line breaks
+	between groups.
+
+	* readelf.c (handle_core_registers, handle_core_items): New functions,
+	broken out of ...
+	(handle_core_note): ... here.   Call them.
+
+2007-08-22  Roland McGrath  <roland@redhat.com>
+
+	* unstrip.c (new_shstrtab): New function, broken out of ...
+	(copy_elided_sections): ... here.
+
+2007-08-20  Roland McGrath  <roland@redhat.com>
+
+	Avoid local function trampolines in nm binary.
+	* nm.c (sort_by_address): Move to a static function instead of local
+	inside show_symbols.
+	(sort_by_name_strtab): New static variable.
+	(sort_by_name): Use it.  Move to a static function instead of local
+	inside show_symbols.
+	(show_symbols): Set sort_by_name_strtab.
+
+2007-08-19  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (handle_auxv_note): New function.
+	(handle_notes): Call it.
+
+	* readelf.c (printf_with_wrap, convert): New functions.
+	(handle_core_item, (handle_core_register): New functions.
+	(handle_notes): Call those with details from ebl_core_note.
+
+2007-08-12  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_note): Accept type 0 with name "Linux".
+
+	* elflint.c (special_sections): Accept SHF_ALLOC for ".note".
+
+	* elflint.c (section_flags_string): Return "none" for 0, not "".
+
+2007-08-11  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_note): Accept NT_GNU_HWCAP, NT_GNU_BUILD_ID.
+
+2007-08-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (hex_dump): Use isprint to determine whether to print
+	character itself or full stop character.
+	(dump_data): No need to check endp for NULL after strtol call.
+
+2007-08-03  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_string_sections): New variable.
+	(options, parse_opt): Handle --strings/-p to set it.
+	(print_strings): New function.
+	(process_elf_file): Call it under -p.
+
+	* readelf.c (options): Add hidden aliases --segments, --sections,
+	as taken by binutils readelf.
+
+2007-08-01  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (dump_data_sections, dump_data_sections_tail):
+	New variables.
+	(options, parse_opt): Handle --hex-dump/-x, set them.
+	(hex_dump): New function.
+	(dump_data): New function, call it.
+	(process_elf_file): Call it.
+
+2007-07-25  Roland McGrath  <roland@redhat.com>
+
+	* addr2line.c (show_symbols): New variable.
+	(print_addrsym): New function.
+	(handle_address): Call it.
+	(options, parse_opt): Handle -S/--symbols.
+
+2007-06-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* addr2line.c: Update for latest autoconf header.
+	* ar.c: Likewise.
+	* elfcmp.c: Likewise.
+	* elflint.c: Likewise.
+	* findtextrel.c: Likewise.
+	* ld.c: Likewise.
+	* ldgeneric.c: Likewise.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c: Likewise.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* strings.c: Likewise.
+	* strip.c: Likewise.
+	* unstrip.c: Likewise.
+
+2007-05-18  Roland McGrath  <roland@redhat.com>
+
+	* unstrip.c (copy_elided_sections): Match up non-NOBITS sections with
+	stripped file, so as not to duplicate a section copied in both.
+
+	* strip.c (handle_elf): Keep SHT_NOTE section copies in the debug file.
+
+2007-05-17  Roland McGrath  <roland@redhat.com>
+
+	* unstrip.c (copy_elided_sections): Don't call gelf_newphdr for 0.
+
+	* unstrip.c (handle_file): Tweak BIAS != 0 warning.
+
+	* unstrip.c (handle_file): Take new arg CREATE_DIRS.  If set,
+	call make_directories here.
+	(handle_explicit_files): Take new arg CREATE_DIRS, pass it down.
+	(handle_dwfl_module): Likewise.
+	(handle_implicit_modules): Update callers.
+	(handle_output_dir_module): Likewise.  Don't do make_directories here.
+
+	* unstrip.c (get_section_name): New function, broken out of ...
+	(copy_elided_sections): here.  Update callers.
+	(find_alloc_section): Broken out of ...
+	(copy_elided_sections): ... here.  Update caller.
+	(symtab_count_leading_section_symbols): Take new arg NEWSYMDATA,
+	update STT_SECTION symbols' st_value fields as a side effect.
+	(check_symtab_section_symbols): Update caller.
+	(add_new_section_symbols): Set st_value in symbols added.
+	(collect_symbols): Reset S->value for STT_SECTION symbols recorded.
+	Take new arg SPLIT_BSS.  Adjust S->shndx recorded for symbols moved
+	from .bss to .dynbss.
+	(find_alloc_sections_prelink): New function.  Associate debug file
+	allocated SHT_NOBITS shdrs with stripped moved by prelink via
+	.gnu.prelink_undo information.
+	(copy_elided_sections): Call it when we couldn't find every allocated
+	section.  Don't use a debug file non-NOBITS section if SHF_ALLOC.
+	Take STRIPPED_EHDR arg instead of E_TYPE and PHNUM.
+	(handle_file): Update callers.
+
+	* unstrip.c (copy_elided_sections): Ignore unfound unallocated section
+	named ".comment".
+
+	* elflint.c (check_sections): Fix association of segments with
+	sections when p_memsz > p_filesz.
+
+2007-04-29  Roland McGrath  <roland@redhat.com>
+
+	* addr2line.c (options, main): Tweak argp group settings to fix
+	usage output.
+
+2007-04-28  Roland McGrath  <roland@redhat.com>
+
+	* strip.c (handle_elf): Update debug file's SHT_NOBITS sections'
+	sizes to match sections adjusted in the stripped file.
+
+2007-04-24  Roland McGrath  <roland@redhat.com>
+
+	* elfcmp.c (OPT_HASH_INEXACT): New macro.
+	(hash_inexact): New variable.
+	(options, parse_opt): Add --hash-inexact option to set it.
+	(hash_content_equivalent): New function.
+	(main): Call it for differing SHT_HASH sections under --hash-inexact.
+
+2007-04-23  Roland McGrath  <roland@redhat.com>
+
+	* unstrip.c: New file.
+	* Makefile.am (bin_PROGRAMS): Add it.
+	(unstrip_LDADD): New variable.
+
+	* strip.c (options): Allow --output for -o.
+
+2007-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c: Remove unused code.  Add a few consts.
+
+2007-02-15  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_debug): Fix brainos in SHDR test.
+
+2007-02-05  Roland McGrath  <roland@redhat.com>
+
+	* ar.c: Include <limits.h>, since we use LONG_MAX.
+
+2007-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* ar.c: Add ugly hack to work around gcc complaining that we
+	ignore fchown's return value.
+	(do_oper_insert): Handle error when writing padding.
+	* ranlib.c: Add fchown complain work around.
+
+	* arlib.c: Make symtab a global variable.  Change all users.
+	* arlib2.c: Likewise.
+	* ranlib.c: Likewise.
+	* ar.c: Likewise.
+	* arlib.h: Declare it.
+
+2007-01-11  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_sections): Use ebl_machine_section_flag_check on
+	SHF_MASKPROC bits separately from generic sh_flags validation.
+
+2007-02-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* ar.c: New file.
+	* arlib.c: New file.
+	* arlib2.c: New file.
+	* arlib.h: New file.
+	* Makefile (noinst_LIBRARIES): Add libar.
+	(libar_a_SOURCES): Define.
+	(ar_LDADD): Define.
+	(CFLAGS_ar): Define.
+	* ranlib.c: Change to use arlib.
+
+	* elflint.c (check_symtab): Work around GNU ld bug which omits
+	sections but not symbols in those sections.
+
+2007-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* addr2line.c: Update copyright year.
+	* elfcmp.c: Likewise.
+	* elflint.c: Likewise.
+	* findtextrel.c: Likewise.
+	* ld.c: Likewise.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c:  Likewise.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* strings.c: Likewise.
+	* strip.c: Likewise.
+
+2006-12-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (compare_hash_gnu_hash): New function.  Report if the
+	two hash tables have different content (module expected omission
+	of undefined symbols).
+
+2006-10-31  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_program_header): Don't complain about
+	p_filesz > p_memsz if p_memsz is zero and p_type is PT_NOTE.
+
+2006-09-19  Jakub Jelinek  <jakub@redhat.com>
+
+	* strip.c (process_file): Disallow -f on archives.
+
+2006-10-09  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (libld_elf_i386.so): Use $(LINK), not $(CC).
+
+2006-08-29  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (MAINTAINERCLEANFILES): New variable.
+
+	* readelf.c (handle_relocs_rel): Typo fix, test DESTSHDR properly.
+	Reported by Christian Aichinger <Greek0@gmx.net>.
+
+	* elflint.c (valid_e_machine): Add EM_ALPHA.
+	Reported by Christian Aichinger <Greek0@gmx.net>.
+
+2006-08-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_dynamic): Don't require DT_HASH for DT_SYMTAB.
+	Keep track of which "high DT" entries are present.
+	Check that either old or GNU-style hash table is present.
+	If GNU-style hash table is used a symbol table is mandatory.
+	Check that if any prelink entry is present all of them are.
+	(check_gnu_hash): Only fail for undefined symbols in GNU-style hash
+	table if they don't refer to functions.
+
+2006-07-17  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (struct version_namelist): Use GElf_Versym for `ndx' field.
+	(add_version): Likewise for argument.
+	(check_versym): Cast constant to GElf_Versym for comparison.
+
+2006-07-12  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (handle_gnu_hash): Add casts for machines where
+	Elf32_Word != unsigned int.
+
+2006-07-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_sysv_hash64): Fix printf format.
+
+2006-07-11  Roland McGrath  <roland@redhat.com>
+
+	* addr2line.c (options): English fix in -f doc string.
+
+	* addr2line.c (use_comp_dir): New variable.
+	(options, parse_opt): Grok -A/--absolute to set it.
+	(handle_address): If set, prepend dwfl_line_comp_dir results to
+	relative file names.
+
+2006-07-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c: Adjust for latest new hash table format.
+	* readelf.c: Likewise.
+
+	* elflint.c (check_versym): Ignore hidden bit when comparing version
+	numbers.
+
+2006-07-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* ldgeneric.c (ld_generic_create_outfile): Correctly recognize
+	discarded COMDAT symbols.
+
+	* i386_ld.c (elf_i386_count_relocations): Lot of corrections.
+	(elf_i386_create_relocations): Likewise.
+	* ld.h (struct symbol): Add local and hidden bits.
+	* ld.c (create_special_section_symbol): These synthsized symbols
+	are local and hidden.
+	* ldgeneric.c (file_process2): Check whether input file matches
+	the emulation.
+	(fillin_special_symbol): Create symbols as local and/or hidden
+	if requested.
+	(ld_generic_create_outfile): Make local copy of symbol.
+	Don't hide global, defined symbols in dynamic symbol table unless
+	requested.  Synthetic symbols have no version information.
+
+	* elflint.c: Add support for checking 64-bit SysV-style hash tables.
+	* readelf.c: Add support for printing 64-bit SysV-style hash tables.
+
+2006-07-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (is_rel_dyn): Fix and extend DT_RELCOUNT/DT_RELACOUNT
+	testing.
+
+2006-07-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c: Add testing of DT_GNU_HASH.
+	* readelf.c: Implement showing histogram for DT_GNU_HASH section.
+
+	* Makefile.am: Add hacks to create dependency files for non-generic
+	linker.
+
+2006-06-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* ldgeneric.c (ld_generic_generate_sections): Don't create .interp
+	section if creating a DSO and no interpreter is given.
+	(ld_generic_create_outfile): Don't store reference to symbols in
+	discarded COMDAT groups.  Don't create PHDR and INTERP program header
+	for DSO if no interpreter is specified.
+	(create_verneed_data): Pretty printing.
+
+	* ldscript.y (content): If a DSO is created don't set default
+	interpreter from linker script.
+
+	* i386_ld.c (elf_i386_count_relocations): Do not add relocations
+	for symbols in discarded COMDAT groups.
+	(elf_i386_create_relocations): Likewise.
+	* ld.h (struct scninfo): Add unused_comdat.
+	* ldgeneric.c (add_section): Also check group signature when
+	matching COMDAT sections.
+	(add_relocatable_file): Ignore symbols in COMDAT group which are
+	discarded.
+
+	* elflint.c (check_one_reloc): For *_NONE relocs only check type
+	and symbol reference.
+
+2006-06-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_dynamic): Fix checking value of tags which are
+	offsets in the string section.  Make sure DT_STRTAB points to the
+	section referenced in sh_link.
+
+	* ld.c (options): Add headers.  Add short option 'R' for '--rpath'.
+
+	* ld.c: Recognize --eh-frame-hdr option.
+	* ld.h (struct ld_state): Add eh_frame_hdr field.
+	* ldgeneric.c (struct unw_eh_frame_hdr): Define.
+
+	* ldgeneric.c (add_section): Use ebl_sh_flags_combine instead of
+	SH_FLAGS_COMBINE.
+	(add_relocatable_file): Minor optimization of last change.
+	(match_section): Don't preserve SHF_GROUP flag any longer.
+
+2006-06-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* ld.c (parse_z_option): Recognize execstack and noexecstack.
+	Handle record and ignore as position dependent options.
+	(parse_z_option_2): Handle ignore and record here.
+	* ld.h (struct ld_state): Add execstack field.
+	* ldgeneric.c (add_relocatable_file): Recognize .note.GNU-stack
+	sections.
+	(ld_generic_create_outfile): Fix program header creation in native
+	linker.  Add PT_GNU_STACK program header.
+
+2006-06-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_ld.c (elf_i386_finalize_plt): Don't change symbol table entries
+	for PLT entries if there is no local definition.
+
+	* ld.c (parse_option): Handle -z ignore like --as-needed and
+	-z record like --no-as-needed.
+	* ld.h (struct ld_state): Remove ignore_unused_dsos field.
+	* ldgeneric.c (new_generated_scn): Always compute ndt_needed by
+	looping over DSOs.  When deciding about adding DT_NEEDED entries
+	use ->as_needed instead of ignore_unused_dsos.
+
+2006-05-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* ld.c: Recognize --as-needed and --no-as-needed options.
+	* ld.h (struct usedfile): Add as_needed field.
+	(struct ld_state): Likewise.
+	* ldgeneric.c (ld_handle_filename_list): Copy as_needed flag from
+	the list.
+	* ldscript.y (filename_id_list): Split to correctly parse all
+	combinations.
+	(mark_as_needed): Fix loop.
+
+2006-05-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* addr2line.c (print_dwarf_function): Use unsigned type for lineno
+	and colno.
+
+2006-05-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (handle_relocs_rela): Better notations for addon value.
+	(print_ehdr): Distinguish e_ident[EI_VERSION] from e_version.
+
+2006-04-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* addr2line.c: Update copyright year.
+	* elfcmp.c: Likewise.
+	* elflint.c: Likewise.
+	* findtextrel.c: Likewise.
+	* ld.c: Likewise.
+	* nm.c: Likewise.
+	* objdump.c: Likewise.
+	* ranlib.c: Likewise.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* strings.c: Likewise.
+	* strip.c: Likewise.
+
+2006-03-09  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (AM_LDFLAGS): New variable.
+
+2006-03-01  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (dwarf_tag_string, dwarf_attr_string): Update name tables
+	for dwarf.h changes matching 3.0 spec.
+	(dwarf_encoding_string, dwarf_lang_string, print_ops): Likewise.
+
+2005-12-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_one_reloc): If relocation section is not loaded,
+	don't check whether the relocations modify read-only sections or
+	loaded and unloaded sections.
+
+2005-11-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_one_reloc): Take additional parameters.  Use
+	them to determine whether relocation is valid in this type of
+	file.  DSOs and executables can contain relocation sections in
+	unloaded sections which just show the relocations the linker
+	applied.  Adjust all callers.
+	(check_program_header): Check that PT_PHDR is loaded and that offset
+	matches the one in the ELF header.
+
+2005-10-26  Roland McGrath  <roland@redhat.com>
+
+	* nm.c (get_var_range): dwarf_getloclist -> dwarf_getlocation.
+
+2005-09-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* strip.c (handle_elf): Unify some error messages.
+	* ld.c (main): Likewise.
+	* ldgeneric.c (open_elf): Likewise.
+	* elfcmp.c (main): Likewise.
+	* elflint.c (check_elf_header): Likewise.
+
+	* size.c (process_file): Fix typo in error message.
+
+	* readelf.c: Lots of little cleanups.  Use _unlocked functions.
+
+2005-09-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* strings.c (main): Reset elfmap variable after munmap call.
+	[_MUDFLAP] (map_file): Simplify mudflap debugging by not using mmap.
+
+2005-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* ranlib.c: Don't define pread_retry and write_retry here.
+
+	* Makefile.an [BUILD_STATIC] (libdw): Add -ldl.
+	(CLEANFILES): Add *.gcno *.gcda *.gconv.
+
+	* strings.c (process_chunk): Reorder expressions in conditional
+	(process_chunk_mb): Likewise.
+
+	* strings.c: New file.
+	* Makefile.am (bin_PROGRAMS): Add strings.
+	(strings_no_Wstring): Define.
+	(strings_LDADD): Define.
+
+2005-08-27  Roland McGrath  <roland@redhat.com>
+
+	* addr2line.c (dwarf_diename_integrate): Function removed.
+	(print_dwarf_function): Use plain dwarf_diename.
+
+2005-08-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_versym): Versioned symbols should not have
+	local binding.
+
+2005-08-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_versym): Allow VER_NDX_LOCAL symbols to be
+	undefined.
+
+	* Makefile.am: Add rules to build ranlib.
+	* ranlib.c: New file.
+
+2005-08-14  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_sections): Use ebl_section_type_name and allow any
+	sh_type it recognizes.
+
+	* elflint.c (check_sections): Print unknown flags in hex, don't
+	truncate high bits.  Print section number and name for unknown type.
+
+2005-08-13  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_program_header): Use ebl_segment_type_name and
+	allow any p_type it recognizes.  Include p_type value in error
+	message for unknown type.
+
+2005-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_symtab): Simplify last change a bit.  Pass ehdr
+	to ebl_check_special_symbol.
+	(check_sections): Pass ehdr to ebl_bss_plt_p.
+
+2005-08-12  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (check_symtab): Check that _GLOBAL_OFFSET_TABLE_ st_shndx
+	refers to the right section if it's not SHN_ABS.
+	Let ebl_check_special_symbol override _G_O_T_ value and size checks.
+
+	* elflint.c (check_sections): Don't complain about a non-NOBITS
+	section taking no segment space, if it's sh_size is 0.
+
+	* elflint.c (check_sections): Use ebl_bss_plt_p to see if .plt should
+	be PROGBITS or NOBITS.
+
+	* elflint.c (check_symtab): Use ebl_check_special_symbol to override
+	standard st_value and st_size checks.
+
+2005-07-28  Roland McGrath  <roland@redhat.com>
+
+	* addr2line.c (options, parse_opt): Don't handle -e here.
+	(executable): Variable removed.
+	(argp_children): New static variable.
+	(argp): Use it.  Make const.
+	(main): Fill in argp_children from dwfl_standard_argp ().
+	Let libdwfl handle file selection, pass Dwfl handle to handle_address.
+	(print_dwarf_function): New function.  Try to figure out inline chain.
+	(elf_getname): Function removed, libdwfl does it for us.
+	(handle_address): Take Dwfl handle instead of Elf, Dwarf handles.
+	Use dwfl_module_addrname instead of elf_getname.
+	Use dwfl_module_getsrc and dwfl_lineinfo instead of libdw calls.
+	* Makefile.am (INCLUDES): Add libdwfl directory to path.
+
+2005-08-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* strip.c (parse_opt): STATE parameter is now used.
+	Various little cleanups.
+
+	* readelf.c (print_debug_line_section): Correct fallout of renaming
+	of DW_LNS_set_epilog_begin.
+
+2005-08-08  Roland McGrath  <roland@redhat.com>
+
+	* strip.c (options, parse_opt): Grok -R .comment for compatibility
+	with binutils strip.  Likewise -d, -S, as aliases for -g.
+	Likewise ignore -s/--strip-all.
+
+2005-08-07  Roland McGrath  <roland@redhat.com>
+
+	* strip.c (process_file): Open read-only when using a different output
+	file.
+
+2005-08-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (in_nobits_scn): New function.
+	(check_versym): Allow references for defined symbols against versions
+	of other DSOs also for symbols in nobits sections.
+	Move a few variables around.
+
+	* Makefile.am (AM_CFLAGS): Avoid duplication.
+	Link with statis libs if BUILD_STATIC.
+
+2005-08-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c: Many, many more tests.  Mostly related to symbol
+	versioning.  Those sections should now be completely checked.
+
+	* readelf.c (print_dynamic): Use gelf_offscn.
+
+2005-08-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c: Add lots more tests: more extension symbol table sanity,
+	versioning section tests, hash table tests.  General cleanup.
+
+2005-08-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* objdump.c: New file.
+	* Makefile.am (bin_PROGRAMS): Add objdump.
+	(objdump_LDADD): Define.
+
+	* elflint.c (check_reloc_shdr): New function split out from check_rela
+	and check_rel.
+	(check_one_reloc): New function.  Likewise.
+	(check_rela): Use check_reloc_shdr and check_one_reloc.
+	(check_rel): Likewise.
+	(check_program_header): Check that PT_DYNAMIC entry matches .dynamic
+	section.
+	Add checks that relocations against read-only segments are flagged,
+	that the text relocation flag is not set unnecessarily, and that
+	relocations in one section are either against loaded or not-loaded
+	segments.
+
+2005-08-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfcmp.c (main): Ignore section count and section name string table
+	section index.
+
+2005-07-27  Roland McGrath  <roland@redhat.com>
+
+	* elfcmp.c: Include <locale.h>.
+
+2005-07-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfcmp.c: Print name and index of differing section.
+
+2005-07-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfcmp.c: Implement comparing gaps between sections.
+
+2005-07-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c: Include libeblP.h instead of libebl.h.
+	* nm.c: Likewise.
+	* readelf.c: Likewise.
+	* elfcmp.c: Likewise.
+
+	* elfcmp.c (main): Compare individual ELF header fields, excluding
+	e_shoff instead of the whole struct at once.
+	Use ebl_section_strip_p instead of SECTION_STRIP_P.
+	* strip.c: Use ebl_section_strip_p instead of SECTION_STRIP_P.
+
+2005-07-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfcmp.c (main): Take empty section into account when comparing
+	section content.
+
+	* elflint.c (check_dynamic): Check that d_tag value is >= 0 before
+	using it.
+
+2005-07-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* elfcmp.c: New file.
+	* Makefile.am (bin_PROGRAMS): Add elfcmp.
+	(elfcmp_LDADD): Define.
+
+	* elflint.c (check_rela): Check that copy relocations only reference
+	object symbols or symbols with unknown type.
+	(check_rel): Likewise.
+
+2005-06-08  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_ops): Add consts.
+
+2005-05-31  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_debug_abbrev_section): Don't bail after first CU's
+	abbreviations.  Print a header line before each CU section.
+
+	* readelf.c (print_debug_loc_section): Fix indentation for larger
+	address size.
+
+2005-05-30  Roland McGrath  <roland@redhat.com>
+
+	* readelf.c (print_debug_line_section): Print section offset of each
+	CU's table, so they are easy to find from seeing the stmt_list value.
+
+	* readelf.c (dwarf_attr_string): Add all attributes in <dwarf.h>.
+	(attr_callback): Grok DW_AT_ranges and print offset in hex.
+
+	* readelf.c (attr_callback): Add 2 to addrsize * 2 for %#0* format.
+	(print_debug_ranges_section, print_debug_loc_section): Likewise.
+
+	* readelf.c (print_ops): Take different args for indentation control.
+	(attr_callback): Caller updated.
+	Grok several more block-form attributes as being location expressions.
+	For those same attributes with udata forms, format output differently
+	for location list offset.
+	(print_debug_loc_section): Implement it for real.
+
+	* readelf.c (options): Mention ranges for --debug-dump.
+	(enum section_e): Add section_ranges.
+	(parse_opt): Grok "ranges" for -w/--debug-dump.
+	(print_debug_ranges_section): New function.
+	(print_debug): Handle .debug_ranges section.
+
+2005-05-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (handle_notes): At least x86-64 need not have the note
+	section values aligned to 8 bytes.
+
+2005-05-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (dwarf_tag_string): Add new tags.
+
+2005-05-08  Roland McGrath  <roland@redhat.com>
+
+	* strip.c (handle_elf): Don't translate hash and versym data formats,
+	elf_getdata already did it for us.
+
+2005-05-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (findtextrel_LDADD): Add $(libmudflap).
+	(addr2line_LDADD): Likewise.
+
+2005-05-03  Roland McGrath  <roland@redhat.com>
+
+	* strip.c (handle_elf): Apply symbol table fixups to discarded
+	relocation sections when they are being saved in the debug file.
+
+	* strip.c (handle_elf): Pass EHDR->e_ident[EI_DATA] to gelf_xlatetom
+	and gelf_xlatetof, not the native byte order.
+
+	* strip.c (parse_opt): Give error if -f or -o is repeated.
+	(main): Exit if argp_parse returns nonzero.
+
+	* strip.c (debug_fname_embed): New variable.
+	(options, parse_opt): New option -F to set it.
+
+2005-05-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (parse_opt): Make any_control_option variable
+	local.  Simplify some tests.
+
+2005-05-03  Roland McGrath  <roland@redhat.com>
+
+	* strip.c (crc32_file): Function removed (now in ../lib).
+
+2005-05-03  Roland McGrath  <roland@redhat.com>
+
+	* elflint.c (is_debuginfo): New variable.
+	(options, parse_opt): New option --debuginfo/-d to set it.
+	(check_sections): If is_debuginfo, don't complain about SHT_NOBITS.
+	(check_note): If is_debuginfo, don't try to get note contents.
+
+2005-04-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (print_debug_abbrev_section): Don't print error when end of
+	section reached.
+
+2005-04-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (dwarf_encoding_string): New function.
+	(dwarf_inline_string): New function.
+	(dwarf_access_string): New function.
+	(dwarf_visibility_string): New function.
+	(dwarf_virtuality_string): New function.
+	(dwarf_identifier_case_string): New function.
+	(dwarf_calling_convention_string): New function.
+	(dwarf_ordering_string): New function.
+	(dwarf_discr_list_string): New function.
+	(attr_callback): Decode man more attribute values.
+
+2005-04-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* addr2line.c: Finish implementation of -f option.
+
+2005-03-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* addr2line.c: New file.
+	* Makefile.am (bin_PROGRAMS): Add addr2line.
+	Define addr2line_LDADD.
+
+	* findtextrel.c: Use new dwarf_addrdie function.
+
+	* findtextrel.c: Fix usage message and re-add accidentally removed
+	line.
+
+2005-03-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* findtextrel.c: New file.
+	* Makefile: Add rules to build findtextrel.
+
+2005-02-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* ldlex.l: Provide ECHO definition to avoid warning.
+
+	* elflint.c (check_program_header): Fix typo in RELRO test.
+
+	* Makefile.am (AM_CFLAGS): Add more warning options.
+	* elflint.c: Fix warnings introduced by the new warning options.
+	* i386_ld.c: Likewise.
+	* ld.c: Likewise.
+	* ld.h: Likewise.
+	* ldgeneric.c: Likewise.
+	* nm.c: Likewise.
+	* readelf.c: Likewise.
+	* sectionhash.c: Likewise.
+	* size.c: Likewise.
+	* string.c: Likewise.
+
+2005-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Check for text relocations in constructed DSOs.
+
+	* Makefile.am [MUDFLAP] (AM_CFLAGS): Add -fmudflap.  Link all apps
+	with -lmudflap.
+
+	* ldscript.y: Add as_needed handling.
+	* ldlex.l: Recognize AS_NEEDED token.
+	* ld.h (struct filename_list): Add as_needed flag.
+
+2005-02-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* elflint.c (check_symtab): Correctly determine size of GOT section.
+
+2005-01-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* ld.c: Remove unnecessary more_help function.  Print bug report
+	address using argp.
+	* strip.c: Likewise.
+	* size.c: Likewise.
+	* nm.c: Likewise.
+	* readelf.c: Likewise.
+	* elflint.c: Likewise.
+
+	* elflint.c (main): Don't check for parameter problems here.
+	(parse_opt): Do it here, where we get informed about some of them
+	anyway.
+
+	* readelf.c (main): Don't check for parameter problems here.
+	(parse_opt): Do it here, where we get informed about some of them
+	anyway.
+
+2005-01-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* strip.c: Update copyright year.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* nm.c: Likewise.
+	* ld.c: Likewise.
+	* elflint.c: Likewise.
+
+	* elflint.c (check_symtab): Don't warn about wrong size for
+	_DYNAMIC and __GLOBAL_OFFSET_TABLE__ for --gnu-ld.
+
+2004-10-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (print_phdr): In section mapping, also indicate
+	sections in read-only segments.
+
+2004-09-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c: Make compile with gcc 4.0.
+	* strip.c: Likewise.
+
+2004-08-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* strip.c (handle_elf): Rewrite dynamic memory handling to use of
+	allocate to work around gcc 3.4 bug.
+
+2004-01-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* ldlex.l (invalid_char): Better error message.
+
+2004-01-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c: Print SHT_GNU_LIBLIST sections.
+
+	* none_ld.c: New file.
+
+2004-01-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Enable building of machine specific linker.
+
+2004-01-20  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support building with mudflap.
+
+	* i386_ld.c: Fix warnings gcc 3.4 spits out.
+	* ldgeneric.c: Likewise.
+	* ldscript.y: Likewise.
+	* readelf.c: Likewise.
+	* strip.c: Likewise.
+
+	* readelf.c (print_debug_line_section): Determine address size
+	correctly.
+
+2004-01-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (print_phdr): Show which sections are covered by the
+	PT_GNU_RELRO entry.
+
+	* elflint.c (check_program_header): Check PT_GNU_RELRO entry.
+
+	* readelf.c (print_debug_macinfo_section): Implement.
+
+2004-01-18  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (print_debug_line_section): Implement.
+
+2004-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* src/elflint.c: Use PACKAGE_NAME instead of PACKAGE.
+	* src/ld.c: Likewise.
+	* src/nm.c: Likewise.
+	* src/readelf.c: Likewise.
+	* src/size.c: Likewise.
+	* src/strip.c: Likewise.
+
+	* strip.c: Add a few more unlikely.  Reduce scope of some variables.
+
+	* Makefile.am: Support building with mudflap.
+
+2004-01-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (print_debug_info_section): Free dies memory.
+
+	* readelf.c: Print .debug_info section content.
+
+2004-01-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (print_shdr): Add support for SHF_ORDERED and SHF_EXCLUDE.
+
+2004-01-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (print_debug_aranges): Implement using libdw.
+
+2004-01-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* nm.c: Adjust for Dwarf_Files type and dwarf_lineno interface change.
+
+	* readelf.c: Use libdw instead of libdwarf.  Not all of the old
+	behavior is available yet.
+	* Makefile.am: Link readelf with libdw.  Remove libdwarf include path.
+
+2004-01-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* nm.c (get_local_names): Adjust call to dwarf_nextcu.
+
+	* nm.c: Implement getting information about local variables.
+
+2004-01-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* nm.c: Read also debug information for local symbols.
+
+2004-01-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* nm.c: Shuffle dwarf handling code around so the maximum column
+	width can be computed ahead of printing.  Avoid collection symbols
+	which are not printed anyway.
+
+	* nm.c: Rewrite dwarf handling to use libdw.
+	* Makefile.am (AM_CFLAGS): Add -std parameter.
+	(INCLUDES): Find header in libdw subdir.
+	(nm_LDADD): Replace libdwarf with libdw.
+
+	* elflint.c: Update copyright year.
+	* readelf.c: Likewise.
+	* size.c: Likewise.
+	* strip.c: Likewise.
+	* nm.c: Likewise.
+
+2003-12-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* strip.c (process_file): Close file before returning.
+
+2003-11-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (handle_dynamic): Make column for tag name wider.
+
+2003-09-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* readelf.c (handle_dynamic): Always terminate tag name with a space.
+
+2003-09-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* strip.c (process_file): Don't mmap the input file, we modify the
+	data structures and don't want the change end up on disk.
+
+2003-09-23  Jakub Jelinek  <jakub@redhat.com>
+
+	* unaligned.h (union u_2ubyte_unaligned,
+	union u_4ubyte_unaligned, union u_8ubyte_unaligned): Add
+	packed attribute.
+	(add_2ubyte_unaligned, add_4ubyte_unaligned,
+	add_8ubyte_unaligned): Avoid nesting bswap_NN macros.
+	Read/store value through _ptr->u instead of *_ptr.
+
+2003-09-22  Ulrich Drepper  <drepper@redhat.com>
+
+	* size.c (show_sysv): Change type of maxlen to int.
+
+	* strip.c (handle_elf): Handle the 64-bit archs which is 64-bit
+	buckets.
+
+	* i386_ld.c: Many many fixes and extensions.
+	* ld.c: Likewise.
+	* ldgeneric.c: Likewise.
+
+2003-08-16  Ulrich Drepper  <drepper@redhat.com>
+
+	* ldgeneric.c (check_definition): Don't add symbol on dso_list if
+	the reference is from another DSO.
+
+2003-08-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* ldgeneric.c (find_entry_point): It is no fatal error if no entry
+	point is found when creating a DSO.
+
+2003-08-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* ld.c (main): Always call FLAG_UNRESOLVED.
+	* ldgeneric.c (ld_generic_flag_unresolved): Only complain about
+	undefined symbols if not creating DSO or ld_state.nodefs is not set.
+
+2003-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.in: Depend on libebl.a, not libebl.so.
+
+	* ld.c (main): Mark stream for linker script as locked by caller.
+	(read_version_script): Likewise.
+	* ldlex.c: Define fread and fwrite to _unlocked variant.
+
+	* i386_ld.c (elf_i386_finalize_plt): Replace #ifdefs with uses of
+	target_bswap_32.
+	* unaligned.h: Define target_bswap_16, target_bswap_32, and
+	target_bswap_64.
+	(store_2ubyte_unaligned, store_4ubyte_unaligned,
+	store_8ubyte_unaligned): Define using new macros.
+
+2003-08-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* i386_ld.c (elf_i386_finalize_plt): Use packed structs to access
+	possibly unaligned memory.  Support use of big endian machines.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* Moved to CVS archive.
diff --git a/third_party/elfutils/src/Makefile.am b/third_party/elfutils/src/Makefile.am
new file mode 100644
index 0000000..2b1c0dc
--- /dev/null
+++ b/third_party/elfutils/src/Makefile.am
@@ -0,0 +1,113 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 1996-2014, 2016 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file 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 3 of the License, or
+## (at your option) any later version.
+##
+## elfutils 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.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program.  If not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+DEFS += $(YYDEBUG) -DDEBUGPRED=@DEBUGPRED@ \
+	-DSRCDIR=\"$(shell cd $(srcdir);pwd)\" -DOBJDIR=\"$(shell pwd)\"
+AM_CPPFLAGS += -I$(srcdir)/../libelf -I$(srcdir)/../libebl \
+	    -I$(srcdir)/../libdw -I$(srcdir)/../libdwelf \
+	    -I$(srcdir)/../libdwfl -I$(srcdir)/../libasm
+
+AM_LDFLAGS = -Wl,-rpath-link,../libelf:../libdw
+
+bin_PROGRAMS = readelf nm size strip elflint findtextrel addr2line \
+	       elfcmp objdump ranlib strings ar unstrip stack elfcompress
+
+noinst_LIBRARIES = libar.a
+
+libar_a_SOURCES = arlib.c arlib2.c arlib-argp.c
+
+EXTRA_DIST = arlib.h debugpred.h
+
+bin_SCRIPTS = make-debug-archive
+EXTRA_DIST += make-debug-archive.in
+CLEANFILES += make-debug-archive
+
+if BUILD_STATIC
+libasm = ../libasm/libasm.a
+libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl
+libelf = ../libelf/libelf.a -lz
+else
+libasm = ../libasm/libasm.so
+libdw = ../libdw/libdw.so
+libelf = ../libelf/libelf.so
+endif
+libebl = ../libebl/libebl.a
+libeu = ../lib/libeu.a
+
+if DEMANGLE
+demanglelib = -lstdc++
+endif
+
+# Bad, bad stack usage...
+readelf_no_Wstack_usage = yes
+nm_no_Wstack_usage = yes
+size_no_Wstack_usage = yes
+strip_no_Wstack_usage = yes
+elflint_no_Wstack_usage = yes
+findtextrel_no_Wstack_usage = yes
+elfcmp_no_Wstack_usage = yes
+objdump_no_Wstack_usage = yes
+ranlib_no_Wstack_usage = yes
+ar_no_Wstack_usage = yes
+unstrip_no_Wstack_usage = yes
+
+readelf_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl
+nm_LDADD = $(libdw) $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl \
+	   $(demanglelib)
+size_LDADD = $(libelf) $(libeu) $(argp_LDADD)
+strip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) -ldl
+elflint_LDADD  = $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl
+findtextrel_LDADD = $(libdw) $(libelf) $(libeu) $(argp_LDADD)
+addr2line_LDADD = $(libdw) $(libelf) $(libeu) $(argp_LDADD) $(demanglelib)
+elfcmp_LDADD = $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl
+objdump_LDADD  = $(libasm) $(libebl) $(libelf) $(libeu) $(argp_LDADD) -ldl
+ranlib_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD)
+strings_LDADD = $(libelf) $(libeu) $(argp_LDADD)
+ar_LDADD = libar.a $(libelf) $(libeu) $(argp_LDADD)
+unstrip_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) -ldl
+stack_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD) -ldl $(demanglelib)
+elfcompress_LDADD = $(libebl) $(libelf) $(libdw) $(libeu) $(argp_LDADD)
+
+installcheck-binPROGRAMS: $(bin_PROGRAMS)
+	bad=0; pid=$$$$; list="$(bin_PROGRAMS)"; for p in $$list; do \
+	  case ' $(AM_INSTALLCHECK_STD_OPTIONS_EXEMPT) ' in \
+	   *" $$p "* | *" $(srcdir)/$$p "*) continue;; \
+	  esac; \
+	  f=`echo "$$p" | \
+	     sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+	  for opt in --help --version; do \
+	    if LD_LIBRARY_PATH=$(DESTDIR)$(libdir) \
+	       $(DESTDIR)$(bindir)/$$f $$opt > c$${pid}_.out 2> c$${pid}_.err \
+		 && test -n "`cat c$${pid}_.out`" \
+		 && test -z "`cat c$${pid}_.err`"; then :; \
+	    else echo "$$f does not support $$opt" 1>&2; bad=1; fi; \
+	  done; \
+	done; rm -f c$${pid}_.???; exit $$bad
+
+CLEANFILES += *.gconv
+
+make-debug-archive: $(srcdir)/make-debug-archive.in
+	$(AM_V_GEN)UNSTRIP=$(bindir)/`echo unstrip | sed '$(transform)'`; \
+	AR=$(bindir)/`echo ar | sed '$(transform)'`; \
+	sed -e "s,[@]UNSTRIP[@],$$UNSTRIP,g" -e "s,[@]AR[@],$$AR,g" \
+	    -e "s%[@]PACKAGE_NAME[@]%$(PACKAGE_NAME)%g" \
+	    -e "s%[@]PACKAGE_VERSION[@]%$(PACKAGE_VERSION)%g" \
+	    $(srcdir)/make-debug-archive.in > $@.new
+	$(AM_V_at)chmod +x $@.new
+	$(AM_V_at)mv -f $@.new $@
diff --git a/third_party/elfutils/src/addr2line.c b/third_party/elfutils/src/addr2line.c
new file mode 100644
index 0000000..444ee52
--- /dev/null
+++ b/third_party/elfutils/src/addr2line.c
@@ -0,0 +1,814 @@
+/* Locate source files and line information for given addresses
+   Copyright (C) 2005-2010, 2012, 2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <assert.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <libdwfl.h>
+#include <dwarf.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <system.h>
+#include <printversion.h>
+
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+
+/* Values for the parameters which have no short form.  */
+#define OPT_DEMANGLER 0x100
+#define OPT_PRETTY 0x101  /* 'p' is already used to select the process.  */
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("Input format options:"), 2 },
+  { "section", 'j', "NAME", 0,
+    N_("Treat addresses as offsets relative to NAME section."), 0 },
+
+  { NULL, 0, NULL, 0, N_("Output format options:"), 3 },
+  { "addresses", 'a', NULL, 0, N_("Print address before each entry"), 0 },
+  { "basenames", 's', NULL, 0, N_("Show only base names of source files"), 0 },
+  { "absolute", 'A', NULL, 0,
+    N_("Show absolute file names using compilation directory"), 0 },
+  { "functions", 'f', NULL, 0, N_("Also show function names"), 0 },
+  { "symbols", 'S', NULL, 0, N_("Also show symbol or section names"), 0 },
+  { "symbols-sections", 'x', NULL, 0, N_("Also show symbol and the section names"), 0 },
+  { "flags", 'F', NULL, 0, N_("Also show line table flags"), 0 },
+  { "inlines", 'i', NULL, 0,
+    N_("Show all source locations that caused inline expansion of subroutines at the address."),
+    0 },
+  { "demangle", 'C', "ARG", OPTION_ARG_OPTIONAL,
+    N_("Show demangled symbols (ARG is always ignored)"), 0 },
+  { "pretty-print", OPT_PRETTY, NULL, 0,
+    N_("Print all information on one line, and indent inlines"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
+  /* Unsupported options.  */
+  { "target", 'b', "ARG", OPTION_HIDDEN, NULL, 0 },
+  { "demangler", OPT_DEMANGLER, "ARG", OPTION_HIDDEN, NULL, 0 },
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("\
+Locate source files and line information for ADDRs (in a.out by default).");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("[ADDR...]");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+static struct argp_child argp_children[2]; /* [0] is set in main.  */
+
+/* Data structure to communicate with argp functions.  */
+static const struct argp argp =
+{
+  options, parse_opt, args_doc, doc, argp_children, NULL, NULL
+};
+
+
+/* Handle ADDR.  */
+static int handle_address (const char *addr, Dwfl *dwfl);
+
+/* True when we should print the address for each entry.  */
+static bool print_addresses;
+
+/* True if only base names of files should be shown.  */
+static bool only_basenames;
+
+/* True if absolute file names based on DW_AT_comp_dir should be shown.  */
+static bool use_comp_dir;
+
+/* True if line flags should be shown.  */
+static bool show_flags;
+
+/* True if function names should be shown.  */
+static bool show_functions;
+
+/* True if ELF symbol or section info should be shown.  */
+static bool show_symbols;
+
+/* True if section associated with a symbol address should be shown.  */
+static bool show_symbol_sections;
+
+/* If non-null, take address parameters as relative to named section.  */
+static const char *just_section;
+
+/* True if all inlined subroutines of the current address should be shown.  */
+static bool show_inlines;
+
+/* True if all names need to be demangled.  */
+static bool demangle;
+
+/* True if all information should be printed on one line.  */
+static bool pretty;
+
+#ifdef USE_DEMANGLE
+static size_t demangle_buffer_len = 0;
+static char *demangle_buffer = NULL;
+#endif
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+  int result = 0;
+
+  /* We use no threads here which can interfere with handling a stream.  */
+  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  /* Make sure the message catalog can be found.  */
+  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+
+  /* Initialize the message catalog.  */
+  (void) textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  This includes opening the modules.  */
+  argp_children[0].argp = dwfl_standard_argp ();
+  argp_children[0].group = 1;
+  Dwfl *dwfl = NULL;
+  (void) argp_parse (&argp, argc, argv, 0, &remaining, &dwfl);
+  assert (dwfl != NULL);
+
+  /* Now handle the addresses.  In case none are given on the command
+     line, read from stdin.  */
+  if (remaining == argc)
+    {
+      /* We use no threads here which can interfere with handling a stream.  */
+      (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+
+      char *buf = NULL;
+      size_t len = 0;
+      ssize_t chars;
+      while (!feof_unlocked (stdin))
+	{
+	  if ((chars = getline (&buf, &len, stdin)) < 0)
+	    break;
+
+	  if (buf[chars - 1] == '\n')
+	    buf[chars - 1] = '\0';
+
+	  result = handle_address (buf, dwfl);
+	}
+
+      free (buf);
+    }
+  else
+    {
+      do
+	result = handle_address (argv[remaining], dwfl);
+      while (++remaining < argc);
+    }
+
+  dwfl_end (dwfl);
+
+#ifdef USE_DEMANGLE
+  free (demangle_buffer);
+#endif
+
+  return result;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+  switch (key)
+    {
+    case ARGP_KEY_INIT:
+      state->child_inputs[0] = state->input;
+      break;
+
+    case 'a':
+      print_addresses = true;
+      break;
+
+    case 'b':
+    case 'C':
+    case OPT_DEMANGLER:
+      demangle = true;
+      break;
+
+    case 's':
+      only_basenames = true;
+      break;
+
+    case 'A':
+      use_comp_dir = true;
+      break;
+
+    case 'f':
+      show_functions = true;
+      break;
+
+    case 'F':
+      show_flags = true;
+      break;
+
+    case 'S':
+      show_symbols = true;
+      break;
+
+    case 'x':
+      show_symbols = true;
+      show_symbol_sections = true;
+      break;
+
+    case 'j':
+      just_section = arg;
+      break;
+
+    case 'i':
+      show_inlines = true;
+      break;
+
+    case OPT_PRETTY:
+      pretty = true;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+static const char *
+symname (const char *name)
+{
+#ifdef USE_DEMANGLE
+  // Require GNU v3 ABI by the "_Z" prefix.
+  if (demangle && name[0] == '_' && name[1] == 'Z')
+    {
+      int status = -1;
+      char *dsymname = __cxa_demangle (name, demangle_buffer,
+				       &demangle_buffer_len, &status);
+      if (status == 0)
+	name = demangle_buffer = dsymname;
+    }
+#endif
+  return name;
+}
+
+static const char *
+get_diename (Dwarf_Die *die)
+{
+  Dwarf_Attribute attr;
+  const char *name;
+
+  name = dwarf_formstring (dwarf_attr_integrate (die, DW_AT_MIPS_linkage_name,
+						 &attr)
+			   ?: dwarf_attr_integrate (die, DW_AT_linkage_name,
+						    &attr));
+
+  if (name == NULL)
+    name = dwarf_diename (die) ?: "??";
+
+  return name;
+}
+
+static bool
+print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr)
+{
+  Dwarf_Addr bias = 0;
+  Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias);
+
+  Dwarf_Die *scopes;
+  int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes);
+  if (nscopes <= 0)
+    return false;
+
+  bool res = false;
+  for (int i = 0; i < nscopes; ++i)
+    switch (dwarf_tag (&scopes[i]))
+      {
+      case DW_TAG_subprogram:
+	{
+	  const char *name = get_diename (&scopes[i]);
+	  if (name == NULL)
+	    goto done;
+	  printf ("%s%c", symname (name), pretty ? ' ' : '\n');
+	  res = true;
+	  goto done;
+	}
+
+      case DW_TAG_inlined_subroutine:
+	{
+	  const char *name = get_diename (&scopes[i]);
+	  if (name == NULL)
+	    goto done;
+
+	  /* When using --pretty-print we only show inlines on their
+	     own line.  Just print the first subroutine name.  */
+	  if (pretty)
+	    {
+	      printf ("%s ", symname (name));
+	      res = true;
+	      goto done;
+	    }
+	  else
+	    printf ("%s inlined", symname (name));
+
+	  Dwarf_Files *files;
+	  if (dwarf_getsrcfiles (cudie, &files, NULL) == 0)
+	    {
+	      Dwarf_Attribute attr_mem;
+	      Dwarf_Word val;
+	      if (dwarf_formudata (dwarf_attr (&scopes[i],
+					       DW_AT_call_file,
+					       &attr_mem), &val) == 0)
+		{
+		  const char *file = dwarf_filesrc (files, val, NULL, NULL);
+		  unsigned int lineno = 0;
+		  unsigned int colno = 0;
+		  if (dwarf_formudata (dwarf_attr (&scopes[i],
+						   DW_AT_call_line,
+						   &attr_mem), &val) == 0)
+		    lineno = val;
+		  if (dwarf_formudata (dwarf_attr (&scopes[i],
+						   DW_AT_call_column,
+						   &attr_mem), &val) == 0)
+		    colno = val;
+
+		  const char *comp_dir = "";
+		  const char *comp_dir_sep = "";
+
+		  if (file == NULL)
+		    file = "???";
+		  else if (only_basenames)
+		    file = basename (file);
+		  else if (use_comp_dir && file[0] != '/')
+		    {
+		      const char *const *dirs;
+		      size_t ndirs;
+		      if (dwarf_getsrcdirs (files, &dirs, &ndirs) == 0
+			  && dirs[0] != NULL)
+			{
+			  comp_dir = dirs[0];
+			  comp_dir_sep = "/";
+			}
+		    }
+
+		  if (lineno == 0)
+		    printf (" from %s%s%s",
+			    comp_dir, comp_dir_sep, file);
+		  else if (colno == 0)
+		    printf (" at %s%s%s:%u",
+			    comp_dir, comp_dir_sep, file, lineno);
+		  else
+		    printf (" at %s%s%s:%u:%u",
+			    comp_dir, comp_dir_sep, file, lineno, colno);
+		}
+	    }
+	  printf (" in ");
+	  continue;
+	}
+      }
+
+done:
+  free (scopes);
+  return res;
+}
+
+static void
+print_addrsym (Dwfl_Module *mod, GElf_Addr addr)
+{
+  GElf_Sym s;
+  GElf_Off off;
+  const char *name = dwfl_module_addrinfo (mod, addr, &off, &s,
+					   NULL, NULL, NULL);
+  if (name == NULL)
+    {
+      /* No symbol name.  Get a section name instead.  */
+      int i = dwfl_module_relocate_address (mod, &addr);
+      if (i >= 0)
+	name = dwfl_module_relocation_info (mod, i, NULL);
+      if (name == NULL)
+	printf ("??%c", pretty ? ' ': '\n');
+      else
+	printf ("(%s)+%#" PRIx64 "%c", name, addr, pretty ? ' ' : '\n');
+    }
+  else
+    {
+      name = symname (name);
+      if (off == 0)
+	printf ("%s", name);
+      else
+	printf ("%s+%#" PRIx64 "", name, off);
+
+      // Also show section name for address.
+      if (show_symbol_sections)
+	{
+	  Dwarf_Addr ebias;
+	  Elf_Scn *scn = dwfl_module_address_section (mod, &addr, &ebias);
+	  if (scn != NULL)
+	    {
+	      GElf_Shdr shdr_mem;
+	      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	      if (shdr != NULL)
+		{
+		  Elf *elf = dwfl_module_getelf (mod, &ebias);
+		  GElf_Ehdr ehdr;
+		  if (gelf_getehdr (elf, &ehdr) != NULL)
+		    printf (" (%s)", elf_strptr (elf, ehdr.e_shstrndx,
+						 shdr->sh_name));
+		}
+	    }
+	}
+      printf ("%c", pretty ? ' ' : '\n');
+    }
+}
+
+static int
+see_one_module (Dwfl_Module *mod,
+		void **userdata __attribute__ ((unused)),
+		const char *name __attribute__ ((unused)),
+		Dwarf_Addr start __attribute__ ((unused)),
+		void *arg)
+{
+  Dwfl_Module **result = arg;
+  if (*result != NULL)
+    return DWARF_CB_ABORT;
+  *result = mod;
+  return DWARF_CB_OK;
+}
+
+static int
+find_symbol (Dwfl_Module *mod,
+	     void **userdata __attribute__ ((unused)),
+	     const char *name __attribute__ ((unused)),
+	     Dwarf_Addr start __attribute__ ((unused)),
+	     void *arg)
+{
+  const char *looking_for = ((void **) arg)[0];
+  GElf_Sym *symbol = ((void **) arg)[1];
+  GElf_Addr *value = ((void **) arg)[2];
+
+  int n = dwfl_module_getsymtab (mod);
+  for (int i = 1; i < n; ++i)
+    {
+      const char *symbol_name = dwfl_module_getsym_info (mod, i, symbol,
+							 value, NULL, NULL,
+							 NULL);
+      if (symbol_name == NULL || symbol_name[0] == '\0')
+	continue;
+      switch (GELF_ST_TYPE (symbol->st_info))
+	{
+	case STT_SECTION:
+	case STT_FILE:
+	case STT_TLS:
+	  break;
+	default:
+	  if (!strcmp (symbol_name, looking_for))
+	    {
+	      ((void **) arg)[0] = NULL;
+	      return DWARF_CB_ABORT;
+	    }
+	}
+    }
+
+  return DWARF_CB_OK;
+}
+
+static bool
+adjust_to_section (const char *name, uintmax_t *addr, Dwfl *dwfl)
+{
+  /* It was (section)+offset.  This makes sense if there is
+     only one module to look in for a section.  */
+  Dwfl_Module *mod = NULL;
+  if (dwfl_getmodules (dwfl, &see_one_module, &mod, 0) != 0
+      || mod == NULL)
+    error (EXIT_FAILURE, 0, gettext ("Section syntax requires"
+				     " exactly one module"));
+
+  int nscn = dwfl_module_relocations (mod);
+  for (int i = 0; i < nscn; ++i)
+    {
+      GElf_Word shndx;
+      const char *scn = dwfl_module_relocation_info (mod, i, &shndx);
+      if (unlikely (scn == NULL))
+	break;
+      if (!strcmp (scn, name))
+	{
+	  /* Found the section.  */
+	  GElf_Shdr shdr_mem;
+	  GElf_Addr shdr_bias;
+	  GElf_Shdr *shdr = gelf_getshdr
+	    (elf_getscn (dwfl_module_getelf (mod, &shdr_bias), shndx),
+	     &shdr_mem);
+	  if (unlikely (shdr == NULL))
+	    break;
+
+	  if (*addr >= shdr->sh_size)
+	    error (0, 0,
+		   gettext ("offset %#" PRIxMAX " lies outside"
+			    " section '%s'"),
+		   *addr, scn);
+
+	  *addr += shdr->sh_addr + shdr_bias;
+	  return true;
+	}
+    }
+
+  return false;
+}
+
+static void
+print_src (const char *src, int lineno, int linecol, Dwarf_Die *cu)
+{
+  const char *comp_dir = "";
+  const char *comp_dir_sep = "";
+
+  if (only_basenames)
+    src = basename (src);
+  else if (use_comp_dir && src[0] != '/')
+    {
+      Dwarf_Attribute attr;
+      comp_dir = dwarf_formstring (dwarf_attr (cu, DW_AT_comp_dir, &attr));
+      if (comp_dir != NULL)
+	comp_dir_sep = "/";
+    }
+
+  if (linecol != 0)
+    printf ("%s%s%s:%d:%d",
+	    comp_dir, comp_dir_sep, src, lineno, linecol);
+  else
+    printf ("%s%s%s:%d",
+	    comp_dir, comp_dir_sep, src, lineno);
+}
+
+static int
+get_addr_width (Dwfl_Module *mod)
+{
+  // Try to find the address width if possible.
+  static int width = 0;
+  if (width == 0 && mod != NULL)
+    {
+      Dwarf_Addr bias;
+      Elf *elf = dwfl_module_getelf (mod, &bias);
+      if (elf != NULL)
+        {
+	  GElf_Ehdr ehdr_mem;
+	  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+	  if (ehdr != NULL)
+	    width = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16;
+	}
+    }
+  if (width == 0)
+    width = 16;
+
+  return width;
+}
+
+static int
+handle_address (const char *string, Dwfl *dwfl)
+{
+  char *endp;
+  uintmax_t addr = strtoumax (string, &endp, 16);
+  if (endp == string || *endp != '\0')
+    {
+      bool parsed = false;
+      int i, j;
+      char *name = NULL;
+      if (sscanf (string, "(%m[^)])%" PRIiMAX "%n", &name, &addr, &i) == 2
+	  && string[i] == '\0')
+	parsed = adjust_to_section (name, &addr, dwfl);
+      switch (sscanf (string, "%m[^-+]%n%" PRIiMAX "%n", &name, &i, &addr, &j))
+	{
+	default:
+	  break;
+	case 1:
+	  addr = 0;
+	  j = i;
+	  FALLTHROUGH;
+	case 2:
+	  if (string[j] != '\0')
+	    break;
+
+	  /* It was symbol[+offset].  */
+	  GElf_Sym sym;
+	  GElf_Addr value = 0;
+	  void *arg[3] = { name, &sym, &value };
+	  (void) dwfl_getmodules (dwfl, &find_symbol, arg, 0);
+	  if (arg[0] != NULL)
+	    error (0, 0, gettext ("cannot find symbol '%s'"), name);
+	  else
+	    {
+	      if (sym.st_size != 0 && addr >= sym.st_size)
+		error (0, 0,
+		       gettext ("offset %#" PRIxMAX " lies outside"
+				" contents of '%s'"),
+		       addr, name);
+	      addr += value;
+	      parsed = true;
+	    }
+	  break;
+	}
+
+      free (name);
+      if (!parsed)
+	return 1;
+    }
+  else if (just_section != NULL
+	   && !adjust_to_section (just_section, &addr, dwfl))
+    return 1;
+
+  Dwfl_Module *mod = dwfl_addrmodule (dwfl, addr);
+
+  if (print_addresses)
+    {
+      int width = get_addr_width (mod);
+      printf ("0x%.*" PRIx64 "%s", width, addr, pretty ? ": " : "\n");
+    }
+
+  if (show_functions)
+    {
+      /* First determine the function name.  Use the DWARF information if
+	 possible.  */
+      if (! print_dwarf_function (mod, addr) && !show_symbols)
+	{
+	  const char *name = dwfl_module_addrname (mod, addr);
+	  name = name != NULL ? symname (name) : "??";
+	  printf ("%s%c", name, pretty ? ' ' : '\n');
+	}
+    }
+
+  if (show_symbols)
+    print_addrsym (mod, addr);
+
+  if ((show_functions || show_symbols) && pretty)
+    printf ("at ");
+
+  Dwfl_Line *line = dwfl_module_getsrc (mod, addr);
+
+  const char *src;
+  int lineno, linecol;
+
+  if (line != NULL && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol,
+					    NULL, NULL)) != NULL)
+    {
+      print_src (src, lineno, linecol, dwfl_linecu (line));
+      if (show_flags)
+	{
+	  Dwarf_Addr bias;
+	  Dwarf_Line *info = dwfl_dwarf_line (line, &bias);
+	  assert (info != NULL);
+
+	  inline void show (int (*get) (Dwarf_Line *, bool *),
+			    const char *note)
+	  {
+	    bool flag;
+	    if ((*get) (info, &flag) == 0 && flag)
+	      fputs (note, stdout);
+	  }
+	  inline void show_int (int (*get) (Dwarf_Line *, unsigned int *),
+				const char *name)
+	  {
+	    unsigned int val;
+	    if ((*get) (info, &val) == 0 && val != 0)
+	      printf (" (%s %u)", name, val);
+	  }
+
+	  show (&dwarf_linebeginstatement, " (is_stmt)");
+	  show (&dwarf_lineblock, " (basic_block)");
+	  show (&dwarf_lineprologueend, " (prologue_end)");
+	  show (&dwarf_lineepiloguebegin, " (epilogue_begin)");
+	  show_int (&dwarf_lineisa, "isa");
+	  show_int (&dwarf_linediscriminator, "discriminator");
+	}
+      putchar ('\n');
+    }
+  else
+    puts ("??:0");
+
+  if (show_inlines)
+    {
+      Dwarf_Addr bias = 0;
+      Dwarf_Die *cudie = dwfl_module_addrdie (mod, addr, &bias);
+
+      Dwarf_Die *scopes = NULL;
+      int nscopes = dwarf_getscopes (cudie, addr - bias, &scopes);
+      if (nscopes < 0)
+	return 1;
+
+      if (nscopes > 0)
+	{
+	  Dwarf_Die subroutine;
+	  Dwarf_Off dieoff = dwarf_dieoffset (&scopes[0]);
+	  dwarf_offdie (dwfl_module_getdwarf (mod, &bias),
+			dieoff, &subroutine);
+	  free (scopes);
+	  scopes = NULL;
+
+	  nscopes = dwarf_getscopes_die (&subroutine, &scopes);
+	  if (nscopes > 1)
+	    {
+	      Dwarf_Die cu;
+	      Dwarf_Files *files;
+	      if (dwarf_diecu (&scopes[0], &cu, NULL, NULL) != NULL
+		  && dwarf_getsrcfiles (cudie, &files, NULL) == 0)
+		{
+		  for (int i = 0; i < nscopes - 1; i++)
+		    {
+		      Dwarf_Word val;
+		      Dwarf_Attribute attr;
+		      Dwarf_Die *die = &scopes[i];
+		      if (dwarf_tag (die) != DW_TAG_inlined_subroutine)
+			continue;
+
+		      if (pretty)
+			printf (" (inlined by) ");
+
+		      if (show_functions)
+			{
+			  /* Search for the parent inline or function.  It
+			     might not be directly above this inline -- e.g.
+			     there could be a lexical_block in between.  */
+			  for (int j = i + 1; j < nscopes; j++)
+			    {
+			      Dwarf_Die *parent = &scopes[j];
+			      int tag = dwarf_tag (parent);
+			      if (tag == DW_TAG_inlined_subroutine
+				  || tag == DW_TAG_entry_point
+				  || tag == DW_TAG_subprogram)
+				{
+				  printf ("%s%s",
+					  symname (get_diename (parent)),
+					  pretty ? " at " : "\n");
+				  break;
+				}
+			    }
+			}
+
+		      src = NULL;
+		      lineno = 0;
+		      linecol = 0;
+		      if (dwarf_formudata (dwarf_attr (die, DW_AT_call_file,
+						       &attr), &val) == 0)
+			src = dwarf_filesrc (files, val, NULL, NULL);
+
+		      if (dwarf_formudata (dwarf_attr (die, DW_AT_call_line,
+						       &attr), &val) == 0)
+			lineno = val;
+
+		      if (dwarf_formudata (dwarf_attr (die, DW_AT_call_column,
+						       &attr), &val) == 0)
+			linecol = val;
+
+		      if (src != NULL)
+			{
+			  print_src (src, lineno, linecol, &cu);
+			  putchar ('\n');
+			}
+		      else
+			puts ("??:0");
+		    }
+		}
+	    }
+	}
+      free (scopes);
+    }
+
+  return 0;
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/ar.c b/third_party/elfutils/src/ar.c
new file mode 100644
index 0000000..818115b
--- /dev/null
+++ b/third_party/elfutils/src/ar.c
@@ -0,0 +1,1555 @@
+/* Create, modify, and extract from archives.
+   Copyright (C) 2005-2012, 2016, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <assert.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libintl.h>
+#include <limits.h>
+#include <locale.h>
+#include <search.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <system.h>
+#include <printversion.h>
+
+#include "arlib.h"
+
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Prototypes for local functions.  */
+static int do_oper_extract (int oper, const char *arfname, char **argv,
+			    int argc, long int instance);
+static int do_oper_delete (const char *arfname, char **argv, int argc,
+			   long int instance);
+static int do_oper_insert (int oper, const char *arfname, char **argv,
+			   int argc, const char *member);
+
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("Commands:"), 1 },
+  { NULL, 'd', NULL, 0, N_("Delete files from archive."), 0 },
+  { NULL, 'm', NULL, 0, N_("Move files in archive."), 0 },
+  { NULL, 'p', NULL, 0, N_("Print files in archive."), 0 },
+  { NULL, 'q', NULL, 0, N_("Quick append files to archive."), 0 },
+  { NULL, 'r', NULL, 0,
+    N_("Replace existing or insert new file into archive."), 0 },
+  { NULL, 't', NULL, 0, N_("Display content of archive."), 0 },
+  { NULL, 'x', NULL, 0, N_("Extract files from archive."), 0 },
+
+  { NULL, 0, NULL, 0, N_("Command Modifiers:"), 2 },
+  { NULL, 'o', NULL, 0, N_("Preserve original dates."), 0 },
+  { NULL, 'N', NULL, 0, N_("Use instance [COUNT] of name."), 0 },
+  { NULL, 'C', NULL, 0,
+    N_("Do not replace existing files with extracted files."), 0 },
+  { NULL, 'T', NULL, 0, N_("Allow filename to be truncated if necessary."),
+    0 },
+  { NULL, 'v', NULL, 0, N_("Provide verbose output."), 0 },
+  { NULL, 's', NULL, 0, N_("Force regeneration of symbol table."), 0 },
+  { NULL, 'a', NULL, 0, N_("Insert file after [MEMBER]."), 0 },
+  { NULL, 'b', NULL, 0, N_("Insert file before [MEMBER]."), 0 },
+  { NULL, 'i', NULL, 0, N_("Same as -b."), 0 },
+  { NULL, 'c', NULL, 0, N_("Suppress message when library has to be created."),
+    0 },
+  { NULL, 'P', NULL, 0, N_("Use full path for file matching."), 0 },
+  { NULL, 'u', NULL, 0, N_("Update only older files in archive."), 0 },
+
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("Create, modify, and extract from archives.");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("[MEMBER] [COUNT] ARCHIVE [FILE...]");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  options, parse_opt, args_doc, doc, arlib_argp_children, NULL, NULL
+};
+
+
+/* What operation to perform.  */
+static enum
+  {
+    oper_none,
+    oper_delete,
+    oper_move,
+    oper_print,
+    oper_qappend,
+    oper_replace,
+    oper_list,
+    oper_extract
+  } operation;
+
+/* Modifiers.  */
+static bool verbose;
+static bool preserve_dates;
+static bool instance_specifed;
+static bool dont_replace_existing;
+static bool allow_truncate_fname;
+static bool force_symtab;
+static bool suppress_create_msg;
+static bool full_path;
+static bool update_newer;
+static enum { ipos_none, ipos_before, ipos_after } ipos;
+
+
+int
+main (int argc, char *argv[])
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+  (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  /* Make sure the message catalog can be found.  */
+  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+
+  /* Initialize the message catalog.  */
+  (void) textdomain (PACKAGE_TARNAME);
+
+  /* For historical reasons the options in the first parameter need
+     not be preceded by a dash.  Add it now if necessary.  */
+  if (argc > 1 && argv[1][0] != '-')
+    {
+      size_t len = strlen (argv[1]) + 1;
+      char *newp = alloca (len + 1);
+      newp[0] = '-';
+      memcpy (&newp[1], argv[1], len);
+      argv[1] = newp;
+    }
+
+  /* Parse and process arguments.  */
+  int remaining;
+  (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &remaining, NULL);
+
+  /* Tell the library which version we are expecting.  */
+  (void) elf_version (EV_CURRENT);
+
+  /* Handle the [MEMBER] parameter.  */
+  const char *member = NULL;
+  if (ipos != ipos_none)
+    {
+      /* Only valid for certain operations.  */
+      if (operation != oper_move && operation != oper_replace)
+	error (1, 0, gettext ("\
+'a', 'b', and 'i' are only allowed with the 'm' and 'r' options"));
+
+      if (remaining == argc)
+	{
+	  error (0, 0, gettext ("\
+MEMBER parameter required for 'a', 'b', and 'i' modifiers"));
+	  argp_help (&argp, stderr, ARGP_HELP_USAGE | ARGP_HELP_SEE,
+		     program_invocation_short_name);
+	  exit (EXIT_FAILURE);
+	}
+
+      member = argv[remaining++];
+    }
+
+  /* Handle the [COUNT] parameter.  */
+  long int instance = -1;
+  if (instance_specifed)
+    {
+      /* Only valid for certain operations.  */
+      if (operation != oper_extract && operation != oper_delete)
+	error (1, 0, gettext ("\
+'N' is only meaningful with the 'x' and 'd' options"));
+
+      if (remaining == argc)
+	{
+	  error (0, 0, gettext ("COUNT parameter required"));
+	  argp_help (&argp, stderr, ARGP_HELP_SEE,
+		     program_invocation_short_name);
+	  exit (EXIT_FAILURE);
+	}
+
+      char *endp;
+      errno = 0;
+      if (((instance = strtol (argv[remaining], &endp, 10)) == LONG_MAX
+	   && errno == ERANGE)
+	  || instance <= 0
+	  || *endp != '\0')
+	error (1, 0, gettext ("invalid COUNT parameter %s"), argv[remaining]);
+
+      ++remaining;
+    }
+
+  if ((dont_replace_existing || allow_truncate_fname)
+      && unlikely (operation != oper_extract))
+    error (1, 0, gettext ("'%c' is only meaningful with the 'x' option"),
+	   dont_replace_existing ? 'C' : 'T');
+
+  /* There must at least be one more parameter specifying the archive.   */
+  if (remaining == argc)
+    {
+      error (0, 0, gettext ("archive name required"));
+      argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name);
+      exit (EXIT_FAILURE);
+    }
+
+  const char *arfname = argv[remaining++];
+  argv += remaining;
+  argc -= remaining;
+
+  int status;
+  switch (operation)
+    {
+    case oper_none:
+      error (0, 0, gettext ("command option required"));
+      argp_help (&argp, stderr, ARGP_HELP_STD_ERR,
+		 program_invocation_short_name);
+      status = 1;
+      break;
+
+    case oper_list:
+    case oper_print:
+      status = do_oper_extract (operation, arfname, argv, argc, -1);
+      break;
+
+    case oper_extract:
+      status = do_oper_extract (operation, arfname, argv, argc, instance);
+      break;
+
+    case oper_delete:
+      status = do_oper_delete (arfname, argv, argc, instance);
+      break;
+
+    case oper_move:
+    case oper_qappend:
+    case oper_replace:
+      status = do_oper_insert (operation, arfname, argv, argc, member);
+      break;
+
+    default:
+      assert (! "should not happen");
+      status = 1;
+      break;
+    }
+
+  return status;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg __attribute__ ((unused)),
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case 'd':
+    case 'm':
+    case 'p':
+    case 'q':
+    case 'r':
+    case 't':
+    case 'x':
+      if (operation != oper_none)
+	{
+	  error (0, 0, gettext ("More than one operation specified"));
+	  argp_help (&argp, stderr, ARGP_HELP_SEE,
+		     program_invocation_short_name);
+	  exit (EXIT_FAILURE);
+	}
+
+      switch (key)
+	{
+	case 'd':
+	  operation = oper_delete;
+	  break;
+	case 'm':
+	  operation = oper_move;
+	  break;
+	case 'p':
+	  operation = oper_print;
+	  break;
+	case 'q':
+	  operation = oper_qappend;
+	  break;
+	case 'r':
+	  operation = oper_replace;
+	  break;
+	case 't':
+	  operation = oper_list;
+	  break;
+	case 'x':
+	  operation = oper_extract;
+	  break;
+	}
+      break;
+
+    case 'a':
+      ipos = ipos_after;
+      break;
+
+    case 'b':
+    case 'i':
+      ipos = ipos_before;
+      break;
+
+    case 'c':
+      suppress_create_msg = true;
+      break;
+
+    case 'C':
+      dont_replace_existing = true;
+      break;
+
+    case 'N':
+      instance_specifed = true;
+      break;
+
+    case 'o':
+      preserve_dates = true;
+      break;
+
+    case 'P':
+      full_path = true;
+      break;
+
+    case 's':
+      force_symtab = true;
+      break;
+
+    case 'T':
+      allow_truncate_fname = true;
+      break;
+
+    case 'u':
+      update_newer = true;
+      break;
+
+    case 'v':
+      verbose = true;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+static int
+open_archive (const char *arfname, int flags, int mode, Elf **elf,
+	      struct stat *st, bool miss_allowed)
+{
+  int fd = open (arfname, flags, mode);
+  if (fd == -1)
+    {
+      if (miss_allowed)
+	return -1;
+
+      error (EXIT_FAILURE, errno, gettext ("cannot open archive '%s'"),
+	     arfname);
+    }
+
+  if (elf != NULL)
+    {
+      Elf_Cmd cmd = flags == O_RDONLY ? ELF_C_READ_MMAP : ELF_C_RDWR_MMAP;
+
+      *elf = elf_begin (fd, cmd, NULL);
+      if (*elf == NULL)
+	error (EXIT_FAILURE, 0, gettext ("cannot open archive '%s': %s"),
+	       arfname, elf_errmsg (-1));
+
+      if (flags == O_RDONLY && elf_kind (*elf) != ELF_K_AR)
+	error (EXIT_FAILURE, 0, gettext ("%s: not an archive file"), arfname);
+    }
+
+  if (st != NULL && fstat (fd, st) != 0)
+    error (EXIT_FAILURE, errno, gettext ("cannot stat archive '%s'"),
+	   arfname);
+
+  return fd;
+}
+
+
+static void
+not_found (int argc, char *argv[argc], bool found[argc])
+{
+  for (int i = 0; i < argc; ++i)
+    if (!found[i])
+      printf (gettext ("no entry %s in archive\n"), argv[i]);
+}
+
+
+static int
+copy_content (Elf *elf, int newfd, off_t off, size_t n)
+{
+  size_t len;
+  char *rawfile = elf_rawfile (elf, &len);
+
+  assert (off + n <= len);
+
+  /* Tell the kernel we will read all the pages sequentially.  */
+  size_t ps = sysconf (_SC_PAGESIZE);
+  if (n > 2 * ps)
+    posix_madvise (rawfile + (off & ~(ps - 1)), n, POSIX_MADV_SEQUENTIAL);
+
+  return write_retry (newfd, rawfile + off, n) != (ssize_t) n;
+}
+
+
+static int
+do_oper_extract (int oper, const char *arfname, char **argv, int argc,
+		 long int instance)
+{
+  bool found[argc > 0 ? argc : 1];
+  memset (found, '\0', sizeof (found));
+
+  size_t name_max = 0;
+  inline bool should_truncate_fname (void)
+  {
+    if (errno == ENAMETOOLONG && allow_truncate_fname)
+      {
+	if (name_max == 0)
+	  {
+	    long int len = pathconf (".", _PC_NAME_MAX);
+	    if (len > 0)
+	      name_max = len;
+	  }
+	return name_max != 0;
+      }
+    return false;
+  }
+
+  off_t index_off = -1;
+  size_t index_size = 0;
+  off_t cur_off = SARMAG;
+
+  int status = 0;
+  Elf *elf;
+  int fd = open_archive (arfname, O_RDONLY, 0, &elf, NULL, false);
+
+  if (hcreate (2 * argc) == 0)
+    error (EXIT_FAILURE, errno, gettext ("cannot create hash table"));
+
+  for (int cnt = 0; cnt < argc; ++cnt)
+    {
+      ENTRY entry = { .key = argv[cnt], .data = &argv[cnt] };
+      if (hsearch (entry, ENTER) == NULL)
+	error (EXIT_FAILURE, errno,
+	       gettext ("cannot insert into hash table"));
+    }
+
+  struct stat st;
+  if (force_symtab)
+    {
+      if (fstat (fd, &st) != 0)
+	{
+	  error (0, errno, gettext ("cannot stat '%s'"), arfname);
+	  close (fd);
+	  return 1;
+	}
+      arlib_init ();
+    }
+
+  Elf_Cmd cmd = ELF_C_READ_MMAP;
+  Elf *subelf;
+  while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+    {
+      Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+
+      if (strcmp (arhdr->ar_name, "/") == 0)
+	{
+	  index_off = elf_getaroff (subelf);
+	  index_size = arhdr->ar_size;
+	  goto next;
+	}
+      if (strcmp (arhdr->ar_name, "//") == 0)
+	goto next;
+
+      if (force_symtab)
+	{
+	  arlib_add_symbols (elf, arfname, arhdr->ar_name, cur_off);
+	  cur_off += (((arhdr->ar_size + 1) & ~((off_t) 1))
+		      + sizeof (struct ar_hdr));
+	}
+
+      bool do_extract = argc <= 0;
+      if (!do_extract)
+	{
+	  ENTRY entry;
+	  entry.key = arhdr->ar_name;
+	  ENTRY *res = hsearch (entry, FIND);
+	  if (res != NULL && (instance < 0 || instance-- == 0)
+	      && !found[(char **) res->data - argv])
+	    found[(char **) res->data - argv] = do_extract = true;
+	}
+
+      if (do_extract)
+	{
+	  if (verbose)
+	    {
+	      if (oper == oper_print)
+		{
+		  printf ("\n<%s>\n\n", arhdr->ar_name);
+
+		  /* We have to flush now because now we use the descriptor
+		     directly.  */
+		  fflush (stdout);
+		}
+	      else if (oper == oper_list)
+		{
+		  char datestr[100];
+		  strftime (datestr, sizeof (datestr), "%b %e %H:%M %Y",
+			    localtime (&arhdr->ar_date));
+
+		  printf ("%c%c%c%c%c%c%c%c%c %u/%u %6ju %s %s\n",
+			  (arhdr->ar_mode & S_IRUSR) ? 'r' : '-',
+			  (arhdr->ar_mode & S_IWUSR) ? 'w' : '-',
+			  (arhdr->ar_mode & S_IXUSR)
+			  ? ((arhdr->ar_mode & S_ISUID) ? 's' : 'x')
+			  : ((arhdr->ar_mode & S_ISUID) ? 'S' : '-'),
+			  (arhdr->ar_mode & S_IRGRP) ? 'r' : '-',
+			  (arhdr->ar_mode & S_IWGRP) ? 'w' : '-',
+			  (arhdr->ar_mode & S_IXGRP)
+			  ? ((arhdr->ar_mode & S_ISGID) ? 's' : 'x')
+			  : ((arhdr->ar_mode & S_ISGID) ? 'S' : '-'),
+			  (arhdr->ar_mode & S_IROTH) ? 'r' : '-',
+			  (arhdr->ar_mode & S_IWOTH) ? 'w' : '-',
+			  (arhdr->ar_mode & S_IXOTH)
+			  ? ((arhdr->ar_mode & S_ISVTX) ? 't' : 'x')
+			  : ((arhdr->ar_mode & S_ISVTX) ? 'T' : '-'),
+			  arhdr->ar_uid,
+			  arhdr->ar_gid,
+			  (uintmax_t) arhdr->ar_size,
+			  datestr,
+			  arhdr->ar_name);
+		}
+	      else
+		printf ("x - %s\n", arhdr->ar_name);
+	    }
+
+	  if (oper == oper_list)
+	    {
+	      if (!verbose)
+		puts (arhdr->ar_name);
+
+	      goto next;
+	    }
+
+	  size_t nleft;
+	  char *data = elf_rawfile (subelf, &nleft);
+	  if (data == NULL)
+	    {
+	      error (0, 0, gettext ("cannot read content of %s: %s"),
+		     arhdr->ar_name, elf_errmsg (-1));
+	      status = 1;
+	      goto next;
+	    }
+
+	  int xfd;
+	  char tempfname[] = "XXXXXX";
+	  bool use_mkstemp = true;
+
+	  if (oper == oper_print)
+	    xfd = STDOUT_FILENO;
+	  else
+	    {
+	      xfd = mkstemp (tempfname);
+	      if (unlikely (xfd == -1))
+		{
+		  /* We cannot create a temporary file.  Try to overwrite
+		     the file or create it if it does not exist.  */
+		  int flags = O_WRONLY | O_CREAT;
+		  if (dont_replace_existing)
+		    flags |= O_EXCL;
+		  else
+		    flags |= O_TRUNC;
+		  xfd = open (arhdr->ar_name, flags, 0600);
+		  if (unlikely (xfd == -1))
+		    {
+		      int printlen = INT_MAX;
+
+		      if (should_truncate_fname ())
+			{
+			  /* Try to truncate the name.  First find out by how
+			     much.  */
+			  printlen = name_max;
+			  char truncfname[name_max + 1];
+			  *((char *) mempcpy (truncfname, arhdr->ar_name,
+					      name_max)) = '\0';
+
+			  xfd = open (truncfname, flags, 0600);
+			}
+
+		      if (xfd == -1)
+			{
+			  error (0, errno, gettext ("cannot open %.*s"),
+				 (int) printlen, arhdr->ar_name);
+			  status = 1;
+			  goto next;
+			}
+		    }
+
+		  use_mkstemp = false;
+		}
+	    }
+
+	  ssize_t n;
+	  while ((n = TEMP_FAILURE_RETRY (write (xfd, data, nleft))) != -1)
+	    {
+	      nleft -= n;
+	      if (nleft == 0)
+		break;
+	      data += n;
+	    }
+
+	  if (unlikely (n == -1))
+	    {
+	      error (0, errno, gettext ("failed to write %s"), arhdr->ar_name);
+	      status = 1;
+	      unlink (tempfname);
+	      close (xfd);
+	      goto next;
+	    }
+
+	  if (oper != oper_print)
+	    {
+	      /* Fix up the mode.  */
+	      if (unlikely (fchmod (xfd, arhdr->ar_mode) != 0))
+		{
+		  error (0, errno, gettext ("cannot change mode of %s"),
+			 arhdr->ar_name);
+		  status = 0;
+		}
+
+	      if (preserve_dates)
+		{
+		  struct timespec tv[2];
+		  tv[0].tv_sec = arhdr->ar_date;
+		  tv[0].tv_nsec = 0;
+		  tv[1].tv_sec = arhdr->ar_date;
+		  tv[1].tv_nsec = 0;
+
+		  if (unlikely (futimens (xfd, tv) != 0))
+		    {
+		      error (0, errno,
+			     gettext ("cannot change modification time of %s"),
+			     arhdr->ar_name);
+		      status = 1;
+		    }
+		}
+
+	      /* If we used a temporary file, move it do the right
+		 name now.  */
+	      if (use_mkstemp)
+		{
+		  int r;
+
+		  if (dont_replace_existing)
+		    {
+		      r = link (tempfname, arhdr->ar_name);
+		      if (likely (r == 0))
+			unlink (tempfname);
+		    }
+		  else
+		    r = rename (tempfname, arhdr->ar_name);
+
+		  if (unlikely (r) != 0)
+		    {
+		      int printlen = INT_MAX;
+
+		      if (should_truncate_fname ())
+			{
+			  /* Try to truncate the name.  First find out by how
+			     much.  */
+			  printlen = name_max;
+			  char truncfname[name_max + 1];
+			  *((char *) mempcpy (truncfname, arhdr->ar_name,
+					      name_max)) = '\0';
+
+			  if (dont_replace_existing)
+			    {
+			      r = link (tempfname, truncfname);
+			      if (likely (r == 0))
+				unlink (tempfname);
+			    }
+			  else
+			    r = rename (tempfname, truncfname);
+			}
+
+		      if (r != 0)
+			{
+			  error (0, errno, gettext ("\
+cannot rename temporary file to %.*s"),
+				 printlen, arhdr->ar_name);
+			  unlink (tempfname);
+			  status = 1;
+			}
+		    }
+		}
+
+	      close (xfd);
+	    }
+	}
+
+    next:
+      cmd = elf_next (subelf);
+      if (elf_end (subelf) != 0)
+	error (1, 0, "%s: %s", arfname, elf_errmsg (-1));
+    }
+
+  hdestroy ();
+
+  if (force_symtab)
+    {
+      arlib_finalize ();
+
+      if (symtab.symsnamelen != 0
+	  /* We have to rewrite the file also if it initially had an index
+	     but now does not need one anymore.  */
+	  || (symtab.symsnamelen == 0 && index_size != 0))
+	{
+	  char tmpfname[strlen (arfname) + 7];
+	  strcpy (stpcpy (tmpfname, arfname), "XXXXXX");
+	  int newfd = mkstemp (tmpfname);
+	  if (unlikely (newfd == -1))
+	    {
+	    nonew:
+	      error (0, errno, gettext ("cannot create new file"));
+	      status = 1;
+	    }
+	  else
+	    {
+	      /* Create the header.  */
+	      if (unlikely (write_retry (newfd, ARMAG, SARMAG) != SARMAG))
+		{
+		  // XXX Use /prof/self/fd/%d ???
+		nonew_unlink:
+		  unlink (tmpfname);
+		  if (newfd != -1)
+		    close (newfd);
+		  goto nonew;
+		}
+
+	      /* Create the new file.  There are three parts as far we are
+		 concerned: 1. original context before the index, 2. the
+		 new index, 3. everything after the new index.  */
+	      off_t rest_off;
+	      if (index_off != -1)
+		rest_off = (index_off + sizeof (struct ar_hdr)
+			    + ((index_size + 1) & ~1ul));
+	      else
+		rest_off = SARMAG;
+
+	      if ((symtab.symsnamelen != 0
+		   && ((write_retry (newfd, symtab.symsoff,
+				     symtab.symsofflen)
+			!= (ssize_t) symtab.symsofflen)
+		       || (write_retry (newfd, symtab.symsname,
+					symtab.symsnamelen)
+			   != (ssize_t) symtab.symsnamelen)))
+		  /* Even if the original file had content before the
+		     symbol table, we write it in the correct order.  */
+		  || (index_off != SARMAG
+		      && copy_content (elf, newfd, SARMAG, index_off - SARMAG))
+		  || copy_content (elf, newfd, rest_off, st.st_size - rest_off)
+		  /* Set the mode of the new file to the same values the
+		     original file has.  */
+		  || fchmod (newfd, st.st_mode & ALLPERMS) != 0
+		  /* Never complain about fchown failing.  */
+		  || (({asm ("" :: "r" (fchown (newfd, st.st_uid,
+						st.st_gid))); }),
+		      close (newfd) != 0)
+		  || (newfd = -1, rename (tmpfname, arfname) != 0))
+		goto nonew_unlink;
+	    }
+	}
+    }
+
+  elf_end (elf);
+
+  close (fd);
+
+  not_found (argc, argv, found);
+
+  return status;
+}
+
+
+struct armem
+{
+  off_t off;
+  off_t old_off;
+  size_t size;
+  long int long_name_off;
+  struct armem *next;
+  void *mem;
+  time_t sec;
+  uid_t uid;
+  gid_t gid;
+  mode_t mode;
+  const char *name;
+  Elf *elf;
+};
+
+
+static int
+write_member (struct armem *memb, off_t *startp, off_t *lenp, Elf *elf,
+	      off_t end_off, int newfd)
+{
+  struct ar_hdr arhdr;
+  /* The ar_name is not actually zero teminated, but we need that for
+     snprintf.  Also if the name is too long, then the string starts
+     with '/' plus an index off number (decimal).  */
+  char tmpbuf[sizeof (arhdr.ar_name) + 2];
+
+  bool changed_header = memb->long_name_off != -1;
+  if (changed_header)
+    {
+      /* In case of a long file name we assume the archive header
+	 changed and we write it here.  */
+      memcpy (&arhdr, elf_rawfile (elf, NULL) + *startp, sizeof (arhdr));
+
+      snprintf (tmpbuf, sizeof (tmpbuf), "/%-*ld",
+		(int) sizeof (arhdr.ar_name), memb->long_name_off);
+      changed_header = memcmp (arhdr.ar_name, tmpbuf,
+			       sizeof (arhdr.ar_name)) != 0;
+    }
+
+  /* If the files are adjacent in the old file extend the range.  */
+  if (*startp != -1 && !changed_header && *startp + *lenp == memb->old_off)
+    {
+      /* Extend the current range.  */
+      *lenp += (memb->next != NULL
+		? memb->next->off : end_off) - memb->off;
+      return 0;
+    }
+
+  /* Write out the old range.  */
+  if (*startp != -1 && copy_content (elf, newfd, *startp, *lenp))
+    return -1;
+
+  *startp = memb->old_off;
+  *lenp = (memb->next != NULL ? memb->next->off : end_off) - memb->off;
+
+  if (changed_header)
+    {
+      memcpy (arhdr.ar_name, tmpbuf, sizeof (arhdr.ar_name));
+
+      if (unlikely (write_retry (newfd, &arhdr, sizeof (arhdr))
+		    != sizeof (arhdr)))
+	return -1;
+
+      *startp += sizeof (struct ar_hdr);
+      assert ((size_t) *lenp >= sizeof (struct ar_hdr));
+      *lenp -= sizeof (struct ar_hdr);
+    }
+
+  return 0;
+}
+
+/* Store the name in the long name table if necessary.
+   Record its offset or -1 if we did not need to use the table.  */
+static void
+remember_long_name (struct armem *mem, const char *name, size_t namelen)
+{
+  mem->long_name_off = (namelen > MAX_AR_NAME_LEN
+			? arlib_add_long_name (name, namelen)
+			: -1l);
+}
+
+static int
+do_oper_delete (const char *arfname, char **argv, int argc,
+		long int instance)
+{
+  bool *found = alloca (sizeof (bool) * argc);
+  memset (found, '\0', sizeof (bool) * argc);
+
+  /* List of the files we keep.  */
+  struct armem *to_copy = NULL;
+
+  int status = 0;
+  Elf *elf;
+  struct stat st;
+  int fd = open_archive (arfname, O_RDONLY, 0, &elf, &st, false);
+
+  if (hcreate (2 * argc) == 0)
+    error (EXIT_FAILURE, errno, gettext ("cannot create hash table"));
+
+  for (int cnt = 0; cnt < argc; ++cnt)
+    {
+      ENTRY entry = { .key = argv[cnt], .data = &argv[cnt] };
+      if (hsearch (entry, ENTER) == NULL)
+	error (EXIT_FAILURE, errno,
+	       gettext ("cannot insert into hash table"));
+    }
+
+  arlib_init ();
+
+  off_t cur_off = SARMAG;
+  Elf_Cmd cmd = ELF_C_READ_MMAP;
+  Elf *subelf;
+  while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+    {
+      Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+
+      /* Ignore the symbol table and the long file name table here.  */
+      if (strcmp (arhdr->ar_name, "/") == 0
+	  || strcmp (arhdr->ar_name, "//") == 0)
+	goto next;
+
+      bool do_delete = argc <= 0;
+      if (!do_delete)
+	{
+	  ENTRY entry;
+	  entry.key = arhdr->ar_name;
+	  ENTRY *res = hsearch (entry, FIND);
+	  if (res != NULL && (instance < 0 || instance-- == 0)
+	      && !found[(char **) res->data - argv])
+	    found[(char **) res->data - argv] = do_delete = true;
+	}
+
+      if (do_delete)
+	{
+	  if (verbose)
+	    printf ("d - %s\n", arhdr->ar_name);
+	}
+      else
+	{
+	  struct armem *newp = alloca (sizeof (struct armem));
+	  newp->old_off = elf_getaroff (subelf);
+	  newp->off = cur_off;
+
+	  cur_off += (((arhdr->ar_size + 1) & ~((off_t) 1))
+		      + sizeof (struct ar_hdr));
+
+	  if (to_copy == NULL)
+	    to_copy = newp->next = newp;
+	  else
+	    {
+	      newp->next = to_copy->next;
+	      to_copy = to_copy->next = newp;
+	    }
+
+	  /* If we recreate the symbol table read the file's symbol
+	     table now.  */
+	  arlib_add_symbols (subelf, arfname, arhdr->ar_name, newp->off);
+
+	  /* Remember long file names.  */
+	  remember_long_name (newp, arhdr->ar_name, strlen (arhdr->ar_name));
+	}
+
+    next:
+      cmd = elf_next (subelf);
+      if (elf_end (subelf) != 0)
+	error (1, 0, "%s: %s", arfname, elf_errmsg (-1));
+    }
+
+  arlib_finalize ();
+
+  hdestroy ();
+
+  /* Create a new, temporary file in the same directory as the
+     original file.  */
+  char tmpfname[strlen (arfname) + 7];
+  strcpy (stpcpy (tmpfname, arfname), "XXXXXX");
+  int newfd = mkstemp (tmpfname);
+  if (unlikely (newfd == -1))
+    goto nonew;
+
+  /* Create the header.  */
+  if (unlikely (write_retry (newfd, ARMAG, SARMAG) != SARMAG))
+    {
+      // XXX Use /prof/self/fd/%d ???
+    nonew_unlink:
+      unlink (tmpfname);
+      if (newfd != -1)
+	close (newfd);
+    nonew:
+      error (0, errno, gettext ("cannot create new file"));
+      status = 1;
+      goto errout;
+    }
+
+  /* If the archive is empty that is all we have to do.  */
+  if (likely (to_copy != NULL))
+    {
+      /* Write the symbol table or the long file name table or both.  */
+      if (symtab.symsnamelen != 0
+	  && ((write_retry (newfd, symtab.symsoff, symtab.symsofflen)
+	       != (ssize_t) symtab.symsofflen)
+	      || (write_retry (newfd, symtab.symsname, symtab.symsnamelen)
+		  != (ssize_t) symtab.symsnamelen)))
+	goto nonew_unlink;
+
+      if (symtab.longnameslen > sizeof (struct ar_hdr)
+	  && (write_retry (newfd, symtab.longnames, symtab.longnameslen)
+	      != (ssize_t) symtab.longnameslen))
+	goto nonew_unlink;
+
+      /* NULL-terminate the list of files to copy.  */
+      struct armem *last = to_copy;
+      to_copy = to_copy->next;
+      last->next = NULL;
+
+      off_t start = -1;
+      off_t len = -1;
+
+      do
+	if (write_member (to_copy, &start, &len, elf, cur_off, newfd) != 0)
+	  goto nonew_unlink;
+      while ((to_copy = to_copy->next) != NULL);
+
+      /* Write the last part.  */
+      if (copy_content (elf, newfd, start, len))
+	goto nonew_unlink;
+    }
+
+  /* Set the mode of the new file to the same values the original file
+     has.  */
+  if (fchmod (newfd, st.st_mode & ALLPERMS) != 0
+      /* Never complain about fchown failing.  */
+      || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
+	  close (newfd) != 0)
+      || (newfd = -1, rename (tmpfname, arfname) != 0))
+    goto nonew_unlink;
+
+ errout:
+  elf_end (elf);
+
+  arlib_fini ();
+
+  close (fd);
+
+  not_found (argc, argv, found);
+
+  return status;
+}
+
+
+/* Prints the given value in the given buffer without a trailing zero char.
+   Returns false if the given value doesn't fit in the given buffer.  */
+static bool
+no0print (bool ofmt, char *buf, int bufsize, long int val)
+{
+  char tmpbuf[bufsize + 1];
+  int ret = snprintf (tmpbuf, sizeof (tmpbuf), ofmt ? "%-*lo" : "%-*ld",
+		      bufsize, val);
+  if (ret >= (int) sizeof (tmpbuf))
+    return false;
+  memcpy (buf, tmpbuf, bufsize);
+  return true;
+}
+
+
+static int
+do_oper_insert (int oper, const char *arfname, char **argv, int argc,
+		const char *member)
+{
+  int status = 0;
+  Elf *elf = NULL;
+  struct stat st;
+  int fd = open_archive (arfname, O_RDONLY, 0, &elf, &st, oper != oper_move);
+
+  /* List of the files we keep.  */
+  struct armem *all = NULL;
+  struct armem *after_memberelem = NULL;
+  struct armem **found = alloca (sizeof (*found) * argc);
+  memset (found, '\0', sizeof (*found) * argc);
+
+  arlib_init ();
+
+  /* Initialize early for no_old case.  */
+  off_t cur_off = SARMAG;
+
+  if (fd == -1)
+    {
+      if (!suppress_create_msg)
+	fprintf (stderr, "%s: creating %s\n",
+		 program_invocation_short_name, arfname);
+
+      goto no_old;
+    }
+
+  /* Store the names of all files from the command line in a hash
+     table so that we can match it.  Note that when no file name is
+     given we are basically doing nothing except recreating the
+     index.  */
+  if (oper != oper_qappend)
+    {
+      if (hcreate (2 * argc) == 0)
+	error (EXIT_FAILURE, errno, gettext ("cannot create hash table"));
+
+      for (int cnt = 0; cnt < argc; ++cnt)
+	{
+	  ENTRY entry;
+	  entry.key = full_path ? argv[cnt] : basename (argv[cnt]);
+	  entry.data = &argv[cnt];
+	  if (hsearch (entry, ENTER) == NULL)
+	    error (EXIT_FAILURE, errno,
+		   gettext ("cannot insert into hash table"));
+	}
+    }
+
+  /* While iterating over the current content of the archive we must
+     determine a number of things: which archive members to keep,
+     which are replaced, and where to insert the new members.  */
+  Elf_Cmd cmd = ELF_C_READ_MMAP;
+  Elf *subelf;
+  while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+    {
+      Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+
+      /* Ignore the symbol table and the long file name table here.  */
+      if (strcmp (arhdr->ar_name, "/") == 0
+	  || strcmp (arhdr->ar_name, "//") == 0)
+	goto next;
+
+      struct armem *newp = alloca (sizeof (struct armem));
+      newp->old_off = elf_getaroff (subelf);
+      newp->size = arhdr->ar_size;
+      newp->sec = arhdr->ar_date;
+      newp->mem = NULL;
+
+      /* Remember long file names.  */
+      remember_long_name (newp, arhdr->ar_name, strlen (arhdr->ar_name));
+
+      /* Check whether this is a file we are looking for.  */
+      if (oper != oper_qappend)
+	{
+	  /* Check whether this is the member used as the insert point.  */
+	  if (member != NULL && strcmp (arhdr->ar_name, member) == 0)
+	    {
+	      /* Note that all == NULL means insert at the beginning.  */
+	      if (ipos == ipos_before)
+		after_memberelem = all;
+	      else
+		after_memberelem = newp;
+	      member = NULL;
+	    }
+
+	  ENTRY entry;
+	  entry.key = arhdr->ar_name;
+	  ENTRY *res = hsearch (entry, FIND);
+	  if (res != NULL && found[(char **) res->data - argv] == NULL)
+	    {
+	      found[(char **) res->data - argv] = newp;
+
+	      /* If we insert before or after a certain element move
+		 all files to a special list.  */
+	      if (unlikely (ipos != ipos_none || oper == oper_move))
+		{
+		  if (after_memberelem == newp)
+		    /* Since we remove this element even though we should
+		       insert everything after it, we in fact insert
+		       everything after the previous element.  */
+		    after_memberelem = all;
+
+		  goto next;
+		}
+	    }
+	}
+
+      if (all == NULL)
+	all = newp->next = newp;
+      else
+	{
+	  newp->next = all->next;
+	  all = all->next = newp;
+	}
+
+    next:
+      cmd = elf_next (subelf);
+      if (elf_end (subelf) != 0)
+	error (EXIT_FAILURE, 0, "%s: %s", arfname, elf_errmsg (-1));
+    }
+
+  if (oper != oper_qappend)
+    hdestroy ();
+
+ no_old:
+  if (member != NULL)
+    error (EXIT_FAILURE, 0, gettext ("position member %s not found"),
+	   member);
+
+  if (oper == oper_move)
+    {
+      /* Make sure all requested elements are found in the archive.  */
+      for (int cnt = 0; cnt < argc; ++cnt)
+	{
+	  if (found[cnt] == NULL)
+	    {
+	      fprintf (stderr, gettext ("%s: no entry %s in archive!\n"),
+		       program_invocation_short_name, argv[cnt]);
+	      status = 1;
+	    }
+
+	  if (verbose)
+	    printf ("m - %s\n", argv[cnt]);
+	}
+    }
+  else
+    {
+      /* Open all the new files, get their sizes and add all symbols.  */
+      for (int cnt = 0; cnt < argc; ++cnt)
+	{
+	  const char *bname = basename (argv[cnt]);
+	  size_t bnamelen = strlen (bname);
+	  if (found[cnt] == NULL)
+	    {
+	      found[cnt] = alloca (sizeof (struct armem));
+	      found[cnt]->old_off = -1;
+
+	      remember_long_name (found[cnt], bname, bnamelen);
+	    }
+
+	  struct stat newst;
+	  Elf *newelf;
+	  int newfd = open (argv[cnt], O_RDONLY);
+	  if (newfd == -1)
+	    {
+	      error (0, errno, gettext ("cannot open %s"), argv[cnt]);
+	      status = 1;
+	    }
+	  else if (fstat (newfd, &newst) == -1)
+	    {
+	      error (0, errno, gettext ("cannot stat %s"), argv[cnt]);
+	      close (newfd);
+	      status = 1;
+	    }
+	  else if (!S_ISREG (newst.st_mode))
+	    {
+	      error (0, errno, gettext ("%s is no regular file"), argv[cnt]);
+	      close (newfd);
+	      status = 1;
+	    }
+	  else if (update_newer
+		   && found[cnt]->old_off != -1l
+		   && found[cnt]->sec > st.st_mtime)
+	    /* Do nothing, the file in the archive is younger.  */
+	    close (newfd);
+	  else if ((newelf = elf_begin (newfd, ELF_C_READ_MMAP, NULL))
+		   == NULL)
+	    {
+	      fprintf (stderr,
+		       gettext ("cannot get ELF descriptor for %s: %s\n"),
+		       argv[cnt], elf_errmsg (-1));
+	      status = 1;
+	    }
+	  else
+	    {
+	      if (verbose)
+		printf ("%c - %s\n",
+			found[cnt]->old_off == -1l ? 'a' : 'r', argv[cnt]);
+
+	      found[cnt]->elf = newelf;
+	      found[cnt]->sec = arlib_deterministic_output ? 0 : newst.st_mtime;
+	      found[cnt]->uid = arlib_deterministic_output ? 0 : newst.st_uid;
+	      found[cnt]->gid = arlib_deterministic_output ? 0 : newst.st_gid;
+	      found[cnt]->mode = newst.st_mode;
+	      found[cnt]->name = bname;
+
+	      found[cnt]->mem = elf_rawfile (newelf, &found[cnt]->size);
+	      if (found[cnt]->mem == NULL
+		  || elf_cntl (newelf, ELF_C_FDDONE) != 0)
+		error (EXIT_FAILURE, 0, gettext ("cannot read %s: %s"),
+		       argv[cnt], elf_errmsg (-1));
+
+	      close (newfd);
+
+	      if (found[cnt]->old_off != -1l)
+		/* Remember long file names.  */
+		remember_long_name (found[cnt], bname, bnamelen);
+	    }
+	}
+    }
+
+  if (status != 0)
+    {
+      elf_end (elf);
+
+      arlib_fini ();
+
+      close (fd);
+
+      return status;
+    }
+
+  /* If we have no entry point so far add at the end.  AFTER_MEMBERELEM
+     being NULL when adding before an entry means add at the beginning.  */
+  if (ipos != ipos_before && after_memberelem == NULL)
+    after_memberelem = all;
+
+  /* Convert the circular list into a normal list first.  */
+  if (all != NULL)
+    {
+      struct armem *tmp = all;
+      all = all->next;
+      tmp->next = NULL;
+    }
+
+  struct armem *last_added = after_memberelem;
+  for (int cnt = 0; cnt < argc; ++cnt)
+    if (oper != oper_replace || found[cnt]->old_off == -1)
+      {
+	if (last_added == NULL)
+	  {
+	    found[cnt]->next = all;
+	    last_added = all = found[cnt];
+	  }
+	else
+	  {
+	    found[cnt]->next = last_added->next;
+	    last_added = last_added->next = found[cnt];
+	  }
+      }
+
+  /* Finally compute the offset and add the symbols for the files
+     after the insert point.  */
+  if (likely (all != NULL))
+    for (struct armem *memp = all; memp != NULL; memp = memp->next)
+      {
+	memp->off = cur_off;
+
+	if (memp->mem == NULL)
+	  {
+	    Elf_Arhdr *arhdr;
+	    /* Fake initializing arhdr and subelf to keep gcc calm.  */
+	    asm ("" : "=m" (arhdr), "=m" (subelf));
+	    if (elf_rand (elf, memp->old_off) == 0
+		|| (subelf = elf_begin (fd, ELF_C_READ_MMAP, elf)) == NULL
+		|| (arhdr = elf_getarhdr (subelf)) == NULL)
+	      /* This should never happen since we already looked at the
+		 archive content.  But who knows...  */
+	      error (EXIT_FAILURE, 0, "%s: %s", arfname, elf_errmsg (-1));
+
+	    arlib_add_symbols (subelf, arfname, arhdr->ar_name, cur_off);
+
+	    elf_end (subelf);
+	  }
+	else
+	  arlib_add_symbols (memp->elf, arfname, memp->name, cur_off);
+
+	cur_off += (((memp->size + 1) & ~((off_t) 1))
+		    + sizeof (struct ar_hdr));
+      }
+
+  /* Now we have all the information for the symbol table and long
+     file name table.  Construct the final layout.  */
+  arlib_finalize ();
+
+  /* Create a new, temporary file in the same directory as the
+     original file.  */
+  char tmpfname[strlen (arfname) + 7];
+  strcpy (stpcpy (tmpfname, arfname), "XXXXXX");
+  int newfd;
+  if (fd != -1)
+    newfd = mkstemp (tmpfname);
+  else
+    {
+      newfd = open (arfname, O_RDWR | O_CREAT | O_EXCL, DEFFILEMODE);
+      if (newfd == -1 && errno == EEXIST)
+	/* Bah, first the file did not exist, now it does.  Restart.  */
+	return do_oper_insert (oper, arfname, argv, argc, member);
+    }
+  if (unlikely (newfd == -1))
+    goto nonew;
+
+  /* Create the header.  */
+  if (unlikely (write_retry (newfd, ARMAG, SARMAG) != SARMAG))
+    {
+    nonew_unlink:
+      if (fd != -1)
+	{
+	  // XXX Use /prof/self/fd/%d ???
+	  unlink (tmpfname);
+	  if (newfd != -1)
+	    close (newfd);
+	}
+    nonew:
+      error (0, errno, gettext ("cannot create new file"));
+      status = 1;
+      goto errout;
+    }
+
+  /* If the new archive is not empty we actually have something to do.  */
+  if (likely (all != NULL))
+    {
+      /* Write the symbol table or the long file name table or both.  */
+      if (symtab.symsnamelen != 0
+	  && ((write_retry (newfd, symtab.symsoff, symtab.symsofflen)
+	       != (ssize_t) symtab.symsofflen)
+	      || (write_retry (newfd, symtab.symsname, symtab.symsnamelen)
+		  != (ssize_t) symtab.symsnamelen)))
+	goto nonew_unlink;
+
+      if (symtab.longnameslen > sizeof (struct ar_hdr)
+	  && (write_retry (newfd, symtab.longnames, symtab.longnameslen)
+	      != (ssize_t) symtab.longnameslen))
+	goto nonew_unlink;
+
+      off_t start = -1;
+      off_t len = -1;
+
+      while (all != NULL)
+	{
+	  if (all->mem != NULL)
+	    {
+	      /* This is a new file.  If there is anything from the
+		 archive left to be written do it now.  */
+	      if (start != -1  && copy_content (elf, newfd, start, len))
+		goto nonew_unlink;
+
+	      start = -1;
+	      len = -1;
+
+	      /* Create the header.  */
+	      struct ar_hdr arhdr;
+	      /* The ar_name is not actually zero teminated, but we
+		 need that for snprintf.  Also if the name is too
+		 long, then the string starts with '/' plus an index
+		 off number (decimal).  */
+	      char tmpbuf[sizeof (arhdr.ar_name) + 2];
+	      if (all->long_name_off == -1)
+		{
+		  size_t namelen = strlen (all->name);
+		  char *p = mempcpy (arhdr.ar_name, all->name, namelen);
+		  *p++ = '/';
+		  memset (p, ' ', sizeof (arhdr.ar_name) - namelen - 1);
+		}
+	      else
+		{
+		  snprintf (tmpbuf, sizeof (tmpbuf), "/%-*ld",
+			    (int) sizeof (arhdr.ar_name), all->long_name_off);
+		  memcpy (arhdr.ar_name, tmpbuf, sizeof (arhdr.ar_name));
+		}
+
+	      if (! no0print (false, arhdr.ar_date, sizeof (arhdr.ar_date),
+			      all->sec))
+		{
+		  error (0, errno, gettext ("cannot represent ar_date"));
+		  goto nonew_unlink;
+		}
+	      if (! no0print (false, arhdr.ar_uid, sizeof (arhdr.ar_uid),
+			      all->uid))
+		{
+		  error (0, errno, gettext ("cannot represent ar_uid"));
+		  goto nonew_unlink;
+		}
+	      if (! no0print (false, arhdr.ar_gid, sizeof (arhdr.ar_gid),
+			      all->gid))
+		{
+		  error (0, errno, gettext ("cannot represent ar_gid"));
+		  goto nonew_unlink;
+		}
+	      if (! no0print (true, arhdr.ar_mode, sizeof (arhdr.ar_mode),
+			all->mode))
+		{
+		  error (0, errno, gettext ("cannot represent ar_mode"));
+		  goto nonew_unlink;
+		}
+	      if (! no0print (false, arhdr.ar_size, sizeof (arhdr.ar_size),
+			all->size))
+		{
+		  error (0, errno, gettext ("cannot represent ar_size"));
+		  goto nonew_unlink;
+		}
+	      memcpy (arhdr.ar_fmag, ARFMAG, sizeof (arhdr.ar_fmag));
+
+	      if (unlikely (write_retry (newfd, &arhdr, sizeof (arhdr))
+			    != sizeof (arhdr)))
+		goto nonew_unlink;
+
+	      /* Now the file itself.  */
+	      if (unlikely (write_retry (newfd, all->mem, all->size)
+			    != (off_t) all->size))
+		goto nonew_unlink;
+
+	      /* Pad the file if its size is odd.  */
+	      if ((all->size & 1) != 0)
+		if (unlikely (write_retry (newfd, "\n", 1) != 1))
+		  goto nonew_unlink;
+	    }
+	  else
+	    {
+	      /* This is a member from the archive.  */
+	      if (write_member (all, &start, &len, elf, cur_off, newfd)
+		  != 0)
+		goto nonew_unlink;
+	    }
+
+	  all = all->next;
+	}
+
+      /* Write the last part.  */
+      if (start != -1 && copy_content (elf, newfd, start, len))
+	goto nonew_unlink;
+    }
+
+  /* Set the mode of the new file to the same values the original file
+     has.  */
+  if (fd != -1
+      && (fchmod (newfd, st.st_mode & ALLPERMS) != 0
+	  /* Never complain about fchown failing.  */
+	  || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
+	      close (newfd) != 0)
+	  || (newfd = -1, rename (tmpfname, arfname) != 0)))
+      goto nonew_unlink;
+
+ errout:
+  for (int cnt = 0; cnt < argc; ++cnt)
+    elf_end (found[cnt]->elf);
+
+  elf_end (elf);
+
+  arlib_fini ();
+
+  if (fd != -1)
+    close (fd);
+
+  return status;
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/arlib-argp.c b/third_party/elfutils/src/arlib-argp.c
new file mode 100644
index 0000000..1bdd8d0
--- /dev/null
+++ b/third_party/elfutils/src/arlib-argp.c
@@ -0,0 +1,94 @@
+/* Options common to ar and ranlib.
+   Copyright (C) 2012 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <libintl.h>
+
+#include "arlib.h"
+
+bool arlib_deterministic_output = DEFAULT_AR_DETERMINISTIC;
+
+static const struct argp_option options[] =
+  {
+    { NULL, 'D', NULL, 0,
+      N_("Use zero for uid, gid, and date in archive members."), 0 },
+    { NULL, 'U', NULL, 0,
+      N_("Use actual uid, gid, and date in archive members."), 0 },
+
+    { NULL, 0, NULL, 0, NULL, 0 }
+  };
+
+static error_t
+parse_opt (int key, char *arg __attribute__ ((unused)),
+           struct argp_state *state __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case 'D':
+      arlib_deterministic_output = true;
+      break;
+
+    case 'U':
+      arlib_deterministic_output = false;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+static char *
+help_filter (int key, const char *text, void *input __attribute__ ((unused)))
+{
+  inline char *text_for_default (void)
+  {
+    char *new_text;
+    if (unlikely (asprintf (&new_text, gettext ("%s (default)"), text) < 0))
+      return (char *) text;
+    return new_text;
+  }
+
+  switch (key)
+    {
+    case 'D':
+      if (DEFAULT_AR_DETERMINISTIC)
+        return text_for_default ();
+      break;
+    case 'U':
+      if (! DEFAULT_AR_DETERMINISTIC)
+        return text_for_default ();
+      break;
+    }
+
+  return (char *) text;
+}
+
+static const struct argp argp =
+  {
+    options, parse_opt, NULL, NULL, NULL, help_filter, NULL
+  };
+
+const struct argp_child arlib_argp_children[] =
+  {
+    { &argp, 0, "", 2 },
+    { NULL, 0, NULL, 0 }
+  };
diff --git a/third_party/elfutils/src/arlib.c b/third_party/elfutils/src/arlib.c
new file mode 100644
index 0000000..e0839aa
--- /dev/null
+++ b/third_party/elfutils/src/arlib.c
@@ -0,0 +1,277 @@
+/* Functions to handle creation of Linux archives.
+   Copyright (C) 2007-2012, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <error.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <libintl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <libeu.h>
+
+#include "arlib.h"
+
+
+/* The one symbol table we hanble.  */
+struct arlib_symtab symtab;
+
+
+/* Initialize ARLIB_SYMTAB structure.  */
+void
+arlib_init (void)
+{
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+  obstack_init (&symtab.symsoffob);
+  obstack_init (&symtab.symsnameob);
+  obstack_init (&symtab.longnamesob);
+
+  /* We add the archive header here as well, that avoids allocating
+     another memory block.  */
+  struct ar_hdr ar_hdr;
+  memcpy (ar_hdr.ar_name, "/               ", sizeof (ar_hdr.ar_name));
+  /* Using snprintf here has a problem: the call always wants to add a
+     NUL byte.  We could use a trick whereby we specify the target
+     buffer size longer than it is and this would not actually fail,
+     since all the fields are consecutive and we fill them in
+     sequence (i.e., the NUL byte gets overwritten).  But
+     _FORTIFY_SOURCE=2 would not let us play these games.  Therefore
+     we play it safe.  */
+  char tmpbuf[sizeof (ar_hdr.ar_date) + 1];
+  int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*lld",
+		    (int) sizeof (ar_hdr.ar_date),
+                    (arlib_deterministic_output ? 0
+                     : (long long int) time (NULL)));
+  memcpy (ar_hdr.ar_date, tmpbuf, s);
+  assert ((sizeof (struct ar_hdr)  % sizeof (uint32_t)) == 0);
+
+  /* Note the string for the ar_uid and ar_gid cases is longer than
+     necessary.  This does not matter since we copy only as much as
+     necessary but it helps the compiler to use the same string for
+     the ar_mode case.  */
+  memcpy (ar_hdr.ar_uid, "0       ", sizeof (ar_hdr.ar_uid));
+  memcpy (ar_hdr.ar_gid, "0       ", sizeof (ar_hdr.ar_gid));
+  memcpy (ar_hdr.ar_mode, "0       ", sizeof (ar_hdr.ar_mode));
+  memcpy (ar_hdr.ar_fmag, ARFMAG, sizeof (ar_hdr.ar_fmag));
+
+  /* Add the archive header to the file content.  */
+  obstack_grow (&symtab.symsoffob, &ar_hdr, sizeof (ar_hdr));
+
+  /* The first word in the offset table specifies the size.  Create
+     such an entry now.  The real value will be filled-in later.  For
+     all supported platforms the following is true.  */
+  assert (sizeof (uint32_t) == sizeof (int));
+  obstack_int_grow (&symtab.symsoffob, 0);
+
+  /* The long name obstack also gets its archive header.  As above,
+     some of the input strings are longer than required but we only
+     copy the necessary part.  */
+  memcpy (ar_hdr.ar_name, "//              ", sizeof (ar_hdr.ar_name));
+  memcpy (ar_hdr.ar_date, "            ", sizeof (ar_hdr.ar_date));
+  memcpy (ar_hdr.ar_uid, "            ", sizeof (ar_hdr.ar_uid));
+  memcpy (ar_hdr.ar_gid, "            ", sizeof (ar_hdr.ar_gid));
+  memcpy (ar_hdr.ar_mode, "            ", sizeof (ar_hdr.ar_mode));
+  /* The ar_size field will be filled in later and ar_fmag is already OK.  */
+  obstack_grow (&symtab.longnamesob, &ar_hdr, sizeof (ar_hdr));
+
+  /* All other members are zero.  */
+  symtab.symsofflen = 0;
+  symtab.symsoff = NULL;
+  symtab.symsnamelen = 0;
+  symtab.symsname = NULL;
+}
+
+
+/* Finalize ARLIB_SYMTAB content.  */
+void
+arlib_finalize (void)
+{
+  /* Note that the size is stored as decimal string in 10 chars,
+     without zero terminator (we add + 1 here only so snprintf can
+     put it at the end, we then don't use it when we memcpy it).  */
+  char tmpbuf[sizeof (((struct ar_hdr *) NULL)->ar_size) + 1];
+
+  symtab.longnameslen = obstack_object_size (&symtab.longnamesob);
+  if (symtab.longnameslen != sizeof (struct ar_hdr))
+    {
+      if ((symtab.longnameslen & 1) != 0)
+	{
+	  /* Add one more byte to make length even.  */
+	  obstack_grow (&symtab.longnamesob, "\n", 1);
+	  ++symtab.longnameslen;
+	}
+
+      symtab.longnames = obstack_finish (&symtab.longnamesob);
+
+      int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*" PRIu32 "",
+			(int) sizeof (((struct ar_hdr *) NULL)->ar_size),
+			(uint32_t) (symtab.longnameslen - sizeof (struct ar_hdr)));
+      memcpy (&((struct ar_hdr *) symtab.longnames)->ar_size, tmpbuf, s);
+    }
+
+  symtab.symsofflen = obstack_object_size (&symtab.symsoffob);
+  assert (symtab.symsofflen % sizeof (uint32_t) == 0);
+  if (symtab.symsofflen != 0)
+    {
+      symtab.symsoff = (uint32_t *) obstack_finish (&symtab.symsoffob);
+
+      /* Fill in the number of offsets now.  */
+      symtab.symsoff[AR_HDR_WORDS] = le_bswap_32 ((symtab.symsofflen
+						    - sizeof (struct ar_hdr))
+						   / sizeof (uint32_t) - 1);
+    }
+
+  symtab.symsnamelen = obstack_object_size (&symtab.symsnameob);
+  if ((symtab.symsnamelen & 1) != 0)
+    {
+      /* Add one more NUL byte to make length even.  */
+      obstack_grow (&symtab.symsnameob, "", 1);
+      ++symtab.symsnamelen;
+    }
+  symtab.symsname = obstack_finish (&symtab.symsnameob);
+
+  /* Determine correction for the offsets in the symbol table.   */
+  off_t disp = 0;
+  if (symtab.symsnamelen > 0)
+    disp = symtab.symsofflen + symtab.symsnamelen;
+  if (symtab.longnameslen > sizeof (struct ar_hdr))
+    disp += symtab.longnameslen;
+
+  if (disp != 0 && symtab.symsoff != NULL)
+    {
+      uint32_t nsyms = le_bswap_32 (symtab.symsoff[AR_HDR_WORDS]);
+
+      for (uint32_t cnt = 1; cnt <= nsyms; ++cnt)
+	{
+	  uint32_t val = le_bswap_32 (symtab.symsoff[AR_HDR_WORDS + cnt]);
+	  val += disp;
+	  symtab.symsoff[AR_HDR_WORDS + cnt] = le_bswap_32 (val);
+	}
+    }
+
+  /* See comment for ar_date above.  */
+  memcpy (&((struct ar_hdr *) symtab.symsoff)->ar_size, tmpbuf,
+	  snprintf (tmpbuf, sizeof (tmpbuf), "%-*" PRIu32 "",
+		    (int) sizeof (((struct ar_hdr *) NULL)->ar_size),
+		    (uint32_t) (symtab.symsofflen + symtab.symsnamelen
+				- sizeof (struct ar_hdr))));
+}
+
+
+/* Free resources for ARLIB_SYMTAB.  */
+void
+arlib_fini (void)
+{
+  obstack_free (&symtab.symsoffob, NULL);
+  obstack_free (&symtab.symsnameob, NULL);
+  obstack_free (&symtab.longnamesob, NULL);
+}
+
+
+/* Add name a file offset of a symbol.  */
+void
+arlib_add_symref (const char *symname, off_t symoff)
+{
+  /* For all supported platforms the following is true.  */
+  assert (sizeof (uint32_t) == sizeof (int));
+  obstack_int_grow (&symtab.symsoffob, (int) le_bswap_32 (symoff));
+
+  size_t symname_len = strlen (symname) + 1;
+  obstack_grow (&symtab.symsnameob, symname, symname_len);
+}
+
+
+/* Add symbols from ELF with value OFFSET to the symbol table SYMTAB.  */
+void
+arlib_add_symbols (Elf *elf, const char *arfname, const char *membername,
+		   off_t off)
+{
+  if (sizeof (off) > sizeof (uint32_t) && off > ~((uint32_t) 0))
+    /* The archive is too big.  */
+    error (EXIT_FAILURE, 0, gettext ("the archive '%s' is too large"),
+	   arfname);
+
+  /* We only add symbol tables for ELF files.  It makes not much sense
+     to add symbols from executables but we do so for compatibility.
+     For DSOs and executables we use the dynamic symbol table, for
+     relocatable files all the DT_SYMTAB tables.  */
+  if (elf_kind (elf) != ELF_K_ELF)
+    return;
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    error (EXIT_FAILURE, 0, gettext ("cannot read ELF header of %s(%s): %s"),
+	   arfname, membername, elf_errmsg (-1));
+
+  GElf_Word symtype;
+  if (ehdr->e_type == ET_REL)
+    symtype = SHT_SYMTAB;
+  else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN)
+    symtype = SHT_DYNSYM;
+  else
+    /* We do not handle that type.  */
+    return;
+
+  /* Iterate over all sections.  */
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      /* Get the section header.  */
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	continue;
+
+      if (shdr->sh_type != symtype)
+	continue;
+
+      Elf_Data *data = elf_getdata (scn, NULL);
+      if (data == NULL)
+	continue;
+
+      int nsyms = shdr->sh_size / shdr->sh_entsize;
+      for (int ndx = shdr->sh_info; ndx < nsyms; ++ndx)
+	{
+	  GElf_Sym sym_mem;
+	  GElf_Sym *sym = gelf_getsym (data, ndx, &sym_mem);
+	  if (sym == NULL)
+	    continue;
+
+	  /* Ignore undefined symbols.  */
+	  if (sym->st_shndx == SHN_UNDEF)
+	    continue;
+
+	  /* Use this symbol.  */
+	  const char *symname = elf_strptr (elf, shdr->sh_link, sym->st_name);
+	  if (symname != NULL)
+	    arlib_add_symref (symname, off);
+	}
+
+      /* Only relocatable files can have more than one symbol table.  */
+      if (ehdr->e_type != ET_REL)
+	break;
+    }
+}
diff --git a/third_party/elfutils/src/arlib.h b/third_party/elfutils/src/arlib.h
new file mode 100644
index 0000000..e117166
--- /dev/null
+++ b/third_party/elfutils/src/arlib.h
@@ -0,0 +1,98 @@
+/* Copyright (C) 2007-2012 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ARLIB_H
+#define _ARLIB_H	1
+
+#include <ar.h>
+#include <argp.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <libelf.h>
+#include <obstack.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+
+/* State of -D/-U flags.  */
+extern bool arlib_deterministic_output;
+
+/* For options common to ar and ranlib.  */
+extern const struct argp_child arlib_argp_children[];
+
+
+/* Maximum length of a file name that fits directly into the ar header.
+   We cannot use the final byte since a / goes there.  */
+#define MAX_AR_NAME_LEN (sizeof (((struct ar_hdr *) NULL)->ar_name) - 1)
+
+
+/* Words matching in size to archive header.  */
+#define AR_HDR_WORDS (sizeof (struct ar_hdr) / sizeof (uint32_t))
+
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+# define le_bswap_32(val) bswap_32 (val)
+#else
+# define le_bswap_32(val) (val)
+#endif
+
+
+/* Symbol table type.  */
+struct arlib_symtab
+{
+  /* Symbol table handling.  */
+  struct obstack symsoffob;
+  struct obstack symsnameob;
+  size_t symsofflen;
+  uint32_t *symsoff;
+  size_t symsnamelen;
+  char *symsname;
+
+  /* Long filename handling.  */
+  struct obstack longnamesob;
+  size_t longnameslen;
+  char *longnames;
+};
+
+
+/* Global variable with symbol table.  */
+extern struct arlib_symtab symtab;
+
+
+/* Initialize ARLIB_SYMTAB structure.  */
+extern void arlib_init (void);
+
+/* Finalize ARLIB_SYMTAB content.  */
+extern void arlib_finalize (void);
+
+/* Free resources for ARLIB_SYMTAB.  */
+extern void arlib_fini (void);
+
+/* Add symbols from ELF with value OFFSET to the symbol table SYMTAB.  */
+extern void arlib_add_symbols (Elf *elf, const char *arfname,
+			       const char *membername, off_t off);
+
+/* Add name a file offset of a symbol.  */
+extern void arlib_add_symref (const char *symname, off_t symoff);
+
+/* Add long file name FILENAME of length FILENAMELEN to the symbol table
+   SYMTAB.  Return the offset into the long file name table.  */
+extern long int arlib_add_long_name (const char *filename, size_t filenamelen);
+
+#endif	/* arlib.h */
diff --git a/third_party/elfutils/src/arlib2.c b/third_party/elfutils/src/arlib2.c
new file mode 100644
index 0000000..553fc57
--- /dev/null
+++ b/third_party/elfutils/src/arlib2.c
@@ -0,0 +1,42 @@
+/* Functions to handle creation of Linux archives.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <error.h>
+#include <libintl.h>
+#include <limits.h>
+#include <string.h>
+
+#include "arlib.h"
+
+
+/* Add long file name FILENAME of length FILENAMELEN to the symbol table
+   SYMTAB.  Return the offset into the long file name table.  */
+long int
+arlib_add_long_name (const char *filename, size_t filenamelen)
+{
+  size_t size = obstack_object_size (&symtab.longnamesob);
+
+  obstack_grow (&symtab.longnamesob, filename, filenamelen);
+  obstack_grow (&symtab.longnamesob, "/\n", 2);
+
+  return size - sizeof (struct ar_hdr);
+}
diff --git a/third_party/elfutils/src/debugpred.h b/third_party/elfutils/src/debugpred.h
new file mode 100644
index 0000000..4845a6e
--- /dev/null
+++ b/third_party/elfutils/src/debugpred.h
@@ -0,0 +1,45 @@
+/* Support to debug branch prediction.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2007.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+
+#if DEBUGPRED
+extern const unsigned long int __start_predict_data;
+extern const unsigned long int __stop_predict_data;
+extern const unsigned long int __start_predict_line;
+extern const char *const __start_predict_file;
+
+static void
+__attribute__ ((destructor))
+predprint (void)
+{
+  const unsigned long int *s = &__start_predict_data;
+  const unsigned long int *e = &__stop_predict_data;
+  const unsigned long int *sl = &__start_predict_line;
+  const char *const *sf = &__start_predict_file;
+  while (s < e)
+    {
+      if (s[0] != 0 || s[1] != 0)
+	printf ("%s:%lu: wrong=%lu, correct=%lu%s\n", *sf, *sl, s[0], s[1],
+		s[0] > s[1] ? "   <==== WARNING" : "");
+      ++sl;
+      ++sf;
+      s += 2;
+    }
+}
+#endif
diff --git a/third_party/elfutils/src/elfcmp.c b/third_party/elfutils/src/elfcmp.c
new file mode 100644
index 0000000..5046420
--- /dev/null
+++ b/third_party/elfutils/src/elfcmp.c
@@ -0,0 +1,896 @@
+/* Compare relevant content of two ELF files.
+   Copyright (C) 2005-2012, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <assert.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <libintl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <printversion.h>
+#include "../libelf/elf-knowledge.h"
+#include "../libebl/libeblP.h"
+
+
+/* Prototypes of local functions.  */
+static Elf *open_file (const char *fname, int *fdp, Ebl **eblp);
+static bool search_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx);
+static  int regioncompare (const void *p1, const void *p2);
+
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+/* Values for the parameters which have no short form.  */
+#define OPT_GAPS		0x100
+#define OPT_HASH_INEXACT	0x101
+#define OPT_IGNORE_BUILD_ID	0x102
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("Control options:"), 0 },
+  { "verbose", 'l', NULL, 0,
+    N_("Output all differences, not just the first"), 0 },
+  { "gaps", OPT_GAPS, "ACTION", 0, N_("Control treatment of gaps in loadable segments [ignore|match] (default: ignore)"), 0 },
+  { "hash-inexact", OPT_HASH_INEXACT, NULL, 0,
+    N_("Ignore permutation of buckets in SHT_HASH section"), 0 },
+  { "ignore-build-id", OPT_IGNORE_BUILD_ID, NULL, 0,
+    N_("Ignore differences in build ID"), 0 },
+  { "quiet", 'q', NULL, 0, N_("Output nothing; yield exit status only"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("\
+Compare relevant parts of two ELF files for equality.");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("FILE1 FILE2");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  options, parse_opt, args_doc, doc, NULL, NULL, NULL
+};
+
+
+/* How to treat gaps in loadable segments.  */
+static enum
+  {
+    gaps_ignore = 0,
+    gaps_match
+  }
+  gaps;
+
+/* Structure to hold information about used regions.  */
+struct region
+{
+  GElf_Addr from;
+  GElf_Addr to;
+  struct region *next;
+};
+
+/* Nonzero if only exit status is wanted.  */
+static bool quiet;
+
+/* True iff multiple differences should be output.  */
+static bool verbose;
+
+/* True iff SHT_HASH treatment should be generous.  */
+static bool hash_inexact;
+
+/* True iff build ID notes should be ignored.  */
+static bool ignore_build_id;
+
+static bool hash_content_equivalent (size_t entsize, Elf_Data *, Elf_Data *);
+
+
+int
+main (int argc, char *argv[])
+{
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  /* Make sure the message catalog can be found.  */
+  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+
+  /* Initialize the message catalog.  */
+  (void) textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  */
+  int remaining;
+  (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+  /* We expect exactly two non-option parameters.  */
+  if (unlikely (remaining + 2 != argc))
+    {
+      fputs (gettext ("Invalid number of parameters.\n"), stderr);
+      argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name);
+      exit (1);
+    }
+
+  if (quiet)
+    verbose = false;
+
+  /* Comparing the files is done in two phases:
+     1. compare all sections.  Sections which are irrelevant (i.e., if
+	strip would remove them) are ignored.  Some section types are
+	handled special.
+     2. all parts of the loadable segments which are not parts of any
+	section is compared according to the rules of the --gaps option.
+  */
+  int result = 0;
+  elf_version (EV_CURRENT);
+
+  const char *const fname1 = argv[remaining];
+  int fd1;
+  Ebl *ebl1;
+  Elf *elf1 = open_file (fname1, &fd1, &ebl1);
+
+  const char *const fname2 = argv[remaining + 1];
+  int fd2;
+  Ebl *ebl2;
+  Elf *elf2 = open_file (fname2, &fd2, &ebl2);
+
+  GElf_Ehdr ehdr1_mem;
+  GElf_Ehdr *ehdr1 = gelf_getehdr (elf1, &ehdr1_mem);
+  if (ehdr1 == NULL)
+    error (2, 0, gettext ("cannot get ELF header of '%s': %s"),
+	   fname1, elf_errmsg (-1));
+  GElf_Ehdr ehdr2_mem;
+  GElf_Ehdr *ehdr2 = gelf_getehdr (elf2, &ehdr2_mem);
+  if (ehdr2 == NULL)
+    error (2, 0, gettext ("cannot get ELF header of '%s': %s"),
+	   fname2, elf_errmsg (-1));
+
+#define DIFFERENCE							      \
+  do									      \
+    {									      \
+      result = 1;							      \
+      if (! verbose)							      \
+	goto out;							      \
+    }									      \
+  while (0)
+
+  /* Compare the ELF headers.  */
+  if (unlikely (memcmp (ehdr1->e_ident, ehdr2->e_ident, EI_NIDENT) != 0
+		|| ehdr1->e_type != ehdr2->e_type
+		|| ehdr1->e_machine != ehdr2->e_machine
+		|| ehdr1->e_version != ehdr2->e_version
+		|| ehdr1->e_entry != ehdr2->e_entry
+		|| ehdr1->e_phoff != ehdr2->e_phoff
+		|| ehdr1->e_flags != ehdr2->e_flags
+		|| ehdr1->e_ehsize != ehdr2->e_ehsize
+		|| ehdr1->e_phentsize != ehdr2->e_phentsize
+		|| ehdr1->e_phnum != ehdr2->e_phnum
+		|| ehdr1->e_shentsize != ehdr2->e_shentsize))
+    {
+      if (! quiet)
+	error (0, 0, gettext ("%s %s diff: ELF header"), fname1, fname2);
+      DIFFERENCE;
+    }
+
+  size_t shnum1;
+  size_t shnum2;
+  if (unlikely (elf_getshdrnum (elf1, &shnum1) != 0))
+    error (2, 0, gettext ("cannot get section count of '%s': %s"),
+	   fname1, elf_errmsg (-1));
+  if (unlikely (elf_getshdrnum (elf2, &shnum2) != 0))
+    error (2, 0, gettext ("cannot get section count of '%s': %s"),
+	   fname2, elf_errmsg (-1));
+  if (unlikely (shnum1 != shnum2))
+    {
+      if (! quiet)
+	error (0, 0, gettext ("%s %s diff: section count"), fname1, fname2);
+      DIFFERENCE;
+    }
+
+  size_t phnum1;
+  size_t phnum2;
+  if (unlikely (elf_getphdrnum (elf1, &phnum1) != 0))
+    error (2, 0, gettext ("cannot get program header count of '%s': %s"),
+	   fname1, elf_errmsg (-1));
+  if (unlikely (elf_getphdrnum (elf2, &phnum2) != 0))
+    error (2, 0, gettext ("cannot get program header count of '%s': %s"),
+	   fname2, elf_errmsg (-1));
+  if (unlikely (phnum1 != phnum2))
+    {
+      if (! quiet)
+	error (0, 0, gettext ("%s %s diff: program header count"),
+	       fname1, fname2);
+      DIFFERENCE;
+    }
+
+  /* Iterate over all sections.  We expect the sections in the two
+     files to match exactly.  */
+  Elf_Scn *scn1 = NULL;
+  Elf_Scn *scn2 = NULL;
+  struct region *regions = NULL;
+  size_t nregions = 0;
+  while (1)
+    {
+      GElf_Shdr shdr1_mem;
+      GElf_Shdr *shdr1;
+      const char *sname1 = NULL;
+      do
+	{
+	  scn1 = elf_nextscn (elf1, scn1);
+	  shdr1 = gelf_getshdr (scn1, &shdr1_mem);
+	  if (shdr1 != NULL)
+	    sname1 = elf_strptr (elf1, ehdr1->e_shstrndx, shdr1->sh_name);
+	}
+      while (scn1 != NULL
+	     && ebl_section_strip_p (ebl1, ehdr1, shdr1, sname1, true, false));
+
+      GElf_Shdr shdr2_mem;
+      GElf_Shdr *shdr2;
+      const char *sname2 = NULL;
+      do
+	{
+	  scn2 = elf_nextscn (elf2, scn2);
+	  shdr2 = gelf_getshdr (scn2, &shdr2_mem);
+	  if (shdr2 != NULL)
+	    sname2 = elf_strptr (elf2, ehdr2->e_shstrndx, shdr2->sh_name);
+	}
+      while (scn2 != NULL
+	     && ebl_section_strip_p (ebl2, ehdr2, shdr2, sname2, true, false));
+
+      if (scn1 == NULL || scn2 == NULL)
+	break;
+
+      if (gaps != gaps_ignore && (shdr1->sh_flags & SHF_ALLOC) != 0)
+	{
+	  struct region *newp = (struct region *) alloca (sizeof (*newp));
+	  newp->from = shdr1->sh_offset;
+	  newp->to = shdr1->sh_offset + shdr1->sh_size;
+	  newp->next = regions;
+	  regions = newp;
+
+	  ++nregions;
+	}
+
+      /* Compare the headers.  We allow the name to be at a different
+	 location.  */
+      if (unlikely (sname1 == NULL || sname2 == NULL
+		    || strcmp (sname1, sname2) != 0))
+	{
+	  error (0, 0, gettext ("%s %s differ: section [%zu], [%zu] name"),
+		 fname1, fname2, elf_ndxscn (scn1), elf_ndxscn (scn2));
+	  DIFFERENCE;
+	}
+
+      /* We ignore certain sections.  */
+      if ((sname1 != NULL && strcmp (sname1, ".gnu_debuglink") == 0)
+	  || (sname1 != NULL && strcmp (sname1, ".gnu.prelink_undo") == 0))
+	continue;
+
+      if (shdr1->sh_type != shdr2->sh_type
+	  // XXX Any flags which should be ignored?
+	  || shdr1->sh_flags != shdr2->sh_flags
+	  || shdr1->sh_addr != shdr2->sh_addr
+	  || (shdr1->sh_offset != shdr2->sh_offset
+	      && (shdr1->sh_flags & SHF_ALLOC)
+	      && ehdr1->e_type != ET_REL)
+	  || shdr1->sh_size != shdr2->sh_size
+	  || shdr1->sh_link != shdr2->sh_link
+	  || shdr1->sh_info != shdr2->sh_info
+	  || shdr1->sh_addralign != shdr2->sh_addralign
+	  || shdr1->sh_entsize != shdr2->sh_entsize)
+	{
+	  error (0, 0, gettext ("%s %s differ: section [%zu] '%s' header"),
+		 fname1, fname2, elf_ndxscn (scn1), sname1);
+	  DIFFERENCE;
+	}
+
+      Elf_Data *data1 = elf_getdata (scn1, NULL);
+      if (data1 == NULL)
+	error (2, 0,
+	       gettext ("cannot get content of section %zu in '%s': %s"),
+	       elf_ndxscn (scn1), fname1, elf_errmsg (-1));
+
+      Elf_Data *data2 = elf_getdata (scn2, NULL);
+      if (data2 == NULL)
+	error (2, 0,
+	       gettext ("cannot get content of section %zu in '%s': %s"),
+	       elf_ndxscn (scn2), fname2, elf_errmsg (-1));
+
+      switch (shdr1->sh_type)
+	{
+	case SHT_DYNSYM:
+	case SHT_SYMTAB:
+	  if (shdr1->sh_entsize == 0)
+	    error (2, 0,
+		   gettext ("symbol table [%zu] in '%s' has zero sh_entsize"),
+		   elf_ndxscn (scn1), fname1);
+
+	  /* Iterate over the symbol table.  We ignore the st_size
+	     value of undefined symbols.  */
+	  for (int ndx = 0; ndx < (int) (shdr1->sh_size / shdr1->sh_entsize);
+	       ++ndx)
+	    {
+	      GElf_Sym sym1_mem;
+	      GElf_Sym *sym1 = gelf_getsym (data1, ndx, &sym1_mem);
+	      if (sym1 == NULL)
+		error (2, 0,
+		       gettext ("cannot get symbol in '%s': %s"),
+		       fname1, elf_errmsg (-1));
+	      GElf_Sym sym2_mem;
+	      GElf_Sym *sym2 = gelf_getsym (data2, ndx, &sym2_mem);
+	      if (sym2 == NULL)
+		error (2, 0,
+		       gettext ("cannot get symbol in '%s': %s"),
+		       fname2, elf_errmsg (-1));
+
+	      const char *name1 = elf_strptr (elf1, shdr1->sh_link,
+					      sym1->st_name);
+	      const char *name2 = elf_strptr (elf2, shdr2->sh_link,
+					      sym2->st_name);
+	      if (unlikely (name1 == NULL || name2 == NULL
+			    || strcmp (name1, name2) != 0
+			    || sym1->st_value != sym2->st_value
+			    || (sym1->st_size != sym2->st_size
+				&& sym1->st_shndx != SHN_UNDEF)
+			    || sym1->st_info != sym2->st_info
+			    || sym1->st_other != sym2->st_other
+			    || sym1->st_shndx != sym2->st_shndx))
+		{
+		  // XXX Do we want to allow reordered symbol tables?
+		symtab_mismatch:
+		  if (! quiet)
+		    {
+		      if (elf_ndxscn (scn1) == elf_ndxscn (scn2))
+			error (0, 0,
+			       gettext ("%s %s differ: symbol table [%zu]"),
+			       fname1, fname2, elf_ndxscn (scn1));
+		      else
+			error (0, 0, gettext ("\
+%s %s differ: symbol table [%zu,%zu]"),
+			       fname1, fname2, elf_ndxscn (scn1),
+			       elf_ndxscn (scn2));
+		    }
+		  DIFFERENCE;
+		  break;
+		}
+
+	      if (sym1->st_shndx == SHN_UNDEF
+		  && sym1->st_size != sym2->st_size)
+		{
+		  /* The size of the symbol in the object defining it
+		     might have changed.  That is OK unless the symbol
+		     is used in a copy relocation.  Look over the
+		     sections in both files and determine which
+		     relocation section uses this symbol table
+		     section.  Then look through the relocations to
+		     see whether any copy relocation references this
+		     symbol.  */
+		  if (search_for_copy_reloc (ebl1, elf_ndxscn (scn1), ndx)
+		      || search_for_copy_reloc (ebl2, elf_ndxscn (scn2), ndx))
+		    goto symtab_mismatch;
+		}
+	    }
+	  break;
+
+	case SHT_NOTE:
+	  /* Parse the note format and compare the notes themselves.  */
+	  {
+	    GElf_Nhdr note1;
+	    GElf_Nhdr note2;
+
+	    size_t off1 = 0;
+	    size_t off2 = 0;
+	    size_t name_offset;
+	    size_t desc_offset;
+	    while (off1 < data1->d_size
+		   && (off1 = gelf_getnote (data1, off1, &note1,
+					    &name_offset, &desc_offset)) > 0)
+	      {
+		const char *name1 = (note1.n_namesz == 0
+				     ? "" : data1->d_buf + name_offset);
+		const void *desc1 = data1->d_buf + desc_offset;
+		if (off2 >= data2->d_size)
+		  {
+		    if (! quiet)
+		      error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' number of notes"),
+			     fname1, fname2, elf_ndxscn (scn1), sname1);
+		    DIFFERENCE;
+		  }
+		off2 = gelf_getnote (data2, off2, &note2,
+				     &name_offset, &desc_offset);
+		if (off2 == 0)
+		  error (2, 0, gettext ("\
+cannot read note section [%zu] '%s' in '%s': %s"),
+			 elf_ndxscn (scn2), sname2, fname2, elf_errmsg (-1));
+		const char *name2 = (note2.n_namesz == 0
+				     ? "" : data2->d_buf + name_offset);
+		const void *desc2 = data2->d_buf + desc_offset;
+
+		if (note1.n_namesz != note2.n_namesz
+		    || memcmp (name1, name2, note1.n_namesz))
+		  {
+		    if (! quiet)
+		      error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' note name"),
+			     fname1, fname2, elf_ndxscn (scn1), sname1);
+		    DIFFERENCE;
+		  }
+		if (note1.n_type != note2.n_type)
+		  {
+		    if (! quiet)
+		      error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' note '%s' type"),
+			     fname1, fname2, elf_ndxscn (scn1), sname1, name1);
+		    DIFFERENCE;
+		  }
+		if (note1.n_descsz != note2.n_descsz
+		    || memcmp (desc1, desc2, note1.n_descsz))
+		  {
+		    if (note1.n_type == NT_GNU_BUILD_ID
+			&& note1.n_namesz == sizeof "GNU"
+			&& !memcmp (name1, "GNU", sizeof "GNU"))
+		      {
+			if (note1.n_descsz != note2.n_descsz)
+			  {
+			    if (! quiet)
+			      error (0, 0, gettext ("\
+%s %s differ: build ID length"),
+				     fname1, fname2);
+			    DIFFERENCE;
+			  }
+			else if (! ignore_build_id)
+			  {
+			    if (! quiet)
+			      error (0, 0, gettext ("\
+%s %s differ: build ID content"),
+				     fname1, fname2);
+			    DIFFERENCE;
+			  }
+		      }
+		    else
+		      {
+			if (! quiet)
+			  error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' note '%s' content"),
+				 fname1, fname2, elf_ndxscn (scn1), sname1,
+				 name1);
+			DIFFERENCE;
+		      }
+		  }
+	      }
+	    if (off2 < data2->d_size)
+	      {
+		if (! quiet)
+		  error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' number of notes"),
+			 fname1, fname2, elf_ndxscn (scn1), sname1);
+		DIFFERENCE;
+	      }
+	  }
+	  break;
+
+	default:
+	  /* Compare the section content byte for byte.  */
+	  assert (shdr1->sh_type == SHT_NOBITS
+		  || (data1->d_buf != NULL || data1->d_size == 0));
+	  assert (shdr2->sh_type == SHT_NOBITS
+		  || (data2->d_buf != NULL || data1->d_size == 0));
+
+	  if (unlikely (data1->d_size != data2->d_size
+			|| (shdr1->sh_type != SHT_NOBITS
+			    && data1->d_size != 0
+			    && memcmp (data1->d_buf, data2->d_buf,
+				       data1->d_size) != 0)))
+	    {
+	      if (hash_inexact
+		  && shdr1->sh_type == SHT_HASH
+		  && data1->d_size == data2->d_size
+		  && hash_content_equivalent (shdr1->sh_entsize, data1, data2))
+		break;
+
+	      if (! quiet)
+		{
+		  if (elf_ndxscn (scn1) == elf_ndxscn (scn2))
+		    error (0, 0, gettext ("\
+%s %s differ: section [%zu] '%s' content"),
+			   fname1, fname2, elf_ndxscn (scn1), sname1);
+		  else
+		    error (0, 0, gettext ("\
+%s %s differ: section [%zu,%zu] '%s' content"),
+			   fname1, fname2, elf_ndxscn (scn1),
+			   elf_ndxscn (scn2), sname1);
+		}
+	      DIFFERENCE;
+	    }
+	  break;
+	}
+    }
+
+  if (unlikely (scn1 != scn2))
+    {
+      if (! quiet)
+	error (0, 0,
+	       gettext ("%s %s differ: unequal amount of important sections"),
+	       fname1, fname2);
+      DIFFERENCE;
+    }
+
+  /* We we look at gaps, create artificial ones for the parts of the
+     program which we are not in sections.  */
+  struct region ehdr_region;
+  struct region phdr_region;
+  if (gaps != gaps_ignore)
+    {
+      ehdr_region.from = 0;
+      ehdr_region.to = ehdr1->e_ehsize;
+      ehdr_region.next = &phdr_region;
+
+      phdr_region.from = ehdr1->e_phoff;
+      phdr_region.to = ehdr1->e_phoff + phnum1 * ehdr1->e_phentsize;
+      phdr_region.next = regions;
+
+      regions = &ehdr_region;
+      nregions += 2;
+    }
+
+  /* If we need to look at the gaps we need access to the file data.  */
+  char *raw1 = NULL;
+  size_t size1 = 0;
+  char *raw2 = NULL;
+  size_t size2 = 0;
+  struct region *regionsarr = alloca (nregions * sizeof (struct region));
+  if (gaps != gaps_ignore)
+    {
+      raw1 = elf_rawfile (elf1, &size1);
+      if (raw1 == NULL )
+	error (2, 0, gettext ("cannot load data of '%s': %s"),
+	       fname1, elf_errmsg (-1));
+
+      raw2 = elf_rawfile (elf2, &size2);
+      if (raw2 == NULL )
+	error (2, 0, gettext ("cannot load data of '%s': %s"),
+	       fname2, elf_errmsg (-1));
+
+      for (size_t cnt = 0; cnt < nregions; ++cnt)
+	{
+	  regionsarr[cnt] = *regions;
+	  regions = regions->next;
+	}
+
+      qsort (regionsarr, nregions, sizeof (regionsarr[0]), regioncompare);
+    }
+
+  /* Compare the program header tables.  */
+  for (unsigned int ndx = 0; ndx < phnum1; ++ndx)
+    {
+      GElf_Phdr phdr1_mem;
+      GElf_Phdr *phdr1 = gelf_getphdr (elf1, ndx, &phdr1_mem);
+      if (phdr1 == NULL)
+	error (2, 0,
+	       gettext ("cannot get program header entry %d of '%s': %s"),
+	       ndx, fname1, elf_errmsg (-1));
+      GElf_Phdr phdr2_mem;
+      GElf_Phdr *phdr2 = gelf_getphdr (elf2, ndx, &phdr2_mem);
+      if (phdr2 == NULL)
+	error (2, 0,
+	       gettext ("cannot get program header entry %d of '%s': %s"),
+	       ndx, fname2, elf_errmsg (-1));
+
+      if (unlikely (memcmp (phdr1, phdr2, sizeof (GElf_Phdr)) != 0))
+	{
+	  if (! quiet)
+	    error (0, 0, gettext ("%s %s differ: program header %d"),
+		   fname1, fname2, ndx);
+	  DIFFERENCE;
+	}
+
+      if (gaps != gaps_ignore && phdr1->p_type == PT_LOAD)
+	{
+	  size_t cnt = 0;
+	  while (cnt < nregions && regionsarr[cnt].to < phdr1->p_offset)
+	    ++cnt;
+
+	  GElf_Off last = phdr1->p_offset;
+	  GElf_Off end = phdr1->p_offset + phdr1->p_filesz;
+	  while (cnt < nregions && regionsarr[cnt].from < end)
+	    {
+	      if (last < regionsarr[cnt].from)
+		{
+		  /* Compare the [LAST,FROM) region.  */
+		  assert (gaps == gaps_match);
+		  if (unlikely (memcmp (raw1 + last, raw2 + last,
+					regionsarr[cnt].from - last) != 0))
+		    {
+		    gapmismatch:
+		      if (!quiet)
+			error (0, 0, gettext ("%s %s differ: gap"),
+			       fname1, fname2);
+		      DIFFERENCE;
+		      break;
+		    }
+
+		}
+	      last = regionsarr[cnt].to;
+	      ++cnt;
+	    }
+
+	  if (cnt == nregions && last < end)
+	    goto gapmismatch;
+	}
+    }
+
+ out:
+  elf_end (elf1);
+  elf_end (elf2);
+  ebl_closebackend (ebl1);
+  ebl_closebackend (ebl2);
+  close (fd1);
+  close (fd2);
+
+  return result;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg,
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case 'q':
+      quiet = true;
+      break;
+
+    case 'l':
+      verbose = true;
+      break;
+
+    case OPT_GAPS:
+      if (strcasecmp (arg, "ignore") == 0)
+	gaps = gaps_ignore;
+      else if (likely (strcasecmp (arg, "match") == 0))
+	gaps = gaps_match;
+      else
+	{
+	  fprintf (stderr,
+		   gettext ("Invalid value '%s' for --gaps parameter."),
+		   arg);
+	  argp_help (&argp, stderr, ARGP_HELP_SEE,
+		     program_invocation_short_name);
+	  exit (1);
+	}
+      break;
+
+    case OPT_HASH_INEXACT:
+      hash_inexact = true;
+      break;
+
+    case OPT_IGNORE_BUILD_ID:
+      ignore_build_id = true;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+static Elf *
+open_file (const char *fname, int *fdp, Ebl **eblp)
+{
+  int fd = open (fname, O_RDONLY);
+  if (unlikely (fd == -1))
+    error (2, errno, gettext ("cannot open '%s'"), fname);
+  Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+  if (elf == NULL)
+    error (2, 0,
+	   gettext ("cannot create ELF descriptor for '%s': %s"),
+	   fname, elf_errmsg (-1));
+  Ebl *ebl = ebl_openbackend (elf);
+  if (ebl == NULL)
+    error (2, 0,
+	   gettext ("cannot create EBL descriptor for '%s'"), fname);
+
+  *fdp = fd;
+  *eblp = ebl;
+  return elf;
+}
+
+
+static bool
+search_for_copy_reloc (Ebl *ebl, size_t scnndx, int symndx)
+{
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	error (2, 0,
+	       gettext ("cannot get section header of section %zu: %s"),
+	       elf_ndxscn (scn), elf_errmsg (-1));
+
+      if ((shdr->sh_type != SHT_REL && shdr->sh_type != SHT_RELA)
+	  || shdr->sh_link != scnndx)
+	continue;
+
+      Elf_Data *data = elf_getdata (scn, NULL);
+      if (data == NULL)
+	error (2, 0,
+	       gettext ("cannot get content of section %zu: %s"),
+	       elf_ndxscn (scn), elf_errmsg (-1));
+
+      if (shdr->sh_type == SHT_REL && shdr->sh_entsize != 0)
+	for (int ndx = 0; ndx < (int) (shdr->sh_size / shdr->sh_entsize);
+	     ++ndx)
+	  {
+	    GElf_Rel rel_mem;
+	    GElf_Rel *rel = gelf_getrel (data, ndx, &rel_mem);
+	    if (rel == NULL)
+	      error (2, 0, gettext ("cannot get relocation: %s"),
+		     elf_errmsg (-1));
+
+	    if ((int) GELF_R_SYM (rel->r_info) == symndx
+		&& ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info)))
+	      return true;
+	  }
+      else if (shdr->sh_entsize != 0)
+	for (int ndx = 0; ndx < (int) (shdr->sh_size / shdr->sh_entsize);
+	     ++ndx)
+	  {
+	    GElf_Rela rela_mem;
+	    GElf_Rela *rela = gelf_getrela (data, ndx, &rela_mem);
+	    if (rela == NULL)
+	      error (2, 0, gettext ("cannot get relocation: %s"),
+		     elf_errmsg (-1));
+
+	    if ((int) GELF_R_SYM (rela->r_info) == symndx
+		&& ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info)))
+	      return true;
+	  }
+    }
+
+  return false;
+}
+
+
+static int
+regioncompare (const void *p1, const void *p2)
+{
+  const struct region *r1 = (const struct region *) p1;
+  const struct region *r2 = (const struct region *) p2;
+
+  if (r1->from < r2->from)
+    return -1;
+  return 1;
+}
+
+
+static int
+compare_Elf32_Word (const void *p1, const void *p2)
+{
+  const Elf32_Word *w1 = p1;
+  const Elf32_Word *w2 = p2;
+  return *w1 < *w2 ? -1 : *w1 > *w2 ? 1 : 0;
+}
+
+static int
+compare_Elf64_Xword (const void *p1, const void *p2)
+{
+  const Elf64_Xword *w1 = p1;
+  const Elf64_Xword *w2 = p2;
+  return *w1 < *w2 ? -1 : *w1 > *w2 ? 1 : 0;
+}
+
+static bool
+hash_content_equivalent (size_t entsize, Elf_Data *data1, Elf_Data *data2)
+{
+#define CHECK_HASH(Hash_Word)						      \
+  {									      \
+    const Hash_Word *const hash1 = data1->d_buf;			      \
+    const Hash_Word *const hash2 = data2->d_buf;			      \
+    const size_t nbucket = hash1[0];					      \
+    const size_t nchain = hash1[1];					      \
+    if (data1->d_size != (2 + nbucket + nchain) * sizeof hash1[0]	      \
+	|| hash2[0] != nbucket || hash2[1] != nchain)			      \
+      return false;							      \
+									      \
+    const Hash_Word *const bucket1 = &hash1[2];				      \
+    const Hash_Word *const chain1 = &bucket1[nbucket];			      \
+    const Hash_Word *const bucket2 = &hash2[2];				      \
+    const Hash_Word *const chain2 = &bucket2[nbucket];			      \
+									      \
+    bool chain_ok[nchain];						      \
+    Hash_Word temp1[nchain - 1];					      \
+    Hash_Word temp2[nchain - 1];					      \
+    memset (chain_ok, 0, sizeof chain_ok);				      \
+    for (size_t i = 0; i < nbucket; ++i)				      \
+      {									      \
+	if (bucket1[i] >= nchain || bucket2[i] >= nchain)		      \
+	  return false;							      \
+									      \
+	size_t b1 = 0;							      \
+	for (size_t p = bucket1[i]; p != STN_UNDEF; p = chain1[p])	      \
+	  if (p >= nchain || b1 >= nchain - 1)				      \
+	    return false;						      \
+	  else								      \
+	    temp1[b1++] = p;						      \
+									      \
+	size_t b2 = 0;							      \
+	for (size_t p = bucket2[i]; p != STN_UNDEF; p = chain2[p])	      \
+	  if (p >= nchain || b2 >= nchain - 1)				      \
+	    return false;						      \
+	  else								      \
+	    temp2[b2++] = p;						      \
+									      \
+	if (b1 != b2)							      \
+	  return false;							      \
+									      \
+	qsort (temp1, b1, sizeof temp1[0], compare_##Hash_Word);	      \
+	qsort (temp2, b2, sizeof temp2[0], compare_##Hash_Word);	      \
+									      \
+	for (b1 = 0; b1 < b2; ++b1)					      \
+	  if (temp1[b1] != temp2[b1])					      \
+	    return false;						      \
+	  else								      \
+	    chain_ok[temp1[b1]] = true;					      \
+      }									      \
+									      \
+    for (size_t i = 0; i < nchain; ++i)					      \
+      if (!chain_ok[i] && chain1[i] != chain2[i])			      \
+	return false;							      \
+									      \
+    return true;							      \
+  }
+
+  switch (entsize)
+    {
+    case 4:
+      CHECK_HASH (Elf32_Word);
+      break;
+    case 8:
+      CHECK_HASH (Elf64_Xword);
+      break;
+    }
+
+  return false;
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/elfcompress.c b/third_party/elfutils/src/elfcompress.c
new file mode 100644
index 0000000..25378a4
--- /dev/null
+++ b/third_party/elfutils/src/elfcompress.c
@@ -0,0 +1,1322 @@
+/* Compress or decompress an ELF file.
+   Copyright (C) 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <argp.h>
+#include <error.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include ELFUTILS_HEADER(elf)
+#include ELFUTILS_HEADER(ebl)
+#include ELFUTILS_HEADER(dwelf)
+#include <gelf.h>
+#include "libeu.h"
+#include "printversion.h"
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+static int verbose = 0; /* < 0, no warnings, > 0 extra verbosity.  */
+static bool force = false;
+static bool permissive = false;
+static const char *foutput = NULL;
+
+#define T_UNSET 0
+#define T_DECOMPRESS 1    /* none */
+#define T_COMPRESS_ZLIB 2 /* zlib */
+#define T_COMPRESS_GNU  3 /* zlib-gnu */
+static int type = T_UNSET;
+
+struct section_pattern
+{
+  char *pattern;
+  struct section_pattern *next;
+};
+
+static struct section_pattern *patterns = NULL;
+
+static void
+add_pattern (const char *pattern)
+{
+  struct section_pattern *p = xmalloc (sizeof *p);
+  p->pattern = xstrdup (pattern);
+  p->next = patterns;
+  patterns = p;
+}
+
+static void
+free_patterns (void)
+{
+  struct section_pattern *pattern = patterns;
+  while (pattern != NULL)
+    {
+      struct section_pattern *p = pattern;
+      pattern = p->next;
+      free (p->pattern);
+      free (p);
+    }
+}
+
+static error_t
+parse_opt (int key, char *arg __attribute__ ((unused)),
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case 'v':
+      verbose++;
+      break;
+
+    case 'q':
+      verbose--;
+      break;
+
+    case 'f':
+      force = true;
+      break;
+
+    case 'p':
+      permissive = true;
+      break;
+
+    case 'n':
+      add_pattern (arg);
+      break;
+
+    case 'o':
+      if (foutput != NULL)
+	argp_error (state, N_("-o option specified twice"));
+      else
+	foutput = arg;
+      break;
+
+    case 't':
+      if (type != T_UNSET)
+	argp_error (state, N_("-t option specified twice"));
+
+      if (strcmp ("none", arg) == 0)
+	type = T_DECOMPRESS;
+      else if (strcmp ("zlib", arg) == 0 || strcmp ("zlib-gabi", arg) == 0)
+	type = T_COMPRESS_ZLIB;
+      else if (strcmp ("zlib-gnu", arg) == 0 || strcmp ("gnu", arg) == 0)
+	type = T_COMPRESS_GNU;
+      else
+	argp_error (state, N_("unknown compression type '%s'"), arg);
+      break;
+
+    case ARGP_KEY_SUCCESS:
+      if (type == T_UNSET)
+	type = T_COMPRESS_ZLIB;
+      if (patterns == NULL)
+	add_pattern (".?(z)debug*");
+      break;
+
+    case ARGP_KEY_NO_ARGS:
+      /* We need at least one input file.  */
+      argp_error (state, N_("No input file given"));
+      break;
+
+    case ARGP_KEY_ARGS:
+      if (foutput != NULL && state->argc - state->next > 1)
+	argp_error (state,
+		    N_("Only one input file allowed together with '-o'"));
+      /* We only use this for checking the number of arguments, we don't
+	 actually want to consume them.  */
+      FALLTHROUGH;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+static bool
+section_name_matches (const char *name)
+{
+  struct section_pattern *pattern = patterns;
+  while (pattern != NULL)
+    {
+      if (fnmatch (pattern->pattern, name, FNM_EXTMATCH) == 0)
+	return true;
+      pattern = pattern->next;
+    }
+  return false;
+}
+
+static int
+setshdrstrndx (Elf *elf, GElf_Ehdr *ehdr, size_t ndx)
+{
+  if (ndx < SHN_LORESERVE)
+    ehdr->e_shstrndx = ndx;
+  else
+    {
+      ehdr->e_shstrndx = SHN_XINDEX;
+      Elf_Scn *zscn = elf_getscn (elf, 0);
+      GElf_Shdr zshdr_mem;
+      GElf_Shdr *zshdr = gelf_getshdr (zscn, &zshdr_mem);
+      if (zshdr == NULL)
+	return -1;
+      zshdr->sh_link = ndx;
+      if (gelf_update_shdr (zscn, zshdr) == 0)
+	return -1;
+    }
+
+  if (gelf_update_ehdr (elf, ehdr) == 0)
+    return -1;
+
+  return 0;
+}
+
+static int
+compress_section (Elf_Scn *scn, size_t orig_size, const char *name,
+		  const char *newname, size_t ndx,
+		  bool gnu, bool compress, bool report_verbose)
+{
+  int res;
+  unsigned int flags = compress && force ? ELF_CHF_FORCE : 0;
+  if (gnu)
+    res = elf_compress_gnu (scn, compress ? 1 : 0, flags);
+  else
+    res = elf_compress (scn, compress ? ELFCOMPRESS_ZLIB : 0, flags);
+
+  if (res < 0)
+    error (0, 0, "Couldn't decompress section [%zd] %s: %s",
+	   ndx, name, elf_errmsg (-1));
+  else
+    {
+      if (compress && res == 0)
+	{
+	  if (verbose >= 0)
+	    printf ("[%zd] %s NOT compressed, wouldn't be smaller\n",
+		    ndx, name);
+	}
+
+      if (report_verbose && res > 0)
+	{
+	  printf ("[%zd] %s %s", ndx, name,
+		  compress ? "compressed" : "decompressed");
+	  if (newname != NULL)
+	    printf (" -> %s", newname);
+
+	  /* Reload shdr, it has changed.  */
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (shdr == NULL)
+	    {
+	      error (0, 0, "Couldn't get shdr for section [%zd]", ndx);
+	      return -1;
+	    }
+	  float new = shdr->sh_size;
+	  float orig = orig_size ?: 1;
+	  printf (" (%zu => %" PRIu64 " %.2f%%)\n",
+		  orig_size, shdr->sh_size, (new / orig) * 100);
+	}
+    }
+
+  return res;
+}
+
+static int
+process_file (const char *fname)
+{
+  if (verbose > 0)
+    printf ("processing: %s\n", fname);
+
+  /* The input ELF.  */
+  int fd = -1;
+  Elf *elf = NULL;
+
+  /* The output ELF.  */
+  char *fnew = NULL;
+  int fdnew = -1;
+  Elf *elfnew = NULL;
+
+  /* Buffer for (one) new section name if necessary.  */
+  char *snamebuf = NULL;
+
+  /* String table (and symbol table), if section names need adjusting.  */
+  Dwelf_Strtab *names = NULL;
+  Dwelf_Strent **scnstrents = NULL;
+  Dwelf_Strent **symstrents = NULL;
+  char **scnnames = NULL;
+
+  /* Section data from names.  */
+  void *namesbuf = NULL;
+
+  /* Which sections match and need to be (un)compressed.  */
+  unsigned int *sections = NULL;
+
+  /* How many sections are we talking about?  */
+  size_t shnum = 0;
+
+#define WORD_BITS (8U * sizeof (unsigned int))
+  void set_section (size_t ndx)
+  {
+    sections[ndx / WORD_BITS] |= (1U << (ndx % WORD_BITS));
+  }
+
+  bool get_section (size_t ndx)
+  {
+    return (sections[ndx / WORD_BITS] & (1U << (ndx % WORD_BITS))) != 0;
+  }
+
+  int cleanup (int res)
+  {
+    elf_end (elf);
+    close (fd);
+
+    elf_end (elfnew);
+    close (fdnew);
+
+    if (fnew != NULL)
+      {
+	unlink (fnew);
+	free (fnew);
+	fnew = NULL;
+      }
+
+    free (snamebuf);
+    if (names != NULL)
+      {
+	dwelf_strtab_free (names);
+	free (scnstrents);
+	free (symstrents);
+	free (namesbuf);
+	if (scnnames != NULL)
+	  {
+	    for (size_t n = 0; n < shnum; n++)
+	      free (scnnames[n]);
+	    free (scnnames);
+	  }
+      }
+
+    free (sections);
+
+    return res;
+  }
+
+  fd = open (fname, O_RDONLY);
+  if (fd < 0)
+    {
+      error (0, errno, "Couldn't open %s\n", fname);
+      return cleanup (-1);
+    }
+
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      error (0, 0, "Couldn't open ELF file %s for reading: %s",
+	     fname, elf_errmsg (-1));
+      return cleanup (-1);
+    }
+
+  /* We dont' handle ar files (or anything else), we probably should.  */
+  Elf_Kind kind = elf_kind (elf);
+  if (kind != ELF_K_ELF)
+    {
+      if (kind == ELF_K_AR)
+	error (0, 0, "Cannot handle ar files: %s", fname);
+      else
+	error (0, 0, "Unknown file type: %s", fname);
+      return cleanup (-1);
+    }
+
+  struct stat st;
+  if (fstat (fd, &st) != 0)
+    {
+      error (0, errno, "Couldn't fstat %s", fname);
+      return cleanup (-1);
+    }
+
+  GElf_Ehdr ehdr;
+  if (gelf_getehdr (elf, &ehdr) == NULL)
+    {
+      error (0, 0, "Couldn't get ehdr for %s: %s", fname, elf_errmsg (-1));
+      return cleanup (-1);
+    }
+
+  /* Get the section header string table.  */
+  size_t shdrstrndx;
+  if (elf_getshdrstrndx (elf, &shdrstrndx) != 0)
+    {
+      error (0, 0, "Couldn't get section header string table index in %s: %s",
+	     fname, elf_errmsg (-1));
+      return cleanup (-1);
+    }
+
+  /* How many sections are we talking about?  */
+  if (elf_getshdrnum (elf, &shnum) != 0)
+    {
+      error (0, 0, "Couldn't get number of sections in %s: %s",
+	     fname, elf_errmsg (1));
+      return cleanup (-1);
+    }
+
+  if (shnum == 0)
+    {
+      error (0, 0, "ELF file %s has no sections", fname);
+      return cleanup (-1);
+    }
+
+  sections = xcalloc (shnum / 8 + 1, sizeof (unsigned int));
+
+  size_t phnum;
+  if (elf_getphdrnum (elf, &phnum) != 0)
+    {
+      error (0, 0, "Couldn't get phdrnum: %s", elf_errmsg (-1));
+      return cleanup (-1);
+    }
+
+  /* Whether we need to adjust any section names (going to/from GNU
+     naming).  If so we'll need to build a new section header string
+     table.  */
+  bool adjust_names = false;
+
+  /* If there are phdrs we want to maintain the layout of the
+     allocated sections in the file.  */
+  bool layout = phnum != 0;
+
+  /* While going through all sections keep track of last section data
+     offset if needed to keep the layout.  We are responsible for
+     adding the section offsets and headers (e_shoff) in that case
+     (which we will place after the last section).  */
+  GElf_Off last_offset = 0;
+  if (layout)
+    last_offset = (ehdr.e_phoff
+		   + gelf_fsize (elf, ELF_T_PHDR, phnum, EV_CURRENT));
+
+  /* Which section, if any, is a symbol table that shares a string
+     table with the section header string table?  */
+  size_t symtabndx = 0;
+
+  /* We do three passes over all sections.
+
+     First an inspection pass over the old Elf to see which section
+     data needs to be copied and/or transformed, which sections need a
+     names change and whether there is a symbol table that might need
+     to be adjusted be if the section header name table is changed.
+
+     Second a collection pass that creates the Elf sections and copies
+     the data.  This pass will compress/decompress section data when
+     needed.  And it will collect all data needed if we'll need to
+     construct a new string table. Afterwards the new string table is
+     constructed.
+
+     Third a fixup/adjustment pass over the new Elf that will adjust
+     any section references (names) and adjust the layout based on the
+     new sizes of the sections if necessary.  This pass is optional if
+     we aren't responsible for the layout and the section header
+     string table hasn't been changed.  */
+
+  /* Inspection pass.  */
+  size_t maxnamelen = 0;
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      size_t ndx = elf_ndxscn (scn);
+      if (ndx > shnum)
+	{
+	  error (0, 0, "Unexpected section number %zd, expected only %zd",
+		 ndx, shnum);
+	  cleanup (-1);
+	}
+
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  error (0, 0, "Couldn't get shdr for section %zd", ndx);
+	  return cleanup (-1);
+	}
+
+      const char *sname = elf_strptr (elf, shdrstrndx, shdr->sh_name);
+      if (sname == NULL)
+	{
+	  error (0, 0, "Couldn't get name for section %zd", ndx);
+	  return cleanup (-1);
+	}
+
+      if (section_name_matches (sname))
+	{
+	  if (shdr->sh_type != SHT_NOBITS
+	      && (shdr->sh_flags & SHF_ALLOC) == 0)
+	    {
+	      set_section (ndx);
+	      /* Check if we might want to change this section name.  */
+	      if (! adjust_names
+		  && ((type != T_COMPRESS_GNU
+		       && strncmp (sname, ".zdebug",
+				   strlen (".zdebug")) == 0)
+		      || (type == T_COMPRESS_GNU
+			  && strncmp (sname, ".debug",
+				      strlen (".debug")) == 0)))
+		adjust_names = true;
+
+	      /* We need a buffer this large if we change the names.  */
+	      if (adjust_names)
+		{
+		  size_t slen = strlen (sname);
+		  if (slen > maxnamelen)
+		    maxnamelen = slen;
+		}
+	    }
+	  else
+	    if (verbose >= 0)
+	      printf ("[%zd] %s ignoring %s section\n", ndx, sname,
+		      (shdr->sh_type == SHT_NOBITS ? "no bits" : "allocated"));
+	}
+
+      if (shdr->sh_type == SHT_SYMTAB)
+	{
+	  /* Check if we might have to adjust the symbol name indexes.  */
+	  if (shdr->sh_link == shdrstrndx)
+	    {
+	      if (symtabndx != 0)
+		{
+		  error (0, 0,
+			 "Multiple symbol tables (%zd, %zd) using the same string table unsupported", symtabndx, ndx);
+		  return cleanup (-1);
+		}
+	      symtabndx = ndx;
+	    }
+	}
+
+      /* Keep track of last allocated data offset.  */
+      if (layout)
+	if ((shdr->sh_flags & SHF_ALLOC) != 0)
+	  {
+	    GElf_Off off = shdr->sh_offset + (shdr->sh_type != SHT_NOBITS
+					      ? shdr->sh_size : 0);
+	    if (last_offset < off)
+	      last_offset = off;
+	  }
+    }
+
+  if (adjust_names)
+    {
+      names = dwelf_strtab_init (true);
+      if (names == NULL)
+	{
+	  error (0, 0, "Not enough memory for new strtab");
+	  return cleanup (-1);
+	}
+      scnstrents = xmalloc (shnum
+			    * sizeof (Dwelf_Strent *));
+      scnnames = xcalloc (shnum, sizeof (char *));
+    }
+
+  /* Create a new (temporary) ELF file for the result.  */
+  if (foutput == NULL)
+    {
+      size_t fname_len = strlen (fname);
+      fnew = xmalloc (fname_len + sizeof (".XXXXXX"));
+      strcpy (mempcpy (fnew, fname, fname_len), ".XXXXXX");
+      fdnew = mkstemp (fnew);
+    }
+  else
+    {
+      fnew = xstrdup (foutput);
+      fdnew = open (fnew, O_WRONLY | O_CREAT, st.st_mode & ALLPERMS);
+    }
+
+  if (fdnew < 0)
+    {
+      error (0, errno, "Couldn't create output file %s", fnew);
+      /* Since we didn't create it we don't want to try to unlink it.  */
+      free (fnew);
+      fnew = NULL;
+      return cleanup (-1);
+    }
+
+  elfnew = elf_begin (fdnew, ELF_C_WRITE, NULL);
+  if (elfnew == NULL)
+    {
+      error (0, 0, "Couldn't open new ELF %s for writing: %s",
+	     fnew, elf_errmsg (-1));
+      return cleanup (-1);
+    }
+
+  /* Create the new ELF header and copy over all the data.  */
+  if (gelf_newehdr (elfnew, gelf_getclass (elf)) == 0)
+    {
+      error (0, 0, "Couldn't create new ehdr: %s", elf_errmsg (-1));
+      return cleanup (-1);
+    }
+
+  GElf_Ehdr newehdr;
+  if (gelf_getehdr (elfnew, &newehdr) == NULL)
+    {
+      error (0, 0, "Couldn't get new ehdr: %s", elf_errmsg (-1));
+      return cleanup (-1);
+    }
+
+  newehdr.e_ident[EI_DATA] = ehdr.e_ident[EI_DATA];
+  newehdr.e_type = ehdr.e_type;
+  newehdr.e_machine = ehdr.e_machine;
+  newehdr.e_version = ehdr.e_version;
+  newehdr.e_entry = ehdr.e_entry;
+  newehdr.e_flags = ehdr.e_flags;
+
+  if (gelf_update_ehdr (elfnew, &newehdr) == 0)
+    {
+      error (0, 0, "Couldn't update ehdr: %s", elf_errmsg (-1));
+      return cleanup (-1);
+    }
+
+  /* Copy over the phdrs as is.  */
+  if (phnum != 0)
+    {
+      if (gelf_newphdr (elfnew, phnum) == 0)
+	{
+	  error (0, 0, "Couldn't create phdrs: %s", elf_errmsg (-1));
+	  return cleanup (-1);
+	}
+
+      for (size_t cnt = 0; cnt < phnum; ++cnt)
+	{
+	  GElf_Phdr phdr_mem;
+	  GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
+	  if (phdr == NULL)
+	    {
+	      error (0, 0, "Couldn't get phdr %zd: %s", cnt, elf_errmsg (-1));
+	      return cleanup (-1);
+	    }
+	  if (gelf_update_phdr (elfnew, cnt, phdr) == 0)
+	    {
+	      error (0, 0, "Couldn't create phdr %zd: %s", cnt,
+		     elf_errmsg (-1));
+	      return cleanup (-1);
+	    }
+	}
+    }
+
+  /* Possibly add a 'z' and zero terminator.  */
+  if (maxnamelen > 0)
+    snamebuf = xmalloc (maxnamelen + 2);
+
+  /* We might want to read/adjust the section header strings and
+     symbol tables.  If so, and those sections are to be compressed
+     then we will have to decompress it during the collection pass and
+     compress it again in the fixup pass.  Don't compress unnecessary
+     and keep track of whether or not to compress them (later in the
+     fixup pass).  Also record the original size, so we can report the
+     difference later when we do compress.  */
+  int shstrtab_compressed = T_UNSET;
+  size_t shstrtab_size = 0;
+  char *shstrtab_name = NULL;
+  char *shstrtab_newname = NULL;
+  int symtab_compressed = T_UNSET;
+  size_t symtab_size = 0;
+  char *symtab_name = NULL;
+  char *symtab_newname = NULL;
+
+  /* Collection pass.  Copy over the sections, (de)compresses matching
+     sections, collect names of sections and symbol table if
+     necessary.  */
+  scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      size_t ndx = elf_ndxscn (scn);
+      assert (ndx < shnum);
+
+      /* (de)compress if section matched.  */
+      char *sname = NULL;
+      char *newname = NULL;
+      if (get_section (ndx))
+	{
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (shdr == NULL)
+	    {
+	      error (0, 0, "Couldn't get shdr for section %zd", ndx);
+	      return cleanup (-1);
+	    }
+
+	  uint64_t size = shdr->sh_size;
+	  sname = elf_strptr (elf, shdrstrndx, shdr->sh_name);
+	  if (sname == NULL)
+	    {
+	      error (0, 0, "Couldn't get name for section %zd", ndx);
+	      return cleanup (-1);
+	    }
+
+	  /* strdup sname, the shdrstrndx section itself might be
+	     (de)compressed, invalidating the string pointers.  */
+	  sname = xstrdup (sname);
+
+	  /* We might want to decompress (and rename), but not
+	     compress during this pass since we might need the section
+	     data in later passes.  Skip those sections for now and
+	     compress them in the fixup pass.  */
+	  bool skip_compress_section = (adjust_names
+					&& (ndx == shdrstrndx
+					    || ndx == symtabndx));
+
+	  switch (type)
+	    {
+	    case T_DECOMPRESS:
+	      if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+		{
+		  if (compress_section (scn, size, sname, NULL, ndx,
+					false, false, verbose > 0) < 0)
+		    return cleanup (-1);
+		}
+	      else if (strncmp (sname, ".zdebug", strlen (".zdebug")) == 0)
+		{
+		  snamebuf[0] = '.';
+		  strcpy (&snamebuf[1], &sname[2]);
+		  newname = snamebuf;
+		  if (compress_section (scn, size, sname, newname, ndx,
+					true, false, verbose > 0) < 0)
+		    return cleanup (-1);
+		}
+	      else if (verbose > 0)
+		printf ("[%zd] %s already decompressed\n", ndx, sname);
+	      break;
+
+	    case T_COMPRESS_GNU:
+	      if (strncmp (sname, ".debug", strlen (".debug")) == 0)
+		{
+		  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+		    {
+		      /* First decompress to recompress GNU style.
+			 Don't report even when verbose.  */
+		      if (compress_section (scn, size, sname, NULL, ndx,
+					    false, false, false) < 0)
+			return cleanup (-1);
+		    }
+
+		  snamebuf[0] = '.';
+		  snamebuf[1] = 'z';
+		  strcpy (&snamebuf[2], &sname[1]);
+		  newname = snamebuf;
+
+		  if (skip_compress_section)
+		    {
+		      if (ndx == shdrstrndx)
+			{
+			  shstrtab_size = size;
+			  shstrtab_compressed = T_COMPRESS_GNU;
+			  shstrtab_name = xstrdup (sname);
+			  shstrtab_newname = xstrdup (newname);
+			}
+		      else
+			{
+			  symtab_size = size;
+			  symtab_compressed = T_COMPRESS_GNU;
+			  symtab_name = xstrdup (sname);
+			  symtab_newname = xstrdup (newname);
+			}
+		    }
+		  else
+		    {
+		      int res = compress_section (scn, size, sname, newname,
+						  ndx, true, true,
+						  verbose > 0);
+		      if (res < 0)
+			return cleanup (-1);
+
+		      if (res == 0)
+			newname = NULL;
+		    }
+		}
+	      else if (verbose >= 0)
+		{
+		  if (strncmp (sname, ".zdebug", strlen (".zdebug")) == 0)
+		    printf ("[%zd] %s unchanged, already GNU compressed",
+			    ndx, sname);
+		  else
+		    printf ("[%zd] %s cannot GNU compress section not starting with .debug\n",
+			    ndx, sname);
+		}
+	      break;
+
+	    case T_COMPRESS_ZLIB:
+	      if ((shdr->sh_flags & SHF_COMPRESSED) == 0)
+		{
+		  if (strncmp (sname, ".zdebug", strlen (".zdebug")) == 0)
+		    {
+		      /* First decompress to recompress zlib style.
+			 Don't report even when verbose.  */
+		      if (compress_section (scn, size, sname, NULL, ndx,
+					    true, false, false) < 0)
+			return cleanup (-1);
+
+		      snamebuf[0] = '.';
+		      strcpy (&snamebuf[1], &sname[2]);
+		      newname = snamebuf;
+		    }
+
+		  if (skip_compress_section)
+		    {
+		      if (ndx == shdrstrndx)
+			{
+			  shstrtab_size = size;
+			  shstrtab_compressed = T_COMPRESS_ZLIB;
+			  shstrtab_name = xstrdup (sname);
+			  shstrtab_newname = (newname == NULL
+					      ? NULL : xstrdup (newname));
+			}
+		      else
+			{
+			  symtab_size = size;
+			  symtab_compressed = T_COMPRESS_ZLIB;
+			  symtab_name = xstrdup (sname);
+			  symtab_newname = (newname == NULL
+					    ? NULL : xstrdup (newname));
+			}
+		    }
+		  else if (compress_section (scn, size, sname, newname, ndx,
+					     false, true, verbose > 0) < 0)
+		    return cleanup (-1);
+		}
+	      else if (verbose > 0)
+		printf ("[%zd] %s already compressed\n", ndx, sname);
+	      break;
+	    }
+
+	  free (sname);
+	}
+
+      Elf_Scn *newscn = elf_newscn (elfnew);
+      if (newscn == NULL)
+	{
+	  error (0, 0, "Couldn't create new section %zd", ndx);
+	  return cleanup (-1);
+	}
+
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  error (0, 0, "Couldn't get shdr for section %zd", ndx);
+	  return cleanup (-1);
+	}
+
+      if (gelf_update_shdr (newscn, shdr) == 0)
+        {
+	  error (0, 0, "Couldn't update section header %zd", ndx);
+	  return cleanup (-1);
+	}
+
+      /* Except for the section header string table all data can be
+	 copied as is.  The section header string table will be
+	 created later and the symbol table might be fixed up if
+	 necessary.  */
+      if (! adjust_names || ndx != shdrstrndx)
+	{
+	  Elf_Data *data = elf_getdata (scn, NULL);
+	  if (data == NULL)
+	    {
+	      error (0, 0, "Couldn't get data from section %zd", ndx);
+	      return cleanup (-1);
+	    }
+
+	  Elf_Data *newdata = elf_newdata (newscn);
+	  if (newdata == NULL)
+	    {
+	      error (0, 0, "Couldn't create new data for section %zd", ndx);
+	      return cleanup (-1);
+	    }
+
+	  *newdata = *data;
+	}
+
+      /* Keep track of the (new) section names.  */
+      if (adjust_names)
+	{
+	  char *name;
+	  if (newname != NULL)
+	    name = newname;
+	  else
+	    {
+	      name = elf_strptr (elf, shdrstrndx, shdr->sh_name);
+	      if (name == NULL)
+		{
+		  error (0, 0, "Couldn't get name for section [%zd]", ndx);
+		  return cleanup (-1);
+		}
+	    }
+
+	  /* We need to keep a copy of the name till the strtab is done.  */
+	  name = scnnames[ndx] = xstrdup (name);
+	  if ((scnstrents[ndx] = dwelf_strtab_add (names, name)) == NULL)
+	    {
+	      error (0, 0, "No memory to add section name string table");
+	      return cleanup (-1);
+	    }
+
+	  /* If the symtab shares strings then add those too.  */
+	  if (ndx == symtabndx)
+	    {
+	      /* If the section is (still) compressed we'll need to
+		 uncompress it first to adjust the data, then
+		 recompress it in the fixup pass.  */
+	      if (symtab_compressed == T_UNSET)
+		{
+		  size_t size = shdr->sh_size;
+		  if ((shdr->sh_flags == SHF_COMPRESSED) != 0)
+		    {
+		      /* Don't report the (internal) uncompression.  */
+		      if (compress_section (newscn, size, sname, NULL, ndx,
+					    false, false, false) < 0)
+			return cleanup (-1);
+
+		      symtab_size = size;
+		      symtab_compressed = T_COMPRESS_ZLIB;
+		    }
+		  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
+		    {
+		      /* Don't report the (internal) uncompression.  */
+		      if (compress_section (newscn, size, sname, NULL, ndx,
+					    true, false, false) < 0)
+			return cleanup (-1);
+
+		      symtab_size = size;
+		      symtab_compressed = T_COMPRESS_GNU;
+		    }
+		}
+
+	      Elf_Data *symd = elf_getdata (newscn, NULL);
+	      if (symd == NULL)
+		{
+		  error (0, 0, "Couldn't get symtab data for section [%zd] %s",
+			 ndx, name);
+		  return cleanup (-1);
+		}
+	      size_t elsize = gelf_fsize (elfnew, ELF_T_SYM, 1, EV_CURRENT);
+	      size_t syms = symd->d_size / elsize;
+	      symstrents = xmalloc (syms * sizeof (Dwelf_Strent *));
+	      for (size_t i = 0; i < syms; i++)
+		{
+		  GElf_Sym sym_mem;
+		  GElf_Sym *sym = gelf_getsym (symd, i, &sym_mem);
+		  if (sym == NULL)
+		    {
+		      error (0, 0, "Couldn't get symbol %zd", i);
+		      return cleanup (-1);
+		    }
+		  if (sym->st_name != 0)
+		    {
+		      /* Note we take the name from the original ELF,
+			 since the new one will not have setup the
+			 strtab yet.  */
+		      const char *symname = elf_strptr (elf, shdrstrndx,
+							sym->st_name);
+		      if (symname == NULL)
+			{
+			  error (0, 0, "Couldn't get symbol %zd name", i);
+			  return cleanup (-1);
+			}
+		      symstrents[i] = dwelf_strtab_add (names, symname);
+		      if (symstrents[i] == NULL)
+			{
+			  error (0, 0, "No memory to add to symbol name");
+			  return cleanup (-1);
+			}
+		    }
+		}
+	    }
+	}
+    }
+
+  if (adjust_names)
+    {
+      /* We got all needed strings, put the new data in the shstrtab.  */
+      if (verbose > 0)
+	printf ("[%zd] Updating section string table\n", shdrstrndx);
+
+      scn = elf_getscn (elfnew, shdrstrndx);
+      if (scn == NULL)
+	{
+	  error (0, 0, "Couldn't get new section header string table [%zd]",
+		 shdrstrndx);
+	  return cleanup (-1);
+	}
+
+      Elf_Data *data = elf_newdata (scn);
+      if (data == NULL)
+	{
+	  error (0, 0, "Couldn't create new section header string table data");
+	  return cleanup (-1);
+	}
+      if (dwelf_strtab_finalize (names, data) == NULL)
+	{
+	  error (0, 0, "Not enough memory to create string table");
+	  return cleanup (-1);
+	}
+      namesbuf = data->d_buf;
+
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  error (0, 0, "Couldn't get shdr for new section strings %zd",
+		 shdrstrndx);
+	  return cleanup (-1);
+	}
+
+      /* Note that we also might have to compress and possibly set
+	 sh_off below */
+      shdr->sh_name = dwelf_strent_off (scnstrents[shdrstrndx]);
+      shdr->sh_type = SHT_STRTAB;
+      shdr->sh_flags = 0;
+      shdr->sh_addr = 0;
+      shdr->sh_offset = 0;
+      shdr->sh_size = data->d_size;
+      shdr->sh_link = SHN_UNDEF;
+      shdr->sh_info = SHN_UNDEF;
+      shdr->sh_addralign = 1;
+      shdr->sh_entsize = 0;
+
+      if (gelf_update_shdr (scn, shdr) == 0)
+	{
+	  error (0, 0, "Couldn't update new section strings [%zd]",
+		 shdrstrndx);
+	  return cleanup (-1);
+	}
+
+      /* We might have to compress the data if the user asked us to,
+	 or if the section was already compressed (and the user didn't
+	 ask for decompression).  Note somewhat identical code for
+	 symtab below.  */
+      if (shstrtab_compressed == T_UNSET)
+	{
+	  /* The user didn't ask for compression, but maybe it was
+	     compressed in the original ELF file.  */
+	  Elf_Scn *oldscn = elf_getscn (elf, shdrstrndx);
+	  if (oldscn == NULL)
+	    {
+	      error (0, 0, "Couldn't get section header string table [%zd]",
+		     shdrstrndx);
+	      return cleanup (-1);
+	    }
+
+	  shdr = gelf_getshdr (oldscn, &shdr_mem);
+	  if (shdr == NULL)
+	    {
+	      error (0, 0, "Couldn't get shdr for old section strings [%zd]",
+		     shdrstrndx);
+	      return cleanup (-1);
+	    }
+
+	  shstrtab_name = elf_strptr (elf, shdrstrndx, shdr->sh_name);
+	  if (shstrtab_name == NULL)
+	    {
+	      error (0, 0, "Couldn't get name for old section strings [%zd]",
+		     shdrstrndx);
+	      return cleanup (-1);
+	    }
+
+	  shstrtab_size = shdr->sh_size;
+	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	    shstrtab_compressed = T_COMPRESS_ZLIB;
+	  else if (strncmp (shstrtab_name, ".zdebug", strlen (".zdebug")) == 0)
+	    shstrtab_compressed = T_COMPRESS_GNU;
+	}
+
+      /* Should we (re)compress?  */
+      if (shstrtab_compressed != T_UNSET)
+	{
+	  if (compress_section (scn, shstrtab_size, shstrtab_name,
+				shstrtab_newname, shdrstrndx,
+				shstrtab_compressed == T_COMPRESS_GNU,
+				true, verbose > 0) < 0)
+	    return cleanup (-1);
+	}
+    }
+
+  /* Make sure to re-get the new ehdr.  Adding phdrs and shdrs will
+     have changed it.  */
+  if (gelf_getehdr (elfnew, &newehdr) == NULL)
+    {
+      error (0, 0, "Couldn't re-get new ehdr: %s", elf_errmsg (-1));
+      return cleanup (-1);
+    }
+
+  /* Set this after the sections have been created, otherwise section
+     zero might not exist yet.  */
+  if (setshdrstrndx (elfnew, &newehdr, shdrstrndx) != 0)
+    {
+      error (0, 0, "Couldn't set new shdrstrndx: %s", elf_errmsg (-1));
+      return cleanup (-1);
+    }
+
+  /* Fixup pass.  Adjust string table references, symbol table and
+     layout if necessary.  */
+  if (layout || adjust_names)
+    {
+      scn = NULL;
+      while ((scn = elf_nextscn (elfnew, scn)) != NULL)
+	{
+	  size_t ndx = elf_ndxscn (scn);
+
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (shdr == NULL)
+	    {
+	      error (0, 0, "Couldn't get shdr for section %zd", ndx);
+	      return cleanup (-1);
+	    }
+
+	  /* Keep the offset of allocated sections so they are at the
+	     same place in the file. Add (possibly changed)
+	     unallocated ones after the allocated ones.  */
+	  if ((shdr->sh_flags & SHF_ALLOC) == 0)
+	    {
+	      /* Zero means one.  No alignment constraints.  */
+	      size_t addralign = shdr->sh_addralign ?: 1;
+	      last_offset = (last_offset + addralign - 1) & ~(addralign - 1);
+	      shdr->sh_offset = last_offset;
+	      if (shdr->sh_type != SHT_NOBITS)
+		last_offset += shdr->sh_size;
+	    }
+
+	  if (adjust_names)
+	    shdr->sh_name = dwelf_strent_off (scnstrents[ndx]);
+
+	  if (gelf_update_shdr (scn, shdr) == 0)
+	    {
+	      error (0, 0, "Couldn't update section header %zd", ndx);
+	      return cleanup (-1);
+	    }
+
+	  if (adjust_names && ndx == symtabndx)
+	    {
+	      if (verbose > 0)
+		printf ("[%zd] Updating symbol table\n", symtabndx);
+
+	      Elf_Data *symd = elf_getdata (scn, NULL);
+	      if (symd == NULL)
+		{
+		  error (0, 0, "Couldn't get new symtab data section [%zd]",
+			 ndx);
+		  return cleanup (-1);
+		}
+	      size_t elsize = gelf_fsize (elfnew, ELF_T_SYM, 1, EV_CURRENT);
+	      size_t syms = symd->d_size / elsize;
+	      for (size_t i = 0; i < syms; i++)
+		{
+		  GElf_Sym sym_mem;
+		  GElf_Sym *sym = gelf_getsym (symd, i, &sym_mem);
+		  if (sym == NULL)
+		    {
+		      error (0, 0, "2 Couldn't get symbol %zd", i);
+		      return cleanup (-1);
+		    }
+
+		  if (sym->st_name != 0)
+		    {
+		      sym->st_name = dwelf_strent_off (symstrents[i]);
+
+		      if (gelf_update_sym (symd, i, sym) == 0)
+			{
+			  error (0, 0, "Couldn't update symbol %zd", i);
+			  return cleanup (-1);
+			}
+		    }
+		}
+
+	      /* We might have to compress the data if the user asked
+		 us to, or if the section was already compressed (and
+		 the user didn't ask for decompression).  Note
+		 somewhat identical code for shstrtab above.  */
+	      if (symtab_compressed == T_UNSET)
+		{
+		  /* The user didn't ask for compression, but maybe it was
+		     compressed in the original ELF file.  */
+		  Elf_Scn *oldscn = elf_getscn (elf, symtabndx);
+		  if (oldscn == NULL)
+		    {
+		      error (0, 0, "Couldn't get symbol table [%zd]",
+			     symtabndx);
+		      return cleanup (-1);
+		    }
+
+		  shdr = gelf_getshdr (oldscn, &shdr_mem);
+		  if (shdr == NULL)
+		    {
+		      error (0, 0, "Couldn't get old symbol table shdr [%zd]",
+			     symtabndx);
+		      return cleanup (-1);
+		    }
+
+		  symtab_name = elf_strptr (elf, shdrstrndx, shdr->sh_name);
+		  if (symtab_name == NULL)
+		    {
+		      error (0, 0, "Couldn't get old symbol table name [%zd]",
+			     symtabndx);
+		      return cleanup (-1);
+		    }
+
+		  symtab_size = shdr->sh_size;
+		  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+		    symtab_compressed = T_COMPRESS_ZLIB;
+		  else if (strncmp (symtab_name, ".zdebug",
+				    strlen (".zdebug")) == 0)
+		    symtab_compressed = T_COMPRESS_GNU;
+		}
+
+	      /* Should we (re)compress?  */
+	      if (symtab_compressed != T_UNSET)
+		{
+		  if (compress_section (scn, symtab_size, symtab_name,
+					symtab_newname, symtabndx,
+					symtab_compressed == T_COMPRESS_GNU,
+					true, verbose > 0) < 0)
+		    return cleanup (-1);
+		}
+	    }
+	}
+    }
+
+  /* If we have phdrs we want elf_update to layout the SHF_ALLOC
+     sections precisely as in the original file.  In that case we are
+     also responsible for setting phoff and shoff */
+  if (layout)
+    {
+      if (gelf_getehdr (elfnew, &newehdr) == NULL)
+	{
+	  error (0, 0, "Couldn't get ehdr: %s", elf_errmsg (-1));
+	  return cleanup (-1);
+	}
+
+      /* Position the shdrs after the last (unallocated) section.  */
+      const size_t offsize = gelf_fsize (elfnew, ELF_T_OFF, 1, EV_CURRENT);
+      newehdr.e_shoff = ((last_offset + offsize - 1)
+			 & ~((GElf_Off) (offsize - 1)));
+
+      /* The phdrs go in the same place as in the original file.
+	 Normally right after the ELF header.  */
+      newehdr.e_phoff = ehdr.e_phoff;
+
+      if (gelf_update_ehdr (elfnew, &newehdr) == 0)
+	{
+	  error (0, 0, "Couldn't update ehdr: %s", elf_errmsg (-1));
+	  return cleanup (-1);
+	}
+    }
+
+  elf_flagelf (elfnew, ELF_C_SET, ((layout ? ELF_F_LAYOUT : 0)
+				   | (permissive ? ELF_F_PERMISSIVE : 0)));
+
+  if (elf_update (elfnew, ELF_C_WRITE) < 0)
+    {
+      error (0, 0, "Couldn't write %s: %s", fnew, elf_errmsg (-1));
+      return cleanup (-1);
+    }
+
+  elf_end (elfnew);
+  elfnew = NULL;
+
+  /* Try to match mode and owner.group of the original file.  */
+  if (fchmod (fdnew, st.st_mode & ALLPERMS) != 0)
+    if (verbose >= 0)
+      error (0, errno, "Couldn't fchmod %s", fnew);
+  if (fchown (fdnew, st.st_uid, st.st_gid) != 0)
+    if (verbose >= 0)
+      error (0, errno, "Couldn't fchown %s", fnew);
+
+  /* Finally replace the old file with the new file.  */
+  if (foutput == NULL)
+    if (rename (fnew, fname) != 0)
+      {
+	error (0, errno, "Couldn't rename %s to %s", fnew, fname);
+	return cleanup (-1);
+      }
+
+  /* We are finally done with the new file, don't unlink it now.  */
+  free (fnew);
+  fnew = NULL;
+
+  return cleanup (0);
+}
+
+int
+main (int argc, char **argv)
+{
+  const struct argp_option options[] =
+    {
+      { "output", 'o', "FILE", 0,
+	N_("Place (de)compressed output into FILE"),
+	0 },
+      { "type", 't', "TYPE", 0,
+	N_("What type of compression to apply. TYPE can be 'none' (decompress), 'zlib' (ELF ZLIB compression, the default, 'zlib-gabi' is an alias) or 'zlib-gnu' (.zdebug GNU style compression, 'gnu' is an alias)"),
+	0 },
+      { "name", 'n', "SECTION", 0,
+	N_("SECTION name to (de)compress, SECTION is an extended wildcard pattern (defaults to '.?(z)debug*')"),
+	0 },
+      { "verbose", 'v', NULL, 0,
+	N_("Print a message for each section being (de)compressed"),
+	0 },
+      { "force", 'f', NULL, 0,
+	N_("Force compression of section even if it would become larger"),
+	0 },
+      { "permissive", 'p', NULL, 0,
+	N_("Relax a few rules to handle slightly broken ELF files"),
+	0 },
+      { "quiet", 'q', NULL, 0,
+	N_("Be silent when a section cannot be compressed"),
+	0 },
+      { NULL, 0, NULL, 0, NULL, 0 }
+    };
+
+  const struct argp argp =
+    {
+      .options = options,
+      .parser = parse_opt,
+      .args_doc = N_("FILE..."),
+      .doc = N_("Compress or decompress sections in an ELF file.")
+    };
+
+  int remaining;
+  if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0)
+    return EXIT_FAILURE;
+
+  /* Should already be handled by ARGP_KEY_NO_ARGS case above,
+     just sanity check.  */
+  if (remaining >= argc)
+    error (EXIT_FAILURE, 0, N_("No input file given"));
+
+  /* Likewise for the ARGP_KEY_ARGS case above, an extra sanity check.  */
+  if (foutput != NULL && remaining + 1 < argc)
+    error (EXIT_FAILURE, 0,
+	   N_("Only one input file allowed together with '-o'"));
+
+  elf_version (EV_CURRENT);
+
+  /* Process all the remaining files.  */
+  int result = 0;
+  do
+    result |= process_file (argv[remaining]);
+  while (++remaining < argc);
+
+  free_patterns ();
+  return result;
+}
diff --git a/third_party/elfutils/src/elflint.c b/third_party/elfutils/src/elflint.c
new file mode 100644
index 0000000..df1b3a0
--- /dev/null
+++ b/third_party/elfutils/src/elflint.c
@@ -0,0 +1,4756 @@
+/* Pedantic checking of ELF files compliance with gABI/psABI spec.
+   Copyright (C) 2001-2015, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <elf-knowledge.h>
+#include <libeu.h>
+#include <system.h>
+#include <printversion.h>
+#include "../libelf/libelfP.h"
+#include "../libelf/common.h"
+#include "../libebl/libeblP.h"
+#include "../libdw/libdwP.h"
+#include "../libdwfl/libdwflP.h"
+#include "../libdw/memory-access.h"
+
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+#define ARGP_strict	300
+#define ARGP_gnuld	301
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { "strict", ARGP_strict, NULL, 0,
+    N_("Be extremely strict, flag level 2 features."), 0 },
+  { "quiet", 'q', NULL, 0, N_("Do not print anything if successful"), 0 },
+  { "debuginfo", 'd', NULL, 0, N_("Binary is a separate debuginfo file"), 0 },
+  { "gnu-ld", ARGP_gnuld, NULL, 0,
+    N_("Binary has been created with GNU ld and is therefore known to be \
+broken in certain ways"), 0 },
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("\
+Pedantic checking of ELF files compliance with gABI/psABI spec.");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("FILE...");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  options, parse_opt, args_doc, doc, NULL, NULL, NULL
+};
+
+
+/* Declarations of local functions.  */
+static void process_file (int fd, Elf *elf, const char *prefix,
+			  const char *suffix, const char *fname, size_t size,
+			  bool only_one);
+static void process_elf_file (Elf *elf, const char *prefix, const char *suffix,
+			      const char *fname, size_t size, bool only_one);
+static void check_note_section (Ebl *ebl, GElf_Ehdr *ehdr,
+				GElf_Shdr *shdr, int idx);
+
+
+/* Report an error.  */
+#define ERROR(str, args...) \
+  do {									      \
+    printf (str, ##args);						      \
+    ++error_count;							      \
+  } while (0)
+static unsigned int error_count;
+
+/* True if we should perform very strict testing.  */
+static bool be_strict;
+
+/* True if no message is to be printed if the run is succesful.  */
+static bool be_quiet;
+
+/* True if binary is from strip -f, not a normal ELF file.  */
+static bool is_debuginfo;
+
+/* True if binary is assumed to be generated with GNU ld.  */
+static bool gnuld;
+
+/* Index of section header string table.  */
+static uint32_t shstrndx;
+
+/* Array to count references in section groups.  */
+static int *scnref;
+
+/* Numbers of sections and program headers.  */
+static unsigned int shnum;
+static unsigned int phnum;
+
+
+int
+main (int argc, char *argv[])
+{
+  /* Set locale.  */
+  setlocale (LC_ALL, "");
+
+  /* Initialize the message catalog.  */
+  textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  */
+  int remaining;
+  argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+  /* Before we start tell the ELF library which version we are using.  */
+  elf_version (EV_CURRENT);
+
+  /* Now process all the files given at the command line.  */
+  bool only_one = remaining + 1 == argc;
+  do
+    {
+      /* Open the file.  */
+      int fd = open (argv[remaining], O_RDONLY);
+      if (fd == -1)
+	{
+	  error (0, errno, gettext ("cannot open input file"));
+	  continue;
+	}
+
+      /* Create an `Elf' descriptor.  */
+      Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+      if (elf == NULL)
+	ERROR (gettext ("cannot generate Elf descriptor: %s\n"),
+	       elf_errmsg (-1));
+      else
+	{
+	  unsigned int prev_error_count = error_count;
+	  struct stat st;
+
+	  if (fstat (fd, &st) != 0)
+	    {
+	      printf ("cannot stat '%s': %m\n", argv[remaining]);
+	      close (fd);
+	      continue;
+	    }
+
+	  process_file (fd, elf, NULL, NULL, argv[remaining], st.st_size,
+			only_one);
+
+	  /* Now we can close the descriptor.  */
+	  if (elf_end (elf) != 0)
+	    ERROR (gettext ("error while closing Elf descriptor: %s\n"),
+		   elf_errmsg (-1));
+
+	  if (prev_error_count == error_count && !be_quiet)
+	    puts (gettext ("No errors"));
+	}
+
+      close (fd);
+    }
+  while (++remaining < argc);
+
+  return error_count != 0;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg __attribute__ ((unused)),
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case ARGP_strict:
+      be_strict = true;
+      break;
+
+    case 'q':
+      be_quiet = true;
+      break;
+
+    case 'd':
+      is_debuginfo = true;
+      break;
+
+    case ARGP_gnuld:
+      gnuld = true;
+      break;
+
+    case ARGP_KEY_NO_ARGS:
+      fputs (gettext ("Missing file name.\n"), stderr);
+      argp_help (&argp, stderr, ARGP_HELP_SEE, program_invocation_short_name);
+      exit (EXIT_FAILURE);
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+/* Process one file.  */
+static void
+process_file (int fd, Elf *elf, const char *prefix, const char *suffix,
+	      const char *fname, size_t size, bool only_one)
+{
+  /* We can handle two types of files: ELF files and archives.  */
+  Elf_Kind kind = elf_kind (elf);
+
+  switch (kind)
+    {
+    case ELF_K_ELF:
+      /* Yes!  It's an ELF file.  */
+      process_elf_file (elf, prefix, suffix, fname, size, only_one);
+      break;
+
+    case ELF_K_AR:
+      {
+	Elf *subelf;
+	Elf_Cmd cmd = ELF_C_READ_MMAP;
+	size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
+	size_t fname_len = strlen (fname) + 1;
+	char new_prefix[prefix_len + 1 + fname_len];
+	char new_suffix[(suffix == NULL ? 0 : strlen (suffix)) + 2];
+	char *cp = new_prefix;
+
+	/* Create the full name of the file.  */
+	if (prefix != NULL)
+	  {
+	    cp = mempcpy (cp, prefix, prefix_len);
+	    *cp++ = '(';
+	    strcpy (stpcpy (new_suffix, suffix), ")");
+	  }
+	else
+	  new_suffix[0] = '\0';
+	memcpy (cp, fname, fname_len);
+
+	/* It's an archive.  We process each file in it.  */
+	while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+	  {
+	    kind = elf_kind (subelf);
+
+	    /* Call this function recursively.  */
+	    if (kind == ELF_K_ELF || kind == ELF_K_AR)
+	      {
+		Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+		assert (arhdr != NULL);
+
+		process_file (fd, subelf, new_prefix, new_suffix,
+			      arhdr->ar_name, arhdr->ar_size, false);
+	      }
+
+	    /* Get next archive element.  */
+	    cmd = elf_next (subelf);
+	    if (elf_end (subelf) != 0)
+	      ERROR (gettext (" error while freeing sub-ELF descriptor: %s\n"),
+		     elf_errmsg (-1));
+	  }
+      }
+      break;
+
+    default:
+      /* We cannot do anything.  */
+      ERROR (gettext ("\
+Not an ELF file - it has the wrong magic bytes at the start\n"));
+      break;
+    }
+}
+
+
+static const char *
+section_name (Ebl *ebl, int idx)
+{
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr;
+  const char *ret;
+
+  if ((unsigned int) idx > shnum)
+    return "<invalid>";
+
+  shdr = gelf_getshdr (elf_getscn (ebl->elf, idx), &shdr_mem);
+  if (shdr == NULL)
+    return "<invalid>";
+
+  ret = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
+  if (ret == NULL)
+    return "<invalid>";
+  return ret;
+}
+
+
+static const int valid_e_machine[] =
+  {
+    EM_M32, EM_SPARC, EM_386, EM_68K, EM_88K, EM_860, EM_MIPS, EM_S370,
+    EM_MIPS_RS3_LE, EM_PARISC, EM_VPP500, EM_SPARC32PLUS, EM_960, EM_PPC,
+    EM_PPC64, EM_S390, EM_V800, EM_FR20, EM_RH32, EM_RCE, EM_ARM,
+    EM_FAKE_ALPHA, EM_SH, EM_SPARCV9, EM_TRICORE, EM_ARC, EM_H8_300,
+    EM_H8_300H, EM_H8S, EM_H8_500, EM_IA_64, EM_MIPS_X, EM_COLDFIRE,
+    EM_68HC12, EM_MMA, EM_PCP, EM_NCPU, EM_NDR1, EM_STARCORE, EM_ME16,
+    EM_ST100, EM_TINYJ, EM_X86_64, EM_PDSP, EM_FX66, EM_ST9PLUS, EM_ST7,
+    EM_68HC16, EM_68HC11, EM_68HC08, EM_68HC05, EM_SVX, EM_ST19, EM_VAX,
+    EM_CRIS, EM_JAVELIN, EM_FIREPATH, EM_ZSP, EM_MMIX, EM_HUANY, EM_PRISM,
+    EM_AVR, EM_FR30, EM_D10V, EM_D30V, EM_V850, EM_M32R, EM_MN10300,
+    EM_MN10200, EM_PJ, EM_OPENRISC, EM_ARC_A5, EM_XTENSA, EM_ALPHA,
+    EM_TILEGX, EM_TILEPRO, EM_AARCH64, EM_BPF
+  };
+#define nvalid_e_machine \
+  (sizeof (valid_e_machine) / sizeof (valid_e_machine[0]))
+
+
+static void
+check_elf_header (Ebl *ebl, GElf_Ehdr *ehdr, size_t size)
+{
+  char buf[512];
+  size_t cnt;
+
+  /* Check e_ident field.  */
+  if (ehdr->e_ident[EI_MAG0] != ELFMAG0)
+    ERROR ("e_ident[%d] != '%c'\n", EI_MAG0, ELFMAG0);
+  if (ehdr->e_ident[EI_MAG1] != ELFMAG1)
+    ERROR ("e_ident[%d] != '%c'\n", EI_MAG1, ELFMAG1);
+  if (ehdr->e_ident[EI_MAG2] != ELFMAG2)
+    ERROR ("e_ident[%d] != '%c'\n", EI_MAG2, ELFMAG2);
+  if (ehdr->e_ident[EI_MAG3] != ELFMAG3)
+    ERROR ("e_ident[%d] != '%c'\n", EI_MAG3, ELFMAG3);
+
+  if (ehdr->e_ident[EI_CLASS] != ELFCLASS32
+      && ehdr->e_ident[EI_CLASS] != ELFCLASS64)
+    ERROR (gettext ("e_ident[%d] == %d is no known class\n"),
+	   EI_CLASS, ehdr->e_ident[EI_CLASS]);
+
+  if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB
+      && ehdr->e_ident[EI_DATA] != ELFDATA2MSB)
+    ERROR (gettext ("e_ident[%d] == %d is no known data encoding\n"),
+	   EI_DATA, ehdr->e_ident[EI_DATA]);
+
+  if (ehdr->e_ident[EI_VERSION] != EV_CURRENT)
+    ERROR (gettext ("unknown ELF header version number e_ident[%d] == %d\n"),
+	   EI_VERSION, ehdr->e_ident[EI_VERSION]);
+
+  /* We currently don't handle any OS ABIs other than Linux and the
+     kFreeBSD variant of Debian.  */
+  if (ehdr->e_ident[EI_OSABI] != ELFOSABI_NONE
+      && ehdr->e_ident[EI_OSABI] != ELFOSABI_LINUX
+      && ehdr->e_ident[EI_OSABI] != ELFOSABI_FREEBSD)
+    ERROR (gettext ("unsupported OS ABI e_ident[%d] == '%s'\n"),
+	   EI_OSABI,
+	   ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
+
+  /* No ABI versions other than zero supported either.  */
+  if (ehdr->e_ident[EI_ABIVERSION] != 0)
+    ERROR (gettext ("unsupport ABI version e_ident[%d] == %d\n"),
+	   EI_ABIVERSION, ehdr->e_ident[EI_ABIVERSION]);
+
+  for (cnt = EI_PAD; cnt < EI_NIDENT; ++cnt)
+    if (ehdr->e_ident[cnt] != 0)
+      ERROR (gettext ("e_ident[%zu] is not zero\n"), cnt);
+
+  /* Check the e_type field.  */
+  if (ehdr->e_type != ET_REL && ehdr->e_type != ET_EXEC
+      && ehdr->e_type != ET_DYN && ehdr->e_type != ET_CORE)
+    ERROR (gettext ("unknown object file type %d\n"), ehdr->e_type);
+
+  /* Check the e_machine field.  */
+  for (cnt = 0; cnt < nvalid_e_machine; ++cnt)
+    if (valid_e_machine[cnt] == ehdr->e_machine)
+      break;
+  if (cnt == nvalid_e_machine)
+    ERROR (gettext ("unknown machine type %d\n"), ehdr->e_machine);
+
+  /* Check the e_version field.  */
+  if (ehdr->e_version != EV_CURRENT)
+    ERROR (gettext ("unknown object file version\n"));
+
+  /* Check the e_phoff and e_phnum fields.  */
+  if (ehdr->e_phoff == 0)
+    {
+      if (ehdr->e_phnum != 0)
+	ERROR (gettext ("invalid program header offset\n"));
+      else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN)
+	ERROR (gettext ("\
+executables and DSOs cannot have zero program header offset\n"));
+    }
+  else if (ehdr->e_phnum == 0)
+    ERROR (gettext ("invalid number of program header entries\n"));
+
+  /* Check the e_shoff field.  */
+  shnum = ehdr->e_shnum;
+  shstrndx = ehdr->e_shstrndx;
+  if (ehdr->e_shoff == 0)
+    {
+      if (ehdr->e_shnum != 0)
+	ERROR (gettext ("invalid section header table offset\n"));
+      else if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
+	       && ehdr->e_type != ET_CORE)
+	ERROR (gettext ("section header table must be present\n"));
+    }
+  else
+    {
+      if (ehdr->e_shnum == 0)
+	{
+	  /* Get the header of the zeroth section.  The sh_size field
+	     might contain the section number.  */
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
+	  if (shdr != NULL)
+	    {
+	      /* The error will be reported later.  */
+	      if (shdr->sh_size == 0)
+		ERROR (gettext ("\
+invalid number of section header table entries\n"));
+	      else
+		shnum = shdr->sh_size;
+	    }
+	}
+
+      if (ehdr->e_shstrndx == SHN_XINDEX)
+	{
+	  /* Get the header of the zeroth section.  The sh_size field
+	     might contain the section number.  */
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
+	  if (shdr != NULL && shdr->sh_link < shnum)
+	    shstrndx = shdr->sh_link;
+	}
+      else if (shstrndx >= shnum)
+	ERROR (gettext ("invalid section header index\n"));
+    }
+
+  /* Check the shdrs actually exist.  And uncompress them before
+     further checking.  Indexes between sections reference the
+     uncompressed data.  */
+  unsigned int scnt;
+  Elf_Scn *scn = NULL;
+  for (scnt = 1; scnt < shnum; ++scnt)
+     {
+	scn = elf_nextscn (ebl->elf, scn);
+	if (scn == NULL)
+	  break;
+	/* If the section wasn't compressed this does nothing, but
+	   returns an error.  We don't care.  */
+	elf_compress (scn, 0, 0);
+     }
+  if (scnt < shnum)
+    ERROR (gettext ("Can only check %u headers, shnum was %u\n"), scnt, shnum);
+  shnum = scnt;
+
+  phnum = ehdr->e_phnum;
+  if (ehdr->e_phnum == PN_XNUM)
+    {
+      /* Get the header of the zeroth section.  The sh_info field
+	 might contain the phnum count.  */
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
+      if (shdr != NULL)
+	{
+	  /* The error will be reported later.  */
+	  if (shdr->sh_info < PN_XNUM)
+	    ERROR (gettext ("\
+invalid number of program header table entries\n"));
+	  else
+	    phnum = shdr->sh_info;
+	}
+    }
+
+  /* Check the phdrs actually exist. */
+  unsigned int pcnt;
+  for (pcnt = 0; pcnt < phnum; ++pcnt)
+     {
+	GElf_Phdr phdr_mem;
+	GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
+	if (phdr == NULL)
+	  break;
+     }
+  if (pcnt < phnum)
+    ERROR (gettext ("Can only check %u headers, phnum was %u\n"), pcnt, phnum);
+  phnum = pcnt;
+
+  /* Check the e_flags field.  */
+  if (!ebl_machine_flag_check (ebl, ehdr->e_flags))
+    ERROR (gettext ("invalid machine flags: %s\n"),
+	   ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
+
+  /* Check e_ehsize, e_phentsize, and e_shentsize fields.  */
+  if (gelf_getclass (ebl->elf) == ELFCLASS32)
+    {
+      if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf32_Ehdr))
+	ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize);
+
+      if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf32_Phdr))
+	ERROR (gettext ("invalid program header size: %hd\n"),
+	       ehdr->e_phentsize);
+      else if (ehdr->e_phoff + phnum * ehdr->e_phentsize > size)
+	ERROR (gettext ("invalid program header position or size\n"));
+
+      if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf32_Shdr))
+	ERROR (gettext ("invalid section header size: %hd\n"),
+	       ehdr->e_shentsize);
+      else if (ehdr->e_shoff + shnum * ehdr->e_shentsize > size)
+	ERROR (gettext ("invalid section header position or size\n"));
+    }
+  else if (gelf_getclass (ebl->elf) == ELFCLASS64)
+    {
+      if (ehdr->e_ehsize != 0 && ehdr->e_ehsize != sizeof (Elf64_Ehdr))
+	ERROR (gettext ("invalid ELF header size: %hd\n"), ehdr->e_ehsize);
+
+      if (ehdr->e_phentsize != 0 && ehdr->e_phentsize != sizeof (Elf64_Phdr))
+	ERROR (gettext ("invalid program header size: %hd\n"),
+	       ehdr->e_phentsize);
+      else if (ehdr->e_phoff + phnum * ehdr->e_phentsize > size)
+	ERROR (gettext ("invalid program header position or size\n"));
+
+      if (ehdr->e_shentsize != 0 && ehdr->e_shentsize != sizeof (Elf64_Shdr))
+	ERROR (gettext ("invalid section header size: %hd\n"),
+	       ehdr->e_shentsize);
+      else if (ehdr->e_shoff + ehdr->e_shnum * ehdr->e_shentsize > size)
+	ERROR (gettext ("invalid section header position or size\n"));
+    }
+}
+
+
+/* Check that there is a section group section with index < IDX which
+   contains section IDX and that there is exactly one.  */
+static void
+check_scn_group (Ebl *ebl, int idx)
+{
+  if (scnref[idx] == 0)
+    {
+      /* No reference so far.  Search following sections, maybe the
+	 order is wrong.  */
+      size_t cnt;
+
+      for (cnt = idx + 1; cnt < shnum; ++cnt)
+	{
+	  Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (shdr == NULL)
+	    /* We cannot get the section header so we cannot check it.
+	       The error to get the section header will be shown
+	       somewhere else.  */
+	    continue;
+
+	  if (shdr->sh_type != SHT_GROUP)
+	    continue;
+
+	  Elf_Data *data = elf_getdata (scn, NULL);
+	  if (data == NULL || data->d_buf == NULL
+	      || data->d_size < sizeof (Elf32_Word))
+	    /* Cannot check the section.  */
+	    continue;
+
+	  Elf32_Word *grpdata = (Elf32_Word *) data->d_buf;
+	  for (size_t inner = 1; inner < data->d_size / sizeof (Elf32_Word);
+	       ++inner)
+	    if (grpdata[inner] == (Elf32_Word) idx)
+	      goto out;
+	}
+
+    out:
+      if (cnt == shnum)
+	ERROR (gettext ("\
+section [%2d] '%s': section with SHF_GROUP flag set not part of a section group\n"),
+	       idx, section_name (ebl, idx));
+      else
+	ERROR (gettext ("\
+section [%2d] '%s': section group [%2zu] '%s' does not precede group member\n"),
+	       idx, section_name (ebl, idx),
+	       cnt, section_name (ebl, cnt));
+    }
+}
+
+
+static void
+check_symtab (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
+{
+  bool no_xndx_warned = false;
+  int no_pt_tls = 0;
+  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+  if (data == NULL)
+    {
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  GElf_Shdr strshdr_mem;
+  GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+				     &strshdr_mem);
+  if (strshdr == NULL)
+    return;
+
+  if (strshdr->sh_type != SHT_STRTAB)
+    {
+      ERROR (gettext ("section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"),
+	     shdr->sh_link, section_name (ebl, shdr->sh_link),
+	     idx, section_name (ebl, idx));
+      strshdr = NULL;
+    }
+
+  /* Search for an extended section index table section.  */
+  Elf_Data *xndxdata = NULL;
+  Elf32_Word xndxscnidx = 0;
+  bool found_xndx = false;
+  for (size_t cnt = 1; cnt < shnum; ++cnt)
+    if (cnt != (size_t) idx)
+      {
+	Elf_Scn *xndxscn = elf_getscn (ebl->elf, cnt);
+	GElf_Shdr xndxshdr_mem;
+	GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
+	if (xndxshdr == NULL)
+	  continue;
+
+	if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX
+	    && xndxshdr->sh_link == (GElf_Word) idx)
+	  {
+	    if (found_xndx)
+	      ERROR (gettext ("\
+section [%2d] '%s': symbol table cannot have more than one extended index section\n"),
+		     idx, section_name (ebl, idx));
+
+	    xndxdata = elf_getdata (xndxscn, NULL);
+	    xndxscnidx = elf_ndxscn (xndxscn);
+	    found_xndx = true;
+	  }
+      }
+
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT);
+  if (shdr->sh_entsize != sh_entsize)
+    ERROR (gettext ("\
+section [%2u] '%s': entry size is does not match ElfXX_Sym\n"),
+	   idx, section_name (ebl, idx));
+
+  /* Test the zeroth entry.  */
+  GElf_Sym sym_mem;
+  Elf32_Word xndx;
+  GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, 0, &sym_mem, &xndx);
+  if (sym == NULL)
+      ERROR (gettext ("section [%2d] '%s': cannot get symbol %d: %s\n"),
+	     idx, section_name (ebl, idx), 0, elf_errmsg (-1));
+  else
+    {
+      if (sym->st_name != 0)
+	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
+	       idx, section_name (ebl, idx), "st_name");
+      if (sym->st_value != 0)
+	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
+	       idx, section_name (ebl, idx), "st_value");
+      if (sym->st_size != 0)
+	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
+	       idx, section_name (ebl, idx), "st_size");
+      if (sym->st_info != 0)
+	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
+	       idx, section_name (ebl, idx), "st_info");
+      if (sym->st_other != 0)
+	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
+	       idx, section_name (ebl, idx), "st_other");
+      if (sym->st_shndx != 0)
+	ERROR (gettext ("section [%2d] '%s': '%s' in zeroth entry not zero\n"),
+	       idx, section_name (ebl, idx), "st_shndx");
+      if (xndxdata != NULL && xndx != 0)
+	ERROR (gettext ("\
+section [%2d] '%s': XINDEX for zeroth entry not zero\n"),
+	       xndxscnidx, section_name (ebl, xndxscnidx));
+    }
+
+  for (size_t cnt = 1; cnt < shdr->sh_size / sh_entsize; ++cnt)
+    {
+      sym = gelf_getsymshndx (data, xndxdata, cnt, &sym_mem, &xndx);
+      if (sym == NULL)
+	{
+	  ERROR (gettext ("section [%2d] '%s': cannot get symbol %zu: %s\n"),
+		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
+	  continue;
+	}
+
+      const char *name = NULL;
+      if (strshdr == NULL)
+	name = "";
+      else if (sym->st_name >= strshdr->sh_size)
+	ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: invalid name value\n"),
+	       idx, section_name (ebl, idx), cnt);
+      else
+	{
+	  name = elf_strptr (ebl->elf, shdr->sh_link, sym->st_name);
+	  if (name == NULL)
+	    name = "";
+	}
+
+      if (sym->st_shndx == SHN_XINDEX)
+	{
+	  if (xndxdata == NULL)
+	    {
+	      if (!no_xndx_warned)
+		ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: too large section index but no extended section index section\n"),
+		       idx, section_name (ebl, idx), cnt);
+	      no_xndx_warned = true;
+	    }
+	  else if (xndx < SHN_LORESERVE)
+	    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: XINDEX used for index which would fit in st_shndx (%" PRIu32 ")\n"),
+		   xndxscnidx, section_name (ebl, xndxscnidx), cnt,
+		   xndx);
+	}
+      else if ((sym->st_shndx >= SHN_LORESERVE
+		// && sym->st_shndx <= SHN_HIRESERVE    always true
+		&& sym->st_shndx != SHN_ABS
+		&& sym->st_shndx != SHN_COMMON)
+	       || (sym->st_shndx >= shnum
+		   && (sym->st_shndx < SHN_LORESERVE
+		       /* || sym->st_shndx > SHN_HIRESERVE  always false */)))
+	ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: invalid section index\n"),
+	       idx, section_name (ebl, idx), cnt);
+      else
+	xndx = sym->st_shndx;
+
+      if (GELF_ST_TYPE (sym->st_info) >= STT_NUM
+	  && !ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info), NULL, 0))
+	ERROR (gettext ("section [%2d] '%s': symbol %zu: unknown type\n"),
+	       idx, section_name (ebl, idx), cnt);
+
+      if (GELF_ST_BIND (sym->st_info) >= STB_NUM
+	  && !ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info), NULL,
+				       0))
+	ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: unknown symbol binding\n"),
+	       idx, section_name (ebl, idx), cnt);
+      if (GELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE
+	  && GELF_ST_TYPE (sym->st_info) != STT_OBJECT)
+	ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: unique symbol not of object type\n"),
+	       idx, section_name (ebl, idx), cnt);
+
+      if (xndx == SHN_COMMON)
+	{
+	  /* Common symbols can only appear in relocatable files.  */
+	  if (ehdr->e_type != ET_REL)
+	    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: COMMON only allowed in relocatable files\n"),
+		   idx, section_name (ebl, idx), cnt);
+	  if (cnt < shdr->sh_info)
+	    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: local COMMON symbols are nonsense\n"),
+		   idx, section_name (ebl, idx), cnt);
+	  if (GELF_R_TYPE (sym->st_info) == STT_FUNC)
+	    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: function in COMMON section is nonsense\n"),
+		   idx, section_name (ebl, idx), cnt);
+	}
+      else if (xndx > 0 && xndx < shnum)
+	{
+	  GElf_Shdr destshdr_mem;
+	  GElf_Shdr *destshdr;
+
+	  destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx), &destshdr_mem);
+	  if (destshdr != NULL)
+	    {
+	      GElf_Addr sh_addr = (ehdr->e_type == ET_REL ? 0
+				   : destshdr->sh_addr);
+	      GElf_Addr st_value;
+	      if (GELF_ST_TYPE (sym->st_info) == STT_FUNC
+		  || (GELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC))
+		st_value = sym->st_value & ebl_func_addr_mask (ebl);
+	      else
+		st_value = sym->st_value;
+	      if (GELF_ST_TYPE (sym->st_info) != STT_TLS)
+		{
+		  if (! ebl_check_special_symbol (ebl, ehdr, sym, name,
+						  destshdr))
+		    {
+		      if (st_value - sh_addr > destshdr->sh_size)
+			{
+			  /* GNU ld has severe bugs.  When it decides to remove
+			     empty sections it leaves symbols referencing them
+			     behind.  These are symbols in .symtab or .dynsym
+			     and for the named symbols have zero size.  See
+			     sourceware PR13621.  */
+			  if (!gnuld
+			      || (strcmp (section_name (ebl, idx), ".symtab")
+			          && strcmp (section_name (ebl, idx),
+					     ".dynsym"))
+			      || sym->st_size != 0
+			      || (strcmp (name, "__preinit_array_start") != 0
+				  && strcmp (name, "__preinit_array_end") != 0
+				  && strcmp (name, "__init_array_start") != 0
+				  && strcmp (name, "__init_array_end") != 0
+				  && strcmp (name, "__fini_array_start") != 0
+				  && strcmp (name, "__fini_array_end") != 0
+				  && strcmp (name, "__bss_start") != 0
+				  && strcmp (name, "__bss_start__") != 0
+				  && strcmp (name, "__TMC_END__") != 0
+				  && strcmp (name, ".TOC.") != 0
+				  && strcmp (name, "_edata") != 0
+				  && strcmp (name, "__edata") != 0
+				  && strcmp (name, "_end") != 0
+				  && strcmp (name, "__end") != 0))
+			    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: st_value out of bounds\n"),
+				   idx, section_name (ebl, idx), cnt);
+			}
+		      else if ((st_value - sh_addr
+				+ sym->st_size) > destshdr->sh_size)
+			ERROR (gettext ("\
+section [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
+			       idx, section_name (ebl, idx), cnt,
+			       (int) xndx, section_name (ebl, xndx));
+		    }
+		}
+	      else
+		{
+		  if ((destshdr->sh_flags & SHF_TLS) == 0)
+		    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: referenced section [%2d] '%s' does not have SHF_TLS flag set\n"),
+			   idx, section_name (ebl, idx), cnt,
+			   (int) xndx, section_name (ebl, xndx));
+
+		  if (ehdr->e_type == ET_REL)
+		    {
+		      /* For object files the symbol value must fall
+			 into the section.  */
+		      if (st_value > destshdr->sh_size)
+			ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"),
+			       idx, section_name (ebl, idx), cnt,
+			       (int) xndx, section_name (ebl, xndx));
+		      else if (st_value + sym->st_size
+			       > destshdr->sh_size)
+			ERROR (gettext ("\
+section [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
+			       idx, section_name (ebl, idx), cnt,
+			       (int) xndx, section_name (ebl, xndx));
+		    }
+		  else
+		    {
+		      GElf_Phdr phdr_mem;
+		      GElf_Phdr *phdr = NULL;
+		      unsigned int pcnt;
+
+		      for (pcnt = 0; pcnt < phnum; ++pcnt)
+			{
+			  phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
+			  if (phdr != NULL && phdr->p_type == PT_TLS)
+			    break;
+			}
+
+		      if (pcnt == phnum)
+			{
+			  if (no_pt_tls++ == 0)
+			    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: TLS symbol but no TLS program header entry\n"),
+				   idx, section_name (ebl, idx), cnt);
+			}
+		      else if (phdr == NULL)
+			{
+			    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: TLS symbol but couldn't get TLS program header entry\n"),
+				   idx, section_name (ebl, idx), cnt);
+			}
+		      else if (!is_debuginfo)
+			{
+			  if (st_value
+			      < destshdr->sh_offset - phdr->p_offset)
+			    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: st_value short of referenced section [%2d] '%s'\n"),
+				   idx, section_name (ebl, idx), cnt,
+				   (int) xndx, section_name (ebl, xndx));
+			  else if (st_value
+				   > (destshdr->sh_offset - phdr->p_offset
+				      + destshdr->sh_size))
+			    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: st_value out of bounds of referenced section [%2d] '%s'\n"),
+				   idx, section_name (ebl, idx), cnt,
+				   (int) xndx, section_name (ebl, xndx));
+			  else if (st_value + sym->st_size
+				   > (destshdr->sh_offset - phdr->p_offset
+				      + destshdr->sh_size))
+			    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu does not fit completely in referenced section [%2d] '%s'\n"),
+				   idx, section_name (ebl, idx), cnt,
+				   (int) xndx, section_name (ebl, xndx));
+			}
+		    }
+		}
+	    }
+	}
+
+      if (GELF_ST_BIND (sym->st_info) == STB_LOCAL)
+	{
+	  if (cnt >= shdr->sh_info)
+	    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: local symbol outside range described in sh_info\n"),
+		   idx, section_name (ebl, idx), cnt);
+	}
+      else
+	{
+	  if (cnt < shdr->sh_info)
+	    ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: non-local symbol outside range described in sh_info\n"),
+		   idx, section_name (ebl, idx), cnt);
+	}
+
+      if (GELF_ST_TYPE (sym->st_info) == STT_SECTION
+	  && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
+	ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: non-local section symbol\n"),
+	       idx, section_name (ebl, idx), cnt);
+
+      if (name != NULL)
+	{
+	  if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
+	    {
+	      /* Check that address and size match the global offset table.  */
+
+	      GElf_Shdr destshdr_mem;
+	      GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, xndx),
+						  &destshdr_mem);
+
+	      if (destshdr == NULL && xndx == SHN_ABS)
+		{
+		  /* In a DSO, we have to find the GOT section by name.  */
+		  Elf_Scn *gotscn = NULL;
+		  Elf_Scn *gscn = NULL;
+		  while ((gscn = elf_nextscn (ebl->elf, gscn)) != NULL)
+		    {
+		      destshdr = gelf_getshdr (gscn, &destshdr_mem);
+		      assert (destshdr != NULL);
+		      const char *sname = elf_strptr (ebl->elf,
+						      ehdr->e_shstrndx,
+						      destshdr->sh_name);
+		      if (sname != NULL)
+			{
+			  if (strcmp (sname, ".got.plt") == 0)
+			    break;
+			  if (strcmp (sname, ".got") == 0)
+			    /* Do not stop looking.
+			       There might be a .got.plt section.  */
+			    gotscn = gscn;
+			}
+
+		      destshdr = NULL;
+		    }
+
+		  if (destshdr == NULL && gotscn != NULL)
+		    destshdr = gelf_getshdr (gotscn, &destshdr_mem);
+		}
+
+	      const char *sname = ((destshdr == NULL || xndx == SHN_UNDEF)
+				   ? NULL
+				   : elf_strptr (ebl->elf, ehdr->e_shstrndx,
+						 destshdr->sh_name));
+	      if (sname == NULL)
+		{
+		  if (xndx != SHN_UNDEF || ehdr->e_type != ET_REL)
+		    ERROR (gettext ("\
+section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \
+bad section [%2d]\n"),
+			   idx, section_name (ebl, idx), xndx);
+		}
+	      else if (strcmp (sname, ".got.plt") != 0
+		       && strcmp (sname, ".got") != 0)
+		ERROR (gettext ("\
+section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol refers to \
+section [%2d] '%s'\n"),
+		       idx, section_name (ebl, idx), xndx, sname);
+
+	      if (destshdr != NULL)
+		{
+		  /* Found it.  */
+		  if (!ebl_check_special_symbol (ebl, ehdr, sym, name,
+						 destshdr))
+		    {
+		      if (ehdr->e_type != ET_REL
+			  && sym->st_value != destshdr->sh_addr)
+			/* This test is more strict than the psABIs which
+			   usually allow the symbol to be in the middle of
+			   the .got section, allowing negative offsets.  */
+			ERROR (gettext ("\
+section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol value %#" PRIx64 " does not match %s section address %#" PRIx64 "\n"),
+			       idx, section_name (ebl, idx),
+			       (uint64_t) sym->st_value,
+			       sname, (uint64_t) destshdr->sh_addr);
+
+		      if (!gnuld && sym->st_size != destshdr->sh_size)
+			ERROR (gettext ("\
+section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol size %" PRIu64 " does not match %s section size %" PRIu64 "\n"),
+			       idx, section_name (ebl, idx),
+			       (uint64_t) sym->st_size,
+			       sname, (uint64_t) destshdr->sh_size);
+		    }
+		}
+	      else
+		ERROR (gettext ("\
+section [%2d] '%s': _GLOBAL_OFFSET_TABLE_ symbol present, but no .got section\n"),
+		       idx, section_name (ebl, idx));
+	    }
+	  else if (strcmp (name, "_DYNAMIC") == 0)
+	    /* Check that address and size match the dynamic section.
+	       We locate the dynamic section via the program header
+	       entry.  */
+	    for (unsigned int pcnt = 0; pcnt < phnum; ++pcnt)
+	      {
+		GElf_Phdr phdr_mem;
+		GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
+
+		if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
+		  {
+		    if (sym->st_value != phdr->p_vaddr)
+		      ERROR (gettext ("\
+section [%2d] '%s': _DYNAMIC_ symbol value %#" PRIx64 " does not match dynamic segment address %#" PRIx64 "\n"),
+			     idx, section_name (ebl, idx),
+			     (uint64_t) sym->st_value,
+			     (uint64_t) phdr->p_vaddr);
+
+		    if (!gnuld && sym->st_size != phdr->p_memsz)
+		      ERROR (gettext ("\
+section [%2d] '%s': _DYNAMIC symbol size %" PRIu64 " does not match dynamic segment size %" PRIu64 "\n"),
+			     idx, section_name (ebl, idx),
+			     (uint64_t) sym->st_size,
+			     (uint64_t) phdr->p_memsz);
+
+		    break;
+		  }
+	    }
+	}
+
+      if (GELF_ST_VISIBILITY (sym->st_other) != STV_DEFAULT
+	  && shdr->sh_type == SHT_DYNSYM)
+	ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: symbol in dynamic symbol table with non-default visibility\n"),
+	       idx, section_name (ebl, idx), cnt);
+      if (! ebl_check_st_other_bits (ebl, sym->st_other))
+	ERROR (gettext ("\
+section [%2d] '%s': symbol %zu: unknown bit set in st_other\n"),
+	       idx, section_name (ebl, idx), cnt);
+
+    }
+}
+
+
+static bool
+is_rel_dyn (Ebl *ebl, const GElf_Ehdr *ehdr, int idx, const GElf_Shdr *shdr,
+	    bool is_rela)
+{
+  /* If this is no executable or DSO it cannot be a .rel.dyn section.  */
+  if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
+    return false;
+
+  /* Check the section name.  Unfortunately necessary.  */
+  if (strcmp (section_name (ebl, idx), is_rela ? ".rela.dyn" : ".rel.dyn"))
+    return false;
+
+  /* When a .rel.dyn section is used a DT_RELCOUNT dynamic section
+     entry can be present as well.  */
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      GElf_Shdr rcshdr_mem;
+      const GElf_Shdr *rcshdr = gelf_getshdr (scn, &rcshdr_mem);
+
+      if (rcshdr == NULL)
+	break;
+
+      if (rcshdr->sh_type == SHT_DYNAMIC && rcshdr->sh_entsize != 0)
+	{
+	  /* Found the dynamic section.  Look through it.  */
+	  Elf_Data *d = elf_getdata (scn, NULL);
+	  size_t cnt;
+
+	  if (d == NULL)
+	    ERROR (gettext ("\
+section [%2d] '%s': cannot get section data.\n"),
+		   idx, section_name (ebl, idx));
+
+	  for (cnt = 1; cnt < rcshdr->sh_size / rcshdr->sh_entsize; ++cnt)
+	    {
+	      GElf_Dyn dyn_mem;
+	      GElf_Dyn *dyn = gelf_getdyn (d, cnt, &dyn_mem);
+
+	      if (dyn == NULL)
+		break;
+
+	      if (dyn->d_tag == DT_RELCOUNT)
+		{
+		  /* Found it.  Does the type match.  */
+		  if (is_rela)
+		    ERROR (gettext ("\
+section [%2d] '%s': DT_RELCOUNT used for this RELA section\n"),
+			   idx, section_name (ebl, idx));
+		  else
+		    {
+		      /* Does the number specified number of relative
+			 relocations exceed the total number of
+			 relocations?  */
+		      if (shdr->sh_entsize != 0
+			  && dyn->d_un.d_val > (shdr->sh_size
+						/ shdr->sh_entsize))
+			ERROR (gettext ("\
+section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
+			       idx, section_name (ebl, idx),
+			       (int) dyn->d_un.d_val);
+
+		      /* Make sure the specified number of relocations are
+			 relative.  */
+		      Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf,
+								   idx), NULL);
+		      if (reldata != NULL && shdr->sh_entsize != 0)
+			for (size_t inner = 0;
+			     inner < shdr->sh_size / shdr->sh_entsize;
+			     ++inner)
+			  {
+			    GElf_Rel rel_mem;
+			    GElf_Rel *rel = gelf_getrel (reldata, inner,
+							 &rel_mem);
+			    if (rel == NULL)
+			      /* The problem will be reported elsewhere.  */
+			      break;
+
+			    if (ebl_relative_reloc_p (ebl,
+						      GELF_R_TYPE (rel->r_info)))
+			      {
+				if (inner >= dyn->d_un.d_val)
+				  ERROR (gettext ("\
+section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"),
+					 idx, section_name (ebl, idx),
+					 (int) dyn->d_un.d_val);
+			      }
+			    else if (inner < dyn->d_un.d_val)
+			      ERROR (gettext ("\
+section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"),
+				     idx, section_name (ebl, idx),
+				     inner, (int) dyn->d_un.d_val);
+			  }
+		    }
+		}
+
+	      if (dyn->d_tag == DT_RELACOUNT)
+		{
+		  /* Found it.  Does the type match.  */
+		  if (!is_rela)
+		    ERROR (gettext ("\
+section [%2d] '%s': DT_RELACOUNT used for this REL section\n"),
+			   idx, section_name (ebl, idx));
+		  else
+		    {
+		      /* Does the number specified number of relative
+			 relocations exceed the total number of
+			 relocations?  */
+		      if (shdr->sh_entsize != 0
+			  && dyn->d_un.d_val > shdr->sh_size / shdr->sh_entsize)
+			ERROR (gettext ("\
+section [%2d] '%s': DT_RELCOUNT value %d too high for this section\n"),
+			       idx, section_name (ebl, idx),
+			       (int) dyn->d_un.d_val);
+
+		      /* Make sure the specified number of relocations are
+			 relative.  */
+		      Elf_Data *reldata = elf_getdata (elf_getscn (ebl->elf,
+								   idx), NULL);
+		      if (reldata != NULL && shdr->sh_entsize != 0)
+			for (size_t inner = 0;
+			     inner < shdr->sh_size / shdr->sh_entsize;
+			     ++inner)
+			  {
+			    GElf_Rela rela_mem;
+			    GElf_Rela *rela = gelf_getrela (reldata, inner,
+							    &rela_mem);
+			    if (rela == NULL)
+			      /* The problem will be reported elsewhere.  */
+			      break;
+
+			    if (ebl_relative_reloc_p (ebl,
+						      GELF_R_TYPE (rela->r_info)))
+			      {
+				if (inner >= dyn->d_un.d_val)
+				  ERROR (gettext ("\
+section [%2d] '%s': relative relocations after index %d as specified by DT_RELCOUNT\n"),
+					 idx, section_name (ebl, idx),
+					 (int) dyn->d_un.d_val);
+			      }
+			    else if (inner < dyn->d_un.d_val)
+			      ERROR (gettext ("\
+section [%2d] '%s': non-relative relocation at index %zu; DT_RELCOUNT specified %d relative relocations\n"),
+				     idx, section_name (ebl, idx),
+				     inner, (int) dyn->d_un.d_val);
+			  }
+		    }
+		}
+	    }
+
+	  break;
+	}
+    }
+
+  return true;
+}
+
+
+struct loaded_segment
+{
+  GElf_Addr from;
+  GElf_Addr to;
+  bool read_only;
+  struct loaded_segment *next;
+};
+
+
+/* Check whether binary has text relocation flag set.  */
+static bool textrel;
+
+/* Keep track of whether text relocation flag is needed.  */
+static bool needed_textrel;
+
+
+static bool
+check_reloc_shdr (Ebl *ebl, const GElf_Ehdr *ehdr, const GElf_Shdr *shdr,
+		  int idx, int reltype, GElf_Shdr **destshdrp,
+		  GElf_Shdr *destshdr_memp, struct loaded_segment **loadedp)
+{
+  bool reldyn = false;
+
+  /* Check whether the link to the section we relocate is reasonable.  */
+  if (shdr->sh_info >= shnum)
+    ERROR (gettext ("section [%2d] '%s': invalid destination section index\n"),
+	   idx, section_name (ebl, idx));
+  else if (shdr->sh_info != 0)
+    {
+      *destshdrp = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
+				 destshdr_memp);
+      if (*destshdrp != NULL)
+	{
+	  if(! ebl_check_reloc_target_type (ebl, (*destshdrp)->sh_type))
+	    {
+	      reldyn = is_rel_dyn (ebl, ehdr, idx, shdr, true);
+	      if (!reldyn)
+		ERROR (gettext ("\
+section [%2d] '%s': invalid destination section type\n"),
+		       idx, section_name (ebl, idx));
+	      else
+		{
+		  /* There is no standard, but we require that .rel{,a}.dyn
+		     sections have a sh_info value of zero.  */
+		  if (shdr->sh_info != 0)
+		    ERROR (gettext ("\
+section [%2d] '%s': sh_info should be zero\n"),
+			   idx, section_name (ebl, idx));
+		}
+	    }
+
+	  if ((((*destshdrp)->sh_flags & SHF_MERGE) != 0)
+	      && ((*destshdrp)->sh_flags & SHF_STRINGS) != 0)
+	    ERROR (gettext ("\
+section [%2d] '%s': no relocations for merge-able string sections possible\n"),
+		   idx, section_name (ebl, idx));
+	}
+    }
+
+  size_t sh_entsize = gelf_fsize (ebl->elf, reltype, 1, EV_CURRENT);
+  if (shdr->sh_entsize != sh_entsize)
+    ERROR (gettext (reltype == ELF_T_RELA ? "\
+section [%2d] '%s': section entry size does not match ElfXX_Rela\n" : "\
+section [%2d] '%s': section entry size does not match ElfXX_Rel\n"),
+	   idx, section_name (ebl, idx));
+
+  /* In preparation of checking whether relocations are text
+     relocations or not we need to determine whether the file is
+     flagged to have text relocation and we need to determine a) what
+     the loaded segments are and b) which are read-only.  This will
+     also allow us to determine whether the same reloc section is
+     modifying loaded and not loaded segments.  */
+  for (unsigned int i = 0; i < phnum; ++i)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
+      if (phdr == NULL)
+	continue;
+
+      if (phdr->p_type == PT_LOAD)
+	{
+	  struct loaded_segment *newp = xmalloc (sizeof (*newp));
+	  newp->from = phdr->p_vaddr;
+	  newp->to = phdr->p_vaddr + phdr->p_memsz;
+	  newp->read_only = (phdr->p_flags & PF_W) == 0;
+	  newp->next = *loadedp;
+	  *loadedp = newp;
+	}
+      else if (phdr->p_type == PT_DYNAMIC)
+	{
+	  Elf_Scn *dynscn = gelf_offscn (ebl->elf, phdr->p_offset);
+	  GElf_Shdr dynshdr_mem;
+	  GElf_Shdr *dynshdr = gelf_getshdr (dynscn, &dynshdr_mem);
+	  Elf_Data *dyndata = elf_getdata (dynscn, NULL);
+	  if (dynshdr != NULL && dynshdr->sh_type == SHT_DYNAMIC
+	      && dyndata != NULL && dynshdr->sh_entsize != 0)
+	    for (size_t j = 0; j < dynshdr->sh_size / dynshdr->sh_entsize; ++j)
+	      {
+		GElf_Dyn dyn_mem;
+		GElf_Dyn *dyn = gelf_getdyn (dyndata, j, &dyn_mem);
+		if (dyn != NULL
+		    && (dyn->d_tag == DT_TEXTREL
+			|| (dyn->d_tag == DT_FLAGS
+			    && (dyn->d_un.d_val & DF_TEXTREL) != 0)))
+		  {
+		    textrel = true;
+		    break;
+		  }
+	      }
+	}
+    }
+
+  /* A quick test which can be easily done here (although it is a bit
+     out of place): the text relocation flag makes only sense if there
+     is a segment which is not writable.  */
+  if (textrel)
+    {
+      struct loaded_segment *seg = *loadedp;
+      while (seg != NULL && !seg->read_only)
+	seg = seg->next;
+      if (seg == NULL)
+	ERROR (gettext ("\
+text relocation flag set but there is no read-only segment\n"));
+    }
+
+  return reldyn;
+}
+
+
+enum load_state
+  {
+    state_undecided,
+    state_loaded,
+    state_unloaded,
+    state_error
+  };
+
+
+static void
+check_one_reloc (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *relshdr, int idx,
+		 size_t cnt, const GElf_Shdr *symshdr, Elf_Data *symdata,
+		 GElf_Addr r_offset, GElf_Xword r_info,
+		 const GElf_Shdr *destshdr, bool reldyn,
+		 struct loaded_segment *loaded, enum load_state *statep)
+{
+  bool known_broken = gnuld;
+
+  if (!ebl_reloc_type_check (ebl, GELF_R_TYPE (r_info)))
+    ERROR (gettext ("section [%2d] '%s': relocation %zu: invalid type\n"),
+	   idx, section_name (ebl, idx), cnt);
+  else if (((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
+	    /* The executable/DSO can contain relocation sections with
+	       all the relocations the linker has applied.  Those sections
+	       are marked non-loaded, though.  */
+	    || (relshdr->sh_flags & SHF_ALLOC) != 0)
+	   && !ebl_reloc_valid_use (ebl, GELF_R_TYPE (r_info)))
+    ERROR (gettext ("\
+section [%2d] '%s': relocation %zu: relocation type invalid for the file type\n"),
+	   idx, section_name (ebl, idx), cnt);
+
+  if (symshdr != NULL
+      && ((GELF_R_SYM (r_info) + 1)
+	  * gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT)
+	  > symshdr->sh_size))
+    ERROR (gettext ("\
+section [%2d] '%s': relocation %zu: invalid symbol index\n"),
+	   idx, section_name (ebl, idx), cnt);
+
+  /* No more tests if this is a no-op relocation.  */
+  if (ebl_none_reloc_p (ebl, GELF_R_TYPE (r_info)))
+    return;
+
+  if (ebl_gotpc_reloc_check (ebl, GELF_R_TYPE (r_info)))
+    {
+      const char *name;
+      char buf[64];
+      GElf_Sym sym_mem;
+      GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem);
+      if (sym != NULL
+	  /* Get the name for the symbol.  */
+	  && (name = elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
+	  && strcmp (name, "_GLOBAL_OFFSET_TABLE_") !=0 )
+	ERROR (gettext ("\
+section [%2d] '%s': relocation %zu: only symbol '_GLOBAL_OFFSET_TABLE_' can be used with %s\n"),
+	       idx, section_name (ebl, idx), cnt,
+	       ebl_reloc_type_name (ebl, GELF_R_SYM (r_info),
+				    buf, sizeof (buf)));
+    }
+
+  if (reldyn)
+    {
+      // XXX TODO Check .rel.dyn section addresses.
+    }
+  else if (!known_broken)
+    {
+      if (destshdr != NULL
+	  && GELF_R_TYPE (r_info) != 0
+	  && (r_offset - (ehdr->e_type == ET_REL ? 0
+			  : destshdr->sh_addr)) >= destshdr->sh_size)
+	ERROR (gettext ("\
+section [%2d] '%s': relocation %zu: offset out of bounds\n"),
+	       idx, section_name (ebl, idx), cnt);
+    }
+
+  GElf_Sym sym_mem;
+  GElf_Sym *sym = gelf_getsym (symdata, GELF_R_SYM (r_info), &sym_mem);
+
+  if (ebl_copy_reloc_p (ebl, GELF_R_TYPE (r_info))
+      /* Make sure the referenced symbol is an object or unspecified.  */
+      && sym != NULL
+      && GELF_ST_TYPE (sym->st_info) != STT_NOTYPE
+      && GELF_ST_TYPE (sym->st_info) != STT_OBJECT)
+    {
+      char buf[64];
+      ERROR (gettext ("section [%2d] '%s': relocation %zu: copy relocation against symbol of type %s\n"),
+	     idx, section_name (ebl, idx), cnt,
+	     ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
+				   buf, sizeof (buf)));
+    }
+
+  if ((ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
+      || (relshdr->sh_flags & SHF_ALLOC) != 0)
+    {
+      bool in_loaded_seg = false;
+      while (loaded != NULL)
+	{
+	  if (r_offset < loaded->to
+	      && r_offset + (sym == NULL ? 0 : sym->st_size) >= loaded->from)
+	    {
+	      /* The symbol is in this segment.  */
+	      if  (loaded->read_only)
+		{
+		  if (textrel)
+		    needed_textrel = true;
+		  else
+		    ERROR (gettext ("section [%2d] '%s': relocation %zu: read-only section modified but text relocation flag not set\n"),
+			   idx, section_name (ebl, idx), cnt);
+		}
+
+	      in_loaded_seg = true;
+	    }
+
+	  loaded = loaded->next;
+	}
+
+      if (*statep == state_undecided)
+	*statep = in_loaded_seg ? state_loaded : state_unloaded;
+      else if ((*statep == state_unloaded && in_loaded_seg)
+	       || (*statep == state_loaded && !in_loaded_seg))
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': relocations are against loaded and unloaded data\n"),
+		 idx, section_name (ebl, idx));
+	  *statep = state_error;
+	}
+    }
+}
+
+
+static void
+check_rela (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
+{
+  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+  if (data == NULL)
+    {
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  /* Check the fields of the section header.  */
+  GElf_Shdr destshdr_mem;
+  GElf_Shdr *destshdr = NULL;
+  struct loaded_segment *loaded = NULL;
+  bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_RELA, &destshdr,
+				  &destshdr_mem, &loaded);
+
+  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+  GElf_Shdr symshdr_mem;
+  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+  Elf_Data *symdata = elf_getdata (symscn, NULL);
+  enum load_state state = state_undecided;
+
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
+  for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
+    {
+      GElf_Rela rela_mem;
+      GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem);
+      if (rela == NULL)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': cannot get relocation %zu: %s\n"),
+		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
+	  continue;
+	}
+
+      check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata,
+		       rela->r_offset, rela->r_info, destshdr, reldyn, loaded,
+		       &state);
+    }
+
+  while (loaded != NULL)
+    {
+      struct loaded_segment *old = loaded;
+      loaded = loaded->next;
+      free (old);
+    }
+}
+
+
+static void
+check_rel (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
+{
+  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+  if (data == NULL)
+    {
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  /* Check the fields of the section header.  */
+  GElf_Shdr destshdr_mem;
+  GElf_Shdr *destshdr = NULL;
+  struct loaded_segment *loaded = NULL;
+  bool reldyn = check_reloc_shdr (ebl, ehdr, shdr, idx, ELF_T_REL, &destshdr,
+				  &destshdr_mem, &loaded);
+
+  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+  GElf_Shdr symshdr_mem;
+  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+  Elf_Data *symdata = elf_getdata (symscn, NULL);
+  enum load_state state = state_undecided;
+
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
+  for (size_t cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
+    {
+      GElf_Rel rel_mem;
+      GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem);
+      if (rel == NULL)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': cannot get relocation %zu: %s\n"),
+		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
+	  continue;
+	}
+
+      check_one_reloc (ebl, ehdr, shdr, idx, cnt, symshdr, symdata,
+		       rel->r_offset, rel->r_info, destshdr, reldyn, loaded,
+		       &state);
+    }
+
+  while (loaded != NULL)
+    {
+      struct loaded_segment *old = loaded;
+      loaded = loaded->next;
+      free (old);
+    }
+}
+
+
+/* Number of dynamic sections.  */
+static int ndynamic;
+
+
+static void
+check_dynamic (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
+{
+  Elf_Data *data;
+  GElf_Shdr strshdr_mem;
+  GElf_Shdr *strshdr;
+  size_t cnt;
+  static const bool dependencies[DT_NUM][DT_NUM] =
+    {
+      [DT_NEEDED] = { [DT_STRTAB] = true },
+      [DT_PLTRELSZ] = { [DT_JMPREL] = true },
+      [DT_HASH] = { [DT_SYMTAB] = true },
+      [DT_STRTAB] = { [DT_STRSZ] = true },
+      [DT_SYMTAB] = { [DT_STRTAB] = true, [DT_SYMENT] = true },
+      [DT_RELA] = { [DT_RELASZ] = true, [DT_RELAENT] = true },
+      [DT_RELASZ] = { [DT_RELA] = true },
+      [DT_RELAENT] = { [DT_RELA] = true },
+      [DT_STRSZ] = { [DT_STRTAB] = true },
+      [DT_SYMENT] = { [DT_SYMTAB] = true },
+      [DT_SONAME] = { [DT_STRTAB] = true },
+      [DT_RPATH] = { [DT_STRTAB] = true },
+      [DT_REL] = { [DT_RELSZ] = true, [DT_RELENT] = true },
+      [DT_RELSZ] = { [DT_REL] = true },
+      [DT_RELENT] = { [DT_REL] = true },
+      [DT_JMPREL] = { [DT_PLTRELSZ] = true, [DT_PLTREL] = true },
+      [DT_RUNPATH] = { [DT_STRTAB] = true },
+      [DT_PLTREL] = { [DT_JMPREL] = true },
+    };
+  bool has_dt[DT_NUM];
+  bool has_val_dt[DT_VALNUM];
+  bool has_addr_dt[DT_ADDRNUM];
+  static const bool level2[DT_NUM] =
+    {
+      [DT_RPATH] = true,
+      [DT_SYMBOLIC] = true,
+      [DT_TEXTREL] = true,
+      [DT_BIND_NOW] = true
+    };
+  static const bool mandatory[DT_NUM] =
+    {
+      [DT_NULL] = true,
+      [DT_STRTAB] = true,
+      [DT_SYMTAB] = true,
+      [DT_STRSZ] = true,
+      [DT_SYMENT] = true
+    };
+
+  memset (has_dt, '\0', sizeof (has_dt));
+  memset (has_val_dt, '\0', sizeof (has_val_dt));
+  memset (has_addr_dt, '\0', sizeof (has_addr_dt));
+
+  if (++ndynamic == 2)
+    ERROR (gettext ("more than one dynamic section present\n"));
+
+  data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+  if (data == NULL)
+    {
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &strshdr_mem);
+  if (strshdr != NULL && strshdr->sh_type != SHT_STRTAB)
+    ERROR (gettext ("\
+section [%2d] '%s': referenced as string table for section [%2d] '%s' but type is not SHT_STRTAB\n"),
+	   shdr->sh_link, section_name (ebl, shdr->sh_link),
+	   idx, section_name (ebl, idx));
+  else if (strshdr == NULL)
+    {
+      ERROR (gettext ("\
+section [%2d]: referenced as string table for section [%2d] '%s' but section link value is invalid\n"),
+	   shdr->sh_link, idx, section_name (ebl, idx));
+      return;
+    }
+
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
+  if (shdr->sh_entsize != sh_entsize)
+    ERROR (gettext ("\
+section [%2d] '%s': section entry size does not match ElfXX_Dyn\n"),
+	   idx, section_name (ebl, idx));
+
+  if (shdr->sh_info != 0)
+    ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"),
+	   idx, section_name (ebl, idx));
+
+  bool non_null_warned = false;
+  for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
+    {
+      GElf_Dyn dyn_mem;
+      GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dyn_mem);
+      if (dyn == NULL)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': cannot get dynamic section entry %zu: %s\n"),
+		 idx, section_name (ebl, idx), cnt, elf_errmsg (-1));
+	  continue;
+	}
+
+      if (has_dt[DT_NULL] && dyn->d_tag != DT_NULL && ! non_null_warned)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': non-DT_NULL entries follow DT_NULL entry\n"),
+		 idx, section_name (ebl, idx));
+	  non_null_warned = true;
+	}
+
+      if (!ebl_dynamic_tag_check (ebl, dyn->d_tag))
+	ERROR (gettext ("section [%2d] '%s': entry %zu: unknown tag\n"),
+	       idx, section_name (ebl, idx), cnt);
+
+      if (dyn->d_tag >= 0 && dyn->d_tag < DT_NUM)
+	{
+	  if (has_dt[dyn->d_tag]
+	      && dyn->d_tag != DT_NEEDED
+	      && dyn->d_tag != DT_NULL
+	      && dyn->d_tag != DT_POSFLAG_1)
+	    {
+	      char buf[50];
+	      ERROR (gettext ("\
+section [%2d] '%s': entry %zu: more than one entry with tag %s\n"),
+		     idx, section_name (ebl, idx), cnt,
+		     ebl_dynamic_tag_name (ebl, dyn->d_tag,
+					   buf, sizeof (buf)));
+	    }
+
+	  if (be_strict && level2[dyn->d_tag])
+	    {
+	      char buf[50];
+	      ERROR (gettext ("\
+section [%2d] '%s': entry %zu: level 2 tag %s used\n"),
+		     idx, section_name (ebl, idx), cnt,
+		     ebl_dynamic_tag_name (ebl, dyn->d_tag,
+					   buf, sizeof (buf)));
+	    }
+
+	  has_dt[dyn->d_tag] = true;
+	}
+      else if (dyn->d_tag >= 0 && dyn->d_tag <= DT_VALRNGHI
+	       && DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM)
+	has_val_dt[DT_VALTAGIDX (dyn->d_tag)] = true;
+      else if (dyn->d_tag >= 0 && dyn->d_tag <= DT_ADDRRNGHI
+	       && DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM)
+	has_addr_dt[DT_ADDRTAGIDX (dyn->d_tag)] = true;
+
+      if (dyn->d_tag == DT_PLTREL && dyn->d_un.d_val != DT_REL
+	  && dyn->d_un.d_val != DT_RELA)
+	ERROR (gettext ("\
+section [%2d] '%s': entry %zu: DT_PLTREL value must be DT_REL or DT_RELA\n"),
+	       idx, section_name (ebl, idx), cnt);
+
+      /* Check that addresses for entries are in loaded segments.  */
+      switch (dyn->d_tag)
+	{
+	  size_t n;
+	case DT_STRTAB:
+	  /* We require the referenced section is the same as the one
+	     specified in sh_link.  */
+	  if (strshdr->sh_addr != dyn->d_un.d_val)
+	    {
+	      ERROR (gettext ("\
+section [%2d] '%s': entry %zu: pointer does not match address of section [%2d] '%s' referenced by sh_link\n"),
+		     idx, section_name (ebl, idx), cnt,
+		     shdr->sh_link, section_name (ebl, shdr->sh_link));
+	      break;
+	    }
+	  goto check_addr;
+
+	default:
+	  if (dyn->d_tag < DT_ADDRRNGLO || dyn->d_tag > DT_ADDRRNGHI)
+	    /* Value is no pointer.  */
+	    break;
+	  FALLTHROUGH;
+
+	case DT_AUXILIARY:
+	case DT_FILTER:
+	case DT_FINI:
+	case DT_FINI_ARRAY:
+	case DT_HASH:
+	case DT_INIT:
+	case DT_INIT_ARRAY:
+	case DT_JMPREL:
+	case DT_PLTGOT:
+	case DT_REL:
+	case DT_RELA:
+	case DT_SYMBOLIC:
+	case DT_SYMTAB:
+	case DT_VERDEF:
+	case DT_VERNEED:
+	case DT_VERSYM:
+	check_addr:
+	  for (n = 0; n < phnum; ++n)
+	    {
+	      GElf_Phdr phdr_mem;
+	      GElf_Phdr *phdr = gelf_getphdr (ebl->elf, n, &phdr_mem);
+	      if (phdr != NULL && phdr->p_type == PT_LOAD
+		  && phdr->p_vaddr <= dyn->d_un.d_ptr
+		  && phdr->p_vaddr + phdr->p_memsz > dyn->d_un.d_ptr)
+		break;
+	    }
+	  if (unlikely (n >= phnum))
+	    {
+	      char buf[50];
+	      ERROR (gettext ("\
+section [%2d] '%s': entry %zu: %s value must point into loaded segment\n"),
+		     idx, section_name (ebl, idx), cnt,
+		     ebl_dynamic_tag_name (ebl, dyn->d_tag, buf,
+					   sizeof (buf)));
+	    }
+	  break;
+
+	case DT_NEEDED:
+	case DT_RPATH:
+	case DT_RUNPATH:
+	case DT_SONAME:
+	  if (dyn->d_un.d_ptr >= strshdr->sh_size)
+	    {
+	      char buf[50];
+	      ERROR (gettext ("\
+section [%2d] '%s': entry %zu: %s value must be valid offset in section [%2d] '%s'\n"),
+		     idx, section_name (ebl, idx), cnt,
+		     ebl_dynamic_tag_name (ebl, dyn->d_tag, buf,
+					   sizeof (buf)),
+		     shdr->sh_link, section_name (ebl, shdr->sh_link));
+	    }
+	  break;
+	}
+    }
+
+  for (cnt = 1; cnt < DT_NUM; ++cnt)
+    if (has_dt[cnt])
+      {
+	for (int inner = 0; inner < DT_NUM; ++inner)
+	  if (dependencies[cnt][inner] && ! has_dt[inner])
+	    {
+	      char buf1[50];
+	      char buf2[50];
+
+	      ERROR (gettext ("\
+section [%2d] '%s': contains %s entry but not %s\n"),
+		     idx, section_name (ebl, idx),
+		     ebl_dynamic_tag_name (ebl, cnt, buf1, sizeof (buf1)),
+		     ebl_dynamic_tag_name (ebl, inner, buf2, sizeof (buf2)));
+	    }
+      }
+    else
+      {
+	if (mandatory[cnt])
+	  {
+	    char buf[50];
+	    ERROR (gettext ("\
+section [%2d] '%s': mandatory tag %s not present\n"),
+		   idx, section_name (ebl, idx),
+		   ebl_dynamic_tag_name (ebl, cnt, buf, sizeof (buf)));
+	  }
+      }
+
+  /* Make sure we have an hash table.  */
+  if (!has_dt[DT_HASH] && !has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)])
+    ERROR (gettext ("\
+section [%2d] '%s': no hash section present\n"),
+	   idx, section_name (ebl, idx));
+
+  /* The GNU-style hash table also needs a symbol table.  */
+  if (!has_dt[DT_HASH] && has_addr_dt[DT_ADDRTAGIDX (DT_GNU_HASH)]
+      && !has_dt[DT_SYMTAB])
+    ERROR (gettext ("\
+section [%2d] '%s': contains %s entry but not %s\n"),
+	   idx, section_name (ebl, idx),
+	   "DT_GNU_HASH", "DT_SYMTAB");
+
+  /* Check the rel/rela tags.  At least one group must be available.  */
+  if ((has_dt[DT_RELA] || has_dt[DT_RELASZ] || has_dt[DT_RELAENT])
+      && (!has_dt[DT_RELA] || !has_dt[DT_RELASZ] || !has_dt[DT_RELAENT]))
+    ERROR (gettext ("\
+section [%2d] '%s': not all of %s, %s, and %s are present\n"),
+	   idx, section_name (ebl, idx),
+	   "DT_RELA", "DT_RELASZ", "DT_RELAENT");
+
+  if ((has_dt[DT_REL] || has_dt[DT_RELSZ] || has_dt[DT_RELENT])
+      && (!has_dt[DT_REL] || !has_dt[DT_RELSZ] || !has_dt[DT_RELENT]))
+    ERROR (gettext ("\
+section [%2d] '%s': not all of %s, %s, and %s are present\n"),
+	   idx, section_name (ebl, idx),
+	   "DT_REL", "DT_RELSZ", "DT_RELENT");
+
+  /* Check that all prelink sections are present if any of them is.  */
+  if (has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)]
+      || has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)])
+    {
+      if (!has_val_dt[DT_VALTAGIDX (DT_GNU_PRELINKED)])
+	ERROR (gettext ("\
+section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"),
+	       idx, section_name (ebl, idx), "DT_GNU_PRELINKED");
+      if (!has_val_dt[DT_VALTAGIDX (DT_CHECKSUM)])
+	ERROR (gettext ("\
+section [%2d] '%s': %s tag missing in DSO marked during prelinking\n"),
+	       idx, section_name (ebl, idx), "DT_CHECKSUM");
+
+      /* Only DSOs can be marked like this.  */
+      if (ehdr->e_type != ET_DYN)
+	ERROR (gettext ("\
+section [%2d] '%s': non-DSO file marked as dependency during prelink\n"),
+	       idx, section_name (ebl, idx));
+    }
+
+  if (has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)]
+      || has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)]
+      || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)]
+      || has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)])
+    {
+      if (!has_val_dt[DT_VALTAGIDX (DT_GNU_CONFLICTSZ)])
+	ERROR (gettext ("\
+section [%2d] '%s': %s tag missing in prelinked executable\n"),
+	       idx, section_name (ebl, idx), "DT_GNU_CONFLICTSZ");
+      if (!has_val_dt[DT_VALTAGIDX (DT_GNU_LIBLISTSZ)])
+	ERROR (gettext ("\
+section [%2d] '%s': %s tag missing in prelinked executable\n"),
+	       idx, section_name (ebl, idx), "DT_GNU_LIBLISTSZ");
+      if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_CONFLICT)])
+	ERROR (gettext ("\
+section [%2d] '%s': %s tag missing in prelinked executable\n"),
+	       idx, section_name (ebl, idx), "DT_GNU_CONFLICT");
+      if (!has_addr_dt[DT_ADDRTAGIDX (DT_GNU_LIBLIST)])
+	ERROR (gettext ("\
+section [%2d] '%s': %s tag missing in prelinked executable\n"),
+	       idx, section_name (ebl, idx), "DT_GNU_LIBLIST");
+    }
+}
+
+
+static void
+check_symtab_shndx (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
+{
+  if (ehdr->e_type != ET_REL)
+    {
+      ERROR (gettext ("\
+section [%2d] '%s': only relocatable files can have extended section index\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+  GElf_Shdr symshdr_mem;
+  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+  if (symshdr != NULL && symshdr->sh_type != SHT_SYMTAB)
+    ERROR (gettext ("\
+section [%2d] '%s': extended section index section not for symbol table\n"),
+	   idx, section_name (ebl, idx));
+  else if (symshdr == NULL)
+    ERROR (gettext ("\
+section [%2d] '%s': sh_link extended section index [%2d] is invalid\n"),
+	   idx, section_name (ebl, idx), shdr->sh_link);
+  Elf_Data *symdata = elf_getdata (symscn, NULL);
+  if (symdata == NULL)
+    ERROR (gettext ("cannot get data for symbol section\n"));
+
+  if (shdr->sh_entsize != sizeof (Elf32_Word))
+    ERROR (gettext ("\
+section [%2d] '%s': entry size does not match Elf32_Word\n"),
+	   idx, section_name (ebl, idx));
+
+  if (symshdr != NULL
+      && shdr->sh_entsize != 0
+      && symshdr->sh_entsize != 0
+      && (shdr->sh_size / shdr->sh_entsize
+	  < symshdr->sh_size / symshdr->sh_entsize))
+    ERROR (gettext ("\
+section [%2d] '%s': extended index table too small for symbol table\n"),
+	   idx, section_name (ebl, idx));
+
+  if (shdr->sh_info != 0)
+    ERROR (gettext ("section [%2d] '%s': sh_info not zero\n"),
+	   idx, section_name (ebl, idx));
+
+  for (size_t cnt = idx + 1; cnt < shnum; ++cnt)
+    {
+      GElf_Shdr rshdr_mem;
+      GElf_Shdr *rshdr = gelf_getshdr (elf_getscn (ebl->elf, cnt), &rshdr_mem);
+      if (rshdr != NULL && rshdr->sh_type == SHT_SYMTAB_SHNDX
+	  && rshdr->sh_link == shdr->sh_link)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': extended section index in section [%2zu] '%s' refers to same symbol table\n"),
+		 idx, section_name (ebl, idx),
+		 cnt, section_name (ebl, cnt));
+	  break;
+	}
+    }
+
+  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+  if (data == NULL || data->d_buf == NULL)
+    {
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  if (data->d_size < sizeof (Elf32_Word)
+      || *((Elf32_Word *) data->d_buf) != 0)
+    ERROR (gettext ("symbol 0 should have zero extended section index\n"));
+
+  for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
+    {
+      Elf32_Word xndx = ((Elf32_Word *) data->d_buf)[cnt];
+
+      if (xndx != 0)
+	{
+	  GElf_Sym sym_data;
+	  GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_data);
+	  if (sym == NULL)
+	    {
+	      ERROR (gettext ("cannot get data for symbol %zu\n"), cnt);
+	      continue;
+	    }
+
+	  if (sym->st_shndx != SHN_XINDEX)
+	    ERROR (gettext ("\
+extended section index is %" PRIu32 " but symbol index is not XINDEX\n"),
+		   (uint32_t) xndx);
+	}
+    }
+}
+
+
+static void
+check_sysv_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
+		 GElf_Shdr *symshdr)
+{
+  Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
+  Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
+
+  if (shdr->sh_size < (2 + nbucket + nchain) * sizeof (Elf32_Word))
+    {
+      ERROR (gettext ("\
+section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"),
+	     idx, section_name (ebl, idx), (long int) shdr->sh_size,
+	     (long int) ((2 + nbucket + nchain) * sizeof (Elf32_Word)));
+      return;
+    }
+
+  size_t maxidx = nchain;
+
+  if (symshdr != NULL && symshdr->sh_entsize != 0)
+    {
+      size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
+
+      if (nchain > symshdr->sh_size / symshdr->sh_entsize)
+	ERROR (gettext ("section [%2d] '%s': chain array too large\n"),
+	       idx, section_name (ebl, idx));
+
+      maxidx = symsize;
+    }
+
+  Elf32_Word *buf = (Elf32_Word *) data->d_buf;
+  Elf32_Word *end = (Elf32_Word *) ((char *) data->d_buf + shdr->sh_size);
+  size_t cnt;
+  for (cnt = 2; cnt < 2 + nbucket; ++cnt)
+    {
+      if (buf + cnt >= end)
+	break;
+      else if (buf[cnt] >= maxidx)
+      ERROR (gettext ("\
+section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
+	     idx, section_name (ebl, idx), cnt - 2);
+    }
+
+  for (; cnt < 2 + nbucket + nchain; ++cnt)
+    {
+      if (buf + cnt >= end)
+	break;
+      else if (buf[cnt] >= maxidx)
+      ERROR (gettext ("\
+section [%2d] '%s': hash chain reference %zu out of bounds\n"),
+	     idx, section_name (ebl, idx), cnt - 2 - nbucket);
+    }
+}
+
+
+static void
+check_sysv_hash64 (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
+		 GElf_Shdr *symshdr)
+{
+  Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
+  Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
+
+  if (shdr->sh_size < (2 + nbucket + nchain) * sizeof (Elf64_Xword))
+    {
+      ERROR (gettext ("\
+section [%2d] '%s': hash table section is too small (is %ld, expected %ld)\n"),
+	     idx, section_name (ebl, idx), (long int) shdr->sh_size,
+	     (long int) ((2 + nbucket + nchain) * sizeof (Elf64_Xword)));
+      return;
+    }
+
+  size_t maxidx = nchain;
+
+  if (symshdr != NULL && symshdr->sh_entsize != 0)
+    {
+      size_t symsize = symshdr->sh_size / symshdr->sh_entsize;
+
+      if (nchain > symshdr->sh_size / symshdr->sh_entsize)
+	ERROR (gettext ("section [%2d] '%s': chain array too large\n"),
+	       idx, section_name (ebl, idx));
+
+      maxidx = symsize;
+    }
+
+  Elf64_Xword *buf = (Elf64_Xword *) data->d_buf;
+  Elf64_Xword *end = (Elf64_Xword *) ((char *) data->d_buf + shdr->sh_size);
+  size_t cnt;
+  for (cnt = 2; cnt < 2 + nbucket; ++cnt)
+    {
+      if (buf + cnt >= end)
+	break;
+      else if (buf[cnt] >= maxidx)
+      ERROR (gettext ("\
+section [%2d] '%s': hash bucket reference %zu out of bounds\n"),
+	     idx, section_name (ebl, idx), cnt - 2);
+    }
+
+  for (; cnt < 2 + nbucket + nchain; ++cnt)
+    {
+      if (buf + cnt >= end)
+	break;
+      else if (buf[cnt] >= maxidx)
+      ERROR (gettext ("\
+section [%2d] '%s': hash chain reference %" PRIu64 " out of bounds\n"),
+	       idx, section_name (ebl, idx), (uint64_t) cnt - 2 - nbucket);
+    }
+}
+
+
+static void
+check_gnu_hash (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data, int idx,
+		GElf_Shdr *symshdr)
+{
+  if (data->d_size < 4 * sizeof (Elf32_Word))
+    {
+      ERROR (gettext ("\
+section [%2d] '%s': not enough data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  Elf32_Word nbuckets = ((Elf32_Word *) data->d_buf)[0];
+  Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
+  Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
+
+  if (bitmask_words == 0 || !powerof2 (bitmask_words))
+    {
+      ERROR (gettext ("\
+section [%2d] '%s': bitmask size zero or not power of 2: %u\n"),
+	     idx, section_name (ebl, idx), bitmask_words);
+      return;
+    }
+
+  size_t bitmask_idxmask = bitmask_words - 1;
+  if (gelf_getclass (ebl->elf) == ELFCLASS64)
+    bitmask_words *= 2;
+  Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
+
+  /* Is there still room for the sym chain?
+     Use uint64_t calculation to prevent 32bit overlow.  */
+  uint64_t used_buf = (4ULL + bitmask_words + nbuckets) * sizeof (Elf32_Word);
+  if (used_buf > data->d_size)
+    {
+      ERROR (gettext ("\
+section [%2d] '%s': hash table section is too small (is %ld, expected at least %ld)\n"),
+	     idx, section_name (ebl, idx), (long int) shdr->sh_size,
+	     (long int) used_buf);
+      return;
+    }
+
+  if (shift > 31)
+    {
+      ERROR (gettext ("\
+section [%2d] '%s': 2nd hash function shift too big: %u\n"),
+	     idx, section_name (ebl, idx), shift);
+      return;
+    }
+
+  size_t maxidx = shdr->sh_size / sizeof (Elf32_Word) - (4 + bitmask_words
+							 + nbuckets);
+
+  if (symshdr != NULL && symshdr->sh_entsize != 0)
+    maxidx = MIN (maxidx, symshdr->sh_size / symshdr->sh_entsize);
+
+  /* We need the symbol section data.  */
+  Elf_Data *symdata = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link), NULL);
+
+  union
+  {
+    Elf32_Word *p32;
+    Elf64_Xword *p64;
+  } bitmask = { .p32 = &((Elf32_Word *) data->d_buf)[4] },
+      collected = { .p32 = xcalloc (bitmask_words, sizeof (Elf32_Word)) };
+
+  size_t classbits = gelf_getclass (ebl->elf) == ELFCLASS32 ? 32 : 64;
+
+  size_t cnt;
+  for (cnt = 4 + bitmask_words; cnt < 4 + bitmask_words + nbuckets; ++cnt)
+    {
+      Elf32_Word symidx = ((Elf32_Word *) data->d_buf)[cnt];
+
+      if (symidx == 0)
+	continue;
+
+      if (symidx < symbias)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': hash chain for bucket %zu lower than symbol index bias\n"),
+		 idx, section_name (ebl, idx), cnt - (4 + bitmask_words));
+	  continue;
+	}
+
+      while (symidx - symbias < maxidx)
+	{
+	  Elf32_Word chainhash = ((Elf32_Word *) data->d_buf)[4
+							      + bitmask_words
+							      + nbuckets
+							      + symidx
+							      - symbias];
+
+	  if (symdata != NULL)
+	    {
+	      /* Check that the referenced symbol is not undefined.  */
+	      GElf_Sym sym_mem;
+	      GElf_Sym *sym = gelf_getsym (symdata, symidx, &sym_mem);
+	      if (sym != NULL && sym->st_shndx == SHN_UNDEF
+		  && GELF_ST_TYPE (sym->st_info) != STT_FUNC)
+		ERROR (gettext ("\
+section [%2d] '%s': symbol %u referenced in chain for bucket %zu is undefined\n"),
+		       idx, section_name (ebl, idx), symidx,
+		       cnt - (4 + bitmask_words));
+
+	      const char *symname = (sym != NULL
+				     ? elf_strptr (ebl->elf, symshdr->sh_link,
+						   sym->st_name)
+				     : NULL);
+	      if (symname != NULL)
+		{
+		  Elf32_Word hval = elf_gnu_hash (symname);
+		  if ((hval & ~1u) != (chainhash & ~1u))
+		    ERROR (gettext ("\
+section [%2d] '%s': hash value for symbol %u in chain for bucket %zu wrong\n"),
+			   idx, section_name (ebl, idx), symidx,
+			   cnt - (4 + bitmask_words));
+
+		  /* Set the bits in the bitmask.  */
+		  size_t maskidx = (hval / classbits) & bitmask_idxmask;
+		  if (maskidx >= bitmask_words)
+		    {
+		      ERROR (gettext ("\
+section [%2d] '%s': mask index for symbol %u in chain for bucket %zu wrong\n"),
+			     idx, section_name (ebl, idx), symidx,
+			     cnt - (4 + bitmask_words));
+		      return;
+		    }
+		  if (classbits == 32)
+		    {
+		      collected.p32[maskidx]
+			|= UINT32_C (1) << (hval & (classbits - 1));
+		      collected.p32[maskidx]
+			|= UINT32_C (1) << ((hval >> shift) & (classbits - 1));
+		    }
+		  else
+		    {
+		      collected.p64[maskidx]
+			|= UINT64_C (1) << (hval & (classbits - 1));
+		      collected.p64[maskidx]
+			|= UINT64_C (1) << ((hval >> shift) & (classbits - 1));
+		    }
+		}
+	    }
+
+	  if ((chainhash & 1) != 0)
+	    break;
+
+	  ++symidx;
+	}
+
+      if (symidx - symbias >= maxidx)
+	ERROR (gettext ("\
+section [%2d] '%s': hash chain for bucket %zu out of bounds\n"),
+	       idx, section_name (ebl, idx), cnt - (4 + bitmask_words));
+      else if (symshdr != NULL && symshdr->sh_entsize != 0
+	       && symidx > symshdr->sh_size / symshdr->sh_entsize)
+	ERROR (gettext ("\
+section [%2d] '%s': symbol reference in chain for bucket %zu out of bounds\n"),
+	       idx, section_name (ebl, idx), cnt - (4 + bitmask_words));
+    }
+
+  if (memcmp (collected.p32, bitmask.p32, bitmask_words * sizeof (Elf32_Word)))
+    ERROR (gettext ("\
+section [%2d] '%s': bitmask does not match names in the hash table\n"),
+	   idx, section_name (ebl, idx));
+
+  free (collected.p32);
+}
+
+
+static void
+check_hash (int tag, Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
+{
+  if (ehdr->e_type == ET_REL)
+    {
+      ERROR (gettext ("\
+section [%2d] '%s': relocatable files cannot have hash tables\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+  if (data == NULL || data->d_buf == NULL)
+    {
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  GElf_Shdr symshdr_mem;
+  GElf_Shdr *symshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+				     &symshdr_mem);
+  if (symshdr != NULL && symshdr->sh_type != SHT_DYNSYM)
+    ERROR (gettext ("\
+section [%2d] '%s': hash table not for dynamic symbol table\n"),
+	   idx, section_name (ebl, idx));
+  else if (symshdr == NULL)
+    ERROR (gettext ("\
+section [%2d] '%s': invalid sh_link symbol table section index [%2d]\n"),
+	   idx, section_name (ebl, idx), shdr->sh_link);
+
+  size_t expect_entsize = (tag == SHT_GNU_HASH
+			   ? (gelf_getclass (ebl->elf) == ELFCLASS32
+			      ? sizeof (Elf32_Word) : 0)
+			   : (size_t) ebl_sysvhash_entrysize (ebl));
+
+  if (shdr->sh_entsize != expect_entsize)
+    ERROR (gettext ("\
+section [%2d] '%s': hash table entry size incorrect\n"),
+	   idx, section_name (ebl, idx));
+
+  if ((shdr->sh_flags & SHF_ALLOC) == 0)
+    ERROR (gettext ("section [%2d] '%s': not marked to be allocated\n"),
+	   idx, section_name (ebl, idx));
+
+  if (shdr->sh_size < (tag == SHT_GNU_HASH ? 4 : 2) * (expect_entsize ?: 4))
+    {
+      ERROR (gettext ("\
+section [%2d] '%s': hash table has not even room for initial administrative entries\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  switch (tag)
+    {
+    case SHT_HASH:
+      if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
+	check_sysv_hash64 (ebl, shdr, data, idx, symshdr);
+      else
+	check_sysv_hash (ebl, shdr, data, idx, symshdr);
+      break;
+
+    case SHT_GNU_HASH:
+      check_gnu_hash (ebl, shdr, data, idx, symshdr);
+      break;
+
+    default:
+      assert (! "should not happen");
+    }
+}
+
+
+/* Compare content of both hash tables, it must be identical.  */
+static void
+compare_hash_gnu_hash (Ebl *ebl, GElf_Ehdr *ehdr, size_t hash_idx,
+		       size_t gnu_hash_idx)
+{
+  Elf_Scn *hash_scn = elf_getscn (ebl->elf, hash_idx);
+  Elf_Data *hash_data = elf_getdata (hash_scn, NULL);
+  GElf_Shdr hash_shdr_mem;
+  GElf_Shdr *hash_shdr = gelf_getshdr (hash_scn, &hash_shdr_mem);
+  Elf_Scn *gnu_hash_scn = elf_getscn (ebl->elf, gnu_hash_idx);
+  Elf_Data *gnu_hash_data = elf_getdata (gnu_hash_scn, NULL);
+  GElf_Shdr gnu_hash_shdr_mem;
+  GElf_Shdr *gnu_hash_shdr = gelf_getshdr (gnu_hash_scn, &gnu_hash_shdr_mem);
+
+  if (hash_shdr == NULL || gnu_hash_shdr == NULL
+      || hash_data == NULL || hash_data->d_buf == NULL
+      || gnu_hash_data == NULL || gnu_hash_data->d_buf == NULL)
+    /* None of these pointers should be NULL since we used the
+       sections already.  We are careful nonetheless.  */
+    return;
+
+  /* The link must point to the same symbol table.  */
+  if (hash_shdr->sh_link != gnu_hash_shdr->sh_link)
+    {
+      ERROR (gettext ("\
+sh_link in hash sections [%2zu] '%s' and [%2zu] '%s' not identical\n"),
+	     hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name),
+	     gnu_hash_idx,
+	     elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name));
+      return;
+    }
+
+  Elf_Scn *sym_scn = elf_getscn (ebl->elf, hash_shdr->sh_link);
+  Elf_Data *sym_data = elf_getdata (sym_scn, NULL);
+  GElf_Shdr sym_shdr_mem;
+  GElf_Shdr *sym_shdr = gelf_getshdr (sym_scn, &sym_shdr_mem);
+
+  if (sym_data == NULL || sym_data->d_buf == NULL
+      || sym_shdr == NULL || sym_shdr->sh_entsize == 0)
+    return;
+
+  const char *hash_name;
+  const char *gnu_hash_name;
+  hash_name  = elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name);
+  gnu_hash_name  = elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name);
+
+  if (gnu_hash_data->d_size < 4 * sizeof (Elf32_Word))
+    {
+      ERROR (gettext ("\
+hash section [%2zu] '%s' does not contain enough data\n"),
+	     gnu_hash_idx, gnu_hash_name);
+      return;
+    }
+
+  uint32_t nentries = sym_shdr->sh_size / sym_shdr->sh_entsize;
+  char *used = alloca (nentries);
+  memset (used, '\0', nentries);
+
+  /* First go over the GNU_HASH table and mark the entries as used.  */
+  const Elf32_Word *gnu_hasharr = (Elf32_Word *) gnu_hash_data->d_buf;
+  Elf32_Word gnu_nbucket = gnu_hasharr[0];
+  Elf32_Word gnu_symbias = gnu_hasharr[1];
+  const int bitmap_factor = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 1 : 2;
+  const Elf32_Word *gnu_bucket = (gnu_hasharr
+				  + (4 + gnu_hasharr[2] * bitmap_factor));
+  const Elf32_Word *gnu_chain = gnu_bucket + gnu_hasharr[0];
+
+  if (gnu_hasharr[2] == 0)
+    {
+      ERROR (gettext ("\
+hash section [%2zu] '%s' has zero bit mask words\n"),
+	     gnu_hash_idx, gnu_hash_name);
+      return;
+    }
+
+  uint64_t used_buf = ((4ULL + gnu_hasharr[2] * bitmap_factor + gnu_nbucket)
+		       * sizeof (Elf32_Word));
+  uint32_t max_nsyms = (gnu_hash_data->d_size - used_buf) / sizeof (Elf32_Word);
+  if (used_buf > gnu_hash_data->d_size)
+    {
+      ERROR (gettext ("\
+hash section [%2zu] '%s' uses too much data\n"),
+	     gnu_hash_idx, gnu_hash_name);
+      return;
+    }
+
+  for (Elf32_Word cnt = 0; cnt < gnu_nbucket; ++cnt)
+    {
+      if (gnu_bucket[cnt] != STN_UNDEF)
+	{
+	  Elf32_Word symidx = gnu_bucket[cnt] - gnu_symbias;
+	  do
+	    {
+	      if (symidx >= max_nsyms || symidx + gnu_symbias >= nentries)
+		{
+		  ERROR (gettext ("\
+hash section [%2zu] '%s' invalid symbol index %" PRIu32 " (max_nsyms: %" PRIu32 ", nentries: %" PRIu32 "\n"),
+			 gnu_hash_idx, gnu_hash_name, symidx, max_nsyms, nentries);
+		  return;
+		}
+	      used[symidx + gnu_symbias] |= 1;
+	    }
+	  while ((gnu_chain[symidx++] & 1u) == 0);
+	}
+    }
+
+  /* Now go over the old hash table and check that we cover the same
+     entries.  */
+  if (hash_shdr->sh_entsize == sizeof (Elf32_Word))
+    {
+      const Elf32_Word *hasharr = (Elf32_Word *) hash_data->d_buf;
+      if (hash_data->d_size < 2 * sizeof (Elf32_Word))
+	{
+	  ERROR (gettext ("\
+hash section [%2zu] '%s' does not contain enough data\n"),
+		 hash_idx, hash_name);
+	  return;
+	}
+
+      Elf32_Word nbucket = hasharr[0];
+      Elf32_Word nchain = hasharr[1];
+      uint64_t hash_used = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
+      if (hash_used > hash_data->d_size)
+	{
+	  ERROR (gettext ("\
+hash section [%2zu] '%s' uses too much data\n"),
+		 hash_idx, hash_name);
+	  return;
+	}
+
+      const Elf32_Word *bucket = &hasharr[2];
+      const Elf32_Word *chain = &hasharr[2 + nbucket];
+
+      for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
+	{
+	  Elf32_Word symidx = bucket[cnt];
+	  while (symidx != STN_UNDEF && symidx < nentries && symidx < nchain)
+	    {
+	      used[symidx] |= 2;
+	      symidx = chain[symidx];
+	    }
+	}
+    }
+  else if (hash_shdr->sh_entsize == sizeof (Elf64_Xword))
+    {
+      const Elf64_Xword *hasharr = (Elf64_Xword *) hash_data->d_buf;
+      if (hash_data->d_size < 2 * sizeof (Elf32_Word))
+	{
+	  ERROR (gettext ("\
+hash section [%2zu] '%s' does not contain enough data\n"),
+		 hash_idx, hash_name);
+	  return;
+	}
+
+      Elf64_Xword nbucket = hasharr[0];
+      Elf64_Xword nchain = hasharr[1];
+      uint64_t maxwords = hash_data->d_size / sizeof (Elf64_Xword);
+      if (maxwords < 2
+	  || maxwords - 2 < nbucket
+	  || maxwords - 2 - nbucket < nchain)
+	{
+	  ERROR (gettext ("\
+hash section [%2zu] '%s' uses too much data\n"),
+		 hash_idx, hash_name);
+	  return;
+	}
+
+      const Elf64_Xword *bucket = &hasharr[2];
+      const Elf64_Xword *chain = &hasharr[2 + nbucket];
+
+      for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
+	{
+	  Elf64_Xword symidx = bucket[cnt];
+	  while (symidx != STN_UNDEF && symidx < nentries && symidx < nchain)
+	    {
+	      used[symidx] |= 2;
+	      symidx = chain[symidx];
+	    }
+	}
+    }
+  else
+    {
+      ERROR (gettext ("\
+hash section [%2zu] '%s' invalid sh_entsize\n"),
+	     hash_idx, hash_name);
+      return;
+    }
+
+  /* Now see which entries are not set in one or both hash tables
+     (unless the symbol is undefined in which case it can be omitted
+     in the new table format).  */
+  if ((used[0] & 1) != 0)
+    ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"),
+	   gnu_hash_idx,
+	   elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name));
+  if ((used[0] & 2) != 0)
+    ERROR (gettext ("section [%2zu] '%s': reference to symbol index 0\n"),
+	   hash_idx, elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name));
+
+  for (uint32_t cnt = 1; cnt < nentries; ++cnt)
+    if (used[cnt] != 0 && used[cnt] != 3)
+      {
+	if (used[cnt] == 1)
+	  ERROR (gettext ("\
+symbol %d referenced in new hash table in [%2zu] '%s' but not in old hash table in [%2zu] '%s'\n"),
+		 cnt, gnu_hash_idx,
+		 elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name),
+		 hash_idx,
+		 elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name));
+	else
+	  {
+	    GElf_Sym sym_mem;
+	    GElf_Sym *sym = gelf_getsym (sym_data, cnt, &sym_mem);
+
+	    if (sym != NULL && sym->st_shndx != STN_UNDEF)
+	      ERROR (gettext ("\
+symbol %d referenced in old hash table in [%2zu] '%s' but not in new hash table in [%2zu] '%s'\n"),
+		     cnt, hash_idx,
+		     elf_strptr (ebl->elf, shstrndx, hash_shdr->sh_name),
+		     gnu_hash_idx,
+		     elf_strptr (ebl->elf, shstrndx, gnu_hash_shdr->sh_name));
+	  }
+      }
+}
+
+
+static void
+check_null (Ebl *ebl, GElf_Shdr *shdr, int idx)
+{
+#define TEST(name, extra) \
+  if (extra && shdr->sh_##name != 0)					      \
+    ERROR (gettext ("section [%2d] '%s': nonzero sh_%s for NULL section\n"),  \
+	   idx, section_name (ebl, idx), #name)
+
+  TEST (name, 1);
+  TEST (flags, 1);
+  TEST (addr, 1);
+  TEST (offset, 1);
+  TEST (size, idx != 0);
+  TEST (link, idx != 0);
+  TEST (info, 1);
+  TEST (addralign, 1);
+  TEST (entsize, 1);
+}
+
+
+static void
+check_group (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
+{
+  if (ehdr->e_type != ET_REL)
+    {
+      ERROR (gettext ("\
+section [%2d] '%s': section groups only allowed in relocatable object files\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  /* Check that sh_link is an index of a symbol table.  */
+  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+  GElf_Shdr symshdr_mem;
+  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+  if (symshdr == NULL)
+    ERROR (gettext ("section [%2d] '%s': cannot get symbol table: %s\n"),
+	   idx, section_name (ebl, idx), elf_errmsg (-1));
+  else
+    {
+      if (symshdr->sh_type != SHT_SYMTAB)
+	ERROR (gettext ("\
+section [%2d] '%s': section reference in sh_link is no symbol table\n"),
+	       idx, section_name (ebl, idx));
+
+      if (shdr->sh_info >= symshdr->sh_size / gelf_fsize (ebl->elf, ELF_T_SYM,
+							  1, EV_CURRENT))
+	ERROR (gettext ("\
+section [%2d] '%s': invalid symbol index in sh_info\n"),
+	       idx, section_name (ebl, idx));
+
+      if (shdr->sh_flags != 0)
+	ERROR (gettext ("section [%2d] '%s': sh_flags not zero\n"),
+	       idx, section_name (ebl, idx));
+
+      GElf_Sym sym_data;
+      GElf_Sym *sym = gelf_getsym (elf_getdata (symscn, NULL), shdr->sh_info,
+				   &sym_data);
+      if (sym == NULL)
+	ERROR (gettext ("\
+section [%2d] '%s': cannot get symbol for signature\n"),
+	       idx, section_name (ebl, idx));
+      else if (elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name) == NULL)
+	ERROR (gettext ("\
+section [%2d] '%s': cannot get symbol name for signature\n"),
+	       idx, section_name (ebl, idx));
+      else if (strcmp (elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name),
+		       "") == 0)
+	ERROR (gettext ("\
+section [%2d] '%s': signature symbol cannot be empty string\n"),
+	       idx, section_name (ebl, idx));
+
+      if (be_strict
+	  && shdr->sh_entsize != elf32_fsize (ELF_T_WORD, 1, EV_CURRENT))
+	ERROR (gettext ("section [%2d] '%s': sh_flags not set correctly\n"),
+	       idx, section_name (ebl, idx));
+    }
+
+  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+  if (data == NULL || data->d_buf == NULL)
+    ERROR (gettext ("section [%2d] '%s': cannot get data: %s\n"),
+	   idx, section_name (ebl, idx), elf_errmsg (-1));
+  else
+    {
+      size_t elsize = elf32_fsize (ELF_T_WORD, 1, EV_CURRENT);
+      size_t cnt;
+      Elf32_Word val;
+
+      if (data->d_size % elsize != 0)
+	ERROR (gettext ("\
+section [%2d] '%s': section size not multiple of sizeof(Elf32_Word)\n"),
+	       idx, section_name (ebl, idx));
+
+      if (data->d_size < elsize)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': section group without flags word\n"),
+	       idx, section_name (ebl, idx));
+	  return;
+	}
+      else if (be_strict)
+	{
+	  if (data->d_size < 2 * elsize)
+	    ERROR (gettext ("\
+section [%2d] '%s': section group without member\n"),
+		   idx, section_name (ebl, idx));
+	  else if (data->d_size < 3 * elsize)
+	    ERROR (gettext ("\
+section [%2d] '%s': section group with only one member\n"),
+		   idx, section_name (ebl, idx));
+	}
+
+#if ALLOW_UNALIGNED
+      val = *((Elf32_Word *) data->d_buf);
+#else
+      memcpy (&val, data->d_buf, elsize);
+#endif
+      if ((val & ~GRP_COMDAT) != 0)
+	ERROR (gettext ("section [%2d] '%s': unknown section group flags\n"),
+	       idx, section_name (ebl, idx));
+
+      for (cnt = elsize; cnt < data->d_size; cnt += elsize)
+	{
+#if ALLOW_UNALIGNED
+	  val = *((Elf32_Word *) ((char *) data->d_buf + cnt));
+#else
+	  memcpy (&val, (char *) data->d_buf + cnt, elsize);
+#endif
+
+	  if (val > shnum)
+	    ERROR (gettext ("\
+section [%2d] '%s': section index %zu out of range\n"),
+		   idx, section_name (ebl, idx), cnt / elsize);
+	  else
+	    {
+	      GElf_Shdr refshdr_mem;
+	      GElf_Shdr *refshdr = gelf_getshdr (elf_getscn (ebl->elf, val),
+						 &refshdr_mem);
+	      if (refshdr == NULL)
+		ERROR (gettext ("\
+section [%2d] '%s': cannot get section header for element %zu: %s\n"),
+		       idx, section_name (ebl, idx), cnt / elsize,
+		       elf_errmsg (-1));
+	      else
+		{
+		  if (refshdr->sh_type == SHT_GROUP)
+		    ERROR (gettext ("\
+section [%2d] '%s': section group contains another group [%2d] '%s'\n"),
+			   idx, section_name (ebl, idx),
+			   val, section_name (ebl, val));
+
+		  if ((refshdr->sh_flags & SHF_GROUP) == 0)
+		    ERROR (gettext ("\
+section [%2d] '%s': element %zu references section [%2d] '%s' without SHF_GROUP flag set\n"),
+			   idx, section_name (ebl, idx), cnt / elsize,
+			   val, section_name (ebl, val));
+		}
+
+	      if (val < shnum && ++scnref[val] == 2)
+		ERROR (gettext ("\
+section [%2d] '%s' is contained in more than one section group\n"),
+		       val, section_name (ebl, val));
+	    }
+	}
+    }
+}
+
+
+static const char *
+section_flags_string (GElf_Word flags, char *buf, size_t len)
+{
+  if (flags == 0)
+    return "none";
+
+  static const struct
+  {
+    GElf_Word flag;
+    const char *name;
+  } known_flags[] =
+    {
+#define NEWFLAG(name) { SHF_##name, #name }
+      NEWFLAG (WRITE),
+      NEWFLAG (ALLOC),
+      NEWFLAG (EXECINSTR),
+      NEWFLAG (MERGE),
+      NEWFLAG (STRINGS),
+      NEWFLAG (INFO_LINK),
+      NEWFLAG (LINK_ORDER),
+      NEWFLAG (OS_NONCONFORMING),
+      NEWFLAG (GROUP),
+      NEWFLAG (TLS),
+      NEWFLAG (COMPRESSED)
+    };
+#undef NEWFLAG
+  const size_t nknown_flags = sizeof (known_flags) / sizeof (known_flags[0]);
+
+  char *cp = buf;
+
+  for (size_t cnt = 0; cnt < nknown_flags; ++cnt)
+    if (flags & known_flags[cnt].flag)
+      {
+	if (cp != buf && len > 1)
+	  {
+	    *cp++ = '|';
+	    --len;
+	  }
+
+	size_t ncopy = MIN (len - 1, strlen (known_flags[cnt].name));
+	cp = mempcpy (cp, known_flags[cnt].name, ncopy);
+	len -= ncopy;
+
+	flags ^= known_flags[cnt].flag;
+      }
+
+  if (flags != 0 || cp == buf)
+    snprintf (cp, len - 1, "%" PRIx64, (uint64_t) flags);
+
+  *cp = '\0';
+
+  return buf;
+}
+
+
+static int
+has_copy_reloc (Ebl *ebl, unsigned int symscnndx, unsigned int symndx)
+{
+  /* First find the relocation section for the symbol table.  */
+  Elf_Scn *scn = NULL;
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = NULL;
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr != NULL
+	  && (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+	  && shdr->sh_link == symscnndx)
+	/* Found the section.  */
+	break;
+    }
+
+  if (scn == NULL)
+    return 0;
+
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL || shdr->sh_entsize == 0)
+    return 0;
+
+  if (shdr->sh_type == SHT_REL)
+    for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i)
+      {
+	GElf_Rel rel_mem;
+	GElf_Rel *rel = gelf_getrel (data, i, &rel_mem);
+	if (rel == NULL)
+	  continue;
+
+	if (GELF_R_SYM (rel->r_info) == symndx
+	    && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rel->r_info)))
+	  return 1;
+      }
+  else
+    for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize; ++i)
+      {
+	GElf_Rela rela_mem;
+	GElf_Rela *rela = gelf_getrela (data, i, &rela_mem);
+	if (rela == NULL)
+	  continue;
+
+	if (GELF_R_SYM (rela->r_info) == symndx
+	    && ebl_copy_reloc_p (ebl, GELF_R_TYPE (rela->r_info)))
+	  return 1;
+      }
+
+  return 0;
+}
+
+
+static int
+in_nobits_scn (Ebl *ebl, unsigned int shndx)
+{
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, shndx), &shdr_mem);
+  return shdr != NULL && shdr->sh_type == SHT_NOBITS;
+}
+
+
+static struct version_namelist
+{
+  const char *objname;
+  const char *name;
+  GElf_Versym ndx;
+  enum { ver_def, ver_need } type;
+  struct version_namelist *next;
+} *version_namelist;
+
+
+static int
+add_version (const char *objname, const char *name, GElf_Versym ndx, int type)
+{
+  /* Check that there are no duplications.  */
+  struct version_namelist *nlp = version_namelist;
+  while (nlp != NULL)
+    {
+      if (((nlp->objname == NULL && objname == NULL)
+	   || (nlp->objname != NULL && objname != NULL
+	       && strcmp (nlp->objname, objname) == 0))
+	  && strcmp (nlp->name, name) == 0)
+	return nlp->type == ver_def ? 1 : -1;
+      nlp = nlp->next;
+    }
+
+  nlp = xmalloc (sizeof (*nlp));
+  nlp->objname = objname;
+  nlp->name = name;
+  nlp->ndx = ndx;
+  nlp->type = type;
+  nlp->next = version_namelist;
+  version_namelist = nlp;
+
+  return 0;
+}
+
+
+static void
+check_versym (Ebl *ebl, int idx)
+{
+  Elf_Scn *scn = elf_getscn (ebl->elf, idx);
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr == NULL)
+    /* The error has already been reported.  */
+    return;
+
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    {
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+  GElf_Shdr symshdr_mem;
+  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+  if (symshdr == NULL)
+    /* The error has already been reported.  */
+    return;
+
+  if (symshdr->sh_type != SHT_DYNSYM)
+    {
+      ERROR (gettext ("\
+section [%2d] '%s' refers in sh_link to section [%2d] '%s' which is no dynamic symbol table\n"),
+	     idx, section_name (ebl, idx),
+	     shdr->sh_link, section_name (ebl, shdr->sh_link));
+      return;
+    }
+
+  /* The number of elements in the version symbol table must be the
+     same as the number of symbols.  */
+  if (shdr->sh_entsize != 0 && symshdr->sh_entsize != 0
+      && (shdr->sh_size / shdr->sh_entsize
+	  != symshdr->sh_size / symshdr->sh_entsize))
+    ERROR (gettext ("\
+section [%2d] '%s' has different number of entries than symbol table [%2d] '%s'\n"),
+	   idx, section_name (ebl, idx),
+	   shdr->sh_link, section_name (ebl, shdr->sh_link));
+
+  Elf_Data *symdata = elf_getdata (symscn, NULL);
+  if (symdata == NULL || shdr->sh_entsize == 0)
+    /* The error has already been reported.  */
+    return;
+
+  for (int cnt = 1; (size_t) cnt < shdr->sh_size / shdr->sh_entsize; ++cnt)
+    {
+      GElf_Versym versym_mem;
+      GElf_Versym *versym = gelf_getversym (data, cnt, &versym_mem);
+      if (versym == NULL)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': symbol %d: cannot read version data\n"),
+		 idx, section_name (ebl, idx), cnt);
+	  break;
+	}
+
+      GElf_Sym sym_mem;
+      GElf_Sym *sym = gelf_getsym (symdata, cnt, &sym_mem);
+      if (sym == NULL)
+	/* Already reported elsewhere.  */
+	continue;
+
+      if (*versym == VER_NDX_GLOBAL)
+	{
+	  /* Global symbol.  Make sure it is not defined as local.  */
+	  if (GELF_ST_BIND (sym->st_info) == STB_LOCAL)
+	    ERROR (gettext ("\
+section [%2d] '%s': symbol %d: local symbol with global scope\n"),
+		   idx, section_name (ebl, idx), cnt);
+	}
+      else if (*versym != VER_NDX_LOCAL)
+	{
+	  /* Versioned symbol.  Make sure it is not defined as local.  */
+	  if (!gnuld && GELF_ST_BIND (sym->st_info) == STB_LOCAL)
+	    ERROR (gettext ("\
+section [%2d] '%s': symbol %d: local symbol with version\n"),
+		   idx, section_name (ebl, idx), cnt);
+
+	  /* Look through the list of defined versions and locate the
+	     index we need for this symbol.  */
+	  struct version_namelist *runp = version_namelist;
+	  while (runp != NULL)
+	    if (runp->ndx == (*versym & (GElf_Versym) 0x7fff))
+	      break;
+	    else
+	      runp = runp->next;
+
+	  if (runp == NULL)
+	    ERROR (gettext ("\
+section [%2d] '%s': symbol %d: invalid version index %d\n"),
+		   idx, section_name (ebl, idx), cnt, (int) *versym);
+	  else if (sym->st_shndx == SHN_UNDEF
+		   && runp->type == ver_def)
+	    ERROR (gettext ("\
+section [%2d] '%s': symbol %d: version index %d is for defined version\n"),
+		   idx, section_name (ebl, idx), cnt, (int) *versym);
+	  else if (sym->st_shndx != SHN_UNDEF
+		   && runp->type == ver_need)
+	    {
+	      /* Unless this symbol has a copy relocation associated
+		 this must not happen.  */
+	      if (!has_copy_reloc (ebl, shdr->sh_link, cnt)
+		  && !in_nobits_scn (ebl, sym->st_shndx))
+		ERROR (gettext ("\
+section [%2d] '%s': symbol %d: version index %d is for requested version\n"),
+		       idx, section_name (ebl, idx), cnt, (int) *versym);
+	    }
+	}
+    }
+}
+
+
+static int
+unknown_dependency_p (Elf *elf, const char *fname)
+{
+  GElf_Phdr phdr_mem;
+  GElf_Phdr *phdr = NULL;
+
+  unsigned int i;
+  for (i = 0; i < phnum; ++i)
+    if ((phdr = gelf_getphdr (elf, i, &phdr_mem)) != NULL
+	&& phdr->p_type == PT_DYNAMIC)
+      break;
+
+  if (i == phnum)
+    return 1;
+  assert (phdr != NULL);
+  Elf_Scn *scn = gelf_offscn (elf, phdr->p_offset);
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC
+      && data != NULL && shdr->sh_entsize != 0)
+    for (size_t j = 0; j < shdr->sh_size / shdr->sh_entsize; ++j)
+      {
+	GElf_Dyn dyn_mem;
+	GElf_Dyn *dyn = gelf_getdyn (data, j, &dyn_mem);
+	if (dyn != NULL && dyn->d_tag == DT_NEEDED)
+	  {
+	    const char *str = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val);
+	    if (str != NULL && strcmp (str, fname) == 0)
+	      /* Found it.  */
+	      return 0;
+	  }
+      }
+
+  return 1;
+}
+
+
+static unsigned int nverneed;
+
+static void
+check_verneed (Ebl *ebl, GElf_Shdr *shdr, int idx)
+{
+  if (++nverneed == 2)
+    ERROR (gettext ("more than one version reference section present\n"));
+
+  GElf_Shdr strshdr_mem;
+  GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+				     &strshdr_mem);
+  if (strshdr == NULL)
+    return;
+  if (strshdr->sh_type != SHT_STRTAB)
+    ERROR (gettext ("\
+section [%2d] '%s': sh_link does not link to string table\n"),
+	   idx, section_name (ebl, idx));
+
+  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+  if (data == NULL)
+    {
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+  unsigned int offset = 0;
+  for (Elf64_Word cnt = shdr->sh_info; cnt > 0; )
+    {
+      cnt--;
+
+      /* Get the data at the next offset.  */
+      GElf_Verneed needmem;
+      GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
+      if (need == NULL)
+	break;
+
+      unsigned int auxoffset = offset + need->vn_aux;
+
+      if (need->vn_version != EV_CURRENT)
+	ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong version %d\n"),
+	       idx, section_name (ebl, idx), cnt, (int) need->vn_version);
+
+      if (need->vn_cnt > 0 && need->vn_aux < gelf_fsize (ebl->elf, ELF_T_VNEED,
+							 1, EV_CURRENT))
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"),
+	         idx, section_name (ebl, idx), cnt);
+	  break;
+	}
+
+      const char *libname = elf_strptr (ebl->elf, shdr->sh_link,
+					need->vn_file);
+      if (libname == NULL)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': entry %d has invalid file reference\n"),
+		 idx, section_name (ebl, idx), cnt);
+	  goto next_need;
+	}
+
+      /* Check that there is a DT_NEEDED entry for the referenced library.  */
+      if (unknown_dependency_p (ebl->elf, libname))
+	ERROR (gettext ("\
+section [%2d] '%s': entry %d references unknown dependency\n"),
+	       idx, section_name (ebl, idx), cnt);
+
+      for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
+	{
+	  GElf_Vernaux auxmem;
+	  GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
+	  if (aux == NULL)
+	    break;
+
+	  if ((aux->vna_flags & ~VER_FLG_WEAK) != 0)
+	    ERROR (gettext ("\
+section [%2d] '%s': auxiliary entry %d of entry %d has unknown flag\n"),
+		   idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
+
+	  const char *verstr = elf_strptr (ebl->elf, shdr->sh_link,
+					   aux->vna_name);
+	  if (verstr == NULL)
+	    {
+	      ERROR (gettext ("\
+section [%2d] '%s': auxiliary entry %d of entry %d has invalid name reference\n"),
+		     idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
+	      break;
+	    }
+	  else
+	    {
+	      GElf_Word hashval = elf_hash (verstr);
+	      if (hashval != aux->vna_hash)
+		ERROR (gettext ("\
+section [%2d] '%s': auxiliary entry %d of entry %d has wrong hash value: %#x, expected %#x\n"),
+		       idx, section_name (ebl, idx), need->vn_cnt - cnt2,
+		       cnt, (int) hashval, (int) aux->vna_hash);
+
+	      int res = add_version (libname, verstr, aux->vna_other,
+				     ver_need);
+	      if (unlikely (res !=0))
+		{
+		  ERROR (gettext ("\
+section [%2d] '%s': auxiliary entry %d of entry %d has duplicate version name '%s'\n"),
+			 idx, section_name (ebl, idx), need->vn_cnt - cnt2,
+			 cnt, verstr);
+		}
+	    }
+
+	  if ((aux->vna_next != 0 || cnt2 > 0)
+	      && aux->vna_next < gelf_fsize (ebl->elf, ELF_T_VNAUX, 1,
+					     EV_CURRENT))
+	    {
+	      ERROR (gettext ("\
+section [%2d] '%s': auxiliary entry %d of entry %d has wrong next field\n"),
+		     idx, section_name (ebl, idx), need->vn_cnt - cnt2, cnt);
+	      break;
+	    }
+
+	  auxoffset += MAX (aux->vna_next,
+			    gelf_fsize (ebl->elf, ELF_T_VNAUX, 1, EV_CURRENT));
+	}
+
+      /* Find the next offset.  */
+    next_need:
+      offset += need->vn_next;
+
+      if ((need->vn_next != 0 || cnt > 0)
+	  && offset < auxoffset)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': entry %d has invalid offset to next entry\n"),
+	         idx, section_name (ebl, idx), cnt);
+	  break;
+	}
+
+      if (need->vn_next == 0 && cnt > 0)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says there are more entries\n"),
+	         idx, section_name (ebl, idx), cnt);
+	  break;
+	}
+    }
+}
+
+
+static unsigned int nverdef;
+
+static void
+check_verdef (Ebl *ebl, GElf_Shdr *shdr, int idx)
+{
+  if (++nverdef == 2)
+    ERROR (gettext ("more than one version definition section present\n"));
+
+  GElf_Shdr strshdr_mem;
+  GElf_Shdr *strshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+				     &strshdr_mem);
+  if (strshdr == NULL)
+    return;
+  if (strshdr->sh_type != SHT_STRTAB)
+    ERROR (gettext ("\
+section [%2d] '%s': sh_link does not link to string table\n"),
+	   idx, section_name (ebl, idx));
+
+  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+  if (data == NULL)
+    {
+    no_data:
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  /* Iterate over all version definition entries.  We check that there
+     is a BASE entry and that each index is unique.  To do the later
+     we collection the information in a list which is later
+     examined.  */
+  struct namelist
+  {
+    const char *name;
+    struct namelist *next;
+  } *namelist = NULL;
+  struct namelist *refnamelist = NULL;
+
+  bool has_base = false;
+  unsigned int offset = 0;
+  for (Elf64_Word cnt = shdr->sh_info; cnt > 0; )
+    {
+      cnt--;
+
+      /* Get the data at the next offset.  */
+      GElf_Verdef defmem;
+      GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
+      if (def == NULL)
+	goto no_data;
+
+      if ((def->vd_flags & VER_FLG_BASE) != 0)
+	{
+	  if (has_base)
+	    ERROR (gettext ("\
+section [%2d] '%s': more than one BASE definition\n"),
+		   idx, section_name (ebl, idx));
+	  if (def->vd_ndx != VER_NDX_GLOBAL)
+	    ERROR (gettext ("\
+section [%2d] '%s': BASE definition must have index VER_NDX_GLOBAL\n"),
+		   idx, section_name (ebl, idx));
+	  has_base = true;
+	}
+      if ((def->vd_flags & ~(VER_FLG_BASE|VER_FLG_WEAK)) != 0)
+	ERROR (gettext ("\
+section [%2d] '%s': entry %d has unknown flag\n"),
+	       idx, section_name (ebl, idx), cnt);
+
+      if (def->vd_version != EV_CURRENT)
+	ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong version %d\n"),
+	       idx, section_name (ebl, idx), cnt, (int) def->vd_version);
+
+      if (def->vd_cnt > 0 && def->vd_aux < gelf_fsize (ebl->elf, ELF_T_VDEF,
+						       1, EV_CURRENT))
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong offset of auxiliary data\n"),
+	         idx, section_name (ebl, idx), cnt);
+	  break;
+	}
+
+      unsigned int auxoffset = offset + def->vd_aux;
+      GElf_Verdaux auxmem;
+      GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
+      if (aux == NULL)
+	goto no_data;
+
+      const char *name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name);
+      if (name == NULL)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': entry %d has invalid name reference\n"),
+		 idx, section_name (ebl, idx), cnt);
+	  goto next_def;
+	}
+      GElf_Word hashval = elf_hash (name);
+      if (def->vd_hash != hashval)
+	ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong hash value: %#x, expected %#x\n"),
+	       idx, section_name (ebl, idx), cnt, (int) hashval,
+	       (int) def->vd_hash);
+
+      int res = add_version (NULL, name, def->vd_ndx, ver_def);
+      if (unlikely (res !=0))
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': entry %d has duplicate version name '%s'\n"),
+		 idx, section_name (ebl, idx), cnt, name);
+	}
+
+      struct namelist *newname = alloca (sizeof (*newname));
+      newname->name = name;
+      newname->next = namelist;
+      namelist = newname;
+
+      auxoffset += aux->vda_next;
+      for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
+	{
+	  aux = gelf_getverdaux (data, auxoffset, &auxmem);
+	  if (aux == NULL)
+	    goto no_data;
+
+	  name = elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name);
+	  if (name == NULL)
+	    {
+	      ERROR (gettext ("\
+section [%2d] '%s': entry %d has invalid name reference in auxiliary data\n"),
+		     idx, section_name (ebl, idx), cnt);
+	      break;
+	    }
+	  else
+	    {
+	      newname = alloca (sizeof (*newname));
+	      newname->name = name;
+	      newname->next = refnamelist;
+	      refnamelist = newname;
+	    }
+
+	  if ((aux->vda_next != 0 || cnt2 + 1 < def->vd_cnt)
+	      && aux->vda_next < gelf_fsize (ebl->elf, ELF_T_VDAUX, 1,
+					     EV_CURRENT))
+	    {
+	      ERROR (gettext ("\
+section [%2d] '%s': entry %d has wrong next field in auxiliary data\n"),
+		     idx, section_name (ebl, idx), cnt);
+	      break;
+	    }
+
+	  auxoffset += MAX (aux->vda_next,
+			    gelf_fsize (ebl->elf, ELF_T_VDAUX, 1, EV_CURRENT));
+	}
+
+      /* Find the next offset.  */
+    next_def:
+      offset += def->vd_next;
+
+      if ((def->vd_next != 0 || cnt > 0)
+	  && offset < auxoffset)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': entry %d has invalid offset to next entry\n"),
+	         idx, section_name (ebl, idx), cnt);
+	  break;
+	}
+
+      if (def->vd_next == 0 && cnt > 0)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': entry %d has zero offset to next entry, but sh_info says there are more entries\n"),
+	         idx, section_name (ebl, idx), cnt);
+	  break;
+	}
+    }
+
+  if (!has_base)
+    ERROR (gettext ("section [%2d] '%s': no BASE definition\n"),
+	   idx, section_name (ebl, idx));
+
+  /* Check whether the referenced names are available.  */
+  while (namelist != NULL)
+    {
+      struct version_namelist *runp = version_namelist;
+      while (runp != NULL)
+	{
+	  if (runp->type == ver_def
+	      && strcmp (runp->name, namelist->name) == 0)
+	    break;
+	  runp = runp->next;
+	}
+
+      if (runp == NULL)
+	ERROR (gettext ("\
+section [%2d] '%s': unknown parent version '%s'\n"),
+	       idx, section_name (ebl, idx), namelist->name);
+
+      namelist = namelist->next;
+    }
+}
+
+static void
+check_attributes (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
+{
+  if (shdr->sh_size == 0)
+    {
+      ERROR (gettext ("section [%2d] '%s': empty object attributes section\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  Elf_Data *data = elf_rawdata (elf_getscn (ebl->elf, idx), NULL);
+  if (data == NULL || data->d_size == 0 || data->d_buf == NULL)
+    {
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  inline size_t pos (const unsigned char *p)
+  {
+    return p - (const unsigned char *) data->d_buf;
+  }
+
+  const unsigned char *p = data->d_buf;
+  if (*p++ != 'A')
+    {
+      ERROR (gettext ("section [%2d] '%s': unrecognized attribute format\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  inline size_t left (void)
+  {
+    return (const unsigned char *) data->d_buf + data->d_size - p;
+  }
+
+  while (left () >= 4)
+    {
+      uint32_t len;
+      memcpy (&len, p, sizeof len);
+
+      if (len == 0)
+	ERROR (gettext ("\
+section [%2d] '%s': offset %zu: zero length field in attribute section\n"),
+	       idx, section_name (ebl, idx), pos (p));
+
+      if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
+	CONVERT (len);
+
+      if (len > left ())
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': offset %zu: invalid length in attribute section\n"),
+		 idx, section_name (ebl, idx), pos (p));
+	  break;
+	}
+
+      const unsigned char *name = p + sizeof len;
+      p += len;
+
+      unsigned const char *q = memchr (name, '\0', len);
+      if (q == NULL)
+	{
+	  ERROR (gettext ("\
+section [%2d] '%s': offset %zu: unterminated vendor name string\n"),
+		 idx, section_name (ebl, idx), pos (p));
+	  break;
+	}
+      ++q;
+
+      if (q - name == sizeof "gnu" && !memcmp (name, "gnu", sizeof "gnu"))
+	while (q < p)
+	  {
+	    unsigned const char *chunk = q;
+
+	    unsigned int subsection_tag;
+	    get_uleb128 (subsection_tag, q, p);
+
+	    if (q >= p)
+	      {
+		ERROR (gettext ("\
+section [%2d] '%s': offset %zu: endless ULEB128 in attribute subsection tag\n"),
+		       idx, section_name (ebl, idx), pos (chunk));
+		break;
+	      }
+
+	    uint32_t subsection_len;
+	    if (p - q < (ptrdiff_t) sizeof subsection_len)
+	      {
+		ERROR (gettext ("\
+section [%2d] '%s': offset %zu: truncated attribute section\n"),
+		       idx, section_name (ebl, idx), pos (q));
+		break;
+	      }
+
+	    memcpy (&subsection_len, q, sizeof subsection_len);
+	    if (subsection_len == 0)
+	      {
+		ERROR (gettext ("\
+section [%2d] '%s': offset %zu: zero length field in attribute subsection\n"),
+		       idx, section_name (ebl, idx), pos (q));
+
+		q += sizeof subsection_len;
+		continue;
+	      }
+
+	    if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
+	      CONVERT (subsection_len);
+
+	    /* Don't overflow, ptrdiff_t might be 32bits, but signed.  */
+	    if (p - chunk < (ptrdiff_t) subsection_len
+	        || subsection_len >= (uint32_t) PTRDIFF_MAX)
+	      {
+		ERROR (gettext ("\
+section [%2d] '%s': offset %zu: invalid length in attribute subsection\n"),
+		       idx, section_name (ebl, idx), pos (q));
+		break;
+	      }
+
+	    const unsigned char *subsection_end = chunk + subsection_len;
+	    chunk = q;
+	    q = subsection_end;
+
+	    if (subsection_tag != 1) /* Tag_File */
+	      ERROR (gettext ("\
+section [%2d] '%s': offset %zu: attribute subsection has unexpected tag %u\n"),
+		     idx, section_name (ebl, idx), pos (chunk), subsection_tag);
+	    else
+	      {
+		chunk += sizeof subsection_len;
+		while (chunk < q)
+		  {
+		    unsigned int tag;
+		    get_uleb128 (tag, chunk, q);
+
+		    uint64_t value = 0;
+		    const unsigned char *r = chunk;
+		    if (tag == 32 || (tag & 1) == 0)
+		      {
+			get_uleb128 (value, r, q);
+			if (r > q)
+			  {
+			    ERROR (gettext ("\
+section [%2d] '%s': offset %zu: endless ULEB128 in attribute tag\n"),
+				   idx, section_name (ebl, idx), pos (chunk));
+			    break;
+			  }
+		      }
+		    if (tag == 32 || (tag & 1) != 0)
+		      {
+			r = memchr (r, '\0', q - r);
+			if (r == NULL)
+			  {
+			    ERROR (gettext ("\
+section [%2d] '%s': offset %zu: unterminated string in attribute\n"),
+				   idx, section_name (ebl, idx), pos (chunk));
+			    break;
+			  }
+			++r;
+		      }
+
+		    const char *tag_name = NULL;
+		    const char *value_name = NULL;
+		    if (!ebl_check_object_attribute (ebl, (const char *) name,
+						     tag, value,
+						     &tag_name, &value_name))
+		      ERROR (gettext ("\
+section [%2d] '%s': offset %zu: unrecognized attribute tag %u\n"),
+			     idx, section_name (ebl, idx), pos (chunk), tag);
+		    else if ((tag & 1) == 0 && value_name == NULL)
+		      ERROR (gettext ("\
+section [%2d] '%s': offset %zu: unrecognized %s attribute value %" PRIu64 "\n"),
+			     idx, section_name (ebl, idx), pos (chunk),
+			     tag_name, value);
+
+		    chunk = r;
+		  }
+	      }
+	  }
+      else
+	ERROR (gettext ("\
+section [%2d] '%s': offset %zu: vendor '%s' unknown\n"),
+	       idx, section_name (ebl, idx), pos (p), name);
+    }
+
+  if (left () != 0)
+    ERROR (gettext ("\
+section [%2d] '%s': offset %zu: extra bytes after last attribute section\n"),
+	   idx, section_name (ebl, idx), pos (p));
+}
+
+static bool has_loadable_segment;
+static bool has_interp_segment;
+
+static const struct
+{
+  const char *name;
+  size_t namelen;
+  GElf_Word type;
+  enum { unused, exact, atleast, exact_or_gnuld } attrflag;
+  GElf_Word attr;
+  GElf_Word attr2;
+} special_sections[] =
+  {
+    /* See figure 4-14 in the gABI.  */
+    { ".bss", 5, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
+    { ".comment", 8, SHT_PROGBITS, atleast, 0, SHF_MERGE | SHF_STRINGS },
+    { ".data", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
+    { ".data1", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE, 0 },
+    { ".debug_str", 11, SHT_PROGBITS, exact_or_gnuld, SHF_MERGE | SHF_STRINGS, 0 },
+    { ".debug", 6, SHT_PROGBITS, exact, 0, 0 },
+    { ".dynamic", 9, SHT_DYNAMIC, atleast, SHF_ALLOC, SHF_WRITE },
+    { ".dynstr", 8, SHT_STRTAB, exact, SHF_ALLOC, 0 },
+    { ".dynsym", 8, SHT_DYNSYM, exact, SHF_ALLOC, 0 },
+    { ".fini", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
+    { ".fini_array", 12, SHT_FINI_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
+    { ".got", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more info?
+    { ".hash", 6, SHT_HASH, exact, SHF_ALLOC, 0 },
+    { ".init", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
+    { ".init_array", 12, SHT_INIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
+    { ".interp", 8, SHT_PROGBITS, atleast, 0, SHF_ALLOC }, // XXX more tests?
+    { ".line", 6, SHT_PROGBITS, exact, 0, 0 },
+    { ".note", 6, SHT_NOTE, atleast, 0, SHF_ALLOC },
+    { ".plt", 5, SHT_PROGBITS, unused, 0, 0 }, // XXX more tests
+    { ".preinit_array", 15, SHT_PREINIT_ARRAY, exact, SHF_ALLOC | SHF_WRITE, 0 },
+    { ".rela", 5, SHT_RELA, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests
+    { ".rel", 4, SHT_REL, atleast, 0, SHF_ALLOC | SHF_INFO_LINK }, // XXX more tests
+    { ".rodata", 8, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS },
+    { ".rodata1", 9, SHT_PROGBITS, atleast, SHF_ALLOC, SHF_MERGE | SHF_STRINGS },
+    { ".shstrtab", 10, SHT_STRTAB, exact, 0, 0 },
+    { ".strtab", 8, SHT_STRTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
+    { ".symtab", 8, SHT_SYMTAB, atleast, 0, SHF_ALLOC }, // XXX more tests
+    { ".symtab_shndx", 14, SHT_SYMTAB_SHNDX, atleast, 0, SHF_ALLOC }, // XXX more tests
+    { ".tbss", 6, SHT_NOBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
+    { ".tdata", 7, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
+    { ".tdata1", 8, SHT_PROGBITS, exact, SHF_ALLOC | SHF_WRITE | SHF_TLS, 0 },
+    { ".text", 6, SHT_PROGBITS, exact, SHF_ALLOC | SHF_EXECINSTR, 0 },
+
+    /* The following are GNU extensions.  */
+    { ".gnu.version", 13, SHT_GNU_versym, exact, SHF_ALLOC, 0 },
+    { ".gnu.version_d", 15, SHT_GNU_verdef, exact, SHF_ALLOC, 0 },
+    { ".gnu.version_r", 15, SHT_GNU_verneed, exact, SHF_ALLOC, 0 },
+    { ".gnu.attributes", 16, SHT_GNU_ATTRIBUTES, exact, 0, 0 },
+  };
+#define nspecial_sections \
+  (sizeof (special_sections) / sizeof (special_sections[0]))
+
+#define IS_KNOWN_SPECIAL(idx, string, prefix)			      \
+  (special_sections[idx].namelen == sizeof string - (prefix ? 1 : 0)  \
+   && !memcmp (special_sections[idx].name, string, \
+	       sizeof string - (prefix ? 1 : 0)))
+
+
+/* Indeces of some sections we need later.  */
+static size_t eh_frame_hdr_scnndx;
+static size_t eh_frame_scnndx;
+static size_t gcc_except_table_scnndx;
+
+
+static void
+check_sections (Ebl *ebl, GElf_Ehdr *ehdr)
+{
+  if (ehdr->e_shoff == 0)
+    /* No section header.  */
+    return;
+
+  /* Allocate array to count references in section groups.  */
+  scnref = (int *) xcalloc (shnum, sizeof (int));
+
+  /* Check the zeroth section first.  It must not have any contents
+     and the section header must contain nonzero value at most in the
+     sh_size and sh_link fields.  */
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
+  if (shdr == NULL)
+    ERROR (gettext ("cannot get section header of zeroth section\n"));
+  else
+    {
+      if (shdr->sh_name != 0)
+	ERROR (gettext ("zeroth section has nonzero name\n"));
+      if (shdr->sh_type != 0)
+	ERROR (gettext ("zeroth section has nonzero type\n"));
+      if (shdr->sh_flags != 0)
+	ERROR (gettext ("zeroth section has nonzero flags\n"));
+      if (shdr->sh_addr != 0)
+	ERROR (gettext ("zeroth section has nonzero address\n"));
+      if (shdr->sh_offset != 0)
+	ERROR (gettext ("zeroth section has nonzero offset\n"));
+      if (shdr->sh_addralign != 0)
+	ERROR (gettext ("zeroth section has nonzero align value\n"));
+      if (shdr->sh_entsize != 0)
+	ERROR (gettext ("zeroth section has nonzero entry size value\n"));
+
+      if (shdr->sh_size != 0 && ehdr->e_shnum != 0)
+	ERROR (gettext ("\
+zeroth section has nonzero size value while ELF header has nonzero shnum value\n"));
+
+      if (shdr->sh_link != 0 && ehdr->e_shstrndx != SHN_XINDEX)
+	ERROR (gettext ("\
+zeroth section has nonzero link value while ELF header does not signal overflow in shstrndx\n"));
+
+      if (shdr->sh_info != 0 && ehdr->e_phnum != PN_XNUM)
+	ERROR (gettext ("\
+zeroth section has nonzero link value while ELF header does not signal overflow in phnum\n"));
+    }
+
+  int *segment_flags = xcalloc (phnum, sizeof segment_flags[0]);
+
+  bool dot_interp_section = false;
+
+  size_t hash_idx = 0;
+  size_t gnu_hash_idx = 0;
+
+  size_t versym_scnndx = 0;
+  for (size_t cnt = 1; cnt < shnum; ++cnt)
+    {
+      Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
+      shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  ERROR (gettext ("\
+cannot get section header for section [%2zu] '%s': %s\n"),
+		 cnt, section_name (ebl, cnt), elf_errmsg (-1));
+	  continue;
+	}
+
+      const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
+
+      if (scnname == NULL)
+	ERROR (gettext ("section [%2zu]: invalid name\n"), cnt);
+      else
+	{
+	  /* Check whether it is one of the special sections defined in
+	     the gABI.  */
+	  size_t s;
+	  for (s = 0; s < nspecial_sections; ++s)
+	    if (strncmp (scnname, special_sections[s].name,
+			 special_sections[s].namelen) == 0)
+	      {
+		char stbuf1[100];
+		char stbuf2[100];
+		char stbuf3[100];
+
+		GElf_Word good_type = special_sections[s].type;
+		if (IS_KNOWN_SPECIAL (s, ".plt", false)
+		    && ebl_bss_plt_p (ebl))
+		  good_type = SHT_NOBITS;
+
+		/* In a debuginfo file, any normal section can be SHT_NOBITS.
+		   This is only invalid for DWARF sections and .shstrtab.  */
+		if (shdr->sh_type != good_type
+		    && (shdr->sh_type != SHT_NOBITS
+			|| !is_debuginfo
+			|| IS_KNOWN_SPECIAL (s, ".debug_str", false)
+			|| IS_KNOWN_SPECIAL (s, ".debug", true)
+			|| IS_KNOWN_SPECIAL (s, ".shstrtab", false)))
+		  ERROR (gettext ("\
+section [%2d] '%s' has wrong type: expected %s, is %s\n"),
+			 (int) cnt, scnname,
+			 ebl_section_type_name (ebl, special_sections[s].type,
+						stbuf1, sizeof (stbuf1)),
+			 ebl_section_type_name (ebl, shdr->sh_type,
+						stbuf2, sizeof (stbuf2)));
+
+		if (special_sections[s].attrflag == exact
+		    || special_sections[s].attrflag == exact_or_gnuld)
+		  {
+		    /* Except for the link order, group bit and
+		       compression flag all the other bits should
+		       match exactly.  */
+		    if ((shdr->sh_flags
+			 & ~(SHF_LINK_ORDER | SHF_GROUP | SHF_COMPRESSED))
+			!= special_sections[s].attr
+			&& (special_sections[s].attrflag == exact || !gnuld))
+		      ERROR (gettext ("\
+section [%2zu] '%s' has wrong flags: expected %s, is %s\n"),
+			     cnt, scnname,
+			     section_flags_string (special_sections[s].attr,
+						   stbuf1, sizeof (stbuf1)),
+			     section_flags_string (shdr->sh_flags
+						   & ~SHF_LINK_ORDER,
+						   stbuf2, sizeof (stbuf2)));
+		  }
+		else if (special_sections[s].attrflag == atleast)
+		  {
+		    if ((shdr->sh_flags & special_sections[s].attr)
+			!= special_sections[s].attr
+			|| ((shdr->sh_flags
+			     & ~(SHF_LINK_ORDER | SHF_GROUP | SHF_COMPRESSED
+				 | special_sections[s].attr
+				 | special_sections[s].attr2))
+			    != 0))
+		      ERROR (gettext ("\
+section [%2zu] '%s' has wrong flags: expected %s and possibly %s, is %s\n"),
+			     cnt, scnname,
+			     section_flags_string (special_sections[s].attr,
+						   stbuf1, sizeof (stbuf1)),
+			     section_flags_string (special_sections[s].attr2,
+						   stbuf2, sizeof (stbuf2)),
+			     section_flags_string (shdr->sh_flags
+						   & ~(SHF_LINK_ORDER
+						       | SHF_GROUP),
+						   stbuf3, sizeof (stbuf3)));
+		  }
+
+		if (strcmp (scnname, ".interp") == 0)
+		  {
+		    dot_interp_section = true;
+
+		    if (ehdr->e_type == ET_REL)
+		      ERROR (gettext ("\
+section [%2zu] '%s' present in object file\n"),
+			     cnt, scnname);
+
+		    if ((shdr->sh_flags & SHF_ALLOC) != 0
+			&& !has_loadable_segment)
+		      ERROR (gettext ("\
+section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"),
+			     cnt, scnname);
+		    else if ((shdr->sh_flags & SHF_ALLOC) == 0
+			     && has_loadable_segment)
+		      ERROR (gettext ("\
+section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"),
+			     cnt, scnname);
+		  }
+		else
+		  {
+		    if (strcmp (scnname, ".symtab_shndx") == 0
+			&& ehdr->e_type != ET_REL)
+		      ERROR (gettext ("\
+section [%2zu] '%s' is extension section index table in non-object file\n"),
+			     cnt, scnname);
+
+		    /* These sections must have the SHF_ALLOC flag set iff
+		       a loadable segment is available.
+
+		       .relxxx
+		       .strtab
+		       .symtab
+		       .symtab_shndx
+
+		       Check that if there is a reference from the
+		       loaded section these sections also have the
+		       ALLOC flag set.  */
+#if 0
+		    // XXX TODO
+		    if ((shdr->sh_flags & SHF_ALLOC) != 0
+			&& !has_loadable_segment)
+		      ERROR (gettext ("\
+section [%2zu] '%s' has SHF_ALLOC flag set but there is no loadable segment\n"),
+			     cnt, scnname);
+		    else if ((shdr->sh_flags & SHF_ALLOC) == 0
+			     && has_loadable_segment)
+		      ERROR (gettext ("\
+section [%2zu] '%s' has SHF_ALLOC flag not set but there are loadable segments\n"),
+			     cnt, scnname);
+#endif
+		  }
+
+		break;
+	      }
+
+	  /* Remember a few special sections for later.  */
+	  if (strcmp (scnname, ".eh_frame_hdr") == 0)
+	    eh_frame_hdr_scnndx = cnt;
+	  else if (strcmp (scnname, ".eh_frame") == 0)
+	    eh_frame_scnndx = cnt;
+	  else if (strcmp (scnname, ".gcc_except_table") == 0)
+	    gcc_except_table_scnndx = cnt;
+	}
+
+      if (shdr->sh_entsize != 0 && shdr->sh_size % shdr->sh_entsize)
+	ERROR (gettext ("\
+section [%2zu] '%s': size not multiple of entry size\n"),
+	       cnt, section_name (ebl, cnt));
+
+      if (elf_strptr (ebl->elf, shstrndx, shdr->sh_name) == NULL)
+	ERROR (gettext ("cannot get section header\n"));
+
+      if (shdr->sh_type >= SHT_NUM
+	  && shdr->sh_type != SHT_GNU_ATTRIBUTES
+	  && shdr->sh_type != SHT_GNU_LIBLIST
+	  && shdr->sh_type != SHT_CHECKSUM
+	  && shdr->sh_type != SHT_GNU_verdef
+	  && shdr->sh_type != SHT_GNU_verneed
+	  && shdr->sh_type != SHT_GNU_versym
+	  && ebl_section_type_name (ebl, shdr->sh_type, NULL, 0) == NULL)
+	ERROR (gettext ("section [%2zu] '%s' has unsupported type %d\n"),
+	       cnt, section_name (ebl, cnt),
+	       (int) shdr->sh_type);
+
+#define ALL_SH_FLAGS (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_MERGE \
+		      | SHF_STRINGS | SHF_INFO_LINK | SHF_LINK_ORDER \
+		      | SHF_OS_NONCONFORMING | SHF_GROUP | SHF_TLS \
+		      | SHF_COMPRESSED)
+      if (shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS)
+	{
+	  GElf_Xword sh_flags = shdr->sh_flags & ~(GElf_Xword) ALL_SH_FLAGS;
+	  if (sh_flags & SHF_MASKPROC)
+	    {
+	      if (!ebl_machine_section_flag_check (ebl,
+						   sh_flags & SHF_MASKPROC))
+		ERROR (gettext ("section [%2zu] '%s'"
+				" contains invalid processor-specific flag(s)"
+				" %#" PRIx64 "\n"),
+		       cnt, section_name (ebl, cnt), sh_flags & SHF_MASKPROC);
+	      sh_flags &= ~(GElf_Xword) SHF_MASKPROC;
+	    }
+	  if (sh_flags != 0)
+	    ERROR (gettext ("section [%2zu] '%s' contains unknown flag(s)"
+			    " %#" PRIx64 "\n"),
+		   cnt, section_name (ebl, cnt), sh_flags);
+	}
+      if (shdr->sh_flags & SHF_TLS)
+	{
+	  // XXX Correct?
+	  if (shdr->sh_addr != 0 && !gnuld)
+	    ERROR (gettext ("\
+section [%2zu] '%s': thread-local data sections address not zero\n"),
+		   cnt, section_name (ebl, cnt));
+
+	  // XXX TODO more tests!?
+	}
+
+      if (shdr->sh_flags & SHF_COMPRESSED)
+	{
+	  if (shdr->sh_flags & SHF_ALLOC)
+	    ERROR (gettext ("\
+section [%2zu] '%s': allocated section cannot be compressed\n"),
+		   cnt, section_name (ebl, cnt));
+
+	  if (shdr->sh_type == SHT_NOBITS)
+	    ERROR (gettext ("\
+section [%2zu] '%s': nobits section cannot be compressed\n"),
+		   cnt, section_name (ebl, cnt));
+
+	  GElf_Chdr chdr;
+	  if (gelf_getchdr (scn, &chdr) == NULL)
+	    ERROR (gettext ("\
+section [%2zu] '%s': compressed section with no compression header: %s\n"),
+		   cnt, section_name (ebl, cnt), elf_errmsg (-1));
+	}
+
+      if (shdr->sh_link >= shnum)
+	ERROR (gettext ("\
+section [%2zu] '%s': invalid section reference in link value\n"),
+	       cnt, section_name (ebl, cnt));
+
+      if (SH_INFO_LINK_P (shdr) && shdr->sh_info >= shnum)
+	ERROR (gettext ("\
+section [%2zu] '%s': invalid section reference in info value\n"),
+	       cnt, section_name (ebl, cnt));
+
+      if ((shdr->sh_flags & SHF_MERGE) == 0
+	  && (shdr->sh_flags & SHF_STRINGS) != 0
+	  && be_strict)
+	ERROR (gettext ("\
+section [%2zu] '%s': strings flag set without merge flag\n"),
+	       cnt, section_name (ebl, cnt));
+
+      if ((shdr->sh_flags & SHF_MERGE) != 0 && shdr->sh_entsize == 0)
+	ERROR (gettext ("\
+section [%2zu] '%s': merge flag set but entry size is zero\n"),
+	       cnt, section_name (ebl, cnt));
+
+      if (shdr->sh_flags & SHF_GROUP)
+	check_scn_group (ebl, cnt);
+
+      if (shdr->sh_flags & SHF_EXECINSTR)
+	{
+	  switch (shdr->sh_type)
+	    {
+	    case SHT_PROGBITS:
+	      break;
+
+	    case SHT_NOBITS:
+	      if (is_debuginfo)
+		break;
+	      FALLTHROUGH;
+	    default:
+	      ERROR (gettext ("\
+section [%2zu] '%s' has unexpected type %d for an executable section\n"),
+		     cnt, section_name (ebl, cnt), shdr->sh_type);
+	      break;
+	    }
+
+	  if (shdr->sh_flags & SHF_WRITE)
+	    {
+	      if (is_debuginfo && shdr->sh_type != SHT_NOBITS)
+		ERROR (gettext ("\
+section [%2zu] '%s' must be of type NOBITS in debuginfo files\n"),
+		       cnt, section_name (ebl, cnt));
+
+	      if (!is_debuginfo
+		  && !ebl_check_special_section (ebl, cnt, shdr,
+						 section_name (ebl, cnt)))
+		ERROR (gettext ("\
+section [%2zu] '%s' is both executable and writable\n"),
+		       cnt, section_name (ebl, cnt));
+	    }
+	}
+
+      if (ehdr->e_type != ET_REL && (shdr->sh_flags & SHF_ALLOC) != 0
+	  && !is_debuginfo)
+	{
+	  /* Make sure the section is contained in a loaded segment
+	     and that the initialization part matches NOBITS sections.  */
+	  unsigned int pcnt;
+	  GElf_Phdr phdr_mem;
+	  GElf_Phdr *phdr;
+
+	  for (pcnt = 0; pcnt < phnum; ++pcnt)
+	    if ((phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem)) != NULL
+		&& ((phdr->p_type == PT_LOAD
+		     && (shdr->sh_flags & SHF_TLS) == 0)
+		    || (phdr->p_type == PT_TLS
+			&& (shdr->sh_flags & SHF_TLS) != 0))
+		&& phdr->p_offset <= shdr->sh_offset
+		&& ((shdr->sh_offset - phdr->p_offset <= phdr->p_filesz
+		     && (shdr->sh_offset - phdr->p_offset < phdr->p_filesz
+			 || shdr->sh_size == 0))
+		    || (shdr->sh_offset - phdr->p_offset < phdr->p_memsz
+			&& shdr->sh_type == SHT_NOBITS)))
+	      {
+		/* Found the segment.  */
+		if (phdr->p_offset + phdr->p_memsz
+		    < shdr->sh_offset + shdr->sh_size)
+		  ERROR (gettext ("\
+section [%2zu] '%s' not fully contained in segment of program header entry %d\n"),
+			 cnt, section_name (ebl, cnt), pcnt);
+
+		if (shdr->sh_type == SHT_NOBITS)
+		  {
+		    if (shdr->sh_offset < phdr->p_offset + phdr->p_filesz
+			&& !is_debuginfo)
+		      {
+			if (!gnuld)
+			  ERROR (gettext ("\
+section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d\n"),
+				 cnt, section_name (ebl, cnt), pcnt);
+			else
+			  {
+			    /* This is truly horrible. GNU ld might put a
+			       NOBITS section in the middle of a PT_LOAD
+			       segment, assuming the next gap in the file
+			       actually consists of zero bits...
+			       So it really is like a PROGBITS section
+			       where the data is all zeros.  Check those
+			       zero bytes are really there.  */
+			    bool bad;
+			    Elf_Data *databits;
+			    databits = elf_getdata_rawchunk (ebl->elf,
+							     shdr->sh_offset,
+							     shdr->sh_size,
+							     ELF_T_BYTE);
+			    bad = (databits == NULL
+				   || databits->d_size != shdr->sh_size);
+			    for (size_t idx = 0;
+				 idx < databits->d_size && ! bad;
+				 idx++)
+			      bad = ((char *) databits->d_buf)[idx] != 0;
+
+			    if (bad)
+			      ERROR (gettext ("\
+section [%2zu] '%s' has type NOBITS but is read from the file in segment of program header entry %d and file contents is non-zero\n"),
+				     cnt, section_name (ebl, cnt), pcnt);
+			  }
+		      }
+		  }
+		else
+		  {
+		    const GElf_Off end = phdr->p_offset + phdr->p_filesz;
+		    if (shdr->sh_offset > end ||
+			(shdr->sh_offset == end && shdr->sh_size != 0))
+		      ERROR (gettext ("\
+section [%2zu] '%s' has not type NOBITS but is not read from the file in segment of program header entry %d\n"),
+			 cnt, section_name (ebl, cnt), pcnt);
+		  }
+
+		if (shdr->sh_type != SHT_NOBITS)
+		  {
+		    if ((shdr->sh_flags & SHF_EXECINSTR) != 0)
+		      {
+			segment_flags[pcnt] |= PF_X;
+			if ((phdr->p_flags & PF_X) == 0)
+			  ERROR (gettext ("\
+section [%2zu] '%s' is executable in nonexecutable segment %d\n"),
+				 cnt, section_name (ebl, cnt), pcnt);
+		      }
+
+		    if ((shdr->sh_flags & SHF_WRITE) != 0)
+		      {
+			segment_flags[pcnt] |= PF_W;
+			if (0	/* XXX vdso images have this */
+			    && (phdr->p_flags & PF_W) == 0)
+			  ERROR (gettext ("\
+section [%2zu] '%s' is writable in unwritable segment %d\n"),
+				 cnt, section_name (ebl, cnt), pcnt);
+		      }
+		  }
+
+		break;
+	      }
+
+	  if (pcnt == phnum)
+	    ERROR (gettext ("\
+section [%2zu] '%s': alloc flag set but section not in any loaded segment\n"),
+		   cnt, section_name (ebl, cnt));
+	}
+
+      if (cnt == shstrndx && shdr->sh_type != SHT_STRTAB)
+	ERROR (gettext ("\
+section [%2zu] '%s': ELF header says this is the section header string table but type is not SHT_TYPE\n"),
+	       cnt, section_name (ebl, cnt));
+
+      switch (shdr->sh_type)
+	{
+	case SHT_DYNSYM:
+	  if (ehdr->e_type == ET_REL)
+	    ERROR (gettext ("\
+section [%2zu] '%s': relocatable files cannot have dynamic symbol tables\n"),
+		   cnt, section_name (ebl, cnt));
+	  FALLTHROUGH;
+	case SHT_SYMTAB:
+	  check_symtab (ebl, ehdr, shdr, cnt);
+	  break;
+
+	case SHT_RELA:
+	  check_rela (ebl, ehdr, shdr, cnt);
+	  break;
+
+	case SHT_REL:
+	  check_rel (ebl, ehdr, shdr, cnt);
+	  break;
+
+	case SHT_DYNAMIC:
+	  check_dynamic (ebl, ehdr, shdr, cnt);
+	  break;
+
+	case SHT_SYMTAB_SHNDX:
+	  check_symtab_shndx (ebl, ehdr, shdr, cnt);
+	  break;
+
+	case SHT_HASH:
+	  check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt);
+	  hash_idx = cnt;
+	  break;
+
+	case SHT_GNU_HASH:
+	  check_hash (shdr->sh_type, ebl, ehdr, shdr, cnt);
+	  gnu_hash_idx = cnt;
+	  break;
+
+	case SHT_NULL:
+	  check_null (ebl, shdr, cnt);
+	  break;
+
+	case SHT_GROUP:
+	  check_group (ebl, ehdr, shdr, cnt);
+	  break;
+
+	case SHT_NOTE:
+	  check_note_section (ebl, ehdr, shdr, cnt);
+	  break;
+
+	case SHT_GNU_versym:
+	  /* We cannot process this section now since we have no guarantee
+	     that the verneed and verdef sections have already been read.
+	     Just remember the section index.  */
+	  if (versym_scnndx != 0)
+	    ERROR (gettext ("more than one version symbol table present\n"));
+	  versym_scnndx = cnt;
+	  break;
+
+	case SHT_GNU_verneed:
+	  check_verneed (ebl, shdr, cnt);
+	  break;
+
+	case SHT_GNU_verdef:
+	  check_verdef (ebl, shdr, cnt);
+	  break;
+
+	case SHT_GNU_ATTRIBUTES:
+	  check_attributes (ebl, ehdr, shdr, cnt);
+	  break;
+
+	default:
+	  /* Nothing.  */
+	  break;
+	}
+    }
+
+  if (has_interp_segment && !dot_interp_section)
+    ERROR (gettext ("INTERP program header entry but no .interp section\n"));
+
+  if (!is_debuginfo)
+    for (unsigned int pcnt = 0; pcnt < phnum; ++pcnt)
+      {
+	GElf_Phdr phdr_mem;
+	GElf_Phdr *phdr = gelf_getphdr (ebl->elf, pcnt, &phdr_mem);
+	if (phdr != NULL && (phdr->p_type == PT_LOAD || phdr->p_type == PT_TLS))
+	  {
+	    if ((phdr->p_flags & PF_X) != 0
+		&& (segment_flags[pcnt] & PF_X) == 0)
+	      ERROR (gettext ("\
+loadable segment [%u] is executable but contains no executable sections\n"),
+		     pcnt);
+
+	    if ((phdr->p_flags & PF_W) != 0
+		&& (segment_flags[pcnt] & PF_W) == 0)
+	      ERROR (gettext ("\
+loadable segment [%u] is writable but contains no writable sections\n"),
+		     pcnt);
+	  }
+      }
+
+  free (segment_flags);
+
+  if (version_namelist != NULL)
+    {
+      if (versym_scnndx == 0)
+    ERROR (gettext ("\
+no .gnu.versym section present but .gnu.versym_d or .gnu.versym_r section exist\n"));
+      else
+	check_versym (ebl, versym_scnndx);
+
+      /* Check for duplicate index numbers.  */
+      do
+	{
+	  struct version_namelist *runp = version_namelist->next;
+	  while (runp != NULL)
+	    {
+	      if (version_namelist->ndx == runp->ndx)
+		{
+		  ERROR (gettext ("duplicate version index %d\n"),
+			 (int) version_namelist->ndx);
+		  break;
+		}
+	      runp = runp->next;
+	    }
+
+	  struct version_namelist *old = version_namelist;
+	  version_namelist = version_namelist->next;
+	  free (old);
+	}
+      while (version_namelist != NULL);
+    }
+  else if (versym_scnndx != 0)
+    ERROR (gettext ("\
+.gnu.versym section present without .gnu.versym_d or .gnu.versym_r\n"));
+
+  if (hash_idx != 0 && gnu_hash_idx != 0)
+    compare_hash_gnu_hash (ebl, ehdr, hash_idx, gnu_hash_idx);
+
+  free (scnref);
+}
+
+
+static GElf_Off
+check_note_data (Ebl *ebl, const GElf_Ehdr *ehdr,
+		 Elf_Data *data, int shndx, int phndx, GElf_Off start)
+{
+  size_t offset = 0;
+  size_t last_offset = 0;
+  GElf_Nhdr nhdr;
+  size_t name_offset;
+  size_t desc_offset;
+  while (offset < data->d_size
+	 && (offset = gelf_getnote (data, offset,
+				    &nhdr, &name_offset, &desc_offset)) > 0)
+    {
+      last_offset = offset;
+
+      /* Make sure it is one of the note types we know about.  */
+      if (ehdr->e_type == ET_CORE)
+	switch (nhdr.n_type)
+	  {
+	  case NT_PRSTATUS:
+	  case NT_FPREGSET:
+	  case NT_PRPSINFO:
+	  case NT_TASKSTRUCT:		/* NT_PRXREG on Solaris.  */
+	  case NT_PLATFORM:
+	  case NT_AUXV:
+	  case NT_GWINDOWS:
+	  case NT_ASRS:
+	  case NT_PSTATUS:
+	  case NT_PSINFO:
+	  case NT_PRCRED:
+	  case NT_UTSNAME:
+	  case NT_LWPSTATUS:
+	  case NT_LWPSINFO:
+	  case NT_PRFPXREG:
+	    /* Known type.  */
+	    break;
+
+	  default:
+	    if (shndx == 0)
+	      ERROR (gettext ("\
+phdr[%d]: unknown core file note type %" PRIu32 " at offset %" PRIu64 "\n"),
+		     phndx, (uint32_t) nhdr.n_type, start + offset);
+	    else
+	      ERROR (gettext ("\
+section [%2d] '%s': unknown core file note type %" PRIu32
+			      " at offset %zu\n"),
+		     shndx, section_name (ebl, shndx),
+		     (uint32_t) nhdr.n_type, offset);
+	  }
+      else
+	switch (nhdr.n_type)
+	  {
+	  case NT_GNU_ABI_TAG:
+	  case NT_GNU_HWCAP:
+	  case NT_GNU_BUILD_ID:
+	  case NT_GNU_GOLD_VERSION:
+	    break;
+
+	  case 0:
+	    /* Linux vDSOs use a type 0 note for the kernel version word.  */
+	    if (nhdr.n_namesz == sizeof "Linux"
+		&& !memcmp (data->d_buf + name_offset, "Linux", sizeof "Linux"))
+	      break;
+	    FALLTHROUGH;
+	  default:
+	    if (shndx == 0)
+	      ERROR (gettext ("\
+phdr[%d]: unknown object file note type %" PRIu32 " at offset %zu\n"),
+		     phndx, (uint32_t) nhdr.n_type, offset);
+	    else
+	      ERROR (gettext ("\
+section [%2d] '%s': unknown object file note type %" PRIu32
+			      " at offset %zu\n"),
+		     shndx, section_name (ebl, shndx),
+		     (uint32_t) nhdr.n_type, offset);
+	  }
+    }
+
+  return last_offset;
+}
+
+
+static void
+check_note (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Phdr *phdr, int cnt)
+{
+  if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL
+      && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
+    ERROR (gettext ("\
+phdr[%d]: no note entries defined for the type of file\n"),
+	   cnt);
+
+  if (is_debuginfo)
+    /* The p_offset values in a separate debug file are bogus.  */
+    return;
+
+  if (phdr->p_filesz == 0)
+    return;
+
+  GElf_Off notes_size = 0;
+  Elf_Data *data = elf_getdata_rawchunk (ebl->elf,
+					 phdr->p_offset, phdr->p_filesz,
+					 ELF_T_NHDR);
+  if (data != NULL && data->d_buf != NULL)
+    notes_size = check_note_data (ebl, ehdr, data, 0, cnt, phdr->p_offset);
+
+  if (notes_size == 0)
+    ERROR (gettext ("phdr[%d]: cannot get content of note section: %s\n"),
+	   cnt, elf_errmsg (-1));
+  else if (notes_size != phdr->p_filesz)
+    ERROR (gettext ("phdr[%d]: extra %" PRIu64 " bytes after last note\n"),
+	   cnt, phdr->p_filesz - notes_size);
+}
+
+
+static void
+check_note_section (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr, int idx)
+{
+  if (shdr->sh_size == 0)
+    return;
+
+  Elf_Data *data = elf_getdata (elf_getscn (ebl->elf, idx), NULL);
+  if (data == NULL || data->d_buf == NULL)
+    {
+      ERROR (gettext ("section [%2d] '%s': cannot get section data\n"),
+	     idx, section_name (ebl, idx));
+      return;
+    }
+
+  if (ehdr->e_type != ET_CORE && ehdr->e_type != ET_REL
+      && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
+    ERROR (gettext ("\
+section [%2d] '%s': no note entries defined for the type of file\n"),
+	     idx, section_name (ebl, idx));
+
+  GElf_Off notes_size = check_note_data (ebl, ehdr, data, idx, 0, 0);
+
+  if (notes_size == 0)
+    ERROR (gettext ("section [%2d] '%s': cannot get content of note section\n"),
+	   idx, section_name (ebl, idx));
+  else if (notes_size != shdr->sh_size)
+    ERROR (gettext ("section [%2d] '%s': extra %" PRIu64
+		    " bytes after last note\n"),
+	   idx, section_name (ebl, idx), shdr->sh_size - notes_size);
+}
+
+
+/* Index of the PT_GNU_EH_FRAME program eader entry.  */
+static int pt_gnu_eh_frame_pndx;
+
+
+static void
+check_program_header (Ebl *ebl, GElf_Ehdr *ehdr)
+{
+  if (ehdr->e_phoff == 0)
+    return;
+
+  if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN
+      && ehdr->e_type != ET_CORE)
+    ERROR (gettext ("\
+only executables, shared objects, and core files can have program headers\n"));
+
+  int num_pt_interp = 0;
+  int num_pt_tls = 0;
+  int num_pt_relro = 0;
+
+  for (unsigned int cnt = 0; cnt < phnum; ++cnt)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr;
+
+      phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
+      if (phdr == NULL)
+	{
+	  ERROR (gettext ("cannot get program header entry %d: %s\n"),
+		 cnt, elf_errmsg (-1));
+	  continue;
+	}
+
+      if (phdr->p_type >= PT_NUM && phdr->p_type != PT_GNU_EH_FRAME
+	  && phdr->p_type != PT_GNU_STACK && phdr->p_type != PT_GNU_RELRO
+	  /* Check for a known machine-specific type.  */
+	  && ebl_segment_type_name (ebl, phdr->p_type, NULL, 0) == NULL)
+	ERROR (gettext ("\
+program header entry %d: unknown program header entry type %#" PRIx64 "\n"),
+	       cnt, (uint64_t) phdr->p_type);
+
+      if (phdr->p_type == PT_LOAD)
+	has_loadable_segment = true;
+      else if (phdr->p_type == PT_INTERP)
+	{
+	  if (++num_pt_interp != 1)
+	    {
+	      if (num_pt_interp == 2)
+		ERROR (gettext ("\
+more than one INTERP entry in program header\n"));
+	    }
+	  has_interp_segment = true;
+	}
+      else if (phdr->p_type == PT_TLS)
+	{
+	  if (++num_pt_tls == 2)
+	    ERROR (gettext ("more than one TLS entry in program header\n"));
+	}
+      else if (phdr->p_type == PT_NOTE)
+	check_note (ebl, ehdr, phdr, cnt);
+      else if (phdr->p_type == PT_DYNAMIC)
+	{
+	  if (ehdr->e_type == ET_EXEC && ! has_interp_segment)
+	    ERROR (gettext ("\
+static executable cannot have dynamic sections\n"));
+	  else
+	    {
+	      /* Check that the .dynamic section, if it exists, has
+		 the same address.  */
+	      Elf_Scn *scn = NULL;
+	      while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+		{
+		  GElf_Shdr shdr_mem;
+		  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+		  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
+		    {
+		      if (phdr->p_offset != shdr->sh_offset)
+			ERROR (gettext ("\
+dynamic section reference in program header has wrong offset\n"));
+		      if (phdr->p_memsz != shdr->sh_size)
+			ERROR (gettext ("\
+dynamic section size mismatch in program and section header\n"));
+		      break;
+		    }
+		}
+	    }
+	}
+      else if (phdr->p_type == PT_GNU_RELRO)
+	{
+	  if (++num_pt_relro == 2)
+	    ERROR (gettext ("\
+more than one GNU_RELRO entry in program header\n"));
+	  else
+	    {
+	      /* Check that the region is in a writable segment.  */
+	      unsigned int inner;
+	      for (inner = 0; inner < phnum; ++inner)
+		{
+		  GElf_Phdr phdr2_mem;
+		  GElf_Phdr *phdr2;
+
+		  phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem);
+		  if (phdr2 == NULL)
+		    continue;
+
+		  if (phdr2->p_type == PT_LOAD
+		      && phdr->p_vaddr >= phdr2->p_vaddr
+		      && (phdr->p_vaddr + phdr->p_memsz
+			  <= phdr2->p_vaddr + phdr2->p_memsz))
+		    {
+		      if ((phdr2->p_flags & PF_W) == 0)
+			ERROR (gettext ("\
+loadable segment GNU_RELRO applies to is not writable\n"));
+		      /* Unless fully covered, relro flags could be a
+			 subset of the phdrs2 flags.  For example the load
+			 segment could also have PF_X set.  */
+		      if (phdr->p_vaddr == phdr2->p_vaddr
+			  && (phdr->p_vaddr + phdr->p_memsz
+			      == phdr2->p_vaddr + phdr2->p_memsz))
+			{
+			  if ((phdr2->p_flags & ~PF_W)
+			      != (phdr->p_flags & ~PF_W))
+			    ERROR (gettext ("\
+loadable segment [%u] flags do not match GNU_RELRO [%u] flags\n"),
+				   cnt, inner);
+			}
+		      else
+			{
+			  if ((phdr->p_flags & ~phdr2->p_flags) != 0)
+			    ERROR (gettext ("\
+GNU_RELRO [%u] flags are not a subset of the loadable segment [%u] flags\n"),
+				   inner, cnt);
+			}
+		      break;
+		    }
+		}
+
+	      if (inner >= phnum)
+		ERROR (gettext ("\
+%s segment not contained in a loaded segment\n"), "GNU_RELRO");
+	    }
+	}
+      else if (phdr->p_type == PT_PHDR)
+	{
+	  /* Check that the region is in a writable segment.  */
+	  unsigned int inner;
+	  for (inner = 0; inner < phnum; ++inner)
+	    {
+	      GElf_Phdr phdr2_mem;
+	      GElf_Phdr *phdr2;
+
+	      phdr2 = gelf_getphdr (ebl->elf, inner, &phdr2_mem);
+	      if (phdr2 != NULL
+		  && phdr2->p_type == PT_LOAD
+		  && phdr->p_vaddr >= phdr2->p_vaddr
+		  && (phdr->p_vaddr + phdr->p_memsz
+		      <= phdr2->p_vaddr + phdr2->p_memsz))
+		break;
+	    }
+
+	  if (inner >= phnum)
+	    ERROR (gettext ("\
+%s segment not contained in a loaded segment\n"), "PHDR");
+
+	  /* Check that offset in segment corresponds to offset in ELF
+	     header.  */
+	  if (phdr->p_offset != ehdr->e_phoff)
+	    ERROR (gettext ("\
+program header offset in ELF header and PHDR entry do not match"));
+	}
+      else if (phdr->p_type == PT_GNU_EH_FRAME)
+	{
+	  /* If there is an .eh_frame_hdr section it must be
+	     referenced by this program header entry.  */
+	  Elf_Scn *scn = NULL;
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = NULL;
+	  bool any = false;
+	  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+	    {
+	      any = true;
+	      shdr = gelf_getshdr (scn, &shdr_mem);
+	      if (shdr != NULL
+		  && shdr->sh_type == (is_debuginfo
+				       ? SHT_NOBITS : SHT_PROGBITS)
+		  && elf_strptr (ebl->elf, shstrndx, shdr->sh_name) != NULL
+		  && ! strcmp (".eh_frame_hdr",
+			       elf_strptr (ebl->elf, shstrndx, shdr->sh_name)))
+		{
+		  if (! is_debuginfo)
+		    {
+		      if (phdr->p_offset != shdr->sh_offset)
+			ERROR (gettext ("\
+call frame search table reference in program header has wrong offset\n"));
+		      if (phdr->p_memsz != shdr->sh_size)
+			ERROR (gettext ("\
+call frame search table size mismatch in program and section header\n"));
+		    }
+		  break;
+		}
+	    }
+
+	  if (scn == NULL)
+	    {
+	      /* If there is no section header table we don't
+		 complain.  But if there is one there should be an
+		 entry for .eh_frame_hdr.  */
+	      if (any)
+		ERROR (gettext ("\
+PT_GNU_EH_FRAME present but no .eh_frame_hdr section\n"));
+	    }
+	  else
+	    {
+	      /* The section must be allocated and not be writable and
+		 executable.  */
+	      if ((phdr->p_flags & PF_R) == 0)
+		ERROR (gettext ("\
+call frame search table must be allocated\n"));
+	      else if (shdr != NULL && (shdr->sh_flags & SHF_ALLOC) == 0)
+		ERROR (gettext ("\
+section [%2zu] '%s' must be allocated\n"), elf_ndxscn (scn), ".eh_frame_hdr");
+
+	      if ((phdr->p_flags & PF_W) != 0)
+		ERROR (gettext ("\
+call frame search table must not be writable\n"));
+	      else if (shdr != NULL && (shdr->sh_flags & SHF_WRITE) != 0)
+		ERROR (gettext ("\
+section [%2zu] '%s' must not be writable\n"),
+		       elf_ndxscn (scn), ".eh_frame_hdr");
+
+	      if ((phdr->p_flags & PF_X) != 0)
+		ERROR (gettext ("\
+call frame search table must not be executable\n"));
+	      else if (shdr != NULL && (shdr->sh_flags & SHF_EXECINSTR) != 0)
+		ERROR (gettext ("\
+section [%2zu] '%s' must not be executable\n"),
+		       elf_ndxscn (scn), ".eh_frame_hdr");
+	    }
+
+	  /* Remember which entry this is.  */
+	  pt_gnu_eh_frame_pndx = cnt;
+	}
+
+      if (phdr->p_filesz > phdr->p_memsz
+	  && (phdr->p_memsz != 0 || phdr->p_type != PT_NOTE))
+	ERROR (gettext ("\
+program header entry %d: file size greater than memory size\n"),
+	       cnt);
+
+      if (phdr->p_align > 1)
+	{
+	  if (!powerof2 (phdr->p_align))
+	    ERROR (gettext ("\
+program header entry %d: alignment not a power of 2\n"), cnt);
+	  else if ((phdr->p_vaddr - phdr->p_offset) % phdr->p_align != 0)
+	    ERROR (gettext ("\
+program header entry %d: file offset and virtual address not module of alignment\n"), cnt);
+	}
+    }
+}
+
+
+static void
+check_exception_data (Ebl *ebl __attribute__ ((unused)),
+		      GElf_Ehdr *ehdr __attribute__ ((unused)))
+{
+  if ((ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN)
+      && pt_gnu_eh_frame_pndx == 0 && eh_frame_hdr_scnndx != 0)
+    ERROR (gettext ("executable/DSO with .eh_frame_hdr section does not have "
+		    "a PT_GNU_EH_FRAME program header entry"));
+}
+
+
+/* Process one file.  */
+static void
+process_elf_file (Elf *elf, const char *prefix, const char *suffix,
+		  const char *fname, size_t size, bool only_one)
+{
+  /* Reset variables.  */
+  ndynamic = 0;
+  nverneed = 0;
+  nverdef = 0;
+  textrel = false;
+  needed_textrel = false;
+  has_loadable_segment = false;
+  has_interp_segment = false;
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  Ebl *ebl;
+
+  /* Print the file name.  */
+  if (!only_one)
+    {
+      if (prefix != NULL)
+	printf ("\n%s(%s)%s:\n", prefix, fname, suffix);
+      else
+	printf ("\n%s:\n", fname);
+    }
+
+  if (ehdr == NULL)
+    {
+      ERROR (gettext ("cannot read ELF header: %s\n"), elf_errmsg (-1));
+      return;
+    }
+
+  ebl = ebl_openbackend (elf);
+  /* If there is no appropriate backend library we cannot test
+     architecture and OS specific features.  Any encountered extension
+     is an error.  */
+
+  /* Go straight by the gABI, check all the parts in turn.  */
+  check_elf_header (ebl, ehdr, size);
+
+  /* Check the program header.  */
+  check_program_header (ebl, ehdr);
+
+  /* Next the section headers.  It is OK if there are no section
+     headers at all.  */
+  check_sections (ebl, ehdr);
+
+  /* Check the exception handling data, if it exists.  */
+  if (pt_gnu_eh_frame_pndx != 0 || eh_frame_hdr_scnndx != 0
+      || eh_frame_scnndx != 0 || gcc_except_table_scnndx != 0)
+    check_exception_data (ebl, ehdr);
+
+  /* Report if no relocation section needed the text relocation flag.  */
+  if (textrel && !needed_textrel)
+    ERROR (gettext ("text relocation flag set but not needed\n"));
+
+  /* Free the resources.  */
+  ebl_closebackend (ebl);
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/findtextrel.c b/third_party/elfutils/src/findtextrel.c
new file mode 100644
index 0000000..8f1e239
--- /dev/null
+++ b/third_party/elfutils/src/findtextrel.c
@@ -0,0 +1,611 @@
+/* Locate source files or functions which caused text relocations.
+   Copyright (C) 2005-2010, 2012, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <assert.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libdw.h>
+#include <libintl.h>
+#include <locale.h>
+#include <search.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <printversion.h>
+
+
+struct segments
+{
+  GElf_Addr from;
+  GElf_Addr to;
+};
+
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+/* Values for the parameters which have no short form.  */
+#define OPT_DEBUGINFO 0x100
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("Input Selection:"), 0 },
+  { "root", 'r', "PATH", 0, N_("Prepend PATH to all file names"), 0 },
+  { "debuginfo", OPT_DEBUGINFO, "PATH", 0,
+    N_("Use PATH as root of debuginfo hierarchy"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("\
+Locate source of text relocations in FILEs (a.out by default).");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("[FILE...]");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  options, parse_opt, args_doc, doc, NULL, NULL, NULL
+};
+
+
+/* Print symbols in file named FNAME.  */
+static int process_file (const char *fname, bool more_than_one);
+
+/* Check for text relocations in the given file.  The segment
+   information is known.  */
+static void check_rel (size_t nsegments, struct segments segments[nsegments],
+		       GElf_Addr addr, Elf *elf, Elf_Scn *symscn, Dwarf *dw,
+		       const char *fname, bool more_than_one,
+		       void **knownsrcs);
+
+
+
+/* User-provided root directory.  */
+static const char *rootdir = "/";
+
+/* Root of debuginfo directory hierarchy.  */
+static const char *debuginfo_root;
+
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+  int result = 0;
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  /* Make sure the message catalog can be found.  */
+  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+
+  /* Initialize the message catalog.  */
+  (void) textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  */
+  (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+  /* Tell the library which version we are expecting.  */
+  elf_version (EV_CURRENT);
+
+  /* If the user has not specified the root directory for the
+     debuginfo hierarchy, we have to determine it ourselves.  */
+  if (debuginfo_root == NULL)
+    {
+      // XXX The runtime should provide this information.
+#if defined __ia64__ || defined __alpha__
+      debuginfo_root = "/usr/lib/debug";
+#else
+      debuginfo_root = (sizeof (long int) == 4
+			? "/usr/lib/debug" : "/usr/lib64/debug");
+#endif
+    }
+
+  if (remaining == argc)
+    result = process_file ("a.out", false);
+  else
+    {
+      /* Process all the remaining files.  */
+      const bool more_than_one = remaining + 1 < argc;
+
+      do
+	result |= process_file (argv[remaining], more_than_one);
+      while (++remaining < argc);
+    }
+
+  return result;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg,
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case 'r':
+      rootdir = arg;
+      break;
+
+    case OPT_DEBUGINFO:
+      debuginfo_root = arg;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+static void
+noop (void *arg __attribute__ ((unused)))
+{
+}
+
+
+static int
+process_file (const char *fname, bool more_than_one)
+{
+  int result = 0;
+  void *knownsrcs = NULL;
+
+  size_t fname_len = strlen (fname);
+  size_t rootdir_len = strlen (rootdir);
+  const char *real_fname = fname;
+  if (fname[0] == '/' && (rootdir[0] != '/' || rootdir[1] != '\0'))
+    {
+      /* Prepend the user-provided root directory.  */
+      char *new_fname = alloca (rootdir_len + fname_len + 2);
+      *((char *) mempcpy (stpcpy (mempcpy (new_fname, rootdir, rootdir_len),
+				  "/"),
+			  fname, fname_len)) = '\0';
+      real_fname = new_fname;
+    }
+
+  int fd = open (real_fname, O_RDONLY);
+  if (fd == -1)
+    {
+      error (0, errno, gettext ("cannot open '%s'"), fname);
+      return 1;
+    }
+
+  Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+  if (elf == NULL)
+    {
+      error (0, 0, gettext ("cannot create ELF descriptor for '%s': %s"),
+	     fname, elf_errmsg (-1));
+      goto err_close;
+    }
+
+  /* Make sure the file is a DSO.  */
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      error (0, 0, gettext ("cannot get ELF header '%s': %s"),
+	     fname, elf_errmsg (-1));
+    err_elf_close:
+      elf_end (elf);
+    err_close:
+      close (fd);
+      return 1;
+    }
+
+  if (ehdr->e_type != ET_DYN)
+    {
+      error (0, 0, gettext ("'%s' is not a DSO or PIE"), fname);
+      goto err_elf_close;
+    }
+
+  /* Determine whether the DSO has text relocations at all and locate
+     the symbol table.  */
+  Elf_Scn *symscn = NULL;
+  Elf_Scn *scn = NULL;
+  bool seen_dynamic = false;
+  bool have_textrel = false;
+  while ((scn = elf_nextscn (elf, scn)) != NULL
+	 && (!seen_dynamic || symscn == NULL))
+    {
+      /* Handle the section if it is a symbol table.  */
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr == NULL)
+	{
+	  error (0, 0,
+		 gettext ("getting get section header of section %zu: %s"),
+		 elf_ndxscn (scn), elf_errmsg (-1));
+	  goto err_elf_close;
+	}
+
+      switch (shdr->sh_type)
+	{
+	case SHT_DYNAMIC:
+	  if (!seen_dynamic)
+	    {
+	      seen_dynamic = true;
+
+	      Elf_Data *data = elf_getdata (scn, NULL);
+
+	      for (size_t cnt = 0; cnt < shdr->sh_size / shdr->sh_entsize;
+		   ++cnt)
+		{
+		  GElf_Dyn dynmem;
+		  GElf_Dyn *dyn;
+
+		  dyn = gelf_getdyn (data, cnt, &dynmem);
+		  if (dyn == NULL)
+		    {
+		      error (0, 0, gettext ("cannot read dynamic section: %s"),
+			     elf_errmsg (-1));
+		      goto err_elf_close;
+		    }
+
+		  if (dyn->d_tag == DT_TEXTREL
+		      || (dyn->d_tag == DT_FLAGS
+			  && (dyn->d_un.d_val & DF_TEXTREL) != 0))
+		    have_textrel = true;
+		}
+	    }
+	  break;
+
+	case SHT_SYMTAB:
+	  symscn = scn;
+	  break;
+	}
+    }
+
+  if (!have_textrel)
+    {
+      error (0, 0, gettext ("no text relocations reported in '%s'"), fname);
+      goto err_elf_close;
+    }
+
+  int fd2 = -1;
+  Elf *elf2 = NULL;
+  /* Get the address ranges for the loaded segments.  */
+  size_t nsegments_max = 10;
+  size_t nsegments = 0;
+  struct segments *segments
+    = (struct segments *) malloc (nsegments_max * sizeof (segments[0]));
+  if (segments == NULL)
+    error (1, errno, gettext ("while reading ELF file"));
+
+  size_t phnum;
+  if (elf_getphdrnum (elf, &phnum) != 0)
+    error (1, 0, gettext ("cannot get program header count: %s"),
+           elf_errmsg (-1));
+
+
+  for (size_t i = 0; i < phnum; ++i)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
+      if (phdr == NULL)
+	{
+	  error (0, 0,
+		 gettext ("cannot get program header index at offset %zd: %s"),
+		 i, elf_errmsg (-1));
+	  result = 1;
+	  goto next;
+	}
+
+      if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
+	{
+	  if (nsegments == nsegments_max)
+	    {
+	      nsegments_max *= 2;
+	      segments
+		= (struct segments *) realloc (segments,
+					       nsegments_max
+					       * sizeof (segments[0]));
+	      if (segments == NULL)
+		{
+		  error (0, 0, gettext ("\
+cannot get program header index at offset %zd: %s"),
+			 i, elf_errmsg (-1));
+		  result = 1;
+		  goto next;
+		}
+	    }
+
+	  segments[nsegments].from = phdr->p_vaddr;
+	  segments[nsegments].to = phdr->p_vaddr + phdr->p_memsz;
+	  ++nsegments;
+	}
+    }
+
+  if (nsegments > 0)
+    {
+
+      Dwarf *dw = dwarf_begin_elf (elf, DWARF_C_READ, NULL);
+      /* Look for debuginfo files if the information is not the in
+	 opened file itself.  This makes only sense if the input file
+	 is specified with an absolute path.  */
+      if (dw == NULL && fname[0] == '/')
+	{
+	  size_t debuginfo_rootlen = strlen (debuginfo_root);
+	  char *difname = (char *) alloca (rootdir_len + debuginfo_rootlen
+					   + fname_len + 8);
+	  strcpy (mempcpy (stpcpy (mempcpy (mempcpy (difname, rootdir,
+						     rootdir_len),
+					    debuginfo_root,
+					    debuginfo_rootlen),
+				   "/"),
+			   fname, fname_len),
+		  ".debug");
+
+	  fd2 = open (difname, O_RDONLY);
+	  if (fd2 != -1
+	      && (elf2 = elf_begin (fd2, ELF_C_READ_MMAP, NULL)) != NULL)
+	    dw = dwarf_begin_elf (elf2, DWARF_C_READ, NULL);
+	}
+
+      /* Look at all relocations and determine which modify
+	 write-protected segments.  */
+      scn = NULL;
+      while ((scn = elf_nextscn (elf, scn)) != NULL)
+	{
+	  /* Handle the section if it is a symbol table.  */
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+	  if (shdr == NULL)
+	    {
+	      error (0, 0,
+		     gettext ("cannot get section header of section %zu: %s"),
+		     elf_ndxscn (scn), elf_errmsg (-1));
+	      result = 1;
+	      goto next;
+	    }
+
+	  if ((shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+	      && symscn == NULL)
+	    {
+	      symscn = elf_getscn (elf, shdr->sh_link);
+	      if (symscn == NULL)
+		{
+		  error (0, 0, gettext ("\
+cannot get symbol table section %zu in '%s': %s"),
+			 (size_t) shdr->sh_link, fname, elf_errmsg (-1));
+		  result = 1;
+		  goto next;
+		}
+	    }
+
+	  if (shdr->sh_type == SHT_REL)
+	    {
+	      Elf_Data *data = elf_getdata (scn, NULL);
+
+	      for (int cnt = 0;
+		   (size_t) cnt < shdr->sh_size / shdr->sh_entsize;
+		   ++cnt)
+		{
+		  GElf_Rel rel_mem;
+		  GElf_Rel *rel = gelf_getrel (data, cnt, &rel_mem);
+		  if (rel == NULL)
+		    {
+		      error (0, 0, gettext ("\
+cannot get relocation at index %d in section %zu in '%s': %s"),
+			     cnt, elf_ndxscn (scn), fname, elf_errmsg (-1));
+		      result = 1;
+		      goto next;
+		    }
+
+		  check_rel (nsegments, segments, rel->r_offset, elf,
+			     symscn, dw, fname, more_than_one, &knownsrcs);
+		}
+	    }
+	  else if (shdr->sh_type == SHT_RELA)
+	    {
+	      Elf_Data *data = elf_getdata (scn, NULL);
+
+	      for (int cnt = 0;
+		   (size_t) cnt < shdr->sh_size / shdr->sh_entsize;
+		   ++cnt)
+		{
+		  GElf_Rela rela_mem;
+		  GElf_Rela *rela = gelf_getrela (data, cnt, &rela_mem);
+		  if (rela == NULL)
+		    {
+		      error (0, 0, gettext ("\
+cannot get relocation at index %d in section %zu in '%s': %s"),
+			     cnt, elf_ndxscn (scn), fname, elf_errmsg (-1));
+		      result = 1;
+		      goto next;
+		    }
+
+		  check_rel (nsegments, segments, rela->r_offset, elf,
+			     symscn, dw, fname, more_than_one, &knownsrcs);
+		}
+	    }
+	}
+
+      dwarf_end (dw);
+    }
+
+ next:
+  elf_end (elf);
+  elf_end (elf2);
+  close (fd);
+  if (fd2 != -1)
+    close (fd2);
+
+  free (segments);
+  tdestroy (knownsrcs, noop);
+
+  return result;
+}
+
+
+static int
+ptrcompare (const void *p1, const void *p2)
+{
+  if ((uintptr_t) p1 < (uintptr_t) p2)
+    return -1;
+  if ((uintptr_t) p1 > (uintptr_t) p2)
+    return 1;
+  return 0;
+}
+
+
+static void
+check_rel (size_t nsegments, struct segments segments[nsegments],
+	   GElf_Addr addr, Elf *elf, Elf_Scn *symscn, Dwarf *dw,
+	   const char *fname, bool more_than_one, void **knownsrcs)
+{
+  for (size_t cnt = 0; cnt < nsegments; ++cnt)
+    if (segments[cnt].from <= addr && segments[cnt].to > addr)
+      {
+	Dwarf_Die die_mem;
+	Dwarf_Die *die;
+	Dwarf_Line *line;
+	const char *src;
+
+	if (more_than_one)
+	  printf ("%s: ", fname);
+
+	if ((die = dwarf_addrdie (dw, addr, &die_mem)) != NULL
+	    && (line = dwarf_getsrc_die (die, addr)) != NULL
+	    && (src = dwarf_linesrc (line, NULL, NULL)) != NULL)
+	  {
+	    /* There can be more than one relocation against one file.
+	       Try to avoid multiple messages.  And yes, the code uses
+	       pointer comparison.  */
+	    if (tfind (src, knownsrcs, ptrcompare) == NULL)
+	      {
+		printf (gettext ("%s not compiled with -fpic/-fPIC\n"), src);
+		tsearch (src, knownsrcs, ptrcompare);
+	      }
+	    return;
+	  }
+	else
+	  {
+	    /* At least look at the symbol table to see which function
+	       the modified address is in.  */
+	    Elf_Data *symdata = elf_getdata (symscn, NULL);
+	    GElf_Shdr shdr_mem;
+	    GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem);
+	    if (shdr != NULL)
+	      {
+		GElf_Addr lowaddr = 0;
+		int lowidx = -1;
+		GElf_Addr highaddr = ~0ul;
+		int highidx = -1;
+		GElf_Sym sym_mem;
+		GElf_Sym *sym;
+
+		for (int i = 0; (size_t) i < shdr->sh_size / shdr->sh_entsize;
+		     ++i)
+		  {
+		    sym = gelf_getsym (symdata, i, &sym_mem);
+		    if (sym == NULL)
+		      continue;
+
+		    if (sym->st_value < addr && sym->st_value > lowaddr)
+		      {
+			lowaddr = sym->st_value;
+			lowidx = i;
+		      }
+		    if (sym->st_value > addr && sym->st_value < highaddr)
+		      {
+			highaddr = sym->st_value;
+			highidx = i;
+		      }
+		  }
+
+		if (lowidx != -1)
+		  {
+		    sym = gelf_getsym (symdata, lowidx, &sym_mem);
+		    assert (sym != NULL);
+
+		    const char *lowstr = elf_strptr (elf, shdr->sh_link,
+						     sym->st_name);
+
+		    if (sym->st_value + sym->st_size > addr)
+		      {
+			/* It is this function.  */
+			if (tfind (lowstr, knownsrcs, ptrcompare) == NULL)
+			  {
+			    printf (gettext ("\
+the file containing the function '%s' is not compiled with -fpic/-fPIC\n"),
+				    lowstr);
+			    tsearch (lowstr, knownsrcs, ptrcompare);
+			  }
+		      }
+		    else if (highidx == -1)
+		      printf (gettext ("\
+the file containing the function '%s' might not be compiled with -fpic/-fPIC\n"),
+			      lowstr);
+		    else
+		      {
+			sym = gelf_getsym (symdata, highidx, &sym_mem);
+			assert (sym != NULL);
+
+			printf (gettext ("\
+either the file containing the function '%s' or the file containing the function '%s' is not compiled with -fpic/-fPIC\n"),
+				lowstr, elf_strptr (elf, shdr->sh_link,
+						    sym->st_name));
+		      }
+		    return;
+		  }
+		else if (highidx != -1)
+		  {
+		    sym = gelf_getsym (symdata, highidx, &sym_mem);
+		    assert (sym != NULL);
+
+		    printf (gettext ("\
+the file containing the function '%s' might not be compiled with -fpic/-fPIC\n"),
+			    elf_strptr (elf, shdr->sh_link, sym->st_name));
+		    return;
+		  }
+	      }
+	  }
+
+	printf (gettext ("\
+a relocation modifies memory at offset %llu in a write-protected segment\n"),
+		(unsigned long long int) addr);
+	break;
+      }
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/make-debug-archive.in b/third_party/elfutils/src/make-debug-archive.in
new file mode 100644
index 0000000..c3fcbce
--- /dev/null
+++ b/third_party/elfutils/src/make-debug-archive.in
@@ -0,0 +1,132 @@
+#!/bin/sh
+#
+# Script to make an offline archive for debugging with libdwfl-based tools.
+#
+#	make-debug-archive ARCHIVE {options}
+#	make-debug-archive --kernel [--force] [RELEASE]
+#
+# Valid options are those listed under 'Input selection options'
+# by running @UNSTRIP@ --help.
+#
+# The archive installed by --kernel be used automatically by -K.
+# An offline archive can be used via -e in any tool that accepts those options.
+#
+
+UNSTRIP=${UNSTRIP:-@UNSTRIP@}
+AR=${AR:-@AR@}
+SUDO=${SUDO:-/usr/bin/sudo}
+
+LS=/bin/ls
+RM=/bin/rm
+MV=/bin/mv
+MKDIR=/bin/mkdir
+XARGS=/usr/bin/xargs
+
+outdir=${TMPDIR:-/tmp}/debugar$$
+
+usage()
+{
+  echo "Usage: $0 ARCHIVE {options}"
+  echo "   or: $0 --kernel [--sudo] [--force] [RELEASE]"
+  echo
+  echo "Valid options are listed under 'Input selection options'"
+  echo "when running: $UNSTRIP --help"
+  echo
+  echo "The --kernel form updates the file used by -K if the"
+  echo "kernel installation has changed, or always with --force."
+  echo "With --sudo, touches the installed file via $SUDO."
+}
+
+fatal_usage()
+{
+  usage >&2
+  exit 2
+}
+
+script_version()
+{
+  echo "`basename $0` (@PACKAGE_NAME@) @PACKAGE_VERSION@"
+  echo "Copyright (C) 2007 Red Hat, Inc."
+  echo "This is free software; see the source for copying conditions."
+  echo "There is NO warranty; not even for MERCHANTABILITY or"
+  echo "FITNESS FOR A PARTICULAR PURPOSE."
+  echo "Written by Roland McGrath."
+}
+
+sudo=
+kernel=no
+force_kernel=no
+while [ $# -gt 0 ]; do
+  case "x$1" in
+  x--help) usage; exit 0 ;;
+  x--version) script_version; exit 0 ;;
+  x--kernel) kernel=yes ;;
+  x--force) force_kernel=yes ;;
+  x--sudo) sudo=$SUDO ;;
+  *) break ;;
+  esac
+  shift
+done
+
+if [ $kernel = no ] && [ $force_kernel = yes -o -n "$sudo" ]; then
+  usage
+fi
+
+if [ $kernel = yes ]; then
+  if [ $# -eq 0 ]; then
+    release=`uname -r`
+  elif [ $# -eq 1 ]; then
+    release=$1
+  else
+    fatal_usage
+  fi
+
+  dir=/usr/lib/debug/lib/modules/$release
+  archive=$dir/debug.a
+  dep=/lib/modules/$release/modules.dep
+
+  if [ ! -d $dir ]; then
+    echo >&2 "$0: $dir not installed"
+    exit 1
+  fi
+
+  # Without --force, bail if the kernel installation is not newer.
+  # This file is normally touched by installing new kernels or modules.
+  if [ $force_kernel = no -a "$archive" -nt "$dep" ]; then
+    exit 0
+  fi
+
+  # We have to kill the old one first, because our own -K would use it.
+  [ ! -e "$archive" ] || $sudo $RM -f "$archive" || exit
+
+  set "$archive" "-K$release"
+fi
+
+if [ $# -lt 2 ]; then
+  fatal_usage
+fi
+
+archive="$1"
+shift
+
+case "$archive" in
+/*) ;;
+*) archive="`/bin/pwd`/$archive" ;;
+esac
+
+if [ -z "$sudo" ]; then
+  new_archive="$archive.new"
+else
+  new_archive="$outdir.a"
+fi
+
+$RM -f "$new_archive" || exit
+
+trap '$RM -rf "$outdir" "$new_archive"' 0 1 2 15
+
+$MKDIR "$outdir" &&
+$UNSTRIP -d "$outdir" -m -a -R "$@" &&
+(cd "$outdir" && $LS | $XARGS $AR cq "$new_archive") &&
+$sudo $MV -f "$new_archive" "$archive"
+
+exit
diff --git a/third_party/elfutils/src/nm.c b/third_party/elfutils/src/nm.c
new file mode 100644
index 0000000..969c6d3
--- /dev/null
+++ b/third_party/elfutils/src/nm.c
@@ -0,0 +1,1599 @@
+/* Print symbol information from ELF file in human-readable form.
+   Copyright (C) 2000-2008, 2009, 2011, 2012, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ar.h>
+#include <argp.h>
+#include <assert.h>
+#include <ctype.h>
+#include <dwarf.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <libdw.h>
+#include <libintl.h>
+#include <locale.h>
+#include <obstack.h>
+#include <search.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <libeu.h>
+#include <system.h>
+#include <color.h>
+#include <printversion.h>
+#include "../libebl/libeblP.h"
+#include "../libdwfl/libdwflP.h"
+
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+
+/* Values for the parameters which have no short form.  */
+#define OPT_DEFINED		0x100
+#define OPT_MARK_SPECIAL	0x101
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("Output selection:"), 0 },
+  { "debug-syms", 'a', NULL, 0, N_("Display debugger-only symbols"), 0 },
+  { "defined-only", OPT_DEFINED, NULL, 0, N_("Display only defined symbols"),
+    0 },
+  { "dynamic", 'D', NULL, 0,
+    N_("Display dynamic symbols instead of normal symbols"), 0 },
+  { "extern-only", 'g', NULL, 0, N_("Display only external symbols"), 0 },
+  { "undefined-only", 'u', NULL, 0, N_("Display only undefined symbols"), 0 },
+  { "print-armap", 's', NULL, 0,
+    N_("Include index for symbols from archive members"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Output format:"), 0 },
+  { "print-file-name", 'A', NULL, 0,
+    N_("Print name of the input file before every symbol"), 0 },
+  { NULL, 'o', NULL, OPTION_HIDDEN, "Same as -A", 0 },
+  { "format", 'f', "FORMAT", 0,
+    N_("Use the output format FORMAT.  FORMAT can be `bsd', `sysv' or `posix'.  The default is `sysv'"),
+    0 },
+  { NULL, 'B', NULL, 0, N_("Same as --format=bsd"), 0 },
+  { "portability", 'P', NULL, 0, N_("Same as --format=posix"), 0 },
+  { "radix", 't', "RADIX", 0, N_("Use RADIX for printing symbol values"), 0 },
+  { "mark-special", OPT_MARK_SPECIAL, NULL, 0, N_("Mark special symbols"), 0 },
+  { "mark-weak", OPT_MARK_SPECIAL, NULL, OPTION_HIDDEN, "", 0 },
+  { "print-size", 'S', NULL, 0, N_("Print size of defined symbols"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Output options:"), 0 },
+  { "numeric-sort", 'n', NULL, 0, N_("Sort symbols numerically by address"),
+    0 },
+  { "no-sort", 'p', NULL, 0, N_("Do not sort the symbols"), 0 },
+  { "reverse-sort", 'r', NULL, 0, N_("Reverse the sense of the sort"), 0 },
+#ifdef USE_DEMANGLE
+  { "demangle", 'C', NULL, 0,
+    N_("Decode low-level symbol names into source code names"), 0 },
+#endif
+  { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("List symbols from FILEs (a.out by default).");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("[FILE...]");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Parser children.  */
+static struct argp_child argp_children[] =
+  {
+    { &color_argp, 0, N_("Output formatting"), 2 },
+    { NULL, 0, NULL, 0}
+  };
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  options, parse_opt, args_doc, doc, argp_children, NULL, NULL
+};
+
+
+/* Print symbols in file named FNAME.  */
+static int process_file (const char *fname, bool more_than_one);
+
+/* Handle content of archive.  */
+static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
+		      const char *suffix);
+
+/* Handle ELF file.  */
+static int handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
+		       const char *suffix);
+
+
+#define INTERNAL_ERROR(fname) \
+  error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s): %s"),      \
+	 fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1))
+
+
+/* Internal representation of symbols.  */
+typedef struct GElf_SymX
+{
+  GElf_Sym sym;
+  Elf32_Word xndx;
+  char *where;
+} GElf_SymX;
+
+
+/* User-selectable options.  */
+
+/* The selected output format.  */
+static enum
+{
+  format_sysv = 0,
+  format_bsd,
+  format_posix
+} format;
+
+/* Print defined, undefined, or both?  */
+static bool hide_undefined;
+static bool hide_defined;
+
+/* Print local symbols also?  */
+static bool hide_local;
+
+/* Nonzero if full filename should precede every symbol.  */
+static bool print_file_name;
+
+/* If true print size of defined symbols in BSD format.  */
+static bool print_size;
+
+/* If true print archive index.  */
+static bool print_armap;
+
+/* If true reverse sorting.  */
+static bool reverse_sort;
+
+#ifdef USE_DEMANGLE
+/* If true demangle symbols.  */
+static bool demangle;
+#endif
+
+/* Type of the section we are printing.  */
+static GElf_Word symsec_type = SHT_SYMTAB;
+
+/* Sorting selection.  */
+static enum
+{
+  sort_name = 0,
+  sort_numeric,
+  sort_nosort
+} sort;
+
+/* Radix for printed numbers.  */
+static enum
+{
+  radix_hex = 0,
+  radix_decimal,
+  radix_octal
+} radix;
+
+/* If nonzero mark special symbols:
+   - weak symbols are distinguished from global symbols by adding
+     a `*' after the identifying letter for the symbol class and type.
+   - TLS symbols are distinguished from normal symbols by adding
+     a '@' after the identifying letter for the symbol class and type.  */
+static bool mark_special;
+
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+  int result = 0;
+
+  /* We use no threads here which can interfere with handling a stream.  */
+  (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+  (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  /* Make sure the message catalog can be found.  */
+  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+
+  /* Initialize the message catalog.  */
+  (void) textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  */
+  (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+  /* Tell the library which version we are expecting.  */
+  (void) elf_version (EV_CURRENT);
+
+  if (remaining == argc)
+    /* The user didn't specify a name so we use a.out.  */
+    result = process_file ("a.out", false);
+  else
+    {
+      /* Process all the remaining files.  */
+      const bool more_than_one = remaining + 1 < argc;
+
+      do
+	result |= process_file (argv[remaining], more_than_one);
+      while (++remaining < argc);
+    }
+
+  return result;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg,
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case 'a':
+      /* XXX */
+      break;
+
+#ifdef USE_DEMANGLE
+    case 'C':
+      demangle = true;
+      break;
+#endif
+
+    case 'f':
+      if (strcmp (arg, "bsd") == 0)
+	format = format_bsd;
+      else if (strcmp (arg, "posix") == 0)
+	format = format_posix;
+      else
+	/* Be bug compatible.  The BFD implementation also defaulted to
+	   using the SysV format if nothing else matches.  */
+	format = format_sysv;
+      break;
+
+    case 'g':
+      hide_local = true;
+      break;
+
+    case 'n':
+      sort = sort_numeric;
+      break;
+
+    case 'p':
+      sort = sort_nosort;
+      break;
+
+    case 't':
+      if (strcmp (arg, "10") == 0 || strcmp (arg, "d") == 0)
+	radix = radix_decimal;
+      else if (strcmp (arg, "8") == 0 || strcmp (arg, "o") == 0)
+	radix = radix_octal;
+      else
+	radix = radix_hex;
+      break;
+
+    case 'u':
+      hide_undefined = false;
+      hide_defined = true;
+      break;
+
+    case 'A':
+    case 'o':
+      print_file_name = true;
+      break;
+
+    case 'B':
+      format = format_bsd;
+      break;
+
+    case 'D':
+      symsec_type = SHT_DYNSYM;
+      break;
+
+    case 'P':
+      format = format_posix;
+      break;
+
+    case OPT_DEFINED:
+      hide_undefined = true;
+      hide_defined = false;
+      break;
+
+    case OPT_MARK_SPECIAL:
+      mark_special = true;
+      break;
+
+    case 'S':
+      print_size = true;
+      break;
+
+    case 's':
+      print_armap = true;
+      break;
+
+    case 'r':
+      reverse_sort = true;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+/* Open the file and determine the type.  */
+static int
+process_file (const char *fname, bool more_than_one)
+{
+  /* Open the file.  */
+  int fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      error (0, errno, gettext ("cannot open '%s'"), fname);
+      return 1;
+    }
+
+  /* Now get the ELF descriptor.  */
+  Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+  if (elf != NULL)
+    {
+      if (elf_kind (elf) == ELF_K_ELF)
+	{
+	  int result = handle_elf (fd, elf, more_than_one ? "" : NULL,
+				   fname, NULL);
+
+	  if (elf_end (elf) != 0)
+	    INTERNAL_ERROR (fname);
+
+	  if (close (fd) != 0)
+	    error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
+
+	  return result;
+	}
+      else if (elf_kind (elf) == ELF_K_AR)
+	{
+	  int result = handle_ar (fd, elf, NULL, fname, NULL);
+
+	  if (elf_end (elf) != 0)
+	    INTERNAL_ERROR (fname);
+
+	  if (close (fd) != 0)
+	    error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
+
+	  return result;
+	}
+
+      /* We cannot handle this type.  Close the descriptor anyway.  */
+      if (elf_end (elf) != 0)
+	INTERNAL_ERROR (fname);
+    }
+
+  error (0, 0, gettext ("%s: File format not recognized"), fname);
+
+  return 1;
+}
+
+
+static int
+handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
+	   const char *suffix)
+{
+  size_t fname_len = strlen (fname) + 1;
+  size_t prefix_len = prefix != NULL ? strlen (prefix) : 0;
+  char new_prefix[prefix_len + fname_len + 2];
+  size_t suffix_len = suffix != NULL ? strlen (suffix) : 0;
+  char new_suffix[suffix_len + 2];
+  Elf *subelf;
+  Elf_Cmd cmd = ELF_C_READ_MMAP;
+  int result = 0;
+
+  char *cp = new_prefix;
+  if (prefix != NULL)
+    cp = stpcpy (cp, prefix);
+  cp = stpcpy (cp, fname);
+  stpcpy (cp, "[");
+
+  cp = new_suffix;
+  if (suffix != NULL)
+    cp = stpcpy (cp, suffix);
+  stpcpy (cp, "]");
+
+  /* First print the archive index if this is wanted.  */
+  if (print_armap)
+    {
+      Elf_Arsym *arsym = elf_getarsym (elf, NULL);
+
+      if (arsym != NULL)
+	{
+	  Elf_Arhdr *arhdr = NULL;
+	  size_t arhdr_off = 0;	/* Note: 0 is no valid offset.  */
+
+	  fputs_unlocked (gettext("\nArchive index:\n"), stdout);
+
+	  while (arsym->as_off != 0)
+	    {
+	      if (arhdr_off != arsym->as_off
+		  && (elf_rand (elf, arsym->as_off) != arsym->as_off
+		      || (subelf = elf_begin (fd, cmd, elf)) == NULL
+		      || (arhdr = elf_getarhdr (subelf)) == NULL))
+		{
+		  error (0, 0, gettext ("invalid offset %zu for symbol %s"),
+			 arsym->as_off, arsym->as_name);
+		  break;
+		}
+
+	      printf (gettext ("%s in %s\n"), arsym->as_name, arhdr->ar_name);
+
+	      ++arsym;
+	    }
+
+	  if (elf_rand (elf, SARMAG) != SARMAG)
+	    {
+	      error (0, 0,
+		     gettext ("cannot reset archive offset to beginning"));
+	      return 1;
+	    }
+	}
+    }
+
+  /* Process all the files contained in the archive.  */
+  while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+    {
+      /* The the header for this element.  */
+      Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+
+      /* Skip over the index entries.  */
+      if (strcmp (arhdr->ar_name, "/") != 0
+	  && strcmp (arhdr->ar_name, "//") != 0
+	  && strcmp (arhdr->ar_name, "/SYM64/") != 0)
+	{
+	  if (elf_kind (subelf) == ELF_K_ELF)
+	    result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name,
+				  new_suffix);
+	  else if (elf_kind (subelf) == ELF_K_AR)
+	    result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name,
+				 new_suffix);
+	  else
+	    {
+	      error (0, 0, gettext ("%s%s%s: file format not recognized"),
+		     new_prefix, arhdr->ar_name, new_suffix);
+	      result = 1;
+	    }
+	}
+
+      /* Get next archive element.  */
+      cmd = elf_next (subelf);
+      if (elf_end (subelf) != 0)
+	INTERNAL_ERROR (fname);
+    }
+
+  return result;
+}
+
+
+/* Mapping of radix and binary class to length.  */
+static const int length_map[2][3] =
+{
+  [ELFCLASS32 - 1] =
+  {
+    [radix_hex] = 8,
+    [radix_decimal] = 10,
+    [radix_octal] = 11
+  },
+  [ELFCLASS64 - 1] =
+  {
+    [radix_hex] = 16,
+    [radix_decimal] = 20,
+    [radix_octal] = 22
+  }
+};
+
+
+static int
+global_compare (const void *p1, const void *p2)
+{
+  const Dwarf_Global *g1 = (const Dwarf_Global *) p1;
+  const Dwarf_Global *g2 = (const Dwarf_Global *) p2;
+
+  return strcmp (g1->name, g2->name);
+}
+
+
+static void *global_root;
+
+
+static int
+get_global (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
+	    void *arg __attribute__ ((unused)))
+{
+  tsearch (memcpy (xmalloc (sizeof (Dwarf_Global)), global,
+		   sizeof (Dwarf_Global)),
+	   &global_root, global_compare);
+
+  return DWARF_CB_OK;
+}
+
+
+struct local_name
+{
+  const char *name;
+  const char *file;
+  Dwarf_Word lineno;
+  Dwarf_Addr lowpc;
+  Dwarf_Addr highpc;
+};
+
+
+static int
+local_compare (const void *p1, const void *p2)
+{
+  struct local_name *g1 = (struct local_name *) p1;
+  struct local_name *g2 = (struct local_name *) p2;
+  int result;
+
+  result = strcmp (g1->name, g2->name);
+  if (result == 0)
+    {
+      if (g1->lowpc <= g2->lowpc && g1->highpc >= g2->highpc)
+	{
+	  /* g2 is contained in g1.  Update the data.  */
+	  g2->lowpc = g1->lowpc;
+	  g2->highpc = g1->highpc;
+	  result = 0;
+	}
+      else if (g2->lowpc <= g1->lowpc && g2->highpc >= g1->highpc)
+	{
+	  /* g1 is contained in g2.  Update the data.  */
+	  g1->lowpc = g2->lowpc;
+	  g1->highpc = g2->highpc;
+	  result = 0;
+	}
+      else
+	result = g1->lowpc < g2->lowpc ? -1 : 1;
+    }
+
+  return result;
+}
+
+
+static int
+get_var_range (Dwarf_Die *die, Dwarf_Word *lowpc, Dwarf_Word *highpc)
+{
+  Dwarf_Attribute locattr_mem;
+  Dwarf_Attribute *locattr = dwarf_attr (die, DW_AT_location, &locattr_mem);
+  if  (locattr == NULL)
+    return 1;
+
+  Dwarf_Op *loc;
+  size_t nloc;
+  if (dwarf_getlocation (locattr, &loc, &nloc) != 0)
+    return 1;
+
+  /* Interpret the location expressions.  */
+  // XXX For now just the simple one:
+  if (nloc == 1 && loc[0].atom == DW_OP_addr)
+    {
+      *lowpc = *highpc = loc[0].number;
+      return 0;
+    }
+
+  return 1;
+}
+
+
+
+static void *local_root;
+
+
+static void
+get_local_names (Dwarf *dbg)
+{
+  Dwarf_Off offset = 0;
+  Dwarf_Off old_offset;
+  size_t hsize;
+
+  while (dwarf_nextcu (dbg, old_offset = offset, &offset, &hsize, NULL, NULL,
+		       NULL) == 0)
+    {
+      Dwarf_Die cudie_mem;
+      Dwarf_Die *cudie = dwarf_offdie (dbg, old_offset + hsize, &cudie_mem);
+
+      /* If we cannot get the CU DIE there is no need to go on with
+	 this CU.  */
+      if (cudie == NULL)
+	continue;
+      /* This better be a CU DIE.  */
+      if (dwarf_tag (cudie) != DW_TAG_compile_unit)
+	continue;
+
+      /* Get the line information.  */
+      Dwarf_Files *files;
+      size_t nfiles;
+      if (dwarf_getsrcfiles (cudie, &files, &nfiles) != 0)
+	continue;
+
+      Dwarf_Die die_mem;
+      Dwarf_Die *die = &die_mem;
+      if (dwarf_child (cudie, die) == 0)
+	/* Iterate over all immediate children of the CU DIE.  */
+	do
+	  {
+	    int tag = dwarf_tag (die);
+	    if (tag != DW_TAG_subprogram && tag != DW_TAG_variable)
+	      continue;
+
+	    /* We are interested in five attributes: name, decl_file,
+	       decl_line, low_pc, and high_pc.  */
+	    Dwarf_Attribute attr_mem;
+	    Dwarf_Attribute *attr = dwarf_attr (die, DW_AT_name, &attr_mem);
+	    const char *name = dwarf_formstring (attr);
+	    if (name == NULL)
+	      continue;
+
+	    Dwarf_Word fileidx;
+	    attr = dwarf_attr (die, DW_AT_decl_file, &attr_mem);
+	    if (dwarf_formudata (attr, &fileidx) != 0 || fileidx >= nfiles)
+	      continue;
+
+	    Dwarf_Word lineno;
+	    attr = dwarf_attr (die, DW_AT_decl_line, &attr_mem);
+	    if (dwarf_formudata (attr, &lineno) != 0 || lineno == 0)
+	      continue;
+
+	    Dwarf_Addr lowpc;
+	    Dwarf_Addr highpc;
+	    if (tag == DW_TAG_subprogram)
+	      {
+		if (dwarf_lowpc (die, &lowpc) != 0
+		    || dwarf_highpc (die, &highpc) != 0)
+		  continue;
+	      }
+	    else
+	      {
+		if (get_var_range (die, &lowpc, &highpc) != 0)
+		  continue;
+	      }
+
+	    /* We have all the information.  Create a record.  */
+	    struct local_name *newp
+	      = (struct local_name *) xmalloc (sizeof (*newp));
+	    newp->name = name;
+	    newp->file = dwarf_filesrc (files, fileidx, NULL, NULL);
+	    newp->lineno = lineno;
+	    newp->lowpc = lowpc;
+	    newp->highpc = highpc;
+
+	   /* Check whether a similar local_name is already in the
+	      cache.  That should not happen.  But if it does, we
+	      don't want to leak memory.  */
+	    struct local_name **tres = tsearch (newp, &local_root,
+						local_compare);
+	    if (tres == NULL)
+              error (EXIT_FAILURE, errno,
+                     gettext ("cannot create search tree"));
+	    else if (*tres != newp)
+	      free (newp);
+	  }
+	while (dwarf_siblingof (die, die) == 0);
+    }
+}
+
+/* Do elf_strptr, but return a backup string and never NULL.  */
+static const char *
+sym_name (Elf *elf, GElf_Word strndx, GElf_Word st_name, char buf[], size_t n)
+{
+  const char *symstr = elf_strptr (elf, strndx, st_name);
+  if (symstr == NULL)
+    {
+      snprintf (buf, n, "[invalid st_name %#" PRIx32 "]", st_name);
+      symstr = buf;
+    }
+  return symstr;
+}
+
+/* Show symbols in SysV format.  */
+static void
+show_symbols_sysv (Ebl *ebl, GElf_Word strndx, const char *fullname,
+		   GElf_SymX *syms, size_t nsyms, int longest_name,
+		   int longest_where)
+{
+  size_t shnum;
+  if (elf_getshdrnum (ebl->elf, &shnum) < 0)
+    INTERNAL_ERROR (fullname);
+
+  bool scnnames_malloced = shnum * sizeof (const char *) > 128 * 1024;
+  const char **scnnames;
+  if (scnnames_malloced)
+    scnnames = (const char **) xmalloc (sizeof (const char *) * shnum);
+  else
+    scnnames = (const char **) alloca (sizeof (const char *) * shnum);
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  /* Cache the section names.  */
+  Elf_Scn *scn = NULL;
+  size_t cnt = 1;
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+
+      assert (elf_ndxscn (scn) == cnt);
+      cnt++;
+
+      char *name = elf_strptr (ebl->elf, shstrndx,
+			       gelf_getshdr (scn, &shdr_mem)->sh_name);
+      if (unlikely (name == NULL))
+	{
+	  const size_t bufsz = sizeof "[invalid sh_name 0x12345678]";
+	  name = alloca (bufsz);
+	  snprintf (name, bufsz, "[invalid sh_name %#" PRIx32 "]",
+		    gelf_getshdr (scn, &shdr_mem)->sh_name);
+	}
+      scnnames[elf_ndxscn (scn)] = name;
+    }
+
+  int digits = length_map[gelf_getclass (ebl->elf) - 1][radix];
+
+  /* We always print this prolog.  */
+  printf (gettext ("\n\nSymbols from %s:\n\n"), fullname);
+
+  /* The header line.  */
+  printf (gettext ("%*s%-*s %-*s Class  Type     %-*s %*s Section\n\n"),
+	  print_file_name ? (int) strlen (fullname) + 1: 0, "",
+	  longest_name, sgettext ("sysv|Name"),
+	  /* TRANS: the "sysv|" parts makes the string unique.  */
+	  digits, sgettext ("sysv|Value"),
+	  /* TRANS: the "sysv|" parts makes the string unique.  */
+	  digits, sgettext ("sysv|Size"),
+	  /* TRANS: the "sysv|" parts makes the string unique.  */
+	  longest_where, sgettext ("sysv|Line"));
+
+#ifdef USE_DEMANGLE
+  size_t demangle_buffer_len = 0;
+  char *demangle_buffer = NULL;
+#endif
+
+  /* Iterate over all symbols.  */
+  for (cnt = 1; cnt < nsyms; ++cnt)
+    {
+      /* In this format SECTION entries are not printed.  */
+      if (GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_SECTION)
+	continue;
+
+      char symstrbuf[50];
+      const char *symstr = sym_name (ebl->elf, strndx, syms[cnt].sym.st_name,
+				     symstrbuf, sizeof symstrbuf);
+
+#ifdef USE_DEMANGLE
+      /* Demangle if necessary.  Require GNU v3 ABI by the "_Z" prefix.  */
+      if (demangle && symstr[0] == '_' && symstr[1] == 'Z')
+	{
+	  int status = -1;
+	  char *dmsymstr = __cxa_demangle (symstr, demangle_buffer,
+					   &demangle_buffer_len, &status);
+
+	  if (status == 0)
+	    symstr = dmsymstr;
+	}
+#endif
+
+      char symbindbuf[50];
+      char symtypebuf[50];
+      char secnamebuf[1024];
+      char addressbuf[(64 + 2) / 3 + 1];
+      char sizebuf[(64 + 2) / 3 + 1];
+
+      /* If we have to precede the line with the file name.  */
+      if (print_file_name)
+	{
+	  fputs_unlocked (fullname, stdout);
+	  putchar_unlocked (':');
+	}
+
+      /* Covert the address.  */
+      if (syms[cnt].sym.st_shndx == SHN_UNDEF)
+	addressbuf[0] = sizebuf[0] = '\0';
+      else
+	{
+	  snprintf (addressbuf, sizeof (addressbuf),
+		    (radix == radix_hex ? "%0*" PRIx64
+		     : (radix == radix_decimal ? "%0*" PRId64
+			: "%0*" PRIo64)),
+		    digits, syms[cnt].sym.st_value);
+	  snprintf (sizebuf, sizeof (sizebuf),
+		    (radix == radix_hex ? "%0*" PRIx64
+		     : (radix == radix_decimal ? "%0*" PRId64
+			: "%0*" PRIo64)),
+		    digits, syms[cnt].sym.st_size);
+	}
+
+      /* Print the actual string.  */
+      printf ("%-*s|%s|%-6s|%-8s|%s|%*s|%s\n",
+	      longest_name, symstr, addressbuf,
+	      ebl_symbol_binding_name (ebl,
+				       GELF_ST_BIND (syms[cnt].sym.st_info),
+				       symbindbuf, sizeof (symbindbuf)),
+	      ebl_symbol_type_name (ebl, GELF_ST_TYPE (syms[cnt].sym.st_info),
+				    symtypebuf, sizeof (symtypebuf)),
+	      sizebuf, longest_where, syms[cnt].where,
+	      ebl_section_name (ebl, syms[cnt].sym.st_shndx, syms[cnt].xndx,
+				secnamebuf, sizeof (secnamebuf), scnnames,
+				shnum));
+    }
+
+#ifdef USE_DEMANGLE
+  free (demangle_buffer);
+#endif
+
+  if (scnnames_malloced)
+    free (scnnames);
+}
+
+
+static char
+class_type_char (Elf *elf, const GElf_Ehdr *ehdr, GElf_Sym *sym)
+{
+  int local_p = GELF_ST_BIND (sym->st_info) == STB_LOCAL;
+
+  /* XXX Add support for architecture specific types and classes.  */
+  if (sym->st_shndx == SHN_ABS)
+    return local_p ? 'a' : 'A';
+
+  if (sym->st_shndx == SHN_UNDEF)
+    /* Undefined symbols must be global.  */
+    return 'U';
+
+  char result = "NDTSFBD         "[GELF_ST_TYPE (sym->st_info)];
+
+  if (result == 'D')
+    {
+      /* Special handling: unique data symbols.  */
+      if (ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX
+	  && GELF_ST_BIND (sym->st_info) == STB_GNU_UNIQUE)
+	result = 'u';
+      else
+	{
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, sym->st_shndx),
+					  &shdr_mem);
+	  if (shdr != NULL)
+	    {
+	      if ((shdr->sh_flags & SHF_WRITE) == 0)
+		result = 'R';
+	      else if (shdr->sh_type == SHT_NOBITS)
+		result = 'B';
+	    }
+	}
+    }
+
+  return local_p ? tolower (result) : result;
+}
+
+
+static void
+show_symbols_bsd (Elf *elf, const GElf_Ehdr *ehdr, GElf_Word strndx,
+		  const char *prefix, const char *fname, const char *fullname,
+		  GElf_SymX *syms, size_t nsyms)
+{
+  int digits = length_map[gelf_getclass (elf) - 1][radix];
+
+  if (prefix != NULL && ! print_file_name)
+    printf ("\n%s:\n", fname);
+
+#ifdef USE_DEMANGLE
+  size_t demangle_buffer_len = 0;
+  char *demangle_buffer = NULL;
+#endif
+
+  /* Iterate over all symbols.  */
+  for (size_t cnt = 0; cnt < nsyms; ++cnt)
+    {
+      char symstrbuf[50];
+      const char *symstr = sym_name (elf, strndx, syms[cnt].sym.st_name,
+				     symstrbuf, sizeof symstrbuf);
+
+      /* Printing entries with a zero-length name makes the output
+	 not very well parseable.  Since these entries don't carry
+	 much information we leave them out.  */
+      if (symstr[0] == '\0')
+	continue;
+
+      /* We do not print the entries for files.  */
+      if (GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_FILE)
+	continue;
+
+#ifdef USE_DEMANGLE
+      /* Demangle if necessary.  Require GNU v3 ABI by the "_Z" prefix.  */
+      if (demangle && symstr[0] == '_' && symstr[1] == 'Z')
+	{
+	  int status = -1;
+	  char *dmsymstr = __cxa_demangle (symstr, demangle_buffer,
+					   &demangle_buffer_len, &status);
+
+	  if (status == 0)
+	    symstr = dmsymstr;
+	}
+#endif
+
+      /* If we have to precede the line with the file name.  */
+      if (print_file_name)
+	{
+	  fputs_unlocked (fullname, stdout);
+	  putchar_unlocked (':');
+	}
+
+      bool is_tls = GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_TLS;
+      bool is_weak = GELF_ST_BIND (syms[cnt].sym.st_info) == STB_WEAK;
+      const char *marker = (mark_special
+			    ? (is_tls ? "@" : (is_weak ? "*" : " ")) : "");
+
+      if (syms[cnt].sym.st_shndx == SHN_UNDEF)
+	{
+	  const char *color = "";
+	  if (color_mode)
+	    {
+	      if (is_tls)
+		color = color_undef_tls;
+	      else if (is_weak)
+		color = color_undef_weak;
+	      else
+		color = color_undef;
+	    }
+
+	  printf ("%*s %sU%s %s", digits, "", color, marker, symstr);
+	}
+      else
+	{
+	  const char *color = "";
+	  if (color_mode)
+	    {
+	      if (is_tls)
+		color = color_tls;
+	      else if (is_weak)
+		color = color_weak;
+	      else
+		color = color_symbol;
+	    }
+	  if (print_size && syms[cnt].sym.st_size != 0)
+	    {
+#define HEXFMT "%6$s%2$0*1$" PRIx64 "%8$s %10$0*9$" PRIx64 " %7$s%3$c%4$s %5$s"
+#define DECFMT "%6$s%2$*1$" PRId64 "%8$s %10$*9$" PRId64 " %7$s%3$c%4$s %5$s"
+#define OCTFMT "%6$s%2$0*1$" PRIo64 "%8$s %10$0*9$" PRIo64 " %7$s%3$c%4$s %5$s"
+	      printf ((radix == radix_hex ? HEXFMT
+		       : (radix == radix_decimal ? DECFMT : OCTFMT)),
+		      digits, syms[cnt].sym.st_value,
+		      class_type_char (elf, ehdr, &syms[cnt].sym), marker,
+		      symstr,
+		      color_mode ? color_address : "",
+		      color,
+		      color_mode ? color_off : "",
+		      digits, (uint64_t) syms[cnt].sym.st_size);
+#undef HEXFMT
+#undef DECFMT
+#undef OCTFMT
+	    }
+	  else
+	    {
+#define HEXFMT "%6$s%2$0*1$" PRIx64 "%8$s %7$s%3$c%4$s %5$s"
+#define DECFMT "%6$s%2$*1$" PRId64 "%8$s %7$s%3$c%4$s %5$s"
+#define OCTFMT "%6$s%2$0*1$" PRIo64 "%8$s %7$s%3$c%4$s %5$s"
+	      printf ((radix == radix_hex ? HEXFMT
+		       : (radix == radix_decimal ? DECFMT : OCTFMT)),
+		      digits, syms[cnt].sym.st_value,
+		      class_type_char (elf, ehdr, &syms[cnt].sym), marker,
+		      symstr,
+		      color_mode ? color_address : "",
+		      color,
+		      color_mode ? color_off : "");
+#undef HEXFMT
+#undef DECFMT
+#undef OCTFMT
+	    }
+	}
+
+      if (color_mode)
+	fputs_unlocked (color_off, stdout);
+      putchar_unlocked ('\n');
+    }
+
+#ifdef USE_DEMANGLE
+  free (demangle_buffer);
+#endif
+}
+
+
+static void
+show_symbols_posix (Elf *elf, const GElf_Ehdr *ehdr, GElf_Word strndx,
+		    const char *prefix, const char *fullname, GElf_SymX *syms,
+		    size_t nsyms)
+{
+  if (prefix != NULL && ! print_file_name)
+    printf ("%s:\n", fullname);
+
+  int digits = length_map[gelf_getclass (elf) - 1][radix];
+
+#ifdef USE_DEMANGLE
+  size_t demangle_buffer_len = 0;
+  char *demangle_buffer = NULL;
+#endif
+
+  /* Iterate over all symbols.  */
+  for (size_t cnt = 0; cnt < nsyms; ++cnt)
+    {
+      char symstrbuf[50];
+      const char *symstr = sym_name (elf, strndx, syms[cnt].sym.st_name,
+				     symstrbuf, sizeof symstrbuf);
+
+      /* Printing entries with a zero-length name makes the output
+	 not very well parseable.  Since these entries don't carry
+	 much information we leave them out.  */
+      if (symstr[0] == '\0')
+	continue;
+
+#ifdef USE_DEMANGLE
+      /* Demangle if necessary.  Require GNU v3 ABI by the "_Z" prefix.  */
+      if (demangle && symstr[0] == '_' && symstr[1] == 'Z')
+	{
+	  int status = -1;
+	  char *dmsymstr = __cxa_demangle (symstr, demangle_buffer,
+					   &demangle_buffer_len, &status);
+
+	  if (status == 0)
+	    symstr = dmsymstr;
+	}
+#endif
+
+      /* If we have to precede the line with the file name.  */
+      if (print_file_name)
+	{
+	  fputs_unlocked (fullname, stdout);
+	  putchar_unlocked (':');
+	  putchar_unlocked (' ');
+	}
+
+      printf ((radix == radix_hex
+	       ? "%s %c%s %0*" PRIx64 " %0*" PRIx64 "\n"
+	       : (radix == radix_decimal
+		  ? "%s %c%s %*" PRId64 " %*" PRId64 "\n"
+		  : "%s %c%s %0*" PRIo64 " %0*" PRIo64 "\n")),
+	      symstr,
+	      class_type_char (elf, ehdr, &syms[cnt].sym),
+	      mark_special
+	      ? (GELF_ST_TYPE (syms[cnt].sym.st_info) == STT_TLS
+		 ? "@"
+		 : (GELF_ST_BIND (syms[cnt].sym.st_info) == STB_WEAK
+		    ? "*" : " "))
+	      : "",
+	      digits, syms[cnt].sym.st_value,
+	      digits, syms[cnt].sym.st_size);
+    }
+
+#ifdef USE_DEMANGLE
+  free (demangle_buffer);
+#endif
+}
+
+
+/* Maximum size of memory we allocate on the stack.  */
+#define MAX_STACK_ALLOC	65536
+
+static int
+sort_by_address (const void *p1, const void *p2)
+{
+  GElf_SymX *s1 = (GElf_SymX *) p1;
+  GElf_SymX *s2 = (GElf_SymX *) p2;
+
+  int result = (s1->sym.st_value < s2->sym.st_value
+		? -1 : (s1->sym.st_value == s2->sym.st_value ? 0 : 1));
+
+  return reverse_sort ? -result : result;
+}
+
+static Elf_Data *sort_by_name_strtab;
+
+static int
+sort_by_name (const void *p1, const void *p2)
+{
+  GElf_SymX *s1 = (GElf_SymX *) p1;
+  GElf_SymX *s2 = (GElf_SymX *) p2;
+
+  const char *n1 = sort_by_name_strtab->d_buf + s1->sym.st_name;
+  const char *n2 = sort_by_name_strtab->d_buf + s2->sym.st_name;
+
+  int result = strcmp (n1, n2);
+
+  return reverse_sort ? -result : result;
+}
+
+/* Stub libdwfl callback, only the ELF handle already open is ever
+   used.  Only used for finding the alternate debug file if the Dwarf
+   comes from the main file.  We are not interested in separate
+   debuginfo.  */
+static int
+find_no_debuginfo (Dwfl_Module *mod,
+		   void **userdata,
+		   const char *modname,
+		   Dwarf_Addr base,
+		   const char *file_name,
+		   const char *debuglink_file,
+		   GElf_Word debuglink_crc,
+		   char **debuginfo_file_name)
+{
+  Dwarf_Addr dwbias;
+  dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
+
+  /* We are only interested if the Dwarf has been setup on the main
+     elf file but is only missing the alternate debug link.  If dwbias
+     hasn't even been setup, this is searching for separate debuginfo
+     for the main elf.  We don't care in that case.  */
+  if (dwbias == (Dwarf_Addr) -1)
+    return -1;
+
+  return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
+				       file_name, debuglink_file,
+				       debuglink_crc, debuginfo_file_name);
+}
+
+/* Get the Dwarf for the module/file we want.  */
+struct getdbg
+{
+  const char *name;
+  Dwarf **dbg;
+};
+
+static int
+getdbg_dwflmod (Dwfl_Module *dwflmod,
+		void **userdata __attribute__ ((unused)),
+		const char *name,
+		Dwarf_Addr base __attribute__ ((unused)),
+		void *arg)
+{
+  struct getdbg *get = (struct getdbg *) arg;
+  if (get != NULL && get->name != NULL && strcmp (get->name, name) == 0)
+    {
+      Dwarf_Addr bias;
+      *get->dbg = dwfl_module_getdwarf (dwflmod, &bias);
+      return DWARF_CB_ABORT;
+    }
+
+  return DWARF_CB_OK;
+}
+
+static void
+show_symbols (int fd, Ebl *ebl, GElf_Ehdr *ehdr,
+	      Elf_Scn *scn, Elf_Scn *xndxscn,
+	      GElf_Shdr *shdr, const char *prefix, const char *fname,
+	      const char *fullname)
+{
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  /* The section is that large.  */
+  size_t size = shdr->sh_size;
+  /* One entry is this large.  */
+  size_t entsize = shdr->sh_entsize;
+
+  /* Consistency checks.  */
+  if (entsize == 0
+      || entsize != gelf_fsize (ebl->elf, ELF_T_SYM, 1, EV_CURRENT))
+    error (0, 0,
+	   gettext ("%s: entry size in section %zd `%s' is not what we expect"),
+	   fullname, elf_ndxscn (scn),
+	   elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
+  else if (size % entsize != 0)
+    error (0, 0,
+	   gettext ("%s: size of section %zd `%s' is not multiple of entry size"),
+	   fullname, elf_ndxscn (scn),
+	   elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
+
+  /* Compute number of entries.  Handle buggy entsize values.  */
+  size_t nentries = size / (entsize ?: 1);
+
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+  struct obstack whereob;
+  obstack_init (&whereob);
+
+  /* Get a DWARF debugging descriptor.  It's no problem if this isn't
+     possible.  We just won't print any line number information.  */
+  Dwarf *dbg = NULL;
+  Dwfl *dwfl = NULL;
+  if (format == format_sysv)
+    {
+      if (ehdr->e_type != ET_REL)
+	dbg = dwarf_begin_elf (ebl->elf, DWARF_C_READ, NULL);
+      else
+	{
+	  /* Abuse libdwfl to do the relocations for us.  This is just
+	     for the ET_REL file containing Dwarf, so no need for
+	     fancy lookups.  */
+
+	  /* Duplicate an fd for dwfl_report_offline to swallow.  */
+	  int dwfl_fd = dup (fd);
+	  if (likely (dwfl_fd >= 0))
+	    {
+	      static const Dwfl_Callbacks callbacks =
+		{
+		  .section_address = dwfl_offline_section_address,
+		  .find_debuginfo = find_no_debuginfo
+		};
+	      dwfl = dwfl_begin (&callbacks);
+	      if (likely (dwfl != NULL))
+		{
+		  /* Let 0 be the logical address of the file (or
+		     first in archive).  */
+		  dwfl->offline_next_address = 0;
+		  if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd)
+		      == NULL)
+		    {
+		      /* Consumed on success, not on failure.  */
+		      close (dwfl_fd);
+		    }
+		  else
+		    {
+		      dwfl_report_end (dwfl, NULL, NULL);
+
+		      struct getdbg get = { .name = fname, .dbg = &dbg };
+		      dwfl_getmodules (dwfl, &getdbg_dwflmod, &get, 0);
+		    }
+		}
+	    }
+	}
+      if (dbg != NULL)
+	{
+	  (void) dwarf_getpubnames (dbg, get_global, NULL, 0);
+
+	  get_local_names (dbg);
+	}
+    }
+
+  /* Get the data of the section.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  Elf_Data *xndxdata = elf_getdata (xndxscn, NULL);
+  if (data == NULL || (xndxscn != NULL && xndxdata == NULL))
+    INTERNAL_ERROR (fullname);
+
+  /* Allocate the memory.
+
+     XXX We can use a dirty trick here.  Since GElf_Sym == Elf64_Sym we
+     can use the data memory instead of copying again if what we read
+     is a 64 bit file.  */
+  if (nentries > SIZE_MAX / sizeof (GElf_SymX))
+    error (EXIT_FAILURE, 0,
+          gettext ("%s: entries (%zd) in section %zd `%s' is too large"),
+          fullname, nentries, elf_ndxscn (scn),
+          elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
+  GElf_SymX *sym_mem;
+  if (nentries * sizeof (GElf_SymX) < MAX_STACK_ALLOC)
+    sym_mem = (GElf_SymX *) alloca (nentries * sizeof (GElf_SymX));
+  else
+    sym_mem = (GElf_SymX *) xmalloc (nentries * sizeof (GElf_SymX));
+
+  /* Iterate over all symbols.  */
+#ifdef USE_DEMANGLE
+  size_t demangle_buffer_len = 0;
+  char *demangle_buffer = NULL;
+#endif
+  int longest_name = 4;
+  int longest_where = 4;
+  size_t nentries_used = 0;
+  for (size_t cnt = 0; cnt < nentries; ++cnt)
+    {
+      GElf_Sym *sym = gelf_getsymshndx (data, xndxdata, cnt,
+					&sym_mem[nentries_used].sym,
+					&sym_mem[nentries_used].xndx);
+      if (sym == NULL)
+	INTERNAL_ERROR (fullname);
+
+      /* Filter out administrative symbols without a name and those
+	 deselected by the user with command line options.  */
+      if ((hide_undefined && sym->st_shndx == SHN_UNDEF)
+	  || (hide_defined && sym->st_shndx != SHN_UNDEF)
+	  || (hide_local && GELF_ST_BIND (sym->st_info) == STB_LOCAL))
+	continue;
+
+      sym_mem[nentries_used].where = "";
+      if (format == format_sysv)
+	{
+	  const char *symstr = elf_strptr (ebl->elf, shdr->sh_link,
+					   sym->st_name);
+	  if (symstr == NULL)
+	    continue;
+
+#ifdef USE_DEMANGLE
+	  /* Demangle if necessary.  Require GNU v3 ABI by the "_Z" prefix.  */
+	  if (demangle && symstr[0] == '_' && symstr[1] == 'Z')
+	    {
+	      int status = -1;
+	      char *dmsymstr = __cxa_demangle (symstr, demangle_buffer,
+					       &demangle_buffer_len, &status);
+
+	      if (status == 0)
+		symstr = dmsymstr;
+	    }
+#endif
+
+	  longest_name = MAX ((size_t) longest_name, strlen (symstr));
+
+	  if (sym->st_shndx != SHN_UNDEF
+	      && GELF_ST_BIND (sym->st_info) != STB_LOCAL
+	      && global_root != NULL)
+	    {
+	      Dwarf_Global fake = { .name = symstr };
+	      Dwarf_Global **found = tfind (&fake, &global_root,
+					    global_compare);
+	      if (found != NULL)
+		{
+		  Dwarf_Die die_mem;
+		  Dwarf_Die *die = dwarf_offdie (dbg, (*found)->die_offset,
+						 &die_mem);
+
+		  Dwarf_Die cudie_mem;
+		  Dwarf_Die *cudie = NULL;
+
+		  Dwarf_Addr lowpc;
+		  Dwarf_Addr highpc;
+		  if (die != NULL
+		      && dwarf_lowpc (die, &lowpc) == 0
+		      && lowpc <= sym->st_value
+		      && dwarf_highpc (die, &highpc) == 0
+		      && highpc > sym->st_value)
+		    cudie = dwarf_offdie (dbg, (*found)->cu_offset,
+					  &cudie_mem);
+		  if (cudie != NULL)
+		    {
+		      Dwarf_Line *line = dwarf_getsrc_die (cudie,
+							   sym->st_value);
+		      if (line != NULL)
+			{
+			  /* We found the line.  */
+			  int lineno;
+			  (void) dwarf_lineno (line, &lineno);
+			  const char *file = dwarf_linesrc (line, NULL, NULL);
+			  file = (file != NULL) ? basename (file) : "???";
+			  int n;
+			  n = obstack_printf (&whereob, "%s:%d%c", file,
+					      lineno, '\0');
+			  sym_mem[nentries_used].where
+			    = obstack_finish (&whereob);
+
+			  /* The return value of obstack_print included the
+			     NUL byte, so subtract one.  */
+			  if (--n > (int) longest_where)
+			    longest_where = (size_t) n;
+			}
+		    }
+		}
+	    }
+
+	  /* Try to find the symbol among the local symbols.  */
+	  if (sym_mem[nentries_used].where[0] == '\0')
+	    {
+	      struct local_name fake =
+		{
+		  .name = symstr,
+		  .lowpc = sym->st_value,
+		  .highpc = sym->st_value,
+		};
+	      struct local_name **found = tfind (&fake, &local_root,
+						 local_compare);
+	      if (found != NULL)
+		{
+		  /* We found the line.  */
+		  int n = obstack_printf (&whereob, "%s:%" PRIu64 "%c",
+					  basename ((*found)->file),
+					  (*found)->lineno,
+					  '\0');
+		  sym_mem[nentries_used].where = obstack_finish (&whereob);
+
+		  /* The return value of obstack_print included the
+		     NUL byte, so subtract one.  */
+		  if (--n > (int) longest_where)
+		    longest_where = (size_t) n;
+		}
+	    }
+	}
+
+      /* We use this entry.  */
+      ++nentries_used;
+    }
+#ifdef USE_DEMANGLE
+  free (demangle_buffer);
+#endif
+  /* Now we know the exact number.  */
+  nentries = nentries_used;
+
+  /* Sort the entries according to the users wishes.  */
+  if (sort == sort_name)
+    {
+      sort_by_name_strtab = elf_getdata (elf_getscn (ebl->elf, shdr->sh_link),
+					 NULL);
+      qsort (sym_mem, nentries, sizeof (GElf_SymX), sort_by_name);
+    }
+  else if (sort == sort_numeric)
+    qsort (sym_mem, nentries, sizeof (GElf_SymX), sort_by_address);
+
+  /* Finally print according to the users selection.  */
+  switch (format)
+    {
+    case format_sysv:
+      show_symbols_sysv (ebl, shdr->sh_link, fullname, sym_mem, nentries,
+			 longest_name, longest_where);
+      break;
+
+    case format_bsd:
+      show_symbols_bsd (ebl->elf, ehdr, shdr->sh_link, prefix, fname, fullname,
+			sym_mem, nentries);
+      break;
+
+    case format_posix:
+    default:
+      assert (format == format_posix);
+      show_symbols_posix (ebl->elf, ehdr, shdr->sh_link, prefix, fullname,
+			  sym_mem, nentries);
+      break;
+    }
+
+  /* Free all memory.  */
+  if (nentries * sizeof (sym_mem[0]) >= MAX_STACK_ALLOC)
+    free (sym_mem);
+
+  obstack_free (&whereob, NULL);
+
+  if (dbg != NULL)
+    {
+      tdestroy (global_root, free);
+      global_root = NULL;
+
+      tdestroy (local_root, free);
+      local_root = NULL;
+
+      if (dwfl == NULL)
+	(void) dwarf_end (dbg);
+    }
+  if (dwfl != NULL)
+    dwfl_end (dwfl);
+}
+
+
+static int
+handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
+	    const char *suffix)
+{
+  size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
+  size_t suffix_len = suffix == NULL ? 0 : strlen (suffix);
+  size_t fname_len = strlen (fname) + 1;
+  char fullname[prefix_len + 1 + fname_len + suffix_len];
+  char *cp = fullname;
+  Elf_Scn *scn = NULL;
+  int any = 0;
+  int result = 0;
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr;
+  Ebl *ebl;
+
+  /* Get the backend for this object file type.  */
+  ebl = ebl_openbackend (elf);
+
+  /* We need the ELF header in a few places.  */
+  ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    INTERNAL_ERROR (fullname);
+
+  /* If we are asked to print the dynamic symbol table and this is
+     executable or dynamic executable, fail.  */
+  if (symsec_type == SHT_DYNSYM
+      && ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
+    {
+      /* XXX Add machine specific object file types.  */
+      error (0, 0, gettext ("%s%s%s%s: Invalid operation"),
+	     prefix ?: "", prefix ? "(" : "", fname, prefix ? ")" : "");
+      result = 1;
+      goto out;
+    }
+
+  /* Create the full name of the file.  */
+  if (prefix != NULL)
+    cp = mempcpy (cp, prefix, prefix_len);
+  cp = mempcpy (cp, fname, fname_len);
+  if (suffix != NULL)
+    memcpy (cp - 1, suffix, suffix_len + 1);
+
+  /* Find the symbol table.
+
+     XXX Can there be more than one?  Do we print all?  Currently we do.  */
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr == NULL)
+	INTERNAL_ERROR (fullname);
+
+      if (shdr->sh_type == symsec_type)
+	{
+	  Elf_Scn *xndxscn = NULL;
+
+	  /* We have a symbol table.  First make sure we remember this.  */
+	  any = 1;
+
+	  /* Look for an extended section index table for this section.  */
+	  if (symsec_type == SHT_SYMTAB)
+	    {
+	      size_t scnndx = elf_ndxscn (scn);
+
+	      while ((xndxscn = elf_nextscn (elf, xndxscn)) != NULL)
+		{
+		  GElf_Shdr xndxshdr_mem;
+		  GElf_Shdr *xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
+
+		  if (xndxshdr == NULL)
+		    INTERNAL_ERROR (fullname);
+
+		  if (xndxshdr->sh_type == SHT_SYMTAB_SHNDX
+		      && xndxshdr->sh_link == scnndx)
+		    break;
+		}
+	    }
+
+	  show_symbols (fd, ebl, ehdr, scn, xndxscn, shdr, prefix, fname,
+			fullname);
+	}
+    }
+
+  if (! any)
+    {
+      error (0, 0, gettext ("%s%s%s: no symbols"),
+	     prefix ?: "", prefix ? ":" : "", fname);
+      result = 1;
+    }
+
+ out:
+  /* Close the ELF backend library descriptor.  */
+  ebl_closebackend (ebl);
+
+  return result;
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/objdump.c b/third_party/elfutils/src/objdump.c
new file mode 100644
index 0000000..0dd9a6a
--- /dev/null
+++ b/third_party/elfutils/src/objdump.c
@@ -0,0 +1,795 @@
+/* Print information from ELF file in human-readable form.
+   Copyright (C) 2005, 2006, 2007, 2009, 2011, 2012, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <error.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <libeu.h>
+#include <system.h>
+#include <color.h>
+#include <printversion.h>
+#include "../libebl/libeblP.h"
+
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("Mode selection:"), 0 },
+  { "reloc", 'r', NULL, 0, N_("Display relocation information."), 0 },
+  { "full-contents", 's', NULL, 0,
+    N_("Display the full contents of all sections requested"), 0 },
+  { "disassemble", 'd', NULL, 0,
+    N_("Display assembler code of executable sections"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Output content selection:"), 0 },
+  { "section", 'j', "NAME", 0,
+    N_("Only display information for section NAME."), 0 },
+
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("\
+Show information from FILEs (a.out by default).");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("[FILE...]");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Parser children.  */
+static struct argp_child argp_children[] =
+  {
+    { &color_argp, 0, N_("Output formatting"), 2 },
+    { NULL, 0, NULL, 0}
+  };
+
+/* Data structure to communicate with argp functions.  */
+static const struct argp argp =
+{
+  options, parse_opt, args_doc, doc, argp_children, NULL, NULL
+};
+
+
+/* Print symbols in file named FNAME.  */
+static int process_file (const char *fname, bool more_than_one);
+
+/* Handle content of archive.  */
+static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
+		      const char *suffix);
+
+/* Handle ELF file.  */
+static int handle_elf (Elf *elf, const char *prefix, const char *fname,
+		       const char *suffix);
+
+
+#define INTERNAL_ERROR(fname) \
+  error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s): %s"),      \
+	 fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1))
+
+
+/* List of sections which should be used.  */
+static struct section_list
+{
+  bool is_name;
+  union
+  {
+    const char *name;
+    uint32_t scnndx;
+  };
+  struct section_list *next;
+} *section_list;
+
+
+/* If true print archive index.  */
+static bool print_relocs;
+
+/* If true print full contents of requested sections.  */
+static bool print_full_content;
+
+/* If true print disassembled output..  */
+static bool print_disasm;
+
+
+int
+main (int argc, char *argv[])
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+  (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  /* Make sure the message catalog can be found.  */
+  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+
+  /* Initialize the message catalog.  */
+  (void) textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  */
+  int remaining;
+  (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+  /* Tell the library which version we are expecting.  */
+  (void) elf_version (EV_CURRENT);
+
+  int result = 0;
+  if (remaining == argc)
+    /* The user didn't specify a name so we use a.out.  */
+    result = process_file ("a.out", false);
+  else
+    {
+      /* Process all the remaining files.  */
+      const bool more_than_one = remaining + 1 < argc;
+
+      do
+	result |= process_file (argv[remaining], more_than_one);
+      while (++remaining < argc);
+    }
+
+  return result;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg,
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  /* True if any of the control options is set.  */
+  static bool any_control_option;
+
+  switch (key)
+    {
+    case 'j':
+      {
+	struct section_list *newp = xmalloc (sizeof (*newp));
+	char *endp;
+	newp->scnndx = strtoul (arg, &endp, 0);
+	if (*endp == 0)
+	  newp->is_name = false;
+	else
+	  {
+	    newp->name = arg;
+	    newp->is_name = true;
+	  }
+	newp->next = section_list;
+	section_list = newp;
+      }
+      any_control_option = true;
+      break;
+
+    case 'd':
+      print_disasm = true;
+      any_control_option = true;
+      break;
+
+    case 'r':
+      print_relocs = true;
+      any_control_option = true;
+      break;
+
+    case 's':
+      print_full_content = true;
+      any_control_option = true;
+      break;
+
+    case ARGP_KEY_FINI:
+      if (! any_control_option)
+	{
+	  fputs (gettext ("No operation specified.\n"), stderr);
+	  argp_help (&argp, stderr, ARGP_HELP_SEE,
+		     program_invocation_short_name);
+	  exit (EXIT_FAILURE);
+	}
+      /* We only use this for checking the number of arguments, we don't
+	 actually want to consume them.  */
+      FALLTHROUGH;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+/* Open the file and determine the type.  */
+static int
+process_file (const char *fname, bool more_than_one)
+{
+  /* Open the file.  */
+  int fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      error (0, errno, gettext ("cannot open %s"), fname);
+      return 1;
+    }
+
+  /* Now get the ELF descriptor.  */
+  Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+  if (elf != NULL)
+    {
+      if (elf_kind (elf) == ELF_K_ELF)
+	{
+	  int result = handle_elf (elf, more_than_one ? "" : NULL,
+				   fname, NULL);
+
+	  if (elf_end (elf) != 0)
+	    INTERNAL_ERROR (fname);
+
+	  if (close (fd) != 0)
+	    error (EXIT_FAILURE, errno, gettext ("while close `%s'"), fname);
+
+	  return result;
+	}
+      else if (elf_kind (elf) == ELF_K_AR)
+	{
+	  int result = handle_ar (fd, elf, NULL, fname, NULL);
+
+	  if (elf_end (elf) != 0)
+	    INTERNAL_ERROR (fname);
+
+	  if (close (fd) != 0)
+	    error (EXIT_FAILURE, errno, gettext ("while close `%s'"), fname);
+
+	  return result;
+	}
+
+      /* We cannot handle this type.  Close the descriptor anyway.  */
+      if (elf_end (elf) != 0)
+	INTERNAL_ERROR (fname);
+    }
+
+  error (0, 0, gettext ("%s: File format not recognized"), fname);
+
+  return 1;
+}
+
+
+static int
+handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
+	   const char *suffix)
+{
+  size_t fname_len = strlen (fname) + 1;
+  size_t prefix_len = prefix != NULL ? strlen (prefix) : 0;
+  char new_prefix[prefix_len + fname_len + 2];
+  size_t suffix_len = suffix != NULL ? strlen (suffix) : 0;
+  char new_suffix[suffix_len + 2];
+  Elf *subelf;
+  Elf_Cmd cmd = ELF_C_READ_MMAP;
+  int result = 0;
+
+  char *cp = new_prefix;
+  if (prefix != NULL)
+    cp = stpcpy (cp, prefix);
+  cp = stpcpy (cp, fname);
+  stpcpy (cp, "[");
+
+  cp = new_suffix;
+  if (suffix != NULL)
+    cp = stpcpy (cp, suffix);
+  stpcpy (cp, "]");
+
+  /* Process all the files contained in the archive.  */
+  while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+    {
+      /* The the header for this element.  */
+      Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+
+      /* Skip over the index entries.  */
+      if (strcmp (arhdr->ar_name, "/") != 0
+	  && strcmp (arhdr->ar_name, "//") != 0)
+	{
+	  if (elf_kind (subelf) == ELF_K_ELF)
+	    result |= handle_elf (subelf, new_prefix, arhdr->ar_name,
+				  new_suffix);
+	  else if (elf_kind (subelf) == ELF_K_AR)
+	    result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name,
+				 new_suffix);
+	  else
+	    {
+	      error (0, 0, gettext ("%s%s%s: file format not recognized"),
+		     new_prefix, arhdr->ar_name, new_suffix);
+	      result = 1;
+	    }
+	}
+
+      /* Get next archive element.  */
+      cmd = elf_next (subelf);
+      if (elf_end (subelf) != 0)
+	INTERNAL_ERROR (fname);
+    }
+
+  return result;
+}
+
+
+static void
+show_relocs_x (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *symdata,
+	       Elf_Data *xndxdata, size_t symstrndx, size_t shstrndx,
+	       GElf_Addr r_offset, GElf_Xword r_info, GElf_Sxword r_addend)
+{
+  int elfclass = gelf_getclass (ebl->elf);
+  char buf[128];
+
+  printf ("%0*" PRIx64 " %-20s ",
+	  elfclass == ELFCLASS32 ? 8 : 16, r_offset,
+	  ebl_reloc_type_name (ebl, GELF_R_TYPE (r_info), buf, sizeof (buf)));
+
+  Elf32_Word xndx;
+  GElf_Sym symmem;
+  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata, GELF_R_SYM (r_info),
+				    &symmem, &xndx);
+
+  if (sym == NULL)
+    printf ("<%s %ld>",
+	    gettext ("INVALID SYMBOL"), (long int) GELF_R_SYM (r_info));
+  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
+    printf ("%s",
+	    elf_strptr (ebl->elf, symstrndx, sym->st_name));
+  else
+    {
+      GElf_Shdr destshdr_mem;
+      GElf_Shdr *destshdr;
+      destshdr = gelf_getshdr (elf_getscn (ebl->elf,
+					   sym->st_shndx == SHN_XINDEX
+					   ? xndx : sym->st_shndx),
+			       &destshdr_mem);
+
+      if (shdr == NULL || destshdr == NULL)
+	printf ("<%s %ld>",
+		gettext ("INVALID SECTION"),
+		(long int) (sym->st_shndx == SHN_XINDEX
+			    ? xndx : sym->st_shndx));
+      else
+	printf ("%s",
+		elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+    }
+
+  if (r_addend != 0)
+    {
+      char sign = '+';
+      if (r_addend < 0)
+	{
+	  sign = '-';
+	  r_addend = -r_addend;
+	}
+      printf ("%c%#" PRIx64, sign, r_addend);
+    }
+  putchar ('\n');
+}
+
+
+static void
+show_relocs_rel (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data,
+		 Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx,
+		 size_t shstrndx)
+{
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
+  int nentries = shdr->sh_size / sh_entsize;
+
+  for (int cnt = 0; cnt < nentries; ++cnt)
+    {
+      GElf_Rel relmem;
+      GElf_Rel *rel;
+
+      rel = gelf_getrel (data, cnt, &relmem);
+      if (rel != NULL)
+	show_relocs_x (ebl, shdr, symdata, xndxdata, symstrndx, shstrndx,
+		       rel->r_offset, rel->r_info, 0);
+    }
+}
+
+
+static void
+show_relocs_rela (Ebl *ebl, GElf_Shdr *shdr, Elf_Data *data,
+		  Elf_Data *symdata, Elf_Data *xndxdata, size_t symstrndx,
+		  size_t shstrndx)
+{
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
+  int nentries = shdr->sh_size / sh_entsize;
+
+  for (int cnt = 0; cnt < nentries; ++cnt)
+    {
+      GElf_Rela relmem;
+      GElf_Rela *rel;
+
+      rel = gelf_getrela (data, cnt, &relmem);
+      if (rel != NULL)
+	show_relocs_x (ebl, shdr, symdata, xndxdata, symstrndx, shstrndx,
+		       rel->r_offset, rel->r_info, rel->r_addend);
+    }
+}
+
+
+static bool
+section_match (Elf *elf, uint32_t scnndx, GElf_Shdr *shdr, size_t shstrndx)
+{
+  if (section_list == NULL)
+    return true;
+
+  struct section_list *runp = section_list;
+  const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
+
+  do
+    {
+      if (runp->is_name)
+	{
+	  if (name && strcmp (runp->name, name) == 0)
+	    return true;
+	}
+      else
+	{
+	  if (runp->scnndx == scnndx)
+	    return true;
+	}
+
+      runp = runp->next;
+    }
+  while (runp != NULL);
+
+  return false;
+}
+
+
+static int
+show_relocs (Ebl *ebl, const char *fname, uint32_t shstrndx)
+{
+  int elfclass = gelf_getclass (ebl->elf);
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr == NULL)
+	INTERNAL_ERROR (fname);
+
+      if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+	{
+	  if  (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
+	    continue;
+
+	  GElf_Shdr destshdr_mem;
+	  GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf,
+							  shdr->sh_info),
+					      &destshdr_mem);
+	  if (unlikely (destshdr == NULL))
+	    continue;
+
+	  printf (gettext ("\nRELOCATION RECORDS FOR [%s]:\n"
+			   "%-*s TYPE                 VALUE\n"),
+		  elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
+		  elfclass == ELFCLASS32 ? 8 : 16, gettext ("OFFSET"));
+
+	  /* Get the data of the section.  */
+	  Elf_Data *data = elf_getdata (scn, NULL);
+	  if (data == NULL)
+	    continue;
+
+	  /* Get the symbol table information.  */
+	  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+	  GElf_Shdr symshdr_mem;
+	  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+	  Elf_Data *symdata = elf_getdata (symscn, NULL);
+	  if (unlikely (symshdr == NULL || symdata == NULL))
+	    continue;
+
+	  /* Search for the optional extended section index table.  */
+	  Elf_Data *xndxdata = NULL;
+	  Elf_Scn *xndxscn = NULL;
+	  while ((xndxscn = elf_nextscn (ebl->elf, xndxscn)) != NULL)
+	    {
+	      GElf_Shdr xndxshdr_mem;
+	      GElf_Shdr *xndxshdr;
+
+	      xndxshdr = gelf_getshdr (xndxscn, &xndxshdr_mem);
+	      if (xndxshdr != NULL && xndxshdr->sh_type == SHT_SYMTAB_SHNDX
+		  && xndxshdr->sh_link == elf_ndxscn (symscn))
+		{
+		  /* Found it.  */
+		  xndxdata = elf_getdata (xndxscn, NULL);
+		  break;
+		}
+	    }
+
+	  if (shdr->sh_type == SHT_REL)
+	    show_relocs_rel (ebl, shdr, data, symdata, xndxdata,
+			     symshdr->sh_link, shstrndx);
+	  else
+	    show_relocs_rela (ebl, shdr, data, symdata, xndxdata,
+			      symshdr->sh_link, shstrndx);
+
+	  putchar ('\n');
+	}
+    }
+
+  return 0;
+}
+
+
+static int
+show_full_content (Ebl *ebl, const char *fname, uint32_t shstrndx)
+{
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr == NULL)
+	INTERNAL_ERROR (fname);
+
+      if (shdr->sh_type == SHT_PROGBITS && shdr->sh_size > 0)
+	{
+	  if  (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
+	    continue;
+
+	  printf (gettext ("Contents of section %s:\n"),
+		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
+
+	  /* Get the data of the section.  */
+	  Elf_Data *data = elf_getdata (scn, NULL);
+	  if (data == NULL)
+	    continue;
+
+	  unsigned char *cp = data->d_buf;
+	  size_t cnt;
+	  for (cnt = 0; cnt + 16 < data->d_size; cp += 16, cnt += 16)
+	    {
+	      printf (" %04zx ", cnt);
+
+	      for (size_t inner = 0; inner < 16; inner += 4)
+		printf ("%02hhx%02hhx%02hhx%02hhx ",
+			cp[inner], cp[inner + 1], cp[inner + 2],
+			cp[inner + 3]);
+	      fputc_unlocked (' ', stdout);
+
+	      for (size_t inner = 0; inner < 16; ++inner)
+		fputc_unlocked (isascii (cp[inner]) && isprint (cp[inner])
+				? cp[inner] : '.', stdout);
+	      fputc_unlocked ('\n', stdout);
+	    }
+
+	  printf (" %04zx ", cnt);
+
+	  size_t remaining = data->d_size - cnt;
+	  size_t inner;
+	  for (inner = 0; inner + 4 <= remaining; inner += 4)
+	    printf ("%02hhx%02hhx%02hhx%02hhx ",
+		    cp[inner], cp[inner + 1], cp[inner + 2], cp[inner + 3]);
+
+	  for (; inner < remaining; ++inner)
+	    printf ("%02hhx", cp[inner]);
+
+	  for (inner = 2 * (16 - inner) + (16 - inner + 3) / 4 + 1; inner > 0;
+	       --inner)
+	    fputc_unlocked (' ', stdout);
+
+	  for (inner = 0; inner < remaining; ++inner)
+	    fputc_unlocked (isascii (cp[inner]) && isprint (cp[inner])
+			    ? cp[inner] : '.', stdout);
+	  fputc_unlocked ('\n', stdout);
+
+	  fputc_unlocked ('\n', stdout);
+	}
+    }
+
+  return 0;
+}
+
+
+struct disasm_info
+{
+  GElf_Addr addr;
+  const uint8_t *cur;
+  const uint8_t *last_end;
+  const char *address_color;
+  const char *bytes_color;
+};
+
+
+// XXX This is not the preferred output for all architectures.  Needs
+// XXX customization, too.
+static int
+disasm_output (char *buf, size_t buflen, void *arg)
+{
+  struct disasm_info *info = (struct disasm_info *) arg;
+
+  if (info->address_color != NULL)
+    printf ("%s%8" PRIx64 "%s:   ",
+	    info->address_color, (uint64_t) info->addr, color_off);
+  else
+    printf ("%8" PRIx64 ":   ", (uint64_t) info->addr);
+
+  if (info->bytes_color != NULL)
+    fputs_unlocked (info->bytes_color, stdout);
+  size_t cnt;
+  for (cnt = 0; cnt < (size_t) MIN (info->cur - info->last_end, 8); ++cnt)
+    printf (" %02" PRIx8, info->last_end[cnt]);
+  if (info->bytes_color != NULL)
+    fputs_unlocked (color_off, stdout);
+
+  printf ("%*s %.*s\n",
+	  (int) (8 - cnt) * 3 + 1, "", (int) buflen, buf);
+
+  info->addr += cnt;
+
+  /* We limit the number of bytes printed before the mnemonic to 8.
+     Print the rest on a separate, following line.  */
+  if (info->cur - info->last_end > 8)
+    {
+      if (info->address_color != NULL)
+	printf ("%s%8" PRIx64 "%s:   ",
+		info->address_color, (uint64_t) info->addr, color_off);
+      else
+	printf ("%8" PRIx64 ":   ", (uint64_t) info->addr);
+
+      if (info->bytes_color != NULL)
+	fputs_unlocked (info->bytes_color, stdout);
+      for (; cnt < (size_t) (info->cur - info->last_end); ++cnt)
+	printf (" %02" PRIx8, info->last_end[cnt]);
+      if (info->bytes_color != NULL)
+	fputs_unlocked (color_off, stdout);
+      putchar_unlocked ('\n');
+      info->addr += info->cur - info->last_end - 8;
+    }
+
+  info->last_end = info->cur;
+
+  return 0;
+}
+
+
+static int
+show_disasm (Ebl *ebl, const char *fname, uint32_t shstrndx)
+{
+  DisasmCtx_t *ctx = disasm_begin (ebl, ebl->elf, NULL /* XXX TODO */);
+  if (ctx == NULL)
+    error (EXIT_FAILURE, 0, gettext ("cannot disassemble"));
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr == NULL)
+	INTERNAL_ERROR (fname);
+
+      if (shdr->sh_type == SHT_PROGBITS && shdr->sh_size > 0
+	  && (shdr->sh_flags & SHF_EXECINSTR) != 0)
+	{
+	  if  (! section_match (ebl->elf, elf_ndxscn (scn), shdr, shstrndx))
+	    continue;
+
+	  Elf_Data *data = elf_getdata (scn, NULL);
+	  if (data == NULL)
+	    continue;
+
+	  printf ("Disassembly of section %s:\n\n",
+		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
+
+	  struct disasm_info info;
+	  info.addr = shdr->sh_addr;
+	  info.last_end = info.cur = data->d_buf;
+	  char *fmt;
+	  if (color_mode)
+	    {
+	      info.address_color = color_address;
+	      info.bytes_color = color_bytes;
+
+	      if (asprintf (&fmt, "%s%%7m %s%%.1o,%s%%.2o,%s%%.3o%%34a %s%%l",
+			    color_mnemonic ?: "",
+			    color_operand1 ?: "",
+			    color_operand2 ?: "",
+			    color_operand3 ?: "",
+			    color_label ?: "") < 0)
+		error (EXIT_FAILURE, errno, _("cannot allocate memory"));
+	    }
+	  else
+	    {
+	      info.address_color = info.bytes_color = NULL;
+
+	      fmt = "%7m %.1o,%.2o,%.3o%34a %l";
+	    }
+
+	  disasm_cb (ctx, &info.cur, info.cur + data->d_size, info.addr,
+		     fmt, disasm_output, &info, NULL /* XXX */);
+
+	  if (color_mode)
+	    free (fmt);
+	}
+    }
+
+  (void) disasm_end (ctx);
+
+  return 0;
+}
+
+
+static int
+handle_elf (Elf *elf, const char *prefix, const char *fname,
+	    const char *suffix)
+{
+
+  /* Get the backend for this object file type.  */
+  Ebl *ebl = ebl_openbackend (elf);
+
+  printf ("%s: elf%d-%s\n\n",
+	  fname, gelf_getclass (elf) == ELFCLASS32 ? 32 : 64,
+	  ebl_backend_name (ebl));
+
+  /* Create the full name of the file.  */
+  size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
+  size_t suffix_len = suffix == NULL ? 0 : strlen (suffix);
+  size_t fname_len = strlen (fname) + 1;
+  char fullname[prefix_len + 1 + fname_len + suffix_len];
+  char *cp = fullname;
+  if (prefix != NULL)
+    cp = mempcpy (cp, prefix, prefix_len);
+  cp = mempcpy (cp, fname, fname_len);
+  if (suffix != NULL)
+    memcpy (cp - 1, suffix, suffix_len + 1);
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  int result = 0;
+  if (print_disasm)
+    result = show_disasm (ebl, fullname, shstrndx);
+  if (print_relocs && !print_disasm)
+    result = show_relocs (ebl, fullname, shstrndx);
+  if (print_full_content)
+    result = show_full_content (ebl, fullname, shstrndx);
+
+  /* Close the ELF backend library descriptor.  */
+  ebl_closebackend (ebl);
+
+  return result;
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/ranlib.c b/third_party/elfutils/src/ranlib.c
new file mode 100644
index 0000000..cc0ee23
--- /dev/null
+++ b/third_party/elfutils/src/ranlib.c
@@ -0,0 +1,282 @@
+/* Generate an index to speed access to archives.
+   Copyright (C) 2005-2012 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ar.h>
+#include <argp.h>
+#include <assert.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libintl.h>
+#include <locale.h>
+#include <obstack.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <system.h>
+#include <printversion.h>
+
+#include "arlib.h"
+
+
+/* Prototypes for local functions.  */
+static int handle_file (const char *fname);
+
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("Generate an index to speed access to archives.");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("ARCHIVE");
+
+/* Data structure to communicate with argp functions.  */
+static const struct argp argp =
+{
+  options, NULL, args_doc, doc, arlib_argp_children, NULL, NULL
+};
+
+
+int
+main (int argc, char *argv[])
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+  (void) __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  /* Make sure the message catalog can be found.  */
+  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+
+  /* Initialize the message catalog.  */
+  (void) textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  */
+  int remaining;
+  (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &remaining, NULL);
+
+  /* Tell the library which version we are expecting.  */
+  (void) elf_version (EV_CURRENT);
+
+  /* There must at least be one more parameter specifying the archive.   */
+  if (remaining == argc)
+    {
+      error (0, 0, gettext ("Archive name required"));
+      argp_help (&argp, stderr, ARGP_HELP_SEE, "ranlib");
+      exit (EXIT_FAILURE);
+    }
+
+  /* We accept the names of multiple archives.  */
+  int status = 0;
+  do
+    status |= handle_file (argv[remaining]);
+  while (++remaining < argc);
+
+  return status;
+}
+
+
+static int
+copy_content (Elf *elf, int newfd, off_t off, size_t n)
+{
+  size_t len;
+  char *rawfile = elf_rawfile (elf, &len);
+
+  assert (off + n <= len);
+
+  /* Tell the kernel we will read all the pages sequentially.  */
+  size_t ps = sysconf (_SC_PAGESIZE);
+  if (n > 2 * ps)
+    posix_madvise (rawfile + (off & ~(ps - 1)), n, POSIX_MADV_SEQUENTIAL);
+
+  return write_retry (newfd, rawfile + off, n) != (ssize_t) n;
+}
+
+
+/* Handle a file given on the command line.  */
+static int
+handle_file (const char *fname)
+{
+  int fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      error (0, errno, gettext ("cannot open '%s'"), fname);
+      return 1;
+    }
+
+  struct stat st;
+  if (fstat (fd, &st) != 0)
+    {
+      error (0, errno, gettext ("cannot stat '%s'"), fname);
+      close (fd);
+      return 1;
+    }
+
+  /* First we walk through the file, looking for all ELF files to
+     collect symbols from.  */
+  Elf *arelf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+  if (arelf == NULL)
+    {
+      error (0, 0, gettext ("cannot create ELF descriptor for '%s': %s"),
+	     fname, elf_errmsg (-1));
+      close (fd);
+      return 1;
+    }
+
+  if (elf_kind (arelf) != ELF_K_AR)
+    {
+      error (0, 0, gettext ("'%s' is no archive"), fname);
+      elf_end (arelf);
+      close (fd);
+      return 1;
+    }
+
+  arlib_init ();
+
+  /* Iterate over the content of the archive.  */
+  off_t index_off = -1;
+  size_t index_size = 0;
+  off_t cur_off = SARMAG;
+  Elf *elf;
+  Elf_Cmd cmd = ELF_C_READ_MMAP;
+  while ((elf = elf_begin (fd, cmd, arelf)) != NULL)
+    {
+      Elf_Arhdr *arhdr = elf_getarhdr (elf);
+      assert (arhdr != NULL);
+
+      /* If this is the index, remember the location.  */
+      if (strcmp (arhdr->ar_name, "/") == 0)
+	{
+	  index_off = elf_getaroff (elf);
+	  index_size = arhdr->ar_size;
+	}
+      else
+	{
+	  arlib_add_symbols (elf, fname, arhdr->ar_name, cur_off);
+	  cur_off += (((arhdr->ar_size + 1) & ~((off_t) 1))
+		      + sizeof (struct ar_hdr));
+	}
+
+      /* Get next archive element.  */
+      cmd = elf_next (elf);
+      if (elf_end (elf) != 0)
+	error (0, 0, gettext ("error while freeing sub-ELF descriptor: %s"),
+	       elf_errmsg (-1));
+    }
+
+  arlib_finalize ();
+
+  /* If the file contains no symbols we need not do anything.  */
+  int status = 0;
+  if (symtab.symsnamelen != 0
+      /* We have to rewrite the file also if it initially had an index
+	 but now does not need one anymore.  */
+      || (symtab.symsnamelen == 0 && index_size != 0))
+    {
+      /* Create a new, temporary file in the same directory as the
+	 original file.  */
+      char tmpfname[strlen (fname) + 7];
+      strcpy (stpcpy (tmpfname, fname), "XXXXXX");
+      int newfd = mkstemp (tmpfname);
+      if (unlikely (newfd == -1))
+	{
+	nonew:
+	  error (0, errno, gettext ("cannot create new file"));
+	  status = 1;
+	}
+      else
+	{
+	  /* Create the header.  */
+	  if (unlikely (write_retry (newfd, ARMAG, SARMAG) != SARMAG))
+	    {
+	      // XXX Use /prof/self/fd/%d ???
+	    nonew_unlink:
+	      unlink (tmpfname);
+	      if (newfd != -1)
+		close (newfd);
+	      goto nonew;
+	    }
+
+	  /* Create the new file.  There are three parts as far we are
+	     concerned: 1. original context before the index, 2. the
+	     new index, 3. everything after the new index.  */
+	  off_t rest_off;
+	  if (index_off != -1)
+	    rest_off = (index_off + sizeof (struct ar_hdr)
+			+ ((index_size + 1) & ~1ul));
+	  else
+	    rest_off = SARMAG;
+
+	  if ((symtab.symsnamelen != 0
+	       && ((write_retry (newfd, symtab.symsoff,
+				 symtab.symsofflen)
+		    != (ssize_t) symtab.symsofflen)
+		   || (write_retry (newfd, symtab.symsname,
+				    symtab.symsnamelen)
+		       != (ssize_t) symtab.symsnamelen)))
+	      /* Even if the original file had content before the
+		 symbol table, we write it in the correct order.  */
+	      || (index_off > SARMAG
+		  && copy_content (arelf, newfd, SARMAG, index_off - SARMAG))
+	      || copy_content (arelf, newfd, rest_off, st.st_size - rest_off)
+	      /* Set the mode of the new file to the same values the
+		 original file has.  */
+	      || fchmod (newfd, st.st_mode & ALLPERMS) != 0
+	      /* Never complain about fchown failing.  */
+	      || (({asm ("" :: "r" (fchown (newfd, st.st_uid, st.st_gid))); }),
+		  close (newfd) != 0)
+	      || (newfd = -1, rename (tmpfname, fname) != 0))
+	    goto nonew_unlink;
+	}
+    }
+
+  elf_end (arelf);
+
+  arlib_fini ();
+
+  close (fd);
+
+  return status;
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/readelf.c b/third_party/elfutils/src/readelf.c
new file mode 100644
index 0000000..d606cf5
--- /dev/null
+++ b/third_party/elfutils/src/readelf.c
@@ -0,0 +1,9973 @@
+/* Print information from ELF file in human-readable form.
+   Copyright (C) 1999-2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <assert.h>
+#include <ctype.h>
+#include <dwarf.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <langinfo.h>
+#include <libdw.h>
+#include <libdwfl.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#include <libeu.h>
+#include <system.h>
+#include <printversion.h>
+#include "../libelf/libelfP.h"
+#include "../libelf/common.h"
+#include "../libebl/libeblP.h"
+#include "../libdwelf/libdwelf.h"
+#include "../libdw/libdwP.h"
+#include "../libdwfl/libdwflP.h"
+#include "../libdw/memory-access.h"
+
+#include "../libdw/known-dwarf.h"
+
+#ifdef __linux__
+#define CORE_SIGILL  SIGILL
+#define CORE_SIGBUS  SIGBUS
+#define CORE_SIGFPE  SIGFPE
+#define CORE_SIGSEGV SIGSEGV
+#define CORE_SI_USER SI_USER
+#else
+/* We want the linux version of those as that is what shows up in the core files. */
+#define CORE_SIGILL  4  /* Illegal instruction (ANSI).  */
+#define CORE_SIGBUS  7  /* BUS error (4.2 BSD).  */
+#define CORE_SIGFPE  8  /* Floating-point exception (ANSI).  */
+#define CORE_SIGSEGV 11 /* Segmentation violation (ANSI).  */
+#define CORE_SI_USER 0  /* Sent by kill, sigsend.  */
+#endif
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+/* argp key value for --elf-section, non-ascii.  */
+#define ELF_INPUT_SECTION 256
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("ELF input selection:"), 0 },
+  { "elf-section", ELF_INPUT_SECTION, "SECTION", OPTION_ARG_OPTIONAL,
+    N_("Use the named SECTION (default .gnu_debugdata) as (compressed) ELF "
+       "input data"), 0 },
+  { NULL, 0, NULL, 0, N_("ELF output selection:"), 0 },
+  { "all", 'a', NULL, 0,
+    N_("All these plus -p .strtab -p .dynstr -p .comment"), 0 },
+  { "dynamic", 'd', NULL, 0, N_("Display the dynamic segment"), 0 },
+  { "file-header", 'h', NULL, 0, N_("Display the ELF file header"), 0 },
+  { "histogram", 'I', NULL, 0,
+    N_("Display histogram of bucket list lengths"), 0 },
+  { "program-headers", 'l', NULL, 0, N_("Display the program headers"), 0 },
+  { "segments", 'l', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
+  { "relocs", 'r', NULL, 0, N_("Display relocations"), 0 },
+  { "section-groups", 'g', NULL, 0, N_("Display the section groups"), 0 },
+  { "section-headers", 'S', NULL, 0, N_("Display the sections' headers"), 0 },
+  { "sections", 'S', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
+  { "symbols", 's', "SECTION", OPTION_ARG_OPTIONAL,
+    N_("Display the symbol table sections"), 0 },
+  { "version-info", 'V', NULL, 0, N_("Display versioning information"), 0 },
+  { "notes", 'n', NULL, 0, N_("Display the ELF notes"), 0 },
+  { "arch-specific", 'A', NULL, 0,
+    N_("Display architecture specific information, if any"), 0 },
+  { "exception", 'e', NULL, 0,
+    N_("Display sections for exception handling"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Additional output selection:"), 0 },
+  { "debug-dump", 'w', "SECTION", OPTION_ARG_OPTIONAL,
+    N_("Display DWARF section content.  SECTION can be one of abbrev, "
+       "aranges, decodedaranges, frame, gdb_index, info, loc, line, "
+       "decodedline, ranges, pubnames, str, macinfo, macro or exception"), 0 },
+  { "hex-dump", 'x', "SECTION", 0,
+    N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
+  { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
+    N_("Print string contents of sections"), 0 },
+  { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
+  { "archive-index", 'c', NULL, 0,
+    N_("Display the symbol index of an archive"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Output control:"), 0 },
+  { "numeric-addresses", 'N', NULL, 0,
+    N_("Do not find symbol names for addresses in DWARF data"), 0 },
+  { "unresolved-address-offsets", 'U', NULL, 0,
+    N_("Display just offsets instead of resolving values to addresses in DWARF data"), 0 },
+  { "wide", 'W', NULL, 0,
+    N_("Ignored for compatibility (lines always wide)"), 0 },
+  { "decompress", 'z', NULL, 0,
+    N_("Show compression information for compressed sections (when used with -S); decompress section before dumping data (when used with -p or -x)"), 0 },
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("\
+Print information from ELF file in human-readable form.");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("FILE...");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  options, parse_opt, args_doc, doc, NULL, NULL, NULL
+};
+
+/* If non-null, the section from which we should read to (compressed) ELF.  */
+static const char *elf_input_section = NULL;
+
+/* Flags set by the option controlling the output.  */
+
+/* True if dynamic segment should be printed.  */
+static bool print_dynamic_table;
+
+/* True if the file header should be printed.  */
+static bool print_file_header;
+
+/* True if the program headers should be printed.  */
+static bool print_program_header;
+
+/* True if relocations should be printed.  */
+static bool print_relocations;
+
+/* True if the section headers should be printed.  */
+static bool print_section_header;
+
+/* True if the symbol table should be printed.  */
+static bool print_symbol_table;
+
+/* A specific section name, or NULL to print all symbol tables.  */
+static char *symbol_table_section;
+
+/* True if the version information should be printed.  */
+static bool print_version_info;
+
+/* True if section groups should be printed.  */
+static bool print_section_groups;
+
+/* True if bucket list length histogram should be printed.  */
+static bool print_histogram;
+
+/* True if the architecture specific data should be printed.  */
+static bool print_arch;
+
+/* True if note section content should be printed.  */
+static bool print_notes;
+
+/* True if SHF_STRINGS section content should be printed.  */
+static bool print_string_sections;
+
+/* True if archive index should be printed.  */
+static bool print_archive_index;
+
+/* True if any of the control options except print_archive_index is set.  */
+static bool any_control_option;
+
+/* True if we should print addresses from DWARF in symbolic form.  */
+static bool print_address_names = true;
+
+/* True if we should print raw values instead of relativized addresses.  */
+static bool print_unresolved_addresses = false;
+
+/* True if we should print the .debug_aranges section using libdw.  */
+static bool decodedaranges = false;
+
+/* True if we should print the .debug_aranges section using libdw.  */
+static bool decodedline = false;
+
+/* True if we want to show more information about compressed sections.  */
+static bool print_decompress = false;
+
+/* Select printing of debugging sections.  */
+static enum section_e
+{
+  section_abbrev = 1,		/* .debug_abbrev  */
+  section_aranges = 2,		/* .debug_aranges  */
+  section_frame = 4,		/* .debug_frame or .eh_frame & al.  */
+  section_info = 8,		/* .debug_info, .debug_types  */
+  section_types = section_info,
+  section_line = 16,		/* .debug_line  */
+  section_loc = 32,		/* .debug_loc  */
+  section_pubnames = 64,	/* .debug_pubnames  */
+  section_str = 128,		/* .debug_str  */
+  section_macinfo = 256,	/* .debug_macinfo  */
+  section_ranges = 512, 	/* .debug_ranges  */
+  section_exception = 1024,	/* .eh_frame & al.  */
+  section_gdb_index = 2048,	/* .gdb_index  */
+  section_macro = 4096,		/* .debug_macro  */
+  section_all = (section_abbrev | section_aranges | section_frame
+		 | section_info | section_line | section_loc
+		 | section_pubnames | section_str | section_macinfo
+		 | section_ranges | section_exception | section_gdb_index
+		 | section_macro)
+} print_debug_sections, implicit_debug_sections;
+
+/* Select hex dumping of sections.  */
+static struct section_argument *dump_data_sections;
+static struct section_argument **dump_data_sections_tail = &dump_data_sections;
+
+/* Select string dumping of sections.  */
+static struct section_argument *string_sections;
+static struct section_argument **string_sections_tail = &string_sections;
+
+struct section_argument
+{
+  struct section_argument *next;
+  const char *arg;
+  bool implicit;
+};
+
+/* Numbers of sections and program headers in the file.  */
+static size_t shnum;
+static size_t phnum;
+
+
+/* Declarations of local functions.  */
+static void process_file (int fd, const char *fname, bool only_one);
+static void process_elf_file (Dwfl_Module *dwflmod, int fd);
+static void print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr);
+static void print_shdr (Ebl *ebl, GElf_Ehdr *ehdr);
+static void print_phdr (Ebl *ebl, GElf_Ehdr *ehdr);
+static void print_scngrp (Ebl *ebl);
+static void print_dynamic (Ebl *ebl);
+static void print_relocs (Ebl *ebl, GElf_Ehdr *ehdr);
+static void handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
+			       GElf_Shdr *shdr);
+static void handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
+				GElf_Shdr *shdr);
+static void print_symtab (Ebl *ebl, int type);
+static void handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
+static void print_verinfo (Ebl *ebl);
+static void handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
+static void handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr);
+static void handle_versym (Ebl *ebl, Elf_Scn *scn,
+			   GElf_Shdr *shdr);
+static void print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr);
+static void handle_hash (Ebl *ebl);
+static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
+static void print_liblist (Ebl *ebl);
+static void print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr);
+static void dump_data (Ebl *ebl);
+static void dump_strings (Ebl *ebl);
+static void print_strings (Ebl *ebl);
+static void dump_archive_index (Elf *, const char *);
+
+
+int
+main (int argc, char *argv[])
+{
+  /* Set locale.  */
+  setlocale (LC_ALL, "");
+
+  /* Initialize the message catalog.  */
+  textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  */
+  int remaining;
+  argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+  /* Before we start tell the ELF library which version we are using.  */
+  elf_version (EV_CURRENT);
+
+  /* Now process all the files given at the command line.  */
+  bool only_one = remaining + 1 == argc;
+  do
+    {
+      /* Open the file.  */
+      int fd = open (argv[remaining], O_RDONLY);
+      if (fd == -1)
+	{
+	  error (0, errno, gettext ("cannot open input file"));
+	  continue;
+	}
+
+      process_file (fd, argv[remaining], only_one);
+
+      close (fd);
+    }
+  while (++remaining < argc);
+
+  return error_message_count != 0;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg,
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  void add_dump_section (const char *name, bool implicit)
+  {
+    struct section_argument *a = xmalloc (sizeof *a);
+    a->arg = name;
+    a->next = NULL;
+    a->implicit = implicit;
+    struct section_argument ***tailp
+      = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
+    **tailp = a;
+    *tailp = &a->next;
+  }
+
+  switch (key)
+    {
+    case 'a':
+      print_file_header = true;
+      print_program_header = true;
+      print_relocations = true;
+      print_section_header = true;
+      print_symbol_table = true;
+      print_version_info = true;
+      print_dynamic_table = true;
+      print_section_groups = true;
+      print_histogram = true;
+      print_arch = true;
+      print_notes = true;
+      implicit_debug_sections |= section_exception;
+      add_dump_section (".strtab", true);
+      add_dump_section (".dynstr", true);
+      add_dump_section (".comment", true);
+      any_control_option = true;
+      break;
+    case 'A':
+      print_arch = true;
+      any_control_option = true;
+      break;
+    case 'd':
+      print_dynamic_table = true;
+      any_control_option = true;
+      break;
+    case 'e':
+      print_debug_sections |= section_exception;
+      any_control_option = true;
+      break;
+    case 'g':
+      print_section_groups = true;
+      any_control_option = true;
+      break;
+    case 'h':
+      print_file_header = true;
+      any_control_option = true;
+      break;
+    case 'I':
+      print_histogram = true;
+      any_control_option = true;
+      break;
+    case 'l':
+      print_program_header = true;
+      any_control_option = true;
+      break;
+    case 'n':
+      print_notes = true;
+      any_control_option = true;
+      break;
+    case 'r':
+      print_relocations = true;
+      any_control_option = true;
+     break;
+    case 'S':
+      print_section_header = true;
+      any_control_option = true;
+      break;
+    case 's':
+      print_symbol_table = true;
+      any_control_option = true;
+      symbol_table_section = arg;
+      break;
+    case 'V':
+      print_version_info = true;
+      any_control_option = true;
+      break;
+    case 'c':
+      print_archive_index = true;
+      break;
+    case 'w':
+      if (arg == NULL)
+	print_debug_sections = section_all;
+      else if (strcmp (arg, "abbrev") == 0)
+	print_debug_sections |= section_abbrev;
+      else if (strcmp (arg, "aranges") == 0)
+	print_debug_sections |= section_aranges;
+      else if (strcmp (arg, "decodedaranges") == 0)
+	{
+	  print_debug_sections |= section_aranges;
+	  decodedaranges = true;
+	}
+      else if (strcmp (arg, "ranges") == 0)
+	{
+	  print_debug_sections |= section_ranges;
+	  implicit_debug_sections |= section_info;
+	}
+      else if (strcmp (arg, "frame") == 0 || strcmp (arg, "frames") == 0)
+	print_debug_sections |= section_frame;
+      else if (strcmp (arg, "info") == 0)
+	print_debug_sections |= section_info;
+      else if (strcmp (arg, "loc") == 0)
+	{
+	  print_debug_sections |= section_loc;
+	  implicit_debug_sections |= section_info;
+	}
+      else if (strcmp (arg, "line") == 0)
+	print_debug_sections |= section_line;
+      else if (strcmp (arg, "decodedline") == 0)
+	{
+	  print_debug_sections |= section_line;
+	  decodedline = true;
+	}
+      else if (strcmp (arg, "pubnames") == 0)
+	print_debug_sections |= section_pubnames;
+      else if (strcmp (arg, "str") == 0)
+	print_debug_sections |= section_str;
+      else if (strcmp (arg, "macinfo") == 0)
+	print_debug_sections |= section_macinfo;
+      else if (strcmp (arg, "macro") == 0)
+	print_debug_sections |= section_macro;
+      else if (strcmp (arg, "exception") == 0)
+	print_debug_sections |= section_exception;
+      else if (strcmp (arg, "gdb_index") == 0)
+	print_debug_sections |= section_gdb_index;
+      else
+	{
+	  fprintf (stderr, gettext ("Unknown DWARF debug section `%s'.\n"),
+		   arg);
+	  argp_help (&argp, stderr, ARGP_HELP_SEE,
+		     program_invocation_short_name);
+	  exit (1);
+	}
+      any_control_option = true;
+      break;
+    case 'p':
+      any_control_option = true;
+      if (arg == NULL)
+	{
+	  print_string_sections = true;
+	  break;
+	}
+      FALLTHROUGH;
+    case 'x':
+      add_dump_section (arg, false);
+      any_control_option = true;
+      break;
+    case 'N':
+      print_address_names = false;
+      break;
+    case 'U':
+      print_unresolved_addresses = true;
+      break;
+    case ARGP_KEY_NO_ARGS:
+      fputs (gettext ("Missing file name.\n"), stderr);
+      goto do_argp_help;
+    case ARGP_KEY_FINI:
+      if (! any_control_option && ! print_archive_index)
+	{
+	  fputs (gettext ("No operation specified.\n"), stderr);
+	do_argp_help:
+	  argp_help (&argp, stderr, ARGP_HELP_SEE,
+		     program_invocation_short_name);
+	  exit (EXIT_FAILURE);
+	}
+      break;
+    case 'W':			/* Ignored.  */
+      break;
+    case 'z':
+      print_decompress = true;
+      break;
+    case ELF_INPUT_SECTION:
+      if (arg == NULL)
+	elf_input_section = ".gnu_debugdata";
+      else
+	elf_input_section = arg;
+      break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+/* Create a file descriptor to read the data from the
+   elf_input_section given a file descriptor to an ELF file.  */
+static int
+open_input_section (int fd)
+{
+  size_t shnums;
+  size_t cnt;
+  size_t shstrndx;
+  Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+  if (elf == NULL)
+    {
+      error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
+	     elf_errmsg (-1));
+      return -1;
+    }
+
+  if (elf_getshdrnum (elf, &shnums) < 0)
+    {
+      error (0, 0, gettext ("cannot determine number of sections: %s"),
+	     elf_errmsg (-1));
+    open_error:
+      elf_end (elf);
+      return -1;
+    }
+
+  if (elf_getshdrstrndx (elf, &shstrndx) < 0)
+    {
+      error (0, 0, gettext ("cannot get section header string table index"));
+      goto open_error;
+    }
+
+  for (cnt = 0; cnt < shnums; ++cnt)
+    {
+      Elf_Scn *scn = elf_getscn (elf, cnt);
+      if (scn == NULL)
+	{
+	  error (0, 0, gettext ("cannot get section: %s"),
+		 elf_errmsg (-1));
+	  goto open_error;
+	}
+
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (unlikely (shdr == NULL))
+	{
+	  error (0, 0, gettext ("cannot get section header: %s"),
+		 elf_errmsg (-1));
+	  goto open_error;
+	}
+
+      const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
+      if (sname == NULL)
+	{
+	  error (0, 0, gettext ("cannot get section name"));
+	  goto open_error;
+	}
+
+      if (strcmp (sname, elf_input_section) == 0)
+	{
+	  Elf_Data *data = elf_rawdata (scn, NULL);
+	  if (data == NULL)
+	    {
+	      error (0, 0, gettext ("cannot get %s content: %s"),
+		     sname, elf_errmsg (-1));
+	      goto open_error;
+	    }
+
+	  /* Create (and immediately unlink) a temporary file to store
+	     section data in to create a file descriptor for it.  */
+	  const char *tmpdir = getenv ("TMPDIR") ?: P_tmpdir;
+	  static const char suffix[] = "/readelfXXXXXX";
+	  int tmplen = strlen (tmpdir) + sizeof (suffix);
+	  char *tempname = alloca (tmplen);
+	  sprintf (tempname, "%s%s", tmpdir, suffix);
+
+	  int sfd = mkstemp (tempname);
+	  if (sfd == -1)
+	    {
+	      error (0, 0, gettext ("cannot create temp file '%s'"),
+		     tempname);
+	      goto open_error;
+	    }
+	  unlink (tempname);
+
+	  ssize_t size = data->d_size;
+	  if (write_retry (sfd, data->d_buf, size) != size)
+	    {
+	      error (0, 0, gettext ("cannot write section data"));
+	      goto open_error;
+	    }
+
+	  if (elf_end (elf) != 0)
+	    {
+	      error (0, 0, gettext ("error while closing Elf descriptor: %s"),
+		     elf_errmsg (-1));
+	      return -1;
+	    }
+
+	  if (lseek (sfd, 0, SEEK_SET) == -1)
+	    {
+	      error (0, 0, gettext ("error while rewinding file descriptor"));
+	      return -1;
+	    }
+
+	  return sfd;
+	}
+    }
+
+  /* Named section not found.  */
+  if (elf_end (elf) != 0)
+    error (0, 0, gettext ("error while closing Elf descriptor: %s"),
+	   elf_errmsg (-1));
+  return -1;
+}
+
+/* Check if the file is an archive, and if so dump its index.  */
+static void
+check_archive_index (int fd, const char *fname, bool only_one)
+{
+  /* Create an `Elf' descriptor.  */
+  Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+  if (elf == NULL)
+    error (0, 0, gettext ("cannot generate Elf descriptor: %s"),
+	   elf_errmsg (-1));
+  else
+    {
+      if (elf_kind (elf) == ELF_K_AR)
+	{
+	  if (!only_one)
+	    printf ("\n%s:\n\n", fname);
+	  dump_archive_index (elf, fname);
+	}
+      else
+	error (0, 0,
+	       gettext ("'%s' is not an archive, cannot print archive index"),
+	       fname);
+
+      /* Now we can close the descriptor.  */
+      if (elf_end (elf) != 0)
+	error (0, 0, gettext ("error while closing Elf descriptor: %s"),
+	       elf_errmsg (-1));
+    }
+}
+
+/* Trivial callback used for checking if we opened an archive.  */
+static int
+count_dwflmod (Dwfl_Module *dwflmod __attribute__ ((unused)),
+	       void **userdata __attribute__ ((unused)),
+	       const char *name __attribute__ ((unused)),
+	       Dwarf_Addr base __attribute__ ((unused)),
+	       void *arg)
+{
+  if (*(bool *) arg)
+    return DWARF_CB_ABORT;
+  *(bool *) arg = true;
+  return DWARF_CB_OK;
+}
+
+struct process_dwflmod_args
+{
+  int fd;
+  bool only_one;
+};
+
+static int
+process_dwflmod (Dwfl_Module *dwflmod,
+		 void **userdata __attribute__ ((unused)),
+		 const char *name __attribute__ ((unused)),
+		 Dwarf_Addr base __attribute__ ((unused)),
+		 void *arg)
+{
+  const struct process_dwflmod_args *a = arg;
+
+  /* Print the file name.  */
+  if (!a->only_one)
+    {
+      const char *fname;
+      dwfl_module_info (dwflmod, NULL, NULL, NULL, NULL, NULL, &fname, NULL);
+
+      printf ("\n%s:\n\n", fname);
+    }
+
+  process_elf_file (dwflmod, a->fd);
+
+  return DWARF_CB_OK;
+}
+
+/* Stub libdwfl callback, only the ELF handle already open is ever used.
+   Only used for finding the alternate debug file if the Dwarf comes from
+   the main file.  We are not interested in separate debuginfo.  */
+static int
+find_no_debuginfo (Dwfl_Module *mod,
+		   void **userdata,
+		   const char *modname,
+		   Dwarf_Addr base,
+		   const char *file_name,
+		   const char *debuglink_file,
+		   GElf_Word debuglink_crc,
+		   char **debuginfo_file_name)
+{
+  Dwarf_Addr dwbias;
+  dwfl_module_info (mod, NULL, NULL, NULL, &dwbias, NULL, NULL, NULL);
+
+  /* We are only interested if the Dwarf has been setup on the main
+     elf file but is only missing the alternate debug link.  If dwbias
+     hasn't even been setup, this is searching for separate debuginfo
+     for the main elf.  We don't care in that case.  */
+  if (dwbias == (Dwarf_Addr) -1)
+    return -1;
+
+  return dwfl_standard_find_debuginfo (mod, userdata, modname, base,
+				       file_name, debuglink_file,
+				       debuglink_crc, debuginfo_file_name);
+}
+
+/* Process one input file.  */
+static void
+process_file (int fd, const char *fname, bool only_one)
+{
+  if (print_archive_index)
+    check_archive_index (fd, fname, only_one);
+
+  if (!any_control_option)
+    return;
+
+  if (elf_input_section != NULL)
+    {
+      /* Replace fname and fd with section content. */
+      char *fnname = alloca (strlen (fname) + strlen (elf_input_section) + 2);
+      sprintf (fnname, "%s:%s", fname, elf_input_section);
+      fd = open_input_section (fd);
+      if (fd == -1)
+        {
+          error (0, 0, gettext ("No such section '%s' in '%s'"),
+		 elf_input_section, fname);
+          return;
+        }
+      fname = fnname;
+    }
+
+  /* Duplicate an fd for dwfl_report_offline to swallow.  */
+  int dwfl_fd = dup (fd);
+  if (unlikely (dwfl_fd < 0))
+    error (EXIT_FAILURE, errno, "dup");
+
+  /* Use libdwfl in a trivial way to open the libdw handle for us.
+     This takes care of applying relocations to DWARF data in ET_REL files.  */
+  static const Dwfl_Callbacks callbacks =
+    {
+      .section_address = dwfl_offline_section_address,
+      .find_debuginfo = find_no_debuginfo
+    };
+  Dwfl *dwfl = dwfl_begin (&callbacks);
+  if (likely (dwfl != NULL))
+    /* Let 0 be the logical address of the file (or first in archive).  */
+    dwfl->offline_next_address = 0;
+  if (dwfl_report_offline (dwfl, fname, fname, dwfl_fd) == NULL)
+    {
+      struct stat st;
+      if (fstat (dwfl_fd, &st) != 0)
+	error (0, errno, gettext ("cannot stat input file"));
+      else if (unlikely (st.st_size == 0))
+	error (0, 0, gettext ("input file is empty"));
+      else
+	error (0, 0, gettext ("failed reading '%s': %s"),
+	       fname, dwfl_errmsg (-1));
+      close (dwfl_fd);		/* Consumed on success, not on failure.  */
+    }
+  else
+    {
+      dwfl_report_end (dwfl, NULL, NULL);
+
+      if (only_one)
+	{
+	  /* Clear ONLY_ONE if we have multiple modules, from an archive.  */
+	  bool seen = false;
+	  only_one = dwfl_getmodules (dwfl, &count_dwflmod, &seen, 0) == 0;
+	}
+
+      /* Process the one or more modules gleaned from this file.  */
+      struct process_dwflmod_args a = { .fd = fd, .only_one = only_one };
+      dwfl_getmodules (dwfl, &process_dwflmod, &a, 0);
+    }
+  dwfl_end (dwfl);
+
+  /* Need to close the replaced fd if we created it.  Caller takes
+     care of original.  */
+  if (elf_input_section != NULL)
+    close (fd);
+}
+
+/* Check whether there are any compressed sections in the ELF file.  */
+static bool
+elf_contains_chdrs (Elf *elf)
+{
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr != NULL && (shdr->sh_flags & SHF_COMPRESSED) != 0)
+	return true;
+    }
+  return false;
+}
+
+/* Process one ELF file.  */
+static void
+process_elf_file (Dwfl_Module *dwflmod, int fd)
+{
+  GElf_Addr dwflbias;
+  Elf *elf = dwfl_module_getelf (dwflmod, &dwflbias);
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+
+  if (ehdr == NULL)
+    {
+    elf_error:
+      error (0, 0, gettext ("cannot read ELF header: %s"), elf_errmsg (-1));
+      return;
+    }
+
+  Ebl *ebl = ebl_openbackend (elf);
+  if (unlikely (ebl == NULL))
+    {
+    ebl_error:
+      error (0, errno, gettext ("cannot create EBL handle"));
+      return;
+    }
+
+  /* Determine the number of sections.  */
+  if (unlikely (elf_getshdrnum (ebl->elf, &shnum) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot determine number of sections: %s"),
+	   elf_errmsg (-1));
+
+  /* Determine the number of phdrs.  */
+  if (unlikely (elf_getphdrnum (ebl->elf, &phnum) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot determine number of program headers: %s"),
+	   elf_errmsg (-1));
+
+  /* For an ET_REL file, libdwfl has adjusted the in-core shdrs and
+     may have applied relocation to some sections.  If there are any
+     compressed sections, any pass (or libdw/libdwfl) might have
+     uncompressed them.  So we need to get a fresh Elf handle on the
+     file to display those.  */
+  bool print_unchanged = ((print_section_header
+			   || print_relocations
+			   || dump_data_sections != NULL
+			   || print_notes)
+			  && (ehdr->e_type == ET_REL
+			      || elf_contains_chdrs (ebl->elf)));
+
+  Elf *pure_elf = NULL;
+  Ebl *pure_ebl = ebl;
+  if (print_unchanged)
+    {
+      /* Read the file afresh.  */
+      off_t aroff = elf_getaroff (elf);
+      pure_elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+      if (aroff > 0)
+	{
+	  /* Archive member.  */
+	  (void) elf_rand (pure_elf, aroff);
+	  Elf *armem = elf_begin (-1, ELF_C_READ_MMAP, pure_elf);
+	  elf_end (pure_elf);
+	  pure_elf = armem;
+	}
+      if (pure_elf == NULL)
+	goto elf_error;
+      pure_ebl = ebl_openbackend (pure_elf);
+      if (pure_ebl == NULL)
+	goto ebl_error;
+    }
+
+  if (print_file_header)
+    print_ehdr (ebl, ehdr);
+  if (print_section_header)
+    print_shdr (pure_ebl, ehdr);
+  if (print_program_header)
+    print_phdr (ebl, ehdr);
+  if (print_section_groups)
+    print_scngrp (ebl);
+  if (print_dynamic_table)
+    print_dynamic (ebl);
+  if (print_relocations)
+    print_relocs (pure_ebl, ehdr);
+  if (print_histogram)
+    handle_hash (ebl);
+  if (print_symbol_table)
+    print_symtab (ebl, SHT_DYNSYM);
+  if (print_version_info)
+    print_verinfo (ebl);
+  if (print_symbol_table)
+    print_symtab (ebl, SHT_SYMTAB);
+  if (print_arch)
+    print_liblist (ebl);
+  if (print_arch)
+    print_attributes (ebl, ehdr);
+  if (dump_data_sections != NULL)
+    dump_data (pure_ebl);
+  if (string_sections != NULL)
+    dump_strings (ebl);
+  if ((print_debug_sections | implicit_debug_sections) != 0)
+    print_debug (dwflmod, ebl, ehdr);
+  if (print_notes)
+    handle_notes (pure_ebl, ehdr);
+  if (print_string_sections)
+    print_strings (ebl);
+
+  ebl_closebackend (ebl);
+
+  if (pure_ebl != ebl)
+    {
+      ebl_closebackend (pure_ebl);
+      elf_end (pure_elf);
+    }
+}
+
+
+/* Print file type.  */
+static void
+print_file_type (unsigned short int e_type)
+{
+  if (likely (e_type <= ET_CORE))
+    {
+      static const char *const knowntypes[] =
+      {
+	N_("NONE (None)"),
+	N_("REL (Relocatable file)"),
+	N_("EXEC (Executable file)"),
+	N_("DYN (Shared object file)"),
+	N_("CORE (Core file)")
+      };
+      puts (gettext (knowntypes[e_type]));
+    }
+  else if (e_type >= ET_LOOS && e_type <= ET_HIOS)
+    printf (gettext ("OS Specific: (%x)\n"),  e_type);
+  else if (e_type >= ET_LOPROC /* && e_type <= ET_HIPROC always true */)
+    printf (gettext ("Processor Specific: (%x)\n"),  e_type);
+  else
+    puts ("???");
+}
+
+
+/* Print ELF header.  */
+static void
+print_ehdr (Ebl *ebl, GElf_Ehdr *ehdr)
+{
+  fputs_unlocked (gettext ("ELF Header:\n  Magic:  "), stdout);
+  for (size_t cnt = 0; cnt < EI_NIDENT; ++cnt)
+    printf (" %02hhx", ehdr->e_ident[cnt]);
+
+  printf (gettext ("\n  Class:                             %s\n"),
+	  ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? "ELF32"
+	  : ehdr->e_ident[EI_CLASS] == ELFCLASS64 ? "ELF64"
+	  : "\?\?\?");
+
+  printf (gettext ("  Data:                              %s\n"),
+	  ehdr->e_ident[EI_DATA] == ELFDATA2LSB
+	  ? "2's complement, little endian"
+	  : ehdr->e_ident[EI_DATA] == ELFDATA2MSB
+	  ? "2's complement, big endian" : "\?\?\?");
+
+  printf (gettext ("  Ident Version:                     %hhd %s\n"),
+	  ehdr->e_ident[EI_VERSION],
+	  ehdr->e_ident[EI_VERSION] == EV_CURRENT ? gettext ("(current)")
+	  : "(\?\?\?)");
+
+  char buf[512];
+  printf (gettext ("  OS/ABI:                            %s\n"),
+	  ebl_osabi_name (ebl, ehdr->e_ident[EI_OSABI], buf, sizeof (buf)));
+
+  printf (gettext ("  ABI Version:                       %hhd\n"),
+	  ehdr->e_ident[EI_ABIVERSION]);
+
+  fputs_unlocked (gettext ("  Type:                              "), stdout);
+  print_file_type (ehdr->e_type);
+
+  printf (gettext ("  Machine:                           %s\n"), ebl->name);
+
+  printf (gettext ("  Version:                           %d %s\n"),
+	  ehdr->e_version,
+	  ehdr->e_version  == EV_CURRENT ? gettext ("(current)") : "(\?\?\?)");
+
+  printf (gettext ("  Entry point address:               %#" PRIx64 "\n"),
+	  ehdr->e_entry);
+
+  printf (gettext ("  Start of program headers:          %" PRId64 " %s\n"),
+	  ehdr->e_phoff, gettext ("(bytes into file)"));
+
+  printf (gettext ("  Start of section headers:          %" PRId64 " %s\n"),
+	  ehdr->e_shoff, gettext ("(bytes into file)"));
+
+  printf (gettext ("  Flags:                             %s\n"),
+	  ebl_machine_flag_name (ebl, ehdr->e_flags, buf, sizeof (buf)));
+
+  printf (gettext ("  Size of this header:               %" PRId16 " %s\n"),
+	  ehdr->e_ehsize, gettext ("(bytes)"));
+
+  printf (gettext ("  Size of program header entries:    %" PRId16 " %s\n"),
+	  ehdr->e_phentsize, gettext ("(bytes)"));
+
+  printf (gettext ("  Number of program headers entries: %" PRId16),
+	  ehdr->e_phnum);
+  if (ehdr->e_phnum == PN_XNUM)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
+      if (shdr != NULL)
+	printf (gettext (" (%" PRIu32 " in [0].sh_info)"),
+		(uint32_t) shdr->sh_info);
+      else
+	fputs_unlocked (gettext (" ([0] not available)"), stdout);
+    }
+  fputc_unlocked ('\n', stdout);
+
+  printf (gettext ("  Size of section header entries:    %" PRId16 " %s\n"),
+	  ehdr->e_shentsize, gettext ("(bytes)"));
+
+  printf (gettext ("  Number of section headers entries: %" PRId16),
+	  ehdr->e_shnum);
+  if (ehdr->e_shnum == 0)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
+      if (shdr != NULL)
+	printf (gettext (" (%" PRIu32 " in [0].sh_size)"),
+		(uint32_t) shdr->sh_size);
+      else
+	fputs_unlocked (gettext (" ([0] not available)"), stdout);
+    }
+  fputc_unlocked ('\n', stdout);
+
+  if (unlikely (ehdr->e_shstrndx == SHN_XINDEX))
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (elf_getscn (ebl->elf, 0), &shdr_mem);
+      if (shdr != NULL)
+	/* We managed to get the zeroth section.  */
+	snprintf (buf, sizeof (buf), gettext (" (%" PRIu32 " in [0].sh_link)"),
+		  (uint32_t) shdr->sh_link);
+      else
+	{
+	  strncpy (buf, gettext (" ([0] not available)"), sizeof (buf));
+	  buf[sizeof (buf) - 1] = '\0';
+	}
+
+      printf (gettext ("  Section header string table index: XINDEX%s\n\n"),
+	      buf);
+    }
+  else
+    printf (gettext ("  Section header string table index: %" PRId16 "\n\n"),
+	    ehdr->e_shstrndx);
+}
+
+
+static const char *
+get_visibility_type (int value)
+{
+  switch (value)
+    {
+    case STV_DEFAULT:
+      return "DEFAULT";
+    case STV_INTERNAL:
+      return "INTERNAL";
+    case STV_HIDDEN:
+      return "HIDDEN";
+    case STV_PROTECTED:
+      return "PROTECTED";
+    default:
+      return "???";
+    }
+}
+
+static const char *
+elf_ch_type_name (unsigned int code)
+{
+  if (code == 0)
+    return "NONE";
+
+  if (code == ELFCOMPRESS_ZLIB)
+    return "ZLIB";
+
+  return "UNKNOWN";
+}
+
+/* Print the section headers.  */
+static void
+print_shdr (Ebl *ebl, GElf_Ehdr *ehdr)
+{
+  size_t cnt;
+  size_t shstrndx;
+
+  if (! print_file_header)
+    printf (gettext ("\
+There are %d section headers, starting at offset %#" PRIx64 ":\n\
+\n"),
+	    ehdr->e_shnum, ehdr->e_shoff);
+
+  /* Get the section header string table index.  */
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  puts (gettext ("Section Headers:"));
+
+  if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
+    puts (gettext ("[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al"));
+  else
+    puts (gettext ("[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al"));
+
+  if (print_decompress)
+    {
+      if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
+	puts (gettext ("     [Compression  Size   Al]"));
+      else
+	puts (gettext ("     [Compression  Size     Al]"));
+    }
+
+  for (cnt = 0; cnt < shnum; ++cnt)
+    {
+      Elf_Scn *scn = elf_getscn (ebl->elf, cnt);
+
+      if (unlikely (scn == NULL))
+	error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
+	       elf_errmsg (-1));
+
+      /* Get the section header.  */
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (unlikely (shdr == NULL))
+	error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
+	       elf_errmsg (-1));
+
+      char flagbuf[20];
+      char *cp = flagbuf;
+      if (shdr->sh_flags & SHF_WRITE)
+	*cp++ = 'W';
+      if (shdr->sh_flags & SHF_ALLOC)
+	*cp++ = 'A';
+      if (shdr->sh_flags & SHF_EXECINSTR)
+	*cp++ = 'X';
+      if (shdr->sh_flags & SHF_MERGE)
+	*cp++ = 'M';
+      if (shdr->sh_flags & SHF_STRINGS)
+	*cp++ = 'S';
+      if (shdr->sh_flags & SHF_INFO_LINK)
+	*cp++ = 'I';
+      if (shdr->sh_flags & SHF_LINK_ORDER)
+	*cp++ = 'L';
+      if (shdr->sh_flags & SHF_OS_NONCONFORMING)
+	*cp++ = 'N';
+      if (shdr->sh_flags & SHF_GROUP)
+	*cp++ = 'G';
+      if (shdr->sh_flags & SHF_TLS)
+	*cp++ = 'T';
+      if (shdr->sh_flags & SHF_COMPRESSED)
+	*cp++ = 'C';
+      if (shdr->sh_flags & SHF_ORDERED)
+	*cp++ = 'O';
+      if (shdr->sh_flags & SHF_EXCLUDE)
+	*cp++ = 'E';
+      *cp = '\0';
+
+      const char *sname;
+      char buf[128];
+      sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name) ?: "<corrupt>";
+      printf ("[%2zu] %-20s %-12s %0*" PRIx64 " %0*" PRIx64 " %0*" PRIx64
+	      " %2" PRId64 " %-5s %2" PRId32 " %3" PRId32
+	      " %2" PRId64 "\n",
+	      cnt, sname,
+	      ebl_section_type_name (ebl, shdr->sh_type, buf, sizeof (buf)),
+	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, shdr->sh_addr,
+	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_offset,
+	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, shdr->sh_size,
+	      shdr->sh_entsize, flagbuf, shdr->sh_link, shdr->sh_info,
+	      shdr->sh_addralign);
+
+      if (print_decompress)
+	{
+	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	    {
+	      GElf_Chdr chdr;
+	      if (gelf_getchdr (scn, &chdr) != NULL)
+		printf ("     [ELF %s (%" PRId32 ") %0*" PRIx64
+			" %2" PRId64 "]\n",
+			elf_ch_type_name (chdr.ch_type),
+			chdr.ch_type,
+			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8,
+			chdr.ch_size, chdr.ch_addralign);
+	      else
+		error (0, 0,
+		       gettext ("bad compression header for section %zd: %s"),
+		       elf_ndxscn (scn), elf_errmsg (-1));
+	    }
+	  else if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
+	    {
+	      ssize_t size;
+	      if ((size = dwelf_scn_gnu_compressed_size (scn)) >= 0)
+		printf ("     [GNU ZLIB     %0*zx   ]\n",
+			ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 6 : 8, size);
+	      else
+		error (0, 0,
+		       gettext ("bad gnu compressed size for section %zd: %s"),
+		       elf_ndxscn (scn), elf_errmsg (-1));
+	    }
+	}
+    }
+
+  fputc_unlocked ('\n', stdout);
+}
+
+
+/* Print the program header.  */
+static void
+print_phdr (Ebl *ebl, GElf_Ehdr *ehdr)
+{
+  if (phnum == 0)
+    /* No program header, this is OK in relocatable objects.  */
+    return;
+
+  puts (gettext ("Program Headers:"));
+  if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
+    puts (gettext ("\
+  Type           Offset   VirtAddr   PhysAddr   FileSiz  MemSiz   Flg Align"));
+  else
+    puts (gettext ("\
+  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align"));
+
+  /* Process all program headers.  */
+  bool has_relro = false;
+  GElf_Addr relro_from = 0;
+  GElf_Addr relro_to = 0;
+  for (size_t cnt = 0; cnt < phnum; ++cnt)
+    {
+      char buf[128];
+      GElf_Phdr mem;
+      GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
+
+      /* If for some reason the header cannot be returned show this.  */
+      if (unlikely (phdr == NULL))
+	{
+	  puts ("  ???");
+	  continue;
+	}
+
+      printf ("  %-14s 0x%06" PRIx64 " 0x%0*" PRIx64 " 0x%0*" PRIx64
+	      " 0x%06" PRIx64 " 0x%06" PRIx64 " %c%c%c 0x%" PRIx64 "\n",
+	      ebl_segment_type_name (ebl, phdr->p_type, buf, sizeof (buf)),
+	      phdr->p_offset,
+	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_vaddr,
+	      ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16, phdr->p_paddr,
+	      phdr->p_filesz,
+	      phdr->p_memsz,
+	      phdr->p_flags & PF_R ? 'R' : ' ',
+	      phdr->p_flags & PF_W ? 'W' : ' ',
+	      phdr->p_flags & PF_X ? 'E' : ' ',
+	      phdr->p_align);
+
+      if (phdr->p_type == PT_INTERP)
+	{
+	  /* If we are sure the file offset is valid then we can show
+	     the user the name of the interpreter.  We check whether
+	     there is a section at the file offset.  Normally there
+	     would be a section called ".interp".  But in separate
+	     .debug files it is a NOBITS section (and so doesn't match
+	     with gelf_offscn).  Which probably means the offset is
+	     not valid another reason could be because the ELF file
+	     just doesn't contain any section headers, in that case
+	     just play it safe and don't display anything.  */
+
+	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+	  size_t maxsize;
+	  char *filedata = elf_rawfile (ebl->elf, &maxsize);
+
+	  if (shdr != NULL && shdr->sh_type == SHT_PROGBITS
+	      && filedata != NULL && phdr->p_offset < maxsize
+	      && phdr->p_filesz <= maxsize - phdr->p_offset
+	      && memchr (filedata + phdr->p_offset, '\0',
+			 phdr->p_filesz) != NULL)
+	    printf (gettext ("\t[Requesting program interpreter: %s]\n"),
+		    filedata + phdr->p_offset);
+	}
+      else if (phdr->p_type == PT_GNU_RELRO)
+	{
+	  has_relro = true;
+	  relro_from = phdr->p_vaddr;
+	  relro_to = relro_from + phdr->p_memsz;
+	}
+    }
+
+  if (ehdr->e_shnum == 0)
+    /* No sections in the file.  Punt.  */
+    return;
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  puts (gettext ("\n Section to Segment mapping:\n  Segment Sections..."));
+
+  for (size_t cnt = 0; cnt < phnum; ++cnt)
+    {
+      /* Print the segment number.  */
+      printf ("   %2.2zu     ", cnt);
+
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &phdr_mem);
+      /* This must not happen.  */
+      if (unlikely (phdr == NULL))
+	error (EXIT_FAILURE, 0, gettext ("cannot get program header: %s"),
+	       elf_errmsg (-1));
+
+      /* Iterate over the sections.  */
+      bool in_relro = false;
+      bool in_ro = false;
+      for (size_t inner = 1; inner < shnum; ++inner)
+	{
+	  Elf_Scn *scn = elf_getscn (ebl->elf, inner);
+	  /* This should not happen.  */
+	  if (unlikely (scn == NULL))
+	    error (EXIT_FAILURE, 0, gettext ("cannot get section: %s"),
+		   elf_errmsg (-1));
+
+	  /* Get the section header.  */
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (unlikely (shdr == NULL))
+	    error (EXIT_FAILURE, 0,
+		   gettext ("cannot get section header: %s"),
+		   elf_errmsg (-1));
+
+	  if (shdr->sh_size > 0
+	      /* Compare allocated sections by VMA, unallocated
+		 sections by file offset.  */
+	      && (shdr->sh_flags & SHF_ALLOC
+		  ? (shdr->sh_addr >= phdr->p_vaddr
+		     && (shdr->sh_addr + shdr->sh_size
+			 <= phdr->p_vaddr + phdr->p_memsz))
+		  : (shdr->sh_offset >= phdr->p_offset
+		     && (shdr->sh_offset + shdr->sh_size
+			 <= phdr->p_offset + phdr->p_filesz))))
+	    {
+	      if (has_relro && !in_relro
+		  && shdr->sh_addr >= relro_from
+		  && shdr->sh_addr + shdr->sh_size <= relro_to)
+		{
+		  fputs_unlocked (" [RELRO:", stdout);
+		  in_relro = true;
+		}
+	      else if (has_relro && in_relro && shdr->sh_addr >= relro_to)
+		{
+		  fputs_unlocked ("]", stdout);
+		  in_relro =  false;
+		}
+	      else if (has_relro && in_relro
+		       && shdr->sh_addr + shdr->sh_size > relro_to)
+		fputs_unlocked ("] <RELRO:", stdout);
+	      else if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_W) == 0)
+		{
+		  if (!in_ro)
+		    {
+		      fputs_unlocked (" [RO:", stdout);
+		      in_ro = true;
+		    }
+		}
+	      else
+		{
+		  /* Determine the segment this section is part of.  */
+		  size_t cnt2;
+		  GElf_Phdr phdr2_mem;
+		  GElf_Phdr *phdr2 = NULL;
+		  for (cnt2 = 0; cnt2 < phnum; ++cnt2)
+		    {
+		      phdr2 = gelf_getphdr (ebl->elf, cnt2, &phdr2_mem);
+
+		      if (phdr2 != NULL && phdr2->p_type == PT_LOAD
+			  && shdr->sh_addr >= phdr2->p_vaddr
+			  && (shdr->sh_addr + shdr->sh_size
+			      <= phdr2->p_vaddr + phdr2->p_memsz))
+			break;
+		    }
+
+		  if (cnt2 < phnum)
+		    {
+		      if ((phdr2->p_flags & PF_W) == 0 && !in_ro)
+			{
+			  fputs_unlocked (" [RO:", stdout);
+			  in_ro = true;
+			}
+		      else if ((phdr2->p_flags & PF_W) != 0 && in_ro)
+			{
+			  fputs_unlocked ("]", stdout);
+			  in_ro = false;
+			}
+		    }
+		}
+
+	      printf (" %s",
+		      elf_strptr (ebl->elf, shstrndx, shdr->sh_name));
+
+	      /* Signal that this sectin is only partially covered.  */
+	      if (has_relro && in_relro
+		       && shdr->sh_addr + shdr->sh_size > relro_to)
+		{
+		  fputs_unlocked (">", stdout);
+		  in_relro =  false;
+		}
+	    }
+	}
+      if (in_relro || in_ro)
+	fputs_unlocked ("]", stdout);
+
+      /* Finish the line.  */
+      fputc_unlocked ('\n', stdout);
+    }
+}
+
+
+static const char *
+section_name (Ebl *ebl, GElf_Ehdr *ehdr, GElf_Shdr *shdr)
+{
+  return elf_strptr (ebl->elf, ehdr->e_shstrndx, shdr->sh_name) ?: "???";
+}
+
+
+static void
+handle_scngrp (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
+{
+  /* Get the data of the section.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+
+  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+  GElf_Shdr symshdr_mem;
+  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+  Elf_Data *symdata = elf_getdata (symscn, NULL);
+
+  if (data == NULL || data->d_size < sizeof (Elf32_Word) || symshdr == NULL
+      || symdata == NULL)
+    return;
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  Elf32_Word *grpref = (Elf32_Word *) data->d_buf;
+
+  GElf_Sym sym_mem;
+  GElf_Sym *sym = gelf_getsym (symdata, shdr->sh_info, &sym_mem);
+
+  printf ((grpref[0] & GRP_COMDAT)
+	  ? ngettext ("\
+\nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entry:\n",
+		      "\
+\nCOMDAT section group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
+		      data->d_size / sizeof (Elf32_Word) - 1)
+	  : ngettext ("\
+\nSection group [%2zu] '%s' with signature '%s' contains %zu entry:\n", "\
+\nSection group [%2zu] '%s' with signature '%s' contains %zu entries:\n",
+		      data->d_size / sizeof (Elf32_Word) - 1),
+	  elf_ndxscn (scn),
+	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+	  (sym == NULL ? NULL
+	   : elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name))
+	  ?: gettext ("<INVALID SYMBOL>"),
+	  data->d_size / sizeof (Elf32_Word) - 1);
+
+  for (size_t cnt = 1; cnt < data->d_size / sizeof (Elf32_Word); ++cnt)
+    {
+      GElf_Shdr grpshdr_mem;
+      GElf_Shdr *grpshdr = gelf_getshdr (elf_getscn (ebl->elf, grpref[cnt]),
+					 &grpshdr_mem);
+
+      const char *str;
+      printf ("  [%2u] %s\n",
+	      grpref[cnt],
+	      grpshdr != NULL
+	      && (str = elf_strptr (ebl->elf, shstrndx, grpshdr->sh_name))
+	      ? str : gettext ("<INVALID SECTION>"));
+    }
+}
+
+
+static void
+print_scngrp (Ebl *ebl)
+{
+  /* Find all relocation sections and handle them.  */
+  Elf_Scn *scn = NULL;
+
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+       /* Handle the section if it is a symbol table.  */
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr != NULL && shdr->sh_type == SHT_GROUP)
+	{
+	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	    {
+	      if (elf_compress (scn, 0, 0) < 0)
+		printf ("WARNING: %s [%zd]\n",
+			gettext ("Couldn't uncompress section"),
+			elf_ndxscn (scn));
+	      shdr = gelf_getshdr (scn, &shdr_mem);
+	      if (unlikely (shdr == NULL))
+		error (EXIT_FAILURE, 0,
+		       gettext ("cannot get section [%zd] header: %s"),
+		       elf_ndxscn (scn),
+		       elf_errmsg (-1));
+	    }
+	  handle_scngrp (ebl, scn, shdr);
+	}
+    }
+}
+
+
+static const struct flags
+{
+  int mask;
+  const char *str;
+} dt_flags[] =
+  {
+    { DF_ORIGIN, "ORIGIN" },
+    { DF_SYMBOLIC, "SYMBOLIC" },
+    { DF_TEXTREL, "TEXTREL" },
+    { DF_BIND_NOW, "BIND_NOW" },
+    { DF_STATIC_TLS, "STATIC_TLS" }
+  };
+static const int ndt_flags = sizeof (dt_flags) / sizeof (dt_flags[0]);
+
+static const struct flags dt_flags_1[] =
+  {
+    { DF_1_NOW, "NOW" },
+    { DF_1_GLOBAL, "GLOBAL" },
+    { DF_1_GROUP, "GROUP" },
+    { DF_1_NODELETE, "NODELETE" },
+    { DF_1_LOADFLTR, "LOADFLTR" },
+    { DF_1_INITFIRST, "INITFIRST" },
+    { DF_1_NOOPEN, "NOOPEN" },
+    { DF_1_ORIGIN, "ORIGIN" },
+    { DF_1_DIRECT, "DIRECT" },
+    { DF_1_TRANS, "TRANS" },
+    { DF_1_INTERPOSE, "INTERPOSE" },
+    { DF_1_NODEFLIB, "NODEFLIB" },
+    { DF_1_NODUMP, "NODUMP" },
+    { DF_1_CONFALT, "CONFALT" },
+    { DF_1_ENDFILTEE, "ENDFILTEE" },
+    { DF_1_DISPRELDNE, "DISPRELDNE" },
+    { DF_1_DISPRELPND, "DISPRELPND" },
+  };
+static const int ndt_flags_1 = sizeof (dt_flags_1) / sizeof (dt_flags_1[0]);
+
+static const struct flags dt_feature_1[] =
+  {
+    { DTF_1_PARINIT, "PARINIT" },
+    { DTF_1_CONFEXP, "CONFEXP" }
+  };
+static const int ndt_feature_1 = (sizeof (dt_feature_1)
+				  / sizeof (dt_feature_1[0]));
+
+static const struct flags dt_posflag_1[] =
+  {
+    { DF_P1_LAZYLOAD, "LAZYLOAD" },
+    { DF_P1_GROUPPERM, "GROUPPERM" }
+  };
+static const int ndt_posflag_1 = (sizeof (dt_posflag_1)
+				  / sizeof (dt_posflag_1[0]));
+
+
+static void
+print_flags (int class, GElf_Xword d_val, const struct flags *flags,
+		int nflags)
+{
+  bool first = true;
+  int cnt;
+
+  for (cnt = 0; cnt < nflags; ++cnt)
+    if (d_val & flags[cnt].mask)
+      {
+	if (!first)
+	  putchar_unlocked (' ');
+	fputs_unlocked (flags[cnt].str, stdout);
+	d_val &= ~flags[cnt].mask;
+	first = false;
+      }
+
+  if (d_val != 0)
+    {
+      if (!first)
+	putchar_unlocked (' ');
+      printf ("%#0*" PRIx64, class == ELFCLASS32 ? 10 : 18, d_val);
+    }
+
+  putchar_unlocked ('\n');
+}
+
+
+static void
+print_dt_flags (int class, GElf_Xword d_val)
+{
+  print_flags (class, d_val, dt_flags, ndt_flags);
+}
+
+
+static void
+print_dt_flags_1 (int class, GElf_Xword d_val)
+{
+  print_flags (class, d_val, dt_flags_1, ndt_flags_1);
+}
+
+
+static void
+print_dt_feature_1 (int class, GElf_Xword d_val)
+{
+  print_flags (class, d_val, dt_feature_1, ndt_feature_1);
+}
+
+
+static void
+print_dt_posflag_1 (int class, GElf_Xword d_val)
+{
+  print_flags (class, d_val, dt_posflag_1, ndt_posflag_1);
+}
+
+
+static void
+handle_dynamic (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
+{
+  int class = gelf_getclass (ebl->elf);
+  GElf_Shdr glink_mem;
+  GElf_Shdr *glink;
+  Elf_Data *data;
+  size_t cnt;
+  size_t shstrndx;
+  size_t sh_entsize;
+
+  /* Get the data of the section.  */
+  data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return;
+
+  /* Get the section header string table index.  */
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  sh_entsize = gelf_fsize (ebl->elf, ELF_T_DYN, 1, EV_CURRENT);
+
+  glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
+  if (glink == NULL)
+    error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
+	   elf_ndxscn (scn));
+
+  printf (ngettext ("\
+\nDynamic segment contains %lu entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
+		    "\
+\nDynamic segment contains %lu entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
+		    shdr->sh_size / sh_entsize),
+	  (unsigned long int) (shdr->sh_size / sh_entsize),
+	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
+	  shdr->sh_offset,
+	  (int) shdr->sh_link,
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+  fputs_unlocked (gettext ("  Type              Value\n"), stdout);
+
+  for (cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
+    {
+      GElf_Dyn dynmem;
+      GElf_Dyn *dyn = gelf_getdyn (data, cnt, &dynmem);
+      if (dyn == NULL)
+	break;
+
+      char buf[64];
+      printf ("  %-17s ",
+	      ebl_dynamic_tag_name (ebl, dyn->d_tag, buf, sizeof (buf)));
+
+      switch (dyn->d_tag)
+	{
+	case DT_NULL:
+	case DT_DEBUG:
+	case DT_BIND_NOW:
+	case DT_TEXTREL:
+	  /* No further output.  */
+	  fputc_unlocked ('\n', stdout);
+	  break;
+
+	case DT_NEEDED:
+	  printf (gettext ("Shared library: [%s]\n"),
+		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
+	  break;
+
+	case DT_SONAME:
+	  printf (gettext ("Library soname: [%s]\n"),
+		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
+	  break;
+
+	case DT_RPATH:
+	  printf (gettext ("Library rpath: [%s]\n"),
+		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
+	  break;
+
+	case DT_RUNPATH:
+	  printf (gettext ("Library runpath: [%s]\n"),
+		  elf_strptr (ebl->elf, shdr->sh_link, dyn->d_un.d_val));
+	  break;
+
+	case DT_PLTRELSZ:
+	case DT_RELASZ:
+	case DT_STRSZ:
+	case DT_RELSZ:
+	case DT_RELAENT:
+	case DT_SYMENT:
+	case DT_RELENT:
+	case DT_PLTPADSZ:
+	case DT_MOVEENT:
+	case DT_MOVESZ:
+	case DT_INIT_ARRAYSZ:
+	case DT_FINI_ARRAYSZ:
+	case DT_SYMINSZ:
+	case DT_SYMINENT:
+	case DT_GNU_CONFLICTSZ:
+	case DT_GNU_LIBLISTSZ:
+	  printf (gettext ("%" PRId64 " (bytes)\n"), dyn->d_un.d_val);
+	  break;
+
+	case DT_VERDEFNUM:
+	case DT_VERNEEDNUM:
+	case DT_RELACOUNT:
+	case DT_RELCOUNT:
+	  printf ("%" PRId64 "\n", dyn->d_un.d_val);
+	  break;
+
+	case DT_PLTREL:;
+	  const char *tagname = ebl_dynamic_tag_name (ebl, dyn->d_un.d_val,
+						      NULL, 0);
+	  puts (tagname ?: "???");
+	  break;
+
+	case DT_FLAGS:
+	  print_dt_flags (class, dyn->d_un.d_val);
+	  break;
+
+	case DT_FLAGS_1:
+	  print_dt_flags_1 (class, dyn->d_un.d_val);
+	  break;
+
+	case DT_FEATURE_1:
+	  print_dt_feature_1 (class, dyn->d_un.d_val);
+	  break;
+
+	case DT_POSFLAG_1:
+	  print_dt_posflag_1 (class, dyn->d_un.d_val);
+	  break;
+
+	default:
+	  printf ("%#0*" PRIx64 "\n",
+		  class == ELFCLASS32 ? 10 : 18, dyn->d_un.d_val);
+	  break;
+	}
+    }
+}
+
+
+/* Print the dynamic segment.  */
+static void
+print_dynamic (Ebl *ebl)
+{
+  for (size_t i = 0; i < phnum; ++i)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (ebl->elf, i, &phdr_mem);
+
+      if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
+	{
+	  Elf_Scn *scn = gelf_offscn (ebl->elf, phdr->p_offset);
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (shdr != NULL && shdr->sh_type == SHT_DYNAMIC)
+	    handle_dynamic (ebl, scn, shdr);
+	  break;
+	}
+    }
+}
+
+
+/* Print relocations.  */
+static void
+print_relocs (Ebl *ebl, GElf_Ehdr *ehdr)
+{
+  /* Find all relocation sections and handle them.  */
+  Elf_Scn *scn = NULL;
+
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+       /* Handle the section if it is a symbol table.  */
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (likely (shdr != NULL))
+	{
+	  if (shdr->sh_type == SHT_REL)
+	    handle_relocs_rel (ebl, ehdr, scn, shdr);
+	  else if (shdr->sh_type == SHT_RELA)
+	    handle_relocs_rela (ebl, ehdr, scn, shdr);
+	}
+    }
+}
+
+
+/* Handle a relocation section.  */
+static void
+handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
+{
+  int class = gelf_getclass (ebl->elf);
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_REL, 1, EV_CURRENT);
+  int nentries = shdr->sh_size / sh_entsize;
+
+  /* Get the data of the section.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return;
+
+  /* Get the symbol table information.  */
+  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+  GElf_Shdr symshdr_mem;
+  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+  Elf_Data *symdata = elf_getdata (symscn, NULL);
+
+  /* Get the section header of the section the relocations are for.  */
+  GElf_Shdr destshdr_mem;
+  GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
+				      &destshdr_mem);
+
+  if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
+    {
+      printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
+	      shdr->sh_offset);
+      return;
+    }
+
+  /* Search for the optional extended section index table.  */
+  Elf_Data *xndxdata = NULL;
+  int xndxscnidx = elf_scnshndx (scn);
+  if (unlikely (xndxscnidx > 0))
+    xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  if (shdr->sh_info != 0)
+    printf (ngettext ("\
+\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
+		    "\
+\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
+		      nentries),
+	    elf_ndxscn (scn),
+	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+	    (unsigned int) shdr->sh_info,
+	    elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
+	    shdr->sh_offset,
+	    nentries);
+  else
+    /* The .rel.dyn section does not refer to a specific section but
+       instead of section index zero.  Do not try to print a section
+       name.  */
+    printf (ngettext ("\
+\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
+		    "\
+\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
+		      nentries),
+	    (unsigned int) elf_ndxscn (scn),
+	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+	    shdr->sh_offset,
+	    nentries);
+  fputs_unlocked (class == ELFCLASS32
+		  ? gettext ("\
+  Offset      Type                 Value       Name\n")
+		  : gettext ("\
+  Offset              Type                 Value               Name\n"),
+	 stdout);
+
+  int is_statically_linked = 0;
+  for (int cnt = 0; cnt < nentries; ++cnt)
+    {
+      GElf_Rel relmem;
+      GElf_Rel *rel = gelf_getrel (data, cnt, &relmem);
+      if (likely (rel != NULL))
+	{
+	  char buf[128];
+	  GElf_Sym symmem;
+	  Elf32_Word xndx;
+	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
+					    GELF_R_SYM (rel->r_info),
+					    &symmem, &xndx);
+	  if (unlikely (sym == NULL))
+	    {
+	      /* As a special case we have to handle relocations in static
+		 executables.  This only happens for IRELATIVE relocations
+		 (so far).  There is no symbol table.  */
+	      if (is_statically_linked == 0)
+		{
+		  /* Find the program header and look for a PT_INTERP entry. */
+		  is_statically_linked = -1;
+		  if (ehdr->e_type == ET_EXEC)
+		    {
+		      is_statically_linked = 1;
+
+		      for (size_t inner = 0; inner < phnum; ++inner)
+			{
+			  GElf_Phdr phdr_mem;
+			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
+							  &phdr_mem);
+			  if (phdr != NULL && phdr->p_type == PT_INTERP)
+			    {
+			      is_statically_linked = -1;
+			      break;
+			    }
+			}
+		    }
+		}
+
+	      if (is_statically_linked > 0 && shdr->sh_link == 0)
+		printf ("\
+  %#0*" PRIx64 "  %-20s %*s  %s\n",
+			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+			/* Avoid the leading R_ which isn't carrying any
+			   information.  */
+			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					       buf, sizeof (buf)) + 2
+			: gettext ("<INVALID RELOC>"),
+			class == ELFCLASS32 ? 10 : 18, "",
+			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+	      else
+		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
+			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+			/* Avoid the leading R_ which isn't carrying any
+			   information.  */
+			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					       buf, sizeof (buf)) + 2
+			: gettext ("<INVALID RELOC>"),
+			gettext ("INVALID SYMBOL"),
+			(long int) GELF_R_SYM (rel->r_info));
+	    }
+	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
+	    printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
+		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+		    likely (ebl_reloc_type_check (ebl,
+						  GELF_R_TYPE (rel->r_info)))
+		    /* Avoid the leading R_ which isn't carrying any
+		       information.  */
+		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					   buf, sizeof (buf)) + 2
+		    : gettext ("<INVALID RELOC>"),
+		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
+		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
+	  else
+	    {
+	      /* This is a relocation against a STT_SECTION symbol.  */
+	      GElf_Shdr secshdr_mem;
+	      GElf_Shdr *secshdr;
+	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
+						  sym->st_shndx == SHN_XINDEX
+						  ? xndx : sym->st_shndx),
+				      &secshdr_mem);
+
+	      if (unlikely (secshdr == NULL))
+		printf ("  %#0*" PRIx64 "  %-20s <%s %ld>\n",
+			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+			/* Avoid the leading R_ which isn't carrying any
+			   information.  */
+			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					       buf, sizeof (buf)) + 2
+			: gettext ("<INVALID RELOC>"),
+			gettext ("INVALID SECTION"),
+			(long int) (sym->st_shndx == SHN_XINDEX
+				    ? xndx : sym->st_shndx));
+	      else
+		printf ("  %#0*" PRIx64 "  %-20s %#0*" PRIx64 "  %s\n",
+			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+			/* Avoid the leading R_ which isn't carrying any
+			   information.  */
+			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					       buf, sizeof (buf)) + 2
+			: gettext ("<INVALID RELOC>"),
+			class == ELFCLASS32 ? 10 : 18, sym->st_value,
+			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
+	    }
+	}
+    }
+}
+
+
+/* Handle a relocation section.  */
+static void
+handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
+{
+  int class = gelf_getclass (ebl->elf);
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_RELA, 1, EV_CURRENT);
+  int nentries = shdr->sh_size / sh_entsize;
+
+  /* Get the data of the section.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return;
+
+  /* Get the symbol table information.  */
+  Elf_Scn *symscn = elf_getscn (ebl->elf, shdr->sh_link);
+  GElf_Shdr symshdr_mem;
+  GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
+  Elf_Data *symdata = elf_getdata (symscn, NULL);
+
+  /* Get the section header of the section the relocations are for.  */
+  GElf_Shdr destshdr_mem;
+  GElf_Shdr *destshdr = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_info),
+				      &destshdr_mem);
+
+  if (unlikely (symshdr == NULL || symdata == NULL || destshdr == NULL))
+    {
+      printf (gettext ("\nInvalid symbol table at offset %#0" PRIx64 "\n"),
+	      shdr->sh_offset);
+      return;
+    }
+
+  /* Search for the optional extended section index table.  */
+  Elf_Data *xndxdata = NULL;
+  int xndxscnidx = elf_scnshndx (scn);
+  if (unlikely (xndxscnidx > 0))
+    xndxdata = elf_getdata (elf_getscn (ebl->elf, xndxscnidx), NULL);
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  if (shdr->sh_info != 0)
+    printf (ngettext ("\
+\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
+		    "\
+\nRelocation section [%2zu] '%s' for section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
+		    nentries),
+	  elf_ndxscn (scn),
+	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+	  (unsigned int) shdr->sh_info,
+	  elf_strptr (ebl->elf, shstrndx, destshdr->sh_name),
+	  shdr->sh_offset,
+	  nentries);
+  else
+    /* The .rela.dyn section does not refer to a specific section but
+       instead of section index zero.  Do not try to print a section
+       name.  */
+    printf (ngettext ("\
+\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
+		    "\
+\nRelocation section [%2u] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
+		      nentries),
+	    (unsigned int) elf_ndxscn (scn),
+	    elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+	    shdr->sh_offset,
+	    nentries);
+  fputs_unlocked (class == ELFCLASS32
+		  ? gettext ("\
+  Offset      Type            Value       Addend Name\n")
+		  : gettext ("\
+  Offset              Type            Value               Addend Name\n"),
+		  stdout);
+
+  int is_statically_linked = 0;
+  for (int cnt = 0; cnt < nentries; ++cnt)
+    {
+      GElf_Rela relmem;
+      GElf_Rela *rel = gelf_getrela (data, cnt, &relmem);
+      if (likely (rel != NULL))
+	{
+	  char buf[64];
+	  GElf_Sym symmem;
+	  Elf32_Word xndx;
+	  GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
+					    GELF_R_SYM (rel->r_info),
+					    &symmem, &xndx);
+
+	  if (unlikely (sym == NULL))
+	    {
+	      /* As a special case we have to handle relocations in static
+		 executables.  This only happens for IRELATIVE relocations
+		 (so far).  There is no symbol table.  */
+	      if (is_statically_linked == 0)
+		{
+		  /* Find the program header and look for a PT_INTERP entry. */
+		  is_statically_linked = -1;
+		  if (ehdr->e_type == ET_EXEC)
+		    {
+		      is_statically_linked = 1;
+
+		      for (size_t inner = 0; inner < phnum; ++inner)
+			{
+			  GElf_Phdr phdr_mem;
+			  GElf_Phdr *phdr = gelf_getphdr (ebl->elf, inner,
+							  &phdr_mem);
+			  if (phdr != NULL && phdr->p_type == PT_INTERP)
+			    {
+			      is_statically_linked = -1;
+			      break;
+			    }
+			}
+		    }
+		}
+
+	      if (is_statically_linked > 0 && shdr->sh_link == 0)
+		printf ("\
+  %#0*" PRIx64 "  %-15s %*s  %#6" PRIx64 " %s\n",
+			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+			/* Avoid the leading R_ which isn't carrying any
+			   information.  */
+			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					       buf, sizeof (buf)) + 2
+			: gettext ("<INVALID RELOC>"),
+			class == ELFCLASS32 ? 10 : 18, "",
+			rel->r_addend,
+			elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+	      else
+		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
+			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+			/* Avoid the leading R_ which isn't carrying any
+			   information.  */
+			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					       buf, sizeof (buf)) + 2
+			: gettext ("<INVALID RELOC>"),
+			gettext ("INVALID SYMBOL"),
+			(long int) GELF_R_SYM (rel->r_info));
+	    }
+	  else if (GELF_ST_TYPE (sym->st_info) != STT_SECTION)
+	    printf ("\
+  %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
+		    class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+		    likely (ebl_reloc_type_check (ebl,
+						  GELF_R_TYPE (rel->r_info)))
+		    /* Avoid the leading R_ which isn't carrying any
+		       information.  */
+		    ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					   buf, sizeof (buf)) + 2
+		    : gettext ("<INVALID RELOC>"),
+		    class == ELFCLASS32 ? 10 : 18, sym->st_value,
+		    rel->r_addend,
+		    elf_strptr (ebl->elf, symshdr->sh_link, sym->st_name));
+	  else
+	    {
+	      /* This is a relocation against a STT_SECTION symbol.  */
+	      GElf_Shdr secshdr_mem;
+	      GElf_Shdr *secshdr;
+	      secshdr = gelf_getshdr (elf_getscn (ebl->elf,
+						  sym->st_shndx == SHN_XINDEX
+						  ? xndx : sym->st_shndx),
+				      &secshdr_mem);
+
+	      if (unlikely (secshdr == NULL))
+		printf ("  %#0*" PRIx64 "  %-15s <%s %ld>\n",
+			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+			/* Avoid the leading R_ which isn't carrying any
+			   information.  */
+			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					       buf, sizeof (buf)) + 2
+			: gettext ("<INVALID RELOC>"),
+			gettext ("INVALID SECTION"),
+			(long int) (sym->st_shndx == SHN_XINDEX
+				    ? xndx : sym->st_shndx));
+	      else
+		printf ("\
+  %#0*" PRIx64 "  %-15s %#0*" PRIx64 "  %+6" PRId64 " %s\n",
+			class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+			ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+			/* Avoid the leading R_ which isn't carrying any
+			   information.  */
+			? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+					       buf, sizeof (buf)) + 2
+			: gettext ("<INVALID RELOC>"),
+			class == ELFCLASS32 ? 10 : 18, sym->st_value,
+			rel->r_addend,
+			elf_strptr (ebl->elf, shstrndx, secshdr->sh_name));
+	    }
+	}
+    }
+}
+
+
+/* Print the program header.  */
+static void
+print_symtab (Ebl *ebl, int type)
+{
+  /* Find the symbol table(s).  For this we have to search through the
+     section table.  */
+  Elf_Scn *scn = NULL;
+
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      /* Handle the section if it is a symbol table.  */
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr != NULL && shdr->sh_type == (GElf_Word) type)
+	{
+	  if (symbol_table_section != NULL)
+	    {
+	      /* Get the section header string table index.  */
+	      size_t shstrndx;
+	      const char *sname;
+	      if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+		error (EXIT_FAILURE, 0,
+		       gettext ("cannot get section header string table index"));
+	      sname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
+	      if (sname == NULL || strcmp (sname, symbol_table_section) != 0)
+		continue;
+	    }
+
+	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	    {
+	      if (elf_compress (scn, 0, 0) < 0)
+		printf ("WARNING: %s [%zd]\n",
+			gettext ("Couldn't uncompress section"),
+			elf_ndxscn (scn));
+	      shdr = gelf_getshdr (scn, &shdr_mem);
+	      if (unlikely (shdr == NULL))
+		error (EXIT_FAILURE, 0,
+		       gettext ("cannot get section [%zd] header: %s"),
+		       elf_ndxscn (scn), elf_errmsg (-1));
+	    }
+	  handle_symtab (ebl, scn, shdr);
+	}
+    }
+}
+
+
+static void
+handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
+{
+  Elf_Data *versym_data = NULL;
+  Elf_Data *verneed_data = NULL;
+  Elf_Data *verdef_data = NULL;
+  Elf_Data *xndx_data = NULL;
+  int class = gelf_getclass (ebl->elf);
+  Elf32_Word verneed_stridx = 0;
+  Elf32_Word verdef_stridx = 0;
+
+  /* Get the data of the section.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return;
+
+  /* Find out whether we have other sections we might need.  */
+  Elf_Scn *runscn = NULL;
+  while ((runscn = elf_nextscn (ebl->elf, runscn)) != NULL)
+    {
+      GElf_Shdr runshdr_mem;
+      GElf_Shdr *runshdr = gelf_getshdr (runscn, &runshdr_mem);
+
+      if (likely (runshdr != NULL))
+	{
+	  if (runshdr->sh_type == SHT_GNU_versym
+	      && runshdr->sh_link == elf_ndxscn (scn))
+	    /* Bingo, found the version information.  Now get the data.  */
+	    versym_data = elf_getdata (runscn, NULL);
+	  else if (runshdr->sh_type == SHT_GNU_verneed)
+	    {
+	      /* This is the information about the needed versions.  */
+	      verneed_data = elf_getdata (runscn, NULL);
+	      verneed_stridx = runshdr->sh_link;
+	    }
+	  else if (runshdr->sh_type == SHT_GNU_verdef)
+	    {
+	      /* This is the information about the defined versions.  */
+	      verdef_data = elf_getdata (runscn, NULL);
+	      verdef_stridx = runshdr->sh_link;
+	    }
+	  else if (runshdr->sh_type == SHT_SYMTAB_SHNDX
+	      && runshdr->sh_link == elf_ndxscn (scn))
+	    /* Extended section index.  */
+	    xndx_data = elf_getdata (runscn, NULL);
+	}
+    }
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  GElf_Shdr glink_mem;
+  GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+				   &glink_mem);
+  if (glink == NULL)
+    error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
+	   elf_ndxscn (scn));
+
+  /* Now we can compute the number of entries in the section.  */
+  unsigned int nsyms = data->d_size / (class == ELFCLASS32
+				       ? sizeof (Elf32_Sym)
+				       : sizeof (Elf64_Sym));
+
+  printf (ngettext ("\nSymbol table [%2u] '%s' contains %u entry:\n",
+		    "\nSymbol table [%2u] '%s' contains %u entries:\n",
+		    nsyms),
+	  (unsigned int) elf_ndxscn (scn),
+	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), nsyms);
+  printf (ngettext (" %lu local symbol  String table: [%2u] '%s'\n",
+		    " %lu local symbols  String table: [%2u] '%s'\n",
+		    shdr->sh_info),
+	  (unsigned long int) shdr->sh_info,
+	  (unsigned int) shdr->sh_link,
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+
+  fputs_unlocked (class == ELFCLASS32
+		  ? gettext ("\
+  Num:    Value   Size Type    Bind   Vis          Ndx Name\n")
+		  : gettext ("\
+  Num:            Value   Size Type    Bind   Vis          Ndx Name\n"),
+		  stdout);
+
+  for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
+    {
+      char typebuf[64];
+      char bindbuf[64];
+      char scnbuf[64];
+      Elf32_Word xndx;
+      GElf_Sym sym_mem;
+      GElf_Sym *sym = gelf_getsymshndx (data, xndx_data, cnt, &sym_mem, &xndx);
+
+      if (unlikely (sym == NULL))
+	continue;
+
+      /* Determine the real section index.  */
+      if (likely (sym->st_shndx != SHN_XINDEX))
+	xndx = sym->st_shndx;
+
+      printf (gettext ("\
+%5u: %0*" PRIx64 " %6" PRId64 " %-7s %-6s %-9s %6s %s"),
+	      cnt,
+	      class == ELFCLASS32 ? 8 : 16,
+	      sym->st_value,
+	      sym->st_size,
+	      ebl_symbol_type_name (ebl, GELF_ST_TYPE (sym->st_info),
+				    typebuf, sizeof (typebuf)),
+	      ebl_symbol_binding_name (ebl, GELF_ST_BIND (sym->st_info),
+				       bindbuf, sizeof (bindbuf)),
+	      get_visibility_type (GELF_ST_VISIBILITY (sym->st_other)),
+	      ebl_section_name (ebl, sym->st_shndx, xndx, scnbuf,
+				sizeof (scnbuf), NULL, shnum),
+	      elf_strptr (ebl->elf, shdr->sh_link, sym->st_name));
+
+      if (versym_data != NULL)
+	{
+	  /* Get the version information.  */
+	  GElf_Versym versym_mem;
+	  GElf_Versym *versym = gelf_getversym (versym_data, cnt, &versym_mem);
+
+	  if (versym != NULL && ((*versym & 0x8000) != 0 || *versym > 1))
+	    {
+	      bool is_nobits = false;
+	      bool check_def = xndx != SHN_UNDEF;
+
+	      if (xndx < SHN_LORESERVE || sym->st_shndx == SHN_XINDEX)
+		{
+		  GElf_Shdr symshdr_mem;
+		  GElf_Shdr *symshdr =
+		    gelf_getshdr (elf_getscn (ebl->elf, xndx), &symshdr_mem);
+
+		  is_nobits = (symshdr != NULL
+			       && symshdr->sh_type == SHT_NOBITS);
+		}
+
+	      if (is_nobits || ! check_def)
+		{
+		  /* We must test both.  */
+		  GElf_Vernaux vernaux_mem;
+		  GElf_Vernaux *vernaux = NULL;
+		  size_t vn_offset = 0;
+
+		  GElf_Verneed verneed_mem;
+		  GElf_Verneed *verneed = gelf_getverneed (verneed_data, 0,
+							   &verneed_mem);
+		  while (verneed != NULL)
+		    {
+		      size_t vna_offset = vn_offset;
+
+		      vernaux = gelf_getvernaux (verneed_data,
+						 vna_offset += verneed->vn_aux,
+						 &vernaux_mem);
+		      while (vernaux != NULL
+			     && vernaux->vna_other != *versym
+			     && vernaux->vna_next != 0)
+			{
+			  /* Update the offset.  */
+			  vna_offset += vernaux->vna_next;
+
+			  vernaux = (vernaux->vna_next == 0
+				     ? NULL
+				     : gelf_getvernaux (verneed_data,
+							vna_offset,
+							&vernaux_mem));
+			}
+
+		      /* Check whether we found the version.  */
+		      if (vernaux != NULL && vernaux->vna_other == *versym)
+			/* Found it.  */
+			break;
+
+		      vn_offset += verneed->vn_next;
+		      verneed = (verneed->vn_next == 0
+				 ? NULL
+				 : gelf_getverneed (verneed_data, vn_offset,
+						    &verneed_mem));
+		    }
+
+		  if (vernaux != NULL && vernaux->vna_other == *versym)
+		    {
+		      printf ("@%s (%u)",
+			      elf_strptr (ebl->elf, verneed_stridx,
+					  vernaux->vna_name),
+			      (unsigned int) vernaux->vna_other);
+		      check_def = 0;
+		    }
+		  else if (unlikely (! is_nobits))
+		    error (0, 0, gettext ("bad dynamic symbol"));
+		  else
+		    check_def = 1;
+		}
+
+	      if (check_def && *versym != 0x8001)
+		{
+		  /* We must test both.  */
+		  size_t vd_offset = 0;
+
+		  GElf_Verdef verdef_mem;
+		  GElf_Verdef *verdef = gelf_getverdef (verdef_data, 0,
+							&verdef_mem);
+		  while (verdef != NULL)
+		    {
+		      if (verdef->vd_ndx == (*versym & 0x7fff))
+			/* Found the definition.  */
+			break;
+
+		      vd_offset += verdef->vd_next;
+		      verdef = (verdef->vd_next == 0
+				? NULL
+				: gelf_getverdef (verdef_data, vd_offset,
+						  &verdef_mem));
+		    }
+
+		  if (verdef != NULL)
+		    {
+		      GElf_Verdaux verdaux_mem;
+		      GElf_Verdaux *verdaux
+			= gelf_getverdaux (verdef_data,
+					   vd_offset + verdef->vd_aux,
+					   &verdaux_mem);
+
+		      if (verdaux != NULL)
+			printf ((*versym & 0x8000) ? "@%s" : "@@%s",
+				elf_strptr (ebl->elf, verdef_stridx,
+					    verdaux->vda_name));
+		    }
+		}
+	    }
+	}
+
+      putchar_unlocked ('\n');
+    }
+}
+
+
+/* Print version information.  */
+static void
+print_verinfo (Ebl *ebl)
+{
+  /* Find the version information sections.  For this we have to
+     search through the section table.  */
+  Elf_Scn *scn = NULL;
+
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      /* Handle the section if it is part of the versioning handling.  */
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (likely (shdr != NULL))
+	{
+	  if (shdr->sh_type == SHT_GNU_verneed)
+	    handle_verneed (ebl, scn, shdr);
+	  else if (shdr->sh_type == SHT_GNU_verdef)
+	    handle_verdef (ebl, scn, shdr);
+	  else if (shdr->sh_type == SHT_GNU_versym)
+	    handle_versym (ebl, scn, shdr);
+	}
+    }
+}
+
+
+static const char *
+get_ver_flags (unsigned int flags)
+{
+  static char buf[32];
+  char *endp;
+
+  if (flags == 0)
+    return gettext ("none");
+
+  if (flags & VER_FLG_BASE)
+    endp = stpcpy (buf, "BASE ");
+  else
+    endp = buf;
+
+  if (flags & VER_FLG_WEAK)
+    {
+      if (endp != buf)
+	endp = stpcpy (endp, "| ");
+
+      endp = stpcpy (endp, "WEAK ");
+    }
+
+  if (unlikely (flags & ~(VER_FLG_BASE | VER_FLG_WEAK)))
+    {
+      strncpy (endp, gettext ("| <unknown>"), buf + sizeof (buf) - endp);
+      buf[sizeof (buf) - 1] = '\0';
+    }
+
+  return buf;
+}
+
+
+static void
+handle_verneed (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
+{
+  int class = gelf_getclass (ebl->elf);
+
+  /* Get the data of the section.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return;
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  GElf_Shdr glink_mem;
+  GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+				   &glink_mem);
+  if (glink == NULL)
+    error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
+	   elf_ndxscn (scn));
+
+  printf (ngettext ("\
+\nVersion needs section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
+		    "\
+\nVersion needs section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
+		    shdr->sh_info),
+	  (unsigned int) elf_ndxscn (scn),
+	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name), shdr->sh_info,
+	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
+	  shdr->sh_offset,
+	  (unsigned int) shdr->sh_link,
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+
+  unsigned int offset = 0;
+  for (int cnt = shdr->sh_info; --cnt >= 0; )
+    {
+      /* Get the data at the next offset.  */
+      GElf_Verneed needmem;
+      GElf_Verneed *need = gelf_getverneed (data, offset, &needmem);
+      if (unlikely (need == NULL))
+	break;
+
+      printf (gettext ("  %#06x: Version: %hu  File: %s  Cnt: %hu\n"),
+	      offset, (unsigned short int) need->vn_version,
+	      elf_strptr (ebl->elf, shdr->sh_link, need->vn_file),
+	      (unsigned short int) need->vn_cnt);
+
+      unsigned int auxoffset = offset + need->vn_aux;
+      for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
+	{
+	  GElf_Vernaux auxmem;
+	  GElf_Vernaux *aux = gelf_getvernaux (data, auxoffset, &auxmem);
+	  if (unlikely (aux == NULL))
+	    break;
+
+	  printf (gettext ("  %#06x: Name: %s  Flags: %s  Version: %hu\n"),
+		  auxoffset,
+		  elf_strptr (ebl->elf, shdr->sh_link, aux->vna_name),
+		  get_ver_flags (aux->vna_flags),
+		  (unsigned short int) aux->vna_other);
+
+	  if (aux->vna_next == 0)
+	    break;
+
+	  auxoffset += aux->vna_next;
+	}
+
+      /* Find the next offset.  */
+      if (need->vn_next == 0)
+	break;
+
+      offset += need->vn_next;
+    }
+}
+
+
+static void
+handle_verdef (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
+{
+  /* Get the data of the section.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return;
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  GElf_Shdr glink_mem;
+  GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+				   &glink_mem);
+  if (glink == NULL)
+    error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
+	   elf_ndxscn (scn));
+
+  int class = gelf_getclass (ebl->elf);
+  printf (ngettext ("\
+\nVersion definition section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
+		    "\
+\nVersion definition section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
+		    shdr->sh_info),
+	  (unsigned int) elf_ndxscn (scn),
+	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+	  shdr->sh_info,
+	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
+	  shdr->sh_offset,
+	  (unsigned int) shdr->sh_link,
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+
+  unsigned int offset = 0;
+  for (int cnt = shdr->sh_info; --cnt >= 0; )
+    {
+      /* Get the data at the next offset.  */
+      GElf_Verdef defmem;
+      GElf_Verdef *def = gelf_getverdef (data, offset, &defmem);
+      if (unlikely (def == NULL))
+	break;
+
+      unsigned int auxoffset = offset + def->vd_aux;
+      GElf_Verdaux auxmem;
+      GElf_Verdaux *aux = gelf_getverdaux (data, auxoffset, &auxmem);
+      if (unlikely (aux == NULL))
+	break;
+
+      printf (gettext ("\
+  %#06x: Version: %hd  Flags: %s  Index: %hd  Cnt: %hd  Name: %s\n"),
+	      offset, def->vd_version,
+	      get_ver_flags (def->vd_flags),
+	      def->vd_ndx,
+	      def->vd_cnt,
+	      elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
+
+      auxoffset += aux->vda_next;
+      for (int cnt2 = 1; cnt2 < def->vd_cnt; ++cnt2)
+	{
+	  aux = gelf_getverdaux (data, auxoffset, &auxmem);
+	  if (unlikely (aux == NULL))
+	    break;
+
+	  printf (gettext ("  %#06x: Parent %d: %s\n"),
+		  auxoffset, cnt2,
+		  elf_strptr (ebl->elf, shdr->sh_link, aux->vda_name));
+
+	  if (aux->vda_next == 0)
+	    break;
+
+	  auxoffset += aux->vda_next;
+	}
+
+      /* Find the next offset.  */
+      if (def->vd_next == 0)
+	break;
+      offset += def->vd_next;
+    }
+}
+
+
+static void
+handle_versym (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
+{
+  int class = gelf_getclass (ebl->elf);
+  const char **vername;
+  const char **filename;
+
+  /* Get the data of the section.  */
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return;
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  /* We have to find the version definition section and extract the
+     version names.  */
+  Elf_Scn *defscn = NULL;
+  Elf_Scn *needscn = NULL;
+
+  Elf_Scn *verscn = NULL;
+  while ((verscn = elf_nextscn (ebl->elf, verscn)) != NULL)
+    {
+      GElf_Shdr vershdr_mem;
+      GElf_Shdr *vershdr = gelf_getshdr (verscn, &vershdr_mem);
+
+      if (likely (vershdr != NULL))
+	{
+	  if (vershdr->sh_type == SHT_GNU_verdef)
+	    defscn = verscn;
+	  else if (vershdr->sh_type == SHT_GNU_verneed)
+	    needscn = verscn;
+	}
+    }
+
+  size_t nvername;
+  if (defscn != NULL || needscn != NULL)
+    {
+      /* We have a version information (better should have).  Now get
+	 the version names.  First find the maximum version number.  */
+      nvername = 0;
+      if (defscn != NULL)
+	{
+	  /* Run through the version definitions and find the highest
+	     index.  */
+	  unsigned int offset = 0;
+	  Elf_Data *defdata;
+	  GElf_Shdr defshdrmem;
+	  GElf_Shdr *defshdr;
+
+	  defdata = elf_getdata (defscn, NULL);
+	  if (unlikely (defdata == NULL))
+	    return;
+
+	  defshdr = gelf_getshdr (defscn, &defshdrmem);
+	  if (unlikely (defshdr == NULL))
+	    return;
+
+	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
+	    {
+	      GElf_Verdef defmem;
+	      GElf_Verdef *def;
+
+	      /* Get the data at the next offset.  */
+	      def = gelf_getverdef (defdata, offset, &defmem);
+	      if (unlikely (def == NULL))
+		break;
+
+	      nvername = MAX (nvername, (size_t) (def->vd_ndx & 0x7fff));
+
+	      if (def->vd_next == 0)
+		break;
+	      offset += def->vd_next;
+	    }
+	}
+      if (needscn != NULL)
+	{
+	  unsigned int offset = 0;
+	  Elf_Data *needdata;
+	  GElf_Shdr needshdrmem;
+	  GElf_Shdr *needshdr;
+
+	  needdata = elf_getdata (needscn, NULL);
+	  if (unlikely (needdata == NULL))
+	    return;
+
+	  needshdr = gelf_getshdr (needscn, &needshdrmem);
+	  if (unlikely (needshdr == NULL))
+	    return;
+
+	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
+	    {
+	      GElf_Verneed needmem;
+	      GElf_Verneed *need;
+	      unsigned int auxoffset;
+	      int cnt2;
+
+	      /* Get the data at the next offset.  */
+	      need = gelf_getverneed (needdata, offset, &needmem);
+	      if (unlikely (need == NULL))
+		break;
+
+	      /* Run through the auxiliary entries.  */
+	      auxoffset = offset + need->vn_aux;
+	      for (cnt2 = need->vn_cnt; --cnt2 >= 0; )
+		{
+		  GElf_Vernaux auxmem;
+		  GElf_Vernaux *aux;
+
+		  aux = gelf_getvernaux (needdata, auxoffset, &auxmem);
+		  if (unlikely (aux == NULL))
+		    break;
+
+		  nvername = MAX (nvername,
+				  (size_t) (aux->vna_other & 0x7fff));
+
+		  if (aux->vna_next == 0)
+		    break;
+		  auxoffset += aux->vna_next;
+		}
+
+	      if (need->vn_next == 0)
+		break;
+	      offset += need->vn_next;
+	    }
+	}
+
+      /* This is the number of versions we know about.  */
+      ++nvername;
+
+      /* Allocate the array.  */
+      vername = (const char **) alloca (nvername * sizeof (const char *));
+      memset(vername, 0, nvername * sizeof (const char *));
+      filename = (const char **) alloca (nvername * sizeof (const char *));
+      memset(filename, 0, nvername * sizeof (const char *));
+
+      /* Run through the data structures again and collect the strings.  */
+      if (defscn != NULL)
+	{
+	  /* Run through the version definitions and find the highest
+	     index.  */
+	  unsigned int offset = 0;
+	  Elf_Data *defdata;
+	  GElf_Shdr defshdrmem;
+	  GElf_Shdr *defshdr;
+
+	  defdata = elf_getdata (defscn, NULL);
+	  if (unlikely (defdata == NULL))
+	    return;
+
+	  defshdr = gelf_getshdr (defscn, &defshdrmem);
+	  if (unlikely (defshdr == NULL))
+	    return;
+
+	  for (unsigned int cnt = 0; cnt < defshdr->sh_info; ++cnt)
+	    {
+
+	      /* Get the data at the next offset.  */
+	      GElf_Verdef defmem;
+	      GElf_Verdef *def = gelf_getverdef (defdata, offset, &defmem);
+	      if (unlikely (def == NULL))
+		break;
+
+	      GElf_Verdaux auxmem;
+	      GElf_Verdaux *aux = gelf_getverdaux (defdata,
+						   offset + def->vd_aux,
+						   &auxmem);
+	      if (unlikely (aux == NULL))
+		break;
+
+	      vername[def->vd_ndx & 0x7fff]
+		= elf_strptr (ebl->elf, defshdr->sh_link, aux->vda_name);
+	      filename[def->vd_ndx & 0x7fff] = NULL;
+
+	      if (def->vd_next == 0)
+		break;
+	      offset += def->vd_next;
+	    }
+	}
+      if (needscn != NULL)
+	{
+	  unsigned int offset = 0;
+
+	  Elf_Data *needdata = elf_getdata (needscn, NULL);
+	  GElf_Shdr needshdrmem;
+	  GElf_Shdr *needshdr = gelf_getshdr (needscn, &needshdrmem);
+	  if (unlikely (needdata == NULL || needshdr == NULL))
+	    return;
+
+	  for (unsigned int cnt = 0; cnt < needshdr->sh_info; ++cnt)
+	    {
+	      /* Get the data at the next offset.  */
+	      GElf_Verneed needmem;
+	      GElf_Verneed *need = gelf_getverneed (needdata, offset,
+						    &needmem);
+	      if (unlikely (need == NULL))
+		break;
+
+	      /* Run through the auxiliary entries.  */
+	      unsigned int auxoffset = offset + need->vn_aux;
+	      for (int cnt2 = need->vn_cnt; --cnt2 >= 0; )
+		{
+		  GElf_Vernaux auxmem;
+		  GElf_Vernaux *aux = gelf_getvernaux (needdata, auxoffset,
+						       &auxmem);
+		  if (unlikely (aux == NULL))
+		    break;
+
+		  vername[aux->vna_other & 0x7fff]
+		    = elf_strptr (ebl->elf, needshdr->sh_link, aux->vna_name);
+		  filename[aux->vna_other & 0x7fff]
+		    = elf_strptr (ebl->elf, needshdr->sh_link, need->vn_file);
+
+		  if (aux->vna_next == 0)
+		    break;
+		  auxoffset += aux->vna_next;
+		}
+
+	      if (need->vn_next == 0)
+		break;
+	      offset += need->vn_next;
+	    }
+	}
+    }
+  else
+    {
+      vername = NULL;
+      nvername = 1;
+      filename = NULL;
+    }
+
+  GElf_Shdr glink_mem;
+  GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link),
+				   &glink_mem);
+  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_HALF, 1, EV_CURRENT);
+  if (glink == NULL)
+    error (EXIT_FAILURE, 0, gettext ("invalid sh_link value in section %zu"),
+	   elf_ndxscn (scn));
+
+  /* Print the header.  */
+  printf (ngettext ("\
+\nVersion symbols section [%2u] '%s' contains %d entry:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
+		    "\
+\nVersion symbols section [%2u] '%s' contains %d entries:\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'",
+		    shdr->sh_size / sh_entsize),
+	  (unsigned int) elf_ndxscn (scn),
+	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+	  (int) (shdr->sh_size / sh_entsize),
+	  class == ELFCLASS32 ? 10 : 18, shdr->sh_addr,
+	  shdr->sh_offset,
+	  (unsigned int) shdr->sh_link,
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+
+  /* Now we can finally look at the actual contents of this section.  */
+  for (unsigned int cnt = 0; cnt < shdr->sh_size / sh_entsize; ++cnt)
+    {
+      if (cnt % 2 == 0)
+	printf ("\n %4d:", cnt);
+
+      GElf_Versym symmem;
+      GElf_Versym *sym = gelf_getversym (data, cnt, &symmem);
+      if (sym == NULL)
+	break;
+
+      switch (*sym)
+	{
+	  ssize_t n;
+	case 0:
+	  fputs_unlocked (gettext ("   0 *local*                     "),
+			  stdout);
+	  break;
+
+	case 1:
+	  fputs_unlocked (gettext ("   1 *global*                    "),
+			  stdout);
+	  break;
+
+	default:
+	  n = printf ("%4d%c%s",
+		      *sym & 0x7fff, *sym & 0x8000 ? 'h' : ' ',
+		      (vername != NULL
+		       && (unsigned int) (*sym & 0x7fff) < nvername)
+		      ? vername[*sym & 0x7fff] : "???");
+	  if ((unsigned int) (*sym & 0x7fff) < nvername
+	      && filename != NULL && filename[*sym & 0x7fff] != NULL)
+	    n += printf ("(%s)", filename[*sym & 0x7fff]);
+	  printf ("%*s", MAX (0, 33 - (int) n), " ");
+	  break;
+	}
+    }
+  putchar_unlocked ('\n');
+}
+
+
+static void
+print_hash_info (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx,
+		 uint_fast32_t maxlength, Elf32_Word nbucket,
+		 uint_fast32_t nsyms, uint32_t *lengths, const char *extrastr)
+{
+  uint32_t *counts = (uint32_t *) xcalloc (maxlength + 1, sizeof (uint32_t));
+
+  for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
+    ++counts[lengths[cnt]];
+
+  GElf_Shdr glink_mem;
+  GElf_Shdr *glink = gelf_getshdr (elf_getscn (ebl->elf,
+					       shdr->sh_link),
+				   &glink_mem);
+  if (glink == NULL)
+    {
+      error (0, 0, gettext ("invalid sh_link value in section %zu"),
+	     elf_ndxscn (scn));
+      return;
+    }
+
+  printf (ngettext ("\
+\nHistogram for bucket list length in section [%2u] '%s' (total of %d bucket):\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
+		    "\
+\nHistogram for bucket list length in section [%2u] '%s' (total of %d buckets):\n Addr: %#0*" PRIx64 "  Offset: %#08" PRIx64 "  Link to section: [%2u] '%s'\n",
+		    nbucket),
+	  (unsigned int) elf_ndxscn (scn),
+	  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+	  (int) nbucket,
+	  gelf_getclass (ebl->elf) == ELFCLASS32 ? 10 : 18,
+	  shdr->sh_addr,
+	  shdr->sh_offset,
+	  (unsigned int) shdr->sh_link,
+	  elf_strptr (ebl->elf, shstrndx, glink->sh_name));
+
+  if (extrastr != NULL)
+    fputs (extrastr, stdout);
+
+  if (likely (nbucket > 0))
+    {
+      uint64_t success = 0;
+
+      /* xgettext:no-c-format */
+      fputs_unlocked (gettext ("\
+ Length  Number  % of total  Coverage\n"), stdout);
+      printf (gettext ("      0  %6" PRIu32 "      %5.1f%%\n"),
+	      counts[0], (counts[0] * 100.0) / nbucket);
+
+      uint64_t nzero_counts = 0;
+      for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
+	{
+	  nzero_counts += counts[cnt] * cnt;
+	  printf (gettext ("\
+%7d  %6" PRIu32 "      %5.1f%%    %5.1f%%\n"),
+		  (int) cnt, counts[cnt], (counts[cnt] * 100.0) / nbucket,
+		  (nzero_counts * 100.0) / nsyms);
+	}
+
+      Elf32_Word acc = 0;
+      for (Elf32_Word cnt = 1; cnt <= maxlength; ++cnt)
+	{
+	  acc += cnt;
+	  success += counts[cnt] * acc;
+	}
+
+      printf (gettext ("\
+ Average number of tests:   successful lookup: %f\n\
+			  unsuccessful lookup: %f\n"),
+	      (double) success / (double) nzero_counts,
+	      (double) nzero_counts / (double) nbucket);
+    }
+
+  free (counts);
+}
+
+
+/* This function handles the traditional System V-style hash table format.  */
+static void
+handle_sysv_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
+{
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (unlikely (data == NULL))
+    {
+      error (0, 0, gettext ("cannot get data for section %d: %s"),
+	     (int) elf_ndxscn (scn), elf_errmsg (-1));
+      return;
+    }
+
+  if (unlikely (data->d_size < 2 * sizeof (Elf32_Word)))
+    {
+    invalid_data:
+      error (0, 0, gettext ("invalid data in sysv.hash section %d"),
+	     (int) elf_ndxscn (scn));
+      return;
+    }
+
+  Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
+  Elf32_Word nchain = ((Elf32_Word *) data->d_buf)[1];
+
+  uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf32_Word);
+  if (used_buf > data->d_size)
+    goto invalid_data;
+
+  Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[2];
+  Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[2 + nbucket];
+
+  uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
+
+  uint_fast32_t maxlength = 0;
+  uint_fast32_t nsyms = 0;
+  for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
+    {
+      Elf32_Word inner = bucket[cnt];
+      while (inner > 0 && inner < nchain)
+	{
+	  ++nsyms;
+	  if (maxlength < ++lengths[cnt])
+	    ++maxlength;
+
+	  inner = chain[inner];
+	}
+    }
+
+  print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
+		   lengths, NULL);
+
+  free (lengths);
+}
+
+
+/* This function handles the incorrect, System V-style hash table
+   format some 64-bit architectures use.  */
+static void
+handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
+{
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (unlikely (data == NULL))
+    {
+      error (0, 0, gettext ("cannot get data for section %d: %s"),
+	     (int) elf_ndxscn (scn), elf_errmsg (-1));
+      return;
+    }
+
+  if (unlikely (data->d_size < 2 * sizeof (Elf64_Xword)))
+    {
+    invalid_data:
+      error (0, 0, gettext ("invalid data in sysv.hash64 section %d"),
+	     (int) elf_ndxscn (scn));
+      return;
+    }
+
+  Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
+  Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
+
+  uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
+  if (maxwords < 2
+      || maxwords - 2 < nbucket
+      || maxwords - 2 - nbucket < nchain)
+    goto invalid_data;
+
+  Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
+  Elf64_Xword *chain = &((Elf64_Xword *) data->d_buf)[2 + nbucket];
+
+  uint32_t *lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
+
+  uint_fast32_t maxlength = 0;
+  uint_fast32_t nsyms = 0;
+  for (Elf64_Xword cnt = 0; cnt < nbucket; ++cnt)
+    {
+      Elf64_Xword inner = bucket[cnt];
+      while (inner > 0 && inner < nchain)
+	{
+	  ++nsyms;
+	  if (maxlength < ++lengths[cnt])
+	    ++maxlength;
+
+	  inner = chain[inner];
+	}
+    }
+
+  print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
+		   lengths, NULL);
+
+  free (lengths);
+}
+
+
+/* This function handles the GNU-style hash table format.  */
+static void
+handle_gnu_hash (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
+{
+  uint32_t *lengths = NULL;
+  Elf_Data *data = elf_getdata (scn, NULL);
+  if (unlikely (data == NULL))
+    {
+      error (0, 0, gettext ("cannot get data for section %d: %s"),
+	     (int) elf_ndxscn (scn), elf_errmsg (-1));
+      return;
+    }
+
+  if (unlikely (data->d_size < 4 * sizeof (Elf32_Word)))
+    {
+    invalid_data:
+      free (lengths);
+      error (0, 0, gettext ("invalid data in gnu.hash section %d"),
+	     (int) elf_ndxscn (scn));
+      return;
+    }
+
+  Elf32_Word nbucket = ((Elf32_Word *) data->d_buf)[0];
+  Elf32_Word symbias = ((Elf32_Word *) data->d_buf)[1];
+
+  /* Next comes the size of the bitmap.  It's measured in words for
+     the architecture.  It's 32 bits for 32 bit archs, and 64 bits for
+     64 bit archs.  There is always a bloom filter present, so zero is
+     an invalid value.  */
+  Elf32_Word bitmask_words = ((Elf32_Word *) data->d_buf)[2];
+  if (gelf_getclass (ebl->elf) == ELFCLASS64)
+    bitmask_words *= 2;
+
+  if (bitmask_words == 0)
+    goto invalid_data;
+
+  Elf32_Word shift = ((Elf32_Word *) data->d_buf)[3];
+
+  /* Is there still room for the sym chain?
+     Use uint64_t calculation to prevent 32bit overlow.  */
+  uint64_t used_buf = (4ULL + bitmask_words + nbucket) * sizeof (Elf32_Word);
+  uint32_t max_nsyms = (data->d_size - used_buf) / sizeof (Elf32_Word);
+  if (used_buf > data->d_size)
+    goto invalid_data;
+
+  lengths = (uint32_t *) xcalloc (nbucket, sizeof (uint32_t));
+
+  Elf32_Word *bitmask = &((Elf32_Word *) data->d_buf)[4];
+  Elf32_Word *bucket = &((Elf32_Word *) data->d_buf)[4 + bitmask_words];
+  Elf32_Word *chain = &((Elf32_Word *) data->d_buf)[4 + bitmask_words
+						    + nbucket];
+
+  /* Compute distribution of chain lengths.  */
+  uint_fast32_t maxlength = 0;
+  uint_fast32_t nsyms = 0;
+  for (Elf32_Word cnt = 0; cnt < nbucket; ++cnt)
+    if (bucket[cnt] != 0)
+      {
+	Elf32_Word inner = bucket[cnt] - symbias;
+	do
+	  {
+	    ++nsyms;
+	    if (maxlength < ++lengths[cnt])
+	      ++maxlength;
+	    if (inner >= max_nsyms)
+	      goto invalid_data;
+	  }
+	while ((chain[inner++] & 1) == 0);
+      }
+
+  /* Count bits in bitmask.  */
+  uint_fast32_t nbits = 0;
+  for (Elf32_Word cnt = 0; cnt < bitmask_words; ++cnt)
+    {
+      uint_fast32_t word = bitmask[cnt];
+
+      word = (word & 0x55555555) + ((word >> 1) & 0x55555555);
+      word = (word & 0x33333333) + ((word >> 2) & 0x33333333);
+      word = (word & 0x0f0f0f0f) + ((word >> 4) & 0x0f0f0f0f);
+      word = (word & 0x00ff00ff) + ((word >> 8) & 0x00ff00ff);
+      nbits += (word & 0x0000ffff) + ((word >> 16) & 0x0000ffff);
+    }
+
+  char *str;
+  if (unlikely (asprintf (&str, gettext ("\
+ Symbol Bias: %u\n\
+ Bitmask Size: %zu bytes  %" PRIuFAST32 "%% bits set  2nd hash shift: %u\n"),
+			  (unsigned int) symbias,
+			  bitmask_words * sizeof (Elf32_Word),
+			  ((nbits * 100 + 50)
+			   / (uint_fast32_t) (bitmask_words
+					      * sizeof (Elf32_Word) * 8)),
+			  (unsigned int) shift) == -1))
+    error (EXIT_FAILURE, 0, gettext ("memory exhausted"));
+
+  print_hash_info (ebl, scn, shdr, shstrndx, maxlength, nbucket, nsyms,
+		   lengths, str);
+
+  free (str);
+  free (lengths);
+}
+
+
+/* Find the symbol table(s).  For this we have to search through the
+   section table.  */
+static void
+handle_hash (Ebl *ebl)
+{
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      /* Handle the section if it is a symbol table.  */
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (likely (shdr != NULL))
+	{
+	  if ((shdr->sh_type == SHT_HASH || shdr->sh_type == SHT_GNU_HASH)
+	      && (shdr->sh_flags & SHF_COMPRESSED) != 0)
+	    {
+	      if (elf_compress (scn, 0, 0) < 0)
+		printf ("WARNING: %s [%zd]\n",
+			gettext ("Couldn't uncompress section"),
+			elf_ndxscn (scn));
+	      shdr = gelf_getshdr (scn, &shdr_mem);
+	      if (unlikely (shdr == NULL))
+		error (EXIT_FAILURE, 0,
+		       gettext ("cannot get section [%zd] header: %s"),
+		       elf_ndxscn (scn), elf_errmsg (-1));
+	    }
+
+	  if (shdr->sh_type == SHT_HASH)
+	    {
+	      if (ebl_sysvhash_entrysize (ebl) == sizeof (Elf64_Xword))
+		handle_sysv_hash64 (ebl, scn, shdr, shstrndx);
+	      else
+		handle_sysv_hash (ebl, scn, shdr, shstrndx);
+	    }
+	  else if (shdr->sh_type == SHT_GNU_HASH)
+	    handle_gnu_hash (ebl, scn, shdr, shstrndx);
+	}
+    }
+}
+
+
+static void
+print_liblist (Ebl *ebl)
+{
+  /* Find the library list sections.  For this we have to search
+     through the section table.  */
+  Elf_Scn *scn = NULL;
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr != NULL && shdr->sh_type == SHT_GNU_LIBLIST)
+	{
+	  size_t sh_entsize = gelf_fsize (ebl->elf, ELF_T_LIB, 1, EV_CURRENT);
+	  int nentries = shdr->sh_size / sh_entsize;
+	  printf (ngettext ("\
+\nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entry:\n",
+			    "\
+\nLibrary list section [%2zu] '%s' at offset %#0" PRIx64 " contains %d entries:\n",
+			    nentries),
+		  elf_ndxscn (scn),
+		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+		  shdr->sh_offset,
+		  nentries);
+
+	  Elf_Data *data = elf_getdata (scn, NULL);
+	  if (data == NULL)
+	    return;
+
+	  puts (gettext ("\
+       Library                       Time Stamp          Checksum Version Flags"));
+
+	  for (int cnt = 0; cnt < nentries; ++cnt)
+	    {
+	      GElf_Lib lib_mem;
+	      GElf_Lib *lib = gelf_getlib (data, cnt, &lib_mem);
+	      if (unlikely (lib == NULL))
+		continue;
+
+	      time_t t = (time_t) lib->l_time_stamp;
+	      struct tm *tm = gmtime (&t);
+	      if (unlikely (tm == NULL))
+		continue;
+
+	      printf ("  [%2d] %-29s %04u-%02u-%02uT%02u:%02u:%02u %08x %-7u %u\n",
+		      cnt, elf_strptr (ebl->elf, shdr->sh_link, lib->l_name),
+		      tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+		      tm->tm_hour, tm->tm_min, tm->tm_sec,
+		      (unsigned int) lib->l_checksum,
+		      (unsigned int) lib->l_version,
+		      (unsigned int) lib->l_flags);
+	    }
+	}
+    }
+}
+
+static void
+print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
+{
+  /* Find the object attributes sections.  For this we have to search
+     through the section table.  */
+  Elf_Scn *scn = NULL;
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr == NULL || (shdr->sh_type != SHT_GNU_ATTRIBUTES
+			   && (shdr->sh_type != SHT_ARM_ATTRIBUTES
+			       || ehdr->e_machine != EM_ARM)))
+	continue;
+
+      printf (gettext ("\
+\nObject attributes section [%2zu] '%s' of %" PRIu64
+		       " bytes at offset %#0" PRIx64 ":\n"),
+	      elf_ndxscn (scn),
+	      elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+	      shdr->sh_size, shdr->sh_offset);
+
+      Elf_Data *data = elf_rawdata (scn, NULL);
+      if (unlikely (data == NULL || data->d_size == 0))
+	return;
+
+      const unsigned char *p = data->d_buf;
+
+      /* There is only one 'version', A.  */
+      if (unlikely (*p++ != 'A'))
+	return;
+
+      fputs_unlocked (gettext ("  Owner          Size\n"), stdout);
+
+      inline size_t left (void)
+      {
+	return (const unsigned char *) data->d_buf + data->d_size - p;
+      }
+
+      /* Loop over the sections.  */
+      while (left () >= 4)
+	{
+	  /* Section length.  */
+	  uint32_t len;
+	  memcpy (&len, p, sizeof len);
+
+	  if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
+	    CONVERT (len);
+
+	  if (unlikely (len > left ()))
+	    break;
+
+	  /* Section vendor name.  */
+	  const unsigned char *name = p + sizeof len;
+	  p += len;
+
+	  unsigned const char *q = memchr (name, '\0', len);
+	  if (unlikely (q == NULL))
+	    break;
+	  ++q;
+
+	  printf (gettext ("  %-13s  %4" PRIu32 "\n"), name, len);
+
+	  bool gnu_vendor = (q - name == sizeof "gnu"
+			     && !memcmp (name, "gnu", sizeof "gnu"));
+
+	  /* Loop over subsections.  */
+	  if (shdr->sh_type != SHT_GNU_ATTRIBUTES
+	      || gnu_vendor)
+	    while (q < p)
+	      {
+		const unsigned char *const sub = q;
+
+		unsigned int subsection_tag;
+		get_uleb128 (subsection_tag, q, p);
+		if (unlikely (q >= p))
+		  break;
+
+		uint32_t subsection_len;
+		if (unlikely (p - sub < (ptrdiff_t) sizeof subsection_len))
+		  break;
+
+		memcpy (&subsection_len, q, sizeof subsection_len);
+
+		if (MY_ELFDATA != ehdr->e_ident[EI_DATA])
+		  CONVERT (subsection_len);
+
+		/* Don't overflow, ptrdiff_t might be 32bits, but signed.  */
+		if (unlikely (subsection_len == 0
+			      || subsection_len >= (uint32_t) PTRDIFF_MAX
+			      || p - sub < (ptrdiff_t) subsection_len))
+		  break;
+
+		const unsigned char *r = q + sizeof subsection_len;
+		q = sub + subsection_len;
+
+		switch (subsection_tag)
+		  {
+		  default:
+		    /* Unknown subsection, print and skip.  */
+		    printf (gettext ("    %-4u %12" PRIu32 "\n"),
+			    subsection_tag, subsection_len);
+		    break;
+
+		  case 1:	/* Tag_File */
+		    printf (gettext ("    File: %11" PRIu32 "\n"),
+			    subsection_len);
+
+		    while (r < q)
+		      {
+			unsigned int tag;
+			get_uleb128 (tag, r, q);
+			if (unlikely (r >= q))
+			  break;
+
+			/* GNU style tags have either a uleb128 value,
+			   when lowest bit is not set, or a string
+			   when the lowest bit is set.
+			   "compatibility" (32) is special.  It has
+			   both a string and a uleb128 value.  For
+			   non-gnu we assume 6 till 31 only take ints.
+			   XXX see arm backend, do we need a separate
+			   hook?  */
+			uint64_t value = 0;
+			const char *string = NULL;
+			if (tag == 32 || (tag & 1) == 0
+			    || (! gnu_vendor && (tag > 5 && tag < 32)))
+			  {
+			    get_uleb128 (value, r, q);
+			    if (r > q)
+			      break;
+			  }
+			if (tag == 32
+			    || ((tag & 1) != 0
+				&& (gnu_vendor
+				    || (! gnu_vendor && tag > 32)))
+			    || (! gnu_vendor && tag > 3 && tag < 6))
+			  {
+			    string = (const char *) r;
+			    r = memchr (r, '\0', q - r);
+			    if (r == NULL)
+			      break;
+			    ++r;
+			  }
+
+			const char *tag_name = NULL;
+			const char *value_name = NULL;
+			ebl_check_object_attribute (ebl, (const char *) name,
+						    tag, value,
+						    &tag_name, &value_name);
+
+			if (tag_name != NULL)
+			  {
+			    if (tag == 32)
+			      printf (gettext ("      %s: %" PRId64 ", %s\n"),
+				      tag_name, value, string);
+			    else if (string == NULL && value_name == NULL)
+			      printf (gettext ("      %s: %" PRId64 "\n"),
+				      tag_name, value);
+			    else
+			      printf (gettext ("      %s: %s\n"),
+				      tag_name, string ?: value_name);
+			  }
+			else
+			  {
+			    /* For "gnu" vendor 32 "compatibility" has
+			       already been handled above.  */
+			    assert (tag != 32
+				    || strcmp ((const char *) name, "gnu"));
+			    if (string == NULL)
+			      printf (gettext ("      %u: %" PRId64 "\n"),
+				      tag, value);
+			    else
+			      printf (gettext ("      %u: %s\n"),
+				      tag, string);
+			  }
+		      }
+		  }
+	      }
+	}
+    }
+}
+
+
+static char *
+format_dwarf_addr (Dwfl_Module *dwflmod,
+		   int address_size, Dwarf_Addr address, Dwarf_Addr raw)
+{
+  /* See if there is a name we can give for this address.  */
+  GElf_Sym sym;
+  GElf_Off off = 0;
+  const char *name = (print_address_names && ! print_unresolved_addresses)
+    ? dwfl_module_addrinfo (dwflmod, address, &off, &sym, NULL, NULL, NULL)
+    : NULL;
+
+  const char *scn;
+  if (print_unresolved_addresses)
+    {
+      address = raw;
+      scn = NULL;
+    }
+  else
+    {
+      /* Relativize the address.  */
+      int n = dwfl_module_relocations (dwflmod);
+      int i = n < 1 ? -1 : dwfl_module_relocate_address (dwflmod, &address);
+
+      /* In an ET_REL file there is a section name to refer to.  */
+      scn = (i < 0 ? NULL
+	     : dwfl_module_relocation_info (dwflmod, i, NULL));
+    }
+
+  char *result;
+  if ((name != NULL
+       ? (off != 0
+	  ? (scn != NULL
+	     ? (address_size == 0
+		? asprintf (&result,
+			    gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
+			    scn, address, name, off)
+		: asprintf (&result,
+			    gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
+			    scn, 2 + address_size * 2, address,
+			    name, off))
+	     : (address_size == 0
+		? asprintf (&result,
+			    gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
+			    address, name, off)
+		: asprintf (&result,
+			    gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
+			    2 + address_size * 2, address,
+			    name, off)))
+	  : (scn != NULL
+	     ? (address_size == 0
+		? asprintf (&result,
+			    gettext ("%s+%#" PRIx64 " <%s>"),
+			    scn, address, name)
+		: asprintf (&result,
+			    gettext ("%s+%#0*" PRIx64 " <%s>"),
+			    scn, 2 + address_size * 2, address, name))
+	     : (address_size == 0
+		? asprintf (&result,
+			    gettext ("%#" PRIx64 " <%s>"),
+			    address, name)
+		: asprintf (&result,
+			    gettext ("%#0*" PRIx64 " <%s>"),
+			    2 + address_size * 2, address, name))))
+       : (scn != NULL
+	  ? (address_size == 0
+	     ? asprintf (&result,
+			 gettext ("%s+%#" PRIx64),
+			 scn, address)
+	     : asprintf (&result,
+			 gettext ("%s+%#0*" PRIx64),
+			 scn, 2 + address_size * 2, address))
+	  : (address_size == 0
+	     ? asprintf (&result,
+			 "%#" PRIx64,
+			 address)
+	     : asprintf (&result,
+			 "%#0*" PRIx64,
+			 2 + address_size * 2, address)))) < 0)
+    error (EXIT_FAILURE, 0, _("memory exhausted"));
+
+  return result;
+}
+
+static const char *
+dwarf_tag_string (unsigned int tag)
+{
+  switch (tag)
+    {
+#define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_TAG
+#undef DWARF_ONE_KNOWN_DW_TAG
+    default:
+      return NULL;
+    }
+}
+
+
+static const char *
+dwarf_attr_string (unsigned int attrnum)
+{
+  switch (attrnum)
+    {
+#define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_AT
+#undef DWARF_ONE_KNOWN_DW_AT
+    default:
+      return NULL;
+    }
+}
+
+
+static const char *
+dwarf_form_string (unsigned int form)
+{
+  switch (form)
+    {
+#define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_FORM
+#undef DWARF_ONE_KNOWN_DW_FORM
+    default:
+      return NULL;
+    }
+}
+
+
+static const char *
+dwarf_lang_string (unsigned int lang)
+{
+  switch (lang)
+    {
+#define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_LANG
+#undef DWARF_ONE_KNOWN_DW_LANG
+    default:
+      return NULL;
+    }
+}
+
+
+static const char *
+dwarf_inline_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_INL(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_INL
+#undef DWARF_ONE_KNOWN_DW_INL
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+static const char *
+dwarf_encoding_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_ATE
+#undef DWARF_ONE_KNOWN_DW_ATE
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+static const char *
+dwarf_access_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_ACCESS(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_ACCESS
+#undef DWARF_ONE_KNOWN_DW_ACCESS
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+static const char *
+dwarf_defaulted_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_DEFAULTED(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_DEFAULTED
+#undef DWARF_ONE_KNOWN_DW_DEFAULTED
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+static const char *
+dwarf_visibility_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_VIS(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_VIS
+#undef DWARF_ONE_KNOWN_DW_VIS
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+static const char *
+dwarf_virtuality_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_VIRTUALITY(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_VIRTUALITY
+#undef DWARF_ONE_KNOWN_DW_VIRTUALITY
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+static const char *
+dwarf_identifier_case_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_ID(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_ID
+#undef DWARF_ONE_KNOWN_DW_ID
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+static const char *
+dwarf_calling_convention_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_CC(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_CC
+#undef DWARF_ONE_KNOWN_DW_CC
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+static const char *
+dwarf_ordering_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_ORD(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_ORD
+#undef DWARF_ONE_KNOWN_DW_ORD
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+static const char *
+dwarf_discr_list_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_DSC(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_DSC
+#undef DWARF_ONE_KNOWN_DW_DSC
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+static const char *
+dwarf_locexpr_opcode_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+      /* Normally we can't affort building huge table of 64K entries,
+	 most of them zero, just because there are a couple defined
+	 values at the far end.  In case of opcodes, it's OK.  */
+#define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_OP
+#undef DWARF_ONE_KNOWN_DW_OP
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+/* Used by all dwarf_foo_name functions.  */
+static const char *
+string_or_unknown (const char *known, unsigned int code,
+                   unsigned int lo_user, unsigned int hi_user,
+		   bool print_unknown_num)
+{
+  static char unknown_buf[20];
+
+  if (likely (known != NULL))
+    return known;
+
+  if (lo_user != 0 && code >= lo_user && code <= hi_user)
+    {
+      snprintf (unknown_buf, sizeof unknown_buf, "lo_user+%#x",
+		code - lo_user);
+      return unknown_buf;
+    }
+
+  if (print_unknown_num)
+    {
+      snprintf (unknown_buf, sizeof unknown_buf, "??? (%#x)", code);
+      return unknown_buf;
+    }
+
+  return "???";
+}
+
+
+static const char *
+dwarf_tag_name (unsigned int tag)
+{
+  const char *ret = dwarf_tag_string (tag);
+  return string_or_unknown (ret, tag, DW_TAG_lo_user, DW_TAG_hi_user, true);
+}
+
+static const char *
+dwarf_attr_name (unsigned int attr)
+{
+  const char *ret = dwarf_attr_string (attr);
+  return string_or_unknown (ret, attr, DW_AT_lo_user, DW_AT_hi_user, true);
+}
+
+
+static const char *
+dwarf_form_name (unsigned int form)
+{
+  const char *ret = dwarf_form_string (form);
+  return string_or_unknown (ret, form, 0, 0, true);
+}
+
+
+static const char *
+dwarf_lang_name (unsigned int lang)
+{
+  const char *ret = dwarf_lang_string (lang);
+  return string_or_unknown (ret, lang, DW_LANG_lo_user, DW_LANG_hi_user, false);
+}
+
+
+static const char *
+dwarf_inline_name (unsigned int code)
+{
+  const char *ret = dwarf_inline_string (code);
+  return string_or_unknown (ret, code, 0, 0, false);
+}
+
+
+static const char *
+dwarf_encoding_name (unsigned int code)
+{
+  const char *ret = dwarf_encoding_string (code);
+  return string_or_unknown (ret, code, DW_ATE_lo_user, DW_ATE_hi_user, false);
+}
+
+
+static const char *
+dwarf_access_name (unsigned int code)
+{
+  const char *ret = dwarf_access_string (code);
+  return string_or_unknown (ret, code, 0, 0, false);
+}
+
+
+static const char *
+dwarf_defaulted_name (unsigned int code)
+{
+  const char *ret = dwarf_defaulted_string (code);
+  return string_or_unknown (ret, code, 0, 0, false);
+}
+
+
+static const char *
+dwarf_visibility_name (unsigned int code)
+{
+  const char *ret = dwarf_visibility_string (code);
+  return string_or_unknown (ret, code, 0, 0, false);
+}
+
+
+static const char *
+dwarf_virtuality_name (unsigned int code)
+{
+  const char *ret = dwarf_virtuality_string (code);
+  return string_or_unknown (ret, code, 0, 0, false);
+}
+
+
+static const char *
+dwarf_identifier_case_name (unsigned int code)
+{
+  const char *ret = dwarf_identifier_case_string (code);
+  return string_or_unknown (ret, code, 0, 0, false);
+}
+
+
+static const char *
+dwarf_calling_convention_name (unsigned int code)
+{
+  const char *ret = dwarf_calling_convention_string (code);
+  return string_or_unknown (ret, code, DW_CC_lo_user, DW_CC_hi_user, false);
+}
+
+
+static const char *
+dwarf_ordering_name (unsigned int code)
+{
+  const char *ret = dwarf_ordering_string (code);
+  return string_or_unknown (ret, code, 0, 0, false);
+}
+
+
+static const char *
+dwarf_discr_list_name (unsigned int code)
+{
+  const char *ret = dwarf_discr_list_string (code);
+  return string_or_unknown (ret, code, 0, 0, false);
+}
+
+
+static void
+print_block (size_t n, const void *block)
+{
+  if (n == 0)
+    puts (_("empty block"));
+  else
+    {
+      printf (_("%zu byte block:"), n);
+      const unsigned char *data = block;
+      do
+	printf (" %02x", *data++);
+      while (--n > 0);
+      putchar ('\n');
+    }
+}
+
+static void
+print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
+	   unsigned int vers, unsigned int addrsize, unsigned int offset_size,
+	   struct Dwarf_CU *cu, Dwarf_Word len, const unsigned char *data)
+{
+  const unsigned int ref_size = vers < 3 ? addrsize : offset_size;
+
+  if (len == 0)
+    {
+      printf ("%*s(empty)\n", indent, "");
+      return;
+    }
+
+#define NEED(n)		if (len < (Dwarf_Word) (n)) goto invalid
+#define CONSUME(n)	NEED (n); else len -= (n)
+
+  Dwarf_Word offset = 0;
+  while (len-- > 0)
+    {
+      uint_fast8_t op = *data++;
+
+      const char *op_name = dwarf_locexpr_opcode_string (op);
+      if (unlikely (op_name == NULL))
+	{
+	  static char buf[20];
+	  if (op >= DW_OP_lo_user)
+	    snprintf (buf, sizeof buf, "lo_user+%#x", op - DW_OP_lo_user);
+	  else
+	    snprintf (buf, sizeof buf, "??? (%#x)", op);
+	  op_name = buf;
+	}
+
+      switch (op)
+	{
+	case DW_OP_addr:;
+	  /* Address operand.  */
+	  Dwarf_Word addr;
+	  NEED (addrsize);
+	  if (addrsize == 4)
+	    addr = read_4ubyte_unaligned (dbg, data);
+	  else if (addrsize == 8)
+	    addr = read_8ubyte_unaligned (dbg, data);
+	  else
+	    goto invalid;
+	  data += addrsize;
+	  CONSUME (addrsize);
+
+	  char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
+	  printf ("%*s[%2" PRIuMAX "] %s %s\n",
+		  indent, "", (uintmax_t) offset, op_name, a);
+	  free (a);
+
+	  offset += 1 + addrsize;
+	  break;
+
+	case DW_OP_call_ref:
+	case DW_OP_GNU_variable_value:
+	  /* Offset operand.  */
+	  if (ref_size != 4 && ref_size != 8)
+	    goto invalid; /* Cannot be used in CFA.  */
+	  NEED (ref_size);
+	  if (ref_size == 4)
+	    addr = read_4ubyte_unaligned (dbg, data);
+	  else
+	    addr = read_8ubyte_unaligned (dbg, data);
+	  data += ref_size;
+	  CONSUME (ref_size);
+	  /* addr is a DIE offset, so format it as one.  */
+	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
+		  indent, "", (uintmax_t) offset,
+		  op_name, (uintmax_t) addr);
+	  offset += 1 + ref_size;
+	  break;
+
+	case DW_OP_deref_size:
+	case DW_OP_xderef_size:
+	case DW_OP_pick:
+	case DW_OP_const1u:
+	  // XXX value might be modified by relocation
+	  NEED (1);
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 "\n",
+		  indent, "", (uintmax_t) offset,
+		  op_name, *((uint8_t *) data));
+	  ++data;
+	  --len;
+	  offset += 2;
+	  break;
+
+	case DW_OP_const2u:
+	  NEED (2);
+	  // XXX value might be modified by relocation
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu16 "\n",
+		  indent, "", (uintmax_t) offset,
+		  op_name, read_2ubyte_unaligned (dbg, data));
+	  CONSUME (2);
+	  data += 2;
+	  offset += 3;
+	  break;
+
+	case DW_OP_const4u:
+	  NEED (4);
+	  // XXX value might be modified by relocation
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu32 "\n",
+		  indent, "", (uintmax_t) offset,
+		  op_name, read_4ubyte_unaligned (dbg, data));
+	  CONSUME (4);
+	  data += 4;
+	  offset += 5;
+	  break;
+
+	case DW_OP_const8u:
+	  NEED (8);
+	  // XXX value might be modified by relocation
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
+		  indent, "", (uintmax_t) offset,
+		  op_name, (uint64_t) read_8ubyte_unaligned (dbg, data));
+	  CONSUME (8);
+	  data += 8;
+	  offset += 9;
+	  break;
+
+	case DW_OP_const1s:
+	  NEED (1);
+	  // XXX value might be modified by relocation
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRId8 "\n",
+		  indent, "", (uintmax_t) offset,
+		  op_name, *((int8_t *) data));
+	  ++data;
+	  --len;
+	  offset += 2;
+	  break;
+
+	case DW_OP_const2s:
+	  NEED (2);
+	  // XXX value might be modified by relocation
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRId16 "\n",
+		  indent, "", (uintmax_t) offset,
+		  op_name, read_2sbyte_unaligned (dbg, data));
+	  CONSUME (2);
+	  data += 2;
+	  offset += 3;
+	  break;
+
+	case DW_OP_const4s:
+	  NEED (4);
+	  // XXX value might be modified by relocation
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRId32 "\n",
+		  indent, "", (uintmax_t) offset,
+		  op_name, read_4sbyte_unaligned (dbg, data));
+	  CONSUME (4);
+	  data += 4;
+	  offset += 5;
+	  break;
+
+	case DW_OP_const8s:
+	  NEED (8);
+	  // XXX value might be modified by relocation
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
+		  indent, "", (uintmax_t) offset,
+		  op_name, read_8sbyte_unaligned (dbg, data));
+	  CONSUME (8);
+	  data += 8;
+	  offset += 9;
+	  break;
+
+	case DW_OP_piece:
+	case DW_OP_regx:
+	case DW_OP_plus_uconst:
+	case DW_OP_constu:;
+	  const unsigned char *start = data;
+	  uint64_t uleb;
+	  NEED (1);
+	  get_uleb128 (uleb, data, data + len);
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 "\n",
+		  indent, "", (uintmax_t) offset, op_name, uleb);
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
+	case DW_OP_bit_piece:
+	  start = data;
+	  uint64_t uleb2;
+	  NEED (1);
+	  get_uleb128 (uleb, data, data + len);
+	  NEED (1);
+	  get_uleb128 (uleb2, data, data + len);
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 ", %" PRIu64 "\n",
+		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
+	case DW_OP_fbreg:
+	case DW_OP_breg0 ... DW_OP_breg31:
+	case DW_OP_consts:
+	  start = data;
+	  int64_t sleb;
+	  NEED (1);
+	  get_sleb128 (sleb, data, data + len);
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRId64 "\n",
+		  indent, "", (uintmax_t) offset, op_name, sleb);
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
+	case DW_OP_bregx:
+	  start = data;
+	  NEED (1);
+	  get_uleb128 (uleb, data, data + len);
+	  NEED (1);
+	  get_sleb128 (sleb, data, data + len);
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " %" PRId64 "\n",
+		  indent, "", (uintmax_t) offset, op_name, uleb, sleb);
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
+	case DW_OP_call2:
+	  NEED (2);
+	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx16 "]\n",
+		  indent, "", (uintmax_t) offset, op_name,
+		  read_2ubyte_unaligned (dbg, data));
+	  CONSUME (2);
+	  data += 2;
+	  offset += 3;
+	  break;
+
+	case DW_OP_call4:
+	  NEED (4);
+	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIx32 "]\n",
+		  indent, "", (uintmax_t) offset, op_name,
+		  read_4ubyte_unaligned (dbg, data));
+	  CONSUME (4);
+	  data += 4;
+	  offset += 5;
+	  break;
+
+	case DW_OP_skip:
+	case DW_OP_bra:
+	  NEED (2);
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIuMAX "\n",
+		  indent, "", (uintmax_t) offset, op_name,
+		  (uintmax_t) (offset + read_2sbyte_unaligned (dbg, data) + 3));
+	  CONSUME (2);
+	  data += 2;
+	  offset += 3;
+	  break;
+
+	case DW_OP_implicit_value:
+	  start = data;
+	  NEED (1);
+	  get_uleb128 (uleb, data, data + len);
+	  printf ("%*s[%2" PRIuMAX "] %s: ",
+		  indent, "", (uintmax_t) offset, op_name);
+	  NEED (uleb);
+	  print_block (uleb, data);
+	  data += uleb;
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
+	case DW_OP_GNU_implicit_pointer:
+	  /* DIE offset operand.  */
+	  start = data;
+	  NEED (ref_size);
+	  if (ref_size != 4 && ref_size != 8)
+	    goto invalid; /* Cannot be used in CFA.  */
+	  if (ref_size == 4)
+	    addr = read_4ubyte_unaligned (dbg, data);
+	  else
+	    addr = read_8ubyte_unaligned (dbg, data);
+	  data += ref_size;
+	  /* Byte offset operand.  */
+	  NEED (1);
+	  get_sleb128 (sleb, data, data + len);
+
+	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] %+" PRId64 "\n",
+		  indent, "", (intmax_t) offset,
+		  op_name, (uintmax_t) addr, sleb);
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
+	case DW_OP_GNU_entry_value:
+	  /* Size plus expression block.  */
+	  start = data;
+	  NEED (1);
+	  get_uleb128 (uleb, data, data + len);
+	  printf ("%*s[%2" PRIuMAX "] %s:\n",
+		  indent, "", (uintmax_t) offset, op_name);
+	  NEED (uleb);
+	  print_ops (dwflmod, dbg, indent + 5, indent + 5, vers,
+		     addrsize, offset_size, cu, uleb, data);
+	  data += uleb;
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
+	case DW_OP_GNU_const_type:
+	  /* uleb128 CU relative DW_TAG_base_type DIE offset, 1-byte
+	     unsigned size plus block.  */
+	  start = data;
+	  NEED (1);
+	  get_uleb128 (uleb, data, data + len);
+	  if (! print_unresolved_addresses && cu != NULL)
+	    uleb += cu->start;
+	  NEED (1);
+	  uint8_t usize = *(uint8_t *) data++;
+	  NEED (usize);
+	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "] ",
+		  indent, "", (uintmax_t) offset, op_name, uleb);
+	  print_block (usize, data);
+	  data += usize;
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
+	case DW_OP_GNU_regval_type:
+	  /* uleb128 register number, uleb128 CU relative
+	     DW_TAG_base_type DIE offset.  */
+	  start = data;
+	  NEED (1);
+	  get_uleb128 (uleb, data, data + len);
+	  NEED (1);
+	  get_uleb128 (uleb2, data, data + len);
+	  if (! print_unresolved_addresses && cu != NULL)
+	    uleb2 += cu->start;
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu64 " [%6" PRIx64 "]\n",
+		  indent, "", (uintmax_t) offset, op_name, uleb, uleb2);
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
+	case DW_OP_GNU_deref_type:
+	  /* 1-byte unsigned size of value, uleb128 CU relative
+	     DW_TAG_base_type DIE offset.  */
+	  start = data;
+	  NEED (1);
+	  usize = *(uint8_t *) data++;
+	  NEED (1);
+	  get_uleb128 (uleb, data, data + len);
+	  if (! print_unresolved_addresses && cu != NULL)
+	    uleb += cu->start;
+	  printf ("%*s[%2" PRIuMAX "] %s %" PRIu8 " [%6" PRIxMAX "]\n",
+		  indent, "", (uintmax_t) offset,
+		  op_name, usize, uleb);
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
+	case DW_OP_GNU_convert:
+	case DW_OP_GNU_reinterpret:
+	  /* uleb128 CU relative offset to DW_TAG_base_type, or zero
+	     for conversion to untyped.  */
+	  start = data;
+	  NEED (1);
+	  get_uleb128 (uleb, data, data + len);
+	  if (uleb != 0 && ! print_unresolved_addresses && cu != NULL)
+	    uleb += cu->start;
+	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
+		  indent, "", (uintmax_t) offset, op_name, uleb);
+	  CONSUME (data - start);
+	  offset += 1 + (data - start);
+	  break;
+
+	case DW_OP_GNU_parameter_ref:
+	  /* 4 byte CU relative reference to the abstract optimized away
+	     DW_TAG_formal_parameter.  */
+	  NEED (4);
+	  uintmax_t param_off = (uintmax_t) read_4ubyte_unaligned (dbg, data);
+	  if (! print_unresolved_addresses && cu != NULL)
+	    param_off += cu->start;
+	  printf ("%*s[%2" PRIuMAX "] %s [%6" PRIxMAX "]\n",
+		  indent, "", (uintmax_t) offset, op_name, param_off);
+	  CONSUME (4);
+	  data += 4;
+	  offset += 5;
+	  break;
+
+	default:
+	  /* No Operand.  */
+	  printf ("%*s[%2" PRIuMAX "] %s\n",
+		  indent, "", (uintmax_t) offset, op_name);
+	  ++offset;
+	  break;
+	}
+
+      indent = indentrest;
+      continue;
+
+    invalid:
+      printf (gettext ("%*s[%2" PRIuMAX "] %s  <TRUNCATED>\n"),
+	      indent, "", (uintmax_t) offset, op_name);
+      break;
+    }
+}
+
+
+struct listptr
+{
+  Dwarf_Off offset:(64 - 3);
+  bool addr64:1;
+  bool dwarf64:1;
+  bool warned:1;
+  struct Dwarf_CU *cu;
+};
+
+#define listptr_offset_size(p)	((p)->dwarf64 ? 8 : 4)
+#define listptr_address_size(p)	((p)->addr64 ? 8 : 4)
+
+static Dwarf_Addr
+listptr_base (struct listptr *p)
+{
+  Dwarf_Addr base;
+  Dwarf_Die cu = CUDIE (p->cu);
+  /* Find the base address of the compilation unit.  It will normally
+     be specified by DW_AT_low_pc.  In DWARF-3 draft 4, the base
+     address could be overridden by DW_AT_entry_pc.  It's been
+     removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc for
+     compilation units with discontinuous ranges.  */
+  if (unlikely (dwarf_lowpc (&cu, &base) != 0))
+    {
+      Dwarf_Attribute attr_mem;
+      if (dwarf_formaddr (dwarf_attr (&cu, DW_AT_entry_pc, &attr_mem),
+			  &base) != 0)
+	base = 0;
+    }
+  return base;
+}
+
+static int
+compare_listptr (const void *a, const void *b, void *arg)
+{
+  const char *name = arg;
+  struct listptr *p1 = (void *) a;
+  struct listptr *p2 = (void *) b;
+
+  if (p1->offset < p2->offset)
+    return -1;
+  if (p1->offset > p2->offset)
+    return 1;
+
+  if (!p1->warned && !p2->warned)
+    {
+      if (p1->addr64 != p2->addr64)
+	{
+	  p1->warned = p2->warned = true;
+	  error (0, 0,
+		 gettext ("%s %#" PRIx64 " used with different address sizes"),
+		 name, (uint64_t) p1->offset);
+	}
+      if (p1->dwarf64 != p2->dwarf64)
+	{
+	  p1->warned = p2->warned = true;
+	  error (0, 0,
+		 gettext ("%s %#" PRIx64 " used with different offset sizes"),
+		 name, (uint64_t) p1->offset);
+	}
+      if (listptr_base (p1) != listptr_base (p2))
+	{
+	  p1->warned = p2->warned = true;
+	  error (0, 0,
+		 gettext ("%s %#" PRIx64 " used with different base addresses"),
+		 name, (uint64_t) p1->offset);
+	}
+    }
+
+  return 0;
+}
+
+struct listptr_table
+{
+  size_t n;
+  size_t alloc;
+  struct listptr *table;
+};
+
+static struct listptr_table known_loclistptr;
+static struct listptr_table known_rangelistptr;
+
+static void
+reset_listptr (struct listptr_table *table)
+{
+  free (table->table);
+  table->table = NULL;
+  table->n = table->alloc = 0;
+}
+
+/* Returns false if offset doesn't fit.  See struct listptr.  */
+static bool
+notice_listptr (enum section_e section, struct listptr_table *table,
+		uint_fast8_t address_size, uint_fast8_t offset_size,
+		struct Dwarf_CU *cu, Dwarf_Off offset)
+{
+  if (print_debug_sections & section)
+    {
+      if (table->n == table->alloc)
+	{
+	  if (table->alloc == 0)
+	    table->alloc = 128;
+	  else
+	    table->alloc *= 2;
+	  table->table = xrealloc (table->table,
+				   table->alloc * sizeof table->table[0]);
+	}
+
+      struct listptr *p = &table->table[table->n++];
+
+      *p = (struct listptr)
+	{
+	  .addr64 = address_size == 8,
+	  .dwarf64 = offset_size == 8,
+	  .offset = offset,
+	  .cu = cu
+	};
+
+      if (p->offset != offset)
+	{
+	  table->n--;
+	  return false;
+	}
+    }
+  return true;
+}
+
+static void
+sort_listptr (struct listptr_table *table, const char *name)
+{
+  if (table->n > 0)
+    qsort_r (table->table, table->n, sizeof table->table[0],
+	     &compare_listptr, (void *) name);
+}
+
+static bool
+skip_listptr_hole (struct listptr_table *table, size_t *idxp,
+		   uint_fast8_t *address_sizep, uint_fast8_t *offset_sizep,
+		   Dwarf_Addr *base, struct Dwarf_CU **cu, ptrdiff_t offset,
+		   unsigned char **readp, unsigned char *endp)
+{
+  if (table->n == 0)
+    return false;
+
+  while (*idxp < table->n && table->table[*idxp].offset < (Dwarf_Off) offset)
+    ++*idxp;
+
+  struct listptr *p = &table->table[*idxp];
+
+  if (*idxp == table->n
+      || p->offset >= (Dwarf_Off) (endp - *readp + offset))
+    {
+      *readp = endp;
+      printf (gettext (" [%6tx]  <UNUSED GARBAGE IN REST OF SECTION>\n"),
+	      offset);
+      return true;
+    }
+
+  if (p->offset != (Dwarf_Off) offset)
+    {
+      *readp += p->offset - offset;
+      printf (gettext (" [%6tx]  <UNUSED GARBAGE> ... %" PRIu64 " bytes ...\n"),
+	      offset, (Dwarf_Off) p->offset - offset);
+      return true;
+    }
+
+  if (address_sizep != NULL)
+    *address_sizep = listptr_address_size (p);
+  if (offset_sizep != NULL)
+    *offset_sizep = listptr_offset_size (p);
+  if (base != NULL)
+    *base = listptr_base (p);
+  if (cu != NULL)
+    *cu = p->cu;
+
+  return false;
+}
+
+
+static void
+print_debug_abbrev_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
+			    Ebl *ebl, GElf_Ehdr *ehdr,
+			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  const size_t sh_size = (dbg->sectiondata[IDX_debug_abbrev] ?
+			  dbg->sectiondata[IDX_debug_abbrev]->d_size : 0);
+
+  printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
+		   " [ Code]\n"),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset);
+
+  Dwarf_Off offset = 0;
+  while (offset < sh_size)
+    {
+      printf (gettext ("\nAbbreviation section at offset %" PRIu64 ":\n"),
+	      offset);
+
+      while (1)
+	{
+	  size_t length;
+	  Dwarf_Abbrev abbrev;
+
+	  int res = dwarf_offabbrev (dbg, offset, &length, &abbrev);
+	  if (res != 0)
+	    {
+	      if (unlikely (res < 0))
+		{
+		  printf (gettext ("\
+ *** error while reading abbreviation: %s\n"),
+			  dwarf_errmsg (-1));
+		  return;
+		}
+
+	      /* This is the NUL byte at the end of the section.  */
+	      ++offset;
+	      break;
+	    }
+
+	  /* We know these calls can never fail.  */
+	  unsigned int code = dwarf_getabbrevcode (&abbrev);
+	  unsigned int tag = dwarf_getabbrevtag (&abbrev);
+	  int has_children = dwarf_abbrevhaschildren (&abbrev);
+
+	  printf (gettext (" [%5u] offset: %" PRId64
+			   ", children: %s, tag: %s\n"),
+		  code, (int64_t) offset,
+		  has_children ? gettext ("yes") : gettext ("no"),
+		  dwarf_tag_name (tag));
+
+	  size_t cnt = 0;
+	  unsigned int name;
+	  unsigned int form;
+	  Dwarf_Off enoffset;
+	  while (dwarf_getabbrevattr (&abbrev, cnt,
+				      &name, &form, &enoffset) == 0)
+	    {
+	      printf ("          attr: %s, form: %s, offset: %#" PRIx64 "\n",
+		      dwarf_attr_name (name), dwarf_form_name (form),
+		      (uint64_t) enoffset);
+
+	      ++cnt;
+	    }
+
+	  offset += length;
+	}
+    }
+}
+
+
+/* Print content of DWARF .debug_aranges section.  We fortunately do
+   not have to know a bit about the structure of the section, libdwarf
+   takes care of it.  */
+static void
+print_decoded_aranges_section (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
+			       GElf_Shdr *shdr, Dwarf *dbg)
+{
+  Dwarf_Aranges *aranges;
+  size_t cnt;
+  if (unlikely (dwarf_getaranges (dbg, &aranges, &cnt) != 0))
+    {
+      error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
+	     dwarf_errmsg (-1));
+      return;
+    }
+
+  GElf_Shdr glink_mem;
+  GElf_Shdr *glink;
+  glink = gelf_getshdr (elf_getscn (ebl->elf, shdr->sh_link), &glink_mem);
+  if (glink == NULL)
+    {
+      error (0, 0, gettext ("invalid sh_link value in section %zu"),
+	     elf_ndxscn (scn));
+      return;
+    }
+
+  printf (ngettext ("\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entry:\n",
+		    "\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 " contains %zu entries:\n",
+		    cnt),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset, cnt);
+
+  /* Compute floor(log16(cnt)).  */
+  size_t tmp = cnt;
+  int digits = 1;
+  while (tmp >= 16)
+    {
+      ++digits;
+      tmp >>= 4;
+    }
+
+  for (size_t n = 0; n < cnt; ++n)
+    {
+      Dwarf_Arange *runp = dwarf_onearange (aranges, n);
+      if (unlikely (runp == NULL))
+	{
+	  printf ("cannot get arange %zu: %s\n", n, dwarf_errmsg (-1));
+	  return;
+	}
+
+      Dwarf_Addr start;
+      Dwarf_Word length;
+      Dwarf_Off offset;
+
+      if (unlikely (dwarf_getarangeinfo (runp, &start, &length, &offset) != 0))
+	printf (gettext (" [%*zu] ???\n"), digits, n);
+      else
+	printf (gettext (" [%*zu] start: %0#*" PRIx64
+			 ", length: %5" PRIu64 ", CU DIE offset: %6"
+			 PRId64 "\n"),
+		digits, n, ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 10 : 18,
+		(uint64_t) start, (uint64_t) length, (int64_t) offset);
+    }
+}
+
+
+/* Print content of DWARF .debug_aranges section.  */
+static void
+print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
+			     Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn,
+			     GElf_Shdr *shdr, Dwarf *dbg)
+{
+  if (decodedaranges)
+    {
+      print_decoded_aranges_section (ebl, ehdr, scn, shdr, dbg);
+      return;
+    }
+
+  Elf_Data *data = dbg->sectiondata[IDX_debug_aranges];
+
+  if (unlikely (data == NULL))
+    {
+      error (0, 0, gettext ("cannot get .debug_aranges content: %s"),
+	     elf_errmsg (-1));
+      return;
+    }
+
+  printf (gettext ("\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset);
+
+  const unsigned char *readp = data->d_buf;
+  const unsigned char *readendp = readp + data->d_size;
+
+  while (readp < readendp)
+    {
+      const unsigned char *hdrstart = readp;
+      size_t start_offset = hdrstart - (const unsigned char *) data->d_buf;
+
+      printf (gettext ("\nTable at offset %zu:\n"), start_offset);
+      if (readp + 4 > readendp)
+	{
+	invalid_data:
+	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
+		 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
+	  return;
+	}
+
+      Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp);
+      unsigned int length_bytes = 4;
+      if (length == DWARF3_LENGTH_64_BIT)
+	{
+	  if (readp + 8 > readendp)
+	    goto invalid_data;
+	  length = read_8ubyte_unaligned_inc (dbg, readp);
+	  length_bytes = 8;
+	}
+
+      const unsigned char *nexthdr = readp + length;
+      printf (gettext ("\n Length:        %6" PRIu64 "\n"),
+	      (uint64_t) length);
+
+      if (unlikely (length > (size_t) (readendp - readp)))
+	goto invalid_data;
+
+      if (length == 0)
+	continue;
+
+      if (readp + 2 > readendp)
+	goto invalid_data;
+      uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, readp);
+      printf (gettext (" DWARF version: %6" PRIuFAST16 "\n"),
+	      version);
+      if (version != 2)
+	{
+	  error (0, 0, gettext ("unsupported aranges version"));
+	  goto next_table;
+	}
+
+      Dwarf_Word offset;
+      if (readp + length_bytes > readendp)
+	goto invalid_data;
+      if (length_bytes == 8)
+	offset = read_8ubyte_unaligned_inc (dbg, readp);
+      else
+	offset = read_4ubyte_unaligned_inc (dbg, readp);
+      printf (gettext (" CU offset:     %6" PRIx64 "\n"),
+	      (uint64_t) offset);
+
+      if (readp + 1 > readendp)
+	goto invalid_data;
+      unsigned int address_size = *readp++;
+      printf (gettext (" Address size:  %6" PRIu64 "\n"),
+	      (uint64_t) address_size);
+      if (address_size != 4 && address_size != 8)
+	{
+	  error (0, 0, gettext ("unsupported address size"));
+	  goto next_table;
+	}
+
+      unsigned int segment_size = *readp++;
+      printf (gettext (" Segment size:  %6" PRIu64 "\n\n"),
+	      (uint64_t) segment_size);
+      if (segment_size != 0 && segment_size != 4 && segment_size != 8)
+	{
+	  error (0, 0, gettext ("unsupported segment size"));
+	  goto next_table;
+	}
+
+      /* Round the address to the next multiple of 2*address_size.  */
+      readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
+		% (2 * address_size));
+
+      while (readp < nexthdr)
+	{
+	  Dwarf_Word range_address;
+	  Dwarf_Word range_length;
+	  Dwarf_Word segment = 0;
+	  if (readp + 2 * address_size + segment_size > readendp)
+	    goto invalid_data;
+	  if (address_size == 4)
+	    {
+	      range_address = read_4ubyte_unaligned_inc (dbg, readp);
+	      range_length = read_4ubyte_unaligned_inc (dbg, readp);
+	    }
+	  else
+	    {
+	      range_address = read_8ubyte_unaligned_inc (dbg, readp);
+	      range_length = read_8ubyte_unaligned_inc (dbg, readp);
+	    }
+
+	  if (segment_size == 4)
+	    segment = read_4ubyte_unaligned_inc (dbg, readp);
+	  else if (segment_size == 8)
+	    segment = read_8ubyte_unaligned_inc (dbg, readp);
+
+	  if (range_address == 0 && range_length == 0 && segment == 0)
+	    break;
+
+	  char *b = format_dwarf_addr (dwflmod, address_size, range_address,
+				       range_address);
+	  char *e = format_dwarf_addr (dwflmod, address_size,
+				       range_address + range_length - 1,
+				       range_length);
+	  if (segment_size != 0)
+	    printf (gettext ("   %s..%s (%" PRIx64 ")\n"), b, e,
+		    (uint64_t) segment);
+	  else
+	    printf (gettext ("   %s..%s\n"), b, e);
+	  free (b);
+	  free (e);
+	}
+
+    next_table:
+      if (readp != nexthdr)
+	{
+	  size_t padding = nexthdr - readp;
+	  printf (gettext ("   %zu padding bytes\n"), padding);
+	  readp = nexthdr;
+	}
+    }
+}
+
+
+/* Print content of DWARF .debug_ranges section.  */
+static void
+print_debug_ranges_section (Dwfl_Module *dwflmod,
+			    Ebl *ebl, GElf_Ehdr *ehdr,
+			    Elf_Scn *scn, GElf_Shdr *shdr,
+			    Dwarf *dbg)
+{
+  Elf_Data *data = dbg->sectiondata[IDX_debug_ranges];
+
+  if (unlikely (data == NULL))
+    {
+      error (0, 0, gettext ("cannot get .debug_ranges content: %s"),
+	     elf_errmsg (-1));
+      return;
+    }
+
+  printf (gettext ("\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset);
+
+  sort_listptr (&known_rangelistptr, "rangelistptr");
+  size_t listptr_idx = 0;
+
+  uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+
+  bool first = true;
+  Dwarf_Addr base = 0;
+  unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
+  unsigned char *readp = data->d_buf;
+  Dwarf_CU *last_cu = NULL;
+  while (readp < endp)
+    {
+      ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
+      Dwarf_CU *cu = last_cu;
+
+      if (first && skip_listptr_hole (&known_rangelistptr, &listptr_idx,
+				      &address_size, NULL, &base, &cu,
+				      offset, &readp, endp))
+	continue;
+
+      if (last_cu != cu)
+	{
+	  char *basestr = format_dwarf_addr (dwflmod, address_size,
+					     base, base);
+	  Dwarf_Die cudie;
+	  if (dwarf_cu_die (cu, &cudie,
+			    NULL, NULL, NULL, NULL,
+			    NULL, NULL) == NULL)
+	    printf (gettext ("\n Unknown CU base: %s\n"), basestr);
+	  else
+	    printf (gettext ("\n CU [%6" PRIx64 "] base: %s\n"),
+		    dwarf_dieoffset (&cudie), basestr);
+	  free (basestr);
+	}
+      last_cu = cu;
+
+      if (unlikely (data->d_size - offset < (size_t) address_size * 2))
+	{
+	  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
+	  break;
+	}
+
+      Dwarf_Addr begin;
+      Dwarf_Addr end;
+      if (address_size == 8)
+	{
+	  begin = read_8ubyte_unaligned_inc (dbg, readp);
+	  end = read_8ubyte_unaligned_inc (dbg, readp);
+	}
+      else
+	{
+	  begin = read_4ubyte_unaligned_inc (dbg, readp);
+	  end = read_4ubyte_unaligned_inc (dbg, readp);
+	  if (begin == (Dwarf_Addr) (uint32_t) -1)
+	    begin = (Dwarf_Addr) -1l;
+	}
+
+      if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
+	{
+	  char *b = format_dwarf_addr (dwflmod, address_size, end, end);
+	  printf (gettext (" [%6tx] base address\n          %s\n"), offset, b);
+	  free (b);
+	  base = end;
+	}
+      else if (begin == 0 && end == 0) /* End of list entry.  */
+	{
+	  if (first)
+	    printf (gettext (" [%6tx] empty list\n"), offset);
+	  first = true;
+	}
+      else
+	{
+	  /* We have an address range entry.  */
+	  if (first)		/* First address range entry in a list.  */
+	    printf (" [%6tx] ", offset);
+	  else
+	    printf ("          ");
+
+	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
+	  if (! print_unresolved_addresses)
+	    {
+	      char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
+					   base + begin);
+	      char *e = format_dwarf_addr (dwflmod, address_size,
+					   base + end - 1, base + end);
+	      printf ("          %s..\n", b);
+	      printf ("          %s\n", e);
+	      free (b);
+	      free (e);
+	    }
+
+	  first = false;
+	}
+    }
+}
+
+#define REGNAMESZ 16
+static const char *
+register_info (Ebl *ebl, unsigned int regno, const Ebl_Register_Location *loc,
+	       char name[REGNAMESZ], int *bits, int *type)
+{
+  const char *set;
+  const char *pfx;
+  int ignore;
+  ssize_t n = ebl_register_info (ebl, regno, name, REGNAMESZ, &pfx, &set,
+				 bits ?: &ignore, type ?: &ignore);
+  if (n <= 0)
+    {
+      if (loc != NULL)
+	snprintf (name, REGNAMESZ, "reg%u", loc->regno);
+      else
+	snprintf (name, REGNAMESZ, "??? 0x%x", regno);
+      if (bits != NULL)
+	*bits = loc != NULL ? loc->bits : 0;
+      if (type != NULL)
+	*type = DW_ATE_unsigned;
+      set = "??? unrecognized";
+    }
+  else
+    {
+      if (bits != NULL && *bits <= 0)
+	*bits = loc != NULL ? loc->bits : 0;
+      if (type != NULL && *type == DW_ATE_void)
+	*type = DW_ATE_unsigned;
+
+    }
+  return set;
+}
+
+static const unsigned char *
+read_encoded (unsigned int encoding, const unsigned char *readp,
+	      const unsigned char *const endp, uint64_t *res, Dwarf *dbg)
+{
+  if ((encoding & 0xf) == DW_EH_PE_absptr)
+    encoding = gelf_getclass (dbg->elf) == ELFCLASS32
+      ? DW_EH_PE_udata4 : DW_EH_PE_udata8;
+
+  switch (encoding & 0xf)
+    {
+    case DW_EH_PE_uleb128:
+      get_uleb128 (*res, readp, endp);
+      break;
+    case DW_EH_PE_sleb128:
+      get_sleb128 (*res, readp, endp);
+      break;
+    case DW_EH_PE_udata2:
+      if (readp + 2 > endp)
+	goto invalid;
+      *res = read_2ubyte_unaligned_inc (dbg, readp);
+      break;
+    case DW_EH_PE_udata4:
+      if (readp + 4 > endp)
+	goto invalid;
+      *res = read_4ubyte_unaligned_inc (dbg, readp);
+      break;
+    case DW_EH_PE_udata8:
+      if (readp + 8 > endp)
+	goto invalid;
+      *res = read_8ubyte_unaligned_inc (dbg, readp);
+      break;
+    case DW_EH_PE_sdata2:
+      if (readp + 2 > endp)
+	goto invalid;
+      *res = read_2sbyte_unaligned_inc (dbg, readp);
+      break;
+    case DW_EH_PE_sdata4:
+      if (readp + 4 > endp)
+	goto invalid;
+      *res = read_4sbyte_unaligned_inc (dbg, readp);
+      break;
+    case DW_EH_PE_sdata8:
+      if (readp + 8 > endp)
+	goto invalid;
+      *res = read_8sbyte_unaligned_inc (dbg, readp);
+      break;
+    default:
+    invalid:
+      error (1, 0,
+	     gettext ("invalid encoding"));
+    }
+
+  return readp;
+}
+
+
+static void
+print_cfa_program (const unsigned char *readp, const unsigned char *const endp,
+		   Dwarf_Word vma_base, unsigned int code_align,
+		   int data_align,
+		   unsigned int version, unsigned int ptr_size,
+		   unsigned int encoding,
+		   Dwfl_Module *dwflmod, Ebl *ebl, Dwarf *dbg)
+{
+  char regnamebuf[REGNAMESZ];
+  const char *regname (unsigned int regno)
+  {
+    register_info (ebl, regno, NULL, regnamebuf, NULL, NULL);
+    return regnamebuf;
+  }
+
+  puts ("\n   Program:");
+  Dwarf_Word pc = vma_base;
+  while (readp < endp)
+    {
+      unsigned int opcode = *readp++;
+
+      if (opcode < DW_CFA_advance_loc)
+	/* Extended opcode.  */
+	switch (opcode)
+	  {
+	    uint64_t op1;
+	    int64_t sop1;
+	    uint64_t op2;
+	    int64_t sop2;
+
+	  case DW_CFA_nop:
+	    puts ("     nop");
+	    break;
+	  case DW_CFA_set_loc:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    readp = read_encoded (encoding, readp, endp, &op1, dbg);
+	    printf ("     set_loc %#" PRIx64 " to %#" PRIx64 "\n",
+		    op1, pc = vma_base + op1);
+	    break;
+	  case DW_CFA_advance_loc1:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    printf ("     advance_loc1 %u to %#" PRIx64 "\n",
+		    *readp, pc += *readp * code_align);
+	    ++readp;
+	    break;
+	  case DW_CFA_advance_loc2:
+	    if ((uint64_t) (endp - readp) < 2)
+	      goto invalid;
+	    op1 = read_2ubyte_unaligned_inc (dbg, readp);
+	    printf ("     advance_loc2 %" PRIu64 " to %#" PRIx64 "\n",
+		    op1, pc += op1 * code_align);
+	    break;
+	  case DW_CFA_advance_loc4:
+	    if ((uint64_t) (endp - readp) < 4)
+	      goto invalid;
+	    op1 = read_4ubyte_unaligned_inc (dbg, readp);
+	    printf ("     advance_loc4 %" PRIu64 " to %#" PRIx64 "\n",
+		    op1, pc += op1 * code_align);
+	    break;
+	  case DW_CFA_offset_extended:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op2, readp, endp);
+	    printf ("     offset_extended r%" PRIu64 " (%s) at cfa%+" PRId64
+		    "\n",
+		    op1, regname (op1), op2 * data_align);
+	    break;
+	  case DW_CFA_restore_extended:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    printf ("     restore_extended r%" PRIu64 " (%s)\n",
+		    op1, regname (op1));
+	    break;
+	  case DW_CFA_undefined:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    printf ("     undefined r%" PRIu64 " (%s)\n", op1, regname (op1));
+	    break;
+	  case DW_CFA_same_value:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    printf ("     same_value r%" PRIu64 " (%s)\n", op1, regname (op1));
+	    break;
+	  case DW_CFA_register:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op2, readp, endp);
+	    printf ("     register r%" PRIu64 " (%s) in r%" PRIu64 " (%s)\n",
+		    op1, regname (op1), op2, regname (op2));
+	    break;
+	  case DW_CFA_remember_state:
+	    puts ("     remember_state");
+	    break;
+	  case DW_CFA_restore_state:
+	    puts ("     restore_state");
+	    break;
+	  case DW_CFA_def_cfa:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op2, readp, endp);
+	    printf ("     def_cfa r%" PRIu64 " (%s) at offset %" PRIu64 "\n",
+		    op1, regname (op1), op2);
+	    break;
+	  case DW_CFA_def_cfa_register:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    printf ("     def_cfa_register r%" PRIu64 " (%s)\n",
+		    op1, regname (op1));
+	    break;
+	  case DW_CFA_def_cfa_offset:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    printf ("     def_cfa_offset %" PRIu64 "\n", op1);
+	    break;
+	  case DW_CFA_def_cfa_expression:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);	/* Length of DW_FORM_block.  */
+	    printf ("     def_cfa_expression %" PRIu64 "\n", op1);
+	    if ((uint64_t) (endp - readp) < op1)
+	      {
+	    invalid:
+	        fputs (gettext ("         <INVALID DATA>\n"), stdout);
+		return;
+	      }
+	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
+		       op1, readp);
+	    readp += op1;
+	    break;
+	  case DW_CFA_expression:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
+	    printf ("     expression r%" PRIu64 " (%s) \n",
+		    op1, regname (op1));
+	    if ((uint64_t) (endp - readp) < op2)
+	      goto invalid;
+	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0, NULL,
+		       op2, readp);
+	    readp += op2;
+	    break;
+	  case DW_CFA_offset_extended_sf:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_sleb128 (sop2, readp, endp);
+	    printf ("     offset_extended_sf r%" PRIu64 " (%s) at cfa%+"
+		    PRId64 "\n",
+		    op1, regname (op1), sop2 * data_align);
+	    break;
+	  case DW_CFA_def_cfa_sf:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_sleb128 (sop2, readp, endp);
+	    printf ("     def_cfa_sf r%" PRIu64 " (%s) at offset %" PRId64 "\n",
+		    op1, regname (op1), sop2 * data_align);
+	    break;
+	  case DW_CFA_def_cfa_offset_sf:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_sleb128 (sop1, readp, endp);
+	    printf ("     def_cfa_offset_sf %" PRId64 "\n", sop1 * data_align);
+	    break;
+	  case DW_CFA_val_offset:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op2, readp, endp);
+	    printf ("     val_offset %" PRIu64 " at offset %" PRIu64 "\n",
+		    op1, op2 * data_align);
+	    break;
+	  case DW_CFA_val_offset_sf:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_sleb128 (sop2, readp, endp);
+	    printf ("     val_offset_sf %" PRIu64 " at offset %" PRId64 "\n",
+		    op1, sop2 * data_align);
+	    break;
+	  case DW_CFA_val_expression:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op2, readp, endp);	/* Length of DW_FORM_block.  */
+	    printf ("     val_expression r%" PRIu64 " (%s)\n",
+		    op1, regname (op1));
+	    if ((uint64_t) (endp - readp) < op2)
+	      goto invalid;
+	    print_ops (dwflmod, dbg, 10, 10, version, ptr_size, 0,
+		       NULL, op2, readp);
+	    readp += op2;
+	    break;
+	  case DW_CFA_MIPS_advance_loc8:
+	    if ((uint64_t) (endp - readp) < 8)
+	      goto invalid;
+	    op1 = read_8ubyte_unaligned_inc (dbg, readp);
+	    printf ("     MIPS_advance_loc8 %" PRIu64 " to %#" PRIx64 "\n",
+		    op1, pc += op1 * code_align);
+	    break;
+	  case DW_CFA_GNU_window_save:
+	    puts ("     GNU_window_save");
+	    break;
+	  case DW_CFA_GNU_args_size:
+	    if ((uint64_t) (endp - readp) < 1)
+	      goto invalid;
+	    get_uleb128 (op1, readp, endp);
+	    printf ("     args_size %" PRIu64 "\n", op1);
+	    break;
+	  default:
+	    printf ("     ??? (%u)\n", opcode);
+	    break;
+	  }
+      else if (opcode < DW_CFA_offset)
+	printf ("     advance_loc %u to %#" PRIx64 "\n",
+		opcode & 0x3f, pc += (opcode & 0x3f) * code_align);
+      else if (opcode < DW_CFA_restore)
+	{
+	  uint64_t offset;
+	  if ((uint64_t) (endp - readp) < 1)
+	    goto invalid;
+	  get_uleb128 (offset, readp, endp);
+	  printf ("     offset r%u (%s) at cfa%+" PRId64 "\n",
+		  opcode & 0x3f, regname (opcode & 0x3f), offset * data_align);
+	}
+      else
+	printf ("     restore r%u (%s)\n",
+		opcode & 0x3f, regname (opcode & 0x3f));
+    }
+}
+
+
+static unsigned int
+encoded_ptr_size (int encoding, unsigned int ptr_size)
+{
+  switch (encoding & 7)
+    {
+    case DW_EH_PE_udata4:
+      return 4;
+    case DW_EH_PE_udata8:
+      return 8;
+    case 0:
+      return ptr_size;
+    }
+
+  fprintf (stderr, "Unsupported pointer encoding: %#x, "
+	   "assuming pointer size of %d.\n", encoding, ptr_size);
+  return ptr_size;
+}
+
+
+static unsigned int
+print_encoding (unsigned int val)
+{
+  switch (val & 0xf)
+    {
+    case DW_EH_PE_absptr:
+      fputs ("absptr", stdout);
+      break;
+    case DW_EH_PE_uleb128:
+      fputs ("uleb128", stdout);
+      break;
+    case DW_EH_PE_udata2:
+      fputs ("udata2", stdout);
+      break;
+    case DW_EH_PE_udata4:
+      fputs ("udata4", stdout);
+      break;
+    case DW_EH_PE_udata8:
+      fputs ("udata8", stdout);
+      break;
+    case DW_EH_PE_sleb128:
+      fputs ("sleb128", stdout);
+      break;
+    case DW_EH_PE_sdata2:
+      fputs ("sdata2", stdout);
+      break;
+    case DW_EH_PE_sdata4:
+      fputs ("sdata4", stdout);
+      break;
+    case DW_EH_PE_sdata8:
+      fputs ("sdata8", stdout);
+      break;
+    default:
+      /* We did not use any of the bits after all.  */
+      return val;
+    }
+
+  return val & ~0xf;
+}
+
+
+static unsigned int
+print_relinfo (unsigned int val)
+{
+  switch (val & 0x70)
+    {
+    case DW_EH_PE_pcrel:
+      fputs ("pcrel", stdout);
+      break;
+    case DW_EH_PE_textrel:
+      fputs ("textrel", stdout);
+      break;
+    case DW_EH_PE_datarel:
+      fputs ("datarel", stdout);
+      break;
+    case DW_EH_PE_funcrel:
+      fputs ("funcrel", stdout);
+      break;
+    case DW_EH_PE_aligned:
+      fputs ("aligned", stdout);
+      break;
+    default:
+      return val;
+    }
+
+  return val & ~0x70;
+}
+
+
+static void
+print_encoding_base (const char *pfx, unsigned int fde_encoding)
+{
+  printf ("(%s", pfx);
+
+  if (fde_encoding == DW_EH_PE_omit)
+    puts ("omit)");
+  else
+    {
+      unsigned int w = fde_encoding;
+
+      w = print_encoding (w);
+
+      if (w & 0x70)
+	{
+	  if (w != fde_encoding)
+	    fputc_unlocked (' ', stdout);
+
+	  w = print_relinfo (w);
+	}
+
+      if (w != 0)
+	printf ("%s%x", w != fde_encoding ? " " : "", w);
+
+      puts (")");
+    }
+}
+
+
+static void
+print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
+			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  size_t shstrndx;
+  /* We know this call will succeed since it did in the caller.  */
+  (void) elf_getshdrstrndx (ebl->elf, &shstrndx);
+  const char *scnname = elf_strptr (ebl->elf, shstrndx, shdr->sh_name);
+
+  /* Needed if we find PC-relative addresses.  */
+  GElf_Addr bias;
+  if (dwfl_module_getelf (dwflmod, &bias) == NULL)
+    {
+      error (0, 0, gettext ("cannot get ELF: %s"), dwfl_errmsg (-1));
+      return;
+    }
+
+  bool is_eh_frame = strcmp (scnname, ".eh_frame") == 0;
+  Elf_Data *data = (is_eh_frame
+		    ? elf_rawdata (scn, NULL)
+		    : dbg->sectiondata[IDX_debug_frame]);
+
+  if (unlikely (data == NULL))
+    {
+      error (0, 0, gettext ("cannot get %s content: %s"),
+	     scnname, elf_errmsg (-1));
+      return;
+    }
+
+  if (is_eh_frame)
+    printf (gettext ("\
+\nCall frame information section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
+	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
+  else
+    printf (gettext ("\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
+	    elf_ndxscn (scn), scnname, (uint64_t) shdr->sh_offset);
+
+  struct cieinfo
+  {
+    ptrdiff_t cie_offset;
+    const char *augmentation;
+    unsigned int code_alignment_factor;
+    unsigned int data_alignment_factor;
+    uint8_t address_size;
+    uint8_t fde_encoding;
+    uint8_t lsda_encoding;
+    struct cieinfo *next;
+  } *cies = NULL;
+
+  const unsigned char *readp = data->d_buf;
+  const unsigned char *const dataend = ((unsigned char *) data->d_buf
+					+ data->d_size);
+  while (readp < dataend)
+    {
+      if (unlikely (readp + 4 > dataend))
+	{
+	invalid_data:
+	  error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
+		     elf_ndxscn (scn), scnname);
+	      return;
+	}
+
+      /* At the beginning there must be a CIE.  There can be multiple,
+	 hence we test tis in a loop.  */
+      ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
+
+      Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, readp);
+      unsigned int length = 4;
+      if (unlikely (unit_length == 0xffffffff))
+	{
+	  if (unlikely (readp + 8 > dataend))
+	    goto invalid_data;
+
+	  unit_length = read_8ubyte_unaligned_inc (dbg, readp);
+	  length = 8;
+	}
+
+      if (unlikely (unit_length == 0))
+	{
+	  printf (gettext ("\n [%6tx] Zero terminator\n"), offset);
+	  continue;
+	}
+
+      Dwarf_Word maxsize = dataend - readp;
+      if (unlikely (unit_length > maxsize))
+	goto invalid_data;
+
+      unsigned int ptr_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+
+      ptrdiff_t start = readp - (unsigned char *) data->d_buf;
+      const unsigned char *const cieend = readp + unit_length;
+      if (unlikely (cieend > dataend || readp + 8 > dataend))
+	goto invalid_data;
+
+      Dwarf_Off cie_id;
+      if (length == 4)
+	{
+	  cie_id = read_4ubyte_unaligned_inc (dbg, readp);
+	  if (!is_eh_frame && cie_id == DW_CIE_ID_32)
+	    cie_id = DW_CIE_ID_64;
+	}
+      else
+	cie_id = read_8ubyte_unaligned_inc (dbg, readp);
+
+      uint_fast8_t version = 2;
+      unsigned int code_alignment_factor;
+      int data_alignment_factor;
+      unsigned int fde_encoding = 0;
+      unsigned int lsda_encoding = 0;
+      Dwarf_Word initial_location = 0;
+      Dwarf_Word vma_base = 0;
+
+      if (cie_id == (is_eh_frame ? 0 : DW_CIE_ID_64))
+	{
+	  version = *readp++;
+	  const char *const augmentation = (const char *) readp;
+	  readp = memchr (readp, '\0', cieend - readp);
+	  if (unlikely (readp == NULL))
+	    goto invalid_data;
+	  ++readp;
+
+	  uint_fast8_t segment_size = 0;
+	  if (version >= 4)
+	    {
+	      if (cieend - readp < 5)
+		goto invalid_data;
+	      ptr_size = *readp++;
+	      segment_size = *readp++;
+	    }
+
+	  if (cieend - readp < 1)
+	    goto invalid_data;
+	  get_uleb128 (code_alignment_factor, readp, cieend);
+	  if (cieend - readp < 1)
+	    goto invalid_data;
+	  get_sleb128 (data_alignment_factor, readp, cieend);
+
+	  /* In some variant for unwind data there is another field.  */
+	  if (strcmp (augmentation, "eh") == 0)
+	    readp += ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+
+	  unsigned int return_address_register;
+	  if (cieend - readp < 1)
+	    goto invalid_data;
+	  if (unlikely (version == 1))
+	    return_address_register = *readp++;
+	  else
+	    get_uleb128 (return_address_register, readp, cieend);
+
+	  printf ("\n [%6tx] CIE length=%" PRIu64 "\n"
+		  "   CIE_id:                   %" PRIu64 "\n"
+		  "   version:                  %u\n"
+		  "   augmentation:             \"%s\"\n",
+		  offset, (uint64_t) unit_length, (uint64_t) cie_id,
+		  version, augmentation);
+	  if (version >= 4)
+	    printf ("   address_size:             %u\n"
+		    "   segment_size:             %u\n",
+		    ptr_size, segment_size);
+	  printf ("   code_alignment_factor:    %u\n"
+		  "   data_alignment_factor:    %d\n"
+		  "   return_address_register:  %u\n",
+		  code_alignment_factor,
+		  data_alignment_factor, return_address_register);
+
+	  if (augmentation[0] == 'z')
+	    {
+	      unsigned int augmentationlen;
+	      get_uleb128 (augmentationlen, readp, cieend);
+
+	      if (augmentationlen > (size_t) (cieend - readp))
+		{
+		  error (0, 0, gettext ("invalid augmentation length"));
+		  readp = cieend;
+		  continue;
+		}
+
+	      const char *hdr = "Augmentation data:";
+	      const char *cp = augmentation + 1;
+	      while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
+		{
+		  printf ("   %-26s%#x ", hdr, *readp);
+		  hdr = "";
+
+		  if (*cp == 'R')
+		    {
+		      fde_encoding = *readp++;
+		      print_encoding_base (gettext ("FDE address encoding: "),
+					   fde_encoding);
+		    }
+		  else if (*cp == 'L')
+		    {
+		      lsda_encoding = *readp++;
+		      print_encoding_base (gettext ("LSDA pointer encoding: "),
+					   lsda_encoding);
+		    }
+		  else if (*cp == 'P')
+		    {
+		      /* Personality.  This field usually has a relocation
+			 attached pointing to __gcc_personality_v0.  */
+		      const unsigned char *startp = readp;
+		      unsigned int encoding = *readp++;
+		      uint64_t val = 0;
+		      readp = read_encoded (encoding, readp,
+					    readp - 1 + augmentationlen,
+					    &val, dbg);
+
+		      while (++startp < readp)
+			printf ("%#x ", *startp);
+
+		      putchar ('(');
+		      print_encoding (encoding);
+		      putchar (' ');
+		      switch (encoding & 0xf)
+			{
+			case DW_EH_PE_sleb128:
+			case DW_EH_PE_sdata2:
+			case DW_EH_PE_sdata4:
+			  printf ("%" PRId64 ")\n", val);
+			  break;
+			default:
+			  printf ("%#" PRIx64 ")\n", val);
+			  break;
+			}
+		    }
+		  else
+		    printf ("(%x)\n", *readp++);
+
+		  ++cp;
+		}
+	    }
+
+	  if (likely (ptr_size == 4 || ptr_size == 8))
+	    {
+	      struct cieinfo *newp = alloca (sizeof (*newp));
+	      newp->cie_offset = offset;
+	      newp->augmentation = augmentation;
+	      newp->fde_encoding = fde_encoding;
+	      newp->lsda_encoding = lsda_encoding;
+	      newp->address_size = ptr_size;
+	      newp->code_alignment_factor = code_alignment_factor;
+	      newp->data_alignment_factor = data_alignment_factor;
+	      newp->next = cies;
+	      cies = newp;
+	    }
+	}
+      else
+	{
+	  struct cieinfo *cie = cies;
+	  while (cie != NULL)
+	    if (is_eh_frame
+		? ((Dwarf_Off) start - cie_id) == (Dwarf_Off) cie->cie_offset
+		: cie_id == (Dwarf_Off) cie->cie_offset)
+	      break;
+	    else
+	      cie = cie->next;
+	  if (unlikely (cie == NULL))
+	    {
+	      puts ("invalid CIE reference in FDE");
+	      return;
+	    }
+
+	  /* Initialize from CIE data.  */
+	  fde_encoding = cie->fde_encoding;
+	  lsda_encoding = cie->lsda_encoding;
+	  ptr_size = encoded_ptr_size (fde_encoding, cie->address_size);
+	  code_alignment_factor = cie->code_alignment_factor;
+	  data_alignment_factor = cie->data_alignment_factor;
+
+	  const unsigned char *base = readp;
+	  // XXX There are sometimes relocations for this value
+	  initial_location = read_addr_unaligned_inc (ptr_size, dbg, readp);
+	  Dwarf_Word address_range
+	    = read_addr_unaligned_inc (ptr_size, dbg, readp);
+
+	  /* pcrel for an FDE address is relative to the runtime
+	     address of the start_address field itself.  Sign extend
+	     if necessary to make sure the calculation is done on the
+	     full 64 bit address even when initial_location only holds
+	     the lower 32 bits.  */
+	  Dwarf_Addr pc_start = initial_location;
+	  if (ptr_size == 4)
+	    pc_start = (uint64_t) (int32_t) pc_start;
+	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
+	    pc_start += ((uint64_t) shdr->sh_addr
+			 + (base - (const unsigned char *) data->d_buf)
+			 - bias);
+
+	  char *a = format_dwarf_addr (dwflmod, cie->address_size,
+				       pc_start, initial_location);
+	  printf ("\n [%6tx] FDE length=%" PRIu64 " cie=[%6tx]\n"
+		  "   CIE_pointer:              %" PRIu64 "\n"
+		  "   initial_location:         %s",
+		  offset, (uint64_t) unit_length,
+		  cie->cie_offset, (uint64_t) cie_id, a);
+	  free (a);
+	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
+	    {
+	      vma_base = (((uint64_t) shdr->sh_offset
+			   + (base - (const unsigned char *) data->d_buf)
+			   + (uint64_t) initial_location)
+			  & (ptr_size == 4
+			     ? UINT64_C (0xffffffff)
+			     : UINT64_C (0xffffffffffffffff)));
+	      printf (gettext (" (offset: %#" PRIx64 ")"),
+		      (uint64_t) vma_base);
+	    }
+
+	  printf ("\n   address_range:            %#" PRIx64,
+		  (uint64_t) address_range);
+	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
+	    printf (gettext (" (end offset: %#" PRIx64 ")"),
+		    ((uint64_t) vma_base + (uint64_t) address_range)
+		    & (ptr_size == 4
+		       ? UINT64_C (0xffffffff)
+		       : UINT64_C (0xffffffffffffffff)));
+	  putchar ('\n');
+
+	  if (cie->augmentation[0] == 'z')
+	    {
+	      unsigned int augmentationlen;
+	      if (cieend - readp < 1)
+		goto invalid_data;
+	      get_uleb128 (augmentationlen, readp, cieend);
+
+	      if (augmentationlen > (size_t) (cieend - readp))
+		{
+		  error (0, 0, gettext ("invalid augmentation length"));
+		  readp = cieend;
+		  continue;
+		}
+
+	      if (augmentationlen > 0)
+		{
+		  const char *hdr = "Augmentation data:";
+		  const char *cp = cie->augmentation + 1;
+		  unsigned int u = 0;
+		  while (*cp != '\0'
+			 && cp < cie->augmentation + augmentationlen + 1)
+		    {
+		      if (*cp == 'L')
+			{
+			  uint64_t lsda_pointer;
+			  const unsigned char *p
+			    = read_encoded (lsda_encoding, &readp[u],
+					    &readp[augmentationlen],
+					    &lsda_pointer, dbg);
+			  u = p - readp;
+			  printf (gettext ("\
+   %-26sLSDA pointer: %#" PRIx64 "\n"),
+				  hdr, lsda_pointer);
+			  hdr = "";
+			}
+		      ++cp;
+		    }
+
+		  while (u < augmentationlen)
+		    {
+		      printf ("   %-26s%#x\n", hdr, readp[u++]);
+		      hdr = "";
+		    }
+		}
+
+	      readp += augmentationlen;
+	    }
+	}
+
+      /* Handle the initialization instructions.  */
+      if (ptr_size != 4 && ptr_size !=8)
+	printf ("invalid CIE pointer size (%u), must be 4 or 8.\n", ptr_size);
+      else
+	print_cfa_program (readp, cieend, vma_base, code_alignment_factor,
+			   data_alignment_factor, version, ptr_size,
+			   fde_encoding, dwflmod, ebl, dbg);
+      readp = cieend;
+    }
+}
+
+
+struct attrcb_args
+{
+  Dwfl_Module *dwflmod;
+  Dwarf *dbg;
+  Dwarf_Die *die;
+  int level;
+  bool silent;
+  unsigned int version;
+  unsigned int addrsize;
+  unsigned int offset_size;
+  struct Dwarf_CU *cu;
+};
+
+
+static int
+attr_callback (Dwarf_Attribute *attrp, void *arg)
+{
+  struct attrcb_args *cbargs = (struct attrcb_args *) arg;
+  const int level = cbargs->level;
+  Dwarf_Die *die = cbargs->die;
+
+  unsigned int attr = dwarf_whatattr (attrp);
+  if (unlikely (attr == 0))
+    {
+      if (!cbargs->silent)
+	error (0, 0, gettext ("DIE [%" PRIx64 "] "
+			      "cannot get attribute code: %s"),
+	       dwarf_dieoffset (die), dwarf_errmsg (-1));
+      return DWARF_CB_ABORT;
+    }
+
+  unsigned int form = dwarf_whatform (attrp);
+  if (unlikely (form == 0))
+    {
+      if (!cbargs->silent)
+	error (0, 0, gettext ("DIE [%" PRIx64 "] "
+			      "cannot get attribute form: %s"),
+	       dwarf_dieoffset (die), dwarf_errmsg (-1));
+      return DWARF_CB_ABORT;
+    }
+
+  switch (form)
+    {
+    case DW_FORM_addr:
+      if (!cbargs->silent)
+	{
+	  Dwarf_Addr addr;
+	  if (unlikely (dwarf_formaddr (attrp, &addr) != 0))
+	    {
+	    attrval_out:
+	      if (!cbargs->silent)
+		error (0, 0, gettext ("DIE [%" PRIx64 "] "
+				      "cannot get attribute '%s' (%s) value: "
+				      "%s"),
+		       dwarf_dieoffset (die),
+		       dwarf_attr_name (attr),
+		       dwarf_form_name (form),
+		       dwarf_errmsg (-1));
+	      /* Don't ABORT, it might be other attributes can be resolved.  */
+	      return DWARF_CB_OK;
+	    }
+	  char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
+				       addr, addr);
+	  printf ("           %*s%-20s (%s) %s\n",
+		  (int) (level * 2), "", dwarf_attr_name (attr),
+		  dwarf_form_name (form), a);
+	  free (a);
+	}
+      break;
+
+    case DW_FORM_indirect:
+    case DW_FORM_strp:
+    case DW_FORM_string:
+    case DW_FORM_GNU_strp_alt:
+      if (cbargs->silent)
+	break;
+      const char *str = dwarf_formstring (attrp);
+      if (unlikely (str == NULL))
+	goto attrval_out;
+      printf ("           %*s%-20s (%s) \"%s\"\n",
+	      (int) (level * 2), "", dwarf_attr_name (attr),
+	      dwarf_form_name (form), str);
+      break;
+
+    case DW_FORM_ref_addr:
+    case DW_FORM_ref_udata:
+    case DW_FORM_ref8:
+    case DW_FORM_ref4:
+    case DW_FORM_ref2:
+    case DW_FORM_ref1:
+    case DW_FORM_GNU_ref_alt:
+      if (cbargs->silent)
+	break;
+      Dwarf_Die ref;
+      if (unlikely (dwarf_formref_die (attrp, &ref) == NULL))
+	goto attrval_out;
+
+      printf ("           %*s%-20s (%s) [%6" PRIxMAX "]\n",
+	      (int) (level * 2), "", dwarf_attr_name (attr),
+	      dwarf_form_name (form), (uintmax_t) dwarf_dieoffset (&ref));
+      break;
+
+    case DW_FORM_ref_sig8:
+      if (cbargs->silent)
+	break;
+      printf ("           %*s%-20s (%s) {%6" PRIx64 "}\n",
+	      (int) (level * 2), "", dwarf_attr_name (attr),
+	      dwarf_form_name (form),
+	      (uint64_t) read_8ubyte_unaligned (attrp->cu->dbg, attrp->valp));
+      break;
+
+    case DW_FORM_sec_offset:
+    case DW_FORM_udata:
+    case DW_FORM_sdata:
+    case DW_FORM_data8:
+    case DW_FORM_data4:
+    case DW_FORM_data2:
+    case DW_FORM_data1:;
+      Dwarf_Word num;
+      if (unlikely (dwarf_formudata (attrp, &num) != 0))
+	goto attrval_out;
+
+      const char *valuestr = NULL;
+      switch (attr)
+	{
+	  /* This case can take either a constant or a loclistptr.  */
+	case DW_AT_data_member_location:
+	  if (form != DW_FORM_sec_offset
+	      && (cbargs->version >= 4
+		  || (form != DW_FORM_data4 && form != DW_FORM_data8)))
+	    {
+	      if (!cbargs->silent)
+		printf ("           %*s%-20s (%s) %" PRIxMAX "\n",
+			(int) (level * 2), "", dwarf_attr_name (attr),
+			dwarf_form_name (form), (uintmax_t) num);
+	      return DWARF_CB_OK;
+	    }
+	  FALLTHROUGH;
+
+	/* These cases always take a loclistptr and no constant. */
+	case DW_AT_location:
+	case DW_AT_data_location:
+	case DW_AT_vtable_elem_location:
+	case DW_AT_string_length:
+	case DW_AT_use_location:
+	case DW_AT_frame_base:
+	case DW_AT_return_addr:
+	case DW_AT_static_link:
+	case DW_AT_GNU_call_site_value:
+	case DW_AT_GNU_call_site_data_value:
+	case DW_AT_GNU_call_site_target:
+	case DW_AT_GNU_call_site_target_clobbered:
+	  {
+	    bool nlpt = notice_listptr (section_loc, &known_loclistptr,
+					cbargs->addrsize, cbargs->offset_size,
+					cbargs->cu, num);
+	    if (!cbargs->silent)
+	      printf ("           %*s%-20s (%s) location list [%6" PRIxMAX "]%s\n",
+		      (int) (level * 2), "", dwarf_attr_name (attr),
+		      dwarf_form_name (form), (uintmax_t) num,
+		      nlpt ? "" : " <WARNING offset too big>");
+	  }
+	  return DWARF_CB_OK;
+
+	case DW_AT_ranges:
+	  {
+	    bool nlpt = notice_listptr (section_ranges, &known_rangelistptr,
+					cbargs->addrsize, cbargs->offset_size,
+					cbargs->cu, num);
+	    if (!cbargs->silent)
+	      printf ("           %*s%-20s (%s) range list [%6" PRIxMAX "]%s\n",
+		      (int) (level * 2), "", dwarf_attr_name (attr),
+		      dwarf_form_name (form), (uintmax_t) num,
+		      nlpt ? "" : " <WARNING offset too big>");
+	  }
+	  return DWARF_CB_OK;
+
+	case DW_AT_language:
+	  valuestr = dwarf_lang_name (num);
+	  break;
+	case DW_AT_encoding:
+	  valuestr = dwarf_encoding_name (num);
+	  break;
+	case DW_AT_accessibility:
+	  valuestr = dwarf_access_name (num);
+	  break;
+	case DW_AT_defaulted:
+	  valuestr = dwarf_defaulted_name (num);
+	  break;
+	case DW_AT_visibility:
+	  valuestr = dwarf_visibility_name (num);
+	  break;
+	case DW_AT_virtuality:
+	  valuestr = dwarf_virtuality_name (num);
+	  break;
+	case DW_AT_identifier_case:
+	  valuestr = dwarf_identifier_case_name (num);
+	  break;
+	case DW_AT_calling_convention:
+	  valuestr = dwarf_calling_convention_name (num);
+	  break;
+	case DW_AT_inline:
+	  valuestr = dwarf_inline_name (num);
+	  break;
+	case DW_AT_ordering:
+	  valuestr = dwarf_ordering_name (num);
+	  break;
+	case DW_AT_discr_list:
+	  valuestr = dwarf_discr_list_name (num);
+	  break;
+	case DW_AT_decl_file:
+	case DW_AT_call_file:
+	  {
+	    /* Try to get the actual file, the current interface only
+	       gives us full paths, but we only want to show the file
+	       name for now.  */
+	    Dwarf_Die cudie;
+	    if (dwarf_cu_die (cbargs->cu, &cudie,
+			      NULL, NULL, NULL, NULL, NULL, NULL) != NULL)
+	      {
+		Dwarf_Files *files;
+		size_t nfiles;
+		if (dwarf_getsrcfiles (&cudie, &files, &nfiles) == 0)
+		  {
+		    valuestr = dwarf_filesrc (files, num, NULL, NULL);
+		    char *filename = strrchr (valuestr, '/');
+		    if (filename != NULL)
+		      valuestr = filename + 1;
+		  }
+	      }
+	  }
+	  break;
+	default:
+	  /* Nothing.  */
+	  break;
+	}
+
+      if (cbargs->silent)
+	break;
+
+      /* When highpc is in constant form it is relative to lowpc.
+	 In that case also show the address.  */
+      Dwarf_Addr highpc;
+      if (attr == DW_AT_high_pc && dwarf_highpc (cbargs->die, &highpc) == 0)
+	{
+	  char *a = format_dwarf_addr (cbargs->dwflmod, cbargs->addrsize,
+				       highpc, highpc);
+	  printf ("           %*s%-20s (%s) %" PRIuMAX " (%s)\n",
+		  (int) (level * 2), "", dwarf_attr_name (attr),
+		  dwarf_form_name (form), (uintmax_t) num, a);
+	  free (a);
+	}
+      else
+	{
+	  Dwarf_Sword snum = 0;
+	  if (form == DW_FORM_sdata)
+	    if (unlikely (dwarf_formsdata (attrp, &snum) != 0))
+	      goto attrval_out;
+
+	  if (valuestr == NULL)
+	    {
+	      printf ("           %*s%-20s (%s)",
+		      (int) (level * 2), "", dwarf_attr_name (attr),
+		      dwarf_form_name (form));
+	      if (form == DW_FORM_sdata)
+		printf (" %" PRIdMAX "\n", (intmax_t) snum);
+	      else
+		printf (" %" PRIuMAX "\n", (uintmax_t) num);
+	    }
+	  else
+	    {
+	      printf ("           %*s%-20s (%s) %s",
+		      (int) (level * 2), "", dwarf_attr_name (attr),
+		      dwarf_form_name (form), valuestr);
+	      if (form == DW_FORM_sdata)
+		printf (" (%" PRIdMAX ")\n", (intmax_t) snum);
+	      else
+		printf (" (%" PRIuMAX ")\n", (uintmax_t) num);
+	    }
+	}
+      break;
+
+    case DW_FORM_flag:
+      if (cbargs->silent)
+	break;
+      bool flag;
+      if (unlikely (dwarf_formflag (attrp, &flag) != 0))
+	goto attrval_out;
+
+      printf ("           %*s%-20s (%s) %s\n",
+	      (int) (level * 2), "", dwarf_attr_name (attr),
+	      dwarf_form_name (form), flag ? gettext ("yes") : gettext ("no"));
+      break;
+
+    case DW_FORM_flag_present:
+      if (cbargs->silent)
+	break;
+      printf ("           %*s%-20s (%s) %s\n",
+	      (int) (level * 2), "", dwarf_attr_name (attr),
+	      dwarf_form_name (form), gettext ("yes"));
+      break;
+
+    case DW_FORM_exprloc:
+    case DW_FORM_block4:
+    case DW_FORM_block2:
+    case DW_FORM_block1:
+    case DW_FORM_block:
+      if (cbargs->silent)
+	break;
+      Dwarf_Block block;
+      if (unlikely (dwarf_formblock (attrp, &block) != 0))
+	goto attrval_out;
+
+      printf ("           %*s%-20s (%s) ",
+	      (int) (level * 2), "", dwarf_attr_name (attr),
+	      dwarf_form_name (form));
+
+      switch (attr)
+	{
+	default:
+	  if (form != DW_FORM_exprloc)
+	    {
+	      print_block (block.length, block.data);
+	      break;
+	    }
+	  FALLTHROUGH;
+
+	case DW_AT_location:
+	case DW_AT_data_location:
+	case DW_AT_data_member_location:
+	case DW_AT_vtable_elem_location:
+	case DW_AT_string_length:
+	case DW_AT_use_location:
+	case DW_AT_frame_base:
+	case DW_AT_return_addr:
+	case DW_AT_static_link:
+	case DW_AT_allocated:
+	case DW_AT_associated:
+	case DW_AT_bit_size:
+	case DW_AT_bit_offset:
+	case DW_AT_bit_stride:
+	case DW_AT_byte_size:
+	case DW_AT_byte_stride:
+	case DW_AT_count:
+	case DW_AT_lower_bound:
+	case DW_AT_upper_bound:
+	case DW_AT_GNU_call_site_value:
+	case DW_AT_GNU_call_site_data_value:
+	case DW_AT_GNU_call_site_target:
+	case DW_AT_GNU_call_site_target_clobbered:
+	  putchar ('\n');
+	  print_ops (cbargs->dwflmod, cbargs->dbg,
+		     12 + level * 2, 12 + level * 2,
+		     cbargs->version, cbargs->addrsize, cbargs->offset_size,
+		     attrp->cu, block.length, block.data);
+	  break;
+	}
+      break;
+
+    default:
+      if (cbargs->silent)
+	break;
+      printf ("           %*s%-20s (%s) ???\n",
+	      (int) (level * 2), "", dwarf_attr_name (attr),
+	      dwarf_form_name (form));
+      break;
+    }
+
+  return DWARF_CB_OK;
+}
+
+static void
+print_debug_units (Dwfl_Module *dwflmod,
+		   Ebl *ebl, GElf_Ehdr *ehdr,
+		   Elf_Scn *scn, GElf_Shdr *shdr,
+		   Dwarf *dbg, bool debug_types)
+{
+  const bool silent = !(print_debug_sections & section_info);
+  const char *secname = section_name (ebl, ehdr, shdr);
+
+  if (!silent)
+    printf (gettext ("\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n [Offset]\n"),
+	    elf_ndxscn (scn), secname, (uint64_t) shdr->sh_offset);
+
+  /* If the section is empty we don't have to do anything.  */
+  if (!silent && shdr->sh_size == 0)
+    return;
+
+  int maxdies = 20;
+  Dwarf_Die *dies = (Dwarf_Die *) xmalloc (maxdies * sizeof (Dwarf_Die));
+
+  Dwarf_Off offset = 0;
+
+  /* New compilation unit.  */
+  size_t cuhl;
+  Dwarf_Half version;
+  Dwarf_Off abbroffset;
+  uint8_t addrsize;
+  uint8_t offsize;
+  Dwarf_Off nextcu;
+  uint64_t typesig;
+  Dwarf_Off typeoff;
+ next_cu:
+  if (dwarf_next_unit (dbg, offset, &nextcu, &cuhl, &version,
+		       &abbroffset, &addrsize, &offsize,
+		       debug_types ? &typesig : NULL,
+		       debug_types ? &typeoff : NULL) != 0)
+    goto do_return;
+
+  if (!silent)
+    {
+      if (debug_types)
+	printf (gettext (" Type unit at offset %" PRIu64 ":\n"
+			 " Version: %" PRIu16 ", Abbreviation section offset: %"
+			 PRIu64 ", Address size: %" PRIu8
+			 ", Offset size: %" PRIu8
+			 "\n Type signature: %#" PRIx64
+			 ", Type offset: %#" PRIx64 "\n"),
+		(uint64_t) offset, version, abbroffset, addrsize, offsize,
+		typesig, (uint64_t) typeoff);
+      else
+	printf (gettext (" Compilation unit at offset %" PRIu64 ":\n"
+			 " Version: %" PRIu16 ", Abbreviation section offset: %"
+			 PRIu64 ", Address size: %" PRIu8
+			 ", Offset size: %" PRIu8 "\n"),
+		(uint64_t) offset, version, abbroffset, addrsize, offsize);
+    }
+
+  struct attrcb_args args =
+    {
+      .dwflmod = dwflmod,
+      .dbg = dbg,
+      .silent = silent,
+      .version = version,
+      .addrsize = addrsize,
+      .offset_size = offsize
+    };
+
+  offset += cuhl;
+
+  int level = 0;
+
+  if (unlikely ((debug_types ? dwarf_offdie_types : dwarf_offdie)
+		(dbg, offset, &dies[level]) == NULL))
+    {
+      if (!silent)
+	error (0, 0, gettext ("cannot get DIE at offset %" PRIu64
+			      " in section '%s': %s"),
+	       (uint64_t) offset, secname, dwarf_errmsg (-1));
+      goto do_return;
+    }
+
+  args.cu = dies[0].cu;
+
+  do
+    {
+      offset = dwarf_dieoffset (&dies[level]);
+      if (unlikely (offset == ~0ul))
+	{
+	  if (!silent)
+	    error (0, 0, gettext ("cannot get DIE offset: %s"),
+		   dwarf_errmsg (-1));
+	  goto do_return;
+	}
+
+      int tag = dwarf_tag (&dies[level]);
+      if (unlikely (tag == DW_TAG_invalid))
+	{
+	  if (!silent)
+	    error (0, 0, gettext ("cannot get tag of DIE at offset [%" PRIx64
+				  "] in section '%s': %s"),
+		   (uint64_t) offset, secname, dwarf_errmsg (-1));
+	  goto do_return;
+	}
+
+      if (!silent)
+	{
+	  unsigned int code = dwarf_getabbrevcode (dies[level].abbrev);
+	  printf (" [%6" PRIx64 "]  %*s%-20s abbrev: %u\n",
+		  (uint64_t) offset, (int) (level * 2), "",
+		  dwarf_tag_name (tag), code);
+	}
+
+      /* Print the attribute values.  */
+      args.level = level;
+      args.die = &dies[level];
+      (void) dwarf_getattrs (&dies[level], attr_callback, &args, 0);
+
+      /* Make room for the next level's DIE.  */
+      if (level + 1 == maxdies)
+	dies = (Dwarf_Die *) xrealloc (dies,
+				       (maxdies += 10)
+				       * sizeof (Dwarf_Die));
+
+      int res = dwarf_child (&dies[level], &dies[level + 1]);
+      if (res > 0)
+	{
+	  while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1)
+	    if (level-- == 0)
+	      break;
+
+	  if (unlikely (res == -1))
+	    {
+	      if (!silent)
+		error (0, 0, gettext ("cannot get next DIE: %s\n"),
+		       dwarf_errmsg (-1));
+	      goto do_return;
+	    }
+	}
+      else if (unlikely (res < 0))
+	{
+	  if (!silent)
+	    error (0, 0, gettext ("cannot get next DIE: %s"),
+		   dwarf_errmsg (-1));
+	  goto do_return;
+	}
+      else
+	++level;
+    }
+  while (level >= 0);
+
+  offset = nextcu;
+  if (offset != 0)
+     goto next_cu;
+
+ do_return:
+  free (dies);
+}
+
+static void
+print_debug_info_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
+			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, false);
+}
+
+static void
+print_debug_types_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
+			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  print_debug_units (dwflmod, ebl, ehdr, scn, shdr, dbg, true);
+}
+
+
+static void
+print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
+			    Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  printf (gettext ("\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n\n"),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset);
+
+  size_t address_size
+    = elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+
+  Dwarf_Off cuoffset;
+  Dwarf_Off ncuoffset = 0;
+  size_t hsize;
+  while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
+		       NULL, NULL, NULL) == 0)
+    {
+      Dwarf_Die cudie;
+      if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
+	continue;
+
+      size_t nlines;
+      Dwarf_Lines *lines;
+      if (dwarf_getsrclines (&cudie, &lines, &nlines) != 0)
+	continue;
+
+      printf (" CU [%" PRIx64 "] %s\n",
+	      dwarf_dieoffset (&cudie), dwarf_diename (&cudie));
+      printf ("  line:col SBPE* disc isa op address"
+	      " (Statement Block Prologue Epilogue *End)\n");
+      const char *last_file = "";
+      for (size_t n = 0; n < nlines; n++)
+	{
+	  Dwarf_Line *line = dwarf_onesrcline (lines, n);
+	  if (line == NULL)
+	    {
+	      printf ("  dwarf_onesrcline: %s\n", dwarf_errmsg (-1));
+	      continue;
+	    }
+	  Dwarf_Word mtime, length;
+	  const char *file = dwarf_linesrc (line, &mtime, &length);
+	  if (file == NULL)
+	    {
+	      printf ("  <%s> (mtime: ?, length: ?)\n", dwarf_errmsg (-1));
+	      last_file = "";
+	    }
+	  else if (strcmp (last_file, file) != 0)
+	    {
+	      printf ("  %s (mtime: %" PRIu64 ", length: %" PRIu64 ")\n",
+		      file, mtime, length);
+	      last_file = file;
+	    }
+
+	  int lineno, colno;
+	  bool statement, endseq, block, prologue_end, epilogue_begin;
+	  unsigned int lineop, isa, disc;
+	  Dwarf_Addr address;
+	  dwarf_lineaddr (line, &address);
+	  dwarf_lineno (line, &lineno);
+	  dwarf_linecol (line, &colno);
+	  dwarf_lineop_index (line, &lineop);
+	  dwarf_linebeginstatement (line, &statement);
+	  dwarf_lineendsequence (line, &endseq);
+	  dwarf_lineblock (line, &block);
+	  dwarf_lineprologueend (line, &prologue_end);
+	  dwarf_lineepiloguebegin (line, &epilogue_begin);
+	  dwarf_lineisa (line, &isa);
+	  dwarf_linediscriminator (line, &disc);
+
+	  /* End sequence is special, it is one byte past.  */
+	  char *a = format_dwarf_addr (dwflmod, address_size,
+				       address - (endseq ? 1 : 0), address);
+	  printf ("  %4d:%-3d %c%c%c%c%c %4d %3d %2d %s\n",
+		  lineno, colno,
+		  (statement ? 'S' : ' '),
+		  (block ? 'B' : ' '),
+		  (prologue_end ? 'P' : ' '),
+		  (epilogue_begin ? 'E' : ' '),
+		  (endseq ? '*' : ' '),
+		  disc, isa, lineop, a);
+	  free (a);
+
+	  if (endseq)
+	    printf("\n");
+	}
+    }
+}
+
+
+static void
+print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
+			  Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  if (decodedline)
+    {
+      print_decoded_line_section (dwflmod, ebl, ehdr, scn, shdr, dbg);
+      return;
+    }
+
+  printf (gettext ("\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset);
+
+  if (shdr->sh_size == 0)
+    return;
+
+  /* There is no functionality in libdw to read the information in the
+     way it is represented here.  Hardcode the decoder.  */
+  Elf_Data *data = dbg->sectiondata[IDX_debug_line];
+  if (unlikely (data == NULL || data->d_buf == NULL))
+    {
+      error (0, 0, gettext ("cannot get line data section data: %s"),
+	     elf_errmsg (-1));
+      return;
+    }
+
+  const unsigned char *linep = (const unsigned char *) data->d_buf;
+  const unsigned char *lineendp;
+
+  while (linep
+	 < (lineendp = (const unsigned char *) data->d_buf + data->d_size))
+    {
+      size_t start_offset = linep - (const unsigned char *) data->d_buf;
+
+      printf (gettext ("\nTable at offset %zu:\n"), start_offset);
+
+      if (unlikely (linep + 4 > lineendp))
+	goto invalid_data;
+      Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep);
+      unsigned int length = 4;
+      if (unlikely (unit_length == 0xffffffff))
+	{
+	  if (unlikely (linep + 8 > lineendp))
+	    {
+	    invalid_data:
+	      error (0, 0, gettext ("invalid data in section [%zu] '%s'"),
+		     elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
+	      return;
+	    }
+	  unit_length = read_8ubyte_unaligned_inc (dbg, linep);
+	  length = 8;
+	}
+
+      /* Check whether we have enough room in the section.  */
+      if (unlikely (unit_length > (size_t) (lineendp - linep)
+	  || unit_length < 2 + length + 5 * 1))
+	goto invalid_data;
+      lineendp = linep + unit_length;
+
+      /* The next element of the header is the version identifier.  */
+      uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep);
+
+      /* Next comes the header length.  */
+      Dwarf_Word header_length;
+      if (length == 4)
+	header_length = read_4ubyte_unaligned_inc (dbg, linep);
+      else
+	header_length = read_8ubyte_unaligned_inc (dbg, linep);
+      //const unsigned char *header_start = linep;
+
+      /* Next the minimum instruction length.  */
+      uint_fast8_t minimum_instr_len = *linep++;
+
+      /* Next the maximum operations per instruction, in version 4 format.  */
+      uint_fast8_t max_ops_per_instr = version < 4 ? 1 : *linep++;
+
+	/* Then the flag determining the default value of the is_stmt
+	   register.  */
+      uint_fast8_t default_is_stmt = *linep++;
+
+      /* Now the line base.  */
+      int_fast8_t line_base = *((const int_fast8_t *) linep);
+      ++linep;
+
+      /* And the line range.  */
+      uint_fast8_t line_range = *linep++;
+
+      /* The opcode base.  */
+      uint_fast8_t opcode_base = *linep++;
+
+      /* Print what we got so far.  */
+      printf (gettext ("\n"
+		       " Length:                     %" PRIu64 "\n"
+		       " DWARF version:              %" PRIuFAST16 "\n"
+		       " Prologue length:            %" PRIu64 "\n"
+		       " Minimum instruction length: %" PRIuFAST8 "\n"
+		       " Maximum operations per instruction: %" PRIuFAST8 "\n"
+		       " Initial value if '%s': %" PRIuFAST8 "\n"
+		       " Line base:                  %" PRIdFAST8 "\n"
+		       " Line range:                 %" PRIuFAST8 "\n"
+		       " Opcode base:                %" PRIuFAST8 "\n"
+		       "\n"
+		       "Opcodes:\n"),
+	      (uint64_t) unit_length, version, (uint64_t) header_length,
+	      minimum_instr_len, max_ops_per_instr,
+	      "is_stmt", default_is_stmt, line_base,
+	      line_range, opcode_base);
+
+      if (unlikely (linep + opcode_base - 1 >= lineendp))
+	{
+	invalid_unit:
+	  error (0, 0,
+		 gettext ("invalid data at offset %tu in section [%zu] '%s'"),
+		 linep - (const unsigned char *) data->d_buf,
+		 elf_ndxscn (scn), section_name (ebl, ehdr, shdr));
+	  linep = lineendp;
+	  continue;
+	}
+      int opcode_base_l10 = 1;
+      unsigned int tmp = opcode_base;
+      while (tmp > 10)
+	{
+	  tmp /= 10;
+	  ++opcode_base_l10;
+	}
+      const uint8_t *standard_opcode_lengths = linep - 1;
+      for (uint_fast8_t cnt = 1; cnt < opcode_base; ++cnt)
+	printf (ngettext ("  [%*" PRIuFAST8 "]  %hhu argument\n",
+			  "  [%*" PRIuFAST8 "]  %hhu arguments\n",
+			  (int) linep[cnt - 1]),
+		opcode_base_l10, cnt, linep[cnt - 1]);
+      linep += opcode_base - 1;
+      if (unlikely (linep >= lineendp))
+	goto invalid_unit;
+
+      puts (gettext ("\nDirectory table:"));
+      while (*linep != 0)
+	{
+	  unsigned char *endp = memchr (linep, '\0', lineendp - linep);
+	  if (unlikely (endp == NULL))
+	    goto invalid_unit;
+
+	  printf (" %s\n", (char *) linep);
+
+	  linep = endp + 1;
+	}
+      /* Skip the final NUL byte.  */
+      ++linep;
+
+      if (unlikely (linep >= lineendp))
+	goto invalid_unit;
+      puts (gettext ("\nFile name table:\n"
+		     " Entry Dir   Time      Size      Name"));
+      for (unsigned int cnt = 1; *linep != 0; ++cnt)
+	{
+	  /* First comes the file name.  */
+	  char *fname = (char *) linep;
+	  unsigned char *endp = memchr (fname, '\0', lineendp - linep);
+	  if (unlikely (endp == NULL))
+	    goto invalid_unit;
+	  linep = endp + 1;
+
+	  /* Then the index.  */
+	  unsigned int diridx;
+	  if (lineendp - linep < 1)
+	    goto invalid_unit;
+	  get_uleb128 (diridx, linep, lineendp);
+
+	  /* Next comes the modification time.  */
+	  unsigned int mtime;
+	  if (lineendp - linep < 1)
+	    goto invalid_unit;
+	  get_uleb128 (mtime, linep, lineendp);
+
+	  /* Finally the length of the file.  */
+	  unsigned int fsize;
+	  if (lineendp - linep < 1)
+	    goto invalid_unit;
+	  get_uleb128 (fsize, linep, lineendp);
+
+	  printf (" %-5u %-5u %-9u %-9u %s\n",
+		  cnt, diridx, mtime, fsize, fname);
+	}
+      /* Skip the final NUL byte.  */
+      ++linep;
+
+      puts (gettext ("\nLine number statements:"));
+      Dwarf_Word address = 0;
+      unsigned int op_index = 0;
+      size_t line = 1;
+      uint_fast8_t is_stmt = default_is_stmt;
+
+      /* Default address value, in case we do not find the CU.  */
+      size_t address_size
+	= elf_getident (ebl->elf, NULL)[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+
+      /* Determine the CU this block is for.  */
+      Dwarf_Off cuoffset;
+      Dwarf_Off ncuoffset = 0;
+      size_t hsize;
+      while (dwarf_nextcu (dbg, cuoffset = ncuoffset, &ncuoffset, &hsize,
+			   NULL, NULL, NULL) == 0)
+	{
+	  Dwarf_Die cudie;
+	  if (dwarf_offdie (dbg, cuoffset + hsize, &cudie) == NULL)
+	    continue;
+	  Dwarf_Attribute stmt_list;
+	  if (dwarf_attr (&cudie, DW_AT_stmt_list, &stmt_list) == NULL)
+	    continue;
+	  Dwarf_Word lineoff;
+	  if (dwarf_formudata (&stmt_list, &lineoff) != 0)
+	    continue;
+	  if (lineoff == start_offset)
+	    {
+	      /* Found the CU.  */
+	      address_size = cudie.cu->address_size;
+	      break;
+	    }
+	}
+
+      /* Apply the "operation advance" from a special opcode
+	 or DW_LNS_advance_pc (as per DWARF4 6.2.5.1).  */
+      unsigned int op_addr_advance;
+      bool show_op_index;
+      inline void advance_pc (unsigned int op_advance)
+      {
+	op_addr_advance = minimum_instr_len * ((op_index + op_advance)
+					       / max_ops_per_instr);
+	address += op_advance;
+	show_op_index = (op_index > 0 ||
+			 (op_index + op_advance) % max_ops_per_instr > 0);
+	op_index = (op_index + op_advance) % max_ops_per_instr;
+      }
+
+      if (max_ops_per_instr == 0)
+	{
+	  error (0, 0,
+		 gettext ("invalid maximum operations per instruction is zero"));
+	  linep = lineendp;
+	  continue;
+	}
+
+      while (linep < lineendp)
+	{
+	  size_t offset = linep - (const unsigned char *) data->d_buf;
+	  unsigned int u128;
+	  int s128;
+
+	  /* Read the opcode.  */
+	  unsigned int opcode = *linep++;
+
+	  printf (" [%6" PRIx64 "]", (uint64_t)offset);
+	  /* Is this a special opcode?  */
+	  if (likely (opcode >= opcode_base))
+	    {
+	      if (unlikely (line_range == 0))
+		goto invalid_unit;
+
+	      /* Yes.  Handling this is quite easy since the opcode value
+		 is computed with
+
+		 opcode = (desired line increment - line_base)
+			   + (line_range * address advance) + opcode_base
+	      */
+	      int line_increment = (line_base
+				    + (opcode - opcode_base) % line_range);
+
+	      /* Perform the increments.  */
+	      line += line_increment;
+	      advance_pc ((opcode - opcode_base) / line_range);
+
+	      char *a = format_dwarf_addr (dwflmod, 0, address, address);
+	      if (show_op_index)
+		printf (gettext ("\
+ special opcode %u: address+%u = %s, op_index = %u, line%+d = %zu\n"),
+			opcode, op_addr_advance, a, op_index,
+			line_increment, line);
+	      else
+		printf (gettext ("\
+ special opcode %u: address+%u = %s, line%+d = %zu\n"),
+			opcode, op_addr_advance, a, line_increment, line);
+	      free (a);
+	    }
+	  else if (opcode == 0)
+	    {
+	      /* This an extended opcode.  */
+	      if (unlikely (linep + 2 > lineendp))
+		goto invalid_unit;
+
+	      /* The length.  */
+	      unsigned int len = *linep++;
+
+	      if (unlikely (linep + len > lineendp))
+		goto invalid_unit;
+
+	      /* The sub-opcode.  */
+	      opcode = *linep++;
+
+	      printf (gettext (" extended opcode %u: "), opcode);
+
+	      switch (opcode)
+		{
+		case DW_LNE_end_sequence:
+		  puts (gettext (" end of sequence"));
+
+		  /* Reset the registers we care about.  */
+		  address = 0;
+		  op_index = 0;
+		  line = 1;
+		  is_stmt = default_is_stmt;
+		  break;
+
+		case DW_LNE_set_address:
+		  op_index = 0;
+		  if (unlikely ((size_t) (lineendp - linep) < address_size))
+		    goto invalid_unit;
+		  if (address_size == 4)
+		    address = read_4ubyte_unaligned_inc (dbg, linep);
+		  else
+		    address = read_8ubyte_unaligned_inc (dbg, linep);
+		  {
+		    char *a = format_dwarf_addr (dwflmod, 0, address, address);
+		    printf (gettext (" set address to %s\n"), a);
+		    free (a);
+		  }
+		  break;
+
+		case DW_LNE_define_file:
+		  {
+		    char *fname = (char *) linep;
+		    unsigned char *endp = memchr (linep, '\0',
+						  lineendp - linep);
+		    if (unlikely (endp == NULL))
+		      goto invalid_unit;
+		    linep = endp + 1;
+
+		    unsigned int diridx;
+		    if (lineendp - linep < 1)
+		      goto invalid_unit;
+		    get_uleb128 (diridx, linep, lineendp);
+		    Dwarf_Word mtime;
+		    if (lineendp - linep < 1)
+		      goto invalid_unit;
+		    get_uleb128 (mtime, linep, lineendp);
+		    Dwarf_Word filelength;
+		    if (lineendp - linep < 1)
+		      goto invalid_unit;
+		    get_uleb128 (filelength, linep, lineendp);
+
+		    printf (gettext ("\
+ define new file: dir=%u, mtime=%" PRIu64 ", length=%" PRIu64 ", name=%s\n"),
+			    diridx, (uint64_t) mtime, (uint64_t) filelength,
+			    fname);
+		  }
+		  break;
+
+		case DW_LNE_set_discriminator:
+		  /* Takes one ULEB128 parameter, the discriminator.  */
+		  if (unlikely (standard_opcode_lengths[opcode] != 1))
+		    goto invalid_unit;
+
+		  get_uleb128 (u128, linep, lineendp);
+		  printf (gettext (" set discriminator to %u\n"), u128);
+		  break;
+
+		default:
+		  /* Unknown, ignore it.  */
+		  puts (gettext (" unknown opcode"));
+		  linep += len - 1;
+		  break;
+		}
+	    }
+	  else if (opcode <= DW_LNS_set_isa)
+	    {
+	      /* This is a known standard opcode.  */
+	      switch (opcode)
+		{
+		case DW_LNS_copy:
+		  /* Takes no argument.  */
+		  puts (gettext (" copy"));
+		  break;
+
+		case DW_LNS_advance_pc:
+		  /* Takes one uleb128 parameter which is added to the
+		     address.  */
+		  get_uleb128 (u128, linep, lineendp);
+		  advance_pc (u128);
+		  {
+		    char *a = format_dwarf_addr (dwflmod, 0, address, address);
+		    if (show_op_index)
+		      printf (gettext ("\
+ advance address by %u to %s, op_index to %u\n"),
+			      op_addr_advance, a, op_index);
+		    else
+		      printf (gettext (" advance address by %u to %s\n"),
+			      op_addr_advance, a);
+		    free (a);
+		  }
+		  break;
+
+		case DW_LNS_advance_line:
+		  /* Takes one sleb128 parameter which is added to the
+		     line.  */
+		  get_sleb128 (s128, linep, lineendp);
+		  line += s128;
+		  printf (gettext ("\
+ advance line by constant %d to %" PRId64 "\n"),
+			  s128, (int64_t) line);
+		  break;
+
+		case DW_LNS_set_file:
+		  /* Takes one uleb128 parameter which is stored in file.  */
+		  get_uleb128 (u128, linep, lineendp);
+		  printf (gettext (" set file to %" PRIu64 "\n"),
+			  (uint64_t) u128);
+		  break;
+
+		case DW_LNS_set_column:
+		  /* Takes one uleb128 parameter which is stored in column.  */
+		  if (unlikely (standard_opcode_lengths[opcode] != 1))
+		    goto invalid_unit;
+
+		  get_uleb128 (u128, linep, lineendp);
+		  printf (gettext (" set column to %" PRIu64 "\n"),
+			  (uint64_t) u128);
+		  break;
+
+		case DW_LNS_negate_stmt:
+		  /* Takes no argument.  */
+		  is_stmt = 1 - is_stmt;
+		  printf (gettext (" set '%s' to %" PRIuFAST8 "\n"),
+			  "is_stmt", is_stmt);
+		  break;
+
+		case DW_LNS_set_basic_block:
+		  /* Takes no argument.  */
+		  puts (gettext (" set basic block flag"));
+		  break;
+
+		case DW_LNS_const_add_pc:
+		  /* Takes no argument.  */
+
+		  if (unlikely (line_range == 0))
+		    goto invalid_unit;
+
+		  advance_pc ((255 - opcode_base) / line_range);
+		  {
+		    char *a = format_dwarf_addr (dwflmod, 0, address, address);
+		    if (show_op_index)
+		      printf (gettext ("\
+ advance address by constant %u to %s, op_index to %u\n"),
+			      op_addr_advance, a, op_index);
+		    else
+		      printf (gettext ("\
+ advance address by constant %u to %s\n"),
+			      op_addr_advance, a);
+		    free (a);
+		  }
+		  break;
+
+		case DW_LNS_fixed_advance_pc:
+		  /* Takes one 16 bit parameter which is added to the
+		     address.  */
+		  if (unlikely (standard_opcode_lengths[opcode] != 1))
+		    goto invalid_unit;
+
+		  u128 = read_2ubyte_unaligned_inc (dbg, linep);
+		  address += u128;
+		  op_index = 0;
+		  {
+		    char *a = format_dwarf_addr (dwflmod, 0, address, address);
+		    printf (gettext ("\
+ advance address by fixed value %u to %s\n"),
+			    u128, a);
+		    free (a);
+		  }
+		  break;
+
+		case DW_LNS_set_prologue_end:
+		  /* Takes no argument.  */
+		  puts (gettext (" set prologue end flag"));
+		  break;
+
+		case DW_LNS_set_epilogue_begin:
+		  /* Takes no argument.  */
+		  puts (gettext (" set epilogue begin flag"));
+		  break;
+
+		case DW_LNS_set_isa:
+		  /* Takes one uleb128 parameter which is stored in isa.  */
+		  if (unlikely (standard_opcode_lengths[opcode] != 1))
+		    goto invalid_unit;
+
+		  get_uleb128 (u128, linep, lineendp);
+		  printf (gettext (" set isa to %u\n"), u128);
+		  break;
+		}
+	    }
+	  else
+	    {
+	      /* This is a new opcode the generator but not we know about.
+		 Read the parameters associated with it but then discard
+		 everything.  Read all the parameters for this opcode.  */
+	      printf (ngettext (" unknown opcode with %" PRIu8 " parameter:",
+				" unknown opcode with %" PRIu8 " parameters:",
+				standard_opcode_lengths[opcode]),
+		      standard_opcode_lengths[opcode]);
+	      for (int n = standard_opcode_lengths[opcode]; n > 0; --n)
+		{
+		  get_uleb128 (u128, linep, lineendp);
+		  if (n != standard_opcode_lengths[opcode])
+		    putc_unlocked (',', stdout);
+		  printf (" %u", u128);
+		}
+
+	      /* Next round, ignore this opcode.  */
+	      continue;
+	    }
+	}
+    }
+
+  /* There must only be one data block.  */
+  assert (elf_getdata (scn, data) == NULL);
+}
+
+
+static void
+print_debug_loc_section (Dwfl_Module *dwflmod,
+			 Ebl *ebl, GElf_Ehdr *ehdr,
+			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  Elf_Data *data = dbg->sectiondata[IDX_debug_loc];
+
+  if (unlikely (data == NULL))
+    {
+      error (0, 0, gettext ("cannot get .debug_loc content: %s"),
+	     elf_errmsg (-1));
+      return;
+    }
+
+  printf (gettext ("\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset);
+
+  sort_listptr (&known_loclistptr, "loclistptr");
+  size_t listptr_idx = 0;
+
+  uint_fast8_t address_size = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 4 : 8;
+  uint_fast8_t offset_size = 4;
+
+  bool first = true;
+  Dwarf_Addr base = 0;
+  unsigned char *readp = data->d_buf;
+  unsigned char *const endp = (unsigned char *) data->d_buf + data->d_size;
+  Dwarf_CU *last_cu = NULL;
+  while (readp < endp)
+    {
+      ptrdiff_t offset = readp - (unsigned char *) data->d_buf;
+      Dwarf_CU *cu = last_cu;
+
+      if (first && skip_listptr_hole (&known_loclistptr, &listptr_idx,
+				      &address_size, &offset_size, &base,
+				      &cu, offset, &readp, endp))
+	continue;
+
+      if (last_cu != cu)
+       {
+	char *basestr = format_dwarf_addr (dwflmod, address_size,
+					   base, base);
+	Dwarf_Die cudie;
+	if (dwarf_cu_die (cu, &cudie,
+			  NULL, NULL, NULL, NULL,
+			  NULL, NULL) == NULL)
+	  printf (gettext ("\n Unknown CU base: %s\n"), basestr);
+	else
+	  printf (gettext ("\n CU [%6" PRIx64 "] base: %s\n"),
+		  dwarf_dieoffset (&cudie), basestr);
+	free (basestr);
+       }
+      last_cu = cu;
+
+      if (unlikely (data->d_size - offset < (size_t) address_size * 2))
+	{
+	  printf (gettext (" [%6tx]  <INVALID DATA>\n"), offset);
+	  break;
+	}
+
+      Dwarf_Addr begin;
+      Dwarf_Addr end;
+      if (address_size == 8)
+	{
+	  begin = read_8ubyte_unaligned_inc (dbg, readp);
+	  end = read_8ubyte_unaligned_inc (dbg, readp);
+	}
+      else
+	{
+	  begin = read_4ubyte_unaligned_inc (dbg, readp);
+	  end = read_4ubyte_unaligned_inc (dbg, readp);
+	  if (begin == (Dwarf_Addr) (uint32_t) -1)
+	    begin = (Dwarf_Addr) -1l;
+	}
+
+      if (begin == (Dwarf_Addr) -1l) /* Base address entry.  */
+	{
+	  char *b = format_dwarf_addr (dwflmod, address_size, end, end);
+	  printf (gettext (" [%6tx] base address\n          %s\n"), offset, b);
+	  free (b);
+	  base = end;
+	}
+      else if (begin == 0 && end == 0) /* End of list entry.  */
+	{
+	  if (first)
+	    printf (gettext (" [%6tx] empty list\n"), offset);
+	  first = true;
+	}
+      else
+	{
+	  /* We have a location expression entry.  */
+	  uint_fast16_t len = read_2ubyte_unaligned_inc (dbg, readp);
+
+	  if (first)		/* First entry in a list.  */
+	    printf (" [%6tx] ", offset);
+	  else
+	    printf ("          ");
+
+	  printf ("range %" PRIx64 ", %" PRIx64 "\n", begin, end);
+	  if (! print_unresolved_addresses)
+	    {
+	      char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
+					   base + begin);
+	      char *e = format_dwarf_addr (dwflmod, address_size,
+					   base + end - 1, base + end);
+	      printf ("          %s..\n", b);
+	      printf ("          %s\n", e);
+	      free (b);
+	      free (e);
+	    }
+
+	  if (endp - readp <= (ptrdiff_t) len)
+	    {
+	      fputs (gettext ("   <INVALID DATA>\n"), stdout);
+	      break;
+	    }
+
+	  print_ops (dwflmod, dbg, 11, 11,
+		     cu != NULL ? cu->version : 3,
+		     address_size, offset_size, cu, len, readp);
+
+	  first = false;
+	  readp += len;
+	}
+    }
+}
+
+struct mac_culist
+{
+  Dwarf_Die die;
+  Dwarf_Off offset;
+  Dwarf_Files *files;
+  struct mac_culist *next;
+};
+
+
+static int
+mac_compare (const void *p1, const void *p2)
+{
+  struct mac_culist *m1 = (struct mac_culist *) p1;
+  struct mac_culist *m2 = (struct mac_culist *) p2;
+
+  if (m1->offset < m2->offset)
+    return -1;
+  if (m1->offset > m2->offset)
+    return 1;
+  return 0;
+}
+
+
+static void
+print_debug_macinfo_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
+			     Ebl *ebl, GElf_Ehdr *ehdr,
+			     Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  printf (gettext ("\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset);
+  putc_unlocked ('\n', stdout);
+
+  /* There is no function in libdw to iterate over the raw content of
+     the section but it is easy enough to do.  */
+  Elf_Data *data = dbg->sectiondata[IDX_debug_macinfo];
+  if (unlikely (data == NULL || data->d_buf == NULL))
+    {
+      error (0, 0, gettext ("cannot get macro information section data: %s"),
+	     elf_errmsg (-1));
+      return;
+    }
+
+  /* Get the source file information for all CUs.  */
+  Dwarf_Off offset;
+  Dwarf_Off ncu = 0;
+  size_t hsize;
+  struct mac_culist *culist = NULL;
+  size_t nculist = 0;
+  while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
+    {
+      Dwarf_Die cudie;
+      if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
+	continue;
+
+      Dwarf_Attribute attr;
+      if (dwarf_attr (&cudie, DW_AT_macro_info, &attr) == NULL)
+	continue;
+
+      Dwarf_Word macoff;
+      if (dwarf_formudata (&attr, &macoff) != 0)
+	continue;
+
+      struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
+      newp->die = cudie;
+      newp->offset = macoff;
+      newp->files = NULL;
+      newp->next = culist;
+      culist = newp;
+      ++nculist;
+    }
+
+  /* Convert the list into an array for easier consumption.  */
+  struct mac_culist *cus = (struct mac_culist *) alloca ((nculist + 1)
+							 * sizeof (*cus));
+  /* Add sentinel.  */
+  cus[nculist].offset = data->d_size;
+  cus[nculist].files = (Dwarf_Files *) -1l;
+  if (nculist > 0)
+    {
+      for (size_t cnt = nculist - 1; culist != NULL; --cnt)
+	{
+	  assert (cnt < nculist);
+	  cus[cnt] = *culist;
+	  culist = culist->next;
+	}
+
+      /* Sort the array according to the offset in the .debug_macinfo
+	 section.  Note we keep the sentinel at the end.  */
+      qsort (cus, nculist, sizeof (*cus), mac_compare);
+    }
+
+  const unsigned char *readp = (const unsigned char *) data->d_buf;
+  const unsigned char *readendp = readp + data->d_size;
+  int level = 1;
+
+  while (readp < readendp)
+    {
+      unsigned int opcode = *readp++;
+      unsigned int u128;
+      unsigned int u128_2;
+      const unsigned char *endp;
+
+      switch (opcode)
+	{
+	case DW_MACINFO_define:
+	case DW_MACINFO_undef:
+	case DW_MACINFO_vendor_ext:
+	  /*  For the first two opcodes the parameters are
+		line, string
+	      For the latter
+		number, string.
+	      We can treat these cases together.  */
+	  get_uleb128 (u128, readp, readendp);
+
+	  endp = memchr (readp, '\0', readendp - readp);
+	  if (unlikely (endp == NULL))
+	    {
+	      printf (gettext ("\
+%*s*** non-terminated string at end of section"),
+		      level, "");
+	      return;
+	    }
+
+	  if (opcode == DW_MACINFO_define)
+	    printf ("%*s#define %s, line %u\n",
+		    level, "", (char *) readp, u128);
+	  else if (opcode == DW_MACINFO_undef)
+	    printf ("%*s#undef %s, line %u\n",
+		    level, "", (char *) readp, u128);
+	  else
+	    printf (" #vendor-ext %s, number %u\n", (char *) readp, u128);
+
+	  readp = endp + 1;
+	  break;
+
+	case DW_MACINFO_start_file:
+	  /* The two parameters are line and file index, in this order.  */
+	  get_uleb128 (u128, readp, readendp);
+	  if (readendp - readp < 1)
+	    {
+	      printf (gettext ("\
+%*s*** missing DW_MACINFO_start_file argument at end of section"),
+		      level, "");
+	      return;
+	    }
+	  get_uleb128 (u128_2, readp, readendp);
+
+	  /* Find the CU DIE for this file.  */
+	  size_t macoff = readp - (const unsigned char *) data->d_buf;
+	  const char *fname = "???";
+	  if (macoff >= cus[0].offset)
+	    {
+	      while (macoff >= cus[1].offset && cus[1].offset != data->d_size)
+		++cus;
+
+	      if (cus[0].files == NULL
+		&& dwarf_getsrcfiles (&cus[0].die, &cus[0].files, NULL) != 0)
+		cus[0].files = (Dwarf_Files *) -1l;
+
+	      if (cus[0].files != (Dwarf_Files *) -1l)
+		fname = (dwarf_filesrc (cus[0].files, u128_2, NULL, NULL)
+			 ?: "???");
+	    }
+
+	  printf ("%*sstart_file %u, [%u] %s\n",
+		  level, "", u128, u128_2, fname);
+	  ++level;
+	  break;
+
+	case DW_MACINFO_end_file:
+	  --level;
+	  printf ("%*send_file\n", level, "");
+	  /* Nothing more to do.  */
+	  break;
+
+	default:
+	  // XXX gcc seems to generate files with a trailing zero.
+	  if (unlikely (opcode != 0 || readp != readendp))
+	    printf ("%*s*** invalid opcode %u\n", level, "", opcode);
+	  break;
+	}
+    }
+}
+
+
+static void
+print_debug_macro_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
+			   Ebl *ebl, GElf_Ehdr *ehdr,
+			   Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  printf (gettext ("\
+\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset);
+  putc_unlocked ('\n', stdout);
+
+  Elf_Data *data = dbg->sectiondata[IDX_debug_macro];
+  if (unlikely (data == NULL || data->d_buf == NULL))
+    {
+      error (0, 0, gettext ("cannot get macro information section data: %s"),
+	     elf_errmsg (-1));
+      return;
+    }
+
+  /* Get the source file information for all CUs.  Uses same
+     datastructure as macinfo.  But uses offset field to directly
+     match .debug_line offset.  And just stored in a list.  */
+  Dwarf_Off offset;
+  Dwarf_Off ncu = 0;
+  size_t hsize;
+  struct mac_culist *culist = NULL;
+  size_t nculist = 0;
+  while (dwarf_nextcu (dbg, offset = ncu, &ncu, &hsize, NULL, NULL, NULL) == 0)
+    {
+      Dwarf_Die cudie;
+      if (dwarf_offdie (dbg, offset + hsize, &cudie) == NULL)
+	continue;
+
+      Dwarf_Attribute attr;
+      if (dwarf_attr (&cudie, DW_AT_stmt_list, &attr) == NULL)
+	continue;
+
+      Dwarf_Word lineoff;
+      if (dwarf_formudata (&attr, &lineoff) != 0)
+	continue;
+
+      struct mac_culist *newp = (struct mac_culist *) alloca (sizeof (*newp));
+      newp->die = cudie;
+      newp->offset = lineoff;
+      newp->files = NULL;
+      newp->next = culist;
+      culist = newp;
+      ++nculist;
+    }
+
+  const unsigned char *readp = (const unsigned char *) data->d_buf;
+  const unsigned char *readendp = readp + data->d_size;
+
+  while (readp < readendp)
+    {
+      printf (gettext (" Offset:             0x%" PRIx64 "\n"),
+	      (uint64_t) (readp - (const unsigned char *) data->d_buf));
+
+      // Header, 2 byte version, 1 byte flag, optional .debug_line offset,
+      // optional vendor extension macro entry table.
+      if (readp + 2 > readendp)
+	{
+	invalid_data:
+	  error (0, 0, gettext ("invalid data"));
+	  return;
+	}
+      const uint16_t vers = read_2ubyte_unaligned_inc (dbg, readp);
+      printf (gettext (" Version:            %" PRIu16 "\n"), vers);
+
+      // Version 4 is the GNU extension for DWARF4.  DWARF5 will use version
+      // 5 when it gets standardized.
+      if (vers != 4 && vers != 5)
+	{
+	  printf (gettext ("  unknown version, cannot parse section\n"));
+	  return;
+	}
+
+      if (readp + 1 > readendp)
+	goto invalid_data;
+      const unsigned char flag = *readp++;
+      printf (gettext (" Flag:               0x%" PRIx8 "\n"), flag);
+
+      unsigned int offset_len = (flag & 0x01) ? 8 : 4;
+      printf (gettext (" Offset length:      %" PRIu8 "\n"), offset_len);
+      Dwarf_Off line_offset = -1;
+      if (flag & 0x02)
+	{
+	  if (offset_len == 8)
+	    line_offset = read_8ubyte_unaligned_inc (dbg, readp);
+	  else
+	    line_offset = read_4ubyte_unaligned_inc (dbg, readp);
+	  printf (gettext (" .debug_line offset: 0x%" PRIx64 "\n"),
+		  line_offset);
+	}
+
+      const unsigned char *vendor[DW_MACRO_hi_user - DW_MACRO_lo_user];
+      memset (vendor, 0, sizeof vendor);
+      if (flag & 0x04)
+	{
+	  // 1 byte length, for each item, 1 byte opcode, uleb128 number
+	  // of arguments, for each argument 1 byte form code.
+	  if (readp + 1 > readendp)
+	    goto invalid_data;
+	  unsigned int tlen = *readp++;
+	  printf (gettext ("  extension opcode table, %" PRIu8 " items:\n"),
+		  tlen);
+	  for (unsigned int i = 0; i < tlen; i++)
+	    {
+	      if (readp + 1 > readendp)
+		goto invalid_data;
+	      unsigned int opcode = *readp++;
+	      printf (gettext ("    [%" PRIx8 "]"), opcode);
+	      if (opcode < DW_MACRO_lo_user
+		  || opcode > DW_MACRO_hi_user)
+		goto invalid_data;
+	      // Record the start of description for this vendor opcode.
+	      // uleb128 nr args, 1 byte per arg form.
+	      vendor[opcode - DW_MACRO_lo_user] = readp;
+	      if (readp + 1 > readendp)
+		goto invalid_data;
+	      unsigned int args = *readp++;
+	      if (args > 0)
+		{
+		  printf (gettext (" %" PRIu8 " arguments:"), args);
+		  while (args > 0)
+		    {
+		      if (readp + 1 > readendp)
+			goto invalid_data;
+		      unsigned int form = *readp++;
+		      printf (" %s", dwarf_form_name (form));
+		      if (form != DW_FORM_data1
+			  && form != DW_FORM_data2
+			  && form != DW_FORM_data4
+			  && form != DW_FORM_data8
+			  && form != DW_FORM_sdata
+			  && form != DW_FORM_udata
+			  && form != DW_FORM_block
+			  && form != DW_FORM_block1
+			  && form != DW_FORM_block2
+			  && form != DW_FORM_block4
+			  && form != DW_FORM_flag
+			  && form != DW_FORM_string
+			  && form != DW_FORM_strp
+			  && form != DW_FORM_sec_offset)
+			goto invalid_data;
+		      args--;
+		      if (args > 0)
+			putchar_unlocked (',');
+		    }
+		}
+	      else
+		printf (gettext (" no arguments."));
+	      putchar_unlocked ('\n');
+	    }
+	}
+      putchar_unlocked ('\n');
+
+      int level = 1;
+      if (readp + 1 > readendp)
+	goto invalid_data;
+      unsigned int opcode = *readp++;
+      while (opcode != 0)
+	{
+	  unsigned int u128;
+	  unsigned int u128_2;
+	  const unsigned char *endp;
+	  uint64_t off;
+
+          switch (opcode)
+            {
+            case DW_MACRO_start_file:
+	      get_uleb128 (u128, readp, readendp);
+	      if (readp >= readendp)
+		goto invalid_data;
+	      get_uleb128 (u128_2, readp, readendp);
+
+	      /* Find the CU DIE that matches this line offset.  */
+	      const char *fname = "???";
+	      if (line_offset != (Dwarf_Off) -1)
+		{
+		  struct mac_culist *cu = culist;
+		  while (cu != NULL && line_offset != cu->offset)
+		    cu = cu->next;
+		  if (cu != NULL)
+		    {
+		      if (cu->files == NULL
+			  && dwarf_getsrcfiles (&cu->die, &cu->files,
+						NULL) != 0)
+			cu->files = (Dwarf_Files *) -1l;
+
+		      if (cu->files != (Dwarf_Files *) -1l)
+			fname = (dwarf_filesrc (cu->files, u128_2,
+						NULL, NULL) ?: "???");
+		    }
+		}
+	      printf ("%*sstart_file %u, [%u] %s\n",
+		      level, "", u128, u128_2, fname);
+	      ++level;
+	      break;
+
+	    case DW_MACRO_end_file:
+	      --level;
+	      printf ("%*send_file\n", level, "");
+	      break;
+
+	    case DW_MACRO_define:
+	      get_uleb128 (u128, readp, readendp);
+	      endp = memchr (readp, '\0', readendp - readp);
+	      if (endp == NULL)
+		goto invalid_data;
+	      printf ("%*s#define %s, line %u\n",
+		      level, "", readp, u128);
+	      readp = endp + 1;
+	      break;
+
+	    case DW_MACRO_undef:
+	      get_uleb128 (u128, readp, readendp);
+	      endp = memchr (readp, '\0', readendp - readp);
+	      if (endp == NULL)
+		goto invalid_data;
+	      printf ("%*s#undef %s, line %u\n",
+		      level, "", readp, u128);
+	      readp = endp + 1;
+	      break;
+
+	    case DW_MACRO_define_strp:
+	      get_uleb128 (u128, readp, readendp);
+	      if (readp + offset_len > readendp)
+		goto invalid_data;
+	      if (offset_len == 8)
+		off = read_8ubyte_unaligned_inc (dbg, readp);
+	      else
+		off = read_4ubyte_unaligned_inc (dbg, readp);
+	      printf ("%*s#define %s, line %u (indirect)\n",
+		      level, "", dwarf_getstring (dbg, off, NULL), u128);
+	      break;
+
+	    case DW_MACRO_undef_strp:
+	      get_uleb128 (u128, readp, readendp);
+	      if (readp + offset_len > readendp)
+		goto invalid_data;
+	      if (offset_len == 8)
+		off = read_8ubyte_unaligned_inc (dbg, readp);
+	      else
+		off = read_4ubyte_unaligned_inc (dbg, readp);
+	      printf ("%*s#undef %s, line %u (indirect)\n",
+		      level, "", dwarf_getstring (dbg, off, NULL), u128);
+	      break;
+
+	    case DW_MACRO_import:
+	      if (readp + offset_len > readendp)
+		goto invalid_data;
+	      if (offset_len == 8)
+		off = read_8ubyte_unaligned_inc (dbg, readp);
+	      else
+		off = read_4ubyte_unaligned_inc (dbg, readp);
+	      printf ("%*s#include offset 0x%" PRIx64 "\n",
+		      level, "", off);
+	      break;
+
+	    case DW_MACRO_define_sup:
+	      get_uleb128 (u128, readp, readendp);
+	      if (readp + offset_len > readendp)
+		goto invalid_data;
+	      if (offset_len == 8)
+		off = read_8ubyte_unaligned_inc (dbg, readp);
+	      else
+		off = read_4ubyte_unaligned_inc (dbg, readp);
+	      // Needs support for reading from supplementary object file.
+	      printf ("%*s#define <str-at-0x%" PRIx64 ">, line %u (sup)\n",
+		      level, "", off, u128);
+	      break;
+
+	    case DW_MACRO_undef_sup:
+	      get_uleb128 (u128, readp, readendp);
+	      if (readp + offset_len > readendp)
+		goto invalid_data;
+	      if (offset_len == 8)
+		off = read_8ubyte_unaligned_inc (dbg, readp);
+	      else
+		off = read_4ubyte_unaligned_inc (dbg, readp);
+	      // Needs support for reading from supplementary object file.
+	      printf ("%*s#undef <str-at-0x%" PRIx64 ">, line %u (sup)\n",
+		      level, "", off, u128);
+	      break;
+
+	    case DW_MACRO_import_sup:
+	      if (readp + offset_len > readendp)
+		goto invalid_data;
+	      if (offset_len == 8)
+		off = read_8ubyte_unaligned_inc (dbg, readp);
+	      else
+		off = read_4ubyte_unaligned_inc (dbg, readp);
+	      printf ("%*s#include offset 0x%" PRIx64 " (sup)\n",
+		      level, "", off);
+	      break;
+
+	    case DW_MACRO_define_strx:
+	      get_uleb128 (u128, readp, readendp);
+	      if (readp + offset_len > readendp)
+		goto invalid_data;
+	      if (offset_len == 8)
+		off = read_8ubyte_unaligned_inc (dbg, readp);
+	      else
+		off = read_4ubyte_unaligned_inc (dbg, readp);
+	      // Needs support for reading indirect string offset table
+	      printf ("%*s#define <str-at-0x%" PRIx64 ">, line %u (strx)\n",
+		      level, "", off, u128);
+	      break;
+
+	    case DW_MACRO_undef_strx:
+	      get_uleb128 (u128, readp, readendp);
+	      if (readp + offset_len > readendp)
+		goto invalid_data;
+	      if (offset_len == 8)
+		off = read_8ubyte_unaligned_inc (dbg, readp);
+	      else
+		off = read_4ubyte_unaligned_inc (dbg, readp);
+	      // Needs support for reading indirect string offset table.
+	      printf ("%*s#undef <str-at-0x%" PRIx64 ">, line %u (strx)\n",
+		      level, "", off, u128);
+	      break;
+
+	    default:
+	      printf ("%*svendor opcode 0x%" PRIx8, level, "", opcode);
+	      if (opcode < DW_MACRO_lo_user
+		  || opcode > DW_MACRO_lo_user
+		  || vendor[opcode - DW_MACRO_lo_user] == NULL)
+		goto invalid_data;
+
+	      const unsigned char *op_desc;
+	      op_desc = vendor[opcode - DW_MACRO_lo_user];
+
+	      // Just skip the arguments, we cannot really interpret them,
+	      // but print as much as we can.
+	      unsigned int args = *op_desc++;
+	      while (args > 0)
+		{
+		  unsigned int form = *op_desc++;
+		  Dwarf_Word val;
+		  switch (form)
+		    {
+		    case DW_FORM_data1:
+		      if (readp + 1 > readendp)
+			goto invalid_data;
+		      val = *readp++;
+		      printf (" %" PRIx8, (unsigned int) val);
+		      break;
+
+		    case DW_FORM_data2:
+		      if (readp + 2 > readendp)
+			goto invalid_data;
+		      val = read_2ubyte_unaligned_inc (dbg, readp);
+		      printf(" %" PRIx16, (unsigned int) val);
+		      break;
+
+		    case DW_FORM_data4:
+		      if (readp + 4 > readendp)
+			goto invalid_data;
+		      val = read_4ubyte_unaligned_inc (dbg, readp);
+		      printf (" %" PRIx32, (unsigned int) val);
+		      break;
+
+		    case DW_FORM_data8:
+		      if (readp + 8 > readendp)
+			goto invalid_data;
+		      val = read_8ubyte_unaligned_inc (dbg, readp);
+		      printf (" %" PRIx64, val);
+		      break;
+
+		    case DW_FORM_sdata:
+		      get_sleb128 (val, readp, readendp);
+		      printf (" %" PRIx64, val);
+		      break;
+
+		    case DW_FORM_udata:
+		      get_uleb128 (val, readp, readendp);
+		      printf (" %" PRIx64, val);
+		      break;
+
+		    case DW_FORM_block:
+		      get_uleb128 (val, readp, readendp);
+		      printf (" block[%" PRIu64 "]", val);
+		      if (readp + val > readendp)
+			goto invalid_data;
+		      readp += val;
+		      break;
+
+		    case DW_FORM_block1:
+		      if (readp + 1 > readendp)
+			goto invalid_data;
+		      val = *readp++;
+		      printf (" block[%" PRIu64 "]", val);
+		      if (readp + val > readendp)
+			goto invalid_data;
+		      break;
+
+		    case DW_FORM_block2:
+		      if (readp + 2 > readendp)
+			goto invalid_data;
+		      val = read_2ubyte_unaligned_inc (dbg, readp);
+		      printf (" block[%" PRIu64 "]", val);
+		      if (readp + val > readendp)
+			goto invalid_data;
+		      break;
+
+		    case DW_FORM_block4:
+		      if (readp + 2 > readendp)
+			goto invalid_data;
+		      val =read_4ubyte_unaligned_inc (dbg, readp);
+		      printf (" block[%" PRIu64 "]", val);
+		      if (readp + val > readendp)
+			goto invalid_data;
+		      break;
+
+		    case DW_FORM_flag:
+		      if (readp + 1 > readendp)
+			goto invalid_data;
+		      val = *readp++;
+		      printf (" %s", val != 0 ? gettext ("yes") : gettext ("no"));
+		      break;
+
+		    case DW_FORM_string:
+		      endp = memchr (readp, '\0', readendp - readp);
+		      if (endp == NULL)
+			goto invalid_data;
+		      printf (" %s", readp);
+		      readp = endp + 1;
+		      break;
+
+		    case DW_FORM_strp:
+		      if (readp + offset_len > readendp)
+			goto invalid_data;
+		      if (offset_len == 8)
+			val = read_8ubyte_unaligned_inc (dbg, readp);
+		      else
+			val = read_4ubyte_unaligned_inc (dbg, readp);
+		      printf (" %s", dwarf_getstring (dbg, val, NULL));
+		      break;
+
+		    case DW_FORM_sec_offset:
+		      if (readp + offset_len > readendp)
+			goto invalid_data;
+		      if (offset_len == 8)
+			val = read_8ubyte_unaligned_inc (dbg, readp);
+		      else
+			val = read_4ubyte_unaligned_inc (dbg, readp);
+		      printf (" %" PRIx64, val);
+		      break;
+
+		      default:
+			error (0, 0, gettext ("vendor opcode not verified?"));
+			return;
+		    }
+
+		  args--;
+		  if (args > 0)
+		    putchar_unlocked (',');
+		}
+	      putchar_unlocked ('\n');
+	    }
+
+	  if (readp + 1 > readendp)
+	    goto invalid_data;
+	  opcode = *readp++;
+	  if (opcode == 0)
+	    putchar_unlocked ('\n');
+	}
+    }
+}
+
+
+/* Callback for printing global names.  */
+static int
+print_pubnames (Dwarf *dbg __attribute__ ((unused)), Dwarf_Global *global,
+		void *arg)
+{
+  int *np = (int *) arg;
+
+  printf (gettext (" [%5d] DIE offset: %6" PRId64
+		   ", CU DIE offset: %6" PRId64 ", name: %s\n"),
+	  (*np)++, global->die_offset, global->cu_offset, global->name);
+
+  return 0;
+}
+
+
+/* Print the known exported symbols in the DWARF section '.debug_pubnames'.  */
+static void
+print_debug_pubnames_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
+			      Ebl *ebl, GElf_Ehdr *ehdr,
+			      Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset);
+
+  int n = 0;
+  (void) dwarf_getpubnames (dbg, print_pubnames, &n, 0);
+}
+
+/* Print the content of the DWARF string section '.debug_str'.  */
+static void
+print_debug_str_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
+			 Ebl *ebl, GElf_Ehdr *ehdr,
+			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  const size_t sh_size = (dbg->sectiondata[IDX_debug_str] ?
+			  dbg->sectiondata[IDX_debug_str]->d_size : 0);
+
+  /* Compute floor(log16(shdr->sh_size)).  */
+  GElf_Addr tmp = sh_size;
+  int digits = 1;
+  while (tmp >= 16)
+    {
+      ++digits;
+      tmp >>= 4;
+    }
+  digits = MAX (4, digits);
+
+  printf (gettext ("\nDWARF section [%2zu] '%s' at offset %#" PRIx64 ":\n"
+		   " %*s  String\n"),
+	  elf_ndxscn (scn),
+	  section_name (ebl, ehdr, shdr), (uint64_t) shdr->sh_offset,
+	  /* TRANS: the debugstr| prefix makes the string unique.  */
+	  digits + 2, sgettext ("debugstr|Offset"));
+
+  Dwarf_Off offset = 0;
+  while (offset < sh_size)
+    {
+      size_t len;
+      const char *str = dwarf_getstring (dbg, offset, &len);
+      if (unlikely (str == NULL))
+	{
+	  printf (gettext (" *** error while reading strings: %s\n"),
+		  dwarf_errmsg (-1));
+	  break;
+	}
+
+      printf (" [%*" PRIx64 "]  \"%s\"\n", digits, (uint64_t) offset, str);
+
+      offset += len + 1;
+    }
+}
+
+
+/* Print the content of the call frame search table section
+   '.eh_frame_hdr'.  */
+static void
+print_debug_frame_hdr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
+			       Ebl *ebl __attribute__ ((unused)),
+			       GElf_Ehdr *ehdr __attribute__ ((unused)),
+			       Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  printf (gettext ("\
+\nCall frame search table section [%2zu] '.eh_frame_hdr':\n"),
+	  elf_ndxscn (scn));
+
+  Elf_Data *data = elf_rawdata (scn, NULL);
+
+  if (unlikely (data == NULL))
+    {
+      error (0, 0, gettext ("cannot get %s content: %s"),
+	     ".eh_frame_hdr", elf_errmsg (-1));
+      return;
+    }
+
+  const unsigned char *readp = data->d_buf;
+  const unsigned char *const dataend = ((unsigned char *) data->d_buf
+					+ data->d_size);
+
+  if (unlikely (readp + 4 > dataend))
+    {
+    invalid_data:
+      error (0, 0, gettext ("invalid data"));
+      return;
+    }
+
+  unsigned int version = *readp++;
+  unsigned int eh_frame_ptr_enc = *readp++;
+  unsigned int fde_count_enc = *readp++;
+  unsigned int table_enc = *readp++;
+
+  printf (" version:          %u\n"
+	  " eh_frame_ptr_enc: %#x ",
+	  version, eh_frame_ptr_enc);
+  print_encoding_base ("", eh_frame_ptr_enc);
+  printf (" fde_count_enc:    %#x ", fde_count_enc);
+  print_encoding_base ("", fde_count_enc);
+  printf (" table_enc:        %#x ", table_enc);
+  print_encoding_base ("", table_enc);
+
+  uint64_t eh_frame_ptr = 0;
+  if (eh_frame_ptr_enc != DW_EH_PE_omit)
+    {
+      readp = read_encoded (eh_frame_ptr_enc, readp, dataend, &eh_frame_ptr,
+			    dbg);
+      if (unlikely (readp == NULL))
+	goto invalid_data;
+
+      printf (" eh_frame_ptr:     %#" PRIx64, eh_frame_ptr);
+      if ((eh_frame_ptr_enc & 0x70) == DW_EH_PE_pcrel)
+	printf (" (offset: %#" PRIx64 ")",
+		/* +4 because of the 4 byte header of the section.  */
+		(uint64_t) shdr->sh_offset + 4 + eh_frame_ptr);
+
+      putchar_unlocked ('\n');
+    }
+
+  uint64_t fde_count = 0;
+  if (fde_count_enc != DW_EH_PE_omit)
+    {
+      readp = read_encoded (fde_count_enc, readp, dataend, &fde_count, dbg);
+      if (unlikely (readp == NULL))
+	goto invalid_data;
+
+      printf (" fde_count:        %" PRIu64 "\n", fde_count);
+    }
+
+  if (fde_count == 0 || table_enc == DW_EH_PE_omit)
+    return;
+
+  puts (" Table:");
+
+  /* Optimize for the most common case.  */
+  if (table_enc == (DW_EH_PE_datarel | DW_EH_PE_sdata4))
+    while (fde_count > 0 && readp + 8 <= dataend)
+      {
+	int32_t initial_location = read_4sbyte_unaligned_inc (dbg, readp);
+	uint64_t initial_offset = ((uint64_t) shdr->sh_offset
+				   + (int64_t) initial_location);
+	int32_t address = read_4sbyte_unaligned_inc (dbg, readp);
+	// XXX Possibly print symbol name or section offset for initial_offset
+	printf ("  %#" PRIx32 " (offset: %#6" PRIx64 ") -> %#" PRIx32
+		" fde=[%6" PRIx64 "]\n",
+		initial_location, initial_offset,
+		address, address - (eh_frame_ptr + 4));
+      }
+  else
+    while (0 && readp < dataend)
+      {
+
+      }
+}
+
+
+/* Print the content of the exception handling table section
+   '.eh_frame_hdr'.  */
+static void
+print_debug_exception_table (Dwfl_Module *dwflmod __attribute__ ((unused)),
+			     Ebl *ebl __attribute__ ((unused)),
+			     GElf_Ehdr *ehdr __attribute__ ((unused)),
+			     Elf_Scn *scn,
+			     GElf_Shdr *shdr __attribute__ ((unused)),
+			     Dwarf *dbg __attribute__ ((unused)))
+{
+  printf (gettext ("\
+\nException handling table section [%2zu] '.gcc_except_table':\n"),
+	  elf_ndxscn (scn));
+
+  Elf_Data *data = elf_rawdata (scn, NULL);
+
+  if (unlikely (data == NULL))
+    {
+      error (0, 0, gettext ("cannot get %s content: %s"),
+	     ".gcc_except_table", elf_errmsg (-1));
+      return;
+    }
+
+  const unsigned char *readp = data->d_buf;
+  const unsigned char *const dataend = readp + data->d_size;
+
+  if (unlikely (readp + 1 > dataend))
+    {
+    invalid_data:
+      error (0, 0, gettext ("invalid data"));
+      return;
+    }
+  unsigned int lpstart_encoding = *readp++;
+  printf (gettext (" LPStart encoding:    %#x "), lpstart_encoding);
+  print_encoding_base ("", lpstart_encoding);
+  if (lpstart_encoding != DW_EH_PE_omit)
+    {
+      uint64_t lpstart;
+      readp = read_encoded (lpstart_encoding, readp, dataend, &lpstart, dbg);
+      printf (" LPStart:             %#" PRIx64 "\n", lpstart);
+    }
+
+  if (unlikely (readp + 1 > dataend))
+    goto invalid_data;
+  unsigned int ttype_encoding = *readp++;
+  printf (gettext (" TType encoding:      %#x "), ttype_encoding);
+  print_encoding_base ("", ttype_encoding);
+  const unsigned char *ttype_base = NULL;
+  if (ttype_encoding != DW_EH_PE_omit)
+    {
+      unsigned int ttype_base_offset;
+      get_uleb128 (ttype_base_offset, readp, dataend);
+      printf (" TType base offset:   %#x\n", ttype_base_offset);
+      if ((size_t) (dataend - readp) > ttype_base_offset)
+        ttype_base = readp + ttype_base_offset;
+    }
+
+  if (unlikely (readp + 1 > dataend))
+    goto invalid_data;
+  unsigned int call_site_encoding = *readp++;
+  printf (gettext (" Call site encoding:  %#x "), call_site_encoding);
+  print_encoding_base ("", call_site_encoding);
+  unsigned int call_site_table_len;
+  get_uleb128 (call_site_table_len, readp, dataend);
+
+  const unsigned char *const action_table = readp + call_site_table_len;
+  if (unlikely (action_table > dataend))
+    goto invalid_data;
+  unsigned int u = 0;
+  unsigned int max_action = 0;
+  while (readp < action_table)
+    {
+      if (u == 0)
+	puts (gettext ("\n Call site table:"));
+
+      uint64_t call_site_start;
+      readp = read_encoded (call_site_encoding, readp, dataend,
+			    &call_site_start, dbg);
+      uint64_t call_site_length;
+      readp = read_encoded (call_site_encoding, readp, dataend,
+			    &call_site_length, dbg);
+      uint64_t landing_pad;
+      readp = read_encoded (call_site_encoding, readp, dataend,
+			    &landing_pad, dbg);
+      unsigned int action;
+      get_uleb128 (action, readp, dataend);
+      max_action = MAX (action, max_action);
+      printf (gettext (" [%4u] Call site start:   %#" PRIx64 "\n"
+		       "        Call site length:  %" PRIu64 "\n"
+		       "        Landing pad:       %#" PRIx64 "\n"
+		       "        Action:            %u\n"),
+	      u++, call_site_start, call_site_length, landing_pad, action);
+    }
+  if (readp != action_table)
+    goto invalid_data;
+
+  unsigned int max_ar_filter = 0;
+  if (max_action > 0)
+    {
+      puts ("\n Action table:");
+
+      size_t maxdata = (size_t) (dataend - action_table);
+      if (max_action > maxdata || maxdata - max_action < 1)
+	{
+	invalid_action_table:
+	  fputs (gettext ("   <INVALID DATA>\n"), stdout);
+	  return;
+	}
+
+      const unsigned char *const action_table_end
+	= action_table + max_action + 1;
+
+      u = 0;
+      do
+	{
+	  int ar_filter;
+	  get_sleb128 (ar_filter, readp, action_table_end);
+	  if (ar_filter > 0 && (unsigned int) ar_filter > max_ar_filter)
+	    max_ar_filter = ar_filter;
+	  int ar_disp;
+	  if (readp >= action_table_end)
+	    goto invalid_action_table;
+	  get_sleb128 (ar_disp, readp, action_table_end);
+
+	  printf (" [%4u] ar_filter:  % d\n"
+		  "        ar_disp:    % -5d",
+		  u, ar_filter, ar_disp);
+	  if (abs (ar_disp) & 1)
+	    printf (" -> [%4u]\n", u + (ar_disp + 1) / 2);
+	  else if (ar_disp != 0)
+	    puts (" -> ???");
+	  else
+	    putchar_unlocked ('\n');
+	  ++u;
+	}
+      while (readp < action_table_end);
+    }
+
+  if (max_ar_filter > 0 && ttype_base != NULL)
+    {
+      unsigned char dsize;
+      puts ("\n TType table:");
+
+      // XXX Not *4, size of encoding;
+      switch (ttype_encoding & 7)
+	{
+	case DW_EH_PE_udata2:
+	case DW_EH_PE_sdata2:
+	  dsize = 2;
+	  break;
+	case DW_EH_PE_udata4:
+	case DW_EH_PE_sdata4:
+	  dsize = 4;
+	  break;
+	case DW_EH_PE_udata8:
+	case DW_EH_PE_sdata8:
+	  dsize = 8;
+	  break;
+	default:
+	  dsize = 0;
+	  error (1, 0, gettext ("invalid TType encoding"));
+	}
+
+      if (max_ar_filter
+	  > (size_t) (ttype_base - (const unsigned char *) data->d_buf) / dsize)
+	goto invalid_data;
+
+      readp = ttype_base - max_ar_filter * dsize;
+      do
+	{
+	  uint64_t ttype;
+	  readp = read_encoded (ttype_encoding, readp, ttype_base, &ttype,
+				dbg);
+	  printf (" [%4u] %#" PRIx64 "\n", max_ar_filter--, ttype);
+	}
+      while (readp < ttype_base);
+    }
+}
+
+/* Print the content of the '.gdb_index' section.
+   http://sourceware.org/gdb/current/onlinedocs/gdb/Index-Section-Format.html
+*/
+static void
+print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
+			 Elf_Scn *scn, GElf_Shdr *shdr, Dwarf *dbg)
+{
+  printf (gettext ("\nGDB section [%2zu] '%s' at offset %#" PRIx64
+		   " contains %" PRId64 " bytes :\n"),
+	  elf_ndxscn (scn), section_name (ebl, ehdr, shdr),
+	  (uint64_t) shdr->sh_offset, (uint64_t) shdr->sh_size);
+
+  Elf_Data *data = elf_rawdata (scn, NULL);
+
+  if (unlikely (data == NULL))
+    {
+      error (0, 0, gettext ("cannot get %s content: %s"),
+	     ".gdb_index", elf_errmsg (-1));
+      return;
+    }
+
+  // .gdb_index is always in little endian.
+  Dwarf dummy_dbg = { .other_byte_order = MY_ELFDATA != ELFDATA2LSB };
+  dbg = &dummy_dbg;
+
+  const unsigned char *readp = data->d_buf;
+  const unsigned char *const dataend = readp + data->d_size;
+
+  if (unlikely (readp + 4 > dataend))
+    {
+    invalid_data:
+      error (0, 0, gettext ("invalid data"));
+      return;
+    }
+
+  int32_t vers = read_4ubyte_unaligned (dbg, readp);
+  printf (gettext (" Version:         %" PRId32 "\n"), vers);
+
+  // The only difference between version 4 and version 5 is the
+  // hash used for generating the table.  Version 6 contains symbols
+  // for inlined functions, older versions didn't.  Version 7 adds
+  // symbol kinds.  Version 8 just indicates that it correctly includes
+  // TUs for symbols.
+  if (vers < 4 || vers > 8)
+    {
+      printf (gettext ("  unknown version, cannot parse section\n"));
+      return;
+    }
+
+  readp += 4;
+  if (unlikely (readp + 4 > dataend))
+    goto invalid_data;
+
+  uint32_t cu_off = read_4ubyte_unaligned (dbg, readp);
+  printf (gettext (" CU offset:       %#" PRIx32 "\n"), cu_off);
+
+  readp += 4;
+  if (unlikely (readp + 4 > dataend))
+    goto invalid_data;
+
+  uint32_t tu_off = read_4ubyte_unaligned (dbg, readp);
+  printf (gettext (" TU offset:       %#" PRIx32 "\n"), tu_off);
+
+  readp += 4;
+  if (unlikely (readp + 4 > dataend))
+    goto invalid_data;
+
+  uint32_t addr_off = read_4ubyte_unaligned (dbg, readp);
+  printf (gettext (" address offset:  %#" PRIx32 "\n"), addr_off);
+
+  readp += 4;
+  if (unlikely (readp + 4 > dataend))
+    goto invalid_data;
+
+  uint32_t sym_off = read_4ubyte_unaligned (dbg, readp);
+  printf (gettext (" symbol offset:   %#" PRIx32 "\n"), sym_off);
+
+  readp += 4;
+  if (unlikely (readp + 4 > dataend))
+    goto invalid_data;
+
+  uint32_t const_off = read_4ubyte_unaligned (dbg, readp);
+  printf (gettext (" constant offset: %#" PRIx32 "\n"), const_off);
+
+  if (unlikely ((size_t) (dataend - (const unsigned char *) data->d_buf)
+		< const_off))
+    goto invalid_data;
+
+  readp = data->d_buf + cu_off;
+
+  const unsigned char *nextp = data->d_buf + tu_off;
+  if (tu_off >= data->d_size)
+    goto invalid_data;
+
+  size_t cu_nr = (nextp - readp) / 16;
+
+  printf (gettext ("\n CU list at offset %#" PRIx32
+		   " contains %zu entries:\n"),
+	  cu_off, cu_nr);
+
+  size_t n = 0;
+  while (dataend - readp >= 16 && n < cu_nr)
+    {
+      uint64_t off = read_8ubyte_unaligned (dbg, readp);
+      readp += 8;
+
+      uint64_t len = read_8ubyte_unaligned (dbg, readp);
+      readp += 8;
+
+      printf (" [%4zu] start: %0#8" PRIx64
+	      ", length: %5" PRIu64 "\n", n, off, len);
+      n++;
+    }
+
+  readp = data->d_buf + tu_off;
+  nextp = data->d_buf + addr_off;
+  if (addr_off >= data->d_size)
+    goto invalid_data;
+
+  size_t tu_nr = (nextp - readp) / 24;
+
+  printf (gettext ("\n TU list at offset %#" PRIx32
+		   " contains %zu entries:\n"),
+	  tu_off, tu_nr);
+
+  n = 0;
+  while (dataend - readp >= 24 && n < tu_nr)
+    {
+      uint64_t off = read_8ubyte_unaligned (dbg, readp);
+      readp += 8;
+
+      uint64_t type = read_8ubyte_unaligned (dbg, readp);
+      readp += 8;
+
+      uint64_t sig = read_8ubyte_unaligned (dbg, readp);
+      readp += 8;
+
+      printf (" [%4zu] CU offset: %5" PRId64
+	      ", type offset: %5" PRId64
+	      ", signature: %0#8" PRIx64 "\n", n, off, type, sig);
+      n++;
+    }
+
+  readp = data->d_buf + addr_off;
+  nextp = data->d_buf + sym_off;
+  if (sym_off >= data->d_size)
+    goto invalid_data;
+
+  size_t addr_nr = (nextp - readp) / 20;
+
+  printf (gettext ("\n Address list at offset %#" PRIx32
+		   " contains %zu entries:\n"),
+	  addr_off, addr_nr);
+
+  n = 0;
+  while (dataend - readp >= 20 && n < addr_nr)
+    {
+      uint64_t low = read_8ubyte_unaligned (dbg, readp);
+      readp += 8;
+
+      uint64_t high = read_8ubyte_unaligned (dbg, readp);
+      readp += 8;
+
+      uint32_t idx = read_4ubyte_unaligned (dbg, readp);
+      readp += 4;
+
+      char *l = format_dwarf_addr (dwflmod, 8, low, low);
+      char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
+      printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
+	      n, l, h, idx);
+      free (l);
+      free (h);
+      n++;
+    }
+
+  const unsigned char *const_start = data->d_buf + const_off;
+  if (const_off >= data->d_size)
+    goto invalid_data;
+
+  readp = data->d_buf + sym_off;
+  nextp = const_start;
+  size_t sym_nr = (nextp - readp) / 8;
+
+  printf (gettext ("\n Symbol table at offset %#" PRIx32
+		   " contains %zu slots:\n"),
+	  addr_off, sym_nr);
+
+  n = 0;
+  while (dataend - readp >= 8 && n < sym_nr)
+    {
+      uint32_t name = read_4ubyte_unaligned (dbg, readp);
+      readp += 4;
+
+      uint32_t vector = read_4ubyte_unaligned (dbg, readp);
+      readp += 4;
+
+      if (name != 0 || vector != 0)
+	{
+	  const unsigned char *sym = const_start + name;
+	  if (unlikely ((size_t) (dataend - const_start) < name
+			|| memchr (sym, '\0', dataend - sym) == NULL))
+	    goto invalid_data;
+
+	  printf (" [%4zu] symbol: %s, CUs: ", n, sym);
+
+	  const unsigned char *readcus = const_start + vector;
+	  if (unlikely ((size_t) (dataend - const_start) < vector))
+	    goto invalid_data;
+	  uint32_t cus = read_4ubyte_unaligned (dbg, readcus);
+	  while (cus--)
+	    {
+	      uint32_t cu_kind, cu, kind;
+	      bool is_static;
+	      readcus += 4;
+	      if (unlikely (readcus + 4 > dataend))
+		goto invalid_data;
+	      cu_kind = read_4ubyte_unaligned (dbg, readcus);
+	      cu = cu_kind & ((1 << 24) - 1);
+	      kind = (cu_kind >> 28) & 7;
+	      is_static = cu_kind & (1U << 31);
+	      if (cu > cu_nr - 1)
+		printf ("%" PRId32 "T", cu - (uint32_t) cu_nr);
+	      else
+		printf ("%" PRId32, cu);
+	      if (kind != 0)
+		{
+		  printf (" (");
+		  switch (kind)
+		    {
+		    case 1:
+		      printf ("type");
+		      break;
+		    case 2:
+		      printf ("var");
+		      break;
+		    case 3:
+		      printf ("func");
+		      break;
+		    case 4:
+		      printf ("other");
+		      break;
+		    default:
+		      printf ("unknown-0x%" PRIx32, kind);
+		      break;
+		    }
+		  printf (":%c)", (is_static ? 'S' : 'G'));
+		}
+	      if (cus > 0)
+		printf (", ");
+	    }
+	  printf ("\n");
+	}
+      n++;
+    }
+}
+
+static void
+print_debug (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr)
+{
+  /* Before we start the real work get a debug context descriptor.  */
+  Dwarf_Addr dwbias;
+  Dwarf *dbg = dwfl_module_getdwarf (dwflmod, &dwbias);
+  Dwarf dummy_dbg =
+    {
+      .elf = ebl->elf,
+      .other_byte_order = MY_ELFDATA != ehdr->e_ident[EI_DATA]
+    };
+  if (dbg == NULL)
+    {
+      if ((print_debug_sections & ~section_exception) != 0)
+	error (0, 0, gettext ("cannot get debug context descriptor: %s"),
+	       dwfl_errmsg (-1));
+      dbg = &dummy_dbg;
+    }
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  /* Look through all the sections for the debugging sections to print.  */
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr != NULL && shdr->sh_type == SHT_PROGBITS)
+	{
+	  static const struct
+	  {
+	    const char *name;
+	    enum section_e bitmask;
+	    void (*fp) (Dwfl_Module *, Ebl *,
+			GElf_Ehdr *, Elf_Scn *, GElf_Shdr *, Dwarf *);
+	  } debug_sections[] =
+	    {
+#define NEW_SECTION(name) \
+	      { ".debug_" #name, section_##name, print_debug_##name##_section }
+	      NEW_SECTION (abbrev),
+	      NEW_SECTION (aranges),
+	      NEW_SECTION (frame),
+	      NEW_SECTION (info),
+	      NEW_SECTION (types),
+	      NEW_SECTION (line),
+	      NEW_SECTION (loc),
+	      NEW_SECTION (pubnames),
+	      NEW_SECTION (str),
+	      NEW_SECTION (macinfo),
+	      NEW_SECTION (macro),
+	      NEW_SECTION (ranges),
+	      { ".eh_frame", section_frame | section_exception,
+		print_debug_frame_section },
+	      { ".eh_frame_hdr", section_frame | section_exception,
+		print_debug_frame_hdr_section },
+	      { ".gcc_except_table", section_frame | section_exception,
+		print_debug_exception_table },
+	      { ".gdb_index", section_gdb_index, print_gdb_index_section }
+	    };
+	  const int ndebug_sections = (sizeof (debug_sections)
+				       / sizeof (debug_sections[0]));
+	  const char *name = elf_strptr (ebl->elf, shstrndx,
+					 shdr->sh_name);
+	  if (name == NULL)
+	    continue;
+
+	  int n;
+	  for (n = 0; n < ndebug_sections; ++n)
+	    if (strcmp (name, debug_sections[n].name) == 0
+		|| (name[0] == '.' && name[1] == 'z'
+		    && debug_sections[n].name[1] == 'd'
+		    && strcmp (&name[2], &debug_sections[n].name[1]) == 0)
+		)
+	      {
+		if ((print_debug_sections | implicit_debug_sections)
+		    & debug_sections[n].bitmask)
+		  debug_sections[n].fp (dwflmod, ebl, ehdr, scn, shdr, dbg);
+		break;
+	      }
+	}
+    }
+
+  reset_listptr (&known_loclistptr);
+  reset_listptr (&known_rangelistptr);
+}
+
+
+#define ITEM_INDENT		4
+#define WRAP_COLUMN		75
+
+/* Print "NAME: FORMAT", wrapping when output text would make the line
+   exceed WRAP_COLUMN.  Unpadded numbers look better for the core items
+   but this function is also used for registers which should be printed
+   aligned.  Fortunately registers output uses fixed fields width (such
+   as %11d) for the alignment.
+
+   Line breaks should not depend on the particular values although that
+   may happen in some cases of the core items.  */
+
+static unsigned int
+__attribute__ ((format (printf, 6, 7)))
+print_core_item (unsigned int colno, char sep, unsigned int wrap,
+		 size_t name_width, const char *name, const char *format, ...)
+{
+  size_t len = strlen (name);
+  if (name_width < len)
+    name_width = len;
+
+  char *out;
+  va_list ap;
+  va_start (ap, format);
+  int out_len = vasprintf (&out, format, ap);
+  va_end (ap);
+  if (out_len == -1)
+    error (EXIT_FAILURE, 0, _("memory exhausted"));
+
+  size_t n = name_width + sizeof ": " - 1 + out_len;
+
+  if (colno == 0)
+    {
+      printf ("%*s", ITEM_INDENT, "");
+      colno = ITEM_INDENT + n;
+    }
+  else if (colno + 2 + n < wrap)
+    {
+      printf ("%c ", sep);
+      colno += 2 + n;
+    }
+  else
+    {
+      printf ("\n%*s", ITEM_INDENT, "");
+      colno = ITEM_INDENT + n;
+    }
+
+  printf ("%s: %*s%s", name, (int) (name_width - len), "", out);
+
+  free (out);
+
+  return colno;
+}
+
+static const void *
+convert (Elf *core, Elf_Type type, uint_fast16_t count,
+	 void *value, const void *data, size_t size)
+{
+  Elf_Data valuedata =
+    {
+      .d_type = type,
+      .d_buf = value,
+      .d_size = size ?: gelf_fsize (core, type, count, EV_CURRENT),
+      .d_version = EV_CURRENT,
+    };
+  Elf_Data indata =
+    {
+      .d_type = type,
+      .d_buf = (void *) data,
+      .d_size = valuedata.d_size,
+      .d_version = EV_CURRENT,
+    };
+
+  Elf_Data *d = (gelf_getclass (core) == ELFCLASS32
+		 ? elf32_xlatetom : elf64_xlatetom)
+    (&valuedata, &indata, elf_getident (core, NULL)[EI_DATA]);
+  if (d == NULL)
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
+
+  return data + indata.d_size;
+}
+
+typedef uint8_t GElf_Byte;
+
+static unsigned int
+handle_core_item (Elf *core, const Ebl_Core_Item *item, const void *desc,
+		  unsigned int colno, size_t *repeated_size)
+{
+  uint_fast16_t count = item->count ?: 1;
+  /* Ebl_Core_Item count is always a small number.
+     Make sure the backend didn't put in some large bogus value.  */
+  assert (count < 128);
+
+#define TYPES								      \
+  DO_TYPE (BYTE, Byte, "0x%.2" PRIx8, "%" PRId8);			      \
+  DO_TYPE (HALF, Half, "0x%.4" PRIx16, "%" PRId16);			      \
+  DO_TYPE (WORD, Word, "0x%.8" PRIx32, "%" PRId32);			      \
+  DO_TYPE (SWORD, Sword, "%" PRId32, "%" PRId32);			      \
+  DO_TYPE (XWORD, Xword, "0x%.16" PRIx64, "%" PRId64);			      \
+  DO_TYPE (SXWORD, Sxword, "%" PRId64, "%" PRId64)
+
+#define DO_TYPE(NAME, Name, hex, dec) GElf_##Name Name
+  typedef union { TYPES; } value_t;
+  void *data = alloca (count * sizeof (value_t));
+#undef DO_TYPE
+
+#define DO_TYPE(NAME, Name, hex, dec) \
+    GElf_##Name *value_##Name __attribute__((unused)) = data
+  TYPES;
+#undef DO_TYPE
+
+  size_t size = gelf_fsize (core, item->type, count, EV_CURRENT);
+  size_t convsize = size;
+  if (repeated_size != NULL)
+    {
+      if (*repeated_size > size && (item->format == 'b' || item->format == 'B'))
+	{
+	  data = alloca (*repeated_size);
+	  count *= *repeated_size / size;
+	  convsize = count * size;
+	  *repeated_size -= convsize;
+	}
+      else if (item->count != 0 || item->format != '\n')
+	*repeated_size -= size;
+    }
+
+  convert (core, item->type, count, data, desc + item->offset, convsize);
+
+  Elf_Type type = item->type;
+  if (type == ELF_T_ADDR)
+    type = gelf_getclass (core) == ELFCLASS32 ? ELF_T_WORD : ELF_T_XWORD;
+
+  switch (item->format)
+    {
+    case 'd':
+      assert (count == 1);
+      switch (type)
+	{
+#define DO_TYPE(NAME, Name, hex, dec)					      \
+	  case ELF_T_##NAME:						      \
+	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
+				     0, item->name, dec, value_##Name[0]); \
+	    break
+	  TYPES;
+#undef DO_TYPE
+	default:
+	  abort ();
+	}
+      break;
+
+    case 'x':
+      assert (count == 1);
+      switch (type)
+	{
+#define DO_TYPE(NAME, Name, hex, dec)					      \
+	  case ELF_T_##NAME:						      \
+	    colno = print_core_item (colno, ',', WRAP_COLUMN,		      \
+				     0, item->name, hex, value_##Name[0]);      \
+	    break
+	  TYPES;
+#undef DO_TYPE
+	default:
+	  abort ();
+	}
+      break;
+
+    case 'b':
+    case 'B':
+      assert (size % sizeof (unsigned int) == 0);
+      unsigned int nbits = count * size * 8;
+      unsigned int pop = 0;
+      for (const unsigned int *i = data; (void *) i < data + count * size; ++i)
+	pop += __builtin_popcount (*i);
+      bool negate = pop > nbits / 2;
+      const unsigned int bias = item->format == 'b';
+
+      {
+	char printed[(negate ? nbits - pop : pop) * 16 + 1];
+	char *p = printed;
+	*p = '\0';
+
+	if (BYTE_ORDER != LITTLE_ENDIAN && size > sizeof (unsigned int))
+	  {
+	    assert (size == sizeof (unsigned int) * 2);
+	    for (unsigned int *i = data;
+		 (void *) i < data + count * size; i += 2)
+	      {
+		unsigned int w = i[1];
+		i[1] = i[0];
+		i[0] = w;
+	      }
+	  }
+
+	unsigned int lastbit = 0;
+	unsigned int run = 0;
+	for (const unsigned int *i = data;
+	     (void *) i < data + count * size; ++i)
+	  {
+	    unsigned int bit = ((void *) i - data) * 8;
+	    unsigned int w = negate ? ~*i : *i;
+	    while (w != 0)
+	      {
+		/* Note that a right shift equal to (or greater than)
+		   the number of bits of w is undefined behaviour.  In
+		   particular when the least significant bit is bit 32
+		   (w = 0x8000000) then w >>= n is undefined.  So
+		   explicitly handle that case separately.  */
+		unsigned int n = ffs (w);
+		if (n < sizeof (w) * 8)
+		  w >>= n;
+		else
+		  w = 0;
+		bit += n;
+
+		if (lastbit != 0 && lastbit + 1 == bit)
+		  ++run;
+		else
+		  {
+		    if (lastbit == 0)
+		      p += sprintf (p, "%u", bit - bias);
+		    else if (run == 0)
+		      p += sprintf (p, ",%u", bit - bias);
+		    else
+		      p += sprintf (p, "-%u,%u", lastbit - bias, bit - bias);
+		    run = 0;
+		  }
+
+		lastbit = bit;
+	      }
+	  }
+	if (lastbit > 0 && run > 0 && lastbit + 1 != nbits)
+	  p += sprintf (p, "-%u", lastbit - bias);
+
+	colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
+				 negate ? "~<%s>" : "<%s>", printed);
+      }
+      break;
+
+    case 'T':
+    case (char) ('T'|0x80):
+      assert (count == 2);
+      Dwarf_Word sec;
+      Dwarf_Word usec;
+      switch (type)
+	{
+#define DO_TYPE(NAME, Name, hex, dec)					      \
+	  case ELF_T_##NAME:						      \
+	    sec = value_##Name[0];					      \
+	    usec = value_##Name[1];					      \
+	    break
+	  TYPES;
+#undef DO_TYPE
+	default:
+	  abort ();
+	}
+      if (unlikely (item->format == (char) ('T'|0x80)))
+	{
+	  /* This is a hack for an ill-considered 64-bit ABI where
+	     tv_usec is actually a 32-bit field with 32 bits of padding
+	     rounding out struct timeval.  We've already converted it as
+	     a 64-bit field.  For little-endian, this just means the
+	     high half is the padding; it's presumably zero, but should
+	     be ignored anyway.  For big-endian, it means the 32-bit
+	     field went into the high half of USEC.  */
+	  GElf_Ehdr ehdr_mem;
+	  GElf_Ehdr *ehdr = gelf_getehdr (core, &ehdr_mem);
+	  if (likely (ehdr->e_ident[EI_DATA] == ELFDATA2MSB))
+	    usec >>= 32;
+	  else
+	    usec &= UINT32_MAX;
+	}
+      colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
+			       "%" PRIu64 ".%.6" PRIu64, sec, usec);
+      break;
+
+    case 'c':
+      assert (count == 1);
+      colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
+			       "%c", value_Byte[0]);
+      break;
+
+    case 's':
+      colno = print_core_item (colno, ',', WRAP_COLUMN, 0, item->name,
+			       "%.*s", (int) count, value_Byte);
+      break;
+
+    case '\n':
+      /* This is a list of strings separated by '\n'.  */
+      assert (item->count == 0);
+      assert (repeated_size != NULL);
+      assert (item->name == NULL);
+      if (unlikely (item->offset >= *repeated_size))
+	break;
+
+      const char *s = desc + item->offset;
+      size = *repeated_size - item->offset;
+      *repeated_size = 0;
+      while (size > 0)
+	{
+	  const char *eol = memchr (s, '\n', size);
+	  int len = size;
+	  if (eol != NULL)
+	    len = eol - s;
+	  printf ("%*s%.*s\n", ITEM_INDENT, "", len, s);
+	  if (eol == NULL)
+	    break;
+	  size -= eol + 1 - s;
+	  s = eol + 1;
+	}
+
+      colno = WRAP_COLUMN;
+      break;
+
+    case 'h':
+      break;
+
+    default:
+      error (0, 0, "XXX not handling format '%c' for %s",
+	     item->format, item->name);
+      break;
+    }
+
+#undef TYPES
+
+  return colno;
+}
+
+
+/* Sort items by group, and by layout offset within each group.  */
+static int
+compare_core_items (const void *a, const void *b)
+{
+  const Ebl_Core_Item *const *p1 = a;
+  const Ebl_Core_Item *const *p2 = b;
+  const Ebl_Core_Item *item1 = *p1;
+  const Ebl_Core_Item *item2 = *p2;
+
+  return ((item1->group == item2->group ? 0
+	   : strcmp (item1->group, item2->group))
+	  ?: (int) item1->offset - (int) item2->offset);
+}
+
+/* Sort item groups by layout offset of the first item in the group.  */
+static int
+compare_core_item_groups (const void *a, const void *b)
+{
+  const Ebl_Core_Item *const *const *p1 = a;
+  const Ebl_Core_Item *const *const *p2 = b;
+  const Ebl_Core_Item *const *group1 = *p1;
+  const Ebl_Core_Item *const *group2 = *p2;
+  const Ebl_Core_Item *item1 = *group1;
+  const Ebl_Core_Item *item2 = *group2;
+
+  return (int) item1->offset - (int) item2->offset;
+}
+
+static unsigned int
+handle_core_items (Elf *core, const void *desc, size_t descsz,
+		   const Ebl_Core_Item *items, size_t nitems)
+{
+  if (nitems == 0)
+    return 0;
+  unsigned int colno = 0;
+
+  /* FORMAT '\n' makes sense to be present only as a single item as it
+     processes all the data of a note.  FORMATs 'b' and 'B' have a special case
+     if present as a single item but they can be also processed with other
+     items below.  */
+  if (nitems == 1 && (items[0].format == '\n' || items[0].format == 'b'
+		      || items[0].format == 'B'))
+    {
+      assert (items[0].offset == 0);
+      size_t size = descsz;
+      colno = handle_core_item (core, items, desc, colno, &size);
+      /* If SIZE is not zero here there is some remaining data.  But we do not
+	 know how to process it anyway.  */
+      return colno;
+    }
+  for (size_t i = 0; i < nitems; ++i)
+    assert (items[i].format != '\n');
+
+  /* Sort to collect the groups together.  */
+  const Ebl_Core_Item *sorted_items[nitems];
+  for (size_t i = 0; i < nitems; ++i)
+    sorted_items[i] = &items[i];
+  qsort (sorted_items, nitems, sizeof sorted_items[0], &compare_core_items);
+
+  /* Collect the unique groups and sort them.  */
+  const Ebl_Core_Item **groups[nitems];
+  groups[0] = &sorted_items[0];
+  size_t ngroups = 1;
+  for (size_t i = 1; i < nitems; ++i)
+    if (sorted_items[i]->group != sorted_items[i - 1]->group
+	&& strcmp (sorted_items[i]->group, sorted_items[i - 1]->group))
+      groups[ngroups++] = &sorted_items[i];
+  qsort (groups, ngroups, sizeof groups[0], &compare_core_item_groups);
+
+  /* Write out all the groups.  */
+  const void *last = desc;
+  do
+    {
+      for (size_t i = 0; i < ngroups; ++i)
+	{
+	  for (const Ebl_Core_Item **item = groups[i];
+	       (item < &sorted_items[nitems]
+		&& ((*item)->group == groups[i][0]->group
+		    || !strcmp ((*item)->group, groups[i][0]->group)));
+	       ++item)
+	    colno = handle_core_item (core, *item, desc, colno, NULL);
+
+	  /* Force a line break at the end of the group.  */
+	  colno = WRAP_COLUMN;
+	}
+
+      if (descsz == 0)
+	break;
+
+      /* This set of items consumed a certain amount of the note's data.
+	 If there is more data there, we have another unit of the same size.
+	 Loop to print that out too.  */
+      const Ebl_Core_Item *item = &items[nitems - 1];
+      size_t eltsz = item->offset + gelf_fsize (core, item->type,
+						item->count ?: 1, EV_CURRENT);
+
+      int reps = -1;
+      do
+	{
+	  ++reps;
+	  desc += eltsz;
+	  descsz -= eltsz;
+	}
+      while (descsz >= eltsz && !memcmp (desc, last, eltsz));
+
+      if (reps == 1)
+	{
+	  /* For just one repeat, print it unabridged twice.  */
+	  desc -= eltsz;
+	  descsz += eltsz;
+	}
+      else if (reps > 1)
+	printf (gettext ("\n%*s... <repeats %u more times> ..."),
+		ITEM_INDENT, "", reps);
+
+      last = desc;
+    }
+  while (descsz > 0);
+
+  return colno;
+}
+
+static unsigned int
+handle_bit_registers (const Ebl_Register_Location *regloc, const void *desc,
+		      unsigned int colno)
+{
+  desc += regloc->offset;
+
+  abort ();			/* XXX */
+  return colno;
+}
+
+
+static unsigned int
+handle_core_register (Ebl *ebl, Elf *core, int maxregname,
+		      const Ebl_Register_Location *regloc, const void *desc,
+		      unsigned int colno)
+{
+  if (regloc->bits % 8 != 0)
+    return handle_bit_registers (regloc, desc, colno);
+
+  desc += regloc->offset;
+
+  for (int reg = regloc->regno; reg < regloc->regno + regloc->count; ++reg)
+    {
+      char name[REGNAMESZ];
+      int bits;
+      int type;
+      register_info (ebl, reg, regloc, name, &bits, &type);
+
+#define TYPES								      \
+      BITS (8, BYTE, "%4" PRId8, "0x%.2" PRIx8);			      \
+      BITS (16, HALF, "%6" PRId16, "0x%.4" PRIx16);			      \
+      BITS (32, WORD, "%11" PRId32, " 0x%.8" PRIx32);			      \
+      BITS (64, XWORD, "%20" PRId64, "  0x%.16" PRIx64)
+
+#define BITS(bits, xtype, sfmt, ufmt)				\
+      uint##bits##_t b##bits; int##bits##_t b##bits##s
+      union { TYPES; uint64_t b128[2]; } value;
+#undef	BITS
+
+      switch (type)
+	{
+	case DW_ATE_unsigned:
+	case DW_ATE_signed:
+	case DW_ATE_address:
+	  switch (bits)
+	    {
+#define BITS(bits, xtype, sfmt, ufmt)					      \
+	    case bits:							      \
+	      desc = convert (core, ELF_T_##xtype, 1, &value, desc, 0);	      \
+	      if (type == DW_ATE_signed)				      \
+		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
+					 maxregname, name,		      \
+					 sfmt, value.b##bits##s);	      \
+	      else							      \
+		colno = print_core_item (colno, ' ', WRAP_COLUMN,	      \
+					 maxregname, name,		      \
+					 ufmt, value.b##bits);		      \
+	      break
+
+	    TYPES;
+
+	    case 128:
+	      assert (type == DW_ATE_unsigned);
+	      desc = convert (core, ELF_T_XWORD, 2, &value, desc, 0);
+	      int be = elf_getident (core, NULL)[EI_DATA] == ELFDATA2MSB;
+	      colno = print_core_item (colno, ' ', WRAP_COLUMN,
+				       maxregname, name,
+				       "0x%.16" PRIx64 "%.16" PRIx64,
+				       value.b128[!be], value.b128[be]);
+	      break;
+
+	    default:
+	      abort ();
+#undef	BITS
+	    }
+	  break;
+
+	default:
+	  /* Print each byte in hex, the whole thing in native byte order.  */
+	  assert (bits % 8 == 0);
+	  const uint8_t *bytes = desc;
+	  desc += bits / 8;
+	  char hex[bits / 4 + 1];
+	  hex[bits / 4] = '\0';
+	  int incr = 1;
+	  if (elf_getident (core, NULL)[EI_DATA] == ELFDATA2LSB)
+	    {
+	      bytes += bits / 8 - 1;
+	      incr = -1;
+	    }
+	  size_t idx = 0;
+	  for (char *h = hex; bits > 0; bits -= 8, idx += incr)
+	    {
+	      *h++ = "0123456789abcdef"[bytes[idx] >> 4];
+	      *h++ = "0123456789abcdef"[bytes[idx] & 0xf];
+	    }
+	  colno = print_core_item (colno, ' ', WRAP_COLUMN,
+				   maxregname, name, "0x%s", hex);
+	  break;
+	}
+      desc += regloc->pad;
+
+#undef TYPES
+    }
+
+  return colno;
+}
+
+
+struct register_info
+{
+  const Ebl_Register_Location *regloc;
+  const char *set;
+  char name[REGNAMESZ];
+  int regno;
+  int bits;
+  int type;
+};
+
+static int
+register_bitpos (const struct register_info *r)
+{
+  return (r->regloc->offset * 8
+	  + ((r->regno - r->regloc->regno)
+	     * (r->regloc->bits + r->regloc->pad * 8)));
+}
+
+static int
+compare_sets_by_info (const struct register_info *r1,
+		      const struct register_info *r2)
+{
+  return ((int) r2->bits - (int) r1->bits
+	  ?: register_bitpos (r1) - register_bitpos (r2));
+}
+
+/* Sort registers by set, and by size and layout offset within each set.  */
+static int
+compare_registers (const void *a, const void *b)
+{
+  const struct register_info *r1 = a;
+  const struct register_info *r2 = b;
+
+  /* Unused elements sort last.  */
+  if (r1->regloc == NULL)
+    return r2->regloc == NULL ? 0 : 1;
+  if (r2->regloc == NULL)
+    return -1;
+
+  return ((r1->set == r2->set ? 0 : strcmp (r1->set, r2->set))
+	  ?: compare_sets_by_info (r1, r2));
+}
+
+/* Sort register sets by layout offset of the first register in the set.  */
+static int
+compare_register_sets (const void *a, const void *b)
+{
+  const struct register_info *const *p1 = a;
+  const struct register_info *const *p2 = b;
+  return compare_sets_by_info (*p1, *p2);
+}
+
+static unsigned int
+handle_core_registers (Ebl *ebl, Elf *core, const void *desc,
+		       const Ebl_Register_Location *reglocs, size_t nregloc)
+{
+  if (nregloc == 0)
+    return 0;
+
+  ssize_t maxnreg = ebl_register_info (ebl, 0, NULL, 0, NULL, NULL, NULL, NULL);
+  if (maxnreg <= 0)
+    {
+      for (size_t i = 0; i < nregloc; ++i)
+	if (maxnreg < reglocs[i].regno + reglocs[i].count)
+	  maxnreg = reglocs[i].regno + reglocs[i].count;
+      assert (maxnreg > 0);
+    }
+
+  struct register_info regs[maxnreg];
+  memset (regs, 0, sizeof regs);
+
+  /* Sort to collect the sets together.  */
+  int maxreg = 0;
+  for (size_t i = 0; i < nregloc; ++i)
+    for (int reg = reglocs[i].regno;
+	 reg < reglocs[i].regno + reglocs[i].count;
+	 ++reg)
+      {
+	assert (reg < maxnreg);
+	if (reg > maxreg)
+	  maxreg = reg;
+	struct register_info *info = &regs[reg];
+	info->regloc = &reglocs[i];
+	info->regno = reg;
+	info->set = register_info (ebl, reg, &reglocs[i],
+				   info->name, &info->bits, &info->type);
+      }
+  qsort (regs, maxreg + 1, sizeof regs[0], &compare_registers);
+
+  /* Collect the unique sets and sort them.  */
+  inline bool same_set (const struct register_info *a,
+			const struct register_info *b)
+  {
+    return (a < &regs[maxnreg] && a->regloc != NULL
+	    && b < &regs[maxnreg] && b->regloc != NULL
+	    && a->bits == b->bits
+	    && (a->set == b->set || !strcmp (a->set, b->set)));
+  }
+  struct register_info *sets[maxreg + 1];
+  sets[0] = &regs[0];
+  size_t nsets = 1;
+  for (int i = 1; i <= maxreg; ++i)
+    if (regs[i].regloc != NULL && !same_set (&regs[i], &regs[i - 1]))
+      sets[nsets++] = &regs[i];
+  qsort (sets, nsets, sizeof sets[0], &compare_register_sets);
+
+  /* Write out all the sets.  */
+  unsigned int colno = 0;
+  for (size_t i = 0; i < nsets; ++i)
+    {
+      /* Find the longest name of a register in this set.  */
+      size_t maxname = 0;
+      const struct register_info *end;
+      for (end = sets[i]; same_set (sets[i], end); ++end)
+	{
+	  size_t len = strlen (end->name);
+	  if (len > maxname)
+	    maxname = len;
+	}
+
+      for (const struct register_info *reg = sets[i];
+	   reg < end;
+	   reg += reg->regloc->count ?: 1)
+	colno = handle_core_register (ebl, core, maxname,
+				      reg->regloc, desc, colno);
+
+      /* Force a line break at the end of the group.  */
+      colno = WRAP_COLUMN;
+    }
+
+  return colno;
+}
+
+static void
+handle_auxv_note (Ebl *ebl, Elf *core, GElf_Word descsz, GElf_Off desc_pos)
+{
+  Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_AUXV);
+  if (data == NULL)
+  elf_error:
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
+
+  const size_t nauxv = descsz / gelf_fsize (core, ELF_T_AUXV, 1, EV_CURRENT);
+  for (size_t i = 0; i < nauxv; ++i)
+    {
+      GElf_auxv_t av_mem;
+      GElf_auxv_t *av = gelf_getauxv (data, i, &av_mem);
+      if (av == NULL)
+	goto elf_error;
+
+      const char *name;
+      const char *fmt;
+      if (ebl_auxv_info (ebl, av->a_type, &name, &fmt) == 0)
+	{
+	  /* Unknown type.  */
+	  if (av->a_un.a_val == 0)
+	    printf ("    %" PRIu64 "\n", av->a_type);
+	  else
+	    printf ("    %" PRIu64 ": %#" PRIx64 "\n",
+		    av->a_type, av->a_un.a_val);
+	}
+      else
+	switch (fmt[0])
+	  {
+	  case '\0':		/* Normally zero.  */
+	    if (av->a_un.a_val == 0)
+	      {
+		printf ("    %s\n", name);
+		break;
+	      }
+	    FALLTHROUGH;
+	  case 'x':		/* hex */
+	  case 'p':		/* address */
+	  case 's':		/* address of string */
+	    printf ("    %s: %#" PRIx64 "\n", name, av->a_un.a_val);
+	    break;
+	  case 'u':
+	    printf ("    %s: %" PRIu64 "\n", name, av->a_un.a_val);
+	    break;
+	  case 'd':
+	    printf ("    %s: %" PRId64 "\n", name, av->a_un.a_val);
+	    break;
+
+	  case 'b':
+	    printf ("    %s: %#" PRIx64 "  ", name, av->a_un.a_val);
+	    GElf_Xword bit = 1;
+	    const char *pfx = "<";
+	    for (const char *p = fmt + 1; *p != 0; p = strchr (p, '\0') + 1)
+	      {
+		if (av->a_un.a_val & bit)
+		  {
+		    printf ("%s%s", pfx, p);
+		    pfx = " ";
+		  }
+		bit <<= 1;
+	      }
+	    printf (">\n");
+	    break;
+
+	  default:
+	    abort ();
+	  }
+    }
+}
+
+static bool
+buf_has_data (unsigned char const *ptr, unsigned char const *end, size_t sz)
+{
+  return ptr < end && (size_t) (end - ptr) >= sz;
+}
+
+static bool
+buf_read_int (Elf *core, unsigned char const **ptrp, unsigned char const *end,
+	      int *retp)
+{
+  if (! buf_has_data (*ptrp, end, 4))
+    return false;
+
+  *ptrp = convert (core, ELF_T_WORD, 1, retp, *ptrp, 4);
+  return true;
+}
+
+static bool
+buf_read_ulong (Elf *core, unsigned char const **ptrp, unsigned char const *end,
+		uint64_t *retp)
+{
+  size_t sz = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
+  if (! buf_has_data (*ptrp, end, sz))
+    return false;
+
+  union
+  {
+    uint64_t u64;
+    uint32_t u32;
+  } u;
+
+  *ptrp = convert (core, ELF_T_ADDR, 1, &u, *ptrp, sz);
+
+  if (sz == 4)
+    *retp = u.u32;
+  else
+    *retp = u.u64;
+  return true;
+}
+
+static void
+handle_siginfo_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
+{
+  Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
+  if (data == NULL)
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
+
+  unsigned char const *ptr = data->d_buf;
+  unsigned char const *const end = data->d_buf + data->d_size;
+
+  /* Siginfo head is three ints: signal number, error number, origin
+     code.  */
+  int si_signo, si_errno, si_code;
+  if (! buf_read_int (core, &ptr, end, &si_signo)
+      || ! buf_read_int (core, &ptr, end, &si_errno)
+      || ! buf_read_int (core, &ptr, end, &si_code))
+    {
+    fail:
+      printf ("    Not enough data in NT_SIGINFO note.\n");
+      return;
+    }
+
+  /* Next is a pointer-aligned union of structures.  On 64-bit
+     machines, that implies a word of padding.  */
+  if (gelf_getclass (core) == ELFCLASS64)
+    ptr += 4;
+
+  printf ("    si_signo: %d, si_errno: %d, si_code: %d\n",
+	  si_signo, si_errno, si_code);
+
+  if (si_code > 0)
+    switch (si_signo)
+      {
+      case CORE_SIGILL:
+      case CORE_SIGFPE:
+      case CORE_SIGSEGV:
+      case CORE_SIGBUS:
+	{
+	  uint64_t addr;
+	  if (! buf_read_ulong (core, &ptr, end, &addr))
+	    goto fail;
+	  printf ("    fault address: %#" PRIx64 "\n", addr);
+	  break;
+	}
+      default:
+	;
+      }
+  else if (si_code == CORE_SI_USER)
+    {
+      int pid, uid;
+      if (! buf_read_int (core, &ptr, end, &pid)
+	  || ! buf_read_int (core, &ptr, end, &uid))
+	goto fail;
+      printf ("    sender PID: %d, sender UID: %d\n", pid, uid);
+    }
+}
+
+static void
+handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
+{
+  Elf_Data *data = elf_getdata_rawchunk (core, desc_pos, descsz, ELF_T_BYTE);
+  if (data == NULL)
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot convert core note data: %s"), elf_errmsg (-1));
+
+  unsigned char const *ptr = data->d_buf;
+  unsigned char const *const end = data->d_buf + data->d_size;
+
+  uint64_t count, page_size;
+  if (! buf_read_ulong (core, &ptr, end, &count)
+      || ! buf_read_ulong (core, &ptr, end, &page_size))
+    {
+    fail:
+      printf ("    Not enough data in NT_FILE note.\n");
+      return;
+    }
+
+  size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
+  uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
+  if (count > maxcount)
+    goto fail;
+
+  /* Where file names are stored.  */
+  unsigned char const *const fstart = ptr + 3 * count * addrsize;
+  char const *fptr = (char *) fstart;
+
+  printf ("    %" PRId64 " files:\n", count);
+  for (uint64_t i = 0; i < count; ++i)
+    {
+      uint64_t mstart, mend, moffset;
+      if (! buf_read_ulong (core, &ptr, fstart, &mstart)
+	  || ! buf_read_ulong (core, &ptr, fstart, &mend)
+	  || ! buf_read_ulong (core, &ptr, fstart, &moffset))
+	goto fail;
+
+      const char *fnext = memchr (fptr, '\0', (char *) end - fptr);
+      if (fnext == NULL)
+	goto fail;
+
+      int ct = printf ("      %08" PRIx64 "-%08" PRIx64
+		       " %08" PRIx64 " %" PRId64,
+		       mstart, mend, moffset * page_size, mend - mstart);
+      printf ("%*s%s\n", ct > 50 ? 3 : 53 - ct, "", fptr);
+
+      fptr = fnext + 1;
+    }
+}
+
+static void
+handle_core_note (Ebl *ebl, const GElf_Nhdr *nhdr,
+		  const char *name, const void *desc)
+{
+  GElf_Word regs_offset;
+  size_t nregloc;
+  const Ebl_Register_Location *reglocs;
+  size_t nitems;
+  const Ebl_Core_Item *items;
+
+  if (! ebl_core_note (ebl, nhdr, name,
+		       &regs_offset, &nregloc, &reglocs, &nitems, &items))
+    return;
+
+  /* Pass 0 for DESCSZ when there are registers in the note,
+     so that the ITEMS array does not describe the whole thing.
+     For non-register notes, the actual descsz might be a multiple
+     of the unit size, not just exactly the unit size.  */
+  unsigned int colno = handle_core_items (ebl->elf, desc,
+					  nregloc == 0 ? nhdr->n_descsz : 0,
+					  items, nitems);
+  if (colno != 0)
+    putchar_unlocked ('\n');
+
+  colno = handle_core_registers (ebl, ebl->elf, desc + regs_offset,
+				 reglocs, nregloc);
+  if (colno != 0)
+    putchar_unlocked ('\n');
+}
+
+static void
+handle_notes_data (Ebl *ebl, const GElf_Ehdr *ehdr,
+		   GElf_Off start, Elf_Data *data)
+{
+  fputs_unlocked (gettext ("  Owner          Data size  Type\n"), stdout);
+
+  if (data == NULL)
+    goto bad_note;
+
+  size_t offset = 0;
+  GElf_Nhdr nhdr;
+  size_t name_offset;
+  size_t desc_offset;
+  while (offset < data->d_size
+	 && (offset = gelf_getnote (data, offset,
+				    &nhdr, &name_offset, &desc_offset)) > 0)
+    {
+      const char *name = nhdr.n_namesz == 0 ? "" : data->d_buf + name_offset;
+      const char *desc = data->d_buf + desc_offset;
+
+      char buf[100];
+      char buf2[100];
+      printf (gettext ("  %-13.*s  %9" PRId32 "  %s\n"),
+	      (int) nhdr.n_namesz, name, nhdr.n_descsz,
+	      ehdr->e_type == ET_CORE
+	      ? ebl_core_note_type_name (ebl, nhdr.n_type,
+					 buf, sizeof (buf))
+	      : ebl_object_note_type_name (ebl, name, nhdr.n_type,
+					   buf2, sizeof (buf2)));
+
+      /* Filter out invalid entries.  */
+      if (memchr (name, '\0', nhdr.n_namesz) != NULL
+	  /* XXX For now help broken Linux kernels.  */
+	  || 1)
+	{
+	  if (ehdr->e_type == ET_CORE)
+	    {
+	      if (nhdr.n_type == NT_AUXV
+		  && (nhdr.n_namesz == 4 /* Broken old Linux kernels.  */
+		      || (nhdr.n_namesz == 5 && name[4] == '\0'))
+		  && !memcmp (name, "CORE", 4))
+		handle_auxv_note (ebl, ebl->elf, nhdr.n_descsz,
+				  start + desc_offset);
+	      else if (nhdr.n_namesz == 5 && strcmp (name, "CORE") == 0)
+		switch (nhdr.n_type)
+		  {
+		  case NT_SIGINFO:
+		    handle_siginfo_note (ebl->elf, nhdr.n_descsz,
+					 start + desc_offset);
+		    break;
+
+		  case NT_FILE:
+		    handle_file_note (ebl->elf, nhdr.n_descsz,
+				      start + desc_offset);
+		    break;
+
+		  default:
+		    handle_core_note (ebl, &nhdr, name, desc);
+		  }
+	      else
+		handle_core_note (ebl, &nhdr, name, desc);
+	    }
+	  else
+	    ebl_object_note (ebl, name, nhdr.n_type, nhdr.n_descsz, desc);
+	}
+    }
+
+  if (offset == data->d_size)
+    return;
+
+ bad_note:
+  error (0, 0,
+	 gettext ("cannot get content of note: %s"),
+	 data != NULL ? "garbage data" : elf_errmsg (-1));
+}
+
+static void
+handle_notes (Ebl *ebl, GElf_Ehdr *ehdr)
+{
+  /* If we have section headers, just look for SHT_NOTE sections.
+     In a debuginfo file, the program headers are not reliable.  */
+  if (shnum != 0)
+    {
+      /* Get the section header string table index.  */
+      size_t shstrndx;
+      if (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0)
+	error (EXIT_FAILURE, 0,
+	       gettext ("cannot get section header string table index"));
+
+      Elf_Scn *scn = NULL;
+      while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+	{
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+	  if (shdr == NULL || shdr->sh_type != SHT_NOTE)
+	    /* Not what we are looking for.  */
+	    continue;
+
+	  printf (gettext ("\
+\nNote section [%2zu] '%s' of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
+		  elf_ndxscn (scn),
+		  elf_strptr (ebl->elf, shstrndx, shdr->sh_name),
+		  shdr->sh_size, shdr->sh_offset);
+
+	  handle_notes_data (ebl, ehdr, shdr->sh_offset,
+			     elf_getdata (scn, NULL));
+	}
+      return;
+    }
+
+  /* We have to look through the program header to find the note
+     sections.  There can be more than one.  */
+  for (size_t cnt = 0; cnt < phnum; ++cnt)
+    {
+      GElf_Phdr mem;
+      GElf_Phdr *phdr = gelf_getphdr (ebl->elf, cnt, &mem);
+
+      if (phdr == NULL || phdr->p_type != PT_NOTE)
+	/* Not what we are looking for.  */
+	continue;
+
+      printf (gettext ("\
+\nNote segment of %" PRIu64 " bytes at offset %#0" PRIx64 ":\n"),
+	      phdr->p_filesz, phdr->p_offset);
+
+      handle_notes_data (ebl, ehdr, phdr->p_offset,
+			 elf_getdata_rawchunk (ebl->elf,
+					       phdr->p_offset, phdr->p_filesz,
+					       ELF_T_NHDR));
+    }
+}
+
+
+static void
+hex_dump (const uint8_t *data, size_t len)
+{
+  size_t pos = 0;
+  while (pos < len)
+    {
+      printf ("  0x%08zx ", pos);
+
+      const size_t chunk = MIN (len - pos, 16);
+
+      for (size_t i = 0; i < chunk; ++i)
+	if (i % 4 == 3)
+	  printf ("%02x ", data[pos + i]);
+	else
+	  printf ("%02x", data[pos + i]);
+
+      if (chunk < 16)
+	printf ("%*s", (int) ((16 - chunk) * 2 + (16 - chunk + 3) / 4), "");
+
+      for (size_t i = 0; i < chunk; ++i)
+	{
+	  unsigned char b = data[pos + i];
+	  printf ("%c", isprint (b) ? b : '.');
+	}
+
+      putchar ('\n');
+      pos += chunk;
+    }
+}
+
+static void
+dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
+{
+  if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
+    printf (gettext ("\nSection [%zu] '%s' has no data to dump.\n"),
+	    elf_ndxscn (scn), name);
+  else
+    {
+      if (print_decompress)
+	{
+	  /* We try to decompress the section, but keep the old shdr around
+	     so we can show both the original shdr size and the uncompressed
+	     data size.   */
+	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	    {
+	      if (elf_compress (scn, 0, 0) < 0)
+		printf ("WARNING: %s [%zd]\n",
+			gettext ("Couldn't uncompress section"),
+			elf_ndxscn (scn));
+	    }
+	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
+	    {
+	      if (elf_compress_gnu (scn, 0, 0) < 0)
+		printf ("WARNING: %s [%zd]\n",
+			gettext ("Couldn't uncompress section"),
+			elf_ndxscn (scn));
+	    }
+	}
+
+      Elf_Data *data = elf_rawdata (scn, NULL);
+      if (data == NULL)
+	error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
+	       elf_ndxscn (scn), name, elf_errmsg (-1));
+      else
+	{
+	  if (data->d_size == shdr->sh_size)
+	    printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
+			     " bytes at offset %#0" PRIx64 ":\n"),
+		    elf_ndxscn (scn), name,
+		    shdr->sh_size, shdr->sh_offset);
+	  else
+	    printf (gettext ("\nHex dump of section [%zu] '%s', %" PRIu64
+			     " bytes (%zd uncompressed) at offset %#0"
+			     PRIx64 ":\n"),
+		    elf_ndxscn (scn), name,
+		    shdr->sh_size, data->d_size, shdr->sh_offset);
+	  hex_dump (data->d_buf, data->d_size);
+	}
+    }
+}
+
+static void
+print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
+{
+  if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
+    printf (gettext ("\nSection [%zu] '%s' has no strings to dump.\n"),
+	    elf_ndxscn (scn), name);
+  else
+    {
+      if (print_decompress)
+	{
+	  /* We try to decompress the section, but keep the old shdr around
+	     so we can show both the original shdr size and the uncompressed
+	     data size.  */
+	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	    {
+	      if (elf_compress (scn, 0, 0) < 0)
+		printf ("WARNING: %s [%zd]\n",
+			gettext ("Couldn't uncompress section"),
+			elf_ndxscn (scn));
+	    }
+	  else if (strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
+	    {
+	      if (elf_compress_gnu (scn, 0, 0) < 0)
+		printf ("WARNING: %s [%zd]\n",
+			gettext ("Couldn't uncompress section"),
+			elf_ndxscn (scn));
+	    }
+	}
+
+      Elf_Data *data = elf_rawdata (scn, NULL);
+      if (data == NULL)
+	error (0, 0, gettext ("cannot get data for section [%zu] '%s': %s"),
+	       elf_ndxscn (scn), name, elf_errmsg (-1));
+      else
+	{
+	  if (data->d_size == shdr->sh_size)
+	    printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
+			     " bytes at offset %#0" PRIx64 ":\n"),
+		    elf_ndxscn (scn), name,
+		    shdr->sh_size, shdr->sh_offset);
+	  else
+	    printf (gettext ("\nString section [%zu] '%s' contains %" PRIu64
+			     " bytes (%zd uncompressed) at offset %#0"
+			     PRIx64 ":\n"),
+		    elf_ndxscn (scn), name,
+		    shdr->sh_size, data->d_size, shdr->sh_offset);
+
+	  const char *start = data->d_buf;
+	  const char *const limit = start + data->d_size;
+	  do
+	    {
+	      const char *end = memchr (start, '\0', limit - start);
+	      const size_t pos = start - (const char *) data->d_buf;
+	      if (unlikely (end == NULL))
+		{
+		  printf ("  [%6zx]- %.*s\n",
+			  pos, (int) (limit - start), start);
+		  break;
+		}
+	      printf ("  [%6zx]  %s\n", pos, start);
+	      start = end + 1;
+	    } while (start < limit);
+	}
+    }
+}
+
+static void
+for_each_section_argument (Elf *elf, const struct section_argument *list,
+			   void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
+					 const char *name))
+{
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (elf_getshdrstrndx (elf, &shstrndx) < 0)
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  for (const struct section_argument *a = list; a != NULL; a = a->next)
+    {
+      Elf_Scn *scn;
+      GElf_Shdr shdr_mem;
+      const char *name = NULL;
+
+      char *endp = NULL;
+      unsigned long int shndx = strtoul (a->arg, &endp, 0);
+      if (endp != a->arg && *endp == '\0')
+	{
+	  scn = elf_getscn (elf, shndx);
+	  if (scn == NULL)
+	    {
+	      error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
+	      continue;
+	    }
+
+	  if (gelf_getshdr (scn, &shdr_mem) == NULL)
+	    error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
+		   elf_errmsg (-1));
+	  name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
+	}
+      else
+	{
+	  /* Need to look up the section by name.  */
+	  scn = NULL;
+	  bool found = false;
+	  while ((scn = elf_nextscn (elf, scn)) != NULL)
+	    {
+	      if (gelf_getshdr (scn, &shdr_mem) == NULL)
+		continue;
+	      name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
+	      if (name == NULL)
+		continue;
+	      if (!strcmp (name, a->arg))
+		{
+		  found = true;
+		  (*dump) (scn, &shdr_mem, name);
+		}
+	    }
+
+	  if (unlikely (!found) && !a->implicit)
+	    error (0, 0, gettext ("\nsection '%s' does not exist"), a->arg);
+	}
+    }
+}
+
+static void
+dump_data (Ebl *ebl)
+{
+  for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
+}
+
+static void
+dump_strings (Ebl *ebl)
+{
+  for_each_section_argument (ebl->elf, string_sections, &print_string_section);
+}
+
+static void
+print_strings (Ebl *ebl)
+{
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (ebl->elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  Elf_Scn *scn;
+  GElf_Shdr shdr_mem;
+  const char *name;
+  scn = NULL;
+  while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+    {
+      if (gelf_getshdr (scn, &shdr_mem) == NULL)
+	continue;
+
+      if (shdr_mem.sh_type != SHT_PROGBITS
+	  || !(shdr_mem.sh_flags & SHF_STRINGS))
+	continue;
+
+      name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
+      if (name == NULL)
+	continue;
+
+      print_string_section (scn, &shdr_mem, name);
+    }
+}
+
+static void
+dump_archive_index (Elf *elf, const char *fname)
+{
+  size_t narsym;
+  const Elf_Arsym *arsym = elf_getarsym (elf, &narsym);
+  if (arsym == NULL)
+    {
+      int result = elf_errno ();
+      if (unlikely (result != ELF_E_NO_INDEX))
+	error (EXIT_FAILURE, 0,
+	       gettext ("cannot get symbol index of archive '%s': %s"),
+	       fname, elf_errmsg (result));
+      else
+	printf (gettext ("\nArchive '%s' has no symbol index\n"), fname);
+      return;
+    }
+
+  printf (gettext ("\nIndex of archive '%s' has %zu entries:\n"),
+	  fname, narsym);
+
+  size_t as_off = 0;
+  for (const Elf_Arsym *s = arsym; s < &arsym[narsym - 1]; ++s)
+    {
+      if (s->as_off != as_off)
+	{
+	  as_off = s->as_off;
+
+	  Elf *subelf = NULL;
+	  if (unlikely (elf_rand (elf, as_off) == 0)
+	      || unlikely ((subelf = elf_begin (-1, ELF_C_READ_MMAP, elf))
+			   == NULL))
+#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 7)
+	    while (1)
+#endif
+	      error (EXIT_FAILURE, 0,
+		     gettext ("cannot extract member at offset %zu in '%s': %s"),
+		     as_off, fname, elf_errmsg (-1));
+
+	  const Elf_Arhdr *h = elf_getarhdr (subelf);
+
+	  printf (gettext ("Archive member '%s' contains:\n"), h->ar_name);
+
+	  elf_end (subelf);
+	}
+
+      printf ("\t%s\n", s->as_name);
+    }
+}
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/size.c b/third_party/elfutils/src/size.c
new file mode 100644
index 0000000..ad8dbcb
--- /dev/null
+++ b/third_party/elfutils/src/size.c
@@ -0,0 +1,657 @@
+/* Print size information from ELF file.
+   Copyright (C) 2000-2007,2009,2012,2014,2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <system.h>
+#include <printversion.h>
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+
+/* Values for the parameters which have no short form.  */
+#define OPT_FORMAT	0x100
+#define OPT_RADIX	0x101
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("Output format:"), 0 },
+  { "format", OPT_FORMAT, "FORMAT", 0,
+    N_("Use the output format FORMAT.  FORMAT can be `bsd' or `sysv'.  "
+       "The default is `bsd'"), 0 },
+  { NULL, 'A', NULL, 0, N_("Same as `--format=sysv'"), 0 },
+  { NULL, 'B', NULL, 0, N_("Same as `--format=bsd'"), 0 },
+  { "radix", OPT_RADIX, "RADIX", 0, N_("Use RADIX for printing symbol values"),
+    0},
+  { NULL, 'd', NULL, 0, N_("Same as `--radix=10'"), 0 },
+  { NULL, 'o', NULL, 0, N_("Same as `--radix=8'"), 0 },
+  { NULL, 'x', NULL, 0, N_("Same as `--radix=16'"), 0 },
+  { NULL, 'f', NULL, 0,
+    N_("Similar to `--format=sysv' output but in one line"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Output options:"), 0 },
+  { NULL, 'F', NULL, 0,
+    N_("Print size and permission flags for loadable segments"), 0 },
+  { "totals", 't', NULL, 0, N_("Display the total sizes (bsd only)"), 0 },
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("\
+List section sizes of FILEs (a.out by default).");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("[FILE...]");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  options, parse_opt, args_doc, doc, NULL, NULL, NULL
+};
+
+
+/* Print symbols in file named FNAME.  */
+static int process_file (const char *fname);
+
+/* Handle content of archive.  */
+static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname);
+
+/* Handle ELF file.  */
+static void handle_elf (Elf *elf, const char *fullname, const char *fname);
+
+/* Show total size.  */
+static void show_bsd_totals (void);
+
+#define INTERNAL_ERROR(fname) \
+  error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s): %s"),      \
+	 fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1))
+
+
+/* User-selectable options.  */
+
+/* The selected output format.  */
+static enum
+{
+  format_bsd = 0,
+  format_sysv,
+  format_sysv_one_line,
+  format_segments
+} format;
+
+/* Radix for printed numbers.  */
+static enum
+{
+  radix_decimal = 0,
+  radix_hex,
+  radix_octal
+} radix;
+
+
+/* Mapping of radix and binary class to length.  */
+static const int length_map[2][3] =
+{
+  [ELFCLASS32 - 1] =
+  {
+    [radix_hex] = 8,
+    [radix_decimal] = 10,
+    [radix_octal] = 11
+  },
+  [ELFCLASS64 - 1] =
+  {
+    [radix_hex] = 16,
+    [radix_decimal] = 20,
+    [radix_octal] = 22
+  }
+};
+
+/* True if total sizes should be printed.  */
+static bool totals;
+/* To print the total sizes in a reasonable format remember the higest
+   "class" of ELF binaries processed.  */
+static int totals_class;
+
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+  int result = 0;
+
+  /* We use no threads here which can interfere with handling a stream.  */
+  __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+  __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  setlocale (LC_ALL, "");
+
+  /* Make sure the message catalog can be found.  */
+  bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+
+  /* Initialize the message catalog.  */
+  textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  */
+  argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+
+  /* Tell the library which version we are expecting.  */
+  elf_version (EV_CURRENT);
+
+  if (remaining == argc)
+    /* The user didn't specify a name so we use a.out.  */
+    result = process_file ("a.out");
+  else
+    /* Process all the remaining files.  */
+    do
+      result |= process_file (argv[remaining]);
+    while (++remaining < argc);
+
+  /* Print the total sizes but only if the output format is BSD and at
+     least one file has been correctly read (i.e., we recognized the
+     class).  */
+  if (totals && format == format_bsd && totals_class != 0)
+    show_bsd_totals ();
+
+  return result;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg,
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case 'd':
+      radix = radix_decimal;
+      break;
+
+    case 'f':
+      format = format_sysv_one_line;
+      break;
+
+    case 'o':
+      radix = radix_octal;
+      break;
+
+    case 'x':
+      radix = radix_hex;
+      break;
+
+    case 'A':
+      format = format_sysv;
+      break;
+
+    case 'B':
+      format = format_bsd;
+      break;
+
+    case 'F':
+      format = format_segments;
+      break;
+
+    case OPT_FORMAT:
+      if (strcmp (arg, "bsd") == 0 || strcmp (arg, "berkeley") == 0)
+	format = format_bsd;
+      else if (likely (strcmp (arg, "sysv") == 0))
+	format = format_sysv;
+      else
+	error (EXIT_FAILURE, 0, gettext ("Invalid format: %s"), arg);
+      break;
+
+    case OPT_RADIX:
+      if (strcmp (arg, "x") == 0 || strcmp (arg, "16") == 0)
+	radix = radix_hex;
+      else if (strcmp (arg, "d") == 0 || strcmp (arg, "10") == 0)
+	radix = radix_decimal;
+      else if (strcmp (arg, "o") == 0 || strcmp (arg, "8") == 0)
+	radix = radix_octal;
+      else
+	error (EXIT_FAILURE, 0, gettext ("Invalid radix: %s"), arg);
+      break;
+
+    case 't':
+      totals = true;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+/* Open the file and determine the type.  */
+static int
+process_file (const char *fname)
+{
+  int fd = open (fname, O_RDONLY);
+  if (unlikely (fd == -1))
+    {
+      error (0, errno, gettext ("cannot open '%s'"), fname);
+      return 1;
+    }
+
+  /* Now get the ELF descriptor.  */
+  Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+  if (likely (elf != NULL))
+    {
+      if (elf_kind (elf) == ELF_K_ELF)
+	{
+	  handle_elf (elf, NULL, fname);
+
+	  if (unlikely (elf_end (elf) != 0))
+	    INTERNAL_ERROR (fname);
+
+	  if (unlikely (close (fd) != 0))
+	    error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
+
+	  return 0;
+	}
+      else if (likely (elf_kind (elf) == ELF_K_AR))
+	{
+	  int result = handle_ar (fd, elf, NULL, fname);
+
+	  if (unlikely  (close (fd) != 0))
+	    error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
+
+	  return result;
+	}
+
+      /* We cannot handle this type.  Close the descriptor anyway.  */
+      if (unlikely (elf_end (elf) != 0))
+	INTERNAL_ERROR (fname);
+    }
+
+  if (unlikely (close (fd) != 0))
+    error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
+
+  error (0, 0, gettext ("%s: file format not recognized"), fname);
+
+  return 1;
+}
+
+
+/* Print the BSD-style header.  This is done exactly once.  */
+static void
+print_header (Elf *elf)
+{
+  static int done;
+
+  if (! done)
+    {
+      int ddigits = length_map[gelf_getclass (elf) - 1][radix_decimal];
+      int xdigits = length_map[gelf_getclass (elf) - 1][radix_hex];
+
+      printf ("%*s %*s %*s %*s %*s %s\n",
+	      ddigits - 2, sgettext ("bsd|text"),
+	      ddigits - 2, sgettext ("bsd|data"),
+	      ddigits - 2, sgettext ("bsd|bss"),
+	      ddigits - 2, sgettext ("bsd|dec"),
+	      xdigits - 2, sgettext ("bsd|hex"),
+	      sgettext ("bsd|filename"));
+
+      done = 1;
+    }
+}
+
+
+static int
+handle_ar (int fd, Elf *elf, const char *prefix, const char *fname)
+{
+  size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
+  size_t fname_len = strlen (fname) + 1;
+  char new_prefix[prefix_len + 1 + fname_len];
+  char *cp = new_prefix;
+
+  /* Create the full name of the file.  */
+  if (prefix != NULL)
+    {
+      cp = mempcpy (cp, prefix, prefix_len);
+      *cp++ = ':';
+    }
+  memcpy (cp, fname, fname_len);
+
+  /* Process all the files contained in the archive.  */
+  int result = 0;
+  Elf *subelf;
+  Elf_Cmd cmd = ELF_C_READ_MMAP;
+  while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+    {
+      /* The the header for this element.  */
+      Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+
+      if (elf_kind (subelf) == ELF_K_ELF)
+	handle_elf (subelf, new_prefix, arhdr->ar_name);
+      else if (likely (elf_kind (subelf) == ELF_K_AR))
+	result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name);
+      /* else signal error??? */
+
+      /* Get next archive element.  */
+      cmd = elf_next (subelf);
+      if (unlikely (elf_end (subelf) != 0))
+	INTERNAL_ERROR (fname);
+    }
+
+  if (unlikely (elf_end (elf) != 0))
+    INTERNAL_ERROR (fname);
+
+  return result;
+}
+
+
+/* Show sizes in SysV format.  */
+static void
+show_sysv (Elf *elf, const char *prefix, const char *fname,
+	   const char *fullname)
+{
+  int maxlen = 10;
+  const int digits = length_map[gelf_getclass (elf) - 1][radix];
+
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  /* First round over the sections: determine the longest section name.  */
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr == NULL)
+	INTERNAL_ERROR (fullname);
+
+      /* Ignore all sections which are not used at runtime.  */
+      const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
+      if (name != NULL && (shdr->sh_flags & SHF_ALLOC) != 0)
+	maxlen = MAX (maxlen, (int) strlen (name));
+    }
+
+  fputs_unlocked (fname, stdout);
+  if (prefix != NULL)
+    printf (gettext (" (ex %s)"), prefix);
+  printf (":\n%-*s %*s %*s\n",
+	  maxlen, sgettext ("sysv|section"),
+	  digits - 2, sgettext ("sysv|size"),
+	  digits, sgettext ("sysv|addr"));
+
+  /* Iterate over all sections.  */
+  GElf_Off total = 0;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      /* Ignore all sections which are not used at runtime.  */
+      if ((shdr->sh_flags & SHF_ALLOC) != 0)
+	{
+	  printf ((radix == radix_hex
+		   ? "%-*s %*" PRIx64 " %*" PRIx64 "\n"
+		   : (radix == radix_decimal
+		      ? "%-*s %*" PRId64 " %*" PRId64 "\n"
+		      : "%-*s %*" PRIo64 " %*" PRIo64 "\n")),
+		  maxlen, elf_strptr (elf, shstrndx, shdr->sh_name),
+		  digits - 2, shdr->sh_size,
+		  digits, shdr->sh_addr);
+
+	  total += shdr->sh_size;
+	}
+    }
+
+  if (radix == radix_hex)
+    printf ("%-*s %*" PRIx64 "\n\n\n", maxlen, sgettext ("sysv|Total"),
+	    digits - 2, total);
+  else if (radix == radix_decimal)
+    printf ("%-*s %*" PRId64 "\n\n\n", maxlen, sgettext ("sysv|Total"),
+	    digits - 2, total);
+  else
+    printf ("%-*s %*" PRIo64 "\n\n\n", maxlen, sgettext ("sysv|Total"),
+	    digits - 2, total);
+}
+
+
+/* Show sizes in SysV format in one line.  */
+static void
+show_sysv_one_line (Elf *elf)
+{
+  /* Get the section header string table index.  */
+  size_t shstrndx;
+  if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0))
+    error (EXIT_FAILURE, 0,
+	   gettext ("cannot get section header string table index"));
+
+  /* Iterate over all sections.  */
+  GElf_Off total = 0;
+  bool first = true;
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      /* Ignore all sections which are not used at runtime.  */
+      if ((shdr->sh_flags & SHF_ALLOC) == 0)
+	continue;
+
+      if (! first)
+	fputs_unlocked (" + ", stdout);
+      first = false;
+
+      printf ((radix == radix_hex ? "%" PRIx64 "(%s)"
+	       : (radix == radix_decimal ? "%" PRId64 "(%s)"
+		  : "%" PRIo64 "(%s)")),
+	      shdr->sh_size, elf_strptr (elf, shstrndx, shdr->sh_name));
+
+      total += shdr->sh_size;
+    }
+
+  if (radix == radix_hex)
+    printf (" = %#" PRIx64 "\n", total);
+  else if (radix == radix_decimal)
+    printf (" = %" PRId64 "\n", total);
+  else
+    printf (" = %" PRIo64 "\n", total);
+}
+
+
+/* Variables to add up the sizes of all files.  */
+static uintmax_t total_textsize;
+static uintmax_t total_datasize;
+static uintmax_t total_bsssize;
+
+
+/* Show sizes in BSD format.  */
+static void
+show_bsd (Elf *elf, const char *prefix, const char *fname,
+	  const char *fullname)
+{
+  GElf_Off textsize = 0;
+  GElf_Off datasize = 0;
+  GElf_Off bsssize = 0;
+  const int ddigits = length_map[gelf_getclass (elf) - 1][radix_decimal];
+  const int xdigits = length_map[gelf_getclass (elf) - 1][radix_hex];
+
+  /* Iterate over all sections.  */
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      if (shdr == NULL)
+	INTERNAL_ERROR (fullname);
+
+      /* Ignore all sections which are not marked as loaded.  */
+      if ((shdr->sh_flags & SHF_ALLOC) == 0)
+	continue;
+
+      if ((shdr->sh_flags & SHF_WRITE) == 0)
+	textsize += shdr->sh_size;
+      else if (shdr->sh_type == SHT_NOBITS)
+	bsssize += shdr->sh_size;
+      else
+	datasize += shdr->sh_size;
+    }
+
+  printf ("%*" PRId64 " %*" PRId64 " %*" PRId64 " %*" PRId64 " %*"
+	  PRIx64 " %s",
+	  ddigits - 2, textsize,
+	  ddigits - 2, datasize,
+	  ddigits - 2, bsssize,
+	  ddigits - 2, textsize + datasize + bsssize,
+	  xdigits - 2, textsize + datasize + bsssize,
+	  fname);
+  if (prefix != NULL)
+    printf (gettext (" (ex %s)"), prefix);
+  fputs_unlocked ("\n", stdout);
+
+  total_textsize += textsize;
+  total_datasize += datasize;
+  total_bsssize += bsssize;
+
+  totals_class = MAX (totals_class, gelf_getclass (elf));
+}
+
+
+/* Show total size.  */
+static void
+show_bsd_totals (void)
+{
+  int ddigits = length_map[totals_class - 1][radix_decimal];
+  int xdigits = length_map[totals_class - 1][radix_hex];
+
+  printf ("%*" PRIuMAX " %*" PRIuMAX " %*" PRIuMAX " %*" PRIuMAX " %*"
+	  PRIxMAX " %s",
+	  ddigits - 2, total_textsize,
+	  ddigits - 2, total_datasize,
+	  ddigits - 2, total_bsssize,
+	  ddigits - 2, total_textsize + total_datasize + total_bsssize,
+	  xdigits - 2, total_textsize + total_datasize + total_bsssize,
+	  gettext ("(TOTALS)\n"));
+}
+
+
+/* Show size and permission of loadable segments.  */
+static void
+show_segments (Elf *elf, const char *fullname)
+{
+  size_t phnum;
+  if (elf_getphdrnum (elf, &phnum) != 0)
+    INTERNAL_ERROR (fullname);
+
+  GElf_Off total = 0;
+  bool first = true;
+  for (size_t cnt = 0; cnt < phnum; ++cnt)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr;
+
+      phdr = gelf_getphdr (elf, cnt, &phdr_mem);
+      if (phdr == NULL)
+	INTERNAL_ERROR (fullname);
+
+      if (phdr->p_type != PT_LOAD)
+	/* Only load segments.  */
+	continue;
+
+      if (! first)
+	fputs_unlocked (" + ", stdout);
+      first = false;
+
+      printf (radix == radix_hex ? "%" PRIx64 "(%c%c%c)"
+	      : (radix == radix_decimal ? "%" PRId64 "(%c%c%c)"
+		 : "%" PRIo64 "(%c%c%c)"),
+	      phdr->p_memsz,
+	      (phdr->p_flags & PF_R) == 0 ? '-' : 'r',
+	      (phdr->p_flags & PF_W) == 0 ? '-' : 'w',
+	      (phdr->p_flags & PF_X) == 0 ? '-' : 'x');
+
+      total += phdr->p_memsz;
+    }
+
+  if (radix == radix_hex)
+    printf (" = %#" PRIx64 "\n", total);
+  else if (radix == radix_decimal)
+    printf (" = %" PRId64 "\n", total);
+  else
+    printf (" = %" PRIo64 "\n", total);
+}
+
+
+static void
+handle_elf (Elf *elf, const char *prefix, const char *fname)
+{
+  size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
+  size_t fname_len = strlen (fname) + 1;
+  char fullname[prefix_len + 1 + fname_len];
+  char *cp = fullname;
+
+  /* Create the full name of the file.  */
+  if (prefix != NULL)
+    {
+      cp = mempcpy (cp, prefix, prefix_len);
+      *cp++ = ':';
+    }
+  memcpy (cp, fname, fname_len);
+
+  if (format == format_sysv)
+    show_sysv (elf, prefix, fname, fullname);
+  else if (format == format_sysv_one_line)
+    show_sysv_one_line (elf);
+  else if (format == format_segments)
+    show_segments (elf, fullname);
+  else
+    {
+      print_header (elf);
+
+      show_bsd (elf, prefix, fname, fullname);
+    }
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/stack.c b/third_party/elfutils/src/stack.c
new file mode 100644
index 0000000..52ae3a8
--- /dev/null
+++ b/third_party/elfutils/src/stack.c
@@ -0,0 +1,759 @@
+/* Unwinding of frames like gstack/pstack.
+   Copyright (C) 2013-2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <argp.h>
+#include <error.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <string.h>
+#include <locale.h>
+#include <fcntl.h>
+#include ELFUTILS_HEADER(dwfl)
+
+#include <dwarf.h>
+#include <system.h>
+#include <printversion.h>
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+/* non-printable argp options.  */
+#define OPT_DEBUGINFO	0x100
+#define OPT_COREFILE	0x101
+
+static bool show_activation = false;
+static bool show_module = false;
+static bool show_build_id = false;
+static bool show_source = false;
+static bool show_one_tid = false;
+static bool show_quiet = false;
+static bool show_raw = false;
+static bool show_modules = false;
+static bool show_debugname = false;
+static bool show_inlines = false;
+
+static int maxframes = 256;
+
+struct frame
+{
+  Dwarf_Addr pc;
+  bool isactivation;
+};
+
+struct frames
+{
+  int frames;
+  int allocated;
+  struct frame *frame;
+};
+
+static Dwfl *dwfl = NULL;
+static pid_t pid = 0;
+static int core_fd = -1;
+static Elf *core = NULL;
+static const char *exec = NULL;
+static char *debuginfo_path = NULL;
+
+static const Dwfl_Callbacks proc_callbacks =
+  {
+    .find_elf = dwfl_linux_proc_find_elf,
+    .find_debuginfo = dwfl_standard_find_debuginfo,
+    .debuginfo_path = &debuginfo_path,
+  };
+
+static const Dwfl_Callbacks core_callbacks =
+  {
+    .find_elf = dwfl_build_id_find_elf,
+    .find_debuginfo = dwfl_standard_find_debuginfo,
+    .debuginfo_path = &debuginfo_path,
+  };
+
+#ifdef USE_DEMANGLE
+static size_t demangle_buffer_len = 0;
+static char *demangle_buffer = NULL;
+#endif
+
+/* Whether any frames have been shown at all.  Determines exit status.  */
+static bool frames_shown = false;
+
+/* Program exit codes. All frames shown without any errors is GOOD.
+   Some frames shown with some non-fatal errors is an ERROR.  A fatal
+   error or no frames shown at all is BAD.  A command line USAGE exit
+   is generated by argp_error.  */
+#define EXIT_OK     0
+#define EXIT_ERROR  1
+#define EXIT_BAD    2
+#define EXIT_USAGE 64
+
+static int
+get_addr_width (Dwfl_Module *mod)
+{
+  // Try to find the address wide if possible.
+  static int width = 0;
+  if (width == 0 && mod)
+    {
+      Dwarf_Addr bias;
+      Elf *elf = dwfl_module_getelf (mod, &bias);
+      if (elf)
+        {
+	  GElf_Ehdr ehdr_mem;
+	  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+	  if (ehdr)
+	    width = ehdr->e_ident[EI_CLASS] == ELFCLASS32 ? 8 : 16;
+	}
+    }
+  if (width == 0)
+    width = 16;
+
+  return width;
+}
+
+static int
+module_callback (Dwfl_Module *mod, void **userdata __attribute__((unused)),
+		 const char *name, Dwarf_Addr start,
+		 void *arg __attribute__((unused)))
+{
+  /* Forces resolving of main elf and debug files. */
+  Dwarf_Addr bias;
+  Elf *elf = dwfl_module_getelf (mod, &bias);
+  Dwarf *dwarf = dwfl_module_getdwarf (mod, &bias);
+
+  Dwarf_Addr end;
+  const char *mainfile;
+  const char *debugfile;
+  const char *modname = dwfl_module_info (mod, NULL, NULL, &end, NULL,
+                                          NULL, &mainfile, &debugfile);
+  assert (strcmp (modname, name) == 0);
+
+  int width = get_addr_width (mod);
+  printf ("0x%0*" PRIx64 "-0x%0*" PRIx64 " %s\n",
+	  width, start, width, end, basename (name));
+
+  const unsigned char *id;
+  GElf_Addr id_vaddr;
+  int id_len = dwfl_module_build_id (mod, &id, &id_vaddr);
+  if (id_len > 0)
+    {
+      printf ("  [");
+      do
+	printf ("%02" PRIx8, *id++);
+      while (--id_len > 0);
+      printf ("]\n");
+    }
+
+  if (elf != NULL)
+    printf ("  %s\n", mainfile != NULL ? mainfile : "-");
+  if (dwarf != NULL)
+    printf ("  %s\n", debugfile != NULL ? debugfile : "-");
+
+  return DWARF_CB_OK;
+}
+
+static int
+frame_callback (Dwfl_Frame *state, void *arg)
+{
+  struct frames *frames = (struct frames *) arg;
+  int nr = frames->frames;
+  if (! dwfl_frame_pc (state, &frames->frame[nr].pc,
+		       &frames->frame[nr].isactivation))
+    return -1;
+
+  frames->frames++;
+  if (frames->frames == maxframes)
+    return DWARF_CB_ABORT;
+
+  if (frames->frames == frames->allocated)
+    {
+      frames->allocated *= 2;
+      frames->frame = realloc (frames->frame,
+			       sizeof (struct frame) * frames->allocated);
+      if (frames->frame == NULL)
+	error (EXIT_BAD, errno, "realloc frames.frame");
+    }
+
+  return DWARF_CB_OK;
+}
+
+static const char*
+die_name (Dwarf_Die *die)
+{
+  Dwarf_Attribute attr;
+  const char *name;
+  name = dwarf_formstring (dwarf_attr_integrate (die,
+						 DW_AT_MIPS_linkage_name,
+						 &attr)
+			   ?: dwarf_attr_integrate (die,
+						    DW_AT_linkage_name,
+						    &attr));
+  if (name == NULL)
+    name = dwarf_diename (die);
+
+  return name;
+}
+
+static void
+print_frame (int nr, Dwarf_Addr pc, bool isactivation,
+	     Dwarf_Addr pc_adjusted, Dwfl_Module *mod,
+	     const char *symname, Dwarf_Die *cudie,
+	     Dwarf_Die *die)
+{
+  int width = get_addr_width (mod);
+  printf ("#%-2u 0x%0*" PRIx64, nr, width, (uint64_t) pc);
+
+  if (show_activation)
+    printf ("%4s", ! isactivation ? "- 1" : "");
+
+  if (symname != NULL)
+    {
+#ifdef USE_DEMANGLE
+      // Require GNU v3 ABI by the "_Z" prefix.
+      if (! show_raw && symname[0] == '_' && symname[1] == 'Z')
+	{
+	  int status = -1;
+	  char *dsymname = __cxa_demangle (symname, demangle_buffer,
+					   &demangle_buffer_len, &status);
+	  if (status == 0)
+	    symname = demangle_buffer = dsymname;
+	}
+#endif
+      printf (" %s", symname);
+    }
+
+  const char* fname;
+  Dwarf_Addr start;
+  fname = dwfl_module_info(mod, NULL, &start,
+			   NULL, NULL, NULL, NULL, NULL);
+  if (show_module)
+    {
+      if (fname != NULL)
+	printf (" - %s", fname);
+    }
+
+  if (show_build_id)
+    {
+      const unsigned char *id;
+      GElf_Addr id_vaddr;
+      int id_len = dwfl_module_build_id (mod, &id, &id_vaddr);
+      if (id_len > 0)
+	{
+	  printf ("\n    [");
+	  do
+	    printf ("%02" PRIx8, *id++);
+	  while (--id_len > 0);
+	  printf ("]@0x%0" PRIx64 "+0x%" PRIx64,
+		  start, pc_adjusted - start);
+	}
+    }
+
+  if (show_source)
+    {
+      int line, col;
+      const char* sname;
+      line = col = -1;
+      sname = NULL;
+      if (die != NULL)
+	{
+	  Dwarf_Files *files;
+	  if (dwarf_getsrcfiles (cudie, &files, NULL) == 0)
+	    {
+	      Dwarf_Attribute attr;
+	      Dwarf_Word val;
+	      if (dwarf_formudata (dwarf_attr (die, DW_AT_call_file, &attr),
+				   &val) == 0)
+		{
+		  sname = dwarf_filesrc (files, val, NULL, NULL);
+		  if (dwarf_formudata (dwarf_attr (die, DW_AT_call_line,
+						   &attr), &val) == 0)
+		    {
+		      line = val;
+		      if (dwarf_formudata (dwarf_attr (die, DW_AT_call_column,
+						       &attr), &val) == 0)
+			col = val;
+		    }
+		}
+	    }
+	}
+      else
+	{
+	  Dwfl_Line *lineobj = dwfl_module_getsrc(mod, pc_adjusted);
+	  if (lineobj)
+	    sname = dwfl_lineinfo (lineobj, NULL, &line, &col, NULL, NULL);
+	}
+
+      if (sname != NULL)
+	{
+	  printf ("\n    %s", sname);
+	  if (line > 0)
+	    {
+	      printf (":%d", line);
+	      if (col > 0)
+		printf (":%d", col);
+	    }
+	}
+    }
+  printf ("\n");
+}
+
+static void
+print_inline_frames (int *nr, Dwarf_Addr pc, bool isactivation,
+		     Dwarf_Addr pc_adjusted, Dwfl_Module *mod,
+		     const char *symname, Dwarf_Die *cudie, Dwarf_Die *die)
+{
+  Dwarf_Die *scopes = NULL;
+  int nscopes = dwarf_getscopes_die (die, &scopes);
+  if (nscopes > 0)
+    {
+      /* scopes[0] == die, the lowest level, for which we already have
+	 the name.  This is the actual source location where it
+	 happened.  */
+      print_frame ((*nr)++, pc, isactivation, pc_adjusted, mod, symname,
+		   NULL, NULL);
+
+      /* last_scope is the source location where the next frame/function
+	 call was done. */
+      Dwarf_Die *last_scope = &scopes[0];
+      for (int i = 1; i < nscopes && (maxframes == 0 || *nr < maxframes); i++)
+	{
+	  Dwarf_Die *scope = &scopes[i];
+	  int tag = dwarf_tag (scope);
+	  if (tag != DW_TAG_inlined_subroutine
+	      && tag != DW_TAG_entry_point
+	      && tag != DW_TAG_subprogram)
+	    continue;
+
+	  symname = die_name (scope);
+	  print_frame ((*nr)++, pc, isactivation, pc_adjusted, mod, symname,
+		       cudie, last_scope);
+
+	  /* Found the "top-level" in which everything was inlined?  */
+	  if (tag == DW_TAG_subprogram)
+	    break;
+
+	  last_scope = scope;
+	}
+    }
+  free (scopes);
+}
+
+static void
+print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what)
+{
+  if (frames->frames > 0)
+    frames_shown = true;
+
+  printf ("TID %lld:\n", (long long) tid);
+  int frame_nr = 0;
+  for (int nr = 0; nr < frames->frames && (maxframes == 0
+					   || frame_nr < maxframes); nr++)
+    {
+      Dwarf_Addr pc = frames->frame[nr].pc;
+      bool isactivation = frames->frame[nr].isactivation;
+      Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1);
+
+      /* Get PC->SYMNAME.  */
+      Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted);
+      const char *symname = NULL;
+      Dwarf_Die die_mem;
+      Dwarf_Die *die = NULL;
+      Dwarf_Die *cudie = NULL;
+      if (mod && ! show_quiet)
+	{
+	  if (show_debugname)
+	    {
+	      Dwarf_Addr bias = 0;
+	      Dwarf_Die *scopes = NULL;
+	      cudie = dwfl_module_addrdie (mod, pc_adjusted, &bias);
+	      int nscopes = dwarf_getscopes (cudie, pc_adjusted - bias,
+					     &scopes);
+
+	      /* Find the first function-like DIE with a name in scope.  */
+	      for (int i = 0; symname == NULL && i < nscopes; i++)
+		{
+		  Dwarf_Die *scope = &scopes[i];
+		  int tag = dwarf_tag (scope);
+		  if (tag == DW_TAG_subprogram
+		      || tag == DW_TAG_inlined_subroutine
+		      || tag == DW_TAG_entry_point)
+		    symname = die_name (scope);
+
+		  if (symname != NULL)
+		    {
+		      die_mem = *scope;
+		      die = &die_mem;
+		    }
+		}
+	      free (scopes);
+	    }
+
+	  if (symname == NULL)
+	    symname = dwfl_module_addrname (mod, pc_adjusted);
+	}
+
+      if (show_inlines && die != NULL)
+	print_inline_frames (&frame_nr, pc, isactivation, pc_adjusted, mod,
+			     symname, cudie, die);
+      else
+	print_frame (frame_nr++, pc, isactivation, pc_adjusted, mod, symname,
+		     NULL, NULL);
+    }
+
+  if (frames->frames > 0 && frame_nr == maxframes)
+    error (0, 0, "tid %lld: shown max number of frames "
+	   "(%d, use -n 0 for unlimited)", (long long) tid, maxframes);
+  else if (dwflerr != 0)
+    {
+      if (frames->frames > 0)
+	{
+	  unsigned nr = frames->frames - 1;
+	  Dwarf_Addr pc = frames->frame[nr].pc;
+	  bool isactivation = frames->frame[nr].isactivation;
+	  Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1);
+	  Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted);
+	  const char *mainfile = NULL;
+	  const char *modname = dwfl_module_info (mod, NULL, NULL, NULL, NULL,
+						  NULL, &mainfile, NULL);
+	  if (modname == NULL || modname[0] == '\0')
+	    {
+	      if (mainfile != NULL)
+		modname = mainfile;
+	      else
+		modname = "<unknown>";
+	    }
+	  error (0, 0, "%s tid %lld at 0x%" PRIx64 " in %s: %s", what,
+		 (long long) tid, pc_adjusted, modname, dwfl_errmsg (dwflerr));
+	}
+      else
+	error (0, 0, "%s tid %lld: %s", what, (long long) tid,
+	       dwfl_errmsg (dwflerr));
+    }
+}
+
+static int
+thread_callback (Dwfl_Thread *thread, void *thread_arg)
+{
+  struct frames *frames = (struct frames *) thread_arg;
+  pid_t tid = dwfl_thread_tid (thread);
+  int err = 0;
+  frames->frames = 0;
+  switch (dwfl_thread_getframes (thread, frame_callback, thread_arg))
+    {
+    case DWARF_CB_OK:
+    case DWARF_CB_ABORT:
+      break;
+    case -1:
+      err = dwfl_errno ();
+      break;
+    default:
+      abort ();
+    }
+  print_frames (frames, tid, err, "dwfl_thread_getframes");
+  return DWARF_CB_OK;
+}
+
+static error_t
+parse_opt (int key, char *arg __attribute__ ((unused)),
+	   struct argp_state *state)
+{
+  switch (key)
+    {
+    case 'p':
+      pid = atoi (arg);
+      if (pid == 0)
+	argp_error (state, N_("-p PID should be a positive process id."));
+      break;
+
+    case OPT_COREFILE:
+      core_fd = open (arg, O_RDONLY);
+      if (core_fd < 0)
+	error (EXIT_BAD, errno, N_("Cannot open core file '%s'"), arg);
+      elf_version (EV_CURRENT);
+      core = elf_begin (core_fd, ELF_C_READ_MMAP, NULL);
+      if (core == NULL)
+	error (EXIT_BAD, 0, "core '%s' elf_begin: %s", arg, elf_errmsg(-1));
+      break;
+
+    case 'e':
+      exec = arg;
+      break;
+
+    case OPT_DEBUGINFO:
+      debuginfo_path = arg;
+      break;
+
+    case 'm':
+      show_module = true;
+      break;
+
+    case 's':
+      show_source = true;
+      break;
+
+    case 'a':
+      show_activation = true;
+      break;
+
+    case 'd':
+      show_debugname = true;
+      break;
+
+    case 'i':
+      show_inlines = show_debugname = true;
+      break;
+
+    case 'v':
+      show_activation = show_source = show_module = show_debugname = true;
+      show_inlines = true;
+      break;
+
+    case 'b':
+      show_build_id = true;
+      break;
+
+    case 'q':
+      show_quiet = true;
+      break;
+
+    case 'r':
+      show_raw = true;
+      break;
+
+    case '1':
+      show_one_tid = true;
+      break;
+
+    case 'n':
+      maxframes = atoi (arg);
+      if (maxframes < 0)
+	{
+	  argp_error (state, N_("-n MAXFRAMES should be 0 or higher."));
+	  return EINVAL;
+	}
+      break;
+
+    case 'l':
+      show_modules = true;
+      break;
+
+    case ARGP_KEY_END:
+      if (core == NULL && exec != NULL)
+	argp_error (state,
+		    N_("-e EXEC needs a core given by --core."));
+
+      if (pid == 0 && show_one_tid == true)
+	argp_error (state,
+		    N_("-1 needs a thread id given by -p."));
+
+      if ((pid == 0 && core == NULL) || (pid != 0 && core != NULL))
+	argp_error (state,
+		    N_("One of -p PID or --core COREFILE should be given."));
+
+      if (pid != 0)
+	{
+	  dwfl = dwfl_begin (&proc_callbacks);
+	  if (dwfl == NULL)
+	    error (EXIT_BAD, 0, "dwfl_begin: %s", dwfl_errmsg (-1));
+
+	  int err = dwfl_linux_proc_report (dwfl, pid);
+	  if (err < 0)
+	    error (EXIT_BAD, 0, "dwfl_linux_proc_report pid %lld: %s",
+		   (long long) pid, dwfl_errmsg (-1));
+	  else if (err > 0)
+	    error (EXIT_BAD, err, "dwfl_linux_proc_report pid %lld",
+		   (long long) pid);
+	}
+
+      if (core != NULL)
+	{
+	  dwfl = dwfl_begin (&core_callbacks);
+	  if (dwfl == NULL)
+	    error (EXIT_BAD, 0, "dwfl_begin: %s", dwfl_errmsg (-1));
+	  if (dwfl_core_file_report (dwfl, core, exec) < 0)
+	    error (EXIT_BAD, 0, "dwfl_core_file_report: %s", dwfl_errmsg (-1));
+	}
+
+      if (dwfl_report_end (dwfl, NULL, NULL) != 0)
+	error (EXIT_BAD, 0, "dwfl_report_end: %s", dwfl_errmsg (-1));
+
+      if (pid != 0)
+	{
+	  int err = dwfl_linux_proc_attach (dwfl, pid, false);
+	  if (err < 0)
+	    error (EXIT_BAD, 0, "dwfl_linux_proc_attach pid %lld: %s",
+		   (long long) pid, dwfl_errmsg (-1));
+	  else if (err > 0)
+	    error (EXIT_BAD, err, "dwfl_linux_proc_attach pid %lld",
+		   (long long) pid);
+	}
+
+      if (core != NULL)
+	{
+	  if (dwfl_core_file_attach (dwfl, core) < 0)
+	    error (EXIT_BAD, 0, "dwfl_core_file_report: %s", dwfl_errmsg (-1));
+	}
+
+      /* Makes sure we are properly attached.  */
+      if (dwfl_pid (dwfl) < 0)
+	error (EXIT_BAD, 0, "dwfl_pid: %s\n", dwfl_errmsg (-1));
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+  __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  const struct argp_option options[] =
+    {
+      { NULL, 0, NULL, 0, N_("Input selection options:"), 0 },
+      { "pid", 'p', "PID", 0,
+	N_("Show stack of process PID"), 0 },
+      { "core", OPT_COREFILE, "COREFILE", 0,
+	N_("Show stack found in COREFILE"), 0 },
+      {  "executable", 'e', "EXEC", 0, N_("(optional) EXECUTABLE that produced COREFILE"), 0 },
+      { "debuginfo-path", OPT_DEBUGINFO, "PATH", 0,
+	N_("Search path for separate debuginfo files"), 0 },
+
+      { NULL, 0, NULL, 0, N_("Output selection options:"), 0 },
+      { "activation",  'a', NULL, 0,
+	N_("Additionally show frame activation"), 0 },
+      { "debugname",  'd', NULL, 0,
+	N_("Additionally try to lookup DWARF debuginfo name for frame address"),
+	0 },
+      { "inlines",  'i', NULL, 0,
+	N_("Additionally show inlined function frames using DWARF debuginfo if available (implies -d)"), 0 },
+      { "module",  'm', NULL, 0,
+	N_("Additionally show module file information"), 0 },
+      { "source",  's', NULL, 0,
+	N_("Additionally show source file information"), 0 },
+      { "verbose", 'v', NULL, 0,
+	N_("Show all additional information (activation, debugname, inlines, module and source)"), 0 },
+      { "quiet", 'q', NULL, 0,
+	N_("Do not resolve address to function symbol name"), 0 },
+      { "raw", 'r', NULL, 0,
+	N_("Show raw function symbol names, do not try to demangle names"), 0 },
+      { "build-id",  'b', NULL, 0,
+	N_("Show module build-id, load address and pc offset"), 0 },
+      { NULL, '1', NULL, 0,
+	N_("Show the backtrace of only one thread"), 0 },
+      { NULL, 'n', "MAXFRAMES", 0,
+	N_("Show at most MAXFRAMES per thread (default 256, use 0 for unlimited)"), 0 },
+      { "list-modules", 'l', NULL, 0,
+	N_("Show module memory map with build-id, elf and debug files detected"), 0 },
+      { NULL, 0, NULL, 0, NULL, 0 }
+    };
+
+  const struct argp argp =
+    {
+      .options = options,
+      .parser = parse_opt,
+      .doc = N_("Print a stack for each thread in a process or core file.\n\
+\n\
+Program exits with return code 0 if all frames were shown without \
+any errors.  If some frames were shown, but there were some non-fatal \
+errors, possibly causing an incomplete backtrace, the program exits \
+with return code 1.  If no frames could be shown, or a fatal error \
+occured the program exits with return code 2.  If the program was \
+invoked with bad or missing arguments it will exit with return code 64.")
+    };
+
+  argp_parse (&argp, argc, argv, 0, NULL, NULL);
+
+  if (show_modules)
+    {
+      printf ("PID %lld - %s module memory map\n", (long long) dwfl_pid (dwfl),
+	      pid != 0 ? "process" : "core");
+      if (dwfl_getmodules (dwfl, module_callback, NULL, 0) != 0)
+	error (EXIT_BAD, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
+    }
+
+  struct frames frames;
+  /* When maxframes is zero, then 2048 is just the initial allocation
+     that will be increased using realloc in framecallback ().  */
+  frames.allocated = maxframes == 0 ? 2048 : maxframes;
+  frames.frames = 0;
+  frames.frame = malloc (sizeof (struct frame) * frames.allocated);
+  if (frames.frame == NULL)
+    error (EXIT_BAD, errno, "malloc frames.frame");
+
+  if (show_one_tid)
+    {
+      int err = 0;
+      switch (dwfl_getthread_frames (dwfl, pid, frame_callback, &frames))
+	{
+	case DWARF_CB_OK:
+	case DWARF_CB_ABORT:
+	  break;
+	case -1:
+	  err = dwfl_errno ();
+	  break;
+	default:
+	  abort ();
+	}
+      print_frames (&frames, pid, err, "dwfl_getthread_frames");
+    }
+  else
+    {
+      printf ("PID %lld - %s\n", (long long) dwfl_pid (dwfl),
+	      pid != 0 ? "process" : "core");
+      switch (dwfl_getthreads (dwfl, thread_callback, &frames))
+	{
+	case DWARF_CB_OK:
+	case DWARF_CB_ABORT:
+	  break;
+	case -1:
+	  error (0, 0, "dwfl_getthreads: %s", dwfl_errmsg (-1));
+	  break;
+	default:
+	  abort ();
+	}
+    }
+  free (frames.frame);
+  dwfl_end (dwfl);
+
+  if (core != NULL)
+    elf_end (core);
+
+  if (core_fd != -1)
+    close (core_fd);
+
+#ifdef USE_DEMANGLE
+  free (demangle_buffer);
+#endif
+
+  if (! frames_shown)
+    error (EXIT_BAD, 0, N_("Couldn't show any frames."));
+
+  return error_message_count != 0 ? EXIT_ERROR : EXIT_OK;
+}
diff --git a/third_party/elfutils/src/strings.c b/third_party/elfutils/src/strings.c
new file mode 100644
index 0000000..03d0f13
--- /dev/null
+++ b/third_party/elfutils/src/strings.c
@@ -0,0 +1,748 @@
+/* Print the strings of printable characters in files.
+   Copyright (C) 2005-2010, 2012, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <assert.h>
+#include <ctype.h>
+#include <endian.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <libeu.h>
+#include <system.h>
+#include <printversion.h>
+
+#ifndef MAP_POPULATE
+# define MAP_POPULATE 0
+#endif
+
+
+/* Prototypes of local functions.  */
+static int read_fd (int fd, const char *fname, off_t fdlen);
+static int read_elf (Elf *elf, int fd, const char *fname, off_t fdlen);
+
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("Output Selection:"), 0 },
+  { "all", 'a', NULL, 0, N_("Scan entire file, not only loaded sections"), 0 },
+  { "bytes", 'n', "MIN-LEN", 0,
+    N_("Only NUL-terminated sequences of MIN-LEN characters or more are printed"), 0 },
+  { "encoding", 'e', "SELECTOR", 0, N_("\
+Select character size and endianess: s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit"),
+    0},
+  { "print-file-name", 'f', NULL, 0,
+    N_("Print name of the file before each string."), 0 },
+  { "radix", 't', "{o,d,x}", 0,
+    N_("Print location of the string in base 8, 10, or 16 respectively."), 0 },
+  { NULL, 'o', NULL, 0, N_("Alias for --radix=o"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Miscellaneous:"), 0 },
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("\
+Print the strings of printable characters in files.");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("[FILE...]");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  options, parse_opt, args_doc, doc, NULL, NULL, NULL
+};
+
+
+/* Global variables.  */
+
+/* True if whole file and not only loaded sections are looked at.  */
+static bool entire_file;
+
+/* Minimum length of any sequence reported.  */
+static size_t min_len = 4;
+
+/* Number of bytes per character.  */
+static size_t bytes_per_char = 1;
+
+/* Minimum length of any sequence reported in bytes.  */
+static size_t min_len_bytes;
+
+/* True if multibyte characters are in big-endian order.  */
+static bool big_endian;
+
+/* True unless 7-bit ASCII are expected.  */
+static bool char_7bit;
+
+/* True if file names should be printed before strings.  */
+static bool print_file_name;
+
+/* Radix for printed numbers.  */
+static enum
+{
+  radix_none = 0,
+  radix_decimal,
+  radix_hex,
+  radix_octal
+} radix = radix_none;
+
+
+/* Page size in use.  */
+static size_t ps;
+
+
+/* Mapped parts of the ELF file.  */
+static unsigned char *elfmap;
+static unsigned char *elfmap_base;
+static size_t elfmap_size;
+static off_t elfmap_off;
+
+
+int
+main (int argc, char *argv[])
+{
+  /* We use no threads.  */
+  __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  /* Make sure the message catalog can be found.  */
+  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+
+  /* Initialize the message catalog.  */
+  (void) textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  */
+  int remaining;
+  (void) argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+  /* Tell the library which version we are expecting.  */
+  elf_version (EV_CURRENT);
+
+  /* Determine the page size.  We will likely need it a couple of times.  */
+  ps = sysconf (_SC_PAGESIZE);
+
+  struct stat st;
+  int result = 0;
+  if (remaining == argc)
+    /* We read from standard input.  This we cannot do for a
+       structured file.  */
+    result = read_fd (STDIN_FILENO,
+		      print_file_name ? "{standard input}" : NULL,
+		      (fstat (STDIN_FILENO, &st) == 0 && S_ISREG (st.st_mode))
+		      ? st.st_size : INT64_C (0x7fffffffffffffff));
+  else
+    do
+      {
+	int fd = (strcmp (argv[remaining], "-") == 0
+		  ? STDIN_FILENO : open (argv[remaining], O_RDONLY));
+	if (unlikely (fd == -1))
+	  {
+	    error (0, errno, gettext ("cannot open '%s'"), argv[remaining]);
+	    result = 1;
+	  }
+	else
+	  {
+	    const char *fname = print_file_name ? argv[remaining] : NULL;
+	    int fstat_fail = fstat (fd, &st);
+	    off_t fdlen = (fstat_fail
+			     ? INT64_C (0x7fffffffffffffff) : st.st_size);
+	    if (fdlen > (off_t) min_len_bytes)
+	      {
+		Elf *elf = NULL;
+		if (entire_file
+		    || fstat_fail
+		    || !S_ISREG (st.st_mode)
+		    || (elf = elf_begin (fd, ELF_C_READ, NULL)) == NULL
+		    || elf_kind (elf) != ELF_K_ELF)
+		  result |= read_fd (fd, fname, fdlen);
+		else
+		  result |= read_elf (elf, fd, fname, fdlen);
+
+		/* This call will succeed even if ELF is NULL.  */
+		elf_end (elf);
+	      }
+
+	    if (strcmp (argv[remaining], "-") != 0)
+	      close (fd);
+	  }
+
+	if (elfmap != NULL && elfmap != MAP_FAILED)
+	  munmap (elfmap, elfmap_size);
+	elfmap = NULL;
+      }
+    while (++remaining < argc);
+
+  return result;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg,
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case 'a':
+      entire_file = true;
+      break;
+
+    case 'e':
+      /* We expect a string of one character.  */
+      switch (arg[1] != '\0' ? '\0' : arg[0])
+	{
+	case 's':
+	case 'S':
+	  char_7bit = arg[0] == 's';
+	  bytes_per_char = 1;
+	  break;
+
+	case 'b':
+	case 'B':
+	  big_endian = true;
+	  FALLTHROUGH;
+
+	case 'l':
+	case 'L':
+	  bytes_per_char = isupper (arg[0]) ? 4 : 2;
+	  break;
+
+	default:
+	  error (0, 0, gettext ("invalid value '%s' for %s parameter"),
+		 arg, "-e");
+	  argp_help (&argp, stderr, ARGP_HELP_SEE, "strings");
+	  return ARGP_ERR_UNKNOWN;
+	}
+      break;
+
+    case 'f':
+      print_file_name = true;
+      break;
+
+    case 'n':
+      min_len = atoi (arg);
+      break;
+
+    case 'o':
+      goto octfmt;
+
+    case 't':
+      switch (arg[0])
+	{
+	case 'd':
+	  radix = radix_decimal;
+	  break;
+
+	case 'o':
+	octfmt:
+	  radix = radix_octal;
+	  break;
+
+	case 'x':
+	  radix = radix_hex;
+	  break;
+
+	default:
+	  error (0, 0, gettext ("invalid value '%s' for %s parameter"),
+		 arg, "-t");
+	  argp_help (&argp, stderr, ARGP_HELP_SEE, "strings");
+	  return ARGP_ERR_UNKNOWN;
+	}
+      break;
+
+    case ARGP_KEY_FINI:
+      /* Compute the length in bytes of any match.  */
+      if (min_len <= 0 || min_len > INT_MAX / bytes_per_char)
+	error (EXIT_FAILURE, 0,
+	       gettext ("invalid minimum length of matched string size"));
+      min_len_bytes = min_len * bytes_per_char;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+static void
+process_chunk_mb (const char *fname, const unsigned char *buf, off_t to,
+		  size_t len, char **unprinted)
+{
+  size_t curlen = *unprinted == NULL ? 0 : strlen (*unprinted);
+  const unsigned char *start = buf;
+  while (len >= bytes_per_char)
+    {
+      uint32_t ch;
+
+      if (bytes_per_char == 2)
+	{
+	  if (big_endian)
+	    ch = buf[0] << 8 | buf[1];
+	  else
+	    ch = buf[1] << 8 | buf[0];
+	}
+      else
+	{
+	  if (big_endian)
+	    ch = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
+	  else
+	    ch = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
+	}
+
+      if (ch <= 255 && (isprint (ch) || ch == '\t'))
+	{
+	  ++buf;
+	  ++curlen;
+	}
+      else
+	{
+	  if (curlen >= min_len)
+	    {
+	      /* We found a match.  */
+	      if (unlikely (fname != NULL))
+		{
+		  fputs_unlocked (fname, stdout);
+		  fputs_unlocked (": ", stdout);
+		}
+
+	      if (unlikely (radix != radix_none))
+		printf ((radix == radix_octal ? "%7" PRIo64 " "
+			 : (radix == radix_decimal ? "%7" PRId64 " "
+			    : "%7" PRIx64 " ")),
+			(int64_t) to - len - (buf - start));
+
+	      if (unlikely (*unprinted != NULL))
+		{
+		  fputs_unlocked (*unprinted, stdout);
+		  free (*unprinted);
+		  *unprinted = NULL;
+		}
+
+	      /* There is no sane way of printing the string.  If we
+		 assume the file data is encoded in UCS-2/UTF-16 or
+		 UCS-4/UTF-32 respectively we could covert the string.
+		 But there is no such guarantee.  */
+	      fwrite_unlocked (start, 1, buf - start, stdout);
+	      putc_unlocked ('\n', stdout);
+	    }
+
+	  start = ++buf;
+	  curlen =  0;
+
+	  if (len <= min_len)
+	    break;
+	}
+
+      --len;
+    }
+
+  if (curlen != 0)
+    *unprinted = xstrndup ((const char *) start, curlen);
+}
+
+
+static void
+process_chunk (const char *fname, const unsigned char *buf, off_t to,
+	       size_t len, char **unprinted)
+{
+  /* We are not going to slow the check down for the 2- and 4-byte
+     encodings.  Handle them special.  */
+  if (unlikely (bytes_per_char != 1))
+    {
+      process_chunk_mb (fname, buf, to, len, unprinted);
+      return;
+    }
+
+  size_t curlen = *unprinted == NULL ? 0 : strlen (*unprinted);
+  const unsigned char *start = buf;
+  while (len > 0)
+    {
+      if ((isprint (*buf) || *buf == '\t') && (! char_7bit || *buf <= 127))
+	{
+	  ++buf;
+	  ++curlen;
+	}
+      else
+	{
+	  if (curlen >= min_len)
+	    {
+	      /* We found a match.  */
+	      if (likely (fname != NULL))
+		{
+		  fputs_unlocked (fname, stdout);
+		  fputs_unlocked (": ", stdout);
+		}
+
+	      if (likely (radix != radix_none))
+		printf ((radix == radix_octal ? "%7" PRIo64 " "
+			 : (radix == radix_decimal ? "%7" PRId64 " "
+			    : "%7" PRIx64 " ")),
+			(int64_t) to - len - (buf - start));
+
+	      if (unlikely (*unprinted != NULL))
+		{
+		  fputs_unlocked (*unprinted, stdout);
+		  free (*unprinted);
+		  *unprinted = NULL;
+		}
+	      fwrite_unlocked (start, 1, buf - start, stdout);
+	      putc_unlocked ('\n', stdout);
+	    }
+
+	  start = ++buf;
+	  curlen =  0;
+
+	  if (len <= min_len)
+	    break;
+	}
+
+      --len;
+    }
+
+  if (curlen != 0)
+    *unprinted = xstrndup ((const char *) start, curlen);
+}
+
+
+/* Map a file in as large chunks as possible.  */
+static void *
+map_file (int fd, off_t start_off, off_t fdlen, size_t *map_sizep)
+{
+  /* Maximum size we mmap.  We use an #ifdef to avoid overflows on
+     32-bit machines.  64-bit machines these days do not have usable
+     address spaces larger than about 43 bits.  Not that any file
+     should be that large.  */
+# if SIZE_MAX > 0xffffffff
+  const size_t mmap_max = 0x4000000000lu;
+# else
+  const size_t mmap_max = 0x40000000lu;
+# endif
+
+  /* Try to mmap the file.  */
+  size_t map_size = MIN ((off_t) mmap_max, fdlen);
+  const size_t map_size_min = MAX (MAX (SIZE_MAX / 16, 2 * ps),
+				   roundup (2 * min_len_bytes + 1, ps));
+  void *mem;
+  while (1)
+    {
+      /* We map the memory for reading only here.  Since we will
+	 always look at every byte of the file it makes sense to
+	 use MAP_POPULATE.  */
+      mem = mmap (NULL, map_size, PROT_READ, MAP_PRIVATE | MAP_POPULATE,
+		  fd, start_off);
+      if (mem != MAP_FAILED)
+	{
+	  /* We will go through the mapping sequentially.  */
+	  (void) posix_madvise (mem, map_size, POSIX_MADV_SEQUENTIAL);
+	  break;
+	}
+      if (errno != EINVAL && errno != ENOMEM)
+	/* This is an error other than the lack of address space.  */
+	break;
+
+      /* Maybe the size of the mapping is too big.  Try again.  */
+      map_size /= 2;
+      if (map_size < map_size_min)
+	/* That size should have fit.  */
+	break;
+    }
+
+  *map_sizep = map_size;
+  return mem;
+}
+
+
+/* Read the file without mapping.  */
+static int
+read_block_no_mmap (int fd, const char *fname, off_t from, off_t fdlen)
+{
+  char *unprinted = NULL;
+#define CHUNKSIZE 65536
+  unsigned char *buf = xmalloc (CHUNKSIZE + min_len_bytes
+				+ bytes_per_char - 1);
+  size_t ntrailer = 0;
+  int result = 0;
+  while (fdlen > 0)
+    {
+      ssize_t n = TEMP_FAILURE_RETRY (read (fd, buf + ntrailer,
+					    MIN (fdlen, CHUNKSIZE)));
+      if (n == 0)
+	{
+	  /* There are less than MIN_LEN+1 bytes left so there cannot be
+	     another match.  */
+	  assert (unprinted == NULL || ntrailer == 0);
+	  break;
+	}
+      if (unlikely (n < 0))
+	{
+	  /* Something went wrong.  */
+	  result = 1;
+	  break;
+	}
+
+      /* Account for the number of bytes read in this round.  */
+      fdlen -= n;
+
+      /* Do not use the signed N value.  Note that the addition cannot
+	 overflow.  */
+      size_t nb = (size_t) n + ntrailer;
+      if (nb >= min_len_bytes)
+	{
+	  /* We only use complete characters.  */
+	  nb &= ~(bytes_per_char - 1);
+
+	  process_chunk (fname, buf, from + nb, nb, &unprinted);
+
+	  /* If the last bytes of the buffer (modulo the character
+	     size) have been printed we are not copying them.  */
+	  size_t to_keep = unprinted != NULL ? 0 : min_len_bytes;
+
+	  memmove (buf, buf + nb - to_keep, to_keep);
+	  ntrailer = to_keep;
+	  from += nb;
+	}
+      else
+	ntrailer = nb;
+    }
+
+  free (buf);
+
+  /* Don't print anything we collected so far.  There is no
+     terminating NUL byte.  */
+  free (unprinted);
+
+  return result;
+}
+
+
+static int
+read_block (int fd, const char *fname, off_t fdlen, off_t from, off_t to)
+{
+  if (elfmap == NULL)
+    {
+      /* We need a completely new mapping.  */
+      elfmap_off = from & ~(ps - 1);
+      elfmap_base = elfmap = map_file (fd, elfmap_off, fdlen, &elfmap_size);
+
+      if (unlikely (elfmap == MAP_FAILED))
+	/* Let the kernel know we are going to read everything in sequence.  */
+	(void) posix_fadvise (fd, 0, 0, POSIX_FADV_SEQUENTIAL);
+    }
+
+  if (unlikely (elfmap == MAP_FAILED))
+    {
+      /* Read from the file descriptor.  For this we must position the
+	 read pointer.  */
+      // XXX Eventually add flag which avoids this if the position
+      // XXX is known to match.
+      if (from != 0 && lseek (fd, from, SEEK_SET) != from)
+	error (EXIT_FAILURE, errno, gettext ("lseek failed"));
+
+      return read_block_no_mmap (fd, fname, from, to - from);
+    }
+
+  assert ((off_t) min_len_bytes < fdlen);
+
+  if (to < (off_t) elfmap_off || from > (off_t) (elfmap_off + elfmap_size))
+    {
+      /* The existing mapping cannot fit at all.  Map the new area.
+	 We always map the full range of ELFMAP_SIZE bytes even if
+	 this extend beyond the end of the file.  The Linux kernel
+	 handles this OK if the access pages are not touched.  */
+      elfmap_off = from & ~(ps - 1);
+      if (mmap (elfmap, elfmap_size, PROT_READ,
+		MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, from)
+	  == MAP_FAILED)
+	error (EXIT_FAILURE, errno, gettext ("re-mmap failed"));
+      elfmap_base = elfmap;
+    }
+
+  char *unprinted = NULL;
+
+  /* Use the existing mapping as much as possible.  If necessary, map
+     new pages.  */
+  if (from >= (off_t) elfmap_off
+      && from < (off_t) (elfmap_off + elfmap_size))
+    /* There are at least a few bytes in this mapping which we can
+       use.  */
+    process_chunk (fname, elfmap_base + (from - elfmap_off),
+		   MIN (to, (off_t) (elfmap_off + elfmap_size)),
+		   MIN (to, (off_t) (elfmap_off + elfmap_size)) - from,
+		   &unprinted);
+
+  if (to > (off_t) (elfmap_off + elfmap_size))
+    {
+      unsigned char *remap_base = elfmap_base;
+      size_t read_now = elfmap_size - (elfmap_base - elfmap);
+
+      assert (from >= (off_t) elfmap_off
+	      && from < (off_t) (elfmap_off + elfmap_size));
+      off_t handled_to = elfmap_off + elfmap_size;
+      assert (elfmap == elfmap_base
+	      || (elfmap_base - elfmap
+		  == (ptrdiff_t) ((min_len_bytes + ps - 1) & ~(ps - 1))));
+      if (elfmap == elfmap_base)
+	{
+	  size_t keep_area = (min_len_bytes + ps - 1) & ~(ps - 1);
+	  assert (elfmap_size >= keep_area + ps);
+	  /* The keep area is used for the content of the previous
+	     buffer we have to keep.  This means copying those bytes
+	     and for this we have to make the data writable.  */
+	  if (unlikely (mprotect (elfmap, keep_area, PROT_READ | PROT_WRITE)
+			!= 0))
+	    error (EXIT_FAILURE, errno, gettext ("mprotect failed"));
+
+	  elfmap_base = elfmap + keep_area;
+	}
+
+      while (1)
+	{
+	  /* Map the rest of the file, eventually again in pieces.
+	     We speed things up with a nice Linux feature.  Note
+	     that we have at least two pages mapped.  */
+	  size_t to_keep = unprinted != NULL ? 0 : min_len_bytes;
+
+	  assert (read_now >= to_keep);
+	  memmove (elfmap_base - to_keep,
+		   remap_base + read_now - to_keep, to_keep);
+	  remap_base = elfmap_base;
+
+	  assert ((elfmap_size - (elfmap_base - elfmap)) % bytes_per_char
+		  == 0);
+	  read_now = MIN (to - handled_to,
+			  (ptrdiff_t) elfmap_size - (elfmap_base - elfmap));
+
+	  assert (handled_to % ps == 0);
+	  assert (handled_to % bytes_per_char == 0);
+	  if (mmap (remap_base, read_now, PROT_READ,
+		    MAP_PRIVATE | MAP_POPULATE | MAP_FIXED, fd, handled_to)
+	      == MAP_FAILED)
+	    error (EXIT_FAILURE, errno, gettext ("re-mmap failed"));
+	  elfmap_off = handled_to;
+
+	  process_chunk (fname, remap_base - to_keep,
+			 elfmap_off + (read_now & ~(bytes_per_char - 1)),
+			 to_keep + (read_now & ~(bytes_per_char - 1)),
+			 &unprinted);
+	  handled_to += read_now;
+	  if (handled_to >= to)
+	    break;
+	}
+    }
+
+  /* Don't print anything we collected so far.  There is no
+     terminating NUL byte.  */
+  free (unprinted);
+
+  return 0;
+}
+
+
+static int
+read_fd (int fd, const char *fname, off_t fdlen)
+{
+  return read_block (fd, fname, fdlen, 0, fdlen);
+}
+
+
+static int
+read_elf (Elf *elf, int fd, const char *fname, off_t fdlen)
+{
+  assert (fdlen >= 0);
+
+  /* We will look at each section separately.  The ELF file is not
+     mmapped.  The libelf implementation will load the needed parts on
+     demand.  Since we only interate over the section header table the
+     memory consumption at this stage is kept minimal.  */
+  Elf_Scn *scn = elf_nextscn (elf, NULL);
+  if (scn == NULL)
+    return read_fd (fd, fname, fdlen);
+
+  int result = 0;
+  do
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+      /* Only look in sections which are loaded at runtime and
+	 actually have content.  */
+      if (shdr != NULL && shdr->sh_type != SHT_NOBITS
+	  && (shdr->sh_flags & SHF_ALLOC) != 0)
+	{
+	  if (shdr->sh_offset > (Elf64_Off) fdlen
+	      || fdlen - shdr->sh_offset < shdr->sh_size)
+	    {
+	      size_t strndx = 0;
+	      const char *sname;
+	      if (unlikely (elf_getshdrstrndx (elf, &strndx) < 0))
+		sname = "<unknown>";
+	      else
+		sname = elf_strptr (elf, strndx, shdr->sh_name) ?: "<unknown>";
+	      error (0, 0,
+		     gettext ("Skipping section %zd '%s' data outside file"),
+		     elf_ndxscn (scn), sname);
+	      result = 1;
+	    }
+	  else
+	    result |= read_block (fd, fname, fdlen, shdr->sh_offset,
+				  shdr->sh_offset + shdr->sh_size);
+	}
+    }
+  while ((scn = elf_nextscn (elf, scn)) != NULL);
+
+  if (elfmap != NULL && elfmap != MAP_FAILED)
+    munmap (elfmap, elfmap_size);
+  elfmap = NULL;
+
+  return result;
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/strip.c b/third_party/elfutils/src/strip.c
new file mode 100644
index 0000000..773ed54
--- /dev/null
+++ b/third_party/elfutils/src/strip.c
@@ -0,0 +1,2427 @@
+/* Discard section not used at runtime from object files.
+   Copyright (C) 2000-2012, 2014, 2015, 2016, 2017 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <assert.h>
+#include <byteswap.h>
+#include <endian.h>
+#include <error.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <elf-knowledge.h>
+#include <libebl.h>
+#include "libdwelf.h"
+#include <libeu.h>
+#include <system.h>
+#include <printversion.h>
+
+typedef uint8_t GElf_Byte;
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+
+/* Values for the parameters which have no short form.  */
+#define OPT_REMOVE_COMMENT	0x100
+#define OPT_PERMISSIVE		0x101
+#define OPT_STRIP_SECTIONS	0x102
+#define OPT_RELOC_DEBUG 	0x103
+#define OPT_KEEP_SECTION 	0x104
+
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  { NULL, 0, NULL, 0, N_("Output selection:"), 0 },
+  { "output", 'o', "FILE", 0, N_("Place stripped output into FILE"), 0 },
+  { NULL, 'f', "FILE", 0, N_("Extract the removed sections into FILE"), 0 },
+  { NULL, 'F', "FILE", 0, N_("Embed name FILE instead of -f argument"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Output options:"), 0 },
+  { "strip-all", 's', NULL, OPTION_HIDDEN, NULL, 0 },
+  { "strip-debug", 'g', NULL, 0, N_("Remove all debugging symbols"), 0 },
+  { NULL, 'd', NULL, OPTION_ALIAS, NULL, 0 },
+  { NULL, 'S', NULL, OPTION_ALIAS, NULL, 0 },
+  { "strip-sections", OPT_STRIP_SECTIONS, NULL, 0,
+    N_("Remove section headers (not recommended)"), 0 },
+  { "preserve-dates", 'p', NULL, 0,
+    N_("Copy modified/access timestamps to the output"), 0 },
+  { "reloc-debug-sections", OPT_RELOC_DEBUG, NULL, 0,
+    N_("Resolve all trivial relocations between debug sections if the removed sections are placed in a debug file (only relevant for ET_REL files, operation is not reversable, needs -f)"), 0 },
+  { "remove-comment", OPT_REMOVE_COMMENT, NULL, 0,
+    N_("Remove .comment section"), 0 },
+  { "remove-section", 'R', "SECTION", 0, N_("Remove the named section.  SECTION is an extended wildcard pattern.  May be given more than once.  Only non-allocated sections can be removed."), 0 },
+  { "keep-section", OPT_KEEP_SECTION, "SECTION", 0, N_("Keep the named section.  SECTION is an extended wildcard pattern.  May be given more than once."), 0 },
+  { "permissive", OPT_PERMISSIVE, NULL, 0,
+    N_("Relax a few rules to handle slightly broken ELF files"), 0 },
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+/* Short description of program.  */
+static const char doc[] = N_("Discard symbols from object files.");
+
+/* Strings for arguments in help texts.  */
+static const char args_doc[] = N_("[FILE...]");
+
+/* Prototype for option handler.  */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions.  */
+static struct argp argp =
+{
+  options, parse_opt, args_doc, doc, NULL, NULL, NULL
+};
+
+
+/* Print symbols in file named FNAME.  */
+static int process_file (const char *fname);
+
+/* Handle one ELF file.  */
+static int handle_elf (int fd, Elf *elf, const char *prefix,
+		       const char *fname, mode_t mode, struct timespec tvp[2]);
+
+/* Handle all files contained in the archive.  */
+static int handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
+		      struct timespec tvp[2]) __attribute__ ((unused));
+
+static int debug_fd = -1;
+static char *tmp_debug_fname = NULL;
+
+/* Close debug file descriptor, if opened. And remove temporary debug file.  */
+static void cleanup_debug (void);
+
+#define INTERNAL_ERROR(fname) \
+  do { \
+    cleanup_debug (); \
+    error (EXIT_FAILURE, 0, gettext ("%s: INTERNAL ERROR %d (%s): %s"),      \
+	   fname, __LINE__, PACKAGE_VERSION, elf_errmsg (-1)); \
+  } while (0)
+
+
+/* Name of the output file.  */
+static const char *output_fname;
+
+/* Name of the debug output file.  */
+static const char *debug_fname;
+
+/* Name to pretend the debug output file has.  */
+static const char *debug_fname_embed;
+
+/* If true output files shall have same date as the input file.  */
+static bool preserve_dates;
+
+/* If true .comment sections will be removed.  */
+static bool remove_comment;
+
+/* If true remove all debug sections.  */
+static bool remove_debug;
+
+/* If true remove all section headers.  */
+static bool remove_shdrs;
+
+/* If true relax some ELF rules for input files.  */
+static bool permissive;
+
+/* If true perform relocations between debug sections.  */
+static bool reloc_debug;
+
+/* Sections the user explicitly wants to keep or remove.  */
+struct section_pattern
+{
+  char *pattern;
+  struct section_pattern *next;
+};
+
+static struct section_pattern *keep_secs = NULL;
+static struct section_pattern *remove_secs = NULL;
+
+static void
+add_pattern (struct section_pattern **patterns, const char *pattern)
+{
+  struct section_pattern *p = xmalloc (sizeof *p);
+  p->pattern = xstrdup (pattern);
+  p->next = *patterns;
+  *patterns = p;
+}
+
+static void
+free_sec_patterns (struct section_pattern *patterns)
+{
+  struct section_pattern *pattern = patterns;
+  while (pattern != NULL)
+    {
+      struct section_pattern *p = pattern;
+      pattern = p->next;
+      free (p->pattern);
+      free (p);
+    }
+}
+
+static void
+free_patterns (void)
+{
+  free_sec_patterns (keep_secs);
+  free_sec_patterns (remove_secs);
+}
+
+static bool
+section_name_matches (struct section_pattern *patterns, const char *name)
+{
+  struct section_pattern *pattern = patterns;
+  while (pattern != NULL)
+    {
+      if (fnmatch (pattern->pattern, name, FNM_EXTMATCH) == 0)
+	return true;
+      pattern = pattern->next;
+    }
+  return false;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+  int result = 0;
+
+  /* We use no threads here which can interfere with handling a stream.  */
+  __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+  __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  setlocale (LC_ALL, "");
+
+  /* Make sure the message catalog can be found.  */
+  bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+
+  /* Initialize the message catalog.  */
+  textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  */
+  if (argp_parse (&argp, argc, argv, 0, &remaining, NULL) != 0)
+    return EXIT_FAILURE;
+
+  if (reloc_debug && debug_fname == NULL)
+    error (EXIT_FAILURE, 0,
+	   gettext ("--reloc-debug-sections used without -f"));
+
+  /* Tell the library which version we are expecting.  */
+  elf_version (EV_CURRENT);
+
+  if (remaining == argc)
+    /* The user didn't specify a name so we use a.out.  */
+    result = process_file ("a.out");
+  else
+    {
+      /* If we have seen the '-o' or '-f' option there must be exactly one
+	 input file.  */
+      if ((output_fname != NULL || debug_fname != NULL)
+	  && remaining + 1 < argc)
+	error (EXIT_FAILURE, 0, gettext ("\
+Only one input file allowed together with '-o' and '-f'"));
+
+      /* Process all the remaining files.  */
+      do
+	result |= process_file (argv[remaining]);
+      while (++remaining < argc);
+    }
+
+  free_patterns ();
+  return result;
+}
+
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+  switch (key)
+    {
+    case 'f':
+      if (debug_fname != NULL)
+	{
+	  error (0, 0, gettext ("-f option specified twice"));
+	  return EINVAL;
+	}
+      debug_fname = arg;
+      break;
+
+    case 'F':
+      if (debug_fname_embed != NULL)
+	{
+	  error (0, 0, gettext ("-F option specified twice"));
+	  return EINVAL;
+	}
+      debug_fname_embed = arg;
+      break;
+
+    case 'o':
+      if (output_fname != NULL)
+	{
+	  error (0, 0, gettext ("-o option specified twice"));
+	  return EINVAL;
+	}
+      output_fname = arg;
+      break;
+
+    case 'p':
+      preserve_dates = true;
+      break;
+
+    case OPT_RELOC_DEBUG:
+      reloc_debug = true;
+      break;
+
+    case OPT_REMOVE_COMMENT:
+      remove_comment = true;
+      break;
+
+    case 'R':
+      if (fnmatch (arg, ".comment", FNM_EXTMATCH) == 0)
+	remove_comment = true;
+      add_pattern (&remove_secs, arg);
+      break;
+
+    case OPT_KEEP_SECTION:
+      add_pattern (&keep_secs, arg);
+      break;
+
+    case 'g':
+    case 'd':
+    case 'S':
+      remove_debug = true;
+      break;
+
+    case OPT_STRIP_SECTIONS:
+      remove_shdrs = true;
+      break;
+
+    case OPT_PERMISSIVE:
+      permissive = true;
+      break;
+
+    case 's':			/* Ignored for compatibility.  */
+      break;
+
+    case ARGP_KEY_SUCCESS:
+      if (remove_comment == true
+	  && section_name_matches (keep_secs, ".comment"))
+	{
+	  argp_error (state,
+		      gettext ("cannot both keep and remove .comment section"));
+	  return EINVAL;
+	}
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+
+static int
+process_file (const char *fname)
+{
+  /* If we have to preserve the modify and access timestamps get them
+     now.  We cannot use fstat() after opening the file since the open
+     would change the access time.  */
+  struct stat pre_st;
+  struct timespec tv[2];
+ again:
+  if (preserve_dates)
+    {
+      if (stat (fname, &pre_st) != 0)
+	{
+	  error (0, errno, gettext ("cannot stat input file '%s'"), fname);
+	  return 1;
+	}
+
+      /* If we have to preserve the timestamp, we need it in the
+	 format utimes() understands.  */
+      tv[0] = pre_st.st_atim;
+      tv[1] = pre_st.st_mtim;
+    }
+
+  /* Open the file.  */
+  int fd = open (fname, output_fname == NULL ? O_RDWR : O_RDONLY);
+  if (fd == -1)
+    {
+      error (0, errno, gettext ("while opening '%s'"), fname);
+      return 1;
+    }
+
+  /* We always use fstat() even if we called stat() before.  This is
+     done to make sure the information returned by stat() is for the
+     same file.  */
+  struct stat st;
+  if (fstat (fd, &st) != 0)
+    {
+      error (0, errno, gettext ("cannot stat input file '%s'"), fname);
+      return 1;
+    }
+  /* Paranoid mode on.  */
+  if (preserve_dates
+      && (st.st_ino != pre_st.st_ino || st.st_dev != pre_st.st_dev))
+    {
+      /* We detected a race.  Try again.  */
+      close (fd);
+      goto again;
+    }
+
+  /* Now get the ELF descriptor.  */
+  Elf *elf = elf_begin (fd, output_fname == NULL ? ELF_C_RDWR : ELF_C_READ,
+			NULL);
+  int result;
+  switch (elf_kind (elf))
+    {
+    case ELF_K_ELF:
+      result = handle_elf (fd, elf, NULL, fname, st.st_mode & ACCESSPERMS,
+			   preserve_dates ? tv : NULL);
+      break;
+
+    case ELF_K_AR:
+      /* It is not possible to strip the content of an archive direct
+	 the output to a specific file.  */
+      if (unlikely (output_fname != NULL || debug_fname != NULL))
+	{
+	  error (0, 0, gettext ("%s: cannot use -o or -f when stripping archive"),
+		 fname);
+	  result = 1;
+	}
+      else
+	{
+	  /* We would like to support ar archives, but currently it just
+	     doesn't work at all since we call elf_clone on the members
+	     which doesn't really support ar members.
+	     result = handle_ar (fd, elf, NULL, fname,
+				 preserve_dates ? tv : NULL);
+	   */
+	  error (0, 0, gettext ("%s: no support for stripping archive"),
+		 fname);
+	  result = 1;
+	}
+      break;
+
+    default:
+      error (0, 0, gettext ("%s: File format not recognized"), fname);
+      result = 1;
+      break;
+    }
+
+  if (unlikely (elf_end (elf) != 0))
+    INTERNAL_ERROR (fname);
+
+  close (fd);
+
+  return result;
+}
+
+
+/* Maximum size of array allocated on stack.  */
+#define MAX_STACK_ALLOC	(400 * 1024)
+
+static int
+handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
+	    mode_t mode, struct timespec tvp[2])
+{
+  size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
+  size_t fname_len = strlen (fname) + 1;
+  char *fullname = alloca (prefix_len + 1 + fname_len);
+  char *cp = fullname;
+  Elf *debugelf = NULL;
+  tmp_debug_fname = NULL;
+  int result = 0;
+  size_t shdridx = 0;
+  size_t shstrndx;
+  struct shdr_info
+  {
+    Elf_Scn *scn;
+    GElf_Shdr shdr;
+    Elf_Data *data;
+    Elf_Data *debug_data;
+    const char *name;
+    Elf32_Word idx;		/* Index in new file.  */
+    Elf32_Word old_sh_link;	/* Original value of shdr.sh_link.  */
+    Elf32_Word symtab_idx;
+    Elf32_Word version_idx;
+    Elf32_Word group_idx;
+    Elf32_Word group_cnt;
+    Elf_Scn *newscn;
+    Dwelf_Strent *se;
+    Elf32_Word *newsymidx;
+  } *shdr_info = NULL;
+  Elf_Scn *scn;
+  size_t cnt;
+  size_t idx;
+  bool changes;
+  GElf_Ehdr newehdr_mem;
+  GElf_Ehdr *newehdr;
+  GElf_Ehdr debugehdr_mem;
+  GElf_Ehdr *debugehdr;
+  Dwelf_Strtab *shst = NULL;
+  Elf_Data debuglink_crc_data;
+  bool any_symtab_changes = false;
+  Elf_Data *shstrtab_data = NULL;
+  void *debuglink_buf = NULL;
+
+  /* Create the full name of the file.  */
+  if (prefix != NULL)
+    {
+      cp = mempcpy (cp, prefix, prefix_len);
+      *cp++ = ':';
+    }
+  memcpy (cp, fname, fname_len);
+
+  /* If we are not replacing the input file open a new file here.  */
+  if (output_fname != NULL)
+    {
+      fd = open (output_fname, O_RDWR | O_CREAT, mode);
+      if (unlikely (fd == -1))
+	{
+	  error (0, errno, gettext ("cannot open '%s'"), output_fname);
+	  return 1;
+	}
+    }
+
+  debug_fd = -1;
+
+  /* Get the EBL handling.  Removing all debugging symbols with the -g
+     option or resolving all relocations between debug sections with
+     the --reloc-debug-sections option are currently the only reasons
+     we need EBL so don't open the backend unless necessary.  */
+  Ebl *ebl = NULL;
+  if (remove_debug || reloc_debug)
+    {
+      ebl = ebl_openbackend (elf);
+      if (ebl == NULL)
+	{
+	  error (0, errno, gettext ("cannot open EBL backend"));
+	  result = 1;
+	  goto fail;
+	}
+    }
+
+  /* Open the additional file the debug information will be stored in.  */
+  if (debug_fname != NULL)
+    {
+      /* Create a temporary file name.  We do not want to overwrite
+	 the debug file if the file would not contain any
+	 information.  */
+      size_t debug_fname_len = strlen (debug_fname);
+      tmp_debug_fname = (char *) xmalloc (debug_fname_len + sizeof (".XXXXXX"));
+      strcpy (mempcpy (tmp_debug_fname, debug_fname, debug_fname_len),
+	      ".XXXXXX");
+
+      debug_fd = mkstemp (tmp_debug_fname);
+      if (unlikely (debug_fd == -1))
+	{
+	  error (0, errno, gettext ("cannot open '%s'"), debug_fname);
+	  result = 1;
+	  goto fail;
+	}
+    }
+
+  /* Get the information from the old file.  */
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    INTERNAL_ERROR (fname);
+
+  /* Get the section header string table index.  */
+  if (unlikely (elf_getshdrstrndx (elf, &shstrndx) < 0))
+    {
+      cleanup_debug ();
+      error (EXIT_FAILURE, 0,
+	     gettext ("cannot get section header string table index"));
+    }
+
+  /* Get the number of phdrs in the old file.  */
+  size_t phnum;
+  if (elf_getphdrnum (elf, &phnum) != 0)
+    {
+      cleanup_debug ();
+      error (EXIT_FAILURE, 0, gettext ("cannot get number of phdrs"));
+    }
+
+  /* We now create a new ELF descriptor for the same file.  We
+     construct it almost exactly in the same way with some information
+     dropped.  */
+  Elf *newelf;
+  if (output_fname != NULL)
+    newelf = elf_begin (fd, ELF_C_WRITE_MMAP, NULL);
+  else
+    newelf = elf_clone (elf, ELF_C_EMPTY);
+
+  if (unlikely (gelf_newehdr (newelf, gelf_getclass (elf)) == 0)
+      || (ehdr->e_type != ET_REL
+	  && unlikely (gelf_newphdr (newelf, phnum) == 0)))
+    {
+      error (0, 0, gettext ("cannot create new file '%s': %s"),
+	     output_fname ?: fname, elf_errmsg (-1));
+      goto fail;
+    }
+
+  /* Copy over the old program header if needed.  */
+  if (ehdr->e_type != ET_REL)
+    for (cnt = 0; cnt < phnum; ++cnt)
+      {
+	GElf_Phdr phdr_mem;
+	GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
+	if (phdr == NULL
+	    || unlikely (gelf_update_phdr (newelf, cnt, phdr) == 0))
+	  INTERNAL_ERROR (fname);
+      }
+
+  if (debug_fname != NULL)
+    {
+      /* Also create an ELF descriptor for the debug file */
+      debugelf = elf_begin (debug_fd, ELF_C_WRITE_MMAP, NULL);
+      if (unlikely (gelf_newehdr (debugelf, gelf_getclass (elf)) == 0)
+	  || (ehdr->e_type != ET_REL
+	      && unlikely (gelf_newphdr (debugelf, phnum) == 0)))
+	{
+	  error (0, 0, gettext ("cannot create new file '%s': %s"),
+		 debug_fname, elf_errmsg (-1));
+	  goto fail_close;
+	}
+
+      /* Copy over the old program header if needed.  */
+      if (ehdr->e_type != ET_REL)
+	for (cnt = 0; cnt < phnum; ++cnt)
+	  {
+	    GElf_Phdr phdr_mem;
+	    GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
+	    if (phdr == NULL
+		|| unlikely (gelf_update_phdr (debugelf, cnt, phdr) == 0))
+	      INTERNAL_ERROR (fname);
+	  }
+    }
+
+  /* Number of sections.  */
+  size_t shnum;
+  if (unlikely (elf_getshdrnum (elf, &shnum) < 0))
+    {
+      error (0, 0, gettext ("cannot determine number of sections: %s"),
+	     elf_errmsg (-1));
+      goto fail_close;
+    }
+
+  if (shstrndx >= shnum)
+    goto illformed;
+
+#define elf_assert(test) do { if (!(test)) goto illformed; } while (0)
+
+  /* Storage for section information.  We leave room for two more
+     entries since we unconditionally create a section header string
+     table.  Maybe some weird tool created an ELF file without one.
+     The other one is used for the debug link section.  */
+  if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
+    shdr_info = (struct shdr_info *) xcalloc (shnum + 2,
+					      sizeof (struct shdr_info));
+  else
+    {
+      shdr_info = (struct shdr_info *) alloca ((shnum + 2)
+					       * sizeof (struct shdr_info));
+      memset (shdr_info, '\0', (shnum + 2) * sizeof (struct shdr_info));
+    }
+
+  /* Prepare section information data structure.  */
+  scn = NULL;
+  cnt = 1;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      /* This should always be true (i.e., there should not be any
+	 holes in the numbering).  */
+      elf_assert (elf_ndxscn (scn) == cnt);
+
+      shdr_info[cnt].scn = scn;
+
+      /* Get the header.  */
+      if (gelf_getshdr (scn, &shdr_info[cnt].shdr) == NULL)
+	INTERNAL_ERROR (fname);
+
+      /* Get the name of the section.  */
+      shdr_info[cnt].name = elf_strptr (elf, shstrndx,
+					shdr_info[cnt].shdr.sh_name);
+      if (shdr_info[cnt].name == NULL)
+	{
+	illformed:
+	  error (0, 0, gettext ("illformed file '%s'"), fname);
+	  goto fail_close;
+	}
+
+      /* Sanity check the user.  */
+      if (section_name_matches (remove_secs, shdr_info[cnt].name))
+	{
+	  if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0)
+	    {
+	      error (0, 0,
+		     gettext ("Cannot remove allocated section '%s'"),
+		     shdr_info[cnt].name);
+	      result = 1;
+	      goto fail_close;
+	    }
+
+	  if (section_name_matches (keep_secs, shdr_info[cnt].name))
+	    {
+	      error (0, 0,
+		     gettext ("Cannot both keep and remove section '%s'"),
+		     shdr_info[cnt].name);
+	      result = 1;
+	      goto fail_close;
+	    }
+	}
+
+      /* Mark them as present but not yet investigated.  */
+      shdr_info[cnt].idx = 1;
+
+      /* Remember the shdr.sh_link value.  */
+      shdr_info[cnt].old_sh_link = shdr_info[cnt].shdr.sh_link;
+      if (shdr_info[cnt].old_sh_link >= shnum)
+	goto illformed;
+
+      /* Sections in files other than relocatable object files which
+	 not loaded can be freely moved by us.  In theory we can also
+	 freely move around allocated nobits sections.  But we don't
+	 to keep the layout of all allocated sections as similar as
+	 possible to the original file.  In relocatable object files
+	 everything can be moved.  */
+      if (ehdr->e_type == ET_REL
+	  || (shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) == 0)
+	shdr_info[cnt].shdr.sh_offset = 0;
+
+      /* If this is an extended section index table store an
+	 appropriate reference.  */
+      if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX))
+	{
+	  elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0);
+	  shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx = cnt;
+	}
+      else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GROUP))
+	{
+	  /* Cross-reference the sections contained in the section
+	     group.  */
+	  shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
+	  if (shdr_info[cnt].data == NULL
+	      || shdr_info[cnt].data->d_size < sizeof (Elf32_Word))
+	    INTERNAL_ERROR (fname);
+
+	  /* XXX Fix for unaligned access.  */
+	  Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
+	  size_t inner;
+	  for (inner = 1;
+	       inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
+	       ++inner)
+	    {
+	      if (grpref[inner] < shnum)
+		shdr_info[grpref[inner]].group_idx = cnt;
+	      else
+		goto illformed;
+	    }
+
+	  if (inner == 1 || (inner == 2 && (grpref[0] & GRP_COMDAT) == 0))
+	    /* If the section group contains only one element and this
+	       is n COMDAT section we can drop it right away.  */
+	    shdr_info[cnt].idx = 0;
+	  else
+	    shdr_info[cnt].group_cnt = inner - 1;
+	}
+      else if (unlikely (shdr_info[cnt].shdr.sh_type == SHT_GNU_versym))
+	{
+	  elf_assert (shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0);
+	  shdr_info[shdr_info[cnt].shdr.sh_link].version_idx = cnt;
+	}
+
+      /* If this section is part of a group make sure it is not
+	 discarded right away.  */
+      if ((shdr_info[cnt].shdr.sh_flags & SHF_GROUP) != 0)
+	{
+	  elf_assert (shdr_info[cnt].group_idx != 0);
+
+	  if (shdr_info[shdr_info[cnt].group_idx].idx == 0)
+	    {
+	      /* The section group section will be removed.  */
+	      shdr_info[cnt].group_idx = 0;
+	      shdr_info[cnt].shdr.sh_flags &= ~SHF_GROUP;
+	    }
+	}
+
+      /* Increment the counter.  */
+      ++cnt;
+    }
+
+  /* Now determine which sections can go away.  The general rule is that
+     all sections which are not used at runtime are stripped out.  But
+     there are a few exceptions:
+
+     - special sections named ".comment" and ".note" are kept
+     - OS or architecture specific sections are kept since we might not
+       know how to handle them
+     - if a section is referred to from a section which is not removed
+       in the sh_link or sh_info element it cannot be removed either
+     - the user might have explicitly said to remove or keep a section
+  */
+  for (cnt = 1; cnt < shnum; ++cnt)
+    /* Check whether the section can be removed.  Since we will create
+       a new .shstrtab assume it will be removed too.  */
+    if (remove_shdrs ? !(shdr_info[cnt].shdr.sh_flags & SHF_ALLOC)
+	: (ebl_section_strip_p (ebl, ehdr, &shdr_info[cnt].shdr,
+				shdr_info[cnt].name, remove_comment,
+				remove_debug)
+	   || cnt == ehdr->e_shstrndx
+	   || section_name_matches (remove_secs, shdr_info[cnt].name)))
+      {
+	/* The user might want to explicitly keep this one.  */
+	if (section_name_matches (keep_secs, shdr_info[cnt].name))
+	  continue;
+
+	/* For now assume this section will be removed.  */
+	shdr_info[cnt].idx = 0;
+
+	idx = shdr_info[cnt].group_idx;
+	while (idx != 0)
+	  {
+	    /* The section group data is already loaded.  */
+	    elf_assert (shdr_info[idx].data != NULL
+			&& shdr_info[idx].data->d_buf != NULL
+			&& shdr_info[idx].data->d_size >= sizeof (Elf32_Word));
+
+	    /* If the references section group is a normal section
+	       group and has one element remaining, or if it is an
+	       empty COMDAT section group it is removed.  */
+	    bool is_comdat = (((Elf32_Word *) shdr_info[idx].data->d_buf)[0]
+			      & GRP_COMDAT) != 0;
+
+	    --shdr_info[idx].group_cnt;
+	    if ((!is_comdat && shdr_info[idx].group_cnt == 1)
+		|| (is_comdat && shdr_info[idx].group_cnt == 0))
+	      {
+		shdr_info[idx].idx = 0;
+		/* Continue recursively.  */
+		idx = shdr_info[idx].group_idx;
+	      }
+	    else
+	      break;
+	  }
+      }
+
+  /* Mark the SHT_NULL section as handled.  */
+  shdr_info[0].idx = 2;
+
+
+  /* Handle exceptions: section groups and cross-references.  We might
+     have to repeat this a few times since the resetting of the flag
+     might propagate.  */
+  do
+    {
+      changes = false;
+
+      for (cnt = 1; cnt < shnum; ++cnt)
+	{
+	  if (shdr_info[cnt].idx == 0)
+	    {
+	      /* If a relocation section is marked as being removed make
+		 sure the section it is relocating is removed, too.  */
+	      if (shdr_info[cnt].shdr.sh_type == SHT_REL
+		   || shdr_info[cnt].shdr.sh_type == SHT_RELA)
+		{
+		  if (shdr_info[cnt].shdr.sh_info >= shnum)
+		    goto illformed;
+		  else if (shdr_info[shdr_info[cnt].shdr.sh_info].idx != 0)
+		    shdr_info[cnt].idx = 1;
+		}
+
+	      /* If a group section is marked as being removed make
+		 sure all the sections it contains are being removed, too.  */
+	      if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
+		{
+		  Elf32_Word *grpref;
+		  grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
+		  for (size_t in = 1;
+		       in < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
+		       ++in)
+		    if (grpref[in] < shnum)
+		      {
+			if (shdr_info[grpref[in]].idx != 0)
+			  {
+			    shdr_info[cnt].idx = 1;
+			    break;
+			  }
+		      }
+		    else
+		      goto illformed;
+		}
+	    }
+
+	  if (shdr_info[cnt].idx == 1)
+	    {
+	      /* The content of symbol tables we don't remove must not
+		 reference any section which we do remove.  Otherwise
+		 we cannot remove the section.  */
+	      if (debug_fname != NULL
+		  && shdr_info[cnt].debug_data == NULL
+		  && (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
+		      || shdr_info[cnt].shdr.sh_type == SHT_SYMTAB))
+		{
+		  /* Make sure the data is loaded.  */
+		  if (shdr_info[cnt].data == NULL)
+		    {
+		      shdr_info[cnt].data
+			= elf_getdata (shdr_info[cnt].scn, NULL);
+		      if (shdr_info[cnt].data == NULL)
+			INTERNAL_ERROR (fname);
+		    }
+		  Elf_Data *symdata = shdr_info[cnt].data;
+
+		  /* If there is an extended section index table load it
+		     as well.  */
+		  if (shdr_info[cnt].symtab_idx != 0
+		      && shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
+		    {
+		      elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB);
+
+		      shdr_info[shdr_info[cnt].symtab_idx].data
+			= elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
+				       NULL);
+		      if (shdr_info[shdr_info[cnt].symtab_idx].data == NULL)
+			INTERNAL_ERROR (fname);
+		    }
+		  Elf_Data *xndxdata
+		    = shdr_info[shdr_info[cnt].symtab_idx].data;
+
+		  /* Go through all symbols and make sure the section they
+		     reference is not removed.  */
+		  size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+
+		  for (size_t inner = 0;
+		       inner < shdr_info[cnt].data->d_size / elsize;
+		       ++inner)
+		    {
+		      GElf_Sym sym_mem;
+		      Elf32_Word xndx;
+		      GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
+							inner, &sym_mem,
+							&xndx);
+		      if (sym == NULL)
+			INTERNAL_ERROR (fname);
+
+		      size_t scnidx = sym->st_shndx;
+		      if (scnidx == SHN_UNDEF || scnidx >= shnum
+			  || (scnidx >= SHN_LORESERVE
+			      && scnidx <= SHN_HIRESERVE
+			      && scnidx != SHN_XINDEX)
+			  /* Don't count in the section symbols.  */
+			  || GELF_ST_TYPE (sym->st_info) == STT_SECTION)
+			/* This is no section index, leave it alone.  */
+			continue;
+		      else if (scnidx == SHN_XINDEX)
+			scnidx = xndx;
+
+		      if (scnidx >= shnum)
+			goto illformed;
+
+		      if (shdr_info[scnidx].idx == 0)
+			/* This symbol table has a real symbol in
+			   a discarded section.  So preserve the
+			   original table in the debug file.  Unless
+			   it is a redundant data marker to a debug
+			   (data only) section.  */
+			if (! (ebl_section_strip_p (ebl, ehdr,
+						    &shdr_info[scnidx].shdr,
+						    shdr_info[scnidx].name,
+						    remove_comment,
+						    remove_debug)
+			       && ebl_data_marker_symbol (ebl, sym,
+					elf_strptr (elf,
+						    shdr_info[cnt].shdr.sh_link,
+						    sym->st_name))))
+			  shdr_info[cnt].debug_data = symdata;
+		    }
+		}
+
+	      /* Cross referencing happens:
+		 - for the cases the ELF specification says.  That are
+		   + SHT_DYNAMIC in sh_link to string table
+		   + SHT_HASH in sh_link to symbol table
+		   + SHT_REL and SHT_RELA in sh_link to symbol table
+		   + SHT_SYMTAB and SHT_DYNSYM in sh_link to string table
+		   + SHT_GROUP in sh_link to symbol table
+		   + SHT_SYMTAB_SHNDX in sh_link to symbol table
+		   Other (OS or architecture-specific) sections might as
+		   well use this field so we process it unconditionally.
+		 - references inside section groups
+		 - specially marked references in sh_info if the SHF_INFO_LINK
+		 flag is set
+	      */
+
+	      if (shdr_info[shdr_info[cnt].shdr.sh_link].idx == 0)
+		{
+		  shdr_info[shdr_info[cnt].shdr.sh_link].idx = 1;
+		  changes |= shdr_info[cnt].shdr.sh_link < cnt;
+		}
+
+	      /* Handle references through sh_info.  */
+	      if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
+		{
+		  if (shdr_info[cnt].shdr.sh_info >= shnum)
+		    goto illformed;
+		  else if ( shdr_info[shdr_info[cnt].shdr.sh_info].idx == 0)
+		    {
+		      shdr_info[shdr_info[cnt].shdr.sh_info].idx = 1;
+		      changes |= shdr_info[cnt].shdr.sh_info < cnt;
+		    }
+		}
+
+	      /* Mark the section as investigated.  */
+	      shdr_info[cnt].idx = 2;
+	    }
+
+	  if (debug_fname != NULL
+	      && (shdr_info[cnt].idx == 0 || shdr_info[cnt].debug_data != NULL))
+	    {
+	      /* This section is being preserved in the debug file.
+		 Sections it refers to must be preserved there too.
+
+		 In this pass we mark sections to be preserved in both
+		 files by setting the .debug_data pointer to the original
+		 file's .data pointer.  Below, we'll copy the section
+		 contents.  */
+
+	      inline void check_preserved (size_t i)
+	      {
+		if (i != 0 && i < shnum + 2 && shdr_info[i].idx != 0
+		    && shdr_info[i].debug_data == NULL)
+		  {
+		    if (shdr_info[i].data == NULL)
+		      shdr_info[i].data = elf_getdata (shdr_info[i].scn, NULL);
+		    if (shdr_info[i].data == NULL)
+		      INTERNAL_ERROR (fname);
+
+		    shdr_info[i].debug_data = shdr_info[i].data;
+		    changes |= i < cnt;
+		  }
+	      }
+
+	      check_preserved (shdr_info[cnt].shdr.sh_link);
+	      if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
+		check_preserved (shdr_info[cnt].shdr.sh_info);
+	    }
+	}
+    }
+  while (changes);
+
+  /* Copy the removed sections to the debug output file.
+     The ones that are not removed in the stripped file are SHT_NOBITS.  */
+  if (debug_fname != NULL)
+    {
+      for (cnt = 1; cnt < shnum; ++cnt)
+	{
+	  scn = elf_newscn (debugelf);
+	  if (scn == NULL)
+	    {
+	      cleanup_debug ();
+	      error (EXIT_FAILURE, 0,
+		     gettext ("while generating output file: %s"),
+		     elf_errmsg (-1));
+	    }
+
+	  bool discard_section = (shdr_info[cnt].idx > 0
+				  && shdr_info[cnt].debug_data == NULL
+				  && shdr_info[cnt].shdr.sh_type != SHT_NOTE
+				  && shdr_info[cnt].shdr.sh_type != SHT_GROUP
+				  && cnt != ehdr->e_shstrndx);
+
+	  /* Set the section header in the new file.  */
+	  GElf_Shdr debugshdr = shdr_info[cnt].shdr;
+	  if (discard_section)
+	    debugshdr.sh_type = SHT_NOBITS;
+
+	  if (unlikely (gelf_update_shdr (scn, &debugshdr) == 0))
+	    /* There cannot be any overflows.  */
+	    INTERNAL_ERROR (fname);
+
+	  /* Get the data from the old file if necessary. */
+	  if (shdr_info[cnt].data == NULL)
+	    {
+	      shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
+	      if (shdr_info[cnt].data == NULL)
+		INTERNAL_ERROR (fname);
+	    }
+
+	  /* Set the data.  This is done by copying from the old file.  */
+	  Elf_Data *debugdata = elf_newdata (scn);
+	  if (debugdata == NULL)
+	    INTERNAL_ERROR (fname);
+
+	  /* Copy the structure.  This data may be modified in place
+	     before we write out the file.  */
+	  *debugdata = *shdr_info[cnt].data;
+	  if (discard_section)
+	    debugdata->d_buf = NULL;
+	  else if (shdr_info[cnt].debug_data != NULL
+		   || shdr_info[cnt].shdr.sh_type == SHT_GROUP)
+	    {
+	      /* Copy the original data before it gets modified.  */
+	      shdr_info[cnt].debug_data = debugdata;
+	      if (debugdata->d_buf == NULL)
+		INTERNAL_ERROR (fname);
+	      debugdata->d_buf = memcpy (xmalloc (debugdata->d_size),
+					 debugdata->d_buf, debugdata->d_size);
+	    }
+	}
+
+      /* Finish the ELF header.  Fill in the fields not handled by
+	 libelf from the old file.  */
+      debugehdr = gelf_getehdr (debugelf, &debugehdr_mem);
+      if (debugehdr == NULL)
+	INTERNAL_ERROR (fname);
+
+      memcpy (debugehdr->e_ident, ehdr->e_ident, EI_NIDENT);
+      debugehdr->e_type = ehdr->e_type;
+      debugehdr->e_machine = ehdr->e_machine;
+      debugehdr->e_version = ehdr->e_version;
+      debugehdr->e_entry = ehdr->e_entry;
+      debugehdr->e_flags = ehdr->e_flags;
+      debugehdr->e_shstrndx = ehdr->e_shstrndx;
+
+      if (unlikely (gelf_update_ehdr (debugelf, debugehdr) == 0))
+	{
+	  error (0, 0, gettext ("%s: error while creating ELF header: %s"),
+		 debug_fname, elf_errmsg (-1));
+	  result = 1;
+	  goto fail_close;
+	}
+    }
+
+  /* Although we always create a new section header string table we
+     don't explicitly mark the existing one as unused.  It can still
+     be used through a symbol table section we are keeping.  If not it
+     will already be marked as unused.  */
+
+  /* We need a string table for the section headers.  */
+  shst = dwelf_strtab_init (true);
+  if (shst == NULL)
+    {
+      cleanup_debug ();
+      error (EXIT_FAILURE, errno, gettext ("while preparing output for '%s'"),
+	     output_fname ?: fname);
+    }
+
+  /* Assign new section numbers.  */
+  shdr_info[0].idx = 0;
+  for (cnt = idx = 1; cnt < shnum; ++cnt)
+    if (shdr_info[cnt].idx > 0)
+      {
+	shdr_info[cnt].idx = idx++;
+
+	/* Create a new section.  */
+	shdr_info[cnt].newscn = elf_newscn (newelf);
+	if (shdr_info[cnt].newscn == NULL)
+	  {
+	    cleanup_debug ();
+	    error (EXIT_FAILURE, 0,
+		   gettext ("while generating output file: %s"),
+		   elf_errmsg (-1));
+	  }
+
+	elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
+
+	/* Add this name to the section header string table.  */
+	shdr_info[cnt].se = dwelf_strtab_add (shst, shdr_info[cnt].name);
+      }
+
+  /* Test whether we are doing anything at all.  Either all removable
+     sections are already gone.  Or the only section we would remove is
+     the .shstrtab section which we would add again.  */
+  bool removing_sections = !(cnt == idx
+			     || (cnt == idx + 1
+				 && shdr_info[ehdr->e_shstrndx].idx == 0));
+  if (output_fname == NULL && !removing_sections)
+      goto fail_close;
+
+  /* Create the reference to the file with the debug info (if any).  */
+  if (debug_fname != NULL && !remove_shdrs && removing_sections)
+    {
+      /* Add the section header string table section name.  */
+      shdr_info[cnt].se = dwelf_strtab_add_len (shst, ".gnu_debuglink", 15);
+      shdr_info[cnt].idx = idx++;
+
+      /* Create the section header.  */
+      shdr_info[cnt].shdr.sh_type = SHT_PROGBITS;
+      shdr_info[cnt].shdr.sh_flags = 0;
+      shdr_info[cnt].shdr.sh_addr = 0;
+      shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
+      shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
+      shdr_info[cnt].shdr.sh_entsize = 0;
+      shdr_info[cnt].shdr.sh_addralign = 4;
+      /* We set the offset to zero here.  Before we write the ELF file the
+	 field must have the correct value.  This is done in the final
+	 loop over all section.  Then we have all the information needed.  */
+      shdr_info[cnt].shdr.sh_offset = 0;
+
+      /* Create the section.  */
+      shdr_info[cnt].newscn = elf_newscn (newelf);
+      if (shdr_info[cnt].newscn == NULL)
+	{
+	  cleanup_debug ();
+	  error (EXIT_FAILURE, 0,
+		 gettext ("while create section header section: %s"),
+		 elf_errmsg (-1));
+	}
+      elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx);
+
+      shdr_info[cnt].data = elf_newdata (shdr_info[cnt].newscn);
+      if (shdr_info[cnt].data == NULL)
+	{
+	  cleanup_debug ();
+	  error (EXIT_FAILURE, 0, gettext ("cannot allocate section data: %s"),
+		 elf_errmsg (-1));
+	}
+
+      char *debug_basename = basename (debug_fname_embed ?: debug_fname);
+      off_t crc_offset = strlen (debug_basename) + 1;
+      /* Align to 4 byte boundary */
+      crc_offset = ((crc_offset - 1) & ~3) + 4;
+
+      shdr_info[cnt].data->d_align = 4;
+      shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size
+	= crc_offset + 4;
+      debuglink_buf = xcalloc (1, shdr_info[cnt].data->d_size);
+      shdr_info[cnt].data->d_buf = debuglink_buf;
+
+      strcpy (shdr_info[cnt].data->d_buf, debug_basename);
+
+      /* Cache this Elf_Data describing the CRC32 word in the section.
+	 We'll fill this in when we have written the debug file.  */
+      debuglink_crc_data = *shdr_info[cnt].data;
+      debuglink_crc_data.d_buf = ((char *) debuglink_crc_data.d_buf
+				  + crc_offset);
+      debuglink_crc_data.d_size = 4;
+
+      /* One more section done.  */
+      ++cnt;
+    }
+
+  /* Index of the section header table in the shdr_info array.  */
+  shdridx = cnt;
+
+  /* Add the section header string table section name.  */
+  shdr_info[cnt].se = dwelf_strtab_add_len (shst, ".shstrtab", 10);
+  shdr_info[cnt].idx = idx;
+
+  /* Create the section header.  */
+  shdr_info[cnt].shdr.sh_type = SHT_STRTAB;
+  shdr_info[cnt].shdr.sh_flags = 0;
+  shdr_info[cnt].shdr.sh_addr = 0;
+  shdr_info[cnt].shdr.sh_link = SHN_UNDEF;
+  shdr_info[cnt].shdr.sh_info = SHN_UNDEF;
+  shdr_info[cnt].shdr.sh_entsize = 0;
+  /* We set the offset to zero here.  Before we write the ELF file the
+     field must have the correct value.  This is done in the final
+     loop over all section.  Then we have all the information needed.  */
+  shdr_info[cnt].shdr.sh_offset = 0;
+  shdr_info[cnt].shdr.sh_addralign = 1;
+
+  /* Create the section.  */
+  shdr_info[cnt].newscn = elf_newscn (newelf);
+  if (shdr_info[cnt].newscn == NULL)
+    {
+      cleanup_debug ();
+      error (EXIT_FAILURE, 0,
+	     gettext ("while create section header section: %s"),
+	     elf_errmsg (-1));
+    }
+  elf_assert (elf_ndxscn (shdr_info[cnt].newscn) == idx);
+
+  /* Finalize the string table and fill in the correct indices in the
+     section headers.  */
+  shstrtab_data = elf_newdata (shdr_info[cnt].newscn);
+  if (shstrtab_data == NULL)
+    {
+      cleanup_debug ();
+      error (EXIT_FAILURE, 0,
+	     gettext ("while create section header string table: %s"),
+	     elf_errmsg (-1));
+    }
+  if (dwelf_strtab_finalize (shst, shstrtab_data) == NULL)
+    {
+      cleanup_debug ();
+      error (EXIT_FAILURE, 0,
+	     gettext ("no memory to create section header string table"));
+    }
+
+  /* We have to set the section size.  */
+  shdr_info[cnt].shdr.sh_size = shstrtab_data->d_size;
+
+  /* Update the section information.  */
+  GElf_Off lastoffset = 0;
+  for (cnt = 1; cnt <= shdridx; ++cnt)
+    if (shdr_info[cnt].idx > 0)
+      {
+	Elf_Data *newdata;
+
+	scn = elf_getscn (newelf, shdr_info[cnt].idx);
+	elf_assert (scn != NULL);
+
+	/* Update the name.  */
+	shdr_info[cnt].shdr.sh_name = dwelf_strent_off (shdr_info[cnt].se);
+
+	/* Update the section header from the input file.  Some fields
+	   might be section indeces which now have to be adjusted.  Keep
+	   the index to the "current" sh_link in case we need it to lookup
+	   symbol table names.  */
+	size_t sh_link = shdr_info[cnt].shdr.sh_link;
+	if (shdr_info[cnt].shdr.sh_link != 0)
+	  shdr_info[cnt].shdr.sh_link =
+	    shdr_info[shdr_info[cnt].shdr.sh_link].idx;
+
+	if (shdr_info[cnt].shdr.sh_type == SHT_GROUP)
+	  {
+	    elf_assert (shdr_info[cnt].data != NULL
+			&& shdr_info[cnt].data->d_buf != NULL);
+
+	    Elf32_Word *grpref = (Elf32_Word *) shdr_info[cnt].data->d_buf;
+	    for (size_t inner = 0;
+		 inner < shdr_info[cnt].data->d_size / sizeof (Elf32_Word);
+		 ++inner)
+	      if (grpref[inner] < shnum)
+		grpref[inner] = shdr_info[grpref[inner]].idx;
+	      else
+		goto illformed;
+	  }
+
+	/* Handle the SHT_REL, SHT_RELA, and SHF_INFO_LINK flag.  */
+	if (SH_INFO_LINK_P (&shdr_info[cnt].shdr))
+	  shdr_info[cnt].shdr.sh_info =
+	    shdr_info[shdr_info[cnt].shdr.sh_info].idx;
+
+	/* Get the data from the old file if necessary.  We already
+	   created the data for the section header string table.  */
+	if (cnt < shnum)
+	  {
+	    if (shdr_info[cnt].data == NULL)
+	      {
+		shdr_info[cnt].data = elf_getdata (shdr_info[cnt].scn, NULL);
+		if (shdr_info[cnt].data == NULL)
+		  INTERNAL_ERROR (fname);
+	      }
+
+	    /* Set the data.  This is done by copying from the old file.  */
+	    newdata = elf_newdata (scn);
+	    if (newdata == NULL)
+	      INTERNAL_ERROR (fname);
+
+	    /* Copy the structure.  */
+	    *newdata = *shdr_info[cnt].data;
+
+	    /* We know the size.  */
+	    shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size;
+
+	    /* We have to adjust symbol tables.  The st_shndx member might
+	       have to be updated.  */
+	    if (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM
+		|| shdr_info[cnt].shdr.sh_type == SHT_SYMTAB)
+	      {
+		Elf_Data *versiondata = NULL;
+		Elf_Data *shndxdata = NULL;
+
+		size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+
+		if (shdr_info[cnt].symtab_idx != 0)
+		  {
+		    elf_assert (shdr_info[cnt].shdr.sh_type == SHT_SYMTAB_SHNDX);
+		    /* This section has extended section information.
+		       We have to modify that information, too.  */
+		    shndxdata = elf_getdata (shdr_info[shdr_info[cnt].symtab_idx].scn,
+					     NULL);
+
+		    elf_assert (shndxdata != NULL
+				&& shndxdata->d_buf != NULL
+				&& ((shndxdata->d_size / sizeof (Elf32_Word))
+				    >= shdr_info[cnt].data->d_size / elsize));
+		  }
+
+		if (shdr_info[cnt].version_idx != 0)
+		  {
+		    elf_assert (shdr_info[cnt].shdr.sh_type == SHT_DYNSYM);
+		    /* This section has associated version
+		       information.  We have to modify that
+		       information, too.  */
+		    versiondata = elf_getdata (shdr_info[shdr_info[cnt].version_idx].scn,
+					       NULL);
+
+		    elf_assert (versiondata != NULL
+				&& versiondata->d_buf != NULL
+				&& ((versiondata->d_size / sizeof (GElf_Versym))
+				    >= shdr_info[cnt].data->d_size / elsize));
+		  }
+
+		shdr_info[cnt].newsymidx
+		  = (Elf32_Word *) xcalloc (shdr_info[cnt].data->d_size
+					    / elsize, sizeof (Elf32_Word));
+
+		bool last_was_local = true;
+		size_t destidx;
+		size_t inner;
+		for (destidx = inner = 1;
+		     inner < shdr_info[cnt].data->d_size / elsize;
+		     ++inner)
+		  {
+		    Elf32_Word sec;
+		    GElf_Sym sym_mem;
+		    Elf32_Word xshndx;
+		    GElf_Sym *sym = gelf_getsymshndx (shdr_info[cnt].data,
+						      shndxdata, inner,
+						      &sym_mem, &xshndx);
+		    if (sym == NULL)
+		      INTERNAL_ERROR (fname);
+
+		    if (sym->st_shndx == SHN_UNDEF
+			|| (sym->st_shndx >= shnum
+			    && sym->st_shndx != SHN_XINDEX))
+		      {
+			/* This is no section index, leave it alone
+			   unless it is moved.  */
+			if (destidx != inner
+			    && gelf_update_symshndx (shdr_info[cnt].data,
+						     shndxdata,
+						     destidx, sym,
+						     xshndx) == 0)
+			  INTERNAL_ERROR (fname);
+
+			shdr_info[cnt].newsymidx[inner] = destidx++;
+
+			if (last_was_local
+			    && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
+			  {
+			    last_was_local = false;
+			    shdr_info[cnt].shdr.sh_info = destidx - 1;
+			  }
+
+			continue;
+		      }
+
+		    /* Get the full section index, if necessary from the
+		       XINDEX table.  */
+		    if (sym->st_shndx == SHN_XINDEX)
+		      elf_assert (shndxdata != NULL
+				  && shndxdata->d_buf != NULL);
+		    size_t sidx = (sym->st_shndx != SHN_XINDEX
+				   ? sym->st_shndx : xshndx);
+		    sec = shdr_info[sidx].idx;
+
+		    if (sec != 0)
+		      {
+			GElf_Section nshndx;
+			Elf32_Word nxshndx;
+
+			if (sec < SHN_LORESERVE)
+			  {
+			    nshndx = sec;
+			    nxshndx = 0;
+			  }
+			else
+			  {
+			    nshndx = SHN_XINDEX;
+			    nxshndx = sec;
+			  }
+
+			elf_assert (sec < SHN_LORESERVE || shndxdata != NULL);
+
+			if ((inner != destidx || nshndx != sym->st_shndx
+			     || (shndxdata != NULL && nxshndx != xshndx))
+			    && (sym->st_shndx = nshndx,
+				gelf_update_symshndx (shdr_info[cnt].data,
+						      shndxdata,
+						      destidx, sym,
+						      nxshndx) == 0))
+			  INTERNAL_ERROR (fname);
+
+			shdr_info[cnt].newsymidx[inner] = destidx++;
+
+			if (last_was_local
+			    && GELF_ST_BIND (sym->st_info) != STB_LOCAL)
+			  {
+			    last_was_local = false;
+			    shdr_info[cnt].shdr.sh_info = destidx - 1;
+			  }
+		      }
+		    else if ((shdr_info[cnt].shdr.sh_flags & SHF_ALLOC) != 0
+			     && GELF_ST_TYPE (sym->st_info) != STT_SECTION
+			     && shdr_info[sidx].shdr.sh_type != SHT_GROUP)
+		      {
+			/* Removing a real symbol from an allocated
+			   symbol table is hard and probably a
+			   mistake.  Really removing it means
+			   rewriting the dynamic segment and hash
+			   sections.  Just warn and set the symbol
+			   section to UNDEF.  */
+			error (0, 0,
+			       gettext ("Cannot remove symbol [%zd] from allocated symbol table [%zd]"), inner, cnt);
+			sym->st_shndx = SHN_UNDEF;
+			if (gelf_update_sym (shdr_info[cnt].data, destidx,
+					     sym) == 0)
+			  INTERNAL_ERROR (fname);
+			shdr_info[cnt].newsymidx[inner] = destidx++;
+		      }
+		    else if (debug_fname != NULL
+			     && shdr_info[cnt].debug_data == NULL)
+		      /* The symbol points to a section that is discarded
+			 but isn't preserved in the debug file. Check that
+			 this is a section or group signature symbol
+			 for a section which has been removed.  Or a special
+			 data marker symbol to a debug section.  */
+		      {
+			elf_assert (GELF_ST_TYPE (sym->st_info) == STT_SECTION
+				    || ((shdr_info[sidx].shdr.sh_type
+					 == SHT_GROUP)
+					&& (shdr_info[sidx].shdr.sh_info
+					    == inner))
+				    || ebl_data_marker_symbol (ebl, sym,
+						elf_strptr (elf, sh_link,
+							    sym->st_name)));
+		      }
+		  }
+
+		if (destidx != inner)
+		  {
+		    /* The size of the symbol table changed.  */
+		    shdr_info[cnt].shdr.sh_size = newdata->d_size
+		      = destidx * elsize;
+		    any_symtab_changes = true;
+		  }
+		else
+		  {
+		    /* The symbol table didn't really change.  */
+		    free (shdr_info[cnt].newsymidx);
+		    shdr_info[cnt].newsymidx = NULL;
+		  }
+	      }
+	  }
+
+	/* If we have to, compute the offset of the section.  */
+	if (shdr_info[cnt].shdr.sh_offset == 0)
+	  shdr_info[cnt].shdr.sh_offset
+	    = ((lastoffset + shdr_info[cnt].shdr.sh_addralign - 1)
+	       & ~((GElf_Off) (shdr_info[cnt].shdr.sh_addralign - 1)));
+
+	/* Set the section header in the new file.  */
+	if (unlikely (gelf_update_shdr (scn, &shdr_info[cnt].shdr) == 0))
+	  /* There cannot be any overflows.  */
+	  INTERNAL_ERROR (fname);
+
+	/* Remember the last section written so far.  */
+	GElf_Off filesz = (shdr_info[cnt].shdr.sh_type != SHT_NOBITS
+			   ? shdr_info[cnt].shdr.sh_size : 0);
+	if (lastoffset < shdr_info[cnt].shdr.sh_offset + filesz)
+	  lastoffset = shdr_info[cnt].shdr.sh_offset + filesz;
+      }
+
+  /* Adjust symbol references if symbol tables changed.  */
+  if (any_symtab_changes)
+    /* Find all relocation sections which use this symbol table.  */
+    for (cnt = 1; cnt <= shdridx; ++cnt)
+      {
+	/* Update section headers when the data size has changed.
+	   We also update the SHT_NOBITS section in the debug
+	   file so that the section headers match in sh_size.  */
+	inline void update_section_size (const Elf_Data *newdata)
+	{
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  shdr->sh_size = newdata->d_size;
+	  (void) gelf_update_shdr (scn, shdr);
+	  if (debugelf != NULL)
+	    {
+	      /* libelf will use d_size to set sh_size.  */
+	      Elf_Data *debugdata = elf_getdata (elf_getscn (debugelf,
+							     cnt), NULL);
+	      if (debugdata == NULL)
+		INTERNAL_ERROR (fname);
+	      debugdata->d_size = newdata->d_size;
+	    }
+	}
+
+	if (shdr_info[cnt].idx == 0 && debug_fname == NULL)
+	  /* Ignore sections which are discarded.  When we are saving a
+	     relocation section in a separate debug file, we must fix up
+	     the symbol table references.  */
+	  continue;
+
+	const Elf32_Word symtabidx = shdr_info[cnt].old_sh_link;
+	elf_assert (symtabidx < shnum + 2);
+	const Elf32_Word *const newsymidx = shdr_info[symtabidx].newsymidx;
+	switch (shdr_info[cnt].shdr.sh_type)
+	  {
+	    inline bool no_symtab_updates (void)
+	    {
+	      /* If the symbol table hasn't changed, do not do anything.  */
+	      if (shdr_info[symtabidx].newsymidx == NULL)
+		return true;
+
+	      /* If the symbol table is not discarded, but additionally
+		 duplicated in the separate debug file and this section
+		 is discarded, don't adjust anything.  */
+	      return (shdr_info[cnt].idx == 0
+		      && shdr_info[symtabidx].debug_data != NULL);
+	    }
+
+	  case SHT_REL:
+	  case SHT_RELA:
+	    if (no_symtab_updates ())
+	      break;
+
+	    Elf_Data *d = elf_getdata (shdr_info[cnt].idx == 0
+				       ? elf_getscn (debugelf, cnt)
+				       : elf_getscn (newelf,
+						     shdr_info[cnt].idx),
+				       NULL);
+	    elf_assert (d != NULL && d->d_buf != NULL
+			&& shdr_info[cnt].shdr.sh_entsize != 0);
+	    size_t nrels = (shdr_info[cnt].shdr.sh_size
+			    / shdr_info[cnt].shdr.sh_entsize);
+
+	    size_t symsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+	    const Elf32_Word symidxn = (shdr_info[symtabidx].data->d_size
+					/ symsize);
+	    if (shdr_info[cnt].shdr.sh_type == SHT_REL)
+	      for (size_t relidx = 0; relidx < nrels; ++relidx)
+		{
+		  GElf_Rel rel_mem;
+		  if (gelf_getrel (d, relidx, &rel_mem) == NULL)
+		    INTERNAL_ERROR (fname);
+
+		  size_t symidx = GELF_R_SYM (rel_mem.r_info);
+		  elf_assert (symidx < symidxn);
+		  if (newsymidx[symidx] != symidx)
+		    {
+		      rel_mem.r_info
+			= GELF_R_INFO (newsymidx[symidx],
+				       GELF_R_TYPE (rel_mem.r_info));
+
+		      if (gelf_update_rel (d, relidx, &rel_mem) == 0)
+			INTERNAL_ERROR (fname);
+		    }
+		}
+	    else
+	      for (size_t relidx = 0; relidx < nrels; ++relidx)
+		{
+		  GElf_Rela rel_mem;
+		  if (gelf_getrela (d, relidx, &rel_mem) == NULL)
+		    INTERNAL_ERROR (fname);
+
+		  size_t symidx = GELF_R_SYM (rel_mem.r_info);
+		  elf_assert (symidx < symidxn);
+		  if (newsymidx[symidx] != symidx)
+		    {
+		      rel_mem.r_info
+			= GELF_R_INFO (newsymidx[symidx],
+				       GELF_R_TYPE (rel_mem.r_info));
+
+		      if (gelf_update_rela (d, relidx, &rel_mem) == 0)
+			INTERNAL_ERROR (fname);
+		    }
+		}
+	    break;
+
+	  case SHT_HASH:
+	    if (no_symtab_updates ())
+	      break;
+
+	    /* We have to recompute the hash table.  */
+
+	    elf_assert (shdr_info[cnt].idx > 0);
+
+	    /* The hash section in the new file.  */
+	    scn = elf_getscn (newelf, shdr_info[cnt].idx);
+
+	    /* The symbol table data.  */
+	    Elf_Data *symd = elf_getdata (elf_getscn (newelf,
+						      shdr_info[symtabidx].idx),
+					  NULL);
+	    elf_assert (symd != NULL && symd->d_buf != NULL);
+
+	    /* The hash table data.  */
+	    Elf_Data *hashd = elf_getdata (scn, NULL);
+	    elf_assert (hashd != NULL && hashd->d_buf != NULL);
+
+	    if (shdr_info[cnt].shdr.sh_entsize == sizeof (Elf32_Word))
+	      {
+		/* Sane arches first.  */
+		elf_assert (hashd->d_size >= 2 * sizeof (Elf32_Word));
+		Elf32_Word *bucket = (Elf32_Word *) hashd->d_buf;
+
+		size_t strshndx = shdr_info[symtabidx].old_sh_link;
+		size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+
+		Elf32_Word nchain = bucket[1];
+		Elf32_Word nbucket = bucket[0];
+		uint64_t used_buf = ((2ULL + nchain + nbucket)
+				     * sizeof (Elf32_Word));
+		elf_assert (used_buf <= hashd->d_size);
+
+		/* Adjust the nchain value.  The symbol table size
+		   changed.  We keep the same size for the bucket array.  */
+		bucket[1] = symd->d_size / elsize;
+		bucket += 2;
+		Elf32_Word *chain = bucket + nbucket;
+
+		/* New size of the section.  */
+		size_t n_size = ((2 + symd->d_size / elsize + nbucket)
+				 * sizeof (Elf32_Word));
+		elf_assert (n_size <= hashd->d_size);
+		hashd->d_size = n_size;
+		update_section_size (hashd);
+
+		/* Clear the arrays.  */
+		memset (bucket, '\0',
+			(symd->d_size / elsize + nbucket)
+			* sizeof (Elf32_Word));
+
+		for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
+		     inner < symd->d_size / elsize; ++inner)
+		  {
+		    GElf_Sym sym_mem;
+		    GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
+		    elf_assert (sym != NULL);
+
+		    const char *name = elf_strptr (elf, strshndx,
+						   sym->st_name);
+		    elf_assert (name != NULL && nbucket != 0);
+		    size_t hidx = elf_hash (name) % nbucket;
+
+		    if (bucket[hidx] == 0)
+		      bucket[hidx] = inner;
+		    else
+		      {
+			hidx = bucket[hidx];
+
+			while (chain[hidx] != 0 && chain[hidx] < nchain)
+			  hidx = chain[hidx];
+
+			chain[hidx] = inner;
+		      }
+		  }
+	      }
+	    else
+	      {
+		/* Alpha and S390 64-bit use 64-bit SHT_HASH entries.  */
+		elf_assert (shdr_info[cnt].shdr.sh_entsize
+			    == sizeof (Elf64_Xword));
+
+		Elf64_Xword *bucket = (Elf64_Xword *) hashd->d_buf;
+
+		size_t strshndx = shdr_info[symtabidx].old_sh_link;
+		size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+
+		elf_assert (symd->d_size >= 2 * sizeof (Elf64_Xword));
+		Elf64_Xword nbucket = bucket[0];
+		Elf64_Xword nchain = bucket[1];
+		uint64_t maxwords = hashd->d_size / sizeof (Elf64_Xword);
+		elf_assert (maxwords >= 2
+			    && maxwords - 2 >= nbucket
+			    && maxwords - 2 - nbucket >= nchain);
+
+		/* Adjust the nchain value.  The symbol table size
+		   changed.  We keep the same size for the bucket array.  */
+		bucket[1] = symd->d_size / elsize;
+		bucket += 2;
+		Elf64_Xword *chain = bucket + nbucket;
+
+		/* New size of the section.  */
+		size_t n_size = ((2 + symd->d_size / elsize + nbucket)
+				 * sizeof (Elf64_Xword));
+		elf_assert (n_size <= hashd->d_size);
+		hashd->d_size = n_size;
+		update_section_size (hashd);
+
+		/* Clear the arrays.  */
+		memset (bucket, '\0',
+			(symd->d_size / elsize + nbucket)
+			* sizeof (Elf64_Xword));
+
+		for (size_t inner = shdr_info[symtabidx].shdr.sh_info;
+		     inner < symd->d_size / elsize; ++inner)
+		  {
+		    GElf_Sym sym_mem;
+		    GElf_Sym *sym = gelf_getsym (symd, inner, &sym_mem);
+		    elf_assert (sym != NULL);
+
+		    const char *name = elf_strptr (elf, strshndx,
+						   sym->st_name);
+		    elf_assert (name != NULL && nbucket != 0);
+		    size_t hidx = elf_hash (name) % nbucket;
+
+		    if (bucket[hidx] == 0)
+		      bucket[hidx] = inner;
+		    else
+		      {
+			hidx = bucket[hidx];
+
+			while (chain[hidx] != 0 && chain[hidx] < nchain)
+			  hidx = chain[hidx];
+
+			chain[hidx] = inner;
+		      }
+		  }
+	      }
+	    break;
+
+	  case SHT_GNU_versym:
+	    /* If the symbol table changed we have to adjust the entries.  */
+	    if (no_symtab_updates ())
+	      break;
+
+	    elf_assert (shdr_info[cnt].idx > 0);
+
+	    /* The symbol version section in the new file.  */
+	    scn = elf_getscn (newelf, shdr_info[cnt].idx);
+
+	    /* The symbol table data.  */
+	    symd = elf_getdata (elf_getscn (newelf, shdr_info[symtabidx].idx),
+				NULL);
+	    elf_assert (symd != NULL && symd->d_buf != NULL);
+	    size_t symz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+	    const Elf32_Word syms = (shdr_info[symtabidx].data->d_size / symz);
+
+	    /* The version symbol data.  */
+	    Elf_Data *verd = elf_getdata (scn, NULL);
+	    elf_assert (verd != NULL && verd->d_buf != NULL);
+
+	    /* The symbol version array.  */
+	    GElf_Half *verstab = (GElf_Half *) verd->d_buf;
+
+	    /* Walk through the list and */
+	    size_t elsize = gelf_fsize (elf, verd->d_type, 1, EV_CURRENT);
+	    Elf32_Word vers = verd->d_size / elsize;
+	    for (size_t inner = 1; inner < vers && inner < syms; ++inner)
+	      if (newsymidx[inner] != 0 && newsymidx[inner] < vers)
+		/* Overwriting the same array works since the
+		   reordering can only move entries to lower indices
+		   in the array.  */
+		verstab[newsymidx[inner]] = verstab[inner];
+
+	    /* New size of the section.  */
+	    verd->d_size = gelf_fsize (newelf, verd->d_type,
+				       symd->d_size
+				       / gelf_fsize (elf, symd->d_type, 1,
+						     EV_CURRENT),
+				       EV_CURRENT);
+	    update_section_size (verd);
+	    break;
+
+	  case SHT_GROUP:
+	    if (no_symtab_updates ())
+	      break;
+
+	    /* Yes, the symbol table changed.
+	       Update the section header of the section group.  */
+	    scn = elf_getscn (newelf, shdr_info[cnt].idx);
+	    GElf_Shdr shdr_mem;
+	    GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	    elf_assert (shdr != NULL);
+
+	    size_t symsz = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+	    const Elf32_Word symn = (shdr_info[symtabidx].data->d_size
+				     / symsz);
+	    elf_assert (shdr->sh_info < symn);
+	    shdr->sh_info = newsymidx[shdr->sh_info];
+
+	    (void) gelf_update_shdr (scn, shdr);
+	    break;
+	  }
+      }
+
+  /* Remove any relocations between debug sections in ET_REL
+     for the debug file when requested.  These relocations are always
+     zero based between the unallocated sections.  */
+  if (debug_fname != NULL && removing_sections
+      && reloc_debug && ehdr->e_type == ET_REL)
+    {
+      scn = NULL;
+      cnt = 0;
+      while ((scn = elf_nextscn (debugelf, scn)) != NULL)
+	{
+	  cnt++;
+	  /* We need the actual section and header from the debugelf
+	     not just the cached original in shdr_info because we
+	     might want to change the size.  */
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	  if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA)
+	    {
+	      /* Make sure that this relocation section points to a
+		 section to relocate with contents, that isn't
+		 allocated and that is a debug section.  */
+	      Elf_Scn *tscn = elf_getscn (debugelf, shdr->sh_info);
+	      GElf_Shdr tshdr_mem;
+	      GElf_Shdr *tshdr = gelf_getshdr (tscn, &tshdr_mem);
+	      if (tshdr->sh_type == SHT_NOBITS
+		  || tshdr->sh_size == 0
+		  || (tshdr->sh_flags & SHF_ALLOC) != 0)
+		continue;
+
+	      const char *tname =  elf_strptr (debugelf, shstrndx,
+					       tshdr->sh_name);
+	      if (! tname || ! ebl_debugscn_p (ebl, tname))
+		continue;
+
+	      /* OK, lets relocate all trivial cross debug section
+		 relocations. */
+	      Elf_Data *reldata = elf_getdata (scn, NULL);
+	      if (reldata == NULL || reldata->d_buf == NULL)
+		INTERNAL_ERROR (fname);
+
+	      /* Make sure we adjust the uncompressed debug data
+		 (and recompress if necessary at the end).  */
+	      GElf_Chdr tchdr;
+	      int tcompress_type = 0;
+	      if (gelf_getchdr (tscn, &tchdr) != NULL)
+		{
+		  tcompress_type = tchdr.ch_type;
+		  if (elf_compress (tscn, 0, 0) != 1)
+		    INTERNAL_ERROR (fname);
+		}
+
+	      Elf_Data *tdata = elf_getdata (tscn, NULL);
+	      if (tdata == NULL || tdata->d_buf == NULL
+		  || tdata->d_type != ELF_T_BYTE)
+		INTERNAL_ERROR (fname);
+
+	      /* Pick up the symbol table and shndx table to
+		 resolve relocation symbol indexes.  */
+	      Elf64_Word symt = shdr->sh_link;
+	      Elf_Data *symdata, *xndxdata;
+	      elf_assert (symt < shnum + 2);
+	      elf_assert (shdr_info[symt].symtab_idx < shnum + 2);
+	      symdata = (shdr_info[symt].debug_data
+			 ?: shdr_info[symt].data);
+	      xndxdata = (shdr_info[shdr_info[symt].symtab_idx].debug_data
+			  ?: shdr_info[shdr_info[symt].symtab_idx].data);
+
+	      /* Apply one relocation.  Returns true when trivial
+		 relocation actually done.  */
+	      bool relocate (GElf_Addr offset, const GElf_Sxword addend,
+			     bool is_rela, int rtype, int symndx)
+	      {
+		/* R_*_NONE relocs can always just be removed.  */
+		if (rtype == 0)
+		  return true;
+
+		/* We only do simple absolute relocations.  */
+		Elf_Type type = ebl_reloc_simple_type (ebl, rtype);
+		if (type == ELF_T_NUM)
+		  return false;
+
+		/* These are the types we can relocate.  */
+#define TYPES   DO_TYPE (BYTE, Byte); DO_TYPE (HALF, Half);		\
+		DO_TYPE (WORD, Word); DO_TYPE (SWORD, Sword);		\
+		DO_TYPE (XWORD, Xword); DO_TYPE (SXWORD, Sxword)
+
+		/* And only for relocations against other debug sections.  */
+		GElf_Sym sym_mem;
+		Elf32_Word xndx;
+		GElf_Sym *sym = gelf_getsymshndx (symdata, xndxdata,
+						  symndx, &sym_mem,
+						  &xndx);
+		Elf32_Word sec = (sym->st_shndx == SHN_XINDEX
+				  ? xndx : sym->st_shndx);
+		if (sec >= shnum + 2)
+		  INTERNAL_ERROR (fname);
+
+		if (ebl_debugscn_p (ebl, shdr_info[sec].name))
+		  {
+		    size_t size;
+
+#define DO_TYPE(NAME, Name) GElf_##Name Name;
+		    union { TYPES; } tmpbuf;
+#undef DO_TYPE
+
+		    switch (type)
+		      {
+#define DO_TYPE(NAME, Name)				\
+			case ELF_T_##NAME:		\
+			  size = sizeof (GElf_##Name);	\
+			  tmpbuf.Name = 0;		\
+			  break;
+			TYPES;
+#undef DO_TYPE
+		      default:
+			return false;
+		      }
+
+		    if (offset > tdata->d_size
+			|| tdata->d_size - offset < size)
+		      {
+			cleanup_debug ();
+			error (EXIT_FAILURE, 0, gettext ("bad relocation"));
+		      }
+
+		    /* When the symbol value is zero then for SHT_REL
+		       sections this is all that needs to be checked.
+		       The addend is contained in the original data at
+		       the offset already.  So if the (section) symbol
+		       address is zero and the given addend is zero
+		       just remove the relocation, it isn't needed
+		       anymore.  */
+		    if (addend == 0 && sym->st_value == 0)
+		      return true;
+
+		    Elf_Data tmpdata =
+		      {
+			.d_type = type,
+			.d_buf = &tmpbuf,
+			.d_size = size,
+			.d_version = EV_CURRENT,
+		      };
+		    Elf_Data rdata =
+		      {
+			.d_type = type,
+			.d_buf = tdata->d_buf + offset,
+			.d_size = size,
+			.d_version = EV_CURRENT,
+		      };
+
+		    GElf_Addr value = sym->st_value;
+		    if (is_rela)
+		      {
+			/* For SHT_RELA sections we just take the
+			   given addend and add it to the value.  */
+			value += addend;
+		      }
+		    else
+		      {
+			/* For SHT_REL sections we have to peek at
+			   what is already in the section at the given
+			   offset to get the addend.  */
+			Elf_Data *d = gelf_xlatetom (debugelf, &tmpdata,
+						     &rdata,
+						     ehdr->e_ident[EI_DATA]);
+			if (d == NULL)
+			  INTERNAL_ERROR (fname);
+			assert (d == &tmpdata);
+		      }
+
+		    switch (type)
+		      {
+#define DO_TYPE(NAME, Name)					\
+			case ELF_T_##NAME:			\
+			  tmpbuf.Name += (GElf_##Name) value;	\
+			  break;
+			TYPES;
+#undef DO_TYPE
+		      default:
+			abort ();
+		      }
+
+		    /* Now finally put in the new value.  */
+		    Elf_Data *s = gelf_xlatetof (debugelf, &rdata,
+						 &tmpdata,
+						 ehdr->e_ident[EI_DATA]);
+		    if (s == NULL)
+		      INTERNAL_ERROR (fname);
+		    assert (s == &rdata);
+
+		    return true;
+		  }
+		return false;
+	      }
+
+	      if (shdr->sh_entsize == 0)
+		INTERNAL_ERROR (fname);
+
+	      size_t nrels = shdr->sh_size / shdr->sh_entsize;
+	      size_t next = 0;
+	      if (shdr->sh_type == SHT_REL)
+		for (size_t relidx = 0; relidx < nrels; ++relidx)
+		  {
+		    GElf_Rel rel_mem;
+		    GElf_Rel *r = gelf_getrel (reldata, relidx, &rel_mem);
+		    if (! relocate (r->r_offset, 0, false,
+				    GELF_R_TYPE (r->r_info),
+				    GELF_R_SYM (r->r_info)))
+		      {
+			if (relidx != next)
+			  gelf_update_rel (reldata, next, r);
+			++next;
+		      }
+		  }
+	      else
+		for (size_t relidx = 0; relidx < nrels; ++relidx)
+		  {
+		    GElf_Rela rela_mem;
+		    GElf_Rela *r = gelf_getrela (reldata, relidx, &rela_mem);
+		    if (! relocate (r->r_offset, r->r_addend, true,
+				    GELF_R_TYPE (r->r_info),
+				    GELF_R_SYM (r->r_info)))
+		      {
+			if (relidx != next)
+			  gelf_update_rela (reldata, next, r);
+			++next;
+		      }
+		  }
+
+	      nrels = next;
+	      shdr->sh_size = reldata->d_size = nrels * shdr->sh_entsize;
+	      gelf_update_shdr (scn, shdr);
+
+	      if (tcompress_type != 0)
+		if (elf_compress (tscn, tcompress_type, ELF_CHF_FORCE) != 1)
+		  INTERNAL_ERROR (fname);
+	    }
+	}
+    }
+
+  /* Now that we have done all adjustments to the data,
+     we can actually write out the debug file.  */
+  if (debug_fname != NULL && removing_sections)
+    {
+      /* Finally write the file.  */
+      if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1))
+	{
+	  error (0, 0, gettext ("while writing '%s': %s"),
+		 tmp_debug_fname, elf_errmsg (-1));
+	  result = 1;
+	  goto fail_close;
+	}
+
+      /* Create the real output file.  First rename, then change the
+	 mode.  */
+      if (rename (tmp_debug_fname, debug_fname) != 0
+	  || fchmod (debug_fd, mode) != 0)
+	{
+	  error (0, errno, gettext ("while creating '%s'"), debug_fname);
+	  result = 1;
+	  goto fail_close;
+	}
+
+      /* The temporary file does not exist anymore.  */
+      free (tmp_debug_fname);
+      tmp_debug_fname = NULL;
+
+      if (!remove_shdrs)
+	{
+	  uint32_t debug_crc;
+	  Elf_Data debug_crc_data =
+	    {
+	      .d_type = ELF_T_WORD,
+	      .d_buf = &debug_crc,
+	      .d_size = sizeof (debug_crc),
+	      .d_version = EV_CURRENT
+	    };
+
+	  /* Compute the checksum which we will add to the executable.  */
+	  if (crc32_file (debug_fd, &debug_crc) != 0)
+	    {
+	      error (0, errno, gettext ("\
+while computing checksum for debug information"));
+	      unlink (debug_fname);
+	      result = 1;
+	      goto fail_close;
+	    }
+
+	  /* Store it in the debuglink section data.  */
+	  if (unlikely (gelf_xlatetof (newelf, &debuglink_crc_data,
+				       &debug_crc_data, ehdr->e_ident[EI_DATA])
+			!= &debuglink_crc_data))
+	    INTERNAL_ERROR (fname);
+	}
+    }
+
+  /* Finally finish the ELF header.  Fill in the fields not handled by
+     libelf from the old file.  */
+  newehdr = gelf_getehdr (newelf, &newehdr_mem);
+  if (newehdr == NULL)
+    INTERNAL_ERROR (fname);
+
+  memcpy (newehdr->e_ident, ehdr->e_ident, EI_NIDENT);
+  newehdr->e_type = ehdr->e_type;
+  newehdr->e_machine = ehdr->e_machine;
+  newehdr->e_version = ehdr->e_version;
+  newehdr->e_entry = ehdr->e_entry;
+  newehdr->e_flags = ehdr->e_flags;
+  newehdr->e_phoff = ehdr->e_phoff;
+
+  /* We need to position the section header table.  */
+  const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT);
+  newehdr->e_shoff = ((shdr_info[shdridx].shdr.sh_offset
+		       + shdr_info[shdridx].shdr.sh_size + offsize - 1)
+		      & ~((GElf_Off) (offsize - 1)));
+  newehdr->e_shentsize = gelf_fsize (elf, ELF_T_SHDR, 1, EV_CURRENT);
+
+  /* The new section header string table index.  */
+  if (likely (idx < SHN_HIRESERVE) && likely (idx != SHN_XINDEX))
+    newehdr->e_shstrndx = idx;
+  else
+    {
+      /* The index does not fit in the ELF header field.  */
+      shdr_info[0].scn = elf_getscn (elf, 0);
+
+      if (gelf_getshdr (shdr_info[0].scn, &shdr_info[0].shdr) == NULL)
+	INTERNAL_ERROR (fname);
+
+      shdr_info[0].shdr.sh_link = idx;
+      (void) gelf_update_shdr (shdr_info[0].scn, &shdr_info[0].shdr);
+
+      newehdr->e_shstrndx = SHN_XINDEX;
+    }
+
+  if (gelf_update_ehdr (newelf, newehdr) == 0)
+    {
+      error (0, 0, gettext ("%s: error while creating ELF header: %s"),
+	     output_fname ?: fname, elf_errmsg (-1));
+      cleanup_debug ();
+      return 1;
+    }
+
+  /* We have everything from the old file.  */
+  if (elf_cntl (elf, ELF_C_FDDONE) != 0)
+    {
+      error (0, 0, gettext ("%s: error while reading the file: %s"),
+	     fname, elf_errmsg (-1));
+      cleanup_debug ();
+      return 1;
+    }
+
+  /* The ELF library better follows our layout when this is not a
+     relocatable object file.  */
+  elf_flagelf (newelf, ELF_C_SET,
+	       (ehdr->e_type != ET_REL ? ELF_F_LAYOUT : 0)
+	       | (permissive ? ELF_F_PERMISSIVE : 0));
+
+  /* Finally write the file.  */
+  if (elf_update (newelf, ELF_C_WRITE) == -1)
+    {
+      error (0, 0, gettext ("while writing '%s': %s"),
+	     output_fname ?: fname, elf_errmsg (-1));
+      result = 1;
+    }
+
+  if (remove_shdrs)
+    {
+      /* libelf can't cope without the section headers being properly intact.
+	 So we just let it write them normally, and then we nuke them later.  */
+
+      if (newehdr->e_ident[EI_CLASS] == ELFCLASS32)
+	{
+	  assert (offsetof (Elf32_Ehdr, e_shentsize) + sizeof (Elf32_Half)
+		  == offsetof (Elf32_Ehdr, e_shnum));
+	  assert (offsetof (Elf32_Ehdr, e_shnum) + sizeof (Elf32_Half)
+		  == offsetof (Elf32_Ehdr, e_shstrndx));
+	  const Elf32_Off zero_off = 0;
+	  const Elf32_Half zero[3] = { 0, 0, SHN_UNDEF };
+	  if (pwrite_retry (fd, &zero_off, sizeof zero_off,
+			    offsetof (Elf32_Ehdr, e_shoff)) != sizeof zero_off
+	      || (pwrite_retry (fd, zero, sizeof zero,
+				offsetof (Elf32_Ehdr, e_shentsize))
+		  != sizeof zero)
+	      || ftruncate (fd, shdr_info[shdridx].shdr.sh_offset) < 0)
+	    {
+	      error (0, errno, gettext ("while writing '%s'"),
+		     output_fname ?: fname);
+	      result = 1;
+	    }
+	}
+      else
+	{
+	  assert (offsetof (Elf64_Ehdr, e_shentsize) + sizeof (Elf64_Half)
+		  == offsetof (Elf64_Ehdr, e_shnum));
+	  assert (offsetof (Elf64_Ehdr, e_shnum) + sizeof (Elf64_Half)
+		  == offsetof (Elf64_Ehdr, e_shstrndx));
+	  const Elf64_Off zero_off = 0;
+	  const Elf64_Half zero[3] = { 0, 0, SHN_UNDEF };
+	  if (pwrite_retry (fd, &zero_off, sizeof zero_off,
+			    offsetof (Elf64_Ehdr, e_shoff)) != sizeof zero_off
+	      || (pwrite_retry (fd, zero, sizeof zero,
+				offsetof (Elf64_Ehdr, e_shentsize))
+		  != sizeof zero)
+	      || ftruncate (fd, shdr_info[shdridx].shdr.sh_offset) < 0)
+	    {
+	      error (0, errno, gettext ("while writing '%s'"),
+		     output_fname ?: fname);
+	      result = 1;
+	    }
+	}
+    }
+
+ fail_close:
+  if (shdr_info != NULL)
+    {
+      /* For some sections we might have created an table to map symbol
+	 table indices.  Or we might kept (original) data around to put
+	 into the .debug file.  */
+      for (cnt = 1; cnt <= shdridx; ++cnt)
+	{
+	  free (shdr_info[cnt].newsymidx);
+	  if (shdr_info[cnt].debug_data != NULL)
+	    free (shdr_info[cnt].debug_data->d_buf);
+	}
+
+      /* Free data we allocated for the .gnu_debuglink section. */
+      free (debuglink_buf);
+
+      /* Free the memory.  */
+      if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
+	free (shdr_info);
+    }
+
+  /* Free other resources.  */
+  if (shstrtab_data != NULL)
+    free (shstrtab_data->d_buf);
+  if (shst != NULL)
+    dwelf_strtab_free (shst);
+
+  /* That was it.  Close the descriptors.  */
+  if (elf_end (newelf) != 0)
+    {
+      error (0, 0, gettext ("error while finishing '%s': %s"),
+	     output_fname ?: fname, elf_errmsg (-1));
+      result = 1;
+    }
+
+  if (debugelf != NULL && elf_end (debugelf) != 0)
+    {
+      error (0, 0, gettext ("error while finishing '%s': %s"), debug_fname,
+	     elf_errmsg (-1));
+      result = 1;
+    }
+
+ fail:
+  /* Close the EBL backend.  */
+  if (ebl != NULL)
+    ebl_closebackend (ebl);
+
+  cleanup_debug ();
+
+  /* If requested, preserve the timestamp.  */
+  if (tvp != NULL)
+    {
+      if (futimens (fd, tvp) != 0)
+	{
+	  error (0, errno, gettext ("\
+cannot set access and modification date of '%s'"),
+		 output_fname ?: fname);
+	  result = 1;
+	}
+    }
+
+  /* Close the file descriptor if we created a new file.  */
+  if (output_fname != NULL)
+    {
+      close (fd);
+      if (result != 0)
+       unlink (output_fname);
+    }
+
+  return result;
+}
+
+static void
+cleanup_debug (void)
+{
+  if (debug_fd >= 0)
+    {
+      if (tmp_debug_fname != NULL)
+	{
+	  unlink (tmp_debug_fname);
+	  free (tmp_debug_fname);
+	  tmp_debug_fname = NULL;
+	}
+      close (debug_fd);
+      debug_fd = -1;
+    }
+}
+
+static int
+handle_ar (int fd, Elf *elf, const char *prefix, const char *fname,
+	   struct timespec tvp[2])
+{
+  size_t prefix_len = prefix == NULL ? 0 : strlen (prefix);
+  size_t fname_len = strlen (fname) + 1;
+  char new_prefix[prefix_len + 1 + fname_len];
+  char *cp = new_prefix;
+
+  /* Create the full name of the file.  */
+  if (prefix != NULL)
+    {
+      cp = mempcpy (cp, prefix, prefix_len);
+      *cp++ = ':';
+    }
+  memcpy (cp, fname, fname_len);
+
+
+  /* Process all the files contained in the archive.  */
+  Elf *subelf;
+  Elf_Cmd cmd = ELF_C_RDWR;
+  int result = 0;
+  while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+    {
+      /* The the header for this element.  */
+      Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+
+      if (elf_kind (subelf) == ELF_K_ELF)
+	result |= handle_elf (fd, subelf, new_prefix, arhdr->ar_name, 0, NULL);
+      else if (elf_kind (subelf) == ELF_K_AR)
+	result |= handle_ar (fd, subelf, new_prefix, arhdr->ar_name, NULL);
+
+      /* Get next archive element.  */
+      cmd = elf_next (subelf);
+      if (unlikely (elf_end (subelf) != 0))
+	INTERNAL_ERROR (fname);
+    }
+
+  if (tvp != NULL)
+    {
+      if (unlikely (futimens (fd, tvp) != 0))
+	{
+	  error (0, errno, gettext ("\
+cannot set access and modification date of '%s'"), fname);
+	  result = 1;
+	}
+    }
+
+  if (unlikely (close (fd) != 0))
+    error (EXIT_FAILURE, errno, gettext ("while closing '%s'"), fname);
+
+  return result;
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/src/unstrip.c b/third_party/elfutils/src/unstrip.c
new file mode 100644
index 0000000..f368e69
--- /dev/null
+++ b/third_party/elfutils/src/unstrip.c
@@ -0,0 +1,2456 @@
+/* Combine stripped files with separate symbols and debug information.
+   Copyright (C) 2007-2012, 2014, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Roland McGrath <roland@redhat.com>, 2007.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* TODO:
+
+  * SHX_XINDEX
+
+  * prelink vs .debug_* linked addresses
+
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <argp.h>
+#include <assert.h>
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <libintl.h>
+#include <locale.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <gelf.h>
+#include <libebl.h>
+#include <libdwfl.h>
+#include "libdwelf.h"
+#include "libeu.h"
+#include "printversion.h"
+
+#ifndef _
+# define _(str) gettext (str)
+#endif
+
+/* Name and version of program.  */
+ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
+
+/* Bug report address.  */
+ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
+
+/* Definitions of arguments for argp functions.  */
+static const struct argp_option options[] =
+{
+  /* Group 2 will follow group 1 from dwfl_standard_argp.  */
+  { "match-file-names", 'f', NULL, 0,
+    N_("Match MODULE against file names, not module names"), 2 },
+  { "ignore-missing", 'i', NULL, 0, N_("Silently skip unfindable files"), 0 },
+
+  { NULL, 0, NULL, 0, N_("Output options:"), 0 },
+  { "output", 'o', "FILE", 0, N_("Place output into FILE"), 0 },
+  { "output-directory", 'd', "DIRECTORY",
+    0, N_("Create multiple output files under DIRECTORY"), 0 },
+  { "module-names", 'm', NULL, 0, N_("Use module rather than file names"), 0 },
+  { "all", 'a', NULL, 0,
+    N_("Create output for modules that have no separate debug information"),
+    0 },
+  { "relocate", 'R', NULL, 0,
+    N_("Apply relocations to section contents in ET_REL files"), 0 },
+  { "list-only", 'n', NULL, 0,
+    N_("Only list module and file names, build IDs"), 0 },
+ { "force", 'F', NULL, 0,
+    N_("Force combining files even if some ELF headers don't seem to match"),
+   0 },
+  { NULL, 0, NULL, 0, NULL, 0 }
+};
+
+struct arg_info
+{
+  const char *output_file;
+  const char *output_dir;
+  Dwfl *dwfl;
+  char **args;
+  bool list;
+  bool all;
+  bool ignore;
+  bool modnames;
+  bool match_files;
+  bool relocate;
+  bool force;
+};
+
+/* Handle program arguments.  */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+  struct arg_info *info = state->input;
+
+  switch (key)
+    {
+    case ARGP_KEY_INIT:
+      state->child_inputs[0] = &info->dwfl;
+      break;
+
+    case 'o':
+      if (info->output_file != NULL)
+	{
+	  argp_error (state, _("-o option specified twice"));
+	  return EINVAL;
+	}
+      info->output_file = arg;
+      break;
+
+    case 'd':
+      if (info->output_dir != NULL)
+	{
+	  argp_error (state, _("-d option specified twice"));
+	  return EINVAL;
+	}
+      info->output_dir = arg;
+      break;
+
+    case 'm':
+      info->modnames = true;
+      break;
+    case 'f':
+      info->match_files = true;
+      break;
+    case 'a':
+      info->all = true;
+      break;
+    case 'i':
+      info->ignore = true;
+      break;
+    case 'n':
+      info->list = true;
+      break;
+    case 'R':
+      info->relocate = true;
+      break;
+    case 'F':
+      info->force = true;
+      break;
+
+    case ARGP_KEY_ARGS:
+    case ARGP_KEY_NO_ARGS:
+      /* We "consume" all the arguments here.  */
+      info->args = &state->argv[state->next];
+
+      if (info->output_file != NULL && info->output_dir != NULL)
+	{
+	  argp_error (state, _("only one of -o or -d allowed"));
+	  return EINVAL;
+	}
+
+      if (info->list && (info->dwfl == NULL
+			 || info->output_dir != NULL
+			 || info->output_file != NULL))
+	{
+	  argp_error (state,
+		      _("-n cannot be used with explicit files or -o or -d"));
+	  return EINVAL;
+	}
+
+      if (info->output_dir != NULL)
+	{
+	  struct stat st;
+	  error_t fail = 0;
+	  if (stat (info->output_dir, &st) < 0)
+	    fail = errno;
+	  else if (!S_ISDIR (st.st_mode))
+	    fail = ENOTDIR;
+	  if (fail)
+	    {
+	      argp_failure (state, EXIT_FAILURE, fail,
+			    _("output directory '%s'"), info->output_dir);
+	      return fail;
+	    }
+	}
+
+      if (info->dwfl == NULL)
+	{
+	  if (state->next + 2 != state->argc)
+	    {
+	      argp_error (state, _("exactly two file arguments are required"));
+	      return EINVAL;
+	    }
+
+	  if (info->ignore || info->all || info->modnames || info->relocate)
+	    {
+	      argp_error (state, _("\
+-m, -a, -R, and -i options not allowed with explicit files"));
+	      return EINVAL;
+	    }
+
+	  /* Bail out immediately to prevent dwfl_standard_argp's parser
+	     from defaulting to "-e a.out".  */
+	  return ENOSYS;
+	}
+      else if (info->output_file == NULL && info->output_dir == NULL
+	       && !info->list)
+	{
+	  argp_error (state,
+		      _("-o or -d is required when using implicit files"));
+	  return EINVAL;
+	}
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+#define ELF_CHECK(call, msg)						      \
+  do									      \
+    {									      \
+      if (unlikely (!(call)))						      \
+	error (EXIT_FAILURE, 0, msg, elf_errmsg (-1));			      \
+    } while (0)
+
+/* Copy INELF to newly-created OUTELF, exit via error for any problems.  */
+static void
+copy_elf (Elf *outelf, Elf *inelf)
+{
+  ELF_CHECK (gelf_newehdr (outelf, gelf_getclass (inelf)),
+	     _("cannot create ELF header: %s"));
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (inelf, &ehdr_mem);
+  ELF_CHECK (gelf_update_ehdr (outelf, ehdr),
+	     _("cannot copy ELF header: %s"));
+
+  size_t phnum;
+  ELF_CHECK (elf_getphdrnum (inelf, &phnum) == 0,
+	     _("cannot get number of program headers: %s"));
+
+  if (phnum > 0)
+    {
+      ELF_CHECK (gelf_newphdr (outelf, phnum),
+		 _("cannot create program headers: %s"));
+
+      GElf_Phdr phdr_mem;
+      for (size_t i = 0; i < phnum; ++i)
+	ELF_CHECK (gelf_update_phdr (outelf, i,
+				     gelf_getphdr (inelf, i, &phdr_mem)),
+		   _("cannot copy program header: %s"));
+    }
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (inelf, scn)) != NULL)
+    {
+      Elf_Scn *newscn = elf_newscn (outelf);
+
+      GElf_Shdr shdr_mem;
+      ELF_CHECK (gelf_update_shdr (newscn, gelf_getshdr (scn, &shdr_mem)),
+		 _("cannot copy section header: %s"));
+
+      Elf_Data *data = elf_getdata (scn, NULL);
+      ELF_CHECK (data != NULL, _("cannot get section data: %s"));
+      Elf_Data *newdata = elf_newdata (newscn);
+      ELF_CHECK (newdata != NULL, _("cannot copy section data: %s"));
+      *newdata = *data;
+      elf_flagdata (newdata, ELF_C_SET, ELF_F_DIRTY);
+    }
+}
+
+/* Create directories containing PATH.  */
+static void
+make_directories (const char *path)
+{
+  const char *lastslash = strrchr (path, '/');
+  if (lastslash == NULL)
+    return;
+
+  while (lastslash > path && lastslash[-1] == '/')
+    --lastslash;
+  if (lastslash == path)
+    return;
+
+  char *dir = strndupa (path, lastslash - path);
+  while (mkdir (dir, 0777) < 0 && errno != EEXIST)
+    if (errno == ENOENT)
+      make_directories (dir);
+    else
+      error (EXIT_FAILURE, errno, _("cannot create directory '%s'"), dir);
+}
+
+/* Keep track of new section data we are creating, so we can free it
+   when done.  */
+struct data_list
+{
+  void *data;
+  struct data_list *next;
+};
+
+struct data_list *new_data_list;
+
+static void
+record_new_data (void *data)
+{
+  struct data_list *next = new_data_list;
+  new_data_list = xmalloc (sizeof (struct data_list));
+  new_data_list->data = data;
+  new_data_list->next = next;
+}
+
+static void
+free_new_data (void)
+{
+  struct data_list *list = new_data_list;
+  while (list != NULL)
+    {
+      struct data_list *next = list->next;
+      free (list->data);
+      free (list);
+      list = next;
+    }
+  new_data_list = NULL;
+}
+
+/* The binutils linker leaves gratuitous section symbols in .symtab
+   that strip has to remove.  Older linkers likewise include a
+   symbol for every section, even unallocated ones, in .dynsym.
+   Because of this, the related sections can shrink in the stripped
+   file from their original size.  Older versions of strip do not
+   adjust the sh_size field in the debuginfo file's SHT_NOBITS
+   version of the section header, so it can appear larger.  */
+static bool
+section_can_shrink (const GElf_Shdr *shdr)
+{
+  switch (shdr->sh_type)
+    {
+    case SHT_SYMTAB:
+    case SHT_DYNSYM:
+    case SHT_HASH:
+    case SHT_GNU_versym:
+      return true;
+    }
+  return false;
+}
+
+/* See if this symbol table has a leading section symbol for every single
+   section, in order.  The binutils linker produces this.  While we're here,
+   update each section symbol's st_value.  */
+static size_t
+symtab_count_leading_section_symbols (Elf *elf, Elf_Scn *scn, size_t shnum,
+				      Elf_Data *newsymdata)
+{
+  Elf_Data *data = elf_getdata (scn, NULL);
+  Elf_Data *shndxdata = NULL;	/* XXX */
+
+  for (size_t i = 1; i < shnum; ++i)
+    {
+      GElf_Sym sym_mem;
+      GElf_Word shndx = SHN_UNDEF;
+      GElf_Sym *sym = gelf_getsymshndx (data, shndxdata, i, &sym_mem, &shndx);
+      ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s"));
+
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (elf_getscn (elf, i), &shdr_mem);
+      ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
+
+      if (sym->st_shndx != SHN_XINDEX)
+	shndx = sym->st_shndx;
+
+      if (shndx != i || GELF_ST_TYPE (sym->st_info) != STT_SECTION)
+	return i;
+
+      sym->st_value = shdr->sh_addr;
+      if (sym->st_shndx != SHN_XINDEX)
+	shndx = SHN_UNDEF;
+      ELF_CHECK (gelf_update_symshndx (newsymdata, shndxdata, i, sym, shndx),
+		 _("cannot update symbol table: %s"));
+    }
+
+  return shnum;
+}
+
+static void
+update_shdr (Elf_Scn *outscn, GElf_Shdr *newshdr)
+{
+  ELF_CHECK (gelf_update_shdr (outscn, newshdr),
+	     _("cannot update section header: %s"));
+}
+
+/* We expanded the output section, so update its header.  */
+static void
+update_sh_size (Elf_Scn *outscn, const Elf_Data *data)
+{
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *newshdr = gelf_getshdr (outscn, &shdr_mem);
+  ELF_CHECK (newshdr != NULL, _("cannot get section header: %s"));
+
+  newshdr->sh_size = data->d_size;
+
+  update_shdr (outscn, newshdr);
+}
+
+/* Update relocation sections using the symbol table.  */
+static void
+adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
+	       size_t map[], const GElf_Shdr *symshdr)
+{
+  Elf_Data *data = elf_getdata (outscn, NULL);
+
+  inline void adjust_reloc (GElf_Xword *info)
+    {
+      size_t ndx = GELF_R_SYM (*info);
+      if (ndx != STN_UNDEF)
+	*info = GELF_R_INFO (map[ndx - 1], GELF_R_TYPE (*info));
+    }
+
+  switch (shdr->sh_type)
+    {
+    case SHT_REL:
+      for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i)
+	{
+	  GElf_Rel rel_mem;
+	  GElf_Rel *rel = gelf_getrel (data, i, &rel_mem);
+	  adjust_reloc (&rel->r_info);
+	  ELF_CHECK (gelf_update_rel (data, i, rel),
+		     _("cannot update relocation: %s"));
+	}
+      break;
+
+    case SHT_RELA:
+      for (size_t i = 0; i < shdr->sh_size / shdr->sh_entsize; ++i)
+	{
+	  GElf_Rela rela_mem;
+	  GElf_Rela *rela = gelf_getrela (data, i, &rela_mem);
+	  adjust_reloc (&rela->r_info);
+	  ELF_CHECK (gelf_update_rela (data, i, rela),
+		     _("cannot update relocation: %s"));
+	}
+      break;
+
+    case SHT_GROUP:
+      {
+	GElf_Shdr shdr_mem;
+	GElf_Shdr *newshdr = gelf_getshdr (outscn, &shdr_mem);
+	ELF_CHECK (newshdr != NULL, _("cannot get section header: %s"));
+	if (newshdr->sh_info != STN_UNDEF)
+	  {
+	    newshdr->sh_info = map[newshdr->sh_info - 1];
+	    update_shdr (outscn, newshdr);
+	  }
+	break;
+      }
+
+    case SHT_HASH:
+      /* We must expand the table and rejigger its contents.  */
+      {
+	const size_t nsym = symshdr->sh_size / symshdr->sh_entsize;
+	const size_t onent = shdr->sh_size / shdr->sh_entsize;
+	assert (data->d_size == shdr->sh_size);
+
+#define CONVERT_HASH(Hash_Word)						      \
+	{								      \
+	  const Hash_Word *const old_hash = data->d_buf;		      \
+	  const size_t nbucket = old_hash[0];				      \
+	  const size_t nchain = old_hash[1];				      \
+	  const Hash_Word *const old_bucket = &old_hash[2];		      \
+	  const Hash_Word *const old_chain = &old_bucket[nbucket];	      \
+	  assert (onent == 2 + nbucket + nchain);			      \
+									      \
+	  const size_t nent = 2 + nbucket + nsym;			      \
+	  Hash_Word *const new_hash = xcalloc (nent, sizeof new_hash[0]);     \
+	  Hash_Word *const new_bucket = &new_hash[2];			      \
+	  Hash_Word *const new_chain = &new_bucket[nbucket];		      \
+									      \
+	  new_hash[0] = nbucket;					      \
+	  new_hash[1] = nsym;						      \
+	  for (size_t i = 0; i < nbucket; ++i)				      \
+	    if (old_bucket[i] != STN_UNDEF)				      \
+	      new_bucket[i] = map[old_bucket[i] - 1];			      \
+									      \
+	  for (size_t i = 1; i < nchain; ++i)				      \
+	    if (old_chain[i] != STN_UNDEF)				      \
+	      new_chain[map[i - 1]] = map[old_chain[i] - 1];		      \
+									      \
+	  record_new_data (new_hash);					\
+	  data->d_buf = new_hash;					      \
+	  data->d_size = nent * sizeof new_hash[0];			      \
+	}
+
+	switch (shdr->sh_entsize)
+	  {
+	  case 4:
+	    CONVERT_HASH (Elf32_Word);
+	    break;
+	  case 8:
+	    CONVERT_HASH (Elf64_Xword);
+	    break;
+	  default:
+	    abort ();
+	  }
+
+	elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
+	update_sh_size (outscn, data);
+
+#undef	CONVERT_HASH
+      }
+      break;
+
+    case SHT_GNU_versym:
+      /* We must expand the table and move its elements around.  */
+      {
+	const size_t nent = symshdr->sh_size / symshdr->sh_entsize;
+	const size_t onent = shdr->sh_size / shdr->sh_entsize;
+	assert (nent >= onent);
+
+	/* We don't bother using gelf_update_versym because there is
+	   really no conversion to be done.  */
+	assert (sizeof (Elf32_Versym) == sizeof (GElf_Versym));
+	assert (sizeof (Elf64_Versym) == sizeof (GElf_Versym));
+	GElf_Versym *versym = xcalloc (nent, sizeof versym[0]);
+
+	for (size_t i = 1; i < onent; ++i)
+	  {
+	    GElf_Versym *v = gelf_getversym (data, i, &versym[map[i - 1]]);
+	    ELF_CHECK (v != NULL, _("cannot get symbol version: %s"));
+	  }
+
+	record_new_data (versym);
+	data->d_buf = versym;
+	data->d_size = nent * shdr->sh_entsize;
+	elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
+	update_sh_size (outscn, data);
+      }
+      break;
+
+    default:
+      error (EXIT_FAILURE, 0,
+	     _("unexpected section type in [%zu] with sh_link to symtab"),
+	     elf_ndxscn (inscn));
+    }
+}
+
+/* Adjust all the relocation sections in the file.  */
+static void
+adjust_all_relocs (Elf *elf, Elf_Scn *symtab, const GElf_Shdr *symshdr,
+		   size_t map[])
+{
+  size_t new_sh_link = elf_ndxscn (symtab);
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    if (scn != symtab)
+      {
+	GElf_Shdr shdr_mem;
+	GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
+	if (shdr->sh_type != SHT_NOBITS && shdr->sh_link == new_sh_link)
+	  adjust_relocs (scn, scn, shdr, map, symshdr);
+      }
+}
+
+/* The original file probably had section symbols for all of its
+   sections, even the unallocated ones.  To match it as closely as
+   possible, add in section symbols for the added sections.  */
+static Elf_Data *
+add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum,
+			 Elf *elf, bool rel, Elf_Scn *symscn, size_t shnum)
+{
+  const size_t added = shnum - old_shnum;
+
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (symscn, &shdr_mem);
+  ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
+
+  const size_t nsym = shdr->sh_size / shdr->sh_entsize;
+  size_t symndx_map[nsym - 1];
+
+  shdr->sh_info += added;
+  shdr->sh_size += added * shdr->sh_entsize;
+  update_shdr (symscn, shdr);
+
+  Elf_Data *symdata = elf_getdata (symscn, NULL);
+  Elf_Data *shndxdata = NULL;	/* XXX */
+
+  symdata->d_size = shdr->sh_size;
+  symdata->d_buf = xmalloc (symdata->d_size);
+  record_new_data (symdata->d_buf);
+
+  /* Copy the existing section symbols.  */
+  Elf_Data *old_symdata = elf_getdata (old_symscn, NULL);
+  for (size_t i = 0; i < old_shnum; ++i)
+    {
+      GElf_Sym sym_mem;
+      GElf_Word shndx = SHN_UNDEF;
+      GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata,
+					i, &sym_mem, &shndx);
+      ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i,
+				       sym, shndx),
+		 _("cannot update symbol table: %s"));
+
+      if (i > 0)
+	symndx_map[i - 1] = i;
+    }
+
+  /* Add in the new section symbols.  */
+  for (size_t i = old_shnum; i < shnum; ++i)
+    {
+      GElf_Shdr i_shdr_mem;
+      GElf_Shdr *i_shdr = gelf_getshdr (elf_getscn (elf, i), &i_shdr_mem);
+      ELF_CHECK (i_shdr != NULL, _("cannot get section header: %s"));
+      GElf_Sym sym =
+	{
+	  .st_value = rel ? 0 : i_shdr->sh_addr,
+	  .st_info = GELF_ST_INFO (STB_LOCAL, STT_SECTION),
+	  .st_shndx = i < SHN_LORESERVE ? i : SHN_XINDEX
+	};
+      GElf_Word shndx = i < SHN_LORESERVE ? SHN_UNDEF : i;
+      ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, i,
+				       &sym, shndx),
+		 _("cannot update symbol table: %s"));
+    }
+
+  /* Now copy the rest of the existing symbols.  */
+  for (size_t i = old_shnum; i < nsym; ++i)
+    {
+      GElf_Sym sym_mem;
+      GElf_Word shndx = SHN_UNDEF;
+      GElf_Sym *sym = gelf_getsymshndx (old_symdata, shndxdata,
+					i, &sym_mem, &shndx);
+      ELF_CHECK (gelf_update_symshndx (symdata, shndxdata,
+				       i + added, sym, shndx),
+		 _("cannot update symbol table: %s"));
+
+      symndx_map[i - 1] = i + added;
+    }
+
+  /* Adjust any relocations referring to the old symbol table.  */
+  adjust_all_relocs (elf, symscn, shdr, symndx_map);
+
+  return symdata;
+}
+
+/* This has the side effect of updating STT_SECTION symbols' values,
+   in case of prelink adjustments.  */
+static Elf_Data *
+check_symtab_section_symbols (Elf *elf, bool rel, Elf_Scn *scn,
+			      size_t shnum, size_t shstrndx,
+			      Elf_Scn *oscn, size_t oshnum, size_t oshstrndx,
+			      size_t debuglink)
+{
+  size_t n = symtab_count_leading_section_symbols (elf, oscn, oshnum,
+						   elf_getdata (scn, NULL));
+
+  if (n == oshnum)
+    return add_new_section_symbols (oscn, n, elf, rel, scn, shnum);
+
+  if (n == oshstrndx || (n == debuglink && n == oshstrndx - 1))
+    return add_new_section_symbols (oscn, n, elf, rel, scn, shstrndx);
+
+  return NULL;
+}
+
+struct section
+{
+  Elf_Scn *scn;
+  const char *name;
+  Elf_Scn *outscn;
+  Dwelf_Strent *strent;
+  GElf_Shdr shdr;
+};
+
+static int
+compare_alloc_sections (const struct section *s1, const struct section *s2,
+			bool rel)
+{
+  if (!rel)
+    {
+      /* Sort by address.  */
+      if (s1->shdr.sh_addr < s2->shdr.sh_addr)
+	return -1;
+      if (s1->shdr.sh_addr > s2->shdr.sh_addr)
+	return 1;
+    }
+
+  /* At the same address, preserve original section order.  */
+  return (ssize_t) elf_ndxscn (s1->scn) - (ssize_t) elf_ndxscn (s2->scn);
+}
+
+static int
+compare_unalloc_sections (const GElf_Shdr *shdr1, const GElf_Shdr *shdr2,
+			  const char *name1, const char *name2)
+{
+  /* Sort by sh_flags as an arbitrary ordering.  */
+  if (shdr1->sh_flags < shdr2->sh_flags)
+    return -1;
+  if (shdr1->sh_flags > shdr2->sh_flags)
+    return 1;
+
+  /* Sort by name as last resort.  */
+  return strcmp (name1, name2);
+}
+
+static int
+compare_sections (const void *a, const void *b, bool rel)
+{
+  const struct section *s1 = a;
+  const struct section *s2 = b;
+
+  /* Sort all non-allocated sections last.  */
+  if ((s1->shdr.sh_flags ^ s2->shdr.sh_flags) & SHF_ALLOC)
+    return (s1->shdr.sh_flags & SHF_ALLOC) ? -1 : 1;
+
+  return ((s1->shdr.sh_flags & SHF_ALLOC)
+	  ? compare_alloc_sections (s1, s2, rel)
+	  : compare_unalloc_sections (&s1->shdr, &s2->shdr,
+				      s1->name, s2->name));
+}
+
+static int
+compare_sections_rel (const void *a, const void *b)
+{
+  return compare_sections (a, b, true);
+}
+
+static int
+compare_sections_nonrel (const void *a, const void *b)
+{
+  return compare_sections (a, b, false);
+}
+
+
+struct symbol
+{
+  size_t *map;
+
+  union
+  {
+    const char *name;
+    Dwelf_Strent *strent;
+  };
+  union
+  {
+    struct
+    {
+      GElf_Addr value;
+      GElf_Xword size;
+      GElf_Word shndx;
+      union
+      {
+	struct
+	{
+	  uint8_t info;
+	  uint8_t other;
+	} info;
+	int16_t compare;
+      };
+    };
+
+    /* For a symbol discarded after first sort, this matches its better's
+       map pointer.  */
+    size_t *duplicate;
+  };
+};
+
+/* Collect input symbols into our internal form.  */
+static void
+collect_symbols (Elf *outelf, bool rel, Elf_Scn *symscn, Elf_Scn *strscn,
+		 const size_t nent, const GElf_Addr bias,
+		 const size_t scnmap[], struct symbol *table, size_t *map,
+		 struct section *split_bss)
+{
+  Elf_Data *symdata = elf_getdata (symscn, NULL);
+  Elf_Data *strdata = elf_getdata (strscn, NULL);
+  Elf_Data *shndxdata = NULL;	/* XXX */
+
+  for (size_t i = 1; i < nent; ++i)
+    {
+      GElf_Sym sym_mem;
+      GElf_Word shndx = SHN_UNDEF;
+      GElf_Sym *sym = gelf_getsymshndx (symdata, shndxdata, i,
+					&sym_mem, &shndx);
+      ELF_CHECK (sym != NULL, _("cannot get symbol table entry: %s"));
+      if (sym->st_shndx != SHN_XINDEX)
+	shndx = sym->st_shndx;
+
+      if (sym->st_name >= strdata->d_size)
+	error (EXIT_FAILURE, 0,
+	       _("invalid string offset in symbol [%zu]"), i);
+
+      struct symbol *s = &table[i - 1];
+      s->map = &map[i - 1];
+      s->name = strdata->d_buf + sym->st_name;
+      s->value = sym->st_value + bias;
+      s->size = sym->st_size;
+      s->shndx = shndx;
+      s->info.info = sym->st_info;
+      s->info.other = sym->st_other;
+
+      if (scnmap != NULL && shndx != SHN_UNDEF && shndx < SHN_LORESERVE)
+	s->shndx = scnmap[shndx - 1];
+
+      if (GELF_ST_TYPE (s->info.info) == STT_SECTION && !rel)
+	{
+	  /* Update the value to match the output section.  */
+	  GElf_Shdr shdr_mem;
+	  GElf_Shdr *shdr = gelf_getshdr (elf_getscn (outelf, s->shndx),
+					  &shdr_mem);
+	  ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
+	  s->value = shdr->sh_addr;
+	}
+      else if (split_bss != NULL
+	       && s->value < split_bss->shdr.sh_addr
+	       && s->value >= split_bss[-1].shdr.sh_addr
+	       && shndx == elf_ndxscn (split_bss->outscn))
+	/* This symbol was in .bss and was split into .dynbss.  */
+	s->shndx = elf_ndxscn (split_bss[-1].outscn);
+    }
+}
+
+
+#define CMP(value)							      \
+  if (s1->value < s2->value)						      \
+    return -1;								      \
+  if (s1->value > s2->value)						      \
+    return 1
+
+/* Compare symbols with a consistent ordering,
+   but one only meaningful for equality.  */
+static int
+compare_symbols (const void *a, const void *b)
+{
+  const struct symbol *s1 = a;
+  const struct symbol *s2 = b;
+
+  CMP (value);
+  CMP (size);
+  CMP (shndx);
+
+  return (s1->compare - s2->compare) ?: strcmp (s1->name, s2->name);
+}
+
+/* Compare symbols for output order after slots have been assigned.  */
+static int
+compare_symbols_output (const void *a, const void *b)
+{
+  const struct symbol *s1 = a;
+  const struct symbol *s2 = b;
+  int cmp;
+
+  /* Sort discarded symbols last.  */
+  cmp = (s1->name == NULL) - (s2->name == NULL);
+
+  if (cmp == 0)
+    /* Local symbols must come first.  */
+    cmp = ((GELF_ST_BIND (s2->info.info) == STB_LOCAL)
+	   - (GELF_ST_BIND (s1->info.info) == STB_LOCAL));
+
+  if (cmp == 0)
+    /* binutils always puts section symbols first.  */
+    cmp = ((GELF_ST_TYPE (s2->info.info) == STT_SECTION)
+	   - (GELF_ST_TYPE (s1->info.info) == STT_SECTION));
+
+  if (cmp == 0)
+    {
+      if (GELF_ST_TYPE (s1->info.info) == STT_SECTION)
+	{
+	  /* binutils always puts section symbols in section index order.  */
+	  CMP (shndx);
+	  else
+	    assert (s1 == s2);
+	}
+
+      /* Nothing really matters, so preserve the original order.  */
+      CMP (map);
+      else
+	assert (s1 == s2);
+    }
+
+  return cmp;
+}
+
+#undef CMP
+
+/* Return true if the flags of the sections match, ignoring the SHF_INFO_LINK
+   flag if the section contains relocation information.  */
+static bool
+sections_flags_match (Elf64_Xword sh_flags1, Elf64_Xword sh_flags2,
+		      Elf64_Word sh_type)
+{
+  if (sh_type == SHT_REL || sh_type == SHT_RELA)
+    {
+      sh_flags1 &= ~SHF_INFO_LINK;
+      sh_flags2 &= ~SHF_INFO_LINK;
+    }
+
+  return sh_flags1 == sh_flags2;
+}
+
+/* Return true iff the flags, size, and name match.  */
+static bool
+sections_match (const struct section *sections, size_t i,
+		const GElf_Shdr *shdr, const char *name)
+{
+  return (sections_flags_match (sections[i].shdr.sh_flags, shdr->sh_flags,
+				sections[i].shdr.sh_type)
+	  && (sections[i].shdr.sh_size == shdr->sh_size
+	      || (sections[i].shdr.sh_size < shdr->sh_size
+		  && section_can_shrink (&sections[i].shdr)))
+	  && !strcmp (sections[i].name, name));
+}
+
+/* Locate a matching allocated section in SECTIONS.  */
+static struct section *
+find_alloc_section (const GElf_Shdr *shdr, GElf_Addr bias, const char *name,
+		    struct section sections[], size_t nalloc)
+{
+  const GElf_Addr addr = shdr->sh_addr + bias;
+  size_t l = 0, u = nalloc;
+  while (l < u)
+    {
+      size_t i = (l + u) / 2;
+      if (addr < sections[i].shdr.sh_addr)
+	u = i;
+      else if (addr > sections[i].shdr.sh_addr)
+	l = i + 1;
+      else
+	{
+	  /* We've found allocated sections with this address.
+	     Find one with matching size, flags, and name.  */
+	  while (i > 0 && sections[i - 1].shdr.sh_addr == addr)
+	    --i;
+	  for (; i < nalloc && sections[i].shdr.sh_addr == addr;
+	       ++i)
+	    if (sections_match (sections, i, shdr, name))
+	      return &sections[i];
+	  break;
+	}
+    }
+  return NULL;
+}
+
+static inline const char *
+get_section_name (size_t ndx, const GElf_Shdr *shdr, const Elf_Data *shstrtab)
+{
+  if (shdr->sh_name >= shstrtab->d_size)
+    error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"),
+	   ndx, elf_errmsg (-1));
+  return shstrtab->d_buf + shdr->sh_name;
+}
+
+/* Fix things up when prelink has moved some allocated sections around
+   and the debuginfo file's section headers no longer match up.
+   This fills in SECTIONS[0..NALLOC-1].outscn or exits.
+   If there was a .bss section that was split into two sections
+   with the new one preceding it in sh_addr, we return that pointer.  */
+static struct section *
+find_alloc_sections_prelink (Elf *debug, Elf_Data *debug_shstrtab,
+			     Elf *main, const GElf_Ehdr *main_ehdr,
+			     Elf_Data *main_shstrtab, GElf_Addr bias,
+			     struct section *sections,
+			     size_t nalloc, size_t nsections)
+{
+  Elf_Scn *undo = NULL;
+  for (size_t i = nalloc; i < nsections; ++i)
+    {
+      const struct section *sec = &sections[i];
+      if (sec->shdr.sh_type == SHT_PROGBITS
+	  && !(sec->shdr.sh_flags & SHF_ALLOC)
+	  && !strcmp (sec->name, ".gnu.prelink_undo"))
+	{
+	  undo = sec->scn;
+	  break;
+	}
+    }
+
+  /* Find the original allocated sections before prelinking.  */
+  struct section *undo_sections = NULL;
+  size_t undo_nalloc = 0;
+  if (undo != NULL)
+    {
+      /* Clear assignments that might have been bogus.  */
+      for (size_t i = 0; i < nalloc; ++i)
+	sections[i].outscn = NULL;
+
+      Elf_Data *undodata = elf_rawdata (undo, NULL);
+      ELF_CHECK (undodata != NULL,
+		 _("cannot read '.gnu.prelink_undo' section: %s"));
+
+      union
+      {
+	Elf32_Ehdr e32;
+	Elf64_Ehdr e64;
+      } ehdr;
+      Elf_Data dst =
+	{
+	  .d_buf = &ehdr,
+	  .d_size = sizeof ehdr,
+	  .d_type = ELF_T_EHDR,
+	  .d_version = EV_CURRENT
+	};
+      Elf_Data src = *undodata;
+      src.d_size = gelf_fsize (main, ELF_T_EHDR, 1, EV_CURRENT);
+      src.d_type = ELF_T_EHDR;
+      ELF_CHECK (gelf_xlatetom (main, &dst, &src,
+				main_ehdr->e_ident[EI_DATA]) != NULL,
+		 _("cannot read '.gnu.prelink_undo' section: %s"));
+
+      uint_fast16_t phnum;
+      uint_fast16_t shnum;
+      if (ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32)
+	{
+	  phnum = ehdr.e32.e_phnum;
+	  shnum = ehdr.e32.e_shnum;
+	}
+      else
+	{
+	  phnum = ehdr.e64.e_phnum;
+	  shnum = ehdr.e64.e_shnum;
+	}
+
+      bool class32 = ehdr.e32.e_ident[EI_CLASS] == ELFCLASS32;
+      size_t shsize = class32 ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr);
+      if (unlikely (shnum == 0 || shnum > SIZE_MAX / shsize + 1))
+	error (EXIT_FAILURE, 0, _("overflow with shnum = %zu in '%s' section"),
+	       (size_t) shnum, ".gnu.prelink_undo");
+
+      --shnum;
+
+      size_t phsize = gelf_fsize (main, ELF_T_PHDR, phnum, EV_CURRENT);
+      src.d_buf += src.d_size + phsize;
+      src.d_size = gelf_fsize (main, ELF_T_SHDR, shnum, EV_CURRENT);
+      src.d_type = ELF_T_SHDR;
+      if ((size_t) (src.d_buf - undodata->d_buf) > undodata->d_size
+	  || undodata->d_size - (src.d_buf - undodata->d_buf) != src.d_size)
+	error (EXIT_FAILURE, 0, _("invalid contents in '%s' section"),
+	       ".gnu.prelink_undo");
+
+      const size_t shdr_bytes = shnum * shsize;
+      void *shdr = xmalloc (shdr_bytes);
+      dst.d_buf = shdr;
+      dst.d_size = shdr_bytes;
+      ELF_CHECK (gelf_xlatetom (main, &dst, &src,
+				main_ehdr->e_ident[EI_DATA]) != NULL,
+		 _("cannot read '.gnu.prelink_undo' section: %s"));
+
+      undo_sections = xmalloc (shnum * sizeof undo_sections[0]);
+      for (size_t i = 0; i < shnum; ++i)
+	{
+	  struct section *sec = &undo_sections[undo_nalloc];
+	  Elf32_Shdr (*s32)[shnum] = shdr;
+	  Elf64_Shdr (*s64)[shnum] = shdr;
+	  if (class32)
+	    {
+#define COPY(field) sec->shdr.field = (*s32)[i].field
+	      COPY (sh_name);
+	      COPY (sh_type);
+	      COPY (sh_flags);
+	      COPY (sh_addr);
+	      COPY (sh_offset);
+	      COPY (sh_size);
+	      COPY (sh_link);
+	      COPY (sh_info);
+	      COPY (sh_addralign);
+	      COPY (sh_entsize);
+#undef	COPY
+	    }
+	  else
+	    sec->shdr = (*s64)[i];
+	  if (sec->shdr.sh_flags & SHF_ALLOC)
+	    {
+	      sec->shdr.sh_addr += bias;
+	      sec->name = get_section_name (i + 1, &sec->shdr, main_shstrtab);
+	      sec->scn = elf_getscn (main, i + 1); /* Really just for ndx.  */
+	      sec->outscn = NULL;
+	      sec->strent = NULL;
+	      ++undo_nalloc;
+	    }
+	}
+      qsort (undo_sections, undo_nalloc,
+	     sizeof undo_sections[0], compare_sections_nonrel);
+      free (shdr);
+    }
+
+  bool fail = false;
+  inline void check_match (bool match, Elf_Scn *scn, const char *name)
+    {
+      if (!match)
+	{
+	  fail = true;
+	  error (0, 0, _("cannot find matching section for [%zu] '%s'"),
+		 elf_ndxscn (scn), name);
+	}
+    }
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (debug, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
+
+      if (!(shdr->sh_flags & SHF_ALLOC))
+	continue;
+
+      const char *name = get_section_name (elf_ndxscn (scn), shdr,
+					   debug_shstrtab);
+
+      if (undo_sections != NULL)
+	{
+	  struct section *sec = find_alloc_section (shdr, 0, name,
+						    undo_sections,
+						    undo_nalloc);
+	  if (sec != NULL)
+	    {
+	      sec->outscn = scn;
+	      continue;
+	    }
+	}
+
+      /* If there is no prelink info, we are just here to find
+	 the sections to give error messages about.  */
+      for (size_t i = 0; shdr != NULL && i < nalloc; ++i)
+	if (sections[i].outscn == scn)
+	  shdr = NULL;
+      check_match (shdr == NULL, scn, name);
+    }
+
+  if (fail)
+    exit (EXIT_FAILURE);
+
+  /* Now we have lined up output sections for each of the original sections
+     before prelinking.  Translate those to the prelinked sections.
+     This matches what prelink's undo_sections does.  */
+  struct section *split_bss = NULL;
+  for (size_t i = 0; i < undo_nalloc; ++i)
+    {
+      const struct section *undo_sec = &undo_sections[i];
+
+      const char *name = undo_sec->name;
+      scn = undo_sec->scn; /* This is just for elf_ndxscn.  */
+
+      for (size_t j = 0; j < nalloc; ++j)
+	{
+	  struct section *sec = &sections[j];
+#define RELA_SCALED(field) \
+	  (2 * sec->shdr.field == 3 * undo_sec->shdr.field)
+	  if (sec->outscn == NULL
+	      && sec->shdr.sh_name == undo_sec->shdr.sh_name
+	      && sec->shdr.sh_flags == undo_sec->shdr.sh_flags
+	      && sec->shdr.sh_addralign == undo_sec->shdr.sh_addralign
+	      && (((sec->shdr.sh_type == undo_sec->shdr.sh_type
+		    && sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
+		    && (sec->shdr.sh_size == undo_sec->shdr.sh_size
+			|| (sec->shdr.sh_size > undo_sec->shdr.sh_size
+			    && main_ehdr->e_type == ET_EXEC
+			    && !strcmp (sec->name, ".dynstr"))))
+		   || (sec->shdr.sh_size == undo_sec->shdr.sh_size
+		       && ((sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
+			    && undo_sec->shdr.sh_type == SHT_NOBITS)
+			   || undo_sec->shdr.sh_type == SHT_PROGBITS)
+		       && !strcmp (sec->name, ".plt")))
+		  || (sec->shdr.sh_type == SHT_RELA
+		      && undo_sec->shdr.sh_type == SHT_REL
+		      && RELA_SCALED (sh_entsize) && RELA_SCALED (sh_size))
+		  || (sec->shdr.sh_entsize == undo_sec->shdr.sh_entsize
+		      && (sec->shdr.sh_type == undo_sec->shdr.sh_type
+			  || (sec->shdr.sh_type == SHT_PROGBITS
+			      && undo_sec->shdr.sh_type == SHT_NOBITS))
+		      && sec->shdr.sh_size <= undo_sec->shdr.sh_size
+		      && (!strcmp (sec->name, ".bss")
+			  || !strcmp (sec->name, ".sbss"))
+		      && (sec->shdr.sh_size == undo_sec->shdr.sh_size
+			  || (split_bss = sec) > sections))))
+	    {
+	      sec->outscn = undo_sec->outscn;
+	      undo_sec = NULL;
+	      break;
+	    }
+	}
+
+      check_match (undo_sec == NULL, scn, name);
+    }
+
+  free (undo_sections);
+
+  if (fail)
+    exit (EXIT_FAILURE);
+
+  return split_bss;
+}
+
+/* Create new .shstrtab contents, subroutine of copy_elided_sections.
+   This can't be open coded there and still use variable-length auto arrays,
+   since the end of our block would free other VLAs too.  */
+static Elf_Data *
+new_shstrtab (Elf *unstripped, size_t unstripped_shnum,
+	      Elf_Data *shstrtab, size_t unstripped_shstrndx,
+	      struct section *sections, size_t stripped_shnum,
+	      Dwelf_Strtab *strtab)
+{
+  if (strtab == NULL)
+    return NULL;
+
+  Dwelf_Strent *unstripped_strent[unstripped_shnum - 1];
+  memset (unstripped_strent, 0, sizeof unstripped_strent);
+  for (struct section *sec = sections;
+       sec < &sections[stripped_shnum - 1];
+       ++sec)
+    if (sec->outscn != NULL)
+      {
+	if (sec->strent == NULL)
+	  {
+	    sec->strent = dwelf_strtab_add (strtab, sec->name);
+	    ELF_CHECK (sec->strent != NULL,
+		       _("cannot add section name to string table: %s"));
+	  }
+	unstripped_strent[elf_ndxscn (sec->outscn) - 1] = sec->strent;
+      }
+
+  /* Add names of sections we aren't touching.  */
+  for (size_t i = 0; i < unstripped_shnum - 1; ++i)
+    if (unstripped_strent[i] == NULL)
+      {
+	Elf_Scn *scn = elf_getscn (unstripped, i + 1);
+	GElf_Shdr shdr_mem;
+	GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	const char *name = get_section_name (i + 1, shdr, shstrtab);
+	unstripped_strent[i] = dwelf_strtab_add (strtab, name);
+	ELF_CHECK (unstripped_strent[i] != NULL,
+		   _("cannot add section name to string table: %s"));
+      }
+    else
+      unstripped_strent[i] = NULL;
+
+  /* Now finalize the string table so we can get offsets.  */
+  Elf_Data *strtab_data = elf_getdata (elf_getscn (unstripped,
+						   unstripped_shstrndx), NULL);
+  ELF_CHECK (elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY),
+	     _("cannot update section header string table data: %s"));
+  if (dwelf_strtab_finalize (strtab, strtab_data) == NULL)
+    error (EXIT_FAILURE, 0, "Not enough memory to create string table");
+
+  /* Update the sh_name fields of sections we aren't modifying later.  */
+  for (size_t i = 0; i < unstripped_shnum - 1; ++i)
+    if (unstripped_strent[i] != NULL)
+      {
+	Elf_Scn *scn = elf_getscn (unstripped, i + 1);
+	GElf_Shdr shdr_mem;
+	GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	shdr->sh_name = dwelf_strent_off (unstripped_strent[i]);
+	if (i + 1 == unstripped_shstrndx)
+	  shdr->sh_size = strtab_data->d_size;
+	update_shdr (scn, shdr);
+      }
+
+  return strtab_data;
+}
+
+/* Fill in any SHT_NOBITS sections in UNSTRIPPED by
+   copying their contents and sh_type from STRIPPED.  */
+static void
+copy_elided_sections (Elf *unstripped, Elf *stripped,
+		      const GElf_Ehdr *stripped_ehdr, GElf_Addr bias)
+{
+  size_t unstripped_shstrndx;
+  ELF_CHECK (elf_getshdrstrndx (unstripped, &unstripped_shstrndx) == 0,
+	     _("cannot get section header string table section index: %s"));
+
+  size_t stripped_shstrndx;
+  ELF_CHECK (elf_getshdrstrndx (stripped, &stripped_shstrndx) == 0,
+	     _("cannot get section header string table section index: %s"));
+
+  size_t unstripped_shnum;
+  ELF_CHECK (elf_getshdrnum (unstripped, &unstripped_shnum) == 0,
+	     _("cannot get section count: %s"));
+
+  size_t stripped_shnum;
+  ELF_CHECK (elf_getshdrnum (stripped, &stripped_shnum) == 0,
+	     _("cannot get section count: %s"));
+
+  if (unlikely (stripped_shnum > unstripped_shnum))
+    error (EXIT_FAILURE, 0, _("\
+more sections in stripped file than debug file -- arguments reversed?"));
+
+  /* Cache the stripped file's section details.  */
+  struct section sections[stripped_shnum - 1];
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (stripped, scn)) != NULL)
+    {
+      size_t i = elf_ndxscn (scn) - 1;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &sections[i].shdr);
+      ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
+      sections[i].name = elf_strptr (stripped, stripped_shstrndx,
+				     shdr->sh_name);
+      if (sections[i].name == NULL)
+	error (EXIT_FAILURE, 0, _("cannot read section [%zu] name: %s"),
+	       elf_ndxscn (scn), elf_errmsg (-1));
+      sections[i].scn = scn;
+      sections[i].outscn = NULL;
+      sections[i].strent = NULL;
+    }
+
+  const struct section *stripped_symtab = NULL;
+
+  /* Sort the sections, allocated by address and others after.  */
+  qsort (sections, stripped_shnum - 1, sizeof sections[0],
+	 stripped_ehdr->e_type == ET_REL
+	 ? compare_sections_rel : compare_sections_nonrel);
+  size_t nalloc = stripped_shnum - 1;
+  while (nalloc > 0 && !(sections[nalloc - 1].shdr.sh_flags & SHF_ALLOC))
+    {
+      --nalloc;
+      if (sections[nalloc].shdr.sh_type == SHT_SYMTAB)
+	stripped_symtab = &sections[nalloc];
+    }
+
+  /* Locate a matching unallocated section in SECTIONS.  */
+  inline struct section *find_unalloc_section (const GElf_Shdr *shdr,
+					       const char *name)
+    {
+      size_t l = nalloc, u = stripped_shnum - 1;
+      while (l < u)
+	{
+	  size_t i = (l + u) / 2;
+	  struct section *sec = &sections[i];
+	  int cmp = compare_unalloc_sections (shdr, &sec->shdr,
+					      name, sec->name);
+	  if (cmp < 0)
+	    u = i;
+	  else if (cmp > 0)
+	    l = i + 1;
+	  else
+	    return sec;
+	}
+      return NULL;
+    }
+
+  Elf_Data *shstrtab = elf_getdata (elf_getscn (unstripped,
+						unstripped_shstrndx), NULL);
+  ELF_CHECK (shstrtab != NULL,
+	     _("cannot read section header string table: %s"));
+
+  /* Match each debuginfo section with its corresponding stripped section.  */
+  bool check_prelink = false;
+  Elf_Scn *unstripped_symtab = NULL;
+  size_t unstripped_strndx = 0;
+  size_t alloc_avail = 0;
+  scn = NULL;
+  while ((scn = elf_nextscn (unstripped, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
+
+      if (shdr->sh_type == SHT_SYMTAB)
+	{
+	  unstripped_symtab = scn;
+	  unstripped_strndx = shdr->sh_link;
+	  continue;
+	}
+
+      const size_t ndx = elf_ndxscn (scn);
+      if (ndx == unstripped_shstrndx || ndx == unstripped_strndx)
+	continue;
+
+      const char *name = get_section_name (ndx, shdr, shstrtab);
+
+      struct section *sec = NULL;
+      if (shdr->sh_flags & SHF_ALLOC)
+	{
+	  if (stripped_ehdr->e_type != ET_REL)
+	    {
+	      /* Look for the section that matches.  */
+	      sec = find_alloc_section (shdr, bias, name, sections, nalloc);
+	      if (sec == NULL)
+		{
+		  /* We couldn't figure it out.  It may be a prelink issue.  */
+		  check_prelink = true;
+		  continue;
+		}
+	    }
+	  else
+	    {
+	      /* The sh_addr of allocated sections does not help us,
+		 but the order usually matches.  */
+	      if (likely (sections_match (sections, alloc_avail, shdr, name)))
+		sec = &sections[alloc_avail++];
+	      else
+		for (size_t i = alloc_avail + 1; i < nalloc; ++i)
+		  if (sections_match (sections, i, shdr, name))
+		    {
+		      sec = &sections[i];
+		      break;
+		    }
+	    }
+	}
+      else
+	{
+	  /* Look for the section that matches.  */
+	  sec = find_unalloc_section (shdr, name);
+	  if (sec == NULL)
+	    {
+	      /* An additional unallocated section is fine if not SHT_NOBITS.
+		 We looked it up anyway in case it's an unallocated section
+		 copied in both files (e.g. SHT_NOTE), and don't keep both.  */
+	      if (shdr->sh_type != SHT_NOBITS)
+		continue;
+
+	      /* Somehow some old .debug files wound up with SHT_NOBITS
+		 .comment sections, so let those pass.  */
+	      if (!strcmp (name, ".comment"))
+		continue;
+	    }
+	}
+
+      if (sec == NULL)
+	error (EXIT_FAILURE, 0,
+	       _("cannot find matching section for [%zu] '%s'"),
+	       elf_ndxscn (scn), name);
+
+      sec->outscn = scn;
+    }
+
+  /* If that failed due to changes made by prelink, we take another tack.
+     We keep track of a .bss section that was partly split into .dynbss
+     so that collect_symbols can update symbols' st_shndx fields.  */
+  struct section *split_bss = NULL;
+  if (check_prelink)
+    {
+      Elf_Data *data = elf_getdata (elf_getscn (stripped, stripped_shstrndx),
+				    NULL);
+      ELF_CHECK (data != NULL,
+		 _("cannot read section header string table: %s"));
+      split_bss = find_alloc_sections_prelink (unstripped, shstrtab,
+					       stripped, stripped_ehdr,
+					       data, bias, sections,
+					       nalloc, stripped_shnum - 1);
+    }
+
+  /* Make sure each main file section has a place to go.  */
+  const struct section *stripped_dynsym = NULL;
+  size_t debuglink = SHN_UNDEF;
+  size_t ndx_section[stripped_shnum - 1];
+  Dwelf_Strtab *strtab = NULL;
+  for (struct section *sec = sections;
+       sec < &sections[stripped_shnum - 1];
+       ++sec)
+    {
+      size_t secndx = elf_ndxscn (sec->scn);
+
+      if (sec->outscn == NULL)
+	{
+	  /* We didn't find any corresponding section for this.  */
+
+	  if (secndx == stripped_shstrndx)
+	    {
+	      /* We only need one .shstrtab.  */
+	      ndx_section[secndx - 1] = unstripped_shstrndx;
+	      continue;
+	    }
+
+	  if (unstripped_symtab != NULL && sec == stripped_symtab)
+	    {
+	      /* We don't need a second symbol table.  */
+	      ndx_section[secndx - 1] = elf_ndxscn (unstripped_symtab);
+	      continue;
+	    }
+
+	  if (unstripped_symtab != NULL && stripped_symtab != NULL
+	      && secndx == stripped_symtab->shdr.sh_link
+	      && unstripped_strndx != 0)
+	    {
+	      /* ... nor its string table.  */
+	      ndx_section[secndx - 1] = unstripped_strndx;
+	      continue;
+	    }
+
+	  if (!(sec->shdr.sh_flags & SHF_ALLOC)
+	      && !strcmp (sec->name, ".gnu_debuglink"))
+	    {
+	      /* This was created by stripping.  We don't want it.  */
+	      debuglink = secndx;
+	      ndx_section[secndx - 1] = SHN_UNDEF;
+	      continue;
+	    }
+
+	  sec->outscn = elf_newscn (unstripped);
+	  Elf_Data *newdata = elf_newdata (sec->outscn);
+	  ELF_CHECK (newdata != NULL && gelf_update_shdr (sec->outscn,
+							  &sec->shdr),
+		     _("cannot add new section: %s"));
+
+	  if (strtab == NULL)
+	    strtab = dwelf_strtab_init (true);
+	  sec->strent = dwelf_strtab_add (strtab, sec->name);
+	  ELF_CHECK (sec->strent != NULL,
+		     _("cannot add section name to string table: %s"));
+	}
+
+      /* Cache the mapping of original section indices to output sections.  */
+      ndx_section[secndx - 1] = elf_ndxscn (sec->outscn);
+    }
+
+  /* We added some sections, so we need a new shstrtab.  */
+  Elf_Data *strtab_data = new_shstrtab (unstripped, unstripped_shnum,
+					shstrtab, unstripped_shstrndx,
+					sections, stripped_shnum,
+					strtab);
+
+  /* Get the updated section count.  */
+  ELF_CHECK (elf_getshdrnum (unstripped, &unstripped_shnum) == 0,
+	     _("cannot get section count: %s"));
+
+  bool placed[unstripped_shnum - 1];
+  memset (placed, 0, sizeof placed);
+
+  /* Now update the output sections and copy in their data.  */
+  GElf_Off offset = 0;
+  for (const struct section *sec = sections;
+       sec < &sections[stripped_shnum - 1];
+       ++sec)
+    if (sec->outscn != NULL)
+      {
+	GElf_Shdr shdr_mem;
+	GElf_Shdr *shdr = gelf_getshdr (sec->outscn, &shdr_mem);
+	ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
+
+	/* In an ET_REL file under --relocate, the sh_addr of SHF_ALLOC
+	   sections will have been set nonzero by relocation.  This
+	   touched the shdrs of whichever file had the symtab.  sh_addr
+	   is still zero in the corresponding shdr.  The relocated
+	   address is what we want to use.  */
+	if (stripped_ehdr->e_type != ET_REL
+	    || !(shdr_mem.sh_flags & SHF_ALLOC)
+	    || shdr_mem.sh_addr == 0)
+	  shdr_mem.sh_addr = sec->shdr.sh_addr;
+
+	shdr_mem.sh_type = sec->shdr.sh_type;
+	shdr_mem.sh_size = sec->shdr.sh_size;
+	shdr_mem.sh_info = sec->shdr.sh_info;
+	shdr_mem.sh_link = sec->shdr.sh_link;
+
+	/* Buggy binutils objdump might have stripped the SHF_INFO_LINK
+	   put it back if necessary.  */
+	if ((sec->shdr.sh_type == SHT_REL || sec->shdr.sh_type == SHT_RELA)
+	    && sec->shdr.sh_flags != shdr_mem.sh_flags
+	    && (sec->shdr.sh_flags & SHF_INFO_LINK) != 0)
+	  shdr_mem.sh_flags |= SHF_INFO_LINK;
+
+	if (sec->shdr.sh_link != SHN_UNDEF)
+	  shdr_mem.sh_link = ndx_section[sec->shdr.sh_link - 1];
+	if (SH_INFO_LINK_P (&sec->shdr) && sec->shdr.sh_info != 0)
+	  shdr_mem.sh_info = ndx_section[sec->shdr.sh_info - 1];
+
+	if (strtab != NULL)
+	  shdr_mem.sh_name = dwelf_strent_off (sec->strent);
+
+	Elf_Data *indata = elf_getdata (sec->scn, NULL);
+	ELF_CHECK (indata != NULL, _("cannot get section data: %s"));
+	Elf_Data *outdata = elf_getdata (sec->outscn, NULL);
+	ELF_CHECK (outdata != NULL, _("cannot copy section data: %s"));
+	*outdata = *indata;
+	elf_flagdata (outdata, ELF_C_SET, ELF_F_DIRTY);
+
+	/* Preserve the file layout of the allocated sections.  */
+	if (stripped_ehdr->e_type != ET_REL && (shdr_mem.sh_flags & SHF_ALLOC))
+	  {
+	    shdr_mem.sh_offset = sec->shdr.sh_offset;
+	    placed[elf_ndxscn (sec->outscn) - 1] = true;
+
+	    const GElf_Off end_offset = (shdr_mem.sh_offset
+					 + (shdr_mem.sh_type == SHT_NOBITS
+					    ? 0 : shdr_mem.sh_size));
+	    if (end_offset > offset)
+	      offset = end_offset;
+	  }
+
+	update_shdr (sec->outscn, &shdr_mem);
+
+	if (shdr_mem.sh_type == SHT_SYMTAB || shdr_mem.sh_type == SHT_DYNSYM)
+	  {
+	    /* We must adjust all the section indices in the symbol table.  */
+
+	    Elf_Data *shndxdata = NULL;	/* XXX */
+
+	    for (size_t i = 1; i < shdr_mem.sh_size / shdr_mem.sh_entsize; ++i)
+	      {
+		GElf_Sym sym_mem;
+		GElf_Word shndx = SHN_UNDEF;
+		GElf_Sym *sym = gelf_getsymshndx (outdata, shndxdata,
+						  i, &sym_mem, &shndx);
+		ELF_CHECK (sym != NULL,
+			   _("cannot get symbol table entry: %s"));
+		if (sym->st_shndx != SHN_XINDEX)
+		  shndx = sym->st_shndx;
+
+		if (shndx != SHN_UNDEF && shndx < SHN_LORESERVE)
+		  {
+		    if (shndx >= stripped_shnum)
+		      error (EXIT_FAILURE, 0,
+			     _("symbol [%zu] has invalid section index"), i);
+
+		    shndx = ndx_section[shndx - 1];
+		    if (shndx < SHN_LORESERVE)
+		      {
+			sym->st_shndx = shndx;
+			shndx = SHN_UNDEF;
+		      }
+		    else
+		      sym->st_shndx = SHN_XINDEX;
+
+		    ELF_CHECK (gelf_update_symshndx (outdata, shndxdata,
+						     i, sym, shndx),
+			       _("cannot update symbol table: %s"));
+		  }
+	      }
+
+	    if (shdr_mem.sh_type == SHT_SYMTAB)
+	      stripped_symtab = sec;
+	    if (shdr_mem.sh_type == SHT_DYNSYM)
+	      stripped_dynsym = sec;
+	  }
+      }
+
+  /* We may need to update the symbol table.  */
+  Elf_Data *symdata = NULL;
+  Dwelf_Strtab *symstrtab = NULL;
+  Elf_Data *symstrdata = NULL;
+  if (unstripped_symtab != NULL && (stripped_symtab != NULL
+				    || check_prelink /* Section adjustments. */
+				    || (stripped_ehdr->e_type != ET_REL
+					&& bias != 0)))
+    {
+      /* Merge the stripped file's symbol table into the unstripped one.  */
+      const size_t stripped_nsym = (stripped_symtab == NULL ? 1
+				    : (stripped_symtab->shdr.sh_size
+				       / stripped_symtab->shdr.sh_entsize));
+
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (unstripped_symtab, &shdr_mem);
+      ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
+      const size_t unstripped_nsym = shdr->sh_size / shdr->sh_entsize;
+
+      /* First collect all the symbols from both tables.  */
+
+      const size_t total_syms = stripped_nsym - 1 + unstripped_nsym - 1;
+      struct symbol symbols[total_syms];
+      size_t symndx_map[total_syms];
+
+      if (stripped_symtab != NULL)
+	collect_symbols (unstripped, stripped_ehdr->e_type == ET_REL,
+			 stripped_symtab->scn,
+			 elf_getscn (stripped, stripped_symtab->shdr.sh_link),
+			 stripped_nsym, 0, ndx_section,
+			 symbols, symndx_map, NULL);
+
+      Elf_Scn *unstripped_strtab = elf_getscn (unstripped, shdr->sh_link);
+      collect_symbols (unstripped, stripped_ehdr->e_type == ET_REL,
+		       unstripped_symtab, unstripped_strtab, unstripped_nsym,
+		       stripped_ehdr->e_type == ET_REL ? 0 : bias, NULL,
+		       &symbols[stripped_nsym - 1],
+		       &symndx_map[stripped_nsym - 1], split_bss);
+
+      /* Next, sort our array of all symbols.  */
+      qsort (symbols, total_syms, sizeof symbols[0], compare_symbols);
+
+      /* Now we can weed out the duplicates.  Assign remaining symbols
+	 new slots, collecting a map from old indices to new.  */
+      size_t nsym = 0;
+      for (struct symbol *s = symbols; s < &symbols[total_syms]; ++s)
+	{
+	  /* Skip a section symbol for a removed section.  */
+	  if (s->shndx == SHN_UNDEF
+	      && GELF_ST_TYPE (s->info.info) == STT_SECTION)
+	    {
+	      s->name = NULL;	/* Mark as discarded. */
+	      *s->map = STN_UNDEF;
+	      s->duplicate = NULL;
+	      continue;
+	    }
+
+	  struct symbol *n = s;
+	  while (n + 1 < &symbols[total_syms] && !compare_symbols (s, n + 1))
+	    ++n;
+
+	  while (s < n)
+	    {
+	      /* This is a duplicate.  Its twin will get the next slot.  */
+	      s->name = NULL;	/* Mark as discarded. */
+	      s->duplicate = n->map;
+	      ++s;
+	    }
+
+	  /* Allocate the next slot.  */
+	  *s->map = ++nsym;
+	}
+
+      /* Now we sort again, to determine the order in the output.  */
+      qsort (symbols, total_syms, sizeof symbols[0], compare_symbols_output);
+
+      if (nsym < total_syms)
+	/* The discarded symbols are now at the end of the table.  */
+	assert (symbols[nsym].name == NULL);
+
+      /* Now a final pass updates the map with the final order,
+	 and builds up the new string table.  */
+      symstrtab = dwelf_strtab_init (true);
+      for (size_t i = 0; i < nsym; ++i)
+	{
+	  assert (symbols[i].name != NULL);
+	  assert (*symbols[i].map != 0);
+	  *symbols[i].map = 1 + i;
+	  symbols[i].strent = dwelf_strtab_add (symstrtab, symbols[i].name);
+	}
+
+      /* Scan the discarded symbols too, just to update their slots
+	 in SYMNDX_MAP to refer to their live duplicates.  */
+      for (size_t i = nsym; i < total_syms; ++i)
+	{
+	  assert (symbols[i].name == NULL);
+	  if (symbols[i].duplicate == NULL)
+	    assert (*symbols[i].map == STN_UNDEF);
+	  else
+	    {
+	      assert (*symbols[i].duplicate != STN_UNDEF);
+	      *symbols[i].map = *symbols[i].duplicate;
+	    }
+	}
+
+      /* Now we are ready to write the new symbol table.  */
+      symdata = elf_getdata (unstripped_symtab, NULL);
+      symstrdata = elf_getdata (unstripped_strtab, NULL);
+      Elf_Data *shndxdata = NULL;	/* XXX */
+
+      /* If symtab and the section header table share the string table
+	 add the section names to the strtab and then (after finalizing)
+	 fixup the section header sh_names.  Also dispose of the old data.  */
+      Dwelf_Strent *unstripped_strent[unstripped_shnum - 1];
+      if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab))
+	{
+	  for (size_t i = 0; i < unstripped_shnum - 1; ++i)
+	    {
+	      Elf_Scn *sec = elf_getscn (unstripped, i + 1);
+	      GElf_Shdr mem;
+	      GElf_Shdr *hdr = gelf_getshdr (sec, &mem);
+	      const char *name = get_section_name (i + 1, hdr, shstrtab);
+	      unstripped_strent[i] = dwelf_strtab_add (symstrtab, name);
+	      ELF_CHECK (unstripped_strent[i] != NULL,
+			 _("cannot add section name to string table: %s"));
+	    }
+
+	  if (strtab != NULL)
+	    {
+	      dwelf_strtab_free (strtab);
+	      free (strtab_data->d_buf);
+	      strtab = NULL;
+	    }
+	}
+
+      if (dwelf_strtab_finalize (symstrtab, symstrdata) == NULL)
+	error (EXIT_FAILURE, 0, "Not enough memory to create symbol table");
+
+      elf_flagdata (symstrdata, ELF_C_SET, ELF_F_DIRTY);
+
+      /* And update the section header names if necessary.  */
+      if (unstripped_shstrndx == elf_ndxscn (unstripped_strtab))
+	{
+	  for (size_t i = 0; i < unstripped_shnum - 1; ++i)
+	    {
+	      Elf_Scn *sec = elf_getscn (unstripped, i + 1);
+	      GElf_Shdr mem;
+	      GElf_Shdr *hdr = gelf_getshdr (sec, &mem);
+	      shdr->sh_name = dwelf_strent_off (unstripped_strent[i]);
+	      update_shdr (sec, hdr);
+	    }
+	}
+
+      /* Now update the symtab shdr.  Reload symtab shdr because sh_name
+	 might have changed above. */
+      shdr = gelf_getshdr (unstripped_symtab, &shdr_mem);
+      ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
+
+      shdr->sh_size = symdata->d_size = (1 + nsym) * shdr->sh_entsize;
+      symdata->d_buf = xmalloc (symdata->d_size);
+      record_new_data (symdata->d_buf);
+
+      GElf_Sym sym;
+      memset (&sym, 0, sizeof sym);
+      ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, 0, &sym, SHN_UNDEF),
+		 _("cannot update symbol table: %s"));
+
+      shdr->sh_info = 1;
+      for (size_t i = 0; i < nsym; ++i)
+	{
+	  struct symbol *s = &symbols[i];
+
+	  /* Fill in the symbol details.  */
+	  sym.st_name = dwelf_strent_off (s->strent);
+	  sym.st_value = s->value; /* Already biased to output address.  */
+	  sym.st_size = s->size;
+	  sym.st_shndx = s->shndx; /* Already mapped to output index.  */
+	  sym.st_info = s->info.info;
+	  sym.st_other = s->info.other;
+
+	  /* Keep track of the number of leading local symbols.  */
+	  if (GELF_ST_BIND (sym.st_info) == STB_LOCAL)
+	    {
+	      assert (shdr->sh_info == 1 + i);
+	      shdr->sh_info = 1 + i + 1;
+	    }
+
+	  ELF_CHECK (gelf_update_symshndx (symdata, shndxdata, 1 + i,
+					   &sym, SHN_UNDEF),
+		     _("cannot update symbol table: %s"));
+
+	}
+      elf_flagdata (symdata, ELF_C_SET, ELF_F_DIRTY);
+      update_shdr (unstripped_symtab, shdr);
+
+      if (stripped_symtab != NULL)
+	{
+	  /* Adjust any relocations referring to the old symbol table.  */
+	  const size_t old_sh_link = elf_ndxscn (stripped_symtab->scn);
+	  for (const struct section *sec = sections;
+	       sec < &sections[stripped_shnum - 1];
+	       ++sec)
+	    if (sec->outscn != NULL && sec->shdr.sh_link == old_sh_link)
+	      adjust_relocs (sec->outscn, sec->scn, &sec->shdr,
+			     symndx_map, shdr);
+	}
+
+      /* Also adjust references to the other old symbol table.  */
+      adjust_all_relocs (unstripped, unstripped_symtab, shdr,
+			 &symndx_map[stripped_nsym - 1]);
+    }
+  else if (stripped_symtab != NULL && stripped_shnum != unstripped_shnum)
+    check_symtab_section_symbols (unstripped,
+				  stripped_ehdr->e_type == ET_REL,
+				  stripped_symtab->scn,
+				  unstripped_shnum, unstripped_shstrndx,
+				  stripped_symtab->outscn,
+				  stripped_shnum, stripped_shstrndx,
+				  debuglink);
+
+  if (stripped_dynsym != NULL)
+    (void) check_symtab_section_symbols (unstripped,
+					 stripped_ehdr->e_type == ET_REL,
+					 stripped_dynsym->outscn,
+					 unstripped_shnum,
+					 unstripped_shstrndx,
+					 stripped_dynsym->scn, stripped_shnum,
+					 stripped_shstrndx, debuglink);
+
+  /* We need to preserve the layout of the stripped file so the
+     phdrs will match up.  This requires us to do our own layout of
+     the added sections.  We do manual layout even for ET_REL just
+     so we can try to match what the original probably had.  */
+
+  elf_flagelf (unstripped, ELF_C_SET, ELF_F_LAYOUT);
+
+  if (offset == 0)
+    /* For ET_REL we are starting the layout from scratch.  */
+    offset = gelf_fsize (unstripped, ELF_T_EHDR, 1, EV_CURRENT);
+
+  bool skip_reloc = false;
+  do
+    {
+      skip_reloc = !skip_reloc;
+      for (size_t i = 0; i < unstripped_shnum - 1; ++i)
+	if (!placed[i])
+	  {
+	    scn = elf_getscn (unstripped, 1 + i);
+
+	    GElf_Shdr shdr_mem;
+	    GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	    ELF_CHECK (shdr != NULL, _("cannot get section header: %s"));
+
+	    /* We must make sure we have read in the data of all sections
+	       beforehand and marked them to be written out.  When we're
+	       modifying the existing file in place, we might overwrite
+	       this part of the file before we get to handling the section.  */
+
+	    ELF_CHECK (elf_flagdata (elf_getdata (scn, NULL),
+				     ELF_C_SET, ELF_F_DIRTY),
+		       _("cannot read section data: %s"));
+
+	    if (skip_reloc
+		&& (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA))
+	      continue;
+
+	    GElf_Off align = shdr->sh_addralign ?: 1;
+	    offset = (offset + align - 1) & -align;
+	    shdr->sh_offset = offset;
+	    if (shdr->sh_type != SHT_NOBITS)
+	      offset += shdr->sh_size;
+
+	    update_shdr (scn, shdr);
+
+	    if (unstripped_shstrndx == 1 + i)
+	      {
+		/* Place the section headers immediately after
+		   .shstrtab, and update the ELF header.  */
+
+		GElf_Ehdr ehdr_mem;
+		GElf_Ehdr *ehdr = gelf_getehdr (unstripped, &ehdr_mem);
+		ELF_CHECK (ehdr != NULL, _("cannot get ELF header: %s"));
+
+		GElf_Off sh_align = gelf_getclass (unstripped) * 4;
+		offset = (offset + sh_align - 1) & -sh_align;
+		ehdr->e_shnum = unstripped_shnum;
+		ehdr->e_shoff = offset;
+		offset += unstripped_shnum * ehdr->e_shentsize;
+		ELF_CHECK (gelf_update_ehdr (unstripped, ehdr),
+			   _("cannot update ELF header: %s"));
+	      }
+
+	    placed[i] = true;
+	  }
+    }
+  while (skip_reloc);
+
+  size_t phnum;
+  ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0,
+	     _("cannot get number of program headers: %s"));
+
+  if (phnum > 0)
+    ELF_CHECK (gelf_newphdr (unstripped, phnum),
+	       _("cannot create program headers: %s"));
+
+  /* Copy each program header from the stripped file.  */
+  for (size_t i = 0; i < phnum; ++i)
+    {
+      GElf_Phdr phdr_mem;
+      GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem);
+      ELF_CHECK (phdr != NULL, _("cannot get program header: %s"));
+
+      ELF_CHECK (gelf_update_phdr (unstripped, i, phdr),
+		 _("cannot update program header: %s"));
+    }
+
+  /* Finally, write out the file.  */
+  ELF_CHECK (elf_update (unstripped, ELF_C_WRITE) > 0,
+	     _("cannot write output file: %s"));
+
+  if (strtab != NULL)
+    {
+      dwelf_strtab_free (strtab);
+      free (strtab_data->d_buf);
+    }
+
+  if (symstrtab != NULL)
+    {
+      dwelf_strtab_free (symstrtab);
+      free (symstrdata->d_buf);
+    }
+  free_new_data ();
+}
+
+/* Process one pair of files, already opened.  */
+static void
+handle_file (const char *output_file, bool create_dirs,
+	     Elf *stripped, const GElf_Ehdr *stripped_ehdr,
+	     Elf *unstripped)
+{
+  size_t phnum;
+  ELF_CHECK (elf_getphdrnum (stripped, &phnum) == 0,
+	     _("cannot get number of program headers: %s"));
+
+  /* Determine the address bias between the debuginfo file and the main
+     file, which may have been modified by prelinking.  */
+  GElf_Addr bias = 0;
+  if (unstripped != NULL)
+    for (size_t i = 0; i < phnum; ++i)
+      {
+	GElf_Phdr phdr_mem;
+	GElf_Phdr *phdr = gelf_getphdr (stripped, i, &phdr_mem);
+	ELF_CHECK (phdr != NULL, _("cannot get program header: %s"));
+	if (phdr->p_type == PT_LOAD)
+	  {
+	    GElf_Phdr unstripped_phdr_mem;
+	    GElf_Phdr *unstripped_phdr = gelf_getphdr (unstripped, i,
+						       &unstripped_phdr_mem);
+	    ELF_CHECK (unstripped_phdr != NULL,
+		       _("cannot get program header: %s"));
+	    bias = phdr->p_vaddr - unstripped_phdr->p_vaddr;
+	    break;
+	  }
+      }
+
+  /* One day we could adjust all the DWARF data (like prelink itself does).  */
+  if (bias != 0)
+    {
+      if (output_file == NULL)
+	error (0, 0, _("\
+DWARF data not adjusted for prelinking bias; consider prelink -u"));
+      else
+	error (0, 0, _("\
+DWARF data in '%s' not adjusted for prelinking bias; consider prelink -u"),
+	       output_file);
+    }
+
+  if (output_file == NULL)
+    /* Modify the unstripped file in place.  */
+    copy_elided_sections (unstripped, stripped, stripped_ehdr, bias);
+  else
+    {
+      if (create_dirs)
+	make_directories (output_file);
+
+      /* Copy the unstripped file and then modify it.  */
+      int outfd = open (output_file, O_RDWR | O_CREAT,
+			  stripped_ehdr->e_type == ET_REL ? 0666 : 0777);
+      if (outfd < 0)
+	error (EXIT_FAILURE, errno, _("cannot open '%s'"), output_file);
+      Elf *outelf = elf_begin (outfd, ELF_C_WRITE, NULL);
+      ELF_CHECK (outelf != NULL, _("cannot create ELF descriptor: %s"));
+
+      if (unstripped == NULL)
+	{
+	  /* Actually, we are just copying out the main file as it is.  */
+	  copy_elf (outelf, stripped);
+	  if (stripped_ehdr->e_type != ET_REL)
+	    elf_flagelf (outelf, ELF_C_SET, ELF_F_LAYOUT);
+	  ELF_CHECK (elf_update (outelf, ELF_C_WRITE) > 0,
+		     _("cannot write output file: %s"));
+	}
+      else
+	{
+	  copy_elf (outelf, unstripped);
+	  copy_elided_sections (outelf, stripped, stripped_ehdr, bias);
+	}
+
+      elf_end (outelf);
+      close (outfd);
+    }
+}
+
+static int
+open_file (const char *file, bool writable)
+{
+  int fd = open (file, writable ? O_RDWR : O_RDONLY);
+  if (fd < 0)
+    error (EXIT_FAILURE, errno, _("cannot open '%s'"), file);
+  return fd;
+}
+
+/* Handle a pair of files we need to open by name.  */
+static void
+handle_explicit_files (const char *output_file, bool create_dirs, bool force,
+		       const char *stripped_file, const char *unstripped_file)
+{
+
+  /* Warn, and exit if not forced to continue, if some ELF header
+     sanity check for the stripped and unstripped files failed.  */
+  void warn (const char *msg)
+  {
+    error (force ? 0 : EXIT_FAILURE, 0, "%s'%s' and '%s' %s%s.",
+	   force ? _("WARNING: ") : "",
+	   stripped_file, unstripped_file, msg,
+	   force ? "" : _(", use --force"));
+  }
+
+  int stripped_fd = open_file (stripped_file, false);
+  Elf *stripped = elf_begin (stripped_fd, ELF_C_READ, NULL);
+  GElf_Ehdr stripped_ehdr;
+  ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr),
+	     _("cannot create ELF descriptor: %s"));
+
+  int unstripped_fd = -1;
+  Elf *unstripped = NULL;
+  if (unstripped_file != NULL)
+    {
+      unstripped_fd = open_file (unstripped_file, output_file == NULL);
+      unstripped = elf_begin (unstripped_fd,
+			      (output_file == NULL ? ELF_C_RDWR : ELF_C_READ),
+			      NULL);
+      GElf_Ehdr unstripped_ehdr;
+      ELF_CHECK (gelf_getehdr (unstripped, &unstripped_ehdr),
+		 _("cannot create ELF descriptor: %s"));
+
+      if (memcmp (stripped_ehdr.e_ident,
+		  unstripped_ehdr.e_ident, EI_NIDENT) != 0)
+	warn (_("ELF header identification (e_ident) different"));
+
+      if (stripped_ehdr.e_type != unstripped_ehdr.e_type)
+	warn (_("ELF header type (e_type) different"));
+
+      if (stripped_ehdr.e_machine != unstripped_ehdr.e_machine)
+	warn (_("ELF header machine type (e_machine) different"));
+
+      if (stripped_ehdr.e_phnum < unstripped_ehdr.e_phnum)
+	warn (_("stripped program header (e_phnum) smaller than unstripped"));
+    }
+
+  handle_file (output_file, create_dirs, stripped, &stripped_ehdr, unstripped);
+
+  elf_end (stripped);
+  close (stripped_fd);
+
+  elf_end (unstripped);
+  close (unstripped_fd);
+}
+
+
+/* Handle a pair of files opened implicitly by libdwfl for one module.  */
+static void
+handle_dwfl_module (const char *output_file, bool create_dirs, bool force,
+		    Dwfl_Module *mod, bool all, bool ignore, bool relocate)
+{
+  GElf_Addr bias;
+  Elf *stripped = dwfl_module_getelf (mod, &bias);
+  if (stripped == NULL)
+    {
+      if (ignore)
+	return;
+
+      const char *file;
+      const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
+					      NULL, NULL, &file, NULL);
+      if (file == NULL)
+	error (EXIT_FAILURE, 0,
+	       _("cannot find stripped file for module '%s': %s"),
+	       modname, dwfl_errmsg (-1));
+      else
+	error (EXIT_FAILURE, 0,
+	       _("cannot open stripped file '%s' for module '%s': %s"),
+	       modname, file, dwfl_errmsg (-1));
+    }
+
+  Elf *debug = dwarf_getelf (dwfl_module_getdwarf (mod, &bias));
+  if (debug == NULL && !all)
+    {
+      if (ignore)
+	return;
+
+      const char *file;
+      const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
+					      NULL, NULL, NULL, &file);
+      if (file == NULL)
+	error (EXIT_FAILURE, 0,
+	       _("cannot find debug file for module '%s': %s"),
+	       modname, dwfl_errmsg (-1));
+      else
+	error (EXIT_FAILURE, 0,
+	       _("cannot open debug file '%s' for module '%s': %s"),
+	       modname, file, dwfl_errmsg (-1));
+    }
+
+  if (debug == stripped)
+    {
+      if (all)
+	debug = NULL;
+      else
+	{
+	  const char *file;
+	  const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
+						  NULL, NULL, &file, NULL);
+	  error (EXIT_FAILURE, 0, _("module '%s' file '%s' is not stripped"),
+		 modname, file);
+	}
+    }
+
+  GElf_Ehdr stripped_ehdr;
+  ELF_CHECK (gelf_getehdr (stripped, &stripped_ehdr),
+	     _("cannot create ELF descriptor: %s"));
+
+  if (stripped_ehdr.e_type == ET_REL)
+    {
+      if (!relocate)
+	{
+	  /* We can't use the Elf handles already open,
+	     because the DWARF sections have been relocated.  */
+
+	  const char *stripped_file = NULL;
+	  const char *unstripped_file = NULL;
+	  (void) dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL,
+				   &stripped_file, &unstripped_file);
+
+	  handle_explicit_files (output_file, create_dirs, force,
+				 stripped_file, unstripped_file);
+	  return;
+	}
+
+      /* Relocation is what we want!  This ensures that all sections that can
+	 get sh_addr values assigned have them, even ones not used in DWARF.
+	 They might still be used in the symbol table.  */
+      if (dwfl_module_relocations (mod) < 0)
+	error (EXIT_FAILURE, 0,
+	       _("cannot cache section addresses for module '%s': %s"),
+	       dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	       dwfl_errmsg (-1));
+    }
+
+  handle_file (output_file, create_dirs, stripped, &stripped_ehdr, debug);
+}
+
+/* Handle one module being written to the output directory.  */
+static void
+handle_output_dir_module (const char *output_dir, Dwfl_Module *mod, bool force,
+			  bool all, bool ignore, bool modnames, bool relocate)
+{
+  if (! modnames)
+    {
+      /* Make sure we've searched for the ELF file.  */
+      GElf_Addr bias;
+      (void) dwfl_module_getelf (mod, &bias);
+    }
+
+  const char *file;
+  const char *name = dwfl_module_info (mod, NULL, NULL, NULL,
+				       NULL, NULL, &file, NULL);
+
+  if (file == NULL && ignore)
+    return;
+
+  char *output_file;
+  if (asprintf (&output_file, "%s/%s", output_dir, modnames ? name : file) < 0)
+    error (EXIT_FAILURE, 0, _("memory exhausted"));
+
+  handle_dwfl_module (output_file, true, force, mod, all, ignore, relocate);
+}
+
+
+static void
+list_module (Dwfl_Module *mod)
+{
+  /* Make sure we have searched for the files.  */
+  GElf_Addr bias;
+  bool have_elf = dwfl_module_getelf (mod, &bias) != NULL;
+  bool have_dwarf = dwfl_module_getdwarf (mod, &bias) != NULL;
+
+  const char *file;
+  const char *debug;
+  Dwarf_Addr start;
+  Dwarf_Addr end;
+  const char *name = dwfl_module_info (mod, NULL, &start, &end,
+				       NULL, NULL, &file, &debug);
+  if (file != NULL && debug != NULL && (debug == file || !strcmp (debug, file)))
+    debug = ".";
+
+  const unsigned char *id;
+  GElf_Addr id_vaddr;
+  int id_len = dwfl_module_build_id (mod, &id, &id_vaddr);
+
+  printf ("%#" PRIx64 "+%#" PRIx64 " ", start, end - start);
+
+  if (id_len > 0)
+    {
+      do
+	printf ("%02" PRIx8, *id++);
+      while (--id_len > 0);
+      if (id_vaddr != 0)
+	printf ("@%#" PRIx64, id_vaddr);
+    }
+  else
+    putchar ('-');
+
+  printf (" %s %s %s\n",
+	  file ?: have_elf ? "." : "-",
+	  debug ?: have_dwarf ? "." : "-",
+	  name);
+}
+
+
+struct match_module_info
+{
+  char **patterns;
+  Dwfl_Module *found;
+  bool match_files;
+};
+
+static int
+match_module (Dwfl_Module *mod,
+	      void **userdata __attribute__ ((unused)),
+	      const char *name,
+	      Dwarf_Addr start __attribute__ ((unused)),
+	      void *arg)
+{
+  struct match_module_info *info = arg;
+
+  if (info->patterns[0] == NULL) /* Match all.  */
+    {
+    match:
+      info->found = mod;
+      return DWARF_CB_ABORT;
+    }
+
+  if (info->match_files)
+    {
+      /* Make sure we've searched for the ELF file.  */
+      GElf_Addr bias;
+      (void) dwfl_module_getelf (mod, &bias);
+
+      const char *file;
+      const char *check = dwfl_module_info (mod, NULL, NULL, NULL,
+					    NULL, NULL, &file, NULL);
+      assert (check == name);
+      if (file == NULL)
+	return DWARF_CB_OK;
+
+      name = file;
+    }
+
+  for (char **p = info->patterns; *p != NULL; ++p)
+    if (fnmatch (*p, name, 0) == 0)
+      goto match;
+
+  return DWARF_CB_OK;
+}
+
+/* Handle files opened implicitly via libdwfl.  */
+static void
+handle_implicit_modules (const struct arg_info *info)
+{
+  struct match_module_info mmi = { info->args, NULL, info->match_files };
+  inline ptrdiff_t next (ptrdiff_t offset)
+    {
+      return dwfl_getmodules (info->dwfl, &match_module, &mmi, offset);
+    }
+  ptrdiff_t offset = next (0);
+  if (offset == 0)
+    error (EXIT_FAILURE, 0, _("no matching modules found"));
+
+  if (info->list)
+    do
+      list_module (mmi.found);
+    while ((offset = next (offset)) > 0);
+  else if (info->output_dir == NULL)
+    {
+      if (next (offset) != 0)
+	error (EXIT_FAILURE, 0, _("matched more than one module"));
+      handle_dwfl_module (info->output_file, false, info->force, mmi.found,
+			  info->all, info->ignore, info->relocate);
+    }
+  else
+    do
+      handle_output_dir_module (info->output_dir, mmi.found, info->force,
+				info->all, info->ignore,
+				info->modnames, info->relocate);
+    while ((offset = next (offset)) > 0);
+}
+
+int
+main (int argc, char **argv)
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+  __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  setlocale (LC_ALL, "");
+
+  /* Make sure the message catalog can be found.  */
+  bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
+
+  /* Initialize the message catalog.  */
+  textdomain (PACKAGE_TARNAME);
+
+  /* Parse and process arguments.  */
+  const struct argp_child argp_children[] =
+    {
+      {
+	.argp = dwfl_standard_argp (),
+	.header = N_("Input selection options:"),
+	.group = 1,
+      },
+      { .argp = NULL },
+    };
+  const struct argp argp =
+    {
+      .options = options,
+      .parser = parse_opt,
+      .children = argp_children,
+      .args_doc = N_("STRIPPED-FILE DEBUG-FILE\n[MODULE...]"),
+      .doc = N_("\
+Combine stripped files with separate symbols and debug information.\n\
+\n\
+The first form puts the result in DEBUG-FILE if -o was not given.\n\
+\n\
+MODULE arguments give file name patterns matching modules to process.\n\
+With -f these match the file name of the main (stripped) file \
+(slashes are never special), otherwise they match the simple module names.  \
+With no arguments, process all modules found.\n\
+\n\
+Multiple modules are written to files under OUTPUT-DIRECTORY, \
+creating subdirectories as needed.  \
+With -m these files have simple module names, otherwise they have the \
+name of the main file complete with directory underneath OUTPUT-DIRECTORY.\n\
+\n\
+With -n no files are written, but one line to standard output for each module:\
+\n\tSTART+SIZE BUILDID FILE DEBUGFILE MODULENAME\n\
+START and SIZE are hexadecimal giving the address bounds of the module.  \
+BUILDID is hexadecimal for the build ID bits, or - if no ID is known; \
+the hexadecimal may be followed by @0xADDR giving the address where the \
+ID resides if that is known.  \
+FILE is the file name found for the module, or - if none was found, \
+or . if an ELF image is available but not from any named file.  \
+DEBUGFILE is the separate debuginfo file name, \
+or - if no debuginfo was found, or . if FILE contains the debug information.\
+")
+    };
+
+  int remaining;
+  struct arg_info info = { .args = NULL };
+  error_t result = argp_parse (&argp, argc, argv, 0, &remaining, &info);
+  if (result == ENOSYS)
+    assert (info.dwfl == NULL);
+  else if (result)
+    return EXIT_FAILURE;
+  assert (info.args != NULL);
+
+  /* Tell the library which version we are expecting.  */
+  elf_version (EV_CURRENT);
+
+  if (info.dwfl == NULL)
+    {
+      assert (result == ENOSYS);
+
+      if (info.output_dir != NULL)
+	{
+	  char *file;
+	  if (asprintf (&file, "%s/%s", info.output_dir, info.args[0]) < 0)
+	    error (EXIT_FAILURE, 0, _("memory exhausted"));
+	  handle_explicit_files (file, true, info.force,
+				 info.args[0], info.args[1]);
+	  free (file);
+	}
+      else
+	handle_explicit_files (info.output_file, false, info.force,
+			       info.args[0], info.args[1]);
+    }
+  else
+    {
+      /* parse_opt checked this.  */
+      assert (info.output_file != NULL || info.output_dir != NULL || info.list);
+
+      handle_implicit_modules (&info);
+
+      dwfl_end (info.dwfl);
+    }
+
+  return 0;
+}
+
+
+#include "debugpred.h"
diff --git a/third_party/elfutils/tests/ChangeLog b/third_party/elfutils/tests/ChangeLog
new file mode 100644
index 0000000..5ee8626
--- /dev/null
+++ b/third_party/elfutils/tests/ChangeLog
@@ -0,0 +1,2978 @@
+2018-02-09  Joshua Watt  <JPEWhacker@gmail.com>
+
+	* elfstrmerge.c (main): Use FALLTHROUGH macro instead of comment.
+
+2018-01-22  Mark Wielaard  <mark@klomp.org>
+
+	* allfcts.c (setup_alt): Print warning when alt file couldn't be
+	found.
+	* run-allfcts-multi.sh: Add testcase where alt file is in a subdir
+	where it cannot be found by allfcts itself (but it can by libdw).
+
+2018-01-25  Mark Wielaard  <mark@klomp.org>
+
+	* elfstrmerge.c (main): Initialize and check symtabshdr instead of
+	symtabndx.
+
+2018-01-14  Petr Machata  <pmachata@gmail.com>
+
+	* testfile-sizes4.o.bz2: New test file.
+	* testfile-sizes4.s: New test source.
+	* run-aggregate-size.sh: Check testfile-sizes4.o v size 257.
+
+2017-12-23  Mark Wielaard  <mark@klomp.org>
+
+	* backtrace-subr.sh (check_native_core): Use a lock file and try
+	to extract core using coredumpctl.
+	* Makefile.am (CLEANFILES): Clean core-dump-backtrace.lock.
+
+2017-12-11  Dima Kogan  <dima@secretsauce.net>
+
+	* run-aggregate-size.sh: Added check for multi-dimensional arrays.
+	* run-peel-type.sh: Likewise.
+	* testfile-sizes3.o.bz2: Likewise.
+
+2017-12-07  Mark Wielaard  <mark@klomp.org>
+
+	* run-readelf-variant.sh: New test.
+	* testfile-ada-variant.bz2: New testfile.
+	* Makefile.am (TESTS): Add run-readelf-variant.sh.
+	(EXTRA_DISTS): Add run-readelf-variant.sh and
+	testfile-ada-variant.bz2.
+
+2017-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* run-readelf-loc.sh: Adjust expected loc list output.
+	* run-readelf-zdebug-rel.sh: Likewise.
+	* run-readelf-zdebug.sh: Likewise.
+
+2017-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* run-readelf-loc.sh: Adjust expected range list output.
+	* run-readelf-zdebug.sh: Likewise.
+
+2017-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* run-readelf-dwz-multi.sh: Add expected file names.
+	* run-readelf-zdebug-rel.sh: Likewise.
+
+2017-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* run-readelf-dwz-multi.sh: Add expected abbrev codes.
+	* run-readelf-zdebug-rel.sh: Likewise.
+
+2017-11-29  Mark Wielaard  <mark@klomp.org>
+
+	* run-readelf-dwz-multi.sh: Adjust expected ops index spaces.
+	* run-readelf-loc.sh: Likewise.
+	* run-readelf-zdebug-rel.sh: Likewise.
+	* run-readelf-zdebug.sh: Likewise.
+
+2017-11-16  Mark Wielaard  <mark@klomp.org>
+
+	* varlocs.c (main): Fix cfi_debug => cfi_debug_bias typo in assert.
+
+2017-11-10  Mark Wielaard  <mark@klomp.org>
+
+	* run-exprlocs-self.sh: New test.
+	* run-varlocs-self.sh: Likewise.
+	* Makefile.am (TESTS) Add run-exprlocs-self.sh and
+	run-varlocs-self.sh.
+	(EXTRA_DIST): Likewise.
+	* varlocs.c (cfi_debug_bias): New global variable.
+	(is_ET_REL): Likewise.
+	(print_expr): Don't crash and burn when CFI cannot be found for an
+	ET_REL file for DW_OP_call_frame_cfa.
+	(handle_die): If there is no entry_pc pick the lowest pc start range
+	for the DIE.
+	(main): Check at least one CU was found. Use dwfl_module_dwarf_cfi
+	and dwfl_module_eh_cfi to fix memory leak. Set is_ET_REL.
+
+2017-11-03  Mark Wielaard  <mark@klomp.org>
+
+	* run-exprlocs.sh: New test.
+	* testfile-stridex.bz2: New testfile.
+	* Makefile.am (TESTS): Add run-exprlocs.sh.
+	(EXTRA_DIST): Add run-exprlocs.sh and testfile-stridex.bz2.
+	* varlocs.c (dwarf_tag_string): New function.
+	(dwarf_attr_string): Likewise.
+	(dwarf_form_string): Likewise.
+	(print_expr): Fix typo in error message.r
+	Handle DW_OP_GNU_variable_value.
+	(attr_arg): New struct.
+	(handle_attr): New function.
+	(handle_die): Likewise.
+	(main): Handle --exprlocs argument. Call handle_die.
+
+2017-10-16  Mark Wielaard  <mark@klomp.org>
+
+	* md5-sha1-test.c: Removed.
+	* Makefile.am (check_PROGRAMS): Remove md5-sha1-test.
+	(TESTS): Likewise.
+	(md5_sha1_test_LDADD): Removed.
+
+2017-10-04  Mark Wielaard  <mark@klomp.org>
+
+	* msg_tst.c: Handle ELF_E_INVALID_ELF.
+
+2017-09-10  Mark Wielaard  <mark@klomp.org>
+
+	* run-ar.sh: New test.
+	* Makefile.am (TESTS): Add run-ar.sh.
+	(EXTRA_DIST): Likewise.
+
+2017-08-18  Ulf Hermann <ulf.hermann@qt.io>
+
+	* Makefile.am: Drop -rdynamic from deleted_lib_so_LDFLAGS.
+
+2017-04-27  Ulf Hermann <ulf.hermann@qt.io>
+
+	* Makefile.am: Use fpie_CFLAGS and fpic_CFLAGS.
+
+2017-08-08  Dmitry V. Levin <ldv@altlinux.org>
+
+	* run-strip-nothing.sh: Add -s.
+
+2017-07-26  Mark Wielaard  <mark@klomp.org>
+
+	* dwarf-getmacros.c (mac): Use DW_MACRO names instead of DW_MACRO_GNU.
+
+2016-10-27  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_default_lower_bound.c: New test.
+	* Makefile.am (check_PROGRAMS): Add dwarf_default_lower_bound.
+	(TESTS): Likewise.
+	(dwarf_default_lower_bound_LDADD): New variable.
+
+2017-07-21  Mark Wielaard  <mark@klomp.org>
+
+	* get-lines.c (main): Add dwarf_line_file test.
+
+2017-07-19  Gustavo Romero <gromero@linux.vnet.ibm.com>
+
+	* run-addrcfi.sh: Update generic SPRs names to HTM SPRs names
+	* run-allregs.sh: Update generic SPRs names to HTM SPRs names
+
+2017-07-20  Mark Wielaard  <mark@klomp.org>
+
+	* run-strip-g.sh: New test.
+	* Makefile.am (TESTS): Add run-strip-g.sh.
+	(EXTRA_DIST): Likewise.
+
+2017-07-18  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am (TESTS): Always add run-disasm-bpf.sh if HAVE_LIBASM.
+
+2017-05-04  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* elfshphehdr.c: For writing, use /dev/null rather than /dev/zero.
+
+2017-07-14  Mark Wielaard  <mark@klomp.org>
+
+	* run-strip-remove-keep.sh: New test.
+	* Makefile.am (TESTS): Add run-strip-remove-keep.sh.
+	(EXTRA_DIST): Likewise.
+
+2017-06-07  Mark Wielaard  <mark@klomp.org>
+
+	* run-strip-nothing.sh: New test.
+	* Makefile.am (TESTS): Add run-strip-nothing.sh.
+	(EXTRA_DIST): Likewise.
+
+2017-06-06  Mark Wielaard  <mark@klomp.org>
+
+	* run-strip-test.sh: Test strip -g doesn't introduce extra .shstrtab.
+
+2017-05-30  Mark Wielaard  <mark@klomp.org>
+
+	* run-backtrace-fp-core-ppc64le.sh: New test.
+	* backtrace.ppc64le.fp.core.bz2: New test file.
+	* backtrace.ppc64le.fp.exec.bz2: New testfile.
+	* backtrace-subr.sh (check_backtracegen): Accept '(null)'.
+	* Makefile.am (TESTS): Add run-backtrace-fp-core-ppc64le.sh.
+	(EXTRA_DIST): Add run-backtrace-fp-core-ppc64le.sh,
+	backtrace.ppc64le.fp.core.bz2 and backtrace.ppc64le.fp.exec.bz2.
+
+2017-02-13  Ulf Hermann  <ulf.hermann@qt.io>
+	    Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am: Add test for unwinding with frame pointers on aarch64
+	* backtrace.aarch64.fp.core.bz2: New file
+	* backtrace.aarch64.fp.exec.bz2: New file
+	* run-backtrace-fp-core-aarch64.sh: New file
+	* backtrace-subr.sh (check_err): Allow Invalid register.
+	* backtrace.c (callback_verify): Allow duplicate_sigusr2 frames.
+
+2017-04-06  Mark Wielaard  <mark@klomp.org>
+
+	* run-backtrace-fp-core-i386.sh: New test.
+	* backtrace.i386.fp.core.bz2: New test file.
+	* backtrace.i386.fp.exec.bz2: New testfile.
+	* Makefile.am (TESTS): Add run-backtrace-fp-core-i386.sh.
+	(EXTRA_DIST): Add run-backtrace-fp-core-i386.sh,
+	backtrace.i386.fp.core.bz2 and backtrace.i386.fp.exec.bz2.
+
+2017-02-09  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* Makefile.am: Add test for unwinding with frame pointers on x86_64
+	* backtrace.x86_64.fp.core.bz2: New file
+	* backtrace.x86_64.fp.exec.bz2: New file
+	* run-backtrace-fp-core-x86_64.sh: New file
+
+2017-04-25  Mark Wielaard  <mark@klomp.org>
+
+	* backtrace-subr.sh (check_backtracegen): New function.
+	(check_core): Add check_backtracegen call.
+	* backtrace.ppc.exec.bz2: Regenerated.
+	* backtrace.ppc.core.bz2: Likewise.
+
+2017-04-24  Mark Wielaard  <mark@klomp.org>
+
+	* backtrace.c: Remove option to allow unknown symbols in the trace.
+	* backtrace-substr.sh: Remove option to allow unknown symbols
+	to check_core() and allow failed symbol lookups in check_err().
+
+2017-04-20  Ulf Hermann <ulf.hermann@qt.io>
+
+	* run-readelf-dwz-multi.sh: Expect readelf to output "yes" for flags
+	that are set.
+	* run-readelf-zdebug-rel.sh: Likewise.
+
+2017-04-20  Ulf Hermann <ulf.hermann@qt.io>
+
+	* backtrace-child.c: Include sys/ptrace.h only on linux.
+	* backtrace-dwarf.c: Likewise.
+
+2017-04-05  Mark Wielaard  <mark@klomp.org>
+
+	* test-subr.sh (testrun_on_self_compressed): New function.
+	* run-elflint-self.sh: Call testrun_on_self_compressed.
+	* run-elflint-test.sh: Add testfile42z and testfile-s390x-hash-bothz.
+
+2017-03-30  Mark Wielaard  <mark@klomp.org>
+
+	* peel_type.c: New file.
+	* run-peel-type.sh: New test.
+	* Makefile.am (check_PROGRAMS): Add peel_type.c.
+	(TESTS): Add run-peel-type.sh.
+	(EXTRA_DIST): Likewise.
+	(peel_type_LDADD): New variable.
+
+2017-03-27  Mark Wielaard  <mark@klomp.org>
+
+	* fillfile.c: New file.
+	* Makefile.am (check_PROGRAMS): Add fillfile.
+	(TESTS): Likewise.
+	(fillfile_LDADD): New variable.
+
+2017-02-15  Mark Wielaard  <mark@klomp.org>
+
+	* Makefile.am (EXTRA_DIST): Add testfileppc64attrs.o.bz2.
+	* run-readelf-A.sh: Add testfileppc64.o test.
+
+2017-02-15  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* elfstrmerge.c: Include system.h.
+
+2017-02-09  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* backtrace.c: Add an option to allow unknown symbols in the trace
+	* backtrace-substr.sh: Add an option to allow unknown symbols
+	to check_core() and allow failed symbol lookups in check_err()
+
+2017-02-09  Ulf Hermann  <ulf.hermann@qt.io>
+
+	* backtrace-data.c: Don't assert that symbols are found.
+	The unwinder is allowed to ask for invalid addresses. We deny
+	such requests, rather than make the test fail.
+
+2016-11-17  Mark Wielaard  <mjw@redhat.com>
+
+	* run-readelf-s.sh: Add --symbols=.dynsym and --symbols=.symtab tests.
+
+2016-11-02  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace-data.c (thread_callback): Add explicit break after error.
+	* backtrace.c (callback_verify): Change PASSTHRU to FALLTHRU.
+
+2016-10-22  Kevin Cernekee  <cernekee@chromium.org>
+
+	* Makefile.am (TESTS): Add run-unstrip-test4.sh.
+	(EXTRA_DIST): Add run-unstrip-test4.sh, testfile-strtab.bz2,
+	testfile-strtab.stripped.bz2, testfile-strtab.debuginfo.bz2.
+	(run-unstrip-test4.sh): New file.
+	(testfile-strtab.bz2): New file.
+	(testfile-strtab.stripped.bz2): New file.
+	(testfile-strtab.debuginfo.bz2): New file.
+
+2016-10-11  Akihiko Odaki  <akihiko.odaki.4i@stu.hosei.ac.jp>
+
+	* arextract.c: Remove sys/param.h include, add system.h include.
+
+2016-08-30  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (asm_tst?_LDADD): Add libdw.
+
+2016-08-25  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace-child.c: Disable and add documentation about why we disable
+	RAISE_JMP_PATCHING even on x86_64.
+	* backtrace.c (is_x86_64_native): Rename to...
+	(use_raise_jmp_patching): ... this.
+	(callback_verify): Use use_raise_jmp_patching instead of
+	is_x86_64_native.
+	(see_exec_module): Return DWARF_CB_ABORT after finding the correct exe
+	path.
+	(prepare_thread): Use RAISE_JMP_PATCHING instead of __x86_64__
+	conditional.
+	(exec_dump): Only assert on data.mod != NULL. Drop ptrdiff. Use
+	RAISE_JMP_PATCHING instead of __x86_64__ conditional. Use
+	use_raise_jmp_patching instead of is_x86_64_native.
+
+2016-08-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add testfilesparc64attrs.o.bz2.
+
+2016-08-09  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* testfilesparc64attrs.o.bz2: New file.
+	* run-readelf-A.sh: Check attributes in a sparc object.
+
+2016-08-06  Mark Wielaard  <mjw@redhat.com>
+
+	* run-strip-reloc.sh: Add explicit compressed and uncompressed
+	test cases.
+
+2016-08-10  Richard Henderson  <rth@redhat.com>
+
+	* file-bpf-dis1.expect.bz2: Fix expected mod and endian operations
+	output.
+
+2016-07-08  Mark Wielaard  <mjw@redhat.com>
+
+	* update3_LDADD: Use libdw instead of libebl.
+	* update4_LDADD: Likewise.
+	* alldts_LDADD: Likewise.
+	* elfstrmerge_LDADD: Likewise.
+	* alldts.c (main): Use dwelf_strtab instead of ebl_strtab.
+	* elfstrmerge.c (release): Likewise.
+	(main): Likewise.
+	* update3.c (main): Likewise.
+	* update4.c (main): Likewise.
+
+2016-07-10  Andreas Schwab  <schwab@linux-m68k.org>
+
+	* Makefile.am (TESTS): Add run-strip-test11.sh.
+	(EXTRA_DIST): Add run-strip-test11.sh, hello_m68k.ko.bz2,
+	testfile-m86k-core.bz2, testfile-m68k.bz2, testfile-m68k-s.bz2.
+	(run-strip-test11.sh): New file.
+	(hello_m68k.ko.bz2): New file.
+	(testfile-m68k-core.bz2): New file.
+	(testfile-m68k.bz2): New file.
+	(testfile-m68k-s.bz2): New file.
+	* run-allregs.sh: Add test for testfile-m68k-core.
+	* run-readelf-mixed-corenote.sh: Likewise.
+	* run-strip-reloc.sh: Add test for hello_m68k.ko.
+
+2016-07-06  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add vendorelf.
+	(TESTS): Likewise.
+	(vendorelf_LDADD): New variable.
+	* vendorelf.c: New test.
+	* elfshphehdr.c (test): Check elf_getphdrnum succeeds.
+
+2016-06-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add emptyfile.
+	(TESTS): Likewise.
+	(emptyfile_LDADD): New variable.
+	* emptyfile.c: New test.
+
+2016-06-28  Richard Henderson  <rth@redhat.com>
+
+	* Makefile.am (TESTS): Add run-disasm-bpf.sh, conditionally.
+	(EXTRA_DIST): Add run-disasm-bpf.sh, testfile-bpf-dis1.expect.bz2,
+	testfile-bpf-dis1.o.bz2
+	(run-disasm-bpf.sh): New file.
+	(testfile-bpf-dis1.expect.bz2): New file.
+	(testfile-bpf-dis1.o.bz2): New file.
+
+2016-02-09  Mark Wielaard  <mjw@redhat.com>
+
+	* testfile-s390x-hash-both.bz2: New testfile.
+	* Makefile.am (EXTRA_DIST): Add testfile-s390x-hash-both.bz2.
+	* run-elflint-test.sh: Add elflint testfile-s390x-hash-both test.
+
+2016-02-04  Mark Wielaard  <mjw@redhat.com>
+
+	* run-strip-nobitsalign.sh: New test.
+	* testfile-nobitsalign.bz2: New testfile.
+	* testfile-nobitsalign.strip.bz2: Likewise.
+	* Makefile.am (TESTS): Add run-strip-nobitsalign.sh.
+	(EXTRA_DIST): Add run-strip-nobitsalign.sh, testfile-nobitsalign.bz2
+	and testfile-nobitsalign.strip.bz2.
+	* run-strip-test.sh: Add --gnu to elflint calls.
+
+2016-01-13  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl-bug-fd-leak.c: Skip test unless on __linux__.
+
+2016-01-13  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl-proc-attach.c: Guard linux specific header.
+
+2016-01-13  Mark Wielaard  <mjw@redhat.com>
+
+	* system-elf-libelf-test.c: New test.
+	* Makefile.am (TESTS): Add system-elf-libelf-test, if !STANDALONE.
+	(check_PROGRAMS): Likewise.
+	(system_elf_libelf_test_CPPFLAGS): New variable.
+	(system_elf_libelf_test_LDADD): Likewise.
+
+2016-01-08  Mark Wielaard  <mjw@redhat.com>
+
+	* elfputzdata.c (main): Fix parentheses in strncmp test.
+
+2016-01-08  Mark Wielaard  <mjw@redhat.com>
+
+	* elfputzdata.c (main): Use PRId64 to print 64 bit value.
+
+2016-01-08  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): Always unconditionally add
+	run-readelf-zdebug.sh and run-readelf-zdebug-rel.sh.
+
+2015-12-16  Mark Wielaard  <mjw@redhat.com>
+
+	* run-compress-test.sh: New test.
+	* Makefile.am (TESTS): Add run-compress-test.sh.
+	(EXTRA_DISTS): Likewise.
+
+2015-11-26  Mark Wielaard  <mjw@redhat.com>
+
+	* zstrptr.c: New file.
+	* run-zstrptr.sh: New test.
+	* elfputzdata.c (main): (re)compress .shstrtab.
+	* run-elfputzdata.sh: Expect .shstrtab compression.
+	* Makefile.am (check_PROGRAMS): Add zstrptr.
+	(TESTS): Add run-zstrptr.sh.
+	(EXTRA_DIST): Likewise.
+	(zstrptr_LDADD): New variable.
+
+2015-10-20  Mark Wielaard  <mjw@redhat.com>
+
+	* run-readelf-zx.sh: New test.
+	* run-readelf-zp.sh: Likewise.
+	* Makefile.am (TESTS): Add run-readelf-zx.sh and run-readelf-zp.sh.
+	(EXTRA_DIST): Likewise.
+
+2015-10-21  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add elfgetzdata and elfputzdata.
+	(TESTS): Add run-elfgetzdata.sh and run-elfputzdata.sh.
+	(EXTRA_DIST: Likewise.
+	(elfgetzdata_LDADD): New variable.
+	(elfputzdata_LDADD): Likewise.
+	* elfgetzdata.c: New file.
+	* elfputzdata.c: Likewise.
+	* msg_tst.c: Handle ELF_E_ALREADY_COMPRESSED,
+	ELF_E_UNKNOWN_COMPRESSION_TYPE, ELF_E_COMPRESS_ERROR and
+	ELF_E_DECOMPRESS_ERROR.
+	* run-elfgetzdata.sh: New test.
+	* run-elfputzdata.sh: Likewise.
+
+2015-10-28  Mark Wielaard  <mjw@redhat.com>
+
+	* run-readelf-z.sh: New test.
+	* Makefile.am (TESTS): Add run-readelf-z.sh.
+	(EXTRA_DIST): Likewise.
+
+2015-10-28  Mark Wielaard  <mjw@redhat.com>
+
+	* elfgetchdr.c: New file.
+	* run-elfgetchdr.sh: New test.
+	* testfile-zgabi32.bz2: New testfile.
+	* testfile-zgabi32be.bz2: Likewise.
+	* testfile-zgabi64.bz2: Likewise.
+	* testfile-zgabi64be.bz2: Likewise.
+	* Makefile.am (check_PROGRAMS): Add elfgetchdr.
+	(TESTS): Add run-elfgetchdr.sh.
+	(EXTRA_DIST): Add run-elfgetchdr.sh, testfile-zgabi32.bz2,
+	testfile-zgabi32be.bz2, testfile-zgabi64.bz2, testfile-zgabi64be.bz2.
+	(welfgetchdr_LDADD): New variable.
+	* msg_tst.c: Add ELF_E_NOT_COMPRESSED, ELF_E_INVALID_SECTION_TYPE
+	and ELF_E_INVALID_SECTION_FLAGS,
+
+
+2015-10-28  Mark Wielaard  <mjw@redhat.com>
+
+	* dwelfgnucompressed.c: New file.
+	* run-dwelfgnucompressed.sh: New test.
+	* testfile-zgnu32.bz2: New testfile.
+	* testfile-zgnu64.bz2: Likewise.
+	* Makefile.am (check_PROGRAMS): Add dwelfgnucompressed.
+	(TESTS): Add run-dwelfgnucompressed.sh.
+	(EXTRA_DIST): Add run-dwelfgnucompressed.sh, testfile-zgnu32.bz2,
+	testfile-zgnu64.bz2, testfile-zgnu32be.bz2, testfile-zgnu64be.bz2.
+	(dwelfgnucompressed_LDADD): New variable.
+
+2015-12-31  Mark Wielaard  <mjw@redhat.com>
+
+	* elfstrmerge.c (main): Warn about STT_SECTION symbol for shstrhndx.
+	* run-elfstrmerge-test.sh: New test.
+	* Makefile.am (TESTS): Add run-elfstrmerge-test.sh
+	(EXTRA_DIST): Likewise.
+
+2015-12-08  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
+	* run-backtrace-core-sparc.sh: New file.
+	* backtrace.sparc.core.bz2: New file.
+	* backtrace.sparc.exec.bz2: New file.
+	* Makefile.am (EXTRA_DIST): ... and added all here.
+	(TESTS): Added run-backtrace-core-sparc.sh.
+
+2015-12-02  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (valgrind_cmd): Use --leak-check=full.
+	* run-backtrace-demangle.sh: Disable valgrind.
+	* run-stack-demangled-test.sh: Likewise.
+	* run-stack-d-test.sh: Likewise.
+	* run-stack-i-test.sh: Likewise.
+
+2015-12-01  Mark Wielaard  <mjw@redhat.com>
+
+	* test-flag-nobits.c (main): Call elf_end.
+	* rerequest_tag.c (main): Call dwarf_end.
+	* funcscopes.c (handle_function): Free scopes.
+	* dwarf-getstring.c (main): Call dwarf_end.
+	* allregs.c (main): Free state.info.
+	* alldts.c (main): Free dyn.
+	* addrcfi.c (handle_address): Free stuff.frame between handle_cfi
+	calls.
+	* addrscopes.c (handle_address): Free scopes.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am [BUILD_STATIC] (libdw): Add -lz.
+	[BUILD_STATIC] (libelf): Likewise.
+
+2015-10-16  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (dwfl_proc_attach_LDFLAGS): Add AM_LDFLAGS.
+
+2015-10-09  Josh Stone  <jistone@redhat.com>
+
+	* lfs-symbols: New list of LFS-related symbols from lintian.
+	* testfile-nolfs.bz2: New test binary for sanity checking.
+	* run-lfs-symbols.sh: New test.
+	* Makefile.am (TESTS): Add run-lfs-symbols.sh.
+	(EXTRA_DIST): Add lfs-symbols, testfile-nolfs.bz2, and
+	run-lfs-symbols.sh.
+	* alldts.c (main): Replace open64 with open.
+	* dwarf-getstring.c (main): Likewise.
+	* arls.c: Include config.h.
+	* ecp.c: Likewise.
+	* rdwrmmap.c: Likewise.
+	* test-elf_cntl_gelf_getshdr.c: Likewise.
+	* test-flag-nobits.c: Include config.h.
+	(main): Replace open64 with open.
+
+2015-10-09  Mark Wielaard  <mjw@redhat.com>
+
+	* elfshphehdr.c (check): Rename argument from check to statement.
+	(check_elf): Likewise.
+
+2015-10-05  Josh Stone  <jistone@redhat.com>
+
+	* Makefile.am (backtrace-child-biarch): Add AM_V_CC silencer.
+
+2015-10-02  Mark Wielaard  <mjw@redhat.com>
+
+	* elfstrmerge.c: New check program.
+	* run-strip-strmerge.sh: New test.
+	* Makefile.am (check_PROGRAMS): Add elfstrmerge.
+	(EXTRA_DIST): Add run-strip-strmerge.sh
+	(elfstrmerge_LDADD): New variable.
+
+2015-09-29  Mark Wielaard  <mjw@redhat.com>
+
+	* elfshphehdr.c: New test.
+	* Makefile.am (check_PROGRAMS): Add elfshphehdr.
+	(TESTS): Likewise.
+	(elfshphehdr_LDADD): New variable.
+
+2015-09-08  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl-proc-attach.c: New test.
+	* Makefile.am (check_PROGRAMS): Add dwfl-proc-attach.
+	(TESTS): Likewise.
+	(dwfl_proc_attach_LDADD): New variable.
+	(dwfl_proc_attach_LDFLAGS): Likewise.
+
+2015-09-04  Chih-Hung Hsieh  <chh@google.com>
+
+	* varlocs.c (print_base_type): Initialize enctype.
+
+2015-09-04  Chih-Hung Hsieh  <chh@google.com>
+
+	* md5-sha1-test.c (md5_expected): Removed.
+	(sha1_expected): Likewise.
+
+2015-09-04  Chih-Hung Hsieh  <chh@google.com>
+
+	* asm-tst1.c (main): Replace %Z length modifier with %z.
+	* asm-tst2.c (main): Likewise.
+	* asm-tst3.c (main): Likewise.
+	* asm-tst4.c (main): Likewise.
+	* asm-tst5.c (main): Likewise.
+	* asm-tst6.c (main): Likewise.
+	* asm-tst7.c (main): Likewise.
+	* asm-tst8.c (main): Likewise.
+	* asm-tst9.c (main): Likewise.
+	* sectiondump.c (print_bytes): Likewise.
+
+2015-08-14  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addr2line-alt-debugpath.sh: New test.
+	* Makefile.am (TESTS): Add run-addr2line-alt-debugpath.sh
+	(EXTRA_DIST): Likewise.
+
+2015-07-29  Mark Wielaard  <mjw@redhat.com>
+
+	* run-unstrip-test3.sh: New test.
+	* testfile-info-link.bz2: New file.
+	* testfile-info-link.debuginfo.bz2: Likewise.
+	* testfile-info-link.stripped.bz2: Likewise.
+	* Makefile.am (TESTS): Add run-unstrip-test3.sh.
+	(EXTRA_DIST): Add run-unstrip-test3.sh, testfile-info-link.bz2,
+	testfile-info-link.debuginfo.bz2, testfile-info-link.stripped.bz2.
+
+2015-06-27  Pino Toscano  <toscano.pino@tiscali.it>
+
+	* tests/run-deleted.sh: Skip when detecting a not implemented
+	dwfl_linux_proc_attach.
+
+2015-06-27  Pino Toscano  <toscano.pino@tiscali.it>
+
+	* tests/dwfl-bug-fd-leak.c (elfutils_open): Check for null results of
+	dwfl_addrmodule.
+
+2015-06-26  Pino Toscano  <toscano.pino@tiscali.it>
+
+	* tests/vdsosyms.c [!__linux__] (main): Mark argv as unused.
+
+2015-06-26  Pino Toscano  <toscano.pino@tiscali.it>
+
+	* tests/backtrace-data.c: Reduce scope of some includes to match their
+	usage.
+	* tests/backtrace.c: Likewise.
+	* tests/deleted.c: Likewise.
+
+2015-06-16  Mark Wielaard  <mjw@redhat.com>
+
+	* run-strip-test.sh: Add strip-in-place (eu-strip without -o) test
+	for non-ET_REL files.
+
+2015-05-30  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace-subr.sh (check_native_core): Notice core file couldn't be
+	generated before skipping.
+	* run-addr2line-i-demangle-test.sh: Notice demangler is unsupported
+	before skipping.
+	* run-backtrace-demangle.sh: Likewise.
+	* run-stack-demangled-test.sh: Likewise.
+	* run-backtrace-native-biarch.sh: Notice biarch testing is disabled
+	before skipping.
+	* run-backtrace-native-core-biarch.sh: Likewise.
+	* test-subr.sh (testfiles): Notice how bunzip2 fails before skipping.
+
+2015-05-20  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addr2line-i-test.sh: Add pretty test.
+	* run-addr2line-test.sh: Likewise.
+
+2015-05-20  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addr2line-i-demangle-test.sh: New test.
+	* Makefile.am (TESTS): Add run-addr2line-i-demangle-test.sh.
+	(EXTRA_DIST): Likewise.
+
+2015-05-20  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addr2line-test.sh: Add -a test variants.
+	* run-addr2line-i-test.sh: Likewise.
+
+2015-05-20  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addrname-test.sh: Make sure all input addresses are hex.
+
+2015-05-04  Max Filippov  <jcmvbkbc@gmail.com>
+
+	* backtrace-child.c (stdarg, main): Replace assert_perror with assert.
+	* backtrace-data.c (memory_read, maps_lookup, set_initial_registers)
+	(main): Likewise.
+	* backtrace-dwarf.c (main): Likewise.
+	* backtrace.c (prepare_thread, exec_dump): Likewise.
+
+2015-05-04  Anthony G. Basile  <blueness@gentoo.org>
+
+	* Makefile.am (line2addr_LDADD, addrscopes_LDADD, funcscopes_LDADD)
+	(funcretval_LDADD, allregs_LDADD, find_prologues_LDADD)
+	(dwflmodtest_LDADD, dwfl_addr_sect_LDADD, addrcfi_LDADD)
+	(low_high_pc_LDADD, dwflsyms_LDADD, dwfllines_LDADD, varlocs_LDADD)
+	(backtrace_LDADD, aggregate_size_LDADD): Append $(argp_LDADD).
+
+2015-05-01  Mark Wielaard  <mjw@redhat.com>
+
+	* run-stack-d-test.sh: Use --raw and mangled output.
+	* run-stack-i-test.sh: Likewise.
+	* run-stack-demangled-test.sh: New test.
+	* Makefile.am (EXTRA_DIST): Add run-stack-demangled-test.sh.
+	(TESTS): Likewise.
+
+2015-04-01  H.J. Lu  <hjl.tools@gmail.com>
+
+	* Makefile.am (TESTS): Add run-strip-test10.sh.
+	(EXTRA_DIST): Likewise. Add testfile-x32-d.bz2.
+	Add testfile-x32-debug.bz2.
+	* run-strip-test10.sh: New file.
+	* testfile-x32-d.bz2: Likewise.
+	* testfile-x32-debug.bz2: Likewise.
+
+2015-04-01  H.J. Lu  <hjl.tools@gmail.com>
+
+	* Makefile.am (TESTS): Add run-strip-test9.sh.
+	(EXTRA_DIST): Likewise. Add testfile-x32-s.bz2.
+	* run-strip-test9.sh: New file.
+	* testfile-x32-s.bz2: Likewise.
+
+2015-04-01  H.J. Lu  <hjl.tools@gmail.com>
+
+	* Makefile.am (TESTS): Add run-backtrace-core-x32.sh.
+	(EXTRA_DIST): Likewise. Add backtrace.x32.core.bz2.
+	Add backtrace.x32.exec.bz2.
+	* backtrace.x32.core.bz2 : New file.
+	* backtrace.x32.exec.bz2: Likewise.
+	* run-backtrace-core-x32.sh: Likewise.
+
+2015-04-01  H.J. Lu  <hjl.tools@gmail.com>
+
+	* run-addrcfi.sh: Add a test for testfile-x32.
+	* testfile-x32.bz2: New file.
+	* Makefile.am (EXTRA_DIST): Add testfile-x32.bz2.
+
+2015-04-01  H.J. Lu  <hjl.tools@gmail.com>
+
+	* run-allregs.sh: Add a test for testfile-x32-core.
+
+2015-04-01  H.J. Lu  <hjl.tools@gmail.com>
+
+	* run-readelf-mixed-corenote.sh: Add a test for testfile-x32-core.
+	* testfile-x32-core.bz2: New file.
+	* Makefile.am (EXTRA_DIST): Add testfile-x32-core.bz2.
+
+2015-03-18  Petr Machata  <pmachata@redhat.com>
+
+	* addrcfi.c (op_name): Adjust uses of know-dwarf.h macros to match
+	the API changes.
+	* allregs.c (dwarf_encoding_string): Likewise.
+	* show-die-info.c (dwarf_tag_string, dwarf_attr_string): Likewise.
+	* varlocs.c (dwarf_encoding_string, dwarf_opcode_string): Likewise.
+
+2015-03-18  Petr Machata  <pmachata@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add run-dwarf-ranges.sh,
+	debug-ranges-no-lowpc.o.bz2.
+
+2015-03-13  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace-dwarf.c: Add explicit includes.
+	(cleanup_13_abort): Remove unused static declaration.
+	(thread_callback): Add explicit return.
+
+2015-03-13  H.J. Lu  <hjl.tools@gmail.com>
+
+	* backtrace.c (prepare_thread): Use PTRACE_GETREGS/PTRACE_SETREGS
+	instead of PTRACE_POKEUSER.
+	(exec_dump): Check EM_X86_64 instead of ELFCLASS64 for
+	is_x86_64_native.
+
+2015-02-18  Mark Wielaard  <mjw@redhat.com>
+
+	* newdata.c (check_section_data): Use PRId64 for printing loff_t.
+
+2015-02-11  Josh Stone  <jistone@redhat.com>
+
+	* backtrace.c (exec_dump): Initialize jmp.
+
+2015-02-11  Petr Machata  <pmachata@redhat.com>
+
+	* run-dwarf-ranges.sh: New test.
+	* dwarf-ranges.c: New file.
+	* debug-ranges-no-lowpc.s, debug-ranges-no-lowpc.o.bz2: New test case.
+
+2015-01-21  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add elfstrtab.
+	(TESTS): Likewise.
+	(elfstrtab_LDADD): New variable.
+	* elfstrtab.c: New test.
+
+2015-01-20  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add newdata.
+	(TESTS): Likewise.
+	(newdata_LDADD): new variable.
+	* newdata.c: New test.
+
+2015-01-20  Mark Wielaard  <mjw@redhat.com>
+
+	* strptr.c: New file.
+	* run-strptr.sh: New test.
+	* Makefile.am (check_PROGRAMS): Add strptr.
+	(TESTS): Add run-strptr.sh.
+	(EXTRA_DIST): Likewise.
+	(strptr_LDADD): New variable.
+
+2015-01-15  Mark Wielaard  <mjw@redhat.com>
+
+	* deleted.c (main): Call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY).
+	* vdsosyms.c (main): Use getpid () instead of getppid ().
+
+2014-12-27  Mark Wielaard  <mjw@redhat.com>
+
+	* addrscopes.c (handle_address): Last address in scope is highpc - 1.
+	* funcscopes.c (handle_function): Likewise.
+	* run-addrscopes.sh: Adjust last address in scope.
+	* run-funcscopes.sh: Likewise.
+
+2015-01-07  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addrcfi.sh: Add test for ppc32 eh_frame_hdr address search.
+
+2015-01-14  Mark Wielaard  <mjw@redhat.com>
+
+	* testfile-debug-types.bz2: New testfile.
+	* Makefile.am (EXTRA_DIST): Add testfile-debug-types.bz2.
+	* typeiter2.c (main): Print both name and offset of found form DIE.
+	* run-typeiter.s: Adjust output and add testfile-debug-types.
+
+2014-12-26  Mark Wielaard  <mjw@redhat.com>
+
+	* run-test-archive64.sh: Add nm test.
+
+2014-12-19  Mark Wielaard  <mjw@redhat.com>
+
+	* run-deleted.sh: Don't check libfunc on ppc64.
+
+2014-12-19  Mark Wielaard  <mjw@redhat.com>
+
+	* vdsosyms.c (vdso_seen): Removed.
+	(vdso_syms): New global.
+	(module_callback): Set and check vdso_syms.
+	(main): Return value depends on vdso_syms.
+
+2014-12-19  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace-subr.sh (check_native_unsupported): Relax special ARM
+	grep a little.
+	* run-deleted.sh: Call check_native_unsupported.
+
+2014-12-18  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add testfile-macros-0xff.bz2.
+
+2014-12-12  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (deleted_lib_so_CFLAGS): Add
+	-fasynchronous-unwind-tables.
+
+2014-12-11  Josh Stone  <jistone@redhat.com>
+
+	* run-addr2line-i-lex-test.sh: New test.
+	* testfile-lex-inlines.bz2: New testfile.
+	* Makefile.am (EXTRA_DIST): Add run-addr2line-i-lex-test.sh and
+	testfile-lex-inlines.bz2.
+	(TESTS): Add run-addr2line-i-lex-test.sh.
+
+2014-12-10  Josh Stone  <jistone@redhat.com>
+
+	* run-addr2line-i-test.sh: Test 0x5f0 to make sure linkage_name is
+	preferred over the plain die name.
+
+2014-12-02  Petr Machata  <pmachata@redhat.com>
+
+	* dwarf-getmacros.c (mac): Skip over DW_MACINFO_undef,
+	DW_MACRO_GNU_undef_indirect opcodes.  Add a default branch.
+	(main): Initialize off to DWARF_GETMACROS_START when an extra
+	command line argument is passed.
+	* testfile-macros-0xff.bz2: New test case.
+	* testfile-macros-0xff.s: New file (source for the above).
+	* run-dwarf-getmacros.sh: Add two tests.
+
+2014-11-27  Mark Wielaard  <mjw@redhat.com>
+
+	* vdsosyms.c (main): Call dwfl_linux_proc_attach.
+
+2014-11-21  Mark Wielaard  <mjw@redhat.com>
+
+	* run-readelf-A.sh: New test.
+	* testfileppc32attrs.o.bz2: New test file.
+	* Makefile.am (TESTS): Add run-readelf-A.sh.
+	(EXTRA_DIST): Add run-readelf-A.sh and testfileppc32attrs.o.bz2.
+
+2014-11-10  Mark Wielaard  <mjw@redhat.com>
+
+	* vdsosyms.c: New test.
+	* Makefile.am (check_PROGRAMS): Add vdsosyms.
+	(TESTS): Likewise.
+	(vdsosyms_LDADD): New variable.
+
+2014-09-10  Petr Machata  <pmachata@redhat.com>
+
+	* dwarf-getmacros.c: Update to use the new macro iteration
+	interfaces.
+	* run-dwarf-getmacros.sh: Adjust, add a test that uses
+	testfile-macros.
+
+2014-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* run-aggregate-size.sh: Add testfile-sizes3.o test case.
+	* testfile-sizes3.o.bz2: New test file.
+	* Makefile.am (EXTRA_DIST): Add testfile-sizes3.o.bz2.
+
+2014-10-02  Mark Wielaard  <mjw@redhat.com>
+
+	* run-deleted.sh: Unset VALGRIND_CMD before running deleted.
+
+2014-10-02  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add aggregate_size.c.
+	(TESTS): Add run-aggregate-size.sh.
+	(EXTRA_DIST): Add run-aggregate-size.sh, testfile-sizes1.o.bz2
+	and testfile-sizes2.o.bz2.
+	(aggregate_size_LDADD): New variable.
+	* aggregate_size.c: New file.
+	* run-aggregate-size.sh: New test.
+	* testfile-sizes1.o.bz2: New test file.
+	* testfile-sizes2.o.bz2: Likewise.
+
+2014-09-26  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Support NT_FILE for locating files.
+	* Makefile.am (TESTS): Add run-linkmap-cut.sh.
+	(EXTRA_DIST): Add run-linkmap-cut.sh, linkmap-cut-lib.so.bz2,
+	linkmap-cut.bz2 and linkmap-cut.core.bz2 .
+	* linkmap-cut-lib.so.bz2: New file.
+	* linkmap-cut.bz2: New file.
+	* linkmap-cut.core.bz2: New file.
+	* run-linkmap-cut.sh: New file.
+	* run-unstrip-n.sh: Update its expected output.
+
+2014-08-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add deleted and deleted-lib.so.
+	(TESTS, EXTRA_DIST): Add run-deleted.sh.
+	(deleted_LDADD, deleted_lib_so_LDFLAGS, deleted_lib_so_CFLAGS): New.
+	* deleted-lib.c: New file.
+	* deleted.c: New file.
+	* run-deleted.sh: New file.
+
+2014-06-15  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace.c (frame_callback): Error on seeing more than 16 frames.
+
+2014-06-13  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace.c (callback_verify): Accept "__libc_do_syscall" as first
+	frame symname.
+
+2014-06-13  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace-subr.sh (check_native_unsupported): New function.
+	(check_native): Call it.
+	(check_native_core): Likewise.
+	* run-backtrace-dwarf.sh: Likewise.
+
+2014-06-11  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace.c (main): Check that Dwfl was attached by calling
+	dwfl_pid and printing the error when it is not.
+
+2014-05-18  Mark Wielaard  <mjw@redhat.com>
+
+	* testfile-backtrace-demangle.cc (cxxfunc): Make non-static.
+	(f): Likewise.
+	* testfile-backtrace-demangle.bz2: Regenerate.
+	* testfile-backtrace-demangle.core.bz2: Likewise.
+
+2014-05-02  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): run-readelf-dwz-multi.sh and
+	run-allfcts-multi.sh are now added unconditionally.
+
+2014-05-01  Mark Wielaard  <mjw@redhat.com>
+
+	* run-readelf-dwz-multi.sh: Add tests with alt debug files in .dwz
+	subdir.
+
+2014-04-30  Mark Wielaard  <mjw@redhat.com>
+
+	* buildid.c, buildid.sh, testfile42_noshdrs.bz2: New files.
+	* Makefile.am (check_PROGRAMS): Add buildid.
+	(TESTS): Add run-buildid.sh.
+	(EXTRA_DISTS): Add run-buildid.sh and testfile42_noshdrs.bz2.
+	(buildid_LDADD): New variable.
+
+2014-04-24  Florian Weimer  <fweimer@redhat.com>
+
+	* allfcts.c (setup_alt): New function.
+	(main): Call it.  Implementation additional error checking and
+	reporting.
+
+2014-04-24  Florian Weimer  <fweimer@redhat.com>
+
+	* debugaltlink.c, run-debugaltlink.sh: New files.
+	* Makefile.am (check_PROGRAMS): Add debugaltlink.
+	(TESTS): Add run-debugaltlink.sh.
+	(debugaltlink_LDADD): New variable.
+
+2014-04-11  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (AM_CPPFLAGS): Add -I libdwelf.
+	(check_PROGRAMS): Add debuglink.
+	(TESTS): Add run-debuglink.sh
+	(EXTRA_DIST): Likewise.
+	(debuglink_LDADD): New.
+	* debuglink.c: New file.
+	* run-debuglink.sh: Likewise.
+
+2014-03-23  Mark Wielaard  <mjw@redhat.com>
+
+	* run-nm-self.sh: Use test = not == for string comparisons.
+
+2014-04-22  Kurt Roeckx  <kurt@roeckx.be>
+
+	* backtrace.c: Make Linux only.
+	* backtrace-child.c: Make Linux only.
+	* backtrace-data.c: Make Linux only.
+	* backtrace-dwarf.c: Make Linux only.
+	* backtrace-subr.sh: Skip core file unwinding tests when not supported.
+
+2014-03-14  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Remove MUDFLAP conditions. Remove libmudflap from all
+	LDADD lines.
+	* configure.ac: Remove MUDFLAP conditional.
+
+2014-04-09  Mark Wielaard  <mjw@redhat.com>
+
+	* run-readelf-zdebug.sh: New test.
+	* testfile-debug.bz2: New testfile.
+	* testfile-zdebug.bz2: New testfile.
+	* Makefile.am (TESTS): Add run-readelf-zdebug.sh if ZLIB.
+	(EXTRA_DIST): Add run-readelf-zdebug.sh, testfile-debug.bz2 and
+	testfile-zdebug.bz2.
+
+2014-04-10  Mark Wielaard  <mjw@redhat.com>
+
+	* testfile_i686_core.bz2: New test file.
+	* run-readelf-mixed-corenote.sh: Add testfile_i686_core test.
+	* Makefile.am (EXTRA_DIST): Add testfile_i686_core.bz2
+
+2014-04-09  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): Add run-backtrace-core-aarch64.sh.
+	(EXTRA_DIST): Add run-backtrace-core-aarch64.sh,
+	backtrace.aarch64.core.bz2 and backtrace.aarch64.exec.bz2.
+	* run-backtrace-core-aarch64.sh: New test.
+
+2014-03-11  Josh Stone  <jistone@redhat.com>
+
+	* testfilebaxmin.bz2: New testfile.
+	* Makefile.am (EXTRA_DIST): Add testfilebaxmin.bz2.
+	* run-readelf-s.sh: Test testfilebaxmin.
+	* run-dwflsyms.sh: Likewise.
+
+2014-01-26  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace-subr.sh (check_unsupported): Special case arm*.
+
+2014-01-25  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addrcfi.sh (EM_ARM): Change reg13 (sp) from undefined to
+	location expression: call_frame_cfa stack_value.
+
+2014-01-22  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (line2addr_no_Wformat): Removed.
+
+2014-01-21  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): Add run-stack-i-test.sh.
+	(EXTRA_DIST): Likewise.
+	* run-stack-i-test.sh: New test.
+
+2014-01-20  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): Add run-stack-d-test.sh.
+	(EXTRA_DIST): Add run-stack-d-test.sh, testfiledwarfinlines.bz2
+	testfiledwarfinlines.core.bz2.
+	* run-stack-d-test.sh: New test.
+	* testfiledwarfinlines.bz2: New test file.
+	* testfiledwarfinlines.core.bz2: Likewise.
+
+2014-01-16  Mark Wielaard  <mjw@redhat.com>
+
+	* run-nm-self.sh: Don't use testrun_on_self_quiet but just testrun
+	on one ET_REL, one ET_EXEC and one ET_DYN file.
+	* test-subr.sh (self_test_files): Add two ET_REL files, only add
+	two libebl ET_DYN backend files.
+
+2014-01-16  Mark Wielaard  <mjw@redhat.com>
+
+	* run-backtrace-demangle.sh: Check exitcode and max number of frames.
+
+2014-01-18  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Fix false FAILs on testsuite with ulimit -c unlimited.
+	* backtrace-child.c (sigusr2): Call pthread_exit.
+	(main): Return, do not call abort.
+
+2014-01-15  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Fix corruption of non-C++ symbols by the demangler.
+	* Makefile.am (TESTS): Add run-backtrace-demangle.sh.
+	<!DEMANGLE>: Add ELFUTILS_DISABLE_DEMANGLE export.
+	(EXTRA_DIST): Add run-backtrace-demangle.sh,
+	testfile-backtrace-demangle.bz2, testfile-backtrace-demangle.cc,
+	testfile-backtrace-demangle.core.bz2.
+	* backtrace-demangle.cc: New file.
+	* run-backtrace-demangle.sh: New file.
+	* testfile-backtrace-demangle.bz2: New file.
+	* testfile-backtrace-demangle.cc: New file.
+	* testfile-backtrace-demangle.core.bz2: New file.
+
+2014-01-07  Matthias Klose <doko@ubuntu.com>
+
+	* backtrace-subr.sh (check_native_core): Check to see if core file
+	was created without ".PID" extension, if so mv core to core.PID.
+	Skip test if no core file was created or could be found.
+
+2014-01-04  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace-data.c (main): Don't assert if raise returns.
+	* backtrace-dwarf.c (report_pid): Call dwfl_linux_proc_attach with
+	assume_ptrace_attached true.
+	(ptrace_detach_stopped): Removed function.
+	(main): Don't call ptrace_detach_stopped.
+	* backtrace.c (ptrace_detach_stopped): Removed function.
+	(report_pid): Call dwfl_linux_proc_attach with assume_ptrace_attached
+	true.
+	(exec_dump): Don't call ptrace_detach_stopped.
+
+2014-01-04  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace-subr.sh (check_native_core): Skip, exit 77, the test
+	if we cannot adjust core ulimit.
+
+2014-01-04  Mark Wielaard  <mjw@redhat.com>
+
+	* cleanup-13.c (force_unwind_stop): Removed.
+	(force_unwind): Just call abort. Don't setup _Unwind_Exception and
+	don't call _Unwind_ForcedUnwind.
+
+2014-01-03  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addrcfi.sh: Add case for EM_AARCH64.
+	* testfileaarch64.bz2: New testfile.
+	* Makefile.am (EXTRA_DIST): Add testfilesaarch64.bz2.
+
+2013-12-30  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace-dwarf.c (report_pid): Explicitly call
+	dwfl_linux_proc_attach and check for errors.
+	* backtrace.c (report_pid): Likewise.
+
+2013-12-21  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace.c (callback_verify): Only assert that case 5 is the last
+	instruction of backtracegen on x86_64 native.
+
+2013-12-18  Jan Kratochvil  <jan.kratochvil@redhat.com>
+	    Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add testfile66.bz2, testfile66.core.bz2
+	and testfilebaz*ppc64*.bz2 files.
+	* dwflsyms.c (list_syms): Remove unused from parameter mod_name.  Print
+	error on dwfl_module_getsymtab error.
+	(list_syms): Use dwfl_module_getsym and dwfl_module_getsym_info.
+	Compare values for non-ET_REL. Use dwfl_module_addrinfo.
+	Also print section of actual value if different from sym.
+	* run-addrname-test.sh (testfile66, testfile66.core): New tests.
+	Test addr2line -x by showing different sections for address and
+	found name in testfile66.
+	* run-dwflsyms.sh (testfile66, testfile66.core, hello_ppc64.ko,
+	testfilebaz*ppc64): New tests.
+	* testfile66.bz2, testfile66.core.bz2, testfilebazdbgppc64.bz2,
+	testfilebazdbgppc64.debug.bz2, testfilebazdbgppc64_pl.bz2,
+	testfilebazdbgppc64_plr.bz2, testfilebazdynppc64.bz2,
+	testfilebazmdbppc64.bz2, testfilebazminppc64.bz2,
+	testfilebazminppc64_pl.bz2, testfilebazminppc64_plr.bz2,
+	testfilebaztabppc64.bz2: New test files.
+
+2013-12-18  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	unwinder: s390 and s390x
+	* Makefile.am (TESTS): Add run-backtrace-core-s390x.sh and
+	run-backtrace-core-s390.sh.
+	(EXTRA_DIST): Add backtrace.s390x.core.bz2, backtrace.s390x.exec.bz2,
+	backtrace.s390.core.bz2, backtrace.s390.exec.bz2,
+	run-backtrace-core-s390x.sh and run-backtrace-core-s390.sh.
+	* backtrace.s390.core.bz2: New file.
+	* backtrace.s390.exec.bz2: New file.
+	* backtrace.s390x.core.bz2: New file.
+	* backtrace.s390x.exec.bz2: New file.
+	* run-backtrace-core-s390.sh: New file.
+	* run-backtrace-core-s390x.sh: New file.
+
+2013-12-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* backtrace-dwarf.c (executable, find_elf, dwfl_offline): Remove unused
+	code.
+
+2013-12-15  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	unwinder: ppc
+	* Makefile.am (TESTS): Add run-backtrace-core-ppc.sh.
+	(EXTRA_DIST): Add backtrace.ppc.core.bz2,
+	backtrace.ppc.exec.bz2 and run-backtrace-core-ppc.sh.
+	* backtrace.ppc.core.bz2: New file.
+	* backtrace.ppc.exec.bz2: New file.
+	* run-backtrace-core-ppc.sh: New file.
+
+2013-12-10  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (backtrace_child_biarch_SOURCES): New backtrace-child.c.
+
+2013-12-10  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (valgrind_cmd): Remove --trace-children=yes.
+	* backtrace-subr.sh (check_native_core): Disable valgrind while
+	dumping core.
+	* run-backtrace-data.sh: Disable valgrind.
+	* run-backtrace-dwarf.sh: Likewise.
+
+2013-12-09  Mark Wielaard  <mjw@redhat.com>
+
+	* varlocs.c (print_expr): Update comment to explain empty location
+	associated with DW_OP_GNU_implicit_pointer.
+
+2013-12-05  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	Fix test FAIL with -O2.
+	* backtrace-child.c (sigusr2): Add NOINLINE_NOCLONE and final asm stub.
+
+2013-12-05  Mark Wielaard  <mjw@redhat.com>
+
+	* backtrace-data.c (main): If unsupported also print to stderr.
+	* run-backtrace-dwarf.sh: Add check_unsupported and check_main.
+
+2013-12-04  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (backtrace-child-biarch): Add $(EXEEXT).
+
+2013-12-02  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add backtrace, backtrace-child,
+	backtrace-data and backtrace-dwarf.
+	(BUILT_SOURCES, clean-local, backtrace-child-biarch): New.
+	(TESTS): Add run-backtrace-native.sh, run-backtrace-data.sh,
+	run-backtrace-dwarf.sh, run-backtrace-native-biarch.sh,
+	run-backtrace-native-core.sh, run-backtrace-native-core-biarch.sh,
+	run-backtrace-core-x86_64.sh and run-backtrace-core-i386.sh.
+	<!BIARCH> Add export of ELFUTILS_DISABLE_BIARCH.
+	(EXTRA_DIST): Add run-backtrace-data.sh, run-backtrace-dwarf.sh,
+	cleanup-13.c, run-backtrace-native.sh, run-backtrace-native-biarch.sh,
+	run-backtrace-native-core.sh, run-backtrace-native-core-biarch.sh,
+	run-backtrace-core-x86_64.sh, run-backtrace-core-i386.sh,
+	backtrace-subr.sh, backtrace.i386.core.bz2, backtrace.i386.exec.bz2,
+	backtrace.x86_64.core.bz2, backtrace.x86_64.exec.bz2.
+	(backtrace_LDADD, backtrace_child_CFLAGS, backtrace_child_LDFLAGS)
+	(backtrace_data_LDADD, backtrace_dwarf_CFLAGS, backtrace_dwarf_LDADD):
+	New.
+	* backtrace-child.c: New file.
+	* backtrace-data.c: New file.
+	* backtrace-dwarf.c: New file.
+	* backtrace-subr.sh: New file.
+	* backtrace.c: New file.
+	* cleanup-13.c: New file.
+	* backtrace.i386.core.bz2: New file.
+	* backtrace.i386.exec.bz2: New file.
+	* backtrace.x86_64.core.bz2: New file.
+	* backtrace.x86_64.exec.bz2: New file.
+	* run-backtrace-core-i386.sh: New file.
+	* run-backtrace-core-x86_64.sh: New file.
+	* run-backtrace-native-biarch.sh: New file.
+	* run-backtrace-native-core-biarch.sh: New file.
+	* run-backtrace-native-core.sh: New file.
+	* run-backtrace-native.sh: New file.
+	* run-backtrace-data.sh: New file.
+	* run-backtrace-dwarf.sh: New file.
+
+2013-11-27  Mark Wielaard  <mjw@redhat.com>
+
+	* dwflsyms.c (gelf_bind_order): New function.
+	(elf_section_name): Likewise.
+	(addr_in_section): Likewise.
+	(list_syms): Use dwfl_module_getsym_elf and dwfl_module_addrsym_elf.
+	Refine assert using gelf_bind_order. Print elf_section_name. Check
+	bias with addr_in_section.
+	* run-dwflsyms.sh: Add section names to expected output.
+
+2013-11-26  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add run-funcretval.sh.
+
+2013-11-25  Petr Machata  <pmachata@redhat.com>
+
+	* testfile_aarch64_core.bz2, hello_aarch64.ko.bz2: New files.
+	* funcretval_test.c, funcretval_test_aarch64.bz2: Likewise.
+	* Makefile.am (EXTRA_DIST): Add these.
+	(TESTS): Add run-funcretval.sh.
+	* run-allregs.sh: Use testfile_aarch64_core.bz2 for a regs_test.
+	* run-readelf-mixed-corenote.sh: ... and for a readelf -n test.
+	* run-strip-reloc.sh: Add a test on hello_aarch64.ko.bz2.
+	* run-funcretval.sh: New file.
+
+2013-11-18  Josh Stone  <jistone@redhat.com>
+
+	* testfilebazdbg_plr.bz2: New testfile.
+	* testfilebazmin_plr.bz2: Likewise.
+	* Makefile.am (EXTRA_DIST): Add the above files.
+	* run-dwflsyms.sh: Add prelink -r tests.
+
+2013-11-15  Mark Wielaard  <mjw@redhat.com>
+
+	* testfilebazmdb.bz2: Regenerated.
+	* testfilebazmin.bz2: Likewise.
+	* testfilebazdbg_pl.bz2: New testfile.
+	* testfilebazmin_pl.bz2: Likewise.
+	* Makefile.am (EXTRA_DIST): Add testfilebazdbg_pl.bz2 and
+	testfilebazmin_pl.bz2.
+	* dwflsyms.c (list_syms): Call dwfl_module_relocate_address and
+	print relative address of function symbols.
+	* run-dwflsyms.sh: Add prelink tests and adjust expected output.
+
+2013-11-01  Michael Forney  <mforney@mforney.org>
+
+	* Makefile.am (TESTS_ENVIRONMENT): Use and export NM.
+	* run-arsymtest.sh: Use NM.
+
+2013-11-05  Mark Wielaard  <mjw@redhat.com>
+
+	* allfcts.c (main): Correct dwarf_getfuncs return value check.
+
+2013-10-10  Mark Wielaard  <mjw@redhat.com>
+	    Josh Stone  <jistone@redhat.com>
+
+	* run-allfcts-multi.sh: New test.
+	* test-offset-loop.bz2: New testfile.
+	* test-offset-loop.alt.bz2: New testfile.
+	* Makefile.am (TESTS): Add run-allcft-multi.sh if ENABLE_DWZ.
+	(EXTRA_DIST): Add run-allfcts-multi.sh, test-offset-loop.bz2 and
+	test-offset-loop.alt.bz2.
+
+2013-10-15  Mark Wielaard  <mjw@redhat.com>
+
+	* run-unstrip-M.sh: New test.
+	* Makefile.am (TESTS): Add run-unstrip-M.sh.
+	(EXTRA_DIST): Likewise.
+
+2013-10-06  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addrcfi.sh: Remove nop from expected ppc and ppc64
+	location expression.
+
+2013-10-03  Josh Stone  <jistone@redhat.com>
+
+	* typeiter2.c: New file, reversing typeiter.c.
+	* run-typeiter.sh: Also run typeiter2.
+	* Makefile.am (check_PROGRAMS): Add typeiter2.
+	(typeiter2_LDADD): New variable.
+
+2013-09-26  Petr Machata  <pmachata@redhat.com>
+
+	* run-readelf-mixed-corenote.sh: Update output of testfile71
+	dump--readelf can newly decode the NT_FILE note.
+
+2013-09-26  Petr Machata  <pmachata@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add testfile71.bz2.
+	* run-readelf-mixed-corenote.sh: New test for this file.
+	* testfile71.bz2: New file.
+
+2013-09-20  Mark Wielaard  <mjw@redhat.com>
+
+	* allfcts.c (cb): Return DWARF_CB_ABORT.
+	(main): Iterate over all offsets returned by dwarf_getfuncs.
+	* run-allfcts.sh: Add nested_funcs and class_func testcases.
+	* testfile_nested_funcs.bz2: New test file.
+	* testfile_class_func.bz2: Likewise.
+	* Makefile.am (EXTRA_DIST): Add testfile_class_func.bz2 and
+	testfile_nested_funcs.bz2.
+
+2013-08-30  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add varlocs.
+	(TESTS): Add run-varlocs.sh.
+	(EXTRA_DIST): Add run-varlocs.sh, testfile_const_type.c,
+	testfile_const_type.bz2, testfile_implicit_pointer.c,
+	testfile_implicit_pointer.bz2, testfile_parameter_ref.c,
+	testfile_entry_value.c, testfile_entry_value.bz2,
+	testfile_implicit_value.c and testfile_implicit_value.bz2.
+	(varlocs_LDADD): New.
+	* run-varlocs: New test.
+	* testfile_const_type.c: New test source file.
+	* testfile_entry_value.c: Likewise.
+	* testfile_implicit_pointer.c: Likewise.
+	* testfile_implicit_value.c: Likewise.
+	* testfile_parameter_ref.c: Likewise.
+	* testfile_const_type.bz2: New test file.
+	* testfile_entry_value.bz2: Likewise.
+	* testfile_implicit_pointer.bz2: Likewise.
+	* testfile_implicit_value.bz2: Likewise.
+	* testfile_parameter_ref.bz2: Likewise.
+	* varlocs.c: New test source.
+
+2013-08-29  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addrcfi.sh: Add case for EM_ARM.
+	* testfilearm.bz2: New testfile.
+	* Makefile.am (EXTRA_DIST): Add testfilesarm.bz2.
+
+2013-08-28  Mark Wielaard  <mjw@redhat.com>
+
+	* addrcfi.c (handle_cfi): Handle .debug_frame or .eh_frame
+	completely missing.
+	* run-addrcfi.sh: Add case for EM_S390 ELFCLASS32 and ELFCLASS64.
+	* testfiles390.bz2: New testfile.
+	* testfiles390x.bz2: Likewise.
+	* Makefile.am (EXTRA_DIST): Add testfiles390.bz2 and
+	testfiles390x.bz2.
+
+2013-08-28  Mark Wielaard  <mjw@redhat.com>
+
+	* addrcfi.c (handle_cfi): Use printf not error.
+	* run-addrcfi.sh: Add case for EM_PPC and EM_PPC64.
+	* testfileppc32.bz2: New testfile.
+	* testfileppc64.bz2: Likewise.
+	* Makefile.am (EXTRA_DIST): Add testfileppc32.bz2 and
+	testfileppc64.bz2.
+
+2013-08-27  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addrcfi.sh: New test.
+	* Makefile.am (TESTS): Add run-addrcfi.sh.
+	(EXTRA_DIST): Likewise.
+	* addrcfi.c (op_name): New function.
+	(print_detail): Call and print op_name. Check ops, not result
+	to check if this is "same value" or "undefined".
+	(handle_cfi): Make sure cfa_ops doesn't point to NULL.
+
+2013-08-13  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addr2line-i-test.sh: New test.
+	* testfile-inlines.bz2: New testfile.
+	* Makefile.am (EXTRA_DIST): Add run-addr2line-i-test.sh and
+	testfile-inlines.bz2.
+	(TESTS): Add run-addr2line-i-test.sh.
+
+2013-08-12  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addr2line-test.sh: New test.
+	* Makefile.am (EXTRA_DIST): Add run-addr2line-test.sh.
+	(TESTS): Likewise.
+
+2013-07-23  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* run-unstrip-n.sh (test-core.*): Ignore libc.so.6 entry and order of
+	the entries.
+
+2013-07-02  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Fix typo, forgot extension in
+	testfilenolines.bz2.
+
+2013-05-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add test-core-lib.so.bz2,
+	test-core.core.bz2 and test-core.exec.bz2.
+	* run-addrname-test.sh: New test for these files.
+	* run-unstrip-n.sh: Update expected output.  New test for these files.
+	* test-core-lib.so.bz2: New file.
+	* test-core.core.bz2: New file.
+	* test-core.exec.bz2: New file.
+
+2013-05-03  Mark Wielaard  <mjw@redhat.com>
+
+	* testfilenolines.bz2: New test file.
+	* Makefile.am (EXTRA_DIST): Add testfilenolines.bz2.
+	* run-get-lines.sh: Run testrun_compare on testfilenolines.
+
+2013-04-30  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* dwfl-report-elf-align.c: Use false add_p_vaddr for dwfl_report_elf.
+
+2013-04-29  Mark Wielaard  <mjw@redhat.com>
+
+	* test-subr.sh: Don't use pushd, just cd into test-dir.
+	(exit_cleanup): Don't use popd, just cd .. to get out.
+
+2013-04-27  Mark Wielaard  <mjw@redhat.com>
+
+	* test-subr.sh (exit_cleanup): New function.
+	(trap): Use exit_cleanup as argument.
+	* run-native-test.sh (native_exit): New function.
+	(trap): For EXIT (0) use native_exit as argument.
+
+2013-04-27  Mark Wielaard  <mjw@redhat.com>
+
+	* update1.c (main): Use unique tempfile name and unlink file.
+	* update2.c (main): Likewise.
+	* update3.c (main): Likewise.
+	* update4.c (main): Use unique tempfile name.
+
+2013-04-27  Mark Wielaard  <mjw@redhat.com>
+
+	* run-alldts.sh: Add testfile-alldts to tempfiles.
+	* run-elf_cntl_gelf_getshdr.sh: Add test_shdr.out to tempfiles.
+	* run-macro-test.sh: Add readelf.macros.out to tempfiles.
+	* run-strip-reloc.sh: Add readelf.out, readelf.out1, readelf.out2
+	and out.stripped1, out.debug1, out.stripped2, out.debug2 to tempfiles.
+
+2013-04-26  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (installed_TESTS_ENVIRONMENT): Export environment,
+	remove wrapper.
+	(TESTS_ENVIRONMENT): Likewise.
+	(installed_LOG_COMPILER): New variable defining wrapper.
+	(LOG_COMPILER): Likewise.
+	* run-*.sh: Fixup location of input and output files.
+	* test-subr.sh: Create test_dir, pushd to execute test in.
+	(trap): Remove test_dir.
+	(testfiles): Use abs_srcdir.
+	(installed_testrun): Match on abs_builddir or abs_top_builddir.
+	(self_test_files): Adjust path.
+
+2013-04-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am: Use AM_CPPFLAGS instead of INCLUDES.
+
+2013-03-25  Mark Wielaard  <mjw@redhat.com>
+
+	* run-readelf-aranges.sh: New test.
+	* testfilefoobarbaz.bz2: New test file.
+	* Makefile.am (TESTS): Add run-readelf-aranges.sh.
+	(EXTRA_DIST): Add run-readelf-aranges.sh and testfilefoobarbaz.bz2.
+
+2013-03-25  Mark Wielaard  <mjw@redhat.com>
+
+	* run-readelf-dwz-multi.sh: Expect high_pc also as address.
+
+2013-03-20  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add dwfl-report-elf-align.
+	(TESTS): Add run-dwfl-report-elf-align.sh.
+	(EXTRA_DIST): Add run-dwfl-report-elf-align.sh and
+	testfile-dwfl-report-elf-align-shlib.so.bz2 .
+	(dwfl_report_elf_align_LDADD): New.
+	* dwfl-report-elf-align.c: New file.
+	* run-dwfl-report-elf-align.sh: New file.
+	* testfile-dwfl-report-elf-align-shlib.so.bz2: New file.
+
+2013-03-12  Mark Wielaard  <mjw@redhat.com>
+
+	* run-dwfllines.sh: New test.
+	* dwfllines.c: New test program.
+	* Makefile.am (TESTS): Add run-dwfllines.sh.
+	(EXTRA_DIST): Likewise.
+	(dwfllines_LDADD): New variable.
+
+2013-02-22  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): Remove run-readelf-s.sh and run-dwflsyms.sh.
+	(LZMA): Add run-readelf-s.sh and run-dwflsyms.sh to TESTS.
+
+2013-02-15  Mark Wielaard  <mjw@redhat.com>
+
+	* testfile-dwzstr.bz2: New testfile.
+	* testfile-dwzstr.multi.bz2: Likewise.
+	* run-readelf-dwz-multi.sh: Add readelf testfile-dwzstr test.
+	* Makefile.am (EXTRA_DIST): Add testfile-dwzstr.bz2 and
+	testfile-dwzstr.multi.bz2.
+
+2013-01-30  Mark Wielaard  <mjw@redhat.com>
+
+	* testfileloc.bz2: New testfile.
+	* run-readelf-loc.sh: New test.
+	* Makefile.am (TESTS): Add run-readelf-loc.sh.
+	(EXTRA_DIST): Add run-readelf-loc.sh and testfileloc.bz2.
+
+2013-01-29  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* run-readelf-mixed-corenote.sh: New testcase for readelf -n of s390
+	and s390x core notes.
+	* testfile67.bz2: New file.
+	* testfile68.bz2: New file.
+	* Makefile.am (EXTRA_DIST): Add testfile67.bz2 and testfile68.bz2 .
+
+2013-01-23  Mark Wielaard  <mjw@redhat.com>
+
+	* testfilebasmin.bz2: New testfile.
+	* Makefile.am (EXTRA_DIST): Add testfilebasmin.bz2.
+	* run-readelf-s.sh: Test testfilebasmin.
+	* run-dwflsyms.sh: Likewise.
+
+2013-01-16  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add dwflsyms.
+	(TESTS): Add run-readelf-s.sh and run-dwflsyms.sh.
+	(EXTRA_DIST): Add run-readelf-s.sh, testfilebazdbg.bz2,
+	testfilebazdyn.bz2, testfilebazmin.bz2, testfilebazdbg.debug.bz2,
+	testfilebazmdb.bz2, testfilebaztab.bz2 and run-dwflsyms.sh.
+	(dwflsyms_LDADD): New variable.
+
+2013-01-07  Roland McGrath  <roland@hack.frob.com>
+
+	* run-prelink-addr-test.sh: Use ln -snf.
+
+2012-12-03  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (valgrind_cmd): Add --run-libc-freeres=no.
+
+2012-11-29  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* run-addrname-test.sh: New test for PIE relocation.
+	* testfile70.core.bz2: New file.
+	* testfile70.exec.bz2: New file.
+	* Makefile.am (EXTRA_DIST): Add testfile70.core.bz2 and
+	testfile70.exec.bz2 .
+
+2012-10-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add testfile64.bz2, testfile65.bz2,
+	testfile69.core.bz2 and testfile69.so.bz2 .
+
+2012-10-17  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* run-addrname-test.sh: New test for DSO with build-id bias.
+	* testfile69.core.bz2: New file.
+	* testfile69.so.bz2: New file.
+
+2012-10-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* run-addrname-test.sh: New test for core vDSO bias.
+	* testfile65.bz2: New file.
+
+2012-10-10  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* run-addrname-test.sh: New test for symbol preferences.
+	* testfile64.bz2: New file.
+
+2012-10-01  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS_ENVIRONMENT): Define valgrind_cmd if USE_VALGRIND.
+	* test-wrapper.sh: Export VALGRIND_CMD if available.
+	* test-subr.sh (built_testrun): Use VALGRIND_CMD to invoke test prog.
+	(installed_testrun): Likewise.
+
+2012-09-24  Petr Machata  <pmachata@redhat.com>
+
+	* testfile63.bz2: New testfile.
+	* run-readelf-mixed-corenote.sh: New test.
+	* Makefile.am (TEST): Add run-readelf-mixed-corenote.sh.
+	(EXTRA_DIST): Add testfile63.bz2 and run-readelf-mixed-corenote.sh.
+
+2012-09-24  Petr Machata  <pmachata@redhat.com>
+
+	* testfile62.bz2: New testfile.
+	* run-readelf-vmcoreinfo.sh: New test.
+	* Makefile.am (TEST): Add run-readelf-vmcoreinfo.sh.
+	(EXTRA_DIST): Add testfile62.bz2 and run-readelf-vmcoreinfo.sh.
+
+2012-09-18  Petr Machata  <pmachata@redhat.com>
+
+	* testfile61.bz2: New testfile.
+	* run-allregs.sh: Run reg_test testfile61.
+	* Makefile.am (EXTRA_DIST): Add testfile61.bz2.
+
+2012-08-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add testfile60.bz2.
+
+2012-08-22  Jeff Kenton  <jkenton@tilera.com>
+
+	* testfile60.bz2: New testfile.
+	* run-allregs.sh: Run reg_test testfile60.
+
+2012-08-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): Only add run-readelf-dwz-multi.sh if
+	ENABLE_DWZ.
+
+2012-08-16  Mark Wielaard  <mjw@redhat.com>
+
+	* allregs.c (dwarf_encoding_string): Rewritten using known-dwarf
+	macros.
+	* show-die-info.c (tagnames): Removed.
+	(attrs): Removed.
+	(dwarf_tag_string): New function using known-dwarf macros.
+	(dwarf_attr_string): Likewise.
+	(handle): Call dwarf_tag_string and dwarf_attr_string instead.
+	* run-readelf-dwz-multi.sh: Expect language C89, not ISO C89.
+
+2012-06-27  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): Add run-readelf-dwz-multi.sh.
+	(EXTRA_DIST): Add run-readelf-dwz-multi.sh,
+	libtestfile_multi_shared.so.bz2, testfile_multi.dwz.bz2 and
+	testfile_multi_main.bz2.
+	* run-readelf-dwz-multi.sh: New test.
+	* libtestfile_multi_shared.so.bz2: New testfile.
+	* testfile_multi.dwz.bz2: New testifle.
+	* testfile_multi_main.bz2: New testifle.
+
+2012-08-01  Petr Machata  <pmachata@redhat.com>
+
+	* run-test-archive64.sh: New test.
+	* testarchive64.a.bz2: New testfile.
+	* Makefile.am (TESTS): Add run-test-archive64.sh.
+	(EXTRA_DIST): Likewise.
+
+2012-08-01  Mark Wielaard  <mjw@redhat.com>
+
+	* run-nm-self.sh: New test.
+	* run-readelf-self.sh: Likewise.
+	* test-subr.sh (testrun_on_self_quiet): New function.
+	* Makefile.am (TESTS): Add run-nm-self.sh and run-readelf-self.sh.
+	(EXTRA_DIST): Likewise.
+
+2012-08-01  Mark Wielaard  <mjw@redhat.com>
+
+	* test-subr.sh (self_test_files): New list of files.
+	(testrun_on_self): New function.
+	* run-elflint-self.sh: Use testrun_on_self.
+
+2012-07-19  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (check_PROGRAMS): Add test-elf_cntl_gelf_getshdr.
+	(TESTS): Add run-elf_cntl_gelf_getshdr.sh.
+	(EXTRA_DIST): Likewise.
+	(test_elf_cntl_gelf_getshdr_LDADD): New.
+	test-elf_cntl_gelf_getshdr.c: New test program.
+	run-elf_cntl_gelf_getshdr.sh: New test script.
+
+2012-07-19  Mark Wielaard  <mjw@redhat.com>
+
+	* run-elflint-self.sh: runtests on ../backends/*so files.
+
+2012-07-19  Mark Wielaard  <mjw@redhat.com>
+
+	* run-unstrip-n.sh: test_cleanup.
+	* Makefile.am (EXTRA_DIST): Add testcore-rtlib-ppc.bz2.
+
+2012-07-11  Mark Wielaard  <mjw@redhat.com>
+
+	* run-readelf-macro.sh: New test.
+	* testfilemacro.bz2: New testfile.
+	* Makefile.am (TESTS): Add run-readelf-macro.sh.
+	(EXTRA_DIST): Add run-readelf-macro.sh and testfilemacro.bz2.
+
+2012-06-27  Mark Wielaard  <mjw@redhat.com>
+
+	* run-readelf-gdb-index.sh: New test.
+	* testfilegdbindex5.bz2: New testfile.
+	* testfilegdbindex7.bz2: Likewise.
+	* Makefile.am (TESTS): Add run-readelf-gdb-index.sh.
+	(EXTRA_DIST): run-readelf-gdb_index.sh, testfilegdbindex5.bz2 and
+	testfilegdbindex7.bz2.
+
+2012-07-17  Mark Wielaard  <mjw@redhat.com>
+
+	* testcore-rtlib-ppc.bz2: New testfile.
+	* run-unstrip-n.sh: Check new ppc core testfile.
+
+2012-06-26  Mike Frysinger  <vapier@gentoo.org>
+
+	* Makefile.am (check_PROGRAMS): Rename from noinst_PROGRAMS.
+
+2012-06-26  Mark Wielaard  <mjw@redhat.com>
+
+	* run-macro-test.sh: New test.
+	* testfile-macinfo.bz2: New testfile.
+	* testfile-macros.bz2: Likewise.
+
+2012-05-07  Mark Wielaard  <mjw@redhat.com>
+
+	* low_high_pc.c: Use proper inttypes in printf formats.
+
+2012-05-11  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS_ENVIRONMENT): Set LC_ALL and LANG to C.
+
+2012-05-07  Mark Wielaard  <mjw@redhat.com>
+
+	* low_high_pc.c: Allow highpc == lowpc for CU DIEs for buggy GCC.
+
+2012-04-27  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): Add run-low_high_pc.sh
+	(EXTRA_DIST): Add run-low_high_pc.sh and testfile_low_high_pc.bz2
+	(noinst_PROGRAMS): Add low_high_pc.
+	(low_high_pc_LDADD): New variable.
+	* low_high_pc.c: New test.
+
+2012-04-26  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Remove run-show-ciefde.sh.
+	* run-show-ciefde.sh: Removed old libdwarf test.
+	* show-ciefde.c: Likewise.
+
+2012-04-02  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): Add run-unstrip-n.sh.
+	(EXTRA_DIST): Add testcore-rtlib.bz2 and run-unstrip-n.sh.
+	* run-unstrip-n.sh: New test.
+	* testcore-rtlib.bz2: New testfile.
+
+2012-04-02  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): Add run-readelf-d.sh.
+	(EXTRA_DIST): Add testlib_dynseg.so.bz2 and run-readelf-d.sh.
+	* run-readelf-d.sh: New test.
+	* run-elflint-test.sh: Check new testfile.
+
+2012-03-21  Tom Tromey  <tromey@redhat.com>
+
+	* typeiter.c: New file.
+	* run-typeiter.sh: New file.
+	* testfile59.bz2: New file.
+	* Makefile.am (noinst_PROGRAMS): Add typeiter.
+	(TESTS): Add run-typeiter.sh.
+	(EXTRA_DIST): Add run-typeiter.sh, testfile59.bz2.
+	(typeiter_LDADD): New variable.
+
+2012-02-21  Kurt Roeckx  <kurt@roeckx.be>
+
+	* run-alldts.sh: testrun ./alldts.
+
+2012-02-21  Roland McGrath  <roland@hack.frob.com>
+
+	* test-wrapper.sh: Add ${libdir}/elfutils to LD_LIBRARY_PATH.
+	* test-subr.sh (installed_testrun): Likewise.
+
+2012-01-18  Roland McGrath  <roland@hack.frob.com>
+
+	* asm-tst4.c (main): Don't set LD_LIBRARY_PATH in system invocation;
+	it will have been inherited correctly from the test harness.
+	* asm-tst5.c (main): Likewise.
+	* asm-tst6.c (main): Likewise.
+	Reported by Serge Pavlov <serge.pavlov.at.gnu@gmail.com>.
+
+2011-07-09  Roland McGrath  <roland@hack.frob.com>
+
+	* sha1-tst.c: File removed.
+	* Makefile.am (noinst_PROGRAMS, TESTS): Remove it.
+	(sha1_tst_LDADD): Variable removed.
+
+	* md5-sha1-test.c: New file.
+	* Makefile.am [!STANDALONE] (noinst_PROGRAMS, TESTS): Add it.
+	(md5_sha1_test_LDADD): New variable.
+
+2011-05-30  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add run-readelf-twofiles.sh and
+	run-rerequest_tag.sh
+
+2011-05-24  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add hello_s390.ko.bz2.
+	* run-strip-reloc.sh: Add hello_s390.ko testcase.
+	* hello_s390.ko.bz2: New test file.
+
+2011-05-23  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (TESTS): Add run-strip-reloc.sh.
+	(EXTRA_DIST): Add run-strip-reloc.sh, hello_i386.ko.bz2
+	hello_x86_64.ko.bz2 and hello_ppc64.ko.bz2
+	* run-strip-reloc.sh: New test.
+	* hello_i386.ko.bz2: New test file.
+	* hello_x86_64.ko.bz2: Likewise.
+	* hello_ppc64.ko.bz2: Likewise.
+
+2011-05-18  Mark Wielaard  <mjw@redhat.com>
+
+	* run-strip-groups.sh: New test.
+	* testfile58.bz2: New test file.
+	* Makefile.am (EXTRA_DIST): Add testfile58.bz2.
+	(TESTS): Add run-strip-groups.sh.
+	(EXTRA_DIST): Likewise.
+
+2011-03-28  Marek Polacek  <mpolacek@redhat.com>
+
+	* alldts.c: New file.
+	* run-alldts.sh: Use it.
+	* Makefile.am (TESTS, EXTRA_DIST, noinst_PROGRAMS): Add them.
+	(alldts_LDADD): New variable.
+
+2011-03-02  Marek Polacek  <mpolacek@redhat.com>
+
+	* dwarf-getstring.c: New test.
+	* run-dwarf-getstring.sh: And its wrapper.
+	* Makefile.am (EXTRA_DIST): Add and update all.
+
+2011-02-27  Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* Makefile.am (TESTS): Add run-readelf-twofiles.sh.
+	* run-readelf-twofiles.sh: New file.
+
+2011-02-25  Mark Wielaard  <mjw@redhat.com>
+
+	* Makefile.am (BUILD_RPATH): Be consistent in naming.
+
+2011-02-02  Josh Stone  <jistone@redhat.com>
+
+	* run-prelink-addr-test.sh: Add testfile55, 32 and 64-bit.
+	* testfile55-64.bz2, testfile55-64.debug.bz2,
+	testfile55-64.prelink.bz2, testfile55-32.bz2,
+	testfile55-32.debug.bz2, testfile55-32.prelink.bz2: New.
+	* Makefile.am (EXTRA_DIST): Add and update all.
+
+2011-01-12  Roland McGrath  <roland@redhat.com>
+
+	* run-prelink-addr-test.sh: Make symlinks to find .debug files
+	corresponding to .noshdrs files.
+
+2011-01-11  Josh Stone  <jistone@redhat.com>
+
+	* run-prelink-addr-test.sh: Add testfile54, 32 and 64-bit.
+	* testfile54-32.so.bz2, testfile54-32.so.debug.bz2,
+	testfile54-32.prelink.so.bz2, testfile54-32.noshdrs.so.bz2,
+	testfile54-64.so.bz2, testfile54-64.so.debug.bz2,
+	testfile54-64.prelink.so.bz2, testfile54-64.noshdrs.so.bz2: New.
+	* Makefile.am (EXTRA_DIST): Add and update all.
+
+	* run-prelink-addr-test.sh: Run 32 and 64-bit testfile53 tests.
+	* testfile53.bz2, testfile53.debug.bz2,
+	testfile53.prelink.bz2: Deleted, so...
+	* testfile53-64.bz2, testfile53-64.debug.bz2,
+	testfile53-64.prelink.bz2: Recreated with 64-bit names.
+	* testfile53-32.bz2, testfile53-32.debug.bz2,
+	testfile53-32.prelink.bz2: New in 32-bit.
+	* Makefile.am (EXTRA_DIST): Add and update all.
+
+	* run-prelink-addr-test.sh: Run 32 and 64-bit testfile52 tests.
+	* testfile52.so.bz2, testfile52.so.debug.bz2,
+	testfile52.prelink.so.bz2: Deleted, so...
+	* testfile52-32.so.bz2, testfile52-32.so.debug.bz2,
+	testfile52-32.prelink.so.bz2: Recreated with 32-bit names.
+	* testfile52-32.noshdrs.so.bz2: New data file, stripped of headers.
+	* testfile52-64.so.bz2, testfile52-64.so.debug.bz2,
+	testfile52-64.prelink.so.bz2, testfile52-64.noshdrs.so.bz2: New files.
+	* Makefile.am (EXTRA_DIST): Add and update all.
+
+2011-01-10  Josh Stone  <jistone@redhat.com>
+
+	* run-prelink-addr-test.sh: New test for prelinked addrs.
+	* Makefile.am (TESTS, EXTRA_DIST): Add it.
+	* testfile52.so.bz2, testfile52.so.debug.bz2: New data files.
+	* testfile52.prelink.so.bz2: New data file, shows REL->RELA.
+	* testfile53.bz2, testfile53.debug.bz2: New data files.
+	* testfile53.prelink.bz2: New data file, shows ET_EXEC remap.
+	* Makefile.am (EXTRA_DIST): Add them.
+
+2010-06-04  Roland McGrath  <roland@redhat.com>
+
+	* run-unstrip-test.sh: Also test modifying the file in place.
+
+2010-04-22  Roland McGrath  <roland@redhat.com>
+
+	* addrcfi.c (handle_cfi): Fix function name in error message.
+	Use dwarf_errmsg, not dwfl_errmsg, after dwarf_cfi_addrframe.
+
+2010-04-14  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add run-test-flag-nobits.sh here too.
+
+2010-04-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* msg_tst.c: Adjust expected error message.
+
+2010-04-01  Petr Machata  <pmachata@redhat.com>
+
+	* test-flag-nobits.c: New test.
+	* run-test-flag-nobits.sh: And its wrapper.
+	* Makefile.am (noinst_PROGRAMS, TESTS): Add them.
+	(test_flag_nobits_LDADD): New variable.
+
+2010-02-15  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am: Use config/eu.am for common stuff.
+
+	* asm-tst9.c (main): Rename local to avoid shadowing another local.
+
+2009-07-22  Roland McGrath  <roland@redhat.com>
+
+	* addrcfi.c: Update dwarf_frame_{cfa,register} calling convention.
+
+2009-07-08  Roland McGrath  <roland@redhat.com>
+
+	* addrcfi.c: New file.
+	* Makefile.am (noinst_PROGRAMS): Add it.
+	(addrcfi_LDADD): New variable.
+
+2009-05-07  Petr Machata  <pmachata@redhat.com>
+
+	* testfile51.bz2: New data file.
+	* dwarf-getmacros.c: New test core.
+	* run-dwarf-getmacros.sh: New test wrapper.
+	* Makefile.am (TESTS, EXTRA_DIST, noinst_PROGRAMS): Add them.
+	(dwarf_getmacros_LDADD): New variable.
+
+2009-04-23  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile [BUILD_STATIC] (libdw): Add $(zip_LIBS).
+	(rdwrmmap_LDADD): Add $(libmudflap).
+
+2009-04-21  Roland McGrath  <roland@redhat.com>
+
+	* testfile50.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add it.
+	* run-dwfl-addr-sect.sh: Add a case using it.
+
+2008-12-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: Add tests for dppd, dpps, insertps, movntdqa,
+	mpsadbw, packusdw, pblendvb, pblendw, pcmpeqq, pcmpestri, pcmpestrm,
+	pcmpistri, pcmpistrm, pcmpgtq, phminposuw, pinsrb, pinsrd, pmaxsb,
+	pmaxsd, pmaxud, pmaxuw, pminsb, pminsd, pminud, pminuw, pmovsxbw,
+	pmovsxbd, pmovsxbq, pmovsxwd, pmovsxwq, pmovsxdq, pmovsxbw, pmovsxbd,
+	pmovsxbq, pmovsxwd, pmovsxwq, pmovsxdq, pmuldq, pmulld, popcnt, ptest,
+	roundss, roundps, roundpd, and roundsd.
+	* testfile45.S.bz2: Likewise.
+	* testfile44.expect.bz2: Adjust accordingly.
+	* testfile45.expect.bz2: Likewise.
+
+	* testfile44.S.bz2: Add tests for blendvpd and blendvps.
+	* testfile45.S.bz2: Likewise.
+	* testfile44.expect.bz2: Adjust accordingly.
+	* testfile45.expect.bz2: Likewise.
+
+2008-12-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: Add tests for blendpd and blendps.
+	* testfile45.S.bz2: Likewise.
+	* testfile44.expect.bz2: Adjust accordingly.
+	* testfile45.expect.bz2: Likewise.
+
+2008-12-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: Add tests for AMD 3DNOW.
+	* testfile45.S.bz2: Likewise.
+	* testfile44.expect.bz2: Adjust accordingly.
+	* testfile45.expect.bz2: Likewise.
+
+2008-11-26  Roland McGrath  <roland@redhat.com>
+
+	* dwfl-bug-getmodules.c: New file.
+	* Makefile.am (noinst_PROGRAMS): Add it.
+	(dwfl_bug_getmodules_LDADD): New variable.
+
+2008-09-10  Roland McGrath  <roland@redhat.com>
+
+	* test-subr.sh (LC_ALL): Export it set to "C".
+	* run-dwfl-addr-sect.sh: Don't do it here.
+	* run-strings-test.sh: Likewise.
+
+2008-08-21  Denys Vlasenko  <dvlasenk@redhat.com>
+
+	* run-addrname-test.sh: Add a new case.
+	* testfile49.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add it.
+
+2008-04-10  Roland McGrath  <roland@redhat.com>
+
+	* testfile48.bz2, testfile48.bz2.debug: New data files.
+	* Makefile.am (EXTRA_DIST): Add them.
+	* run-strip-test8.sh: Use them.
+
+	* testfile16.bz2, testfile16.debug.bz2: Replace data files.
+
+	* run-strip-test.sh: Fail if stripped output has ".debug_*" sections.
+	* run-strip-test8.sh: New file.
+	* testfile47.bz2: New data file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add them.
+
+2008-03-31  Roland McGrath  <roland@redhat.com>
+
+	* run-early-offscn.sh: New file.
+	* early-offscn.c: New file.
+	* Makefile.am (noinst_PROGRAMS, TESTS, EXTRA_DIST): Add them.
+	(early_offscn_LDADD): New variable.
+
+2008-03-19  Roland McGrath  <roland@redhat.com>
+
+	* run-addrname-test.sh: Add a new case.
+
+2008-02-22  Roland McGrath  <roland@redhat.com>
+
+	* run-elflint-test.sh: Typo fix.
+
+2008-02-21  Roland McGrath  <roland@redhat.com>
+
+	* run-disasm-x86.sh: Use uname instead of arch, keep tools required
+	for the build down to minimum.
+	* run-disasm-x86-64.sh: Likewise.
+
+2008-02-20  Roland McGrath  <roland@redhat.com>
+
+	* testfile46.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add it.
+	* run-elflint-test.sh: Test on it.
+
+2008-02-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Hook up sha1-tst.c.
+	* sha1-tst.c: New file.
+
+2008-01-21  Roland McGrath  <roland@redhat.com>
+
+	* testfile45.S.bz2: Add tests for cltq, cqto.
+	* testfile45.expect.bz2: Adjust.
+
+2008-01-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile45.S.bz2: Add more tests.
+	* testfile45.expect.bz2: Adjust.
+
+2008-01-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile45.expect.bz2: Adjust for adding of address for %rip based
+	address mode.
+
+2008-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile45.S.bz2: Add more tests.
+	* testfile45.expect.bz2: Adjust.
+
+2008-01-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (TESTS): Add run-disasm-x86-64.sh.
+	(EXTRA): Add testfile45.S.bz2, testfile45.expect.bz2,
+	run-disasm-x86-64.sh.
+	* run-disasm-x86-64.sh: New file.
+	* testfile45.S.bz2: New file.
+	* testfile45.expect.bz2: New file.
+	* testfile44.S.bz2: New tests.
+	* testfile44.expect.bz2: Adjust.
+
+2008-01-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: New tests.
+	* testfile44.expect.bz2: Adjust.
+
+2008-01-04  Roland McGrath  <roland@redhat.com>
+
+	* dwfl-bug-fd-leak.c (main): Add a cast.
+
+2008-01-03  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: New tests.
+	* testfile44.expect.bz2: Adjust.
+
+2008-01-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* line2addr.c: Use %m modifier instead of %a to appease gcc.
+
+2008-01-01  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: New tests.
+	* testfile44.expect.bz2: Adjust.
+
+2007-12-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: New tests.
+	* testfile44.expect.bz2: Adjust.
+
+2007-12-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: New tests.
+	* testfile44.expect.bz2: Adjust.
+
+2007-12-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.s.bz2: New tests.
+	* testfile44.expect.bz2: Adjust.
+
+2007-12-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: New tests.
+	* testfile44.expect.bz2: Adjust.
+
+2007-12-27  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: New tests.
+	* testfile44.expect.bz2: Adjust.
+
+2007-12-26  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: New tests.
+	* testfile44.expect.bz2: Adjust
+
+2007-12-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile44.S.bz2: More tests.
+	* testfile44.expect.bz2: Adjust appropriately.
+
+2007-12-19  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (TESTS): Add run-disasm.sh.
+	(EXTRA_DIST): Add run-disasm.sh, testfile44.S.bz2, and
+	testfile44.expect.bz2.
+	* run-disasm.sh: New file.
+	* testfile44.S.bz2: New file.
+	* testfile44.expect.bz2: New file.
+
+2007-12-15  Roland McGrath  <roland@redhat.com>
+
+	* run-allregs.sh: Change expected output for powerpc spefscr.
+
+2007-10-20  Roland McGrath  <roland@redhat.com>
+
+	* run-dwfl-addr-sect.sh: Change expected output, no errors.
+
+2007-10-19  Roland McGrath  <roland@redhat.com>
+
+	* dwfl-addr-sect.c (handle_address): Return int.
+	Don't exit on error, just return nonzero.
+	(main): Collect results.
+	* run-dwfl-addr-sect.sh: New file.
+	* testfile43.bz2: New data file.
+	* Makefile.am (EXTRA_DIST, TESTS): Add them.
+
+2007-10-18  Roland McGrath  <roland@redhat.com>
+
+	* run-allregs.sh: Update expected ppc output for vrsave/vscr.
+
+2007-10-16  Roland McGrath  <roland@redhat.com>
+
+	* test-subr.sh (remove_files): Don't pass -Bb to diff.
+
+2007-10-09  Roland McGrath  <roland@redhat.com>
+
+	* dwflmodtest.c (print_module): Don't use %p in output.
+	* run-dwfl-bug-offline-rel.sh: Updated expected output.
+
+2007-10-08  Roland McGrath  <roland@redhat.com>
+
+	* testfile42.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add it.
+	* run-elflint-test.sh: New test on that file.
+
+2007-10-04  Roland McGrath  <roland@redhat.com>
+
+	* run-readelf-test4.sh: New file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add it.
+
+2007-10-03  Roland McGrath  <roland@redhat.com>
+
+	* run-readelf-test3.sh: New file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add it.
+
+2007-10-01  Roland McGrath  <roland@redhat.com>
+
+	* run-readelf-test2.sh: New file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add it.
+
+2007-09-11  Roland McGrath  <roland@redhat.com>
+
+	* run-addrname-test.sh: Add a new case.
+	* testfile41.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add it.
+
+2007-08-23  Roland McGrath  <roland@redhat.com>
+
+	* run-allregs.sh: Update expected x86-64 output for %rflags.
+
+2007-08-12  Roland McGrath  <roland@redhat.com>
+
+	* run-strip-test7.sh: New file.
+	* testfile39.bz2: New data file.
+	* testfile40.bz2: New data file.
+	* testfile40.debug.bz2: New data file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add them.
+
+2007-08-09  Roland McGrath  <roland@redhat.com>
+
+	* dwfl-bug-report.c: Fix header inclusion.
+
+2007-08-08  Roland McGrath  <roland@redhat.com>
+
+	* run-addrname-test.sh: Add a new case using addr2line -S.
+	* testfile38.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add it.
+
+2007-07-16  Roland McGrath  <roland@redhat.com>
+
+	* dwfl-bug-report.c: New file.
+	* Makefile.am (noinst_PROGRAMS, TESTS): Add it.
+	(dwfl_bug_report_LDADD): New variable.
+
+2007-06-06  Roland McGrath  <roland@redhat.com>
+
+	* run-unstrip-test.sh: Declare testfile.unstrip for removal.
+
+2007-06-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add missing line continuation and
+	testfile37.bz and testfile37.debug.bz2.
+
+2007-05-23  Roland McGrath  <roland@redhat.com>
+
+	* run-allregs.sh: Update expected Alpha results.
+
+2007-05-18  Roland McGrath  <roland@redhat.com>
+
+	* run-strip-test4.sh (stripped, debugfile): Use new reference files.
+	* testfile37.bz2: New data file.
+	* testfile37.debug.bz2: New data file.
+	* run-unstrip-test2.sh: New file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add them.
+
+2007-05-10  Roland McGrath  <roland@redhat.com>
+
+	* run-dwfl-bug-offline-rel.sh: New file.
+	* testfile36.bz2: New data file.
+	* testfile36.debug.bz2: New data file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add them.
+
+2007-04-28  Roland McGrath  <roland@redhat.com>
+
+	* run-strip-test6.sh (stripped, debugfile): Use new reference files.
+	* testfile35.bz2: New data file.
+	* testfile35.debug.bz2: New data file.
+	* run-unstrip-test.sh: New file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add them.
+
+	* run-strip-test.sh: Do all elflint and cmp runs even when some fail.
+
+2007-04-26  Roland McGrath  <roland@redhat.com>
+
+	* run-elflint-self.sh: Run all tests even if one fails.
+
+	* run-allregs.sh: Add expected output for alpha.
+
+2007-04-24  Roland McGrath  <roland@redhat.com>
+
+	* run-strip-test.sh: When we saved the debug info, test unstrip too.
+
+2007-04-22  Roland McGrath  <roland@redhat.com>
+
+	* run-allregs.sh: Update expected register info.
+
+2007-04-16  Roland McGrath  <roland@redhat.com>
+
+	* dwfl-addr-sect.c: New file.
+	* Makefile.am (noinst_PROGRAMS): Add it.
+	(dwfl_addr_sect_LDADD): New variable.
+
+2007-04-05  Roland McGrath  <roland@redhat.com>
+
+	* get-files.c: Test dwarf_getsrcdirs.
+	* run-get-files.sh: Update expected output.
+
+2007-04-01  Roland McGrath  <roland@redhat.com>
+
+	* run-allregs.sh: Updated expected output for x86_64.
+
+2007-03-04  Roland McGrath  <roland@redhat.com>
+
+	* dwfl-bug-fd-leak.c: New file.
+	* Makefile.am (noinst_PROGRAMS, TESTS): Add it.
+	(dwfl_bug_fd_leak_LDADD): New variable.
+
+	* dwflmodtest.c: Test dwfl_getmodules before and after getdwarf,
+	show what files have been located.
+
+2007-02-02  Roland McGrath  <roland@redhat.com>
+
+	* run-addrname-test.sh: New file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add it.
+	* testfile34.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add it.
+
+2007-01-20  Roland McGrath  <roland@redhat.com>
+
+	* testfile33.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add it.
+	* run-elflint-test.sh: Test on it too.
+
+2007-01-18  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (CFLAGS): Don't molest it.
+
+2007-01-11  Roland McGrath  <roland@redhat.com>
+
+	* testfile32.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add it.
+	* run-elflint-test.sh: Test on it too.
+
+2007-02-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* arls.c: New file.
+	* Makefile (noinst_PROGRAMS): Add arls.
+
+	* run-ranlib-test2.sh: Fix type in comment.
+
+2007-01-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* run-elflint-self.sh (runtest): Show which file has the problem.
+
+2007-01-10  Roland McGrath  <roland@redhat.com>
+
+	* dwfl-bug-addr-overflow.c: New file.
+	* Makefile.am (TESTS): Add it.
+	(dwfl_bug_addr_overflow_LDADD): New variable.
+
+2006-12-17  Roland McGrath  <roland@redhat.com>
+
+	* msg_tst.c (libelf_msgs): Fix ELF_E_INVALID_PHDR msg.
+
+2006-09-05  Roland McGrath  <roland@redhat.com>
+
+	* run-strings-test.sh: Export LC_ALL=C for the test.
+
+2006-08-29  Roland McGrath  <roland@redhat.com>
+
+	* run-arextract.sh: Use testrun, tempfiles functions from test-subr.sh.
+	* run-arsymtest.sh: Likewise.
+
+	* run-native-test.sh (native.c compilation): Add some braces.
+
+2006-08-22  Roland McGrath  <roland@redhat.com>
+
+	* allregs.c (dwarf_encoding_string): New function, swiped from readelf.
+	(struct reginfo): New members bits, type.
+	(one_register, match_register): Update to take new args,
+	record and display new info.
+	(main): Display new info.
+	* run-allregs.sh: Update expected results.
+
+2006-08-03  Roland McGrath  <roland@redhat.com>
+
+	* run-allregs.sh: Add sparc cases.
+	* testfile30.bz2: New data file.
+	* testfile31.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add them.
+
+2006-07-21  Roland McGrath  <roland@redhat.com>
+
+	* allregs.c (struct reginfo): Increase size of name.
+	(one_register): Assert that it's big enough.
+
+2006-04-04  Roland McGrath  <roland@redhat.com>
+
+	* run-bug1-test.sh: Test a second case, to cover both byte orders.
+	* testfile29.bz2: New file.
+	* testfile29.rdwr.bz2: New file.
+	* Makefile.am (EXTRA_DIST): Add them.
+
+2006-04-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Add rules to run run-bug1-test.sh.
+	* rdwrmmap.c: New file.
+	* run-bug1-test.sh: New file.
+	* testfile28.bz2: New file.
+	* testfile28.rdwr.bz2: New file.
+
+2006-03-09  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (AM_LDFLAGS): Define to pass -rpath-link.
+
+2006-03-01  Roland McGrath  <roland@redhat.com>
+
+	* show-die-info.c (tagnames, attrs): Update name tables for dwarf.h
+	changes matching 3.0 spec.
+
+2006-01-13  Roland McGrath  <roland@redhat.com>
+
+	* run-native-test.sh: Do kill -9 and reap explicitly at end, since
+	bash 3.1 whines when it's done in the trap 0 handler.
+
+2006-01-11  Roland McGrath  <roland@redhat.com>
+
+	* testfile26.bz2: New data file.
+	* testfile27.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add them.
+	* run-allregs.sh: Test s390 data.
+
+2005-12-14  Roland McGrath  <roland@redhat.com>
+
+	* run-native-test.sh: Redirect output from native test process.
+
+2005-12-13  Roland McGrath  <roland@redhat.com>
+
+	* allregs.c (main): Fail if we find no registers.
+
+	* run-native-test.sh: New file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add it.
+
+2005-12-10  Ulrich Drepper  <drepper@redhat.com
+
+	* run-readelf-test1.sh: New file.
+	* Makefile.am (TESTS): Add run-readelf-test1.sh.
+	(EXTRA_DIST): Likewise.
+
+2005-12-07  Roland McGrath  <roland@redhat.com>
+
+	* ecp.c (main): Use elf_end to clean up.
+
+2005-11-25  Roland McGrath  <roland@redhat.com>
+
+	* coverage.sh: Given -v argument, print names of unused files.
+
+	* addrscopes.c (main): Use dwfl_end before return.
+	* allregs.c (main): Likewise.
+	* find-prologues.c (main): Likewise.
+	* funcretval.c (main): Likewise.
+	* funcscopes.c (main): Likewise.
+	* line2addr.c (main): Likewise.
+
+	* run-allregs.sh: New file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add it.
+
+	* allregs.c: Use libdwfl wrapper instead of direct libebl calls.
+	* Makefile.am (allregs_LDADD): Updated.
+
+	* allregs.c: New file.
+	* Makefile.am (noinst_PROGRAMS): Add it.
+	(allregs_LDADD): New variable.
+
+2005-11-18  Roland McGrath  <roland@redhat.com>
+
+	* test-subr.sh (installed_testrun): Treat /usr/lib64 like /usr/lib.
+	* test-wrapper.sh: Likewise.
+
+2005-11-17  Roland McGrath  <roland@redhat.com>
+
+	* Makefile.am (installed_TESTS_ENVIRONMENT): Set libdir, bindir in
+	environment for test-wrapper.sh.
+	* test-wrapper.sh: Set LD_LIBRARY_PATH from ${libdir} if not /usr/lib.
+	* test-subr.sh (installed_testrun): Likewise.
+	Use explicit path in ${bindir}.
+
+	* Makefile.am (installcheck-local): Fix typo in last change.
+
+2005-11-16  Roland McGrath  <roland@redhat.com>
+
+	* configure.ac: New file, for standalone build/dist of test suite.
+	* Makefile.am [!STANDALONE] (INCLUDES): Don't define it.
+	(asm_TESTS): New variable, broken out of ...
+	(TESTS): ... here.  Also remove msg_tst.
+	[!STANDALONE] (TESTS, noinst_PROGRAMS): Add in $(asm_TESTS), msg_tst.
+	(installed_TESTS_ENVIRONMENT): New variable.
+	[STANDALONE] (TESTS_ENVIRONMENT): Use that.
+	[!STANDALONE] (installcheck-local): Likewise.
+	[STANDALONE] (libdw, libelf, libasm, libebl): Define using -lfoo.
+	* addrscopes.c: Include <config.h>.
+	Use ELFUTILS_HEADER macro in #include of installed elfutils/ headers.
+	* allfcts.c: Likewise.
+	* asm-tst1.c: Likewise.
+	* asm-tst2.c: Likewise.
+	* asm-tst3.c: Likewise.
+	* asm-tst4.c: Likewise.
+	* asm-tst5.c: Likewise.
+	* asm-tst6.c: Likewise.
+	* asm-tst7.c: Likewise.
+	* asm-tst8.c: Likewise.
+	* asm-tst9.c: Likewise.
+	* dwflmodtest.c: Likewise.
+	* find-prologues.c: Likewise.
+	* funcscopes.c: Likewise.
+	* get-aranges.c: Likewise.
+	* get-files.c: Likewise.
+	* get-lines.c: Likewise.
+	* get-pubnames.c: Likewise.
+	* line2addr.c: Likewise.
+	* newscn.c: Likewise.
+	* show-abbrev.c: Likewise.
+	* show-die-info.c: Likewise.
+	* update3.c: Likewise.
+	* update4.c: Likewise.
+	* funcretval.c: Likewise.
+
+	* dwflmodtest.c (print_instance): Don't use INTUSE.
+	(options): Don't use N_ macro.
+
+2005-11-15  Roland McGrath  <roland@redhat.com>
+
+	* coverage.sh: Look in backends.
+	* Makefile.am (BUILD_RPATH): Search ../backends, not ../libebl.
+	(TESTS_ENVIRONMENT): Likewise.
+
+	* funcretval.c (handle_function): Don't take DW_AT_type of FUNCDIE,
+	pass FUNCDIE direclty to dwfl_module_return_value_location.
+
+	* Makefile.am (BUILD_RPATH): New variable.
+	[TESTS_RPATH] (AM_LDFLAGS): Pass -rpath option using that value.
+	(tests_rpath): New variable.
+	(installcheck-local): Pass it to test-wrapper.sh.
+	* test-wrapper.sh: In "installed" format, take yes/no value
+	for elfutils_tests_rpath, which export.  When running a test
+	binary for installcheck, exit 77.
+	* test-subr.sh (installed_testrun): When running a test binary
+	for installcheck, exit 77 if $elfutils_tests_rpath = yes.
+
+2005-11-14  Roland McGrath  <roland@redhat.com>
+
+	* test-subr.sh: New file.
+	* test-wrapper.sh: New file.
+	* Makefile.am (EXTRA_DIST): Add them.
+	(AM_LDFLAGS): Variable removed.
+	(TESTS_ENVIRONMENT): New variable.
+	(installcheck-local): New target.
+	* run-addrscopes.sh: Use test-subr.sh.
+	* run-allfcts.sh: Likewise.
+	* run-ecp-test.sh: Likewise.
+	* run-ecp-test2.sh: Likewise.
+	* run-elflint-self.sh: Likewise.
+	* run-elflint-test.sh: Likewise.
+	* run-find-prologues.sh: Likewise.
+	* run-funcscopes.sh: Likewise.
+	* run-get-aranges.sh: Likewise.
+	* run-get-files.sh: Likewise.
+	* run-get-lines.sh: Likewise.
+	* run-get-pubnames.sh: Likewise.
+	* run-line2addr.sh: Likewise.
+	* run-ranlib-test.sh: Likewise.
+	* run-ranlib-test2.sh: Likewise.
+	* run-show-abbrev.sh: Likewise.
+	* run-show-ciefde.sh: Likewise.
+	* run-show-die-info.sh: Likewise.
+	* run-strings-test.sh: Likewise.
+	* run-strip-test.sh: Likewise.
+
+2005-11-13  Roland McGrath  <roland@redhat.com>
+
+	* funcretval.c: New file.
+	* Makefile.am (noinst_PROGRAMS): Add it.
+	(funcretval_LDADD): New variable.
+
+2005-11-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* line2addr.c (handle_module): Add missing parameter to printf.
+
+2005-10-27  Roland McGrath  <roland@redhat.com>
+
+	* allfcts.c (cb): Update for dwarf_func_* -> dwarf_decl_* changes.
+	* funcscopes.c (handle_function): Likewise.
+	* dwflmodtest.c (print_inline, print_func): Likewise.
+	* find-prologues.c (handle_function): Likewise.
+
+2005-10-27  Roland McGrath  <roland@redhat.com>
+
+	* run-find-prologues.sh: New file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add it.
+
+	* find-prologues.c (handle_function): Skip inlines.
+
+2005-10-25  Roland McGrath  <roland@redhat.com>
+
+	* find-prologues.c: New file.
+	* Makefile.am (noinst_PROGRAMS): Add it.
+	(find_prologues_LDADD): New variable.
+
+2005-09-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* run-strings-test.sh: Remove strings.out in the end.
+
+2005-08-31  Ulrich Drepper  <drepper@redhat.com>
+
+	* run-addrscopes.sh: Use correct exit code if test cannot be performed.
+	* run-allfcts.sh: Likewise.
+	* run-ecp-test.sh: Likewise.
+	* run-ecp-test2.sh: Likewise.
+	* run-elflint-test.sh: Likewise.
+	* run-funcscopes.sh: Likewise.
+	* run-get-aranges.sh: Likewise.
+	* run-get-files.sh: Likewise.
+	* run-get-lines.sh: Likewise.
+	* run-get-pubnames.sh: Likewise.
+	* run-line2addr.sh: Likewise.
+	* run-ranlib-test2.sh: Likewise.
+	* run-show-abbrev.sh: Likewise.
+	* run-show-ciefde.sh: Likewise.
+	* run-show-die-info.sh: Likewise.
+	* run-strings-test.sh: Likewise.
+	* run-strip-test.sh: Likewise.
+
+2005-08-30  Ulrich Drepper  <drepper@redhat.com>
+
+	* coverage.sh: Handle case where there is no .gcno file at all.
+
+2005-08-29  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (EXTRA_DIST): Add coverage.
+	[GCOV]: Generate coverage summary after the tests ran
+	* coverage.sh: New file.
+
+2005-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.an [BUILD_STATIC] (libdw): Add -ldl.
+	(CLEANFILES): Add *.gcno *.gcda *.gconv.
+
+2005-08-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* run-strings-test.sh: New file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add it.
+
+2005-08-27  Roland McGrath  <roland@redhat.com>
+
+	* addrscopes.c (handle_address): Apply bias to PC addresses.
+
+	* run-funcscopes.sh: New file.
+	* testfile25.bz2: New data file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add them.
+
+2005-08-26  Roland McGrath  <roland@redhat.com>
+
+	* addrscopes.c (dwarf_diename_integrate): Removed.
+	(print_vars, handle_address): Use plain dwarf_diename.
+
+2005-08-25  Roland McGrath  <roland@redhat.com>
+
+	* funcscopes.c: New file.
+	* Makefile.am (noinst_PROGRAMS): Add it.
+	(funcscopes_LDADD): New variable.
+
+	* run-addrscopes.sh: Add another case.
+	* testfile24.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add it.
+
+	* addrscopes.c (handle_address): Take new argument IGNORE_INLINES,
+	pass it to dwarf_getscopes.
+	(main): Pass it, true when '=' follows an address.
+
+2005-08-24  Roland McGrath  <roland@redhat.com>
+
+	* line2addr.c (print_address): Omit () for DSOs.
+
+2005-08-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* run-line2addr.sh: Remove testfile23 in the end.
+
+	* Makefile.am [BUILD_STATIC] (libdw): Add $(libelf) and $(libebl).
+	[MUDFLAP] (AM_LDFLAGS): Define to find libebl modules.
+
+2005-08-22  Roland McGrath  <roland@redhat.com>
+
+	* run-line2addr.sh: Add a case.
+	* testfile23.bz2: New data file.
+	* Makefile.am (EXTRA_DIST): Add it.
+
+2005-08-18  Roland McGrath  <roland@redhat.com>
+
+	* run-addrscopes.sh: New file.
+	* testfile22.bz2: New data file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add them.
+
+	* addrscopes.c: New file.
+	* Makefile.am (noinst_PROGRAMS): Add it.
+	(addrscopes_LDADD): New variable.
+
+2005-08-15  Ulrich Drepper  <drepper@redhat.com>
+
+	* run-elflint-self.sh: Don't run test if the file doesn't exist.
+
+2005-08-15  Roland McGrath  <roland@redhat.com>
+
+	* dwflmodtest.c (print_instance, print_inline): New functions.
+	(print_func): Call print_inline.
+	(options, parse_opt): Grok -i/--inlines.
+
+2005-08-07  Roland McGrath  <roland@redhat.com>
+
+	* dwflmodtest.c: Print function details only if -f flag is given.
+
+2005-08-06  Ulrich Drepper  <drepper@redhat.com>
+
+	* run-elflint-self.sh: New file.
+	* Makefile.am (TESTS): Add run-elflint-self.sh.
+	(EXTRA_DIST): Likewise.
+
+	* Makefile.am: Link with statis libs if BUILD_STATIC.
+	(dwflmodtest_LDADD): Also link with -ldl.
+
+2005-08-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Add -ldl to asm_tst[1-9]_LDASS.
+	* asm-tst1.c: Adjust for new asm_begin interface.  Open backend
+	library first.
+	* asm-tst2.c: Likewise.
+	* asm-tst3.c: Likewise.
+	* asm-tst4.c: Likewise.
+	* asm-tst5.c: Likewise.
+	* asm-tst6.c: Likewise.
+	* asm-tst7.c: Likewise.
+	* asm-tst8.c: Likewise.
+	* asm-tst9.c: Likewise.
+
+	* msg_tst.c: Add new error message.
+
+2005-07-28  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am (dwflmodtest_LDADD): Add $(libebl).
+
+2005-06-01  Roland McGrath  <roland@redhat.com>
+
+	* line2addr.c: Rewritten using libdwfl.
+	* run-line2addr.sh: Update test for changed arguments.
+	* Makefile.am (INCLUDES): Add libdwfl source directory to path.
+	(libdwfl): New variable.
+	(line2addr_LDADD): Use it.
+
+2005-07-28  Roland McGrath  <roland@redhat.com>
+
+	* dwflmodtest.c: New file, moved from ../libdwfl/ptest.c to here.
+	* Makefile.am (noinst_PROGRAMS): Add dwflmodtest.
+	(dwflmodtest_LDADD): New variable.
+	(INCLUDES): Add -I$(top_srcdir)/libdwfl here.
+
+2005-07-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* testfile18.bz2: New file.
+	* run-elflint-test.sh: New file.
+	* Makefile.am (TESTS): Add run-elflint-test.sh.
+	(EXTRA_DIST): Add run-elflint-test.sh and testfile18.bz2.
+
+2005-05-24  Ulrich Drepper  <drepper@redhat.com>
+
+	* get-files.c (main): Use correct format specifier.
+
+2005-05-21  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Add -Wextra to CFLAGS.
+	* get-files.c: Remove warning this produced.
+	* get-pubnames.c: Likewise.
+	* newfile.c: Likewise.
+	* newscn.c: Likewise.
+	* scnnames.c: Likewise.
+	* showptable.c: Likewise.
+	* test-nlist.c: Likewise.
+	* update1.c: Likewise.
+	* update2.c: Likewise.
+	* update3.c: Likewise.
+	* update4.c: Likewise.
+
+2005-05-08  Ulrich Drepper  <drepper@redhat.com>
+
+	* run-line2addr.sh: Remove testfile14 at the end.
+
+	* run-strip-test.sh: Remove debuginfo test input file as well.
+
+	* Makefile.am (EXTRA_DIST): Newly added files incorrectly used
+	.bz, not .bz2.
+
+2005-05-03  Roland McGrath  <roland@redhat.com>
+
+	* run-strip-test.sh: Use variables for test file names.
+	Optionally produce separate debug file and check it.
+	* run-strip-test2.sh: Use run-strip-test.sh via ., no duplication.
+	* run-strip-test3.sh: Likewise.
+	* run-strip-test4.sh: New file.
+	* run-strip-test5.sh: New file.
+	* run-strip-test6.sh: New file.
+	* testfile15.bz: New file.
+	* testfile15.debug.bz: New file.
+	* testfile16.bz: New file.
+	* testfile16.debug.bz: New file.
+	* testfile17.bz: New file.
+	* testfile17.debug.bz: New file.
+	* Makefile.am (TESTS, EXTRA_DIST): Add them.
+
+2005-04-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* run-line2addr.sh: Also use testfile14.  Adjust for correct
+	return of multiple matches.
+	* testfile14.bz2: New file.
+	* Makefile.am (EXTRA_DIST): Add testfile14.bz2.
+
+	* show-abbrev.c (main): Adjust for dwarf_getabbrev interface change.
+
+2005-04-04  Roland McGrath  <roland@redhat.com>
+
+	* line2addr.c (main): Initialize LINES and NLINES before calling
+	dwarf_getsrc_file, and free LINES afterwards.
+
+	* allfcts.c (main): Use size_t for CUHL.
+
+2005-04-04  Ulrich Drepper  <drepper@redhat.com>
+
+	* line2addr.c: New file.
+	* run-line2addr.sh: New file.
+	* Makefile.am: Add rules to build, run, and distribute new code.
+
+2005-04-02  Ulrich Drepper  <drepper@redhat.com>
+
+	* allfcts.c: New file.
+	* run-allfcts.sh: New file.
+	* Makefile.am: Add rules to build, run, and distribute new code.
+
+2005-02-05  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am [MUDFLAP] (AM_CFLAGS): Add -fmudflap.  Link all test
+	programs with -lmudflap.
+
+2004-09-25  Ulrich Drepper  <drepper@redhat.com>
+
+	* asm-tst4.c (main): Add LD_LIBRARY_PATH to elflint invocation.
+	* asm-tst5.c (main): Likewise.
+	* asm-tst6.c (main): Likewise.
+
+2004-01-17  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.am: Support building with mudflap.
+
+2004-01-12  Ulrich Drepper  <drepper@redhat.com>
+
+	* get-aranges.c: Rewrite to use libdw.
+	* Makefile.am: Reenable get-aranges test.
+
+2004-01-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* get-lines.c: New file.
+	* get-files.c: Adjust for libdw.
+	* run-get-files.sh: Adjust expected result.
+	* run-get-lines.sh: Likewise.
+	* Makefile.am: Run get-lines test.  Don't run get-aranges and
+	get-ciefde test for now.
+
+	* show-abbrev.c: Adjust call to dwarf_getabbrevattr after interface
+	change.  Print attribute offset information.
+	* run-show-abbrev.sh: Adjust expected output.
+
+2004-01-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* show-abbrev.c: Adjust call to dwarf_nextcu after interface change.
+	* show-die-info.c: Likewise.
+	* run-show-die-info.sh: Adjust expected output.
+
+2003-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* Makefile.in: Depend on libebl.a, not libebl.so.
+
+2003-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* Moved to CVS archive.
diff --git a/third_party/elfutils/tests/Makefile.am b/third_party/elfutils/tests/Makefile.am
new file mode 100644
index 0000000..1fce447
--- /dev/null
+++ b/third_party/elfutils/tests/Makefile.am
@@ -0,0 +1,527 @@
+## Process this file with automake to create Makefile.in
+##
+## Copyright (C) 1996-2017 Red Hat, Inc.
+## This file is part of elfutils.
+##
+## This file 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 3 of the License, or
+## (at your option) any later version.
+##
+## elfutils 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.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program.  If not, see <http://www.gnu.org/licenses/>.
+##
+include $(top_srcdir)/config/eu.am
+BUILD_RPATH = \$$ORIGIN/../libasm:\$$ORIGIN/../libdw:\$$ORIGIN/../backends:\$$ORIGIN/../libelf
+
+AM_LDFLAGS =
+
+if !STANDALONE
+AM_CPPFLAGS += -I$(top_srcdir)/libasm -I$(top_srcdir)/libdw \
+	    -I$(top_srcdir)/libdwfl -I$(top_srcdir)/libdwelf \
+	    -I$(top_srcdir)/libebl -I$(top_srcdir)/libelf \
+	    -I$(top_srcdir)/lib -I..
+AM_LDFLAGS += -Wl,-rpath-link,../libasm:../libdw:../libelf
+endif
+
+if TESTS_RPATH
+AM_LDFLAGS += -Wl,-rpath,$(BUILD_RPATH)
+tests_rpath = yes
+else
+tests_rpath = no
+endif
+
+check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
+		  showptable update1 update2 update3 update4 test-nlist \
+		  show-die-info get-files get-lines get-pubnames \
+		  get-aranges allfcts line2addr addrscopes funcscopes \
+		  show-abbrev hash newscn ecp dwflmodtest \
+		  find-prologues funcretval allregs rdwrmmap \
+		  dwfl-bug-addr-overflow arls dwfl-bug-fd-leak \
+		  dwfl-addr-sect dwfl-bug-report early-offscn \
+		  dwfl-bug-getmodules dwarf-getmacros dwarf-ranges addrcfi \
+		  test-flag-nobits dwarf-getstring rerequest_tag \
+		  alldts typeiter typeiter2 low_high_pc \
+		  test-elf_cntl_gelf_getshdr dwflsyms dwfllines \
+		  dwfl-report-elf-align varlocs backtrace backtrace-child \
+		  backtrace-data backtrace-dwarf debuglink debugaltlink \
+		  buildid deleted deleted-lib.so aggregate_size peel_type \
+		  vdsosyms \
+		  getsrc_die strptr newdata elfstrtab dwfl-proc-attach \
+		  elfshphehdr elfstrmerge dwelfgnucompressed elfgetchdr \
+		  elfgetzdata elfputzdata zstrptr emptyfile vendorelf \
+		  fillfile dwarf_default_lower_bound
+
+asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
+	    asm-tst6 asm-tst7 asm-tst8 asm-tst9
+
+if BIARCH
+check_PROGRAMS += backtrace-child-biarch
+endif
+
+# Substitute $(COMPILE).
+backtrace-child-biarch$(EXEEXT): backtrace-child.c
+	$(AM_V_CC)$(CC_BIARCH) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+		     $(AM_CPPFLAGS) $(CPPFLAGS) \
+		     $(AM_CFLAGS) $(CFLAGS) $(backtrace_child_CFLAGS) \
+		     $(AM_LDFLAGS) $(LDFLAGS) $(backtrace_child_LDFLAGS) \
+		     -o $@ $<
+
+TESTS = run-arextract.sh run-arsymtest.sh run-ar.sh newfile test-nlist \
+	update1 update2 update3 update4 \
+	run-show-die-info.sh run-get-files.sh run-get-lines.sh \
+	run-get-pubnames.sh run-get-aranges.sh run-allfcts.sh \
+	run-show-abbrev.sh run-line2addr.sh hash \
+	newscn run-strip-test.sh run-strip-test2.sh \
+	run-strip-test3.sh run-strip-test4.sh run-strip-test5.sh \
+	run-strip-test6.sh run-strip-test7.sh run-strip-test8.sh \
+	run-strip-test9.sh run-strip-test10.sh run-strip-test11.sh \
+	run-strip-nothing.sh run-strip-g.sh \
+	run-strip-groups.sh run-strip-reloc.sh run-strip-strmerge.sh \
+	run-strip-nobitsalign.sh run-strip-remove-keep.sh \
+	run-unstrip-test.sh run-unstrip-test2.sh run-unstrip-test3.sh \
+	run-unstrip-test4.sh run-unstrip-M.sh run-elfstrmerge-test.sh \
+	run-ecp-test.sh run-ecp-test2.sh run-alldts.sh \
+	run-elflint-test.sh run-elflint-self.sh run-ranlib-test.sh \
+	run-ranlib-test2.sh run-ranlib-test3.sh run-ranlib-test4.sh \
+	run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \
+	run-find-prologues.sh run-allregs.sh run-addrcfi.sh \
+	run-nm-self.sh run-readelf-self.sh \
+	run-varlocs-self.sh run-exprlocs-self.sh \
+	run-readelf-test1.sh run-readelf-test2.sh run-readelf-test3.sh \
+	run-readelf-test4.sh run-readelf-twofiles.sh \
+	run-readelf-macro.sh run-readelf-loc.sh \
+	run-readelf-aranges.sh run-readelf-line.sh run-readelf-z.sh \
+	run-native-test.sh run-bug1-test.sh \
+	run-debuglink.sh run-debugaltlink.sh run-buildid.sh \
+	dwfl-bug-addr-overflow run-addrname-test.sh \
+	dwfl-bug-fd-leak dwfl-bug-report \
+	run-dwfl-bug-offline-rel.sh run-dwfl-addr-sect.sh \
+	run-disasm-x86.sh run-disasm-x86-64.sh \
+	run-early-offscn.sh run-dwarf-getmacros.sh run-dwarf-ranges.sh \
+	run-test-flag-nobits.sh run-prelink-addr-test.sh \
+	run-dwarf-getstring.sh run-rerequest_tag.sh run-typeiter.sh \
+	run-readelf-d.sh run-readelf-gdb_index.sh run-unstrip-n.sh \
+	run-low_high_pc.sh run-macro-test.sh run-elf_cntl_gelf_getshdr.sh \
+	run-test-archive64.sh run-readelf-vmcoreinfo.sh \
+	run-readelf-mixed-corenote.sh run-dwfllines.sh \
+	run-readelf-variant.sh \
+	run-dwfl-report-elf-align.sh run-addr2line-test.sh \
+	run-addr2line-i-test.sh run-addr2line-i-lex-test.sh \
+	run-addr2line-i-demangle-test.sh run-addr2line-alt-debugpath.sh \
+	run-varlocs.sh run-exprlocs.sh run-funcretval.sh \
+	run-backtrace-native.sh run-backtrace-data.sh run-backtrace-dwarf.sh \
+	run-backtrace-native-biarch.sh run-backtrace-native-core.sh \
+	run-backtrace-native-core-biarch.sh run-backtrace-core-x86_64.sh \
+	run-backtrace-fp-core-x86_64.sh \
+	run-backtrace-fp-core-aarch64.sh \
+	run-backtrace-fp-core-ppc64le.sh \
+	run-backtrace-core-x32.sh \
+	run-backtrace-core-i386.sh run-backtrace-fp-core-i386.sh \
+	run-backtrace-core-ppc.sh \
+	run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \
+	run-backtrace-core-aarch64.sh run-backtrace-core-sparc.sh \
+	run-backtrace-demangle.sh run-stack-d-test.sh run-stack-i-test.sh \
+	run-stack-demangled-test.sh run-readelf-zx.sh run-readelf-zp.sh \
+	run-readelf-dwz-multi.sh run-allfcts-multi.sh run-deleted.sh \
+	run-linkmap-cut.sh run-aggregate-size.sh run-peel-type.sh \
+	vdsosyms run-readelf-A.sh \
+	run-getsrc-die.sh run-strptr.sh newdata elfstrtab dwfl-proc-attach \
+	elfshphehdr run-lfs-symbols.sh run-dwelfgnucompressed.sh \
+	run-elfgetchdr.sh \
+	run-elfgetzdata.sh run-elfputzdata.sh run-zstrptr.sh \
+	run-compress-test.sh \
+	run-readelf-zdebug.sh run-readelf-zdebug-rel.sh \
+	emptyfile vendorelf fillfile dwarf_default_lower_bound
+
+if !BIARCH
+export ELFUTILS_DISABLE_BIARCH = 1
+endif
+
+if !DEMANGLE
+export ELFUTILS_DISABLE_DEMANGLE = 1
+endif
+
+if !STANDALONE
+check_PROGRAMS += msg_tst system-elf-libelf-test
+TESTS += msg_tst system-elf-libelf-test
+endif
+
+if LZMA
+TESTS += run-readelf-s.sh run-dwflsyms.sh
+endif
+
+if HAVE_LIBASM
+check_PROGRAMS += $(asm_TESTS)
+TESTS += $(asm_TESTS) run-disasm-bpf.sh
+endif
+
+EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \
+	     run-show-die-info.sh run-get-files.sh run-get-lines.sh \
+	     run-get-pubnames.sh run-get-aranges.sh \
+	     run-show-abbrev.sh run-strip-test.sh \
+	     run-strip-test2.sh run-ecp-test.sh run-ecp-test2.sh \
+	     testfile.bz2 testfile2.bz2 testfile3.bz2 testfile4.bz2 \
+	     testfile5.bz2 testfile6.bz2 testfile7.bz2 testfile8.bz2 \
+	     testfile9.bz2 testfile10.bz2 testfile11.bz2 testfile12.bz2 \
+	     testfile13.bz2 run-strip-test3.sh run-allfcts.sh \
+	     testfile_class_func.bz2 testfile_nested_funcs.bz2 \
+	     run-line2addr.sh run-elflint-test.sh testfile14.bz2 \
+	     run-strip-test4.sh run-strip-test5.sh run-strip-test6.sh \
+	     run-strip-test7.sh run-strip-test8.sh run-strip-groups.sh \
+	     run-strip-test9.sh run-strip-test10.sh run-strip-test11.sh \
+	     run-strip-nothing.sh run-strip-remove-keep.sh run-strip-g.sh \
+	     run-strip-strmerge.sh run-strip-nobitsalign.sh \
+	     testfile-nobitsalign.bz2 testfile-nobitsalign.strip.bz2 \
+	     run-strip-reloc.sh hello_i386.ko.bz2 hello_x86_64.ko.bz2 \
+	     hello_ppc64.ko.bz2 hello_s390.ko.bz2 hello_aarch64.ko.bz2 \
+	     hello_m68k.ko.bz2 \
+	     run-unstrip-test.sh run-unstrip-test2.sh \
+	     testfile-info-link.bz2 testfile-info-link.debuginfo.bz2 \
+	     testfile-info-link.stripped.bz2 run-unstrip-test3.sh \
+	     run-unstrip-test4.sh testfile-strtab.bz2 \
+	     testfile-strtab.stripped.bz2 testfile-strtab.debuginfo.bz2 \
+	     run-unstrip-M.sh run-elfstrmerge-test.sh \
+	     run-elflint-self.sh run-ranlib-test.sh run-ranlib-test2.sh \
+	     run-ranlib-test3.sh run-ranlib-test4.sh \
+	     run-addrscopes.sh run-strings-test.sh run-funcscopes.sh \
+	     run-nm-self.sh run-readelf-self.sh run-addrcfi.sh \
+	     run-varlocs-self.sh run-exprlocs-self.sh \
+	     run-find-prologues.sh run-allregs.sh run-native-test.sh \
+	     run-addrname-test.sh run-dwfl-bug-offline-rel.sh \
+	     run-dwfl-addr-sect.sh run-early-offscn.sh \
+	     run-dwarf-getmacros.sh \
+	     run-dwarf-ranges.sh debug-ranges-no-lowpc.o.bz2 \
+	     run-test-flag-nobits.sh \
+	     run-dwarf-getstring.sh run-rerequest_tag.sh run-alldts.sh \
+	     testfile15.bz2 testfile15.debug.bz2 \
+	     testfile16.bz2 testfile16.debug.bz2 \
+	     testfile17.bz2 testfile17.debug.bz2 \
+	     testfile18.bz2 testfile19.bz2 testfile19.index.bz2 \
+	     testfile20.bz2 testfile20.index.bz2 \
+	     testfile21.bz2 testfile21.index.bz2 \
+	     testfile22.bz2 testfile23.bz2 testfile24.bz2 testfile25.bz2 \
+	     testfile26.bz2 testfile27.bz2 \
+	     coverage.sh test-subr.sh test-wrapper.sh \
+	     run-readelf-test1.sh run-readelf-test2.sh run-readelf-test3.sh \
+	     run-readelf-test4.sh run-readelf-twofiles.sh \
+	     run-bug1-test.sh testfile28.bz2 testfile28.rdwr.bz2 \
+	     run-debuglink.sh run-debugaltlink.sh run-buildid.sh \
+	     testfile29.bz2 testfile29.rdwr.bz2 \
+	     testfile30.bz2 testfile31.bz2 testfile32.bz2 testfile33.bz2 \
+	     testfile34.bz2 testfile35.bz2 testfile35.debug.bz2 \
+	     testfile36.bz2 testfile36.debug.bz2 \
+	     testfile37.bz2 testfile37.debug.bz2 \
+	     testfile38.bz2 testfile39.bz2 testfile40.bz2 testfile40.debug.bz2 \
+	     testfile41.bz2 testfile42.bz2 testfile42_noshdrs.bz2 \
+	     testfile43.bz2 \
+	     testfile44.S.bz2 testfile44.expect.bz2 run-disasm-x86.sh \
+	     testfile45.S.bz2 testfile45.expect.bz2 run-disasm-x86-64.sh \
+	     testfile46.bz2 testfile47.bz2 testfile48.bz2 testfile48.debug.bz2 \
+	     testfile49.bz2 testfile50.bz2 testfile51.bz2 \
+	     testfile-macros-0xff.bz2 \
+	     run-readelf-macro.sh testfilemacro.bz2 \
+	     run-readelf-loc.sh testfileloc.bz2 \
+	     run-readelf-aranges.sh run-readelf-line.sh testfilefoobarbaz.bz2 \
+	     run-readelf-z.sh \
+	     run-readelf-dwz-multi.sh libtestfile_multi_shared.so.bz2 \
+	     testfile_multi.dwz.bz2 testfile_multi_main.bz2 \
+	     testfile-dwzstr.bz2 testfile-dwzstr.multi.bz2 \
+	     run-allfcts-multi.sh \
+	     test-offset-loop.bz2 test-offset-loop.alt.bz2 \
+	     run-prelink-addr-test.sh \
+	     testfile52-32.so.bz2 testfile52-32.so.debug.bz2 \
+	     testfile52-32.prelink.so.bz2 testfile52-32.noshdrs.so.bz2 \
+	     testfile52-64.so.bz2 testfile52-64.so.debug.bz2 \
+	     testfile52-64.prelink.so.bz2 testfile52-64.noshdrs.so.bz2 \
+	     testfile53-32.bz2 testfile53-32.debug.bz2 \
+	     testfile53-32.prelink.bz2 testfile53-64.bz2 \
+	     testfile53-64.debug.bz2 testfile53-64.prelink.bz2 \
+	     testfile54-32.so.bz2 testfile54-32.so.debug.bz2 \
+	     testfile54-32.prelink.so.bz2 testfile54-32.noshdrs.so.bz2 \
+	     testfile54-64.so.bz2 testfile54-64.so.debug.bz2 \
+	     testfile54-64.prelink.so.bz2 testfile54-64.noshdrs.so.bz2 \
+	     testfile55-32.bz2 testfile55-32.debug.bz2 \
+	     testfile55-32.prelink.bz2 testfile55-64.bz2 \
+	     testfile55-64.debug.bz2 testfile55-64.prelink.bz2 \
+	     testfile56.bz2 testfile57.bz2 testfile58.bz2 \
+	     run-typeiter.sh testfile59.bz2 \
+	     run-readelf-d.sh testlib_dynseg.so.bz2 \
+	     testfile-s390x-hash-both.bz2 \
+	     run-readelf-gdb_index.sh testfilegdbindex5.bz2 \
+	     testfilegdbindex7.bz2 \
+	     run-readelf-s.sh testfilebazdbg.bz2 testfilebazdyn.bz2 \
+	     testfilebazmin.bz2 testfilebazdbg.debug.bz2 testfilebazmdb.bz2 \
+	     testfilebaztab.bz2 testfilebasmin.bz2 testfilebaxmin.bz2 \
+	     testfilebazdbg_pl.bz2 testfilebazmin_pl.bz2 \
+	     testfilebazdbg_plr.bz2 testfilebazmin_plr.bz2 \
+	     testfilebazdbgppc64.bz2 testfilebazdbgppc64.debug.bz2 \
+	     testfilebazdbgppc64_pl.bz2 testfilebazdbgppc64_plr.bz2 \
+	     testfilebazdynppc64.bz2 testfilebazmdbppc64.bz2 \
+	     testfilebazminppc64.bz2 testfilebazminppc64_pl.bz2 \
+	     testfilebazminppc64_plr.bz2 testfilebaztabppc64.bz2 \
+	     run-readelf-variant.sh testfile-ada-variant.bz2 \
+	     run-dwflsyms.sh \
+	     run-unstrip-n.sh testcore-rtlib.bz2 testcore-rtlib-ppc.bz2 \
+	     run-low_high_pc.sh testfile_low_high_pc.bz2 \
+	     run-macro-test.sh testfile-macinfo.bz2 testfile-macros.bz2 \
+	     run-elf_cntl_gelf_getshdr.sh \
+	     run-test-archive64.sh testarchive64.a.bz2 \
+	     testfile60.bz2 testfile61.bz2 \
+	     run-readelf-vmcoreinfo.sh testfile62.bz2 \
+	     run-readelf-mixed-corenote.sh testfile63.bz2 testfile64.bz2 \
+	     testfile65.bz2 testfile67.bz2 testfile68.bz2 \
+	     testfile69.core.bz2 testfile69.so.bz2 \
+	     testfile70.core.bz2 testfile70.exec.bz2 testfile71.bz2 \
+	     run-dwfllines.sh run-dwfl-report-elf-align.sh \
+	     testfile-dwfl-report-elf-align-shlib.so.bz2 \
+	     testfilenolines.bz2 test-core-lib.so.bz2 test-core.core.bz2 \
+	     test-core.exec.bz2 run-addr2line-test.sh \
+	     run-addr2line-i-test.sh testfile-inlines.bz2 \
+	     run-addr2line-i-lex-test.sh testfile-lex-inlines.bz2 \
+	     run-addr2line-i-demangle-test.sh run-addr2line-alt-debugpath.sh \
+	     testfileppc32.bz2 testfileppc64.bz2 \
+	     testfiles390.bz2 testfiles390x.bz2 \
+	     testfilearm.bz2 testfileaarch64.bz2 \
+	     run-varlocs.sh run-exprlocs.sh testfile-stridex.bz2 \
+	     testfile_const_type.c testfile_const_type.bz2 \
+	     testfile_implicit_pointer.c testfile_implicit_pointer.bz2 \
+	     testfile_parameter_ref.c testfile_parameter_ref.bz2 \
+	     testfile_entry_value.c testfile_entry_value.bz2 \
+	     testfile_implicit_value.c testfile_implicit_value.bz2 \
+	     testfile_aarch64_core.bz2 testfile_i686_core.bz2 \
+	     run-funcretval.sh funcretval_test.c funcretval_test_aarch64.bz2 \
+	     run-backtrace-data.sh run-backtrace-dwarf.sh cleanup-13.c \
+	     run-backtrace-native.sh run-backtrace-native-biarch.sh \
+	     run-backtrace-native-core.sh run-backtrace-native-core-biarch.sh \
+	     run-backtrace-core-x86_64.sh run-backtrace-core-i386.sh \
+	     run-backtrace-fp-core-x86_64.sh \
+	     run-backtrace-core-x32.sh \
+	     run-backtrace-fp-core-aarch64.sh \
+	     backtrace.aarch64.fp.core.bz2 backtrace.aarch64.fp.exec.bz2 \
+	     backtrace-subr.sh backtrace.i386.core.bz2 backtrace.i386.exec.bz2 \
+	     run-backtrace-fp-core-i386.sh \
+	     backtrace.i386.fp.core.bz2 backtrace.i386.fp.exec.bz2 \
+	     run-backtrace-fp-core-ppc64le.sh \
+	     backtrace.ppc64le.fp.core.bz2 backtrace.ppc64le.fp.exec.bz2 \
+	     backtrace.x86_64.core.bz2 backtrace.x86_64.exec.bz2 \
+	     backtrace.x86_64.fp.core.bz2 backtrace.x86_64.fp.exec.bz2 \
+	     backtrace.ppc.core.bz2 backtrace.ppc.exec.bz2 \
+	     run-backtrace-core-ppc.sh testfile66.bz2 testfile66.core.bz2 \
+	     backtrace.s390x.core.bz2 backtrace.s390x.exec.bz2 \
+	     backtrace.s390.core.bz2 backtrace.s390.exec.bz2 \
+	     run-backtrace-core-s390x.sh run-backtrace-core-s390.sh \
+	     run-backtrace-core-aarch64.sh \
+	     backtrace.aarch64.core.bz2 backtrace.aarch64.exec.bz2 \
+	     run-backtrace-core-sparc.sh \
+	     backtrace.sparc.core.bz2 backtrace.sparc.exec.bz2 \
+	     run-backtrace-demangle.sh testfile-backtrace-demangle.bz2 \
+	     testfile-backtrace-demangle.cc \
+	     testfile-backtrace-demangle.core.bz2 \
+	     run-stack-d-test.sh run-stack-i-test.sh \
+	     run-stack-demangled-test.sh \
+	     testfiledwarfinlines.bz2 testfiledwarfinlines.core.bz2 \
+	     run-readelf-zdebug.sh testfile-debug.bz2 testfile-zdebug.bz2 \
+	     run-readelf-zdebug-rel.sh testfile-debug-rel.o.bz2 \
+	     testfile-debug-rel-g.o.bz2 testfile-debug-rel-z.o.bz2 \
+	     run-readelf-zx.sh run-readelf-zp.sh \
+	     run-deleted.sh run-linkmap-cut.sh linkmap-cut-lib.so.bz2 \
+	     linkmap-cut.bz2 linkmap-cut.core.bz2 \
+	     run-aggregate-size.sh testfile-sizes1.o.bz2 testfile-sizes2.o.bz2 \
+	     testfile-sizes3.o.bz2 testfile-sizes4.o.bz2 testfile-sizes4.s \
+	     run-peel-type.sh \
+	     run-readelf-A.sh testfileppc32attrs.o.bz2 \
+	     testfilesparc64attrs.o.bz2 testfileppc64attrs.o.bz2 \
+	     testfile-debug-types.bz2 \
+	     run-getsrc-die.sh run-strptr.sh \
+	     testfile-x32-core.bz2 testfile-x32.bz2 \
+	     backtrace.x32.core.bz2 backtrace.x32.exec.bz2 \
+	     testfile-x32-s.bz2 testfile-x32-d.bz2 testfile-x32-debug.bz2 \
+	     run-lfs-symbols.sh lfs-symbols testfile-nolfs.bz2 \
+	     testfile-zgnu32.bz2 testfile-zgnu64.bz2 \
+	     testfile-zgnu32be.bz2 testfile-zgnu64be.bz2 \
+	     run-dwelfgnucompressed.sh \
+	     testfile-zgabi32.bz2 testfile-zgabi64.bz2 \
+	     testfile-zgabi32be.bz2 testfile-zgabi64be.bz2 \
+	     run-elfgetchdr.sh run-elfgetzdata.sh run-elfputzdata.sh \
+	     run-zstrptr.sh run-compress-test.sh \
+	     run-disasm-bpf.sh \
+	     testfile-bpf-dis1.expect.bz2 testfile-bpf-dis1.o.bz2 \
+	     testfile-m68k-core.bz2 testfile-m68k.bz2 testfile-m68k-s.bz2
+
+if USE_VALGRIND
+valgrind_cmd='valgrind -q --leak-check=full --error-exitcode=1'
+endif
+
+
+installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir); \
+			      bindir=$(DESTDIR)$(bindir); \
+			      LC_ALL=C; LANG=C; \
+			      VALGRIND_CMD=$(valgrind_cmd); \
+			      abs_srcdir=$(abs_srcdir); \
+			      abs_builddir=$(abs_builddir); \
+			      abs_top_builddir=$(abs_top_builddir); \
+			      export abs_srcdir; export abs_builddir; \
+			      export abs_top_builddir; \
+			      export libdir; export bindir; \
+			      export LC_ALL; export LANG; export VALGRIND_CMD; \
+			      NM=$(NM); export NM;
+installed_LOG_COMPILER = $(abs_srcdir)/test-wrapper.sh \
+			 installed $(tests_rpath) \
+			 '$(program_transform_name)'
+if STANDALONE
+TESTS_ENVIRONMENT = $(installed_TESTS_ENVIRONMENT)
+LOG_COMPILER = $(installed_LOG_COMPILER)
+else !STANDALONE
+TESTS_ENVIRONMENT = LC_ALL=C; LANG=C; VALGRIND_CMD=$(valgrind_cmd); \
+		    abs_srcdir=$(abs_srcdir);  abs_builddir=$(abs_builddir); \
+		    abs_top_builddir=$(abs_top_builddir); \
+		    export abs_srcdir; export abs_builddir; \
+		    export abs_top_builddir; \
+		    export LC_ALL; export LANG; export VALGRIND_CMD; \
+		    NM=$(NM); export NM;
+LOG_COMPILER = $(abs_srcdir)/test-wrapper.sh \
+	       $(abs_top_builddir)/libdw:$(abs_top_builddir)/backends:$(abs_top_builddir)/libelf:$(abs_top_builddir)/libasm
+
+installcheck-local:
+	$(MAKE) $(AM_MAKEFLAGS) \
+		TESTS_ENVIRONMENT="$(installed_TESTS_ENVIRONMENT)" \
+		LOG_COMPILER="$(installed_LOG_COMPILER)" check-TESTS
+endif !STANDALONE
+
+if STANDALONE
+libdw = -ldw
+libelf = -lelf
+libasm = -lasm
+libebl = -lebl
+else !STANDALONE
+if BUILD_STATIC
+libdw = ../libdw/libdw.a -lz $(zip_LIBS) $(libelf) $(libebl) -ldl
+libelf = ../libelf/libelf.a -lz
+libasm = ../libasm/libasm.a
+else
+libdw = ../libdw/libdw.so
+libelf = ../libelf/libelf.so
+libasm = ../libasm/libasm.so
+endif
+libebl = ../libebl/libebl.a
+libeu = ../lib/libeu.a
+endif !STANDALONE
+
+arextract_LDADD = $(libelf)
+arsymtest_LDADD = $(libelf)
+newfile_LDADD = $(libelf)
+saridx_LDADD = $(libelf)
+scnnames_LDADD = $(libelf)
+sectiondump_LDADD = $(libelf)
+showptable_LDADD = $(libelf)
+hash_LDADD = $(libelf)
+test_nlist_LDADD = $(libelf)
+msg_tst_LDADD = $(libelf)
+newscn_LDADD = $(libelf)
+early_offscn_LDADD = $(libelf)
+ecp_LDADD = $(libelf)
+update1_LDADD = $(libelf)
+update2_LDADD = $(libelf)
+update3_LDADD = $(libdw) $(libelf)
+update4_LDADD = $(libdw) $(libelf)
+show_die_info_LDADD = $(libdw) $(libelf)
+get_pubnames_LDADD = $(libdw) $(libelf)
+show_abbrev_LDADD = $(libdw) $(libelf)
+get_lines_LDADD = $(libdw) $(libelf)
+get_files_LDADD = $(libdw) $(libelf)
+get_aranges_LDADD = $(libdw) $(libelf)
+allfcts_LDADD = $(libdw) $(libelf)
+line2addr_LDADD = $(libdw) $(argp_LDADD)
+addrscopes_LDADD = $(libdw) $(argp_LDADD)
+funcscopes_LDADD = $(libdw) $(argp_LDADD)
+funcretval_LDADD = $(libdw) $(argp_LDADD)
+allregs_LDADD = $(libdw) $(argp_LDADD)
+find_prologues_LDADD = $(libdw) $(argp_LDADD)
+#show_ciefde_LDADD = ../libdwarf/libdwarf.so $(libelf)
+asm_tst1_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) -ldl
+asm_tst2_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) -ldl
+asm_tst3_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) -ldl
+asm_tst4_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) -ldl
+asm_tst5_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) -ldl
+asm_tst6_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) -ldl
+asm_tst7_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) -ldl
+asm_tst8_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) -ldl
+asm_tst9_LDADD = $(libasm) $(libebl) $(libelf) $(libdw) -ldl
+dwflmodtest_LDADD = $(libdw) $(libebl) $(libelf) $(argp_LDADD) -ldl
+rdwrmmap_LDADD = $(libelf)
+dwfl_bug_addr_overflow_LDADD = $(libdw) $(libebl) $(libelf) -ldl
+arls_LDADD = $(libelf)
+dwfl_bug_fd_leak_LDADD = $(libdw) $(libebl) $(libelf) -ldl
+dwfl_bug_report_LDADD = $(libdw) $(libebl) $(libelf) -ldl
+dwfl_bug_getmodules_LDADD = $(libdw) $(libebl) $(libelf) -ldl
+dwfl_addr_sect_LDADD = $(libdw) $(libebl) $(libelf) $(argp_LDADD) -ldl
+dwarf_getmacros_LDADD = $(libdw)
+dwarf_ranges_LDADD = $(libdw)
+dwarf_getstring_LDADD = $(libdw)
+addrcfi_LDADD = $(libdw) $(libebl) $(libelf) $(argp_LDADD) -ldl
+test_flag_nobits_LDADD = $(libelf)
+rerequest_tag_LDADD = $(libdw)
+alldts_LDADD = $(libdw) $(libelf)
+typeiter_LDADD = $(libdw) $(libelf)
+typeiter2_LDADD = $(libdw) $(libelf)
+low_high_pc_LDADD = $(libdw) $(libelf) $(argp_LDADD)
+test_elf_cntl_gelf_getshdr_LDADD = $(libelf)
+dwflsyms_LDADD = $(libdw) $(libelf) $(argp_LDADD)
+dwfllines_LDADD = $(libdw) $(libelf) $(argp_LDADD)
+dwfl_report_elf_align_LDADD = $(libdw)
+varlocs_LDADD = $(libdw) $(libelf) $(argp_LDADD)
+backtrace_LDADD = $(libdw) $(libelf) $(argp_LDADD)
+# backtrace-child-biarch also uses those *_CFLAGS and *_LDLAGS variables:
+backtrace_child_CFLAGS = $(fpie_CFLAGS)
+backtrace_child_LDFLAGS = -pie -pthread
+backtrace_child_biarch_SOURCES = backtrace-child.c
+backtrace_data_LDADD = $(libdw) $(libelf)
+backtrace_dwarf_CFLAGS = -Wno-unused-parameter
+backtrace_dwarf_LDADD = $(libdw) $(libelf)
+debuglink_LDADD = $(libdw) $(libelf)
+debugaltlink_LDADD = $(libdw) $(libelf)
+buildid_LDADD = $(libdw) $(libelf)
+deleted_LDADD = ./deleted-lib.so
+deleted_lib_so_LDFLAGS = -shared
+deleted_lib_so_CFLAGS = $(fpic_CFLAGS) -fasynchronous-unwind-tables
+aggregate_size_LDADD = $(libdw) $(libelf) $(argp_LDADD)
+peel_type_LDADD = $(libdw) $(libelf) $(argp_LDADD)
+vdsosyms_LDADD = $(libdw) $(libelf)
+getsrc_die_LDADD = $(libdw) $(libelf)
+strptr_LDADD = $(libelf)
+newdata_LDADD = $(libelf)
+elfstrtab_LDADD = $(libelf)
+dwfl_proc_attach_LDADD = $(libdw)
+dwfl_proc_attach_LDFLAGS = -pthread $(AM_LDFLAGS)
+elfshphehdr_LDADD =$(libelf)
+elfstrmerge_LDADD = $(libdw) $(libelf)
+dwelfgnucompressed_LDADD = $(libelf) $(libdw)
+elfgetchdr_LDADD = $(libelf) $(libdw)
+elfgetzdata_LDADD = $(libelf)
+elfputzdata_LDADD = $(libelf)
+zstrptr_LDADD = $(libelf)
+emptyfile_LDADD = $(libelf)
+vendorelf_LDADD = $(libelf)
+fillfile_LDADD = $(libelf)
+dwarf_default_lower_bound_LDADD = $(libdw)
+
+# We want to test the libelf header against the system elf.h header.
+# Don't include any -I CPPFLAGS.
+system_elf_libelf_test_CPPFLAGS =
+system_elf_libelf_test_LDADD = $(libelf)
+
+# A lock file used to make sure only one test dumps core at a time
+CLEANFILES += core-dump-backtrace.lock
+
+if GCOV
+check: check-am coverage
+.PHONY: coverage
+coverage:
+	-$(srcdir)/coverage.sh
+endif
diff --git a/third_party/elfutils/tests/addrcfi.c b/third_party/elfutils/tests/addrcfi.c
new file mode 100644
index 0000000..589b851
--- /dev/null
+++ b/third_party/elfutils/tests/addrcfi.c
@@ -0,0 +1,233 @@
+/* Test program for CFI handling.
+   Copyright (C) 2009-2010, 2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+#include <argp.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../libdw/known-dwarf.h"
+
+static const char *
+op_name (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_OP
+#undef DWARF_ONE_KNOWN_DW_OP
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+static void
+print_detail (int result, const Dwarf_Op *ops, size_t nops, Dwarf_Addr bias)
+{
+  if (result < 0)
+    printf ("indeterminate (%s)\n", dwarf_errmsg (-1));
+  else if (nops == 0)
+    printf ("%s\n", ops == NULL ? "same_value" : "undefined");
+  else
+    {
+      printf ("%s expression:", result == 0 ? "location" : "value");
+      for (size_t i = 0; i < nops; ++i)
+	{
+	  printf (" %s", op_name(ops[i].atom));
+	  if (ops[i].number2 == 0)
+	    {
+	      if (ops[i].atom == DW_OP_addr)
+		printf ("(%#" PRIx64 ")", ops[i].number + bias);
+	      else if (ops[i].number != 0)
+		printf ("(%" PRId64 ")", ops[i].number);
+	    }
+	  else
+	    printf ("(%" PRId64 ",%" PRId64 ")",
+		    ops[i].number, ops[i].number2);
+	}
+      puts ("");
+    }
+}
+
+struct stuff
+{
+  Dwarf_Frame *frame;
+  Dwarf_Addr bias;
+};
+
+static int
+print_register (void *arg,
+		int regno,
+		const char *setname,
+		const char *prefix,
+		const char *regname,
+		int bits __attribute__ ((unused)),
+		int type __attribute__ ((unused)))
+{
+  struct stuff *stuff = arg;
+
+  printf ("\t%s reg%u (%s%s): ", setname, regno, prefix, regname);
+
+  Dwarf_Op ops_mem[2];
+  Dwarf_Op *ops;
+  size_t nops;
+  int result = dwarf_frame_register (stuff->frame, regno, ops_mem, &ops, &nops);
+  print_detail (result, ops, nops, stuff->bias);
+
+  return DWARF_CB_OK;
+}
+
+static int
+handle_cfi (Dwfl *dwfl, const char *which, Dwarf_CFI *cfi,
+	    GElf_Addr pc, struct stuff *stuff)
+{
+  if (cfi == NULL)
+    {
+      printf ("handle_cfi no CFI (%s): %s\n", which, dwarf_errmsg (-1));
+      return -1;
+    }
+
+  int result = dwarf_cfi_addrframe (cfi, pc - stuff->bias, &stuff->frame);
+  if (result != 0)
+    {
+      printf ("dwarf_cfi_addrframe (%s): %s\n", which, dwarf_errmsg (-1));
+      return 1;
+    }
+
+  Dwarf_Addr start = pc;
+  Dwarf_Addr end = pc;
+  bool signalp;
+  int ra_regno = dwarf_frame_info (stuff->frame, &start, &end, &signalp);
+  if (ra_regno >= 0)
+    {
+      start += stuff->bias;
+      end += stuff->bias;
+    }
+
+  printf ("%s has %#" PRIx64 " => [%#" PRIx64 ", %#" PRIx64 "):\n",
+	  which, pc, start, end);
+
+  if (ra_regno < 0)
+    printf ("\treturn address register unavailable (%s)\n",
+	    dwarf_errmsg (0));
+  else
+    printf ("\treturn address in reg%u%s\n",
+	    ra_regno, signalp ? " (signal frame)" : "");
+
+  // Point cfa_ops to dummy to match print_detail expectations.
+  // (nops == 0 && cfa_ops != NULL => "undefined")
+  Dwarf_Op dummy;
+  Dwarf_Op *cfa_ops = &dummy;
+  size_t cfa_nops;
+  result = dwarf_frame_cfa (stuff->frame, &cfa_ops, &cfa_nops);
+
+  printf ("\tCFA ");
+  print_detail (result, cfa_ops, cfa_nops, stuff->bias);
+
+  (void) dwfl_module_register_names (dwfl_addrmodule (dwfl, pc),
+				     &print_register, stuff);
+
+  return 0;
+}
+
+static int
+handle_address (GElf_Addr pc, Dwfl *dwfl)
+{
+  Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc);
+
+  struct stuff stuff;
+  stuff.frame = NULL;
+  stuff.bias = 0;
+  int res = handle_cfi (dwfl, ".eh_frame",
+			dwfl_module_eh_cfi (mod, &stuff.bias), pc, &stuff);
+  free (stuff.frame);
+
+  stuff.frame = NULL;
+  stuff.bias = 0;
+  res &= handle_cfi (dwfl, ".debug_frame",
+		     dwfl_module_dwarf_cfi (mod, &stuff.bias), pc, &stuff);
+  free (stuff.frame);
+
+  return res;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  Dwfl *dwfl = NULL;
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl);
+  assert (dwfl != NULL);
+
+  int result = 0;
+
+  /* Now handle the addresses.  In case none are given on the command
+     line, read from stdin.  */
+  if (remaining == argc)
+    {
+      /* We use no threads here which can interfere with handling a stream.  */
+      (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+
+      char *buf = NULL;
+      size_t len = 0;
+      while (!feof_unlocked (stdin))
+	{
+	  if (getline (&buf, &len, stdin) < 0)
+	    break;
+
+	  char *endp;
+	  uintmax_t addr = strtoumax (buf, &endp, 0);
+	  if (endp != buf)
+	    result |= handle_address (addr, dwfl);
+	  else
+	    result = 1;
+	}
+
+      free (buf);
+    }
+  else
+    {
+      do
+	{
+	  char *endp;
+	  uintmax_t addr = strtoumax (argv[remaining], &endp, 0);
+	  if (endp != argv[remaining])
+	    result |= handle_address (addr, dwfl);
+	  else
+	    result = 1;
+	}
+      while (++remaining < argc);
+    }
+
+  dwfl_end (dwfl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/addrscopes.c b/third_party/elfutils/tests/addrscopes.c
new file mode 100644
index 0000000..791569f
--- /dev/null
+++ b/third_party/elfutils/tests/addrscopes.c
@@ -0,0 +1,196 @@
+/* Test program for dwarf_getscopes.
+   Copyright (C) 2005, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+#include <argp.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <error.h>
+#include <string.h>
+
+
+static void
+paddr (const char *prefix, Dwarf_Addr addr, Dwfl_Line *line)
+{
+  const char *src;
+  int lineno, linecol;
+  if (line != NULL
+      && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol,
+			       NULL, NULL)) != NULL)
+    {
+      if (linecol != 0)
+	printf ("%s%#" PRIx64 " (%s:%d:%d)",
+		prefix, addr, src, lineno, linecol);
+      else
+	printf ("%s%#" PRIx64 " (%s:%d)",
+		prefix, addr, src, lineno);
+    }
+  else
+    printf ("%s%#" PRIx64, prefix, addr);
+}
+
+static void
+print_vars (unsigned int indent, Dwarf_Die *die)
+{
+  Dwarf_Die child;
+  if (dwarf_child (die, &child) == 0)
+    do
+      switch (dwarf_tag (&child))
+	{
+	case DW_TAG_variable:
+	case DW_TAG_formal_parameter:
+	  printf ("%*s%-30s[%6" PRIx64 "]\n", indent, "",
+		  dwarf_diename (&child),
+		  (uint64_t) dwarf_dieoffset (&child));
+	  break;
+	default:
+	  break;
+	}
+    while (dwarf_siblingof (&child, &child) == 0);
+
+  Dwarf_Attribute attr_mem;
+  Dwarf_Die origin;
+  if (dwarf_hasattr (die, DW_AT_abstract_origin)
+      && dwarf_formref_die (dwarf_attr (die, DW_AT_abstract_origin, &attr_mem),
+			    &origin) != NULL
+      && dwarf_child (&origin, &child) == 0)
+    do
+      switch (dwarf_tag (&child))
+	{
+	case DW_TAG_variable:
+	case DW_TAG_formal_parameter:
+	  printf ("%*s%s (abstract)\n", indent, "",
+		  dwarf_diename (&child));
+	  break;
+	default:
+	  break;
+	}
+    while (dwarf_siblingof (&child, &child) == 0);
+}
+
+
+#define INDENT 4
+
+static void
+handle_address (GElf_Addr pc, Dwfl *dwfl)
+{
+  Dwarf_Addr cubias;
+  Dwarf_Die *cudie = dwfl_addrdie (dwfl, pc, &cubias);
+  if (cudie == NULL)
+    error (EXIT_FAILURE, 0, "dwfl_addrdie: %s", dwfl_errmsg (-1));
+
+  Dwarf_Die *scopes;
+  int n = dwarf_getscopes (cudie, pc - cubias, &scopes);
+  if (n < 0)
+    error (EXIT_FAILURE, 0, "dwarf_getscopes: %s", dwarf_errmsg (-1));
+  else if (n == 0)
+    printf ("%#" PRIx64 ": not in any scope\n", pc);
+  else
+    {
+      printf ("%#" PRIx64 ":\n", pc);
+      unsigned int indent = 0;
+      while (n-- > 0)
+	{
+	  Dwarf_Die *const die = &scopes[n];
+
+	  indent += INDENT;
+	  printf ("%*s%s (%#x)", indent, "",
+		  dwarf_diename (die) ?: "<unnamed>",
+		  dwarf_tag (die));
+
+	  Dwarf_Addr lowpc, highpc;
+	  if (dwarf_lowpc (die, &lowpc) == 0
+	      && dwarf_highpc (die, &highpc) == 0)
+	    {
+	      lowpc += cubias;
+	      highpc += cubias;
+	      Dwfl_Line *loline = dwfl_getsrc (dwfl, lowpc);
+	      Dwfl_Line *hiline = dwfl_getsrc (dwfl, highpc - 1);
+	      paddr (": ", lowpc, loline);
+	      if (highpc != lowpc)
+		paddr (" .. ", highpc - 1, hiline == loline ? NULL : hiline);
+	    }
+	  puts ("");
+
+	  print_vars (indent + INDENT, die);
+	}
+      free (scopes);
+    }
+}
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  Dwfl *dwfl = NULL;
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl);
+  assert (dwfl != NULL);
+
+  int result = 0;
+
+  /* Now handle the addresses.  In case none are given on the command
+     line, read from stdin.  */
+  if (remaining == argc)
+    {
+      /* We use no threads here which can interfere with handling a stream.  */
+      (void) __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+
+      char *buf = NULL;
+      size_t len = 0;
+      while (!feof_unlocked (stdin))
+	{
+	  if (getline (&buf, &len, stdin) < 0)
+	    break;
+
+	  char *endp;
+	  uintmax_t addr = strtoumax (buf, &endp, 0);
+	  if (endp != buf)
+	    handle_address (addr, dwfl);
+	  else
+	    result = 1;
+	}
+
+      free (buf);
+    }
+  else
+    {
+      do
+	{
+	  char *endp;
+	  uintmax_t addr = strtoumax (argv[remaining], &endp, 0);
+	  if (endp != argv[remaining])
+	    handle_address (addr, dwfl);
+	  else
+	    result = 1;
+	}
+      while (++remaining < argc);
+    }
+
+  dwfl_end (dwfl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/aggregate_size.c b/third_party/elfutils/tests/aggregate_size.c
new file mode 100644
index 0000000..930eafa
--- /dev/null
+++ b/third_party/elfutils/tests/aggregate_size.c
@@ -0,0 +1,83 @@
+/* Test program for dwarf_aggregate_size. Prints size of top-level vars.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <argp.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include ELFUTILS_HEADER(dw)
+#include ELFUTILS_HEADER(dwfl)
+#include <stdio.h>
+#include <unistd.h>
+#include <dwarf.h>
+
+void
+print_var_type_size (Dwarf_Die *var)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Die type_mem;
+  Dwarf_Die *type;
+  const char *name = dwarf_diename (var);
+
+  type = dwarf_formref_die (dwarf_attr (var, DW_AT_type, &attr_mem),
+			    &type_mem);
+  if (type != NULL)
+    {
+      Dwarf_Word size;
+      if (dwarf_aggregate_size (type, &size) < 0)
+        printf ("%s no size: %s\n", name, dwarf_errmsg (-1));
+      else
+	printf ("%s size %" PRIu64 "\n", name, size);
+    }
+  else
+    printf ("%s has no type.\n", name);
+}
+
+int
+main (int argc, char *argv[])
+{
+
+  int remaining;
+  Dwfl *dwfl;
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining,
+                     &dwfl);
+  assert (dwfl != NULL);
+
+  Dwarf_Die *cu = NULL;
+  Dwarf_Addr dwbias;
+  while ((cu = dwfl_nextcu (dwfl, cu, &dwbias)) != NULL)
+    {
+      Dwarf_Die die_mem;
+      Dwarf_Die *die = &die_mem;
+      dwarf_child (cu, &die_mem);
+
+      while (1)
+	{
+	  if (dwarf_tag (die) == DW_TAG_variable)
+	    print_var_type_size (die);
+
+	  if (dwarf_siblingof (die, &die_mem) != 0)
+	    break;
+	}
+    }
+
+  dwfl_end (dwfl);
+}
diff --git a/third_party/elfutils/tests/alldts.c b/third_party/elfutils/tests/alldts.c
new file mode 100644
index 0000000..28b3063
--- /dev/null
+++ b/third_party/elfutils/tests/alldts.c
@@ -0,0 +1,270 @@
+/* Create an ELF file with all the DT_* flags set.
+   Copyright (C) 2011, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Marek Polacek <mpolacek@redhat.com>, 2011.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include ELFUTILS_HEADER(dwelf)
+#include <elf.h>
+#include <gelf.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+int
+main (void)
+{
+  static const char fname[] = "testfile-alldts";
+  Dwelf_Strtab *shst;
+  Dwelf_Strent *dynscn;
+  Dwelf_Strent *shstrtabse;
+  const Elf32_Sword dtflags[] =
+    {
+      DT_NULL, DT_NEEDED, DT_PLTRELSZ, DT_PLTGOT,
+      DT_HASH, DT_STRTAB, DT_SYMTAB, DT_RELA,
+      DT_RELASZ, DT_RELAENT, DT_STRSZ, DT_SYMENT,
+      DT_INIT, DT_FINI, DT_SONAME, DT_RPATH,
+      DT_SYMBOLIC, DT_REL, DT_RELSZ, DT_RELENT,
+      DT_PLTREL, DT_DEBUG, DT_TEXTREL, DT_JMPREL,
+      DT_BIND_NOW, DT_INIT_ARRAY, DT_FINI_ARRAY,
+      DT_INIT_ARRAYSZ, DT_FINI_ARRAYSZ, DT_RUNPATH,
+      DT_FLAGS, DT_ENCODING, DT_PREINIT_ARRAY,
+      DT_PREINIT_ARRAYSZ, DT_VERSYM, DT_GNU_PRELINKED,
+      DT_GNU_CONFLICTSZ, DT_GNU_LIBLISTSZ, DT_CHECKSUM,
+      DT_PLTPADSZ, DT_MOVEENT, DT_MOVESZ, DT_FEATURE_1,
+      DT_POSFLAG_1, DT_SYMINSZ, DT_SYMINENT, DT_GNU_HASH,
+      DT_TLSDESC_PLT, DT_TLSDESC_GOT, DT_GNU_CONFLICT,
+      DT_GNU_LIBLIST, DT_CONFIG, DT_DEPAUDIT, DT_AUDIT,
+      DT_PLTPAD, DT_MOVETAB, DT_SYMINFO, DT_RELACOUNT,
+      DT_RELCOUNT, DT_FLAGS_1, DT_VERDEF, DT_VERDEFNUM,
+      DT_VERNEED, DT_VERNEEDNUM, DT_AUXILIARY, DT_FILTER
+    };
+  const int ndtflags = sizeof (dtflags) / sizeof (dtflags[0]);
+
+  /* We use no threads here which can interfere with handling a stream.  */
+  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+
+  /* Open the file.  */
+  int fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s': %m\n", fname);
+      return 1;
+    }
+
+  /* Tell the library which version are we expecting.  */
+  elf_version (EV_CURRENT);
+
+  /* Create an ELF descriptor.  */
+  Elf *elf = elf_begin (fd, ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  /* Create an ELF header.  */
+  Elf32_Ehdr *ehdr = elf32_newehdr (elf);
+  if (ehdr == NULL)
+    {
+      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  ehdr->e_ident[0] = 42;
+  ehdr->e_ident[5] = 1;
+  ehdr->e_ident[6] = 2;
+  ehdr->e_type = ET_EXEC;
+  ehdr->e_machine = EM_386;
+  ehdr->e_version = 1;
+  ehdr->e_ehsize = 1;
+  ehdr->e_shnum = 3;
+
+  elf_flagehdr (elf, ELF_C_SET, ELF_F_DIRTY);
+
+  /* Create the program headers.  */
+  Elf32_Phdr *phdr = elf32_newphdr (elf, 2);
+  if (phdr == NULL)
+    {
+      printf ("cannot create program headers: %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  phdr[0].p_type = PT_PHDR;
+  phdr[1].p_type = PT_DYNAMIC;
+
+  elf_flagphdr (elf, ELF_C_SET, ELF_F_DIRTY);
+  shst = dwelf_strtab_init (true);
+
+  /* Create the .dynamic section.  */
+  Elf_Scn *scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create DYNAMIC section: %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  Elf32_Shdr *shdr = elf32_getshdr (scn);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for DYNAMIC section: %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  dynscn = dwelf_strtab_add (shst, ".dynamic");
+
+  /* We'll need to know the section offset.  But this will be set up
+     by elf_update later, so for now just store the address.  */
+  const Elf32_Off *const dynscn_offset = &shdr->sh_offset;
+  shdr->sh_type = SHT_DYNAMIC;
+  shdr->sh_flags = SHF_ALLOC | SHF_WRITE;
+  shdr->sh_link = SHN_UNDEF;
+  shdr->sh_info = SHN_UNDEF;
+  /* This section will start here.  */
+  shdr->sh_addr = 0x1a0;
+
+  /* Create new section data.  */
+  Elf_Data *data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot create data for DYNAMIC section: %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  /* Allocate memory for all the .dynamic entries.  */
+  Elf32_Dyn *dyn = malloc (ndtflags * sizeof (Elf32_Dyn));
+  if (dyn == NULL)
+    {
+      printf ("malloc failed: %m\n");
+      return 1;
+    }
+
+  /* Now write all the DT_* flags.  */
+  for (int i = 0; i < ndtflags; ++i)
+    {
+      dyn[i].d_tag = dtflags[i];
+      dyn[i].d_un.d_val = 0xdeadbeef;
+    }
+
+  /* Set the pointer to allocated memory.  */
+  data->d_buf = dyn;
+  data->d_type = ELF_T_DYN;
+  data->d_version = EV_CURRENT;
+  data->d_size = ndtflags * sizeof (Elf32_Dyn);
+  data->d_align = 0x8;
+
+  /* Create .shstrtab section.  */
+  scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create SHSTRTAB section: %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  shdr = elf32_getshdr (scn);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for SHSTRTAB section: %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  shstrtabse = dwelf_strtab_add (shst, ".shstrtab");
+
+  shdr->sh_type = SHT_STRTAB;
+  shdr->sh_flags = 0;
+  shdr->sh_addr = 0;
+  shdr->sh_link = SHN_UNDEF;
+  shdr->sh_info = SHN_UNDEF;
+  shdr->sh_entsize = 1;
+
+  /* We have to store the section index in the ELF header.  */
+  ehdr->e_shstrndx = elf_ndxscn (scn);
+
+  data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot create data SHSTRTAB section: %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  /* No more sections, finalize the section header string table.  */
+  dwelf_strtab_finalize (shst, data);
+
+  elf32_getshdr (elf_getscn (elf, 1))->sh_name = dwelf_strent_off (dynscn);
+  shdr->sh_name = dwelf_strent_off (shstrtabse);
+
+  /* Let the library compute the internal structure information.  */
+  if (elf_update (elf, ELF_C_NULL) < 0)
+    {
+      printf ("failure in elf_update(NULL): %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  ehdr = elf32_getehdr (elf);
+
+  phdr[0].p_offset = ehdr->e_phoff;
+  phdr[0].p_vaddr = ehdr->e_phoff;
+  phdr[0].p_paddr = ehdr->e_phoff;
+  phdr[0].p_flags = PF_R | PF_X;
+  phdr[0].p_filesz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
+  phdr[0].p_memsz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
+  phdr[0].p_align = sizeof (Elf32_Word);
+
+  phdr[1].p_flags = PF_W | PF_R;
+  phdr[1].p_offset = *dynscn_offset;
+  /* Set up the start of this segment to equal start address of the
+     .dynamic section.  */
+  phdr[1].p_vaddr = 0x1a0;
+  phdr[1].p_paddr = 0x1a0;
+  phdr[1].p_align = 2 * sizeof (Elf32_Word);
+  phdr[1].p_filesz = ndtflags * sizeof (Elf32_Dyn);
+  phdr[1].p_memsz = ndtflags * sizeof (Elf32_Dyn);
+
+  /* Write out the file.  */
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  /* We don't need the string table anymore.  */
+  dwelf_strtab_free (shst);
+
+  /* And the data allocated in the .shstrtab section.  */
+  free (data->d_buf);
+
+  /* And the dynamic entries.  */
+  free (dyn);
+
+  /* All done.  */
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      return 1;
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/allfcts.c b/third_party/elfutils/tests/allfcts.c
new file mode 100644
index 0000000..f637311
--- /dev/null
+++ b/third_party/elfutils/tests/allfcts.c
@@ -0,0 +1,112 @@
+/* Copyright (C) 2005, 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <err.h>
+#include <fcntl.h>
+#include ELFUTILS_HEADER(dw)
+#include ELFUTILS_HEADER(dwelf)
+#include <stdio.h>
+#include <unistd.h>
+
+
+static int
+cb (Dwarf_Die *func, void *arg __attribute__ ((unused)))
+{
+  const char *file = dwarf_decl_file (func);
+  int line = -1;
+  dwarf_decl_line (func, &line);
+  const char *fct = dwarf_diename (func);
+
+  printf ("%s:%d:%s\n", file, line, fct);
+
+  return DWARF_CB_ABORT;
+}
+
+static Dwarf *
+setup_alt (Dwarf *main)
+{
+  const char *alt_name;
+  const void *build_id;
+  ssize_t ret = dwelf_dwarf_gnu_debugaltlink (main, &alt_name, &build_id);
+  if (ret == 0)
+    return NULL;
+  if (ret == -1)
+    errx (1, "dwelf_dwarf_gnu_debugaltlink: %s", dwarf_errmsg (-1));
+  int fd = open (alt_name, O_RDONLY);
+  if (fd < 0)
+    {
+      printf ("Warning: no alt file found.\n");
+      return NULL;
+    }
+  Dwarf *dbg_alt = dwarf_begin (fd, DWARF_C_READ);
+  if (dbg_alt == NULL)
+    errx (1, "dwarf_begin (%s): %s", alt_name, dwarf_errmsg (-1));
+  if (elf_cntl (dwarf_getelf (dbg_alt), ELF_C_FDREAD) != 0)
+    errx (1, "elf_cntl (%s, ELF_C_FDREAD): %s", alt_name, elf_errmsg (-1));
+  close (fd);
+  dwarf_setalt (main, dbg_alt);
+  return dbg_alt;
+}
+
+int
+main (int argc, char *argv[])
+{
+  for (int i = 1; i < argc; ++i)
+    {
+      int fd = open (argv[i], O_RDONLY);
+      if (fd < 0)
+	err (1, "open (%s)", argv[i]);
+
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if (dbg != NULL)
+	{
+	  Dwarf_Off off = 0;
+	  size_t cuhl;
+	  Dwarf_Off noff;
+	  Dwarf *dbg_alt = setup_alt (dbg);
+
+	  while (dwarf_nextcu (dbg, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
+	    {
+	      Dwarf_Die die_mem;
+	      Dwarf_Die *die = dwarf_offdie (dbg, off + cuhl, &die_mem);
+
+	      /* Explicitly stop in the callback and then resume each time.  */
+	      ptrdiff_t doff = 0;
+	      do
+		{
+		  doff = dwarf_getfuncs (die, cb, NULL, doff);
+		  if (dwarf_errno () != 0)
+		    errx (1, "dwarf_getfuncs (%s): %s",
+			  argv[i], dwarf_errmsg (-1));
+		}
+	      while (doff != 0);
+
+	      off = noff;
+	    }
+
+	  dwarf_end (dbg_alt);
+	  dwarf_end (dbg);
+	}
+      else
+	errx (1, "dwarf_begin (%s): %s", argv[i], dwarf_errmsg (-1));
+
+      close (fd);
+    }
+}
diff --git a/third_party/elfutils/tests/allregs.c b/third_party/elfutils/tests/allregs.c
new file mode 100644
index 0000000..286f7e3
--- /dev/null
+++ b/third_party/elfutils/tests/allregs.c
@@ -0,0 +1,204 @@
+/* Copyright (C) 2005, 2006, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+#include <locale.h>
+#include <argp.h>
+#include <assert.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+
+#include "../libdw/known-dwarf.h"
+
+static const char *
+dwarf_encoding_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_ATE
+#undef DWARF_ONE_KNOWN_DW_ATE
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+
+static int
+first_module (Dwfl_Module *mod,
+	      void **userdatap __attribute__ ((unused)),
+	      const char *name __attribute__ ((unused)),
+	      Dwarf_Addr low_addr __attribute__ ((unused)),
+	      void *arg)
+{
+  Dwarf_Addr bias;
+  if (dwfl_module_getelf (mod, &bias) == NULL) /* Not really a module.  */
+    return DWARF_CB_OK;
+
+  *(Dwfl_Module **) arg = mod;
+  return DWARF_CB_ABORT;
+}
+
+
+struct state
+{
+  struct reginfo *info;
+  int nregs;
+};
+
+struct reginfo
+{
+  const char *set, *pfx;
+  int regno;
+  int bits;
+  int type;
+  char name[32];
+};
+
+static int
+compare (const void *r1, const void *r2)
+{
+  const struct reginfo *a = r1, *b = r2;
+  if (a->set == b->set)
+    return a->regno - b->regno;
+  if (a->set == NULL)
+    return 1;
+  if (b->set == NULL)
+    return -1;
+  if (!strcmp (a->set, "integer"))
+    return -1;
+  if (!strcmp (b->set, "integer"))
+    return 1;
+  return strcmp (a->set, b->set);
+}
+
+static int
+one_register (void *arg,
+	      int regno,
+	      const char *setname,
+	      const char *prefix,
+	      const char *regname,
+	      int bits, int type)
+{
+  struct state *state = arg;
+
+  if (regno >= state->nregs)
+    {
+      state->info = realloc (state->info, (regno + 1) * sizeof state->info[0]);
+      memset (&state->info[state->nregs], 0,
+	      ((void *) &state->info[regno + 1]
+	       - (void *) &state->info[state->nregs]));
+      state->nregs = regno + 1;
+    }
+
+  state->info[regno].regno = regno;
+  state->info[regno].set = setname;
+  state->info[regno].pfx = prefix;
+  state->info[regno].bits = bits;
+  state->info[regno].type = type;
+  assert (strlen (regname) < sizeof state->info[regno].name);
+  strcpy (state->info[regno].name, regname);
+
+  return DWARF_CB_OK;
+}
+
+
+static int
+match_register (void *arg,
+		int regno,
+		const char *setname,
+		const char *prefix,
+		const char *regname,
+		int bits, int type)
+{
+  if (regno == *(int *) arg)
+    printf ("%5d => %s register %s%s %s %d bits\n",
+	    regno, setname, prefix, regname,
+	    dwarf_encoding_string (type), bits);
+
+  return DWARF_CB_ABORT;
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int remaining;
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  Dwfl *dwfl = NULL;
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl);
+  assert (dwfl != NULL);
+
+  Dwfl_Module *mod = NULL;
+  if (dwfl_getmodules (dwfl, &first_module, &mod, 0) < 0)
+    error (EXIT_FAILURE, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
+
+  if (remaining == argc)
+    {
+      struct state state = { NULL, 0 };
+      int result = dwfl_module_register_names (mod, &one_register, &state);
+      if (result != 0 || state.nregs == 0)
+	error (EXIT_FAILURE, 0, "dwfl_module_register_names: %s",
+	       result ? dwfl_errmsg (-1) : "no backend registers known");
+
+      qsort (state.info, state.nregs, sizeof state.info[0], &compare);
+
+      const char *set = NULL;
+      for (int i = 0; i < state.nregs; ++i)
+	if (state.info[i].set != NULL)
+	  {
+	    if (set != state.info[i].set)
+	      printf ("%s registers:\n", state.info[i].set);
+	    set = state.info[i].set;
+
+	    printf ("\t%3d: %s%s (%s), %s %d bits\n",
+		    state.info[i].regno,
+		    state.info[i].pfx ?: "", state.info[i].name,
+		    state.info[i].name,
+		    dwarf_encoding_string (state.info[i].type),
+		    state.info[i].bits);
+	  }
+      free (state.info);
+    }
+  else
+    do
+      {
+	const char *arg = argv[remaining++];
+	int regno = atoi (arg);
+	int result = dwfl_module_register_names (mod, &match_register, &regno);
+	if (result != DWARF_CB_ABORT)
+	  error (EXIT_FAILURE, 0, "dwfl_module_register_names: %s",
+		 result ? dwfl_errmsg (-1) : "no backend registers known");
+      }
+    while (remaining < argc);
+
+  dwfl_end (dwfl);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/arextract.c b/third_party/elfutils/tests/arextract.c
new file mode 100644
index 0000000..2c4dc75
--- /dev/null
+++ b/third_party/elfutils/tests/arextract.c
@@ -0,0 +1,159 @@
+/* Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <gelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <system.h>
+
+
+int
+main (int argc, char *argv[])
+{
+  int fd;
+  Elf *elf;
+  Elf *subelf;
+  Elf_Cmd cmd;
+  off_t offset;
+  size_t todo;
+
+  if (argc < 4)
+    exit (1);
+
+  /* Open the archive.  */
+  fd = open (argv[1], O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("Cannot open input file: %m");
+      exit (1);
+    }
+
+  /* Set the ELF version.  */
+  elf_version (EV_CURRENT);
+
+  /* Create an ELF descriptor.  */
+  cmd = ELF_C_READ;
+  elf = elf_begin (fd, cmd, NULL);
+  if (elf == NULL)
+    {
+      printf ("Cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* If it is no archive punt.  */
+  if (elf_kind (elf) != ELF_K_AR)
+    {
+      printf ("`%s' is no archive\n", argv[1]);
+      exit (1);
+    }
+
+  /* Get the elements of the archive one after the other.  */
+  while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+    {
+      /* The the header for this element.  */
+      Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+
+      if (arhdr == NULL)
+	{
+	  printf ("cannot get arhdr: %s\n", elf_errmsg (-1));
+	  exit (1);
+	}
+
+      if (strcmp (arhdr->ar_name, argv[2]) == 0)
+	{
+	  int outfd;
+
+	  /* Get the offset of the file in the archive.  */
+	  offset = elf_getbase (subelf);
+	  if (offset == -1)
+	    {
+	      printf ("\
+Failed to get base address for the archive element: %s\n",
+		      elf_errmsg (-1));
+	      exit (1);
+	    }
+
+	  /* Open the output file.  */
+	  outfd = open (argv[3], O_CREAT | O_TRUNC | O_RDWR, 0666);
+	  if (outfd == -1)
+	    {
+	      printf ("cannot open output file: %m");
+	      exit (1);
+	    }
+
+	  /* Now write out the data.  */
+	  todo = arhdr->ar_size;
+	  while (todo > 0)
+	    {
+	      char buf[1024];
+	      ssize_t n = pread (fd, buf, MIN (sizeof buf, todo), offset);
+	      if (n == 0)
+		break;
+
+	      if (write (outfd, buf, n) != n)
+		{
+		  puts ("Writing output failed");
+		  exit (1);
+		}
+
+	      offset += n;
+	      todo -= n;
+	    }
+
+	  /* Check whether all the date was read and written out.  */
+	  if (todo != 0)
+	    {
+	      puts ("Reading archive member failed.");
+	      exit (1);
+	    }
+
+	  /* Close the descriptors.  */
+	  if (elf_end (subelf) != 0 || elf_end (elf) != 0)
+	    {
+	      printf ("Freeing ELF descriptors failed: %s", elf_errmsg (-1));
+	      exit (1);
+	    }
+
+	  close (outfd);
+	  close (fd);
+
+	  /* All went well.  */
+	  exit (0);
+	}
+
+      /* Get next archive element.  */
+      cmd = elf_next (subelf);
+      if (elf_end (subelf) != 0)
+	{
+	  printf ("error while freeing sub-ELF descriptor: %s\n",
+		  elf_errmsg (-1));
+	  exit (1);
+	}
+    }
+
+  /* When we reach this point we haven't found the given file in the
+     archive.  */
+  printf ("File `%s' not found in archive\n", argv[2]);
+  exit (1);
+}
diff --git a/third_party/elfutils/tests/arls.c b/third_party/elfutils/tests/arls.c
new file mode 100644
index 0000000..ca0d3e6
--- /dev/null
+++ b/third_party/elfutils/tests/arls.c
@@ -0,0 +1,111 @@
+/* Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <ar.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+static int handle (const char *fname);
+
+
+int
+main (int argc, char *argv[])
+{
+  elf_version (EV_CURRENT);
+
+  int result = 0;
+  if (argc == 1)
+    result = handle ("a.out");
+  else
+    for (int i = 1; i < argc; ++i)
+      result |= handle (argv[1]);
+
+  return result;
+}
+
+
+static int
+handle (const char *fname)
+{
+  int fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open '%s': %m\n", fname);
+      return 1;
+    }
+
+  Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot get ELF handling for '%s': %s\n",
+	      fname, elf_errmsg (-1));
+      close (fd);
+      return 1;
+    }
+
+  if (elf_kind (elf) != ELF_K_AR)
+    {
+      printf ("'%s' is no archive\n", fname);
+      elf_end (elf);
+      close (fd);
+      return 1;
+    }
+
+  printf ("%s:\n", fname);
+  Elf *subelf = NULL;
+  Elf_Cmd cmd = ELF_C_READ_MMAP;
+  while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+    {
+      Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+      if (arhdr == NULL)
+	{
+	  printf ("cannot get archive header in '%s': %s\n",
+		  fname, elf_errmsg (-1));
+	  elf_end (subelf);
+	  elf_end (elf);
+	  close (fd);
+	  return 1;
+	}
+
+      off_t off = elf_getaroff (subelf);
+
+      printf ("\nOffset    %llu\n"
+	      "  Name    %s\n"
+	      "  Date    %ld\n"
+	      "  UID     %d\n"
+	      "  GID     %d\n"
+	      "  Mode    %o\n"
+	      "  Size    %lld\n",
+	      (unsigned long long int) off,
+	      arhdr->ar_name, (long int) arhdr->ar_date, (int) arhdr->ar_uid,
+	      (int) arhdr->ar_gid,
+	      (int) arhdr->ar_mode, (long long int) arhdr->ar_size);
+
+      cmd = elf_next (subelf);
+      elf_end (subelf);
+    }
+
+  close (fd);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/arsymtest.c b/third_party/elfutils/tests/arsymtest.c
new file mode 100644
index 0000000..c724863
--- /dev/null
+++ b/third_party/elfutils/tests/arsymtest.c
@@ -0,0 +1,136 @@
+/* Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+int
+main (int argc, char *argv[])
+{
+  int fd;
+  FILE *fp;
+  Elf *elf;
+  Elf_Arsym *arsym;
+  size_t narsym;
+
+  if (argc < 3)
+    exit (1);
+
+  /* Open the archive.  */
+  fd = open (argv[1], O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("Cannot open input file: %m");
+      exit (1);
+    }
+
+  /* Open the output file.  */
+  fp = fopen (argv[2], "w");
+  if (fp == NULL)
+    {
+      printf ("Cannot open output file: %m");
+      exit (1);
+    }
+
+  /* Set the ELF version.  */
+  elf_version (EV_CURRENT);
+
+  /* Create an ELF descriptor.  */
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("Cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* If it is no archive punt.  */
+  if (elf_kind (elf) != ELF_K_AR)
+    {
+      printf ("`%s' is no archive\n", argv[1]);
+      exit (1);
+    }
+
+  /* Now get the index of the archive.  */
+  arsym = elf_getarsym (elf, &narsym);
+  if (arsym == NULL)
+    {
+      printf ("Cannot get archive index: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* If there is no element in the index do nothing.  There always is
+     an empty entry at the end which is included in the count and
+     which we want to skip.  */
+  if (narsym-- > 1)
+    while (narsym-- > 0)
+      {
+	Elf *subelf;
+	Elf_Arhdr *arhdr;
+
+	if (elf_rand (elf, arsym[narsym].as_off) != arsym[narsym].as_off)
+	  {
+	    printf ("random access for symbol `%s' fails: %s\n",
+		    arsym[narsym].as_name, elf_errmsg (-1));
+	    exit (1);
+	  }
+
+	subelf = elf_begin (fd, ELF_C_READ, elf);
+	if (subelf == NULL)
+	  {
+	    printf ("Cannot create ELF descriptor for archive member: %s\n",
+		    elf_errmsg (-1));
+	    exit (1);
+	  }
+
+	arhdr = elf_getarhdr (subelf);
+	if (arhdr == NULL)
+	  {
+	    printf ("Cannot get archive header for element `%s': %s\n",
+		    arsym[narsym].as_name, elf_errmsg (-1));
+	    exit (1);
+	  }
+
+	/* Now print what we actually want.  */
+	fprintf (fp, "%s in %s\n", arsym[narsym].as_name, arhdr->ar_name);
+
+	/* Free the ELF descriptor.  */
+	if (elf_end (subelf) != 0)
+	  {
+	    printf ("Error while freeing subELF descriptor: %s\n",
+		    elf_errmsg (-1));
+	    exit (1);
+	  }
+      }
+
+  /* Free the ELF descriptor.  */
+  if (elf_end (elf) != 0)
+    {
+      printf ("Error while freeing ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+  fclose (fp);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/asm-tst1.c b/third_party/elfutils/tests/asm-tst1.c
new file mode 100644
index 0000000..9afc676
--- /dev/null
+++ b/third_party/elfutils/tests/asm-tst1.c
@@ -0,0 +1,256 @@
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include ELFUTILS_HEADER(asm)
+#include <libelf.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static const char fname[] = "asm-tst1-out.o";
+
+
+static const GElf_Ehdr expected_ehdr =
+  {
+    .e_ident = { [EI_MAG0] = ELFMAG0,
+		 [EI_MAG1] = ELFMAG1,
+		 [EI_MAG2] = ELFMAG2,
+		 [EI_MAG3] = ELFMAG3,
+		 [EI_CLASS] = ELFCLASS32,
+		 [EI_DATA] = ELFDATA2LSB,
+		 [EI_VERSION] = EV_CURRENT },
+    .e_type = ET_REL,
+    .e_machine = EM_386,
+    .e_version = EV_CURRENT,
+    .e_shoff = 88,
+    .e_ehsize = sizeof (Elf32_Ehdr),
+    .e_shentsize = sizeof (Elf32_Shdr),
+    .e_shnum = 4,
+    .e_shstrndx = 3
+  };
+
+
+static const char *scnnames[4] =
+  {
+    [0] = "",
+    [1] = ".text",
+    [2] = ".data",
+    [3] = ".shstrtab"
+  };
+
+
+int
+main (void)
+{
+  AsmCtx_t *ctx;
+  AsmScn_t *scn1;
+  AsmScn_t *scn2;
+  int fd;
+  Elf *elf;
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr;
+  int result = 0;
+  size_t cnt;
+
+  elf_version (EV_CURRENT);
+
+  Ebl *ebl = ebl_openbackend_machine (EM_386);
+  if (ebl == NULL)
+    {
+      puts ("cannot open backend library");
+      return 1;
+    }
+
+  ctx = asm_begin (fname, ebl, false);
+  if (ctx == NULL)
+    {
+      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
+      return 1;
+    }
+
+  /* Create two sections.  */
+  scn1 = asm_newscn (ctx, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
+  scn2 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+  if (scn1 == NULL || scn2 == NULL)
+    {
+      printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Special alignment for the .text section.  */
+  if (asm_align (scn1, 32) != 0)
+    {
+      printf ("cannot align .text section: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+
+  /* Create the output file.  */
+  if (asm_end (ctx) != 0)
+    {
+      printf ("cannot create output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Check the file.  */
+  fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open generated file: %m\n");
+      result = 1;
+      goto out;
+    }
+
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      result = 1;
+      goto out_close;
+    }
+  if (elf_kind (elf) != ELF_K_ELF)
+    {
+      puts ("not a valid ELF file");
+      result = 1;
+      goto out_close2;
+    }
+
+  ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
+      result = 1;
+      goto out_close2;
+    }
+
+  if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0)
+    {
+      puts ("ELF header does not match");
+      result = 1;
+      goto out_close2;
+    }
+
+  for (cnt = 1; cnt < 4; ++cnt)
+    {
+      Elf_Scn *scn;
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr;
+
+      scn = elf_getscn (elf, cnt);
+      if (scn == NULL)
+	{
+	  printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+
+      shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  printf ("cannot get section header for section %zd: %s\n",
+		  cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+
+      if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
+		  scnnames[cnt]) != 0)
+	{
+	  printf ("section %zd's name differs: %s vs %s\n", cnt,
+		  elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
+		  scnnames[cnt]);
+	  result = 1;
+	}
+
+      if (shdr->sh_type != (cnt == 3 ? SHT_STRTAB : SHT_PROGBITS))
+	{
+	  printf ("section %zd's type differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_EXECINSTR))
+	  || (cnt == 2 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE))
+	  || (cnt == 3 && shdr->sh_flags != 0))
+	{
+	  printf ("section %zd's flags differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_addr != 0)
+	{
+	  printf ("section %zd's address differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 31) & ~31))
+	{
+	  printf ("section %zd's offset differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt != 3 && shdr->sh_size != 0)
+	  || (cnt == 3 && shdr->sh_size != 23))
+	{
+	  printf ("section %zd's size differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_link != 0)
+	{
+	  printf ("section %zd's link differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_info != 0)
+	{
+	  printf ("section %zd's info differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt == 1 && shdr->sh_addralign != 32)
+	  || (cnt != 1 && shdr->sh_addralign != 1))
+	{
+	  printf ("section %zd's addralign differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_entsize != 0)
+	{
+	  printf ("section %zd's entsize differs\n", cnt);
+	  result = 1;
+	}
+    }
+
+ out_close2:
+  elf_end (elf);
+ out_close:
+  close (fd);
+ out:
+  /* We don't need the file anymore.  */
+  unlink (fname);
+
+  ebl_closebackend (ebl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/asm-tst2.c b/third_party/elfutils/tests/asm-tst2.c
new file mode 100644
index 0000000..2556d0c
--- /dev/null
+++ b/third_party/elfutils/tests/asm-tst2.c
@@ -0,0 +1,278 @@
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include ELFUTILS_HEADER(asm)
+#include <libelf.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static const char fname[] = "asm-tst2-out.o";
+
+
+static const GElf_Ehdr expected_ehdr =
+  {
+    .e_ident = { [EI_MAG0] = ELFMAG0,
+		 [EI_MAG1] = ELFMAG1,
+		 [EI_MAG2] = ELFMAG2,
+		 [EI_MAG3] = ELFMAG3,
+		 [EI_CLASS] = ELFCLASS32,
+		 [EI_DATA] = ELFDATA2LSB,
+		 [EI_VERSION] = EV_CURRENT },
+    .e_type = ET_REL,
+    .e_machine = EM_386,
+    .e_version = EV_CURRENT,
+    .e_shoff = 96,
+    .e_ehsize = sizeof (Elf32_Ehdr),
+    .e_shentsize = sizeof (Elf32_Shdr),
+    .e_shnum = 3,
+    .e_shstrndx = 2
+  };
+
+
+static const char *scnnames[3] =
+  {
+    [0] = "",
+    [1] = ".data",
+    [2] = ".shstrtab"
+  };
+
+
+int
+main (void)
+{
+  AsmCtx_t *ctx;
+  AsmScn_t *scn1;
+  AsmScn_t *scn2;
+  int result = 0;
+  int fd;
+  Elf *elf;
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr;
+  size_t cnt;
+
+  elf_version (EV_CURRENT);
+
+  Ebl *ebl = ebl_openbackend_machine (EM_386);
+  if (ebl == NULL)
+    {
+      puts ("cannot open backend library");
+      return 1;
+    }
+
+  ctx = asm_begin (fname, ebl, false);
+  if (ctx == NULL)
+    {
+      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
+      return 1;
+    }
+
+  /* Create two sections.  */
+  scn1 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+  scn2 = asm_newsubscn (scn1, 1);
+  if (scn1 == NULL || scn2 == NULL)
+    {
+      printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Special alignment for the .text section.  */
+  if (asm_align (scn1, 16) != 0)
+    {
+      printf ("cannot align .text section: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+
+  /* Add a few strings.  */
+  if (asm_addstrz (scn1, "one", 4) != 0)
+    {
+      printf ("cannot insert first string: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+  if (asm_addstrz (scn2, "three", 0) != 0)
+    {
+      printf ("cannot insert second string: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+  if (asm_addstrz (scn1, "two", 4) != 0)
+    {
+      printf ("cannot insert third string: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+
+  /* Create the output file.  */
+  if (asm_end (ctx) != 0)
+    {
+      printf ("cannot create output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Check the file.  */
+  fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open generated file: %m\n");
+      result = 1;
+      goto out;
+    }
+
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      result = 1;
+      goto out_close;
+    }
+  if (elf_kind (elf) != ELF_K_ELF)
+    {
+      puts ("not a valid ELF file");
+      result = 1;
+      goto out_close2;
+    }
+
+  ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
+      result = 1;
+      goto out_close2;
+    }
+
+  if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0)
+    {
+      puts ("ELF header does not match");
+      result = 1;
+      goto out_close2;
+    }
+
+  for (cnt = 1; cnt < 3; ++cnt)
+    {
+      Elf_Scn *scn;
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr;
+
+      scn = elf_getscn (elf, cnt);
+      if (scn == NULL)
+	{
+	  printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+
+      shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  printf ("cannot get section header for section %zd: %s\n",
+		  cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+
+      if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
+		  scnnames[cnt]) != 0)
+	{
+	  printf ("section %zd's name differs: %s vs %s\n", cnt,
+		  elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
+		  scnnames[cnt]);
+	  result = 1;
+	}
+
+      if (shdr->sh_type != (cnt == 2 ? SHT_STRTAB : SHT_PROGBITS))
+	{
+	  printf ("section %zd's type differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE))
+	  || (cnt == 2 && shdr->sh_flags != 0))
+	{
+	  printf ("section %zd's flags differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_addr != 0)
+	{
+	  printf ("section %zd's address differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt == 1 && shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 15) & ~15))
+	  || (cnt == 2
+	      && shdr->sh_offset != (((sizeof (Elf32_Ehdr) + 15) & ~15)
+				     + strlen ("one") + 1
+				     + strlen ("two") + 1
+				     + strlen ("three") + 1)))
+	{
+	  printf ("section %zd's offset differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt == 1 && shdr->sh_size != (strlen ("one") + 1
+					 + strlen ("two") + 1
+					 + strlen ("three") + 1))
+	  || (cnt == 2 && shdr->sh_size != 17))
+	{
+	  printf ("section %zd's size differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_link != 0)
+	{
+	  printf ("section %zd's link differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_info != 0)
+	{
+	  printf ("section %zd's info differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt == 1 && shdr->sh_addralign != 16)
+	  || (cnt != 1 && shdr->sh_addralign != 1))
+	{
+	  printf ("section %zd's addralign differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_entsize != 0)
+	{
+	  printf ("section %zd's entsize differs\n", cnt);
+	  result = 1;
+	}
+    }
+
+ out_close2:
+  elf_end (elf);
+ out_close:
+  close (fd);
+ out:
+  /* We don't need the file anymore.  */
+  unlink (fname);
+
+  ebl_closebackend (ebl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/asm-tst3.c b/third_party/elfutils/tests/asm-tst3.c
new file mode 100644
index 0000000..e52cfbe
--- /dev/null
+++ b/third_party/elfutils/tests/asm-tst3.c
@@ -0,0 +1,339 @@
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include ELFUTILS_HEADER(asm)
+#include <libelf.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static const char fname[] = "asm-tst3-out.o";
+
+
+static const char *scnnames[5] =
+  {
+    [0] = "",
+    [1] = ".data",
+    [2] = ".strtab",
+    [3] = ".symtab",
+    [4] = ".shstrtab"
+  };
+
+
+static unsigned int scntypes[5] =
+  {
+    [0] = SHT_NULL,
+    [1] = SHT_PROGBITS,
+    [2] = SHT_STRTAB,
+    [3] = SHT_SYMTAB,
+    [4] = SHT_STRTAB
+  };
+
+
+int
+main (void)
+{
+  AsmCtx_t *ctx;
+  AsmScn_t *scn1;
+  AsmScn_t *scn2;
+  int result = 0;
+  int fd;
+  Elf *elf;
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr;
+  size_t cnt;
+
+  elf_version (EV_CURRENT);
+
+  Ebl *ebl = ebl_openbackend_machine (EM_386);
+  if (ebl == NULL)
+    {
+      puts ("cannot open backend library");
+      return 1;
+    }
+
+  ctx = asm_begin (fname, ebl, false);
+  if (ctx == NULL)
+    {
+      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
+      return 1;
+    }
+
+  /* Create two sections.  */
+  scn1 = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+  scn2 = asm_newsubscn (scn1, 1);
+  if (scn1 == NULL || scn2 == NULL)
+    {
+      printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Special alignment for the .text section.  */
+  if (asm_align (scn1, 16) != 0)
+    {
+      printf ("cannot align .text section: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+
+  /* Add a few strings with names.  */
+  if (asm_newsym (scn1, "one", 4, STT_OBJECT, STB_GLOBAL) == NULL)
+    {
+      printf ("cannot create first name: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+  if (asm_addstrz (scn1, "one", 4) != 0)
+    {
+      printf ("cannot insert first string: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+  if (asm_newsym (scn2, "three", 6, STT_OBJECT, STB_WEAK) == NULL)
+    {
+      printf ("cannot create second name: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+  if (asm_addstrz (scn2, "three", 0) != 0)
+    {
+      printf ("cannot insert second string: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+  if (asm_newsym (scn1, "two", 4, STT_OBJECT, STB_LOCAL) == NULL)
+    {
+      printf ("cannot create third name: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+  if (asm_addstrz (scn1, "two", 4) != 0)
+    {
+      printf ("cannot insert third string: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+
+  /* Create the output file.  */
+  if (asm_end (ctx) != 0)
+    {
+      printf ("cannot create output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Check the file.  */
+  fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open generated file: %m\n");
+      result = 1;
+      goto out;
+    }
+
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      result = 1;
+      goto out_close;
+    }
+  if (elf_kind (elf) != ELF_K_ELF)
+    {
+      puts ("not a valid ELF file");
+      result = 1;
+      goto out_close2;
+    }
+
+  ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
+      result = 1;
+      goto out_close2;
+    }
+
+  for (cnt = 1; cnt < 5; ++cnt)
+    {
+      Elf_Scn *scn;
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr;
+
+      scn = elf_getscn (elf, cnt);
+      if (scn == NULL)
+	{
+	  printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+
+      shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  printf ("cannot get section header for section %zd: %s\n",
+		  cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+
+      if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
+		  scnnames[cnt]) != 0)
+	{
+	  printf ("section %zd's name differs: %s vs %s\n", cnt,
+		  elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
+		  scnnames[cnt]);
+	  result = 1;
+	}
+
+      if (shdr->sh_type != scntypes[cnt])
+	{
+	  printf ("section %zd's type differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE))
+	  || (cnt != 1 && shdr->sh_flags != 0))
+	{
+	  printf ("section %zd's flags differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_addr != 0)
+	{
+	  printf ("section %zd's address differs\n", cnt);
+	  result = 1;
+	}
+
+      if (cnt == 3)
+	{
+	  Elf_Data *data;
+
+	  if (shdr->sh_link != 2)
+	    {
+	      puts ("symbol table has incorrect link");
+	      result = 1;
+	    }
+
+	  data = elf_getdata (scn, NULL);
+	  if (data == NULL)
+	    {
+	      puts ("cannot get data of symbol table");
+	      result = 1;
+	    }
+	  else
+	    {
+	      size_t inner;
+
+	      for (inner = 1;
+		   inner < (shdr->sh_size
+			    / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT));
+		   ++inner)
+		{
+		  GElf_Sym sym_mem;
+		  GElf_Sym *sym;
+
+		  sym = gelf_getsym (data, inner, &sym_mem);
+		  if (sym == NULL)
+		    {
+		      printf ("cannot get symbol %zu: %s\n",
+			      inner, elf_errmsg (-1));
+		      result = 1;
+		    }
+		  else
+		    {
+		      /* The order of the third and fourth entry depends
+			 on how the hash table is organized.  */
+		      static const char *names[4] =
+			{
+			  [0] = "",
+			  [1] = "two",
+			  [2] = "one",
+			  [3] = "three"
+			};
+		      static const int info[4] =
+			{
+			  [0] = GELF_ST_INFO (STB_LOCAL, STT_NOTYPE),
+			  [1] = GELF_ST_INFO (STB_LOCAL, STT_OBJECT),
+			  [2] = GELF_ST_INFO (STB_GLOBAL, STT_OBJECT),
+			  [3] = GELF_ST_INFO (STB_WEAK, STT_OBJECT)
+			};
+		      static const unsigned value[4] =
+			{
+			  [0] = 0,
+			  [1] = 4,
+			  [2] = 0,
+			  [3] = 8
+			};
+
+		      if (strcmp (names[inner],
+				  elf_strptr (elf, shdr->sh_link,
+					      sym->st_name)) != 0)
+			{
+			  printf ("symbol %zu has different name\n", inner);
+			  result = 1;
+			}
+
+		      if (sym->st_value != value[inner])
+			{
+			  printf ("symbol %zu has wrong value\n", inner);
+			  result = 1;
+			}
+
+		      if (sym->st_other != 0)
+			{
+			  printf ("symbol %zu has wrong other info\n", inner);
+			  result = 1;
+			}
+
+		      if (sym->st_shndx != 1)
+			{
+			  printf ("symbol %zu has wrong section reference\n",
+				  inner);
+			  result = 1;
+			}
+
+		      if (sym->st_info != info[inner])
+			{
+			  printf ("symbol %zu has wrong type or binding\n",
+				  inner);
+			  result = 1;
+			}
+
+		      if ((inner != 3 && sym->st_size != 4)
+			  || (inner == 3 && sym->st_size != 6))
+			{
+			  printf ("symbol %zu has wrong size\n", inner);
+			  result = 1;
+			}
+		    }
+		}
+	    }
+	}
+    }
+
+ out_close2:
+  elf_end (elf);
+ out_close:
+  close (fd);
+ out:
+  /* We don't need the file anymore.  */
+  unlink (fname);
+
+  ebl_closebackend (ebl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/asm-tst4.c b/third_party/elfutils/tests/asm-tst4.c
new file mode 100644
index 0000000..52e9e20
--- /dev/null
+++ b/third_party/elfutils/tests/asm-tst4.c
@@ -0,0 +1,104 @@
+/* Copyright (C) 2002-2012 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include ELFUTILS_HEADER(asm)
+#include <libelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+
+static const char fname[] = "asm-tst4-out.o";
+
+
+int
+main (void)
+{
+  AsmCtx_t *ctx;
+  int result = 0;
+  size_t cnt;
+
+  elf_version (EV_CURRENT);
+
+  Ebl *ebl = ebl_openbackend_machine (EM_386);
+  if (ebl == NULL)
+    {
+      puts ("cannot open backend library");
+      return 1;
+    }
+
+  ctx = asm_begin (fname, ebl, false);
+  if (ctx == NULL)
+    {
+      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
+      return 1;
+    }
+
+  /* Create 66000 sections.  */
+  for (cnt = 0; cnt < 66000; ++cnt)
+    {
+      char buf[20];
+      AsmScn_t *scn;
+
+      /* Create a unique name.  */
+      snprintf (buf, sizeof (buf), ".data.%zu", cnt);
+
+      /* Create the section.  */
+      scn = asm_newscn (ctx, buf, SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+      if (scn == NULL)
+	{
+	  printf ("cannot create section \"%s\" in output file: %s\n",
+		  buf, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+
+      /* Add some content.  */
+      if (asm_adduint32 (scn, cnt) != 0)
+	{
+	  printf ("cannot create content of section \"%s\": %s\n",
+		  buf, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+    }
+
+  /* Create the output file.  */
+  if (asm_end (ctx) != 0)
+    {
+      printf ("cannot create output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  if (result == 0)
+    result = WEXITSTATUS (system ("../src/elflint -q asm-tst4-out.o"));
+
+  /* We don't need the file anymore.  */
+  unlink (fname);
+
+  ebl_closebackend (ebl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/asm-tst5.c b/third_party/elfutils/tests/asm-tst5.c
new file mode 100644
index 0000000..5a29b01
--- /dev/null
+++ b/third_party/elfutils/tests/asm-tst5.c
@@ -0,0 +1,116 @@
+/* Copyright (C) 2002-2012 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include ELFUTILS_HEADER(asm)
+#include <libelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include "system.h"
+
+
+static const char fname[] = "asm-tst5-out.o";
+
+
+int
+main (void)
+{
+  AsmCtx_t *ctx;
+  int result = 0;
+  size_t cnt;
+
+  elf_version (EV_CURRENT);
+
+  Ebl *ebl = ebl_openbackend_machine (EM_386);
+  if (ebl == NULL)
+    {
+      puts ("cannot open backend library");
+      return 1;
+    }
+
+  ctx = asm_begin (fname, ebl, false);
+  if (ctx == NULL)
+    {
+      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
+      return 1;
+    }
+
+  /* Create 66000 sections.  */
+  for (cnt = 0; cnt < 66000; ++cnt)
+    {
+      char buf[20];
+      AsmScn_t *scn;
+
+      /* Create a unique name.  */
+      snprintf (buf, sizeof (buf), ".data.%zu", cnt);
+
+      /* Create the section.  */
+      scn = asm_newscn (ctx, buf, SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+      if (scn == NULL)
+	{
+	  printf ("cannot create section \"%s\" in output file: %s\n",
+		  buf, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+
+      /* Add a name.  */
+      snprintf (buf, sizeof (buf), "%zu", cnt);
+      if (asm_newsym (scn, buf, sizeof (uint32_t), STT_OBJECT,
+		      STB_GLOBAL) == NULL)
+	{
+	  printf ("cannot create symbol \"%s\": %s\n", buf, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+
+      /* Add some content.  */
+      if (asm_adduint32 (scn, cnt) != 0)
+	{
+	  printf ("cannot create content of section \"%s\": %s\n",
+		  buf, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+    }
+
+  /* Create the output file.  */
+  if (asm_end (ctx) != 0)
+    {
+      printf ("cannot create output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  if (result == 0)
+    result = WEXITSTATUS (system ("../src/elflint -q asm-tst5-out.o"));
+
+  /* We don't need the file anymore.  */
+  unlink (fname);
+
+  ebl_closebackend (ebl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/asm-tst6.c b/third_party/elfutils/tests/asm-tst6.c
new file mode 100644
index 0000000..bd9b362
--- /dev/null
+++ b/third_party/elfutils/tests/asm-tst6.c
@@ -0,0 +1,150 @@
+/* Copyright (C) 2002-2012 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include ELFUTILS_HEADER(asm)
+#include <libelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include <system.h>
+
+
+static const char fname[] = "asm-tst6-out.o";
+
+
+int
+main (void)
+{
+  AsmCtx_t *ctx;
+  int result = 0;
+  size_t cnt;
+
+  elf_version (EV_CURRENT);
+
+  Ebl *ebl = ebl_openbackend_machine (EM_386);
+  if (ebl == NULL)
+    {
+      puts ("cannot open backend library");
+      return 1;
+    }
+
+  ctx = asm_begin (fname, ebl, false);
+  if (ctx == NULL)
+    {
+      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
+      return 1;
+    }
+
+  for (cnt = 0; cnt < 22000; ++cnt)
+    {
+      char buf[512];
+      AsmScnGrp_t *grp;
+      AsmScn_t *scn;
+      AsmSym_t *sym;
+
+      snprintf (buf, sizeof (buf), ".grp%zu", cnt);
+      grp = asm_newscngrp (ctx, buf, NULL, 0);
+      if (grp == NULL)
+	{
+	  printf ("cannot section group %zu: %s\n", cnt, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+
+      scn = asm_newscn_ingrp (ctx, ".data", SHT_PROGBITS,
+			      SHF_ALLOC | SHF_WRITE, grp);
+      if (scn == NULL)
+	{
+	  printf ("cannot data section for group %zu: %s\n",
+		  cnt, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+
+      /* Add a name.  */
+      snprintf (buf, sizeof (buf), "%zu", cnt);
+      sym = asm_newsym (scn, buf, sizeof (uint32_t), STT_OBJECT,
+			STB_GLOBAL);
+      if (sym == NULL)
+	{
+	  printf ("cannot create symbol \"%s\": %s\n", buf, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+
+      /* Add some content.  */
+      if (asm_adduint32 (scn, cnt) != 0)
+	{
+	  printf ("cannot create content of section \"%s\": %s\n",
+		  buf, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+
+      /* Now we have a symbol, use it as the signature.  */
+      if (asm_scngrp_newsignature (grp, sym) != 0)
+	{
+	  printf ("cannot set signature for section group %zu: %s\n",
+		  cnt, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+
+      /* Create a phony debug info section.  */
+      scn = asm_newscn_ingrp (ctx, ".stab", SHT_PROGBITS, 0, grp);
+      if (scn == NULL)
+	{
+	  printf ("cannot stab section for group %zu: %s\n",
+		  cnt, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+
+      /* Add some content.  */
+      if (asm_adduint32 (scn, cnt) != 0)
+	{
+	  printf ("cannot create content of section \"%s\": %s\n",
+		  buf, asm_errmsg (-1));
+	  asm_abort (ctx);
+	  return 1;
+	}
+    }
+
+  /* Create the output file.  */
+  if (asm_end (ctx) != 0)
+    {
+      printf ("cannot create output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  if (result == 0)
+    result = WEXITSTATUS (system ("../src/elflint -q asm-tst6-out.o"));
+
+  /* We don't need the file anymore.  */
+  unlink (fname);
+
+  ebl_closebackend (ebl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/asm-tst7.c b/third_party/elfutils/tests/asm-tst7.c
new file mode 100644
index 0000000..00cb2bf
--- /dev/null
+++ b/third_party/elfutils/tests/asm-tst7.c
@@ -0,0 +1,181 @@
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include ELFUTILS_HEADER(asm)
+#include <libelf.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+static const char fname[] = "asm-tst7-out.o";
+
+
+int
+main (void)
+{
+  int result = 0;
+  size_t cnt;
+  AsmCtx_t *ctx;
+  Elf *elf;
+  int fd;
+
+  elf_version (EV_CURRENT);
+
+  Ebl *ebl = ebl_openbackend_machine (EM_386);
+  if (ebl == NULL)
+    {
+      puts ("cannot open backend library");
+      return 1;
+    }
+
+  ctx = asm_begin (fname, ebl, false);
+  if (ctx == NULL)
+    {
+      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
+      return 1;
+    }
+
+  if (asm_newcomsym (ctx, "commsym", 4, 16) == NULL)
+    {
+      printf ("cannot create common symbol: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Create the output file.  */
+  if (asm_end (ctx) != 0)
+    {
+      printf ("cannot create output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Check the file.  */
+  fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open generated file: %m\n");
+      result = 1;
+      goto out;
+    }
+
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      result = 1;
+      goto out_close;
+    }
+  if (elf_kind (elf) != ELF_K_ELF)
+    {
+      puts ("not a valid ELF file");
+      result = 1;
+      goto out_close2;
+    }
+
+  for (cnt = 1; 1; ++cnt)
+    {
+      Elf_Scn *scn;
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr;
+
+      scn = elf_getscn (elf, cnt);
+      if (scn == NULL)
+	{
+	  printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+
+      shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  printf ("cannot get section header for section %zd: %s\n",
+		  cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+      /* We are looking for the symbol table.  */
+      if (shdr->sh_type != SHT_SYMTAB)
+	continue;
+
+      for (cnt = 1; cnt< (shdr->sh_size
+			  / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT));
+	   ++cnt)
+	{
+	  GElf_Sym sym_mem;
+	  GElf_Sym *sym;
+
+	  if (cnt > 1)
+	    {
+	      puts ("too many symbol");
+	      result = 1;
+	      break;
+	    }
+
+	  sym = gelf_getsym (elf_getdata (scn, NULL), cnt, &sym_mem);
+	  if (sym == NULL)
+	    {
+	      printf ("cannot get symbol %zu: %s\n", cnt, elf_errmsg (-1));
+	      result = 1;
+	    }
+	  else
+	    {
+	      if (sym->st_shndx != SHN_COMMON)
+		{
+		  printf ("expected common symbol, got section %u\n",
+			  (unsigned int) sym->st_shndx);
+		  result = 1;
+		}
+
+	      if (sym->st_value != 16)
+		{
+		  printf ("requested alignment 16, is %" PRIuMAX "\n",
+			  (uintmax_t) sym->st_value);
+		  result = 1;
+		}
+
+	      if (sym->st_size != 4)
+		{
+		  printf ("requested size 4, is %" PRIuMAX "\n",
+			  (uintmax_t) sym->st_value);
+		  result = 1;
+		}
+	    }
+	}
+
+      break;
+    }
+
+ out_close2:
+  elf_end (elf);
+ out_close:
+  close (fd);
+ out:
+  /* We don't need the file anymore.  */
+  unlink (fname);
+
+  ebl_closebackend (ebl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/asm-tst8.c b/third_party/elfutils/tests/asm-tst8.c
new file mode 100644
index 0000000..4fb0d99
--- /dev/null
+++ b/third_party/elfutils/tests/asm-tst8.c
@@ -0,0 +1,189 @@
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include ELFUTILS_HEADER(asm)
+#include <libelf.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+static const char fname[] = "asm-tst8-out.o";
+
+
+int
+main (void)
+{
+  int result = 0;
+  size_t cnt;
+  AsmCtx_t *ctx;
+  Elf *elf;
+  int fd;
+
+  elf_version (EV_CURRENT);
+
+  Ebl *ebl = ebl_openbackend_machine (EM_386);
+  if (ebl == NULL)
+    {
+      puts ("cannot open backend library");
+      return 1;
+    }
+
+  ctx = asm_begin (fname, ebl, false);
+  if (ctx == NULL)
+    {
+      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
+      return 1;
+    }
+
+  if (asm_newabssym (ctx, "tst8-out.s", 4, 0xfeedbeef, STT_FILE, STB_LOCAL)
+      == NULL)
+    {
+      printf ("cannot create absolute symbol: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Create the output file.  */
+  if (asm_end (ctx) != 0)
+    {
+      printf ("cannot create output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Check the file.  */
+  fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open generated file: %m\n");
+      result = 1;
+      goto out;
+    }
+
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      result = 1;
+      goto out_close;
+    }
+  if (elf_kind (elf) != ELF_K_ELF)
+    {
+      puts ("not a valid ELF file");
+      result = 1;
+      goto out_close2;
+    }
+
+  for (cnt = 1; 1; ++cnt)
+    {
+      Elf_Scn *scn;
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr;
+
+      scn = elf_getscn (elf, cnt);
+      if (scn == NULL)
+	{
+	  printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+
+      shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  printf ("cannot get section header for section %zd: %s\n",
+		  cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+      /* We are looking for the symbol table.  */
+      if (shdr->sh_type != SHT_SYMTAB)
+	continue;
+
+      for (cnt = 1; cnt< (shdr->sh_size
+			  / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT));
+	   ++cnt)
+	{
+	  GElf_Sym sym_mem;
+	  GElf_Sym *sym;
+
+	  if (cnt > 1)
+	    {
+	      puts ("too many symbol");
+	      result = 1;
+	      break;
+	    }
+
+	  sym = gelf_getsym (elf_getdata (scn, NULL), cnt, &sym_mem);
+	  if (sym == NULL)
+	    {
+	      printf ("cannot get symbol %zu: %s\n", cnt, elf_errmsg (-1));
+	      result = 1;
+	    }
+	  else
+	    {
+	      if (sym->st_shndx != SHN_ABS)
+		{
+		  printf ("expected common symbol, got section %u\n",
+			  (unsigned int) sym->st_shndx);
+		  result = 1;
+		}
+
+	      if (sym->st_value != 0xfeedbeef)
+		{
+		  printf ("requested value 0xfeedbeef, is %#" PRIxMAX "\n",
+			  (uintmax_t) sym->st_value);
+		  result = 1;
+		}
+
+	      if (sym->st_size != 4)
+		{
+		  printf ("requested size 4, is %" PRIuMAX "\n",
+			  (uintmax_t) sym->st_value);
+		  result = 1;
+		}
+
+	      if (GELF_ST_TYPE (sym->st_info) != STT_FILE)
+		{
+		  printf ("requested type FILE, is %u\n",
+			  (unsigned int) GELF_ST_TYPE (sym->st_info));
+		  result = 1;
+		}
+	    }
+	}
+
+      break;
+    }
+
+ out_close2:
+  elf_end (elf);
+ out_close:
+  close (fd);
+ out:
+  /* We don't need the file anymore.  */
+  unlink (fname);
+
+  ebl_closebackend (ebl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/asm-tst9.c b/third_party/elfutils/tests/asm-tst9.c
new file mode 100644
index 0000000..b6d0e43
--- /dev/null
+++ b/third_party/elfutils/tests/asm-tst9.c
@@ -0,0 +1,335 @@
+/* Copyright (C) 2002-2010 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include ELFUTILS_HEADER(asm)
+#include <libelf.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static const char fname[] = "asm-tst9-out.o";
+
+
+static int32_t input[] =
+  {
+    0, 1, 129, 510, 2000, 33000, 0x7ffffff, 0x7fffffff
+  };
+#define ninput (sizeof (input) / sizeof (input[0]))
+
+
+static const GElf_Ehdr expected_ehdr =
+  {
+    .e_ident = { [EI_MAG0] = ELFMAG0,
+		 [EI_MAG1] = ELFMAG1,
+		 [EI_MAG2] = ELFMAG2,
+		 [EI_MAG3] = ELFMAG3,
+		 [EI_CLASS] = ELFCLASS32,
+		 [EI_DATA] = ELFDATA2LSB,
+		 [EI_VERSION] = EV_CURRENT },
+    .e_type = ET_REL,
+    .e_machine = EM_386,
+    .e_version = EV_CURRENT,
+    .e_shoff = 180,
+    .e_ehsize = sizeof (Elf32_Ehdr),
+    .e_shentsize = sizeof (Elf32_Shdr),
+    .e_shnum = 3,
+    .e_shstrndx = 2
+  };
+
+
+static const char *scnnames[3] =
+  {
+    [0] = "",
+    [1] = ".data",
+    [2] = ".shstrtab"
+  };
+
+
+static const char expecteddata[] =
+  {
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x7f,
+    0x81, 0x01, 0x81, 0x01, 0xff, 0xfe, 0xff, 0xff, 0x0f, 0xff, 0x7e, 0xfe,
+    0x03, 0xfe, 0x03, 0x82, 0xfc, 0xff, 0xff, 0x0f, 0x82, 0x7c, 0xd0, 0x0f,
+    0xd0, 0x0f, 0xb0, 0xf0, 0xff, 0xff, 0x0f, 0xb0, 0x70, 0xe8, 0x81, 0x02,
+    0xe8, 0x81, 0x02, 0x98, 0xfe, 0xfd, 0xff, 0x0f, 0x98, 0xfe, 0x7d, 0xff,
+    0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0x81, 0x80, 0x80, 0xc0, 0x0f,
+    0x81, 0x80, 0x80, 0x40, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff,
+    0xff, 0x07, 0x81, 0x80, 0x80, 0x80, 0x08, 0x81, 0x80, 0x80, 0x80, 0x78
+  };
+
+
+int
+main (void)
+{
+  AsmCtx_t *ctx;
+  AsmScn_t *scn;
+  int result = 0;
+  int fd;
+  Elf *elf;
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr;
+  size_t cnt;
+
+  elf_version (EV_CURRENT);
+
+  Ebl *ebl = ebl_openbackend_machine (EM_386);
+  if (ebl == NULL)
+    {
+      puts ("cannot open backend library");
+      return 1;
+    }
+
+  ctx = asm_begin (fname, ebl, false);
+  if (ctx == NULL)
+    {
+      printf ("cannot create assembler context: %s\n", asm_errmsg (-1));
+      return 1;
+    }
+
+  /* Create two sections.  */
+  scn = asm_newscn (ctx, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
+  if (scn == NULL)
+    {
+      printf ("cannot create section in output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Special alignment for the .text section.  */
+  if (asm_align (scn, 16) != 0)
+    {
+      printf ("cannot align .text section: %s\n", asm_errmsg (-1));
+      result = 1;
+    }
+
+  /* Add a few ULEB128 and SLEB128 numbers.  */
+  for (cnt = 0; cnt < ninput; ++cnt)
+    {
+      if (asm_adduleb128 (scn, input[cnt]) != 0)
+	{
+	  printf ("cannot insert uleb %" PRIu32 ": %s\n",
+		  (uint32_t) input[cnt], asm_errmsg (-1));
+	  result = 1;
+	}
+
+      if (asm_addsleb128 (scn, input[cnt]) != 0)
+	{
+	  printf ("cannot insert sleb %" PRId32 ": %s\n",
+		  input[cnt], asm_errmsg (-1));
+	  result = 1;
+	}
+
+      if (asm_adduleb128 (scn, -input[cnt]) != 0)
+	{
+	  printf ("cannot insert uleb %" PRIu32 ": %s\n",
+		  (uint32_t) -input[cnt], asm_errmsg (-1));
+	  result = 1;
+	}
+
+      if (asm_addsleb128 (scn, -input[cnt]) != 0)
+	{
+	  printf ("cannot insert sleb %" PRId32 ": %s\n",
+		  -input[cnt], asm_errmsg (-1));
+	  result = 1;
+	}
+    }
+
+  /* Create the output file.  */
+  if (asm_end (ctx) != 0)
+    {
+      printf ("cannot create output file: %s\n", asm_errmsg (-1));
+      asm_abort (ctx);
+      return 1;
+    }
+
+  /* Check the file.  */
+  fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open generated file: %m\n");
+      result = 1;
+      goto out;
+    }
+
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      result = 1;
+      goto out_close;
+    }
+  if (elf_kind (elf) != ELF_K_ELF)
+    {
+      puts ("not a valid ELF file");
+      result = 1;
+      goto out_close2;
+    }
+
+  ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
+      result = 1;
+      goto out_close2;
+    }
+
+  if (memcmp (ehdr, &expected_ehdr, sizeof (GElf_Ehdr)) != 0)
+    {
+      puts ("ELF header does not match");
+      result = 1;
+      goto out_close2;
+    }
+
+  for (cnt = 1; cnt < 3; ++cnt)
+    {
+      Elf_Scn *escn;
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr;
+
+      escn = elf_getscn (elf, cnt);
+      if (escn == NULL)
+	{
+	  printf ("cannot get section %zd: %s\n", cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+
+      shdr = gelf_getshdr (escn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  printf ("cannot get section header for section %zd: %s\n",
+		  cnt, elf_errmsg (-1));
+	  result = 1;
+	  continue;
+	}
+
+      if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
+		  scnnames[cnt]) != 0)
+	{
+	  printf ("section %zd's name differs: %s vs %s\n", cnt,
+		  elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
+		  scnnames[cnt]);
+	  result = 1;
+	}
+
+      if (shdr->sh_type != (cnt == 2 ? SHT_STRTAB : SHT_PROGBITS))
+	{
+	  printf ("section %zd's type differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt == 1 && shdr->sh_flags != (SHF_ALLOC | SHF_WRITE))
+	  || (cnt == 2 && shdr->sh_flags != 0))
+	{
+	  printf ("section %zd's flags differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_addr != 0)
+	{
+	  printf ("section %zd's address differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt == 1 && shdr->sh_offset != ((sizeof (Elf32_Ehdr) + 15) & ~15))
+	  || (cnt == 2
+	      && shdr->sh_offset != (((sizeof (Elf32_Ehdr) + 15) & ~15)
+				     + sizeof (expecteddata))))
+	{
+	  printf ("section %zd's offset differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt == 1 && shdr->sh_size != sizeof (expecteddata))
+	  || (cnt == 2 && shdr->sh_size != 17))
+	{
+	  printf ("section %zd's size differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_link != 0)
+	{
+	  printf ("section %zd's link differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_info != 0)
+	{
+	  printf ("section %zd's info differs\n", cnt);
+	  result = 1;
+	}
+
+      if ((cnt == 1 && shdr->sh_addralign != 16)
+	  || (cnt != 1 && shdr->sh_addralign != 1))
+	{
+	  printf ("section %zd's addralign differs\n", cnt);
+	  result = 1;
+	}
+
+      if (shdr->sh_entsize != 0)
+	{
+	  printf ("section %zd's entsize differs\n", cnt);
+	  result = 1;
+	}
+
+      if (cnt == 1)
+	{
+	  Elf_Data *data = elf_getdata (escn, NULL);
+
+	  if (data == NULL)
+	    {
+	      printf ("cannot get data of section %zd\n", cnt);
+	      result = 1;
+	    }
+	  else
+	    {
+	      if (data->d_size != sizeof (expecteddata))
+		{
+		  printf ("data block size of section %zd wrong: got %zd, "
+			  "expected 96\n", cnt, data->d_size);
+		  result = 1;
+		}
+
+	      if (memcmp (data->d_buf, expecteddata, sizeof (expecteddata))
+		  != 0)
+		{
+		  printf ("data block content of section %zd wrong\n", cnt);
+		  result = 1;
+		}
+	    }
+	}
+    }
+
+ out_close2:
+  elf_end (elf);
+ out_close:
+  close (fd);
+ out:
+  /* We don't need the file anymore.  */
+  unlink (fname);
+
+  ebl_closebackend (ebl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/backtrace-child.c b/third_party/elfutils/tests/backtrace-child.c
new file mode 100644
index 0000000..2c27414
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace-child.c
@@ -0,0 +1,250 @@
+/* Test child for parent backtrace test.
+   Copyright (C) 2013, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Command line syntax: ./backtrace-child [--ptraceme|--gencore]
+   --ptraceme will call ptrace (PTRACE_TRACEME) in the two threads.
+   --gencore will call abort () at its end.
+   Main thread will signal SIGUSR2.  Other thread will signal SIGUSR1.
+   There used to be a difference between x86_64 and other architectures.
+   To test getting a signal at the very first instruction of a function:
+     PC will get changed to function 'jmp' by backtrace.c function
+     prepare_thread.  Then SIGUSR2 will be signalled to backtrace-child
+     which will invoke function sigusr2.
+     This is all done so that signal interrupts execution of the very first
+     instruction of a function.  Properly handled unwind should not slip into
+     the previous unrelated function.
+     The tested functionality is arch-independent but the code reproducing it
+     has to be arch-specific.
+   On non-x86_64:
+     sigusr2 gets called by normal function call from function stdarg.
+   On any arch then sigusr2 calls raise (SIGUSR1) for --ptraceme.
+   abort () is called otherwise, expected for --gencore core dump.
+
+   Expected x86_64 output:
+   TID 10276:
+   # 0 0x7f7ab61e9e6b      raise
+   # 1 0x7f7ab661af47 - 1  main
+   # 2 0x7f7ab5e3bb45 - 1  __libc_start_main
+   # 3 0x7f7ab661aa09 - 1  _start
+   TID 10278:
+   # 0 0x7f7ab61e9e6b      raise
+   # 1 0x7f7ab661ab3c - 1  sigusr2
+   # 2 0x7f7ab5e4fa60      __restore_rt
+   # 3 0x7f7ab661ab47      jmp
+   # 4 0x7f7ab661ac92 - 1  stdarg
+   # 5 0x7f7ab661acba - 1  backtracegen
+   # 6 0x7f7ab661acd1 - 1  start
+   # 7 0x7f7ab61e2c53 - 1  start_thread
+   # 8 0x7f7ab5f0fdbd - 1  __clone
+
+   Expected non-x86_64 (i386) output; __kernel_vsyscall are skipped if found:
+   TID 10408:
+   # 0 0xf779f430          __kernel_vsyscall
+   # 1 0xf7771466 - 1      raise
+   # 2 0xf77c1d07 - 1      main
+   # 3 0xf75bd963 - 1      __libc_start_main
+   # 4 0xf77c1761 - 1      _start
+   TID 10412:
+   # 0 0xf779f430          __kernel_vsyscall
+   # 1 0xf7771466 - 1      raise
+   # 2 0xf77c18f4 - 1      sigusr2
+   # 3 0xf77c1a10 - 1      stdarg
+   # 4 0xf77c1a2c - 1      backtracegen
+   # 5 0xf77c1a48 - 1      start
+   # 6 0xf77699da - 1      start_thread
+   # 7 0xf769bbfe - 1      __clone
+
+   But the raise jmp patching was unreliable. It depends on the CFI for the raise()
+   function in glibc to be the same as for the jmp() function. This is not always
+   the case. Some newer glibc versions rewrote raise() and now the CFA is calculated
+   differently. So we disable raise jmp patching everywhere.
+   */
+
+#ifdef __x86_64__
+/* #define RAISE_JMP_PATCHING 1 */
+#endif
+
+#include <config.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifndef __linux__
+
+int
+main (int argc __attribute__ ((unused)), char **argv)
+{
+  fprintf (stderr, "%s: Unwinding not supported for this architecture\n",
+           argv[0]);
+  return 77;
+}
+
+#else /* __linux__ */
+#include <sys/ptrace.h>
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#define NOINLINE_NOCLONE __attribute__ ((noinline, noclone))
+#else
+#define NOINLINE_NOCLONE __attribute__ ((noinline))
+#endif
+
+#define NORETURN __attribute__ ((noreturn))
+#define UNUSED __attribute__ ((unused))
+#define USED __attribute__ ((used))
+
+static int ptraceme, gencore;
+
+/* Execution will arrive here from jmp by an artificial ptrace-spawn signal.  */
+
+static NOINLINE_NOCLONE void
+sigusr2 (int signo)
+{
+  assert (signo == SIGUSR2);
+  if (! gencore)
+    {
+      raise (SIGUSR1);
+      /* Do not return as stack may be invalid due to ptrace-patched PC to the
+	 jmp function.  */
+      pthread_exit (NULL);
+      /* Not reached.  */
+      abort ();
+    }
+  /* Here we dump the core for --gencore.  */
+  raise (SIGABRT);
+  /* Avoid tail call optimization for the raise call.  */
+  asm volatile ("");
+}
+
+static NOINLINE_NOCLONE void
+dummy1 (void)
+{
+  asm volatile ("");
+}
+
+#ifdef RAISE_JMP_PATCHING
+static NOINLINE_NOCLONE USED void
+jmp (void)
+{
+  /* Not reached, signal will get ptrace-spawn to jump into sigusr2.  */
+  abort ();
+}
+#endif
+
+static NOINLINE_NOCLONE void
+dummy2 (void)
+{
+  asm volatile ("");
+}
+
+static NOINLINE_NOCLONE NORETURN void
+stdarg (int f UNUSED, ...)
+{
+  sighandler_t sigusr2_orig = signal (SIGUSR2, sigusr2);
+  assert (sigusr2_orig == SIG_DFL);
+  errno = 0;
+  if (ptraceme)
+    {
+      long l = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
+      assert (errno == 0);
+      assert (l == 0);
+    }
+#ifdef RAISE_JMP_PATCHING
+  if (! gencore)
+    {
+      /* Execution will get PC patched into function jmp.  */
+      raise (SIGUSR1);
+    }
+#endif
+  sigusr2 (SIGUSR2);
+  /* Not reached.  */
+  abort ();
+}
+
+static NOINLINE_NOCLONE void
+dummy3 (void)
+{
+  asm volatile ("");
+}
+
+static NOINLINE_NOCLONE void
+backtracegen (void)
+{
+  stdarg (1);
+  /* Here should be no instruction after the stdarg call as it is noreturn
+     function.  It must be stdarg so that it is a call and not jump (jump as
+     a tail-call).  */
+}
+
+static NOINLINE_NOCLONE void
+dummy4 (void)
+{
+  asm volatile ("");
+}
+
+static void *
+start (void *arg UNUSED)
+{
+  backtracegen ();
+  /* Not reached.  */
+  abort ();
+}
+
+int
+main (int argc UNUSED, char **argv)
+{
+  setbuf (stdout, NULL);
+  assert (*argv++);
+  ptraceme = (*argv && strcmp (*argv, "--ptraceme") == 0);
+  argv += ptraceme;
+  gencore = (*argv && strcmp (*argv, "--gencore") == 0);
+  argv += gencore;
+  assert (!*argv);
+  /* These dummy* functions are there so that each of their surrounding
+     functions has some unrelated code around.  The purpose of some of the
+     tests is verify unwinding the very first / after the very last instruction
+     does not inappropriately slip into the unrelated code around.  */
+  dummy1 ();
+  dummy2 ();
+  dummy3 ();
+  dummy4 ();
+  if (gencore)
+    printf ("%ld\n", (long) getpid ());
+  pthread_t thread;
+  int i = pthread_create (&thread, NULL, start, NULL);
+  // pthread_* functions do not set errno.
+  assert (i == 0);
+  if (ptraceme)
+    {
+      errno = 0;
+      long l = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
+      assert (errno == 0);
+      assert (l == 0);
+    }
+  if (gencore)
+    pthread_join (thread, NULL);
+  else
+    raise (SIGUSR2);
+  return 0;
+}
+
+#endif /* ! __linux__ */
+
diff --git a/third_party/elfutils/tests/backtrace-data.c b/third_party/elfutils/tests/backtrace-data.c
new file mode 100644
index 0000000..a387d8f
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace-data.c
@@ -0,0 +1,341 @@
+/* Test custom provided Dwfl_Thread_Callbacks vector.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Test custom provided Dwfl_Thread_Callbacks vector.  Test mimics what
+   a ptrace based vector would do.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <locale.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <error.h>
+#include <unistd.h>
+#include <dwarf.h>
+#if defined(__x86_64__) && defined(__linux__)
+#include <sys/resource.h>
+#include <sys/ptrace.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/user.h>
+#include <fcntl.h>
+#include <string.h>
+#include ELFUTILS_HEADER(dwfl)
+#endif
+
+#if !defined(__x86_64__) || !defined(__linux__)
+
+int
+main (int argc __attribute__ ((unused)), char **argv)
+{
+  fprintf (stderr, "%s: Unwinding not supported for this architecture\n",
+          argv[0]);
+  return 77;
+}
+
+#else /* __x86_64__ && __linux__ */
+
+/* The only arch specific code is set_initial_registers.  */
+
+static int
+find_elf (Dwfl_Module *mod __attribute__ ((unused)),
+	  void **userdata __attribute__ ((unused)),
+	  const char *modname __attribute__ ((unused)),
+	  Dwarf_Addr base __attribute__ ((unused)),
+	  char **file_name __attribute__ ((unused)),
+	  Elf **elfp __attribute__ ((unused)))
+{
+  /* Not used as modules are reported explicitly.  */
+  assert (0);
+}
+
+static bool
+memory_read (Dwfl *dwfl, Dwarf_Addr addr, Dwarf_Word *result,
+	     void *dwfl_arg __attribute__ ((unused)))
+{
+  pid_t child = dwfl_pid (dwfl);
+
+  errno = 0;
+  long l = ptrace (PTRACE_PEEKDATA, child, (void *) (uintptr_t) addr, NULL);
+
+  // The unwinder can ask for an invalid address.
+  // Don't assert on that but just politely refuse.
+  if (errno != 0) {
+      errno = 0;
+      return false;
+  }
+  *result = l;
+
+  return true;
+}
+
+/* Return filename and VMA address *BASEP where its mapping starts which
+   contains ADDR.  */
+
+static char *
+maps_lookup (pid_t pid, Dwarf_Addr addr, GElf_Addr *basep)
+{
+  char *fname;
+  int i = asprintf (&fname, "/proc/%ld/maps", (long) pid);
+  assert (errno == 0);
+  assert (i > 0);
+  FILE *f = fopen (fname, "r");
+  assert (errno == 0);
+  assert (f);
+  free (fname);
+  for (;;)
+    {
+      // 37e3c22000-37e3c23000 rw-p 00022000 00:11 49532 /lib64/ld-2.14.90.so */
+      unsigned long start, end, offset;
+      i = fscanf (f, "%lx-%lx %*s %lx %*x:%*x %*x", &start, &end, &offset);
+      assert (errno == 0);
+      if (i != 3)
+          break;
+      char *filename = strdup ("");
+      assert (filename);
+      size_t filename_len = 0;
+      for (;;)
+	{
+	  int c = fgetc (f);
+	  assert (c != EOF);
+	  if (c == '\n')
+	    break;
+	  if (c == ' ' && *filename == '\0')
+	    continue;
+	  filename = realloc (filename, filename_len + 2);
+	  assert (filename);
+	  filename[filename_len++] = c;
+	  filename[filename_len] = '\0';
+	}
+      if (start <= addr && addr < end)
+	{
+	  i = fclose (f);
+	  assert (errno == 0);
+	  assert (i == 0);
+
+	  *basep = start - offset;
+	  return filename;
+	}
+      free (filename);
+    }
+  *basep = 0;
+  return NULL;
+}
+
+/* Add module containing ADDR to the DWFL address space.
+
+   dwfl_report_elf call here violates Dwfl manipulation as one should call
+   dwfl_report only between dwfl_report_begin_add and dwfl_report_end.
+   Current elfutils implementation does not mind as dwfl_report_begin_add is
+   empty.  */
+
+static Dwfl_Module *
+report_module (Dwfl *dwfl, pid_t child, Dwarf_Addr addr)
+{
+  GElf_Addr base;
+  char *long_name = maps_lookup (child, addr, &base);
+  if (!long_name)
+      return NULL; // not found
+  Dwfl_Module *mod = dwfl_report_elf (dwfl, long_name, long_name, -1,
+				      base, false /* add_p_vaddr */);
+  assert (mod);
+  free (long_name);
+  assert (dwfl_addrmodule (dwfl, addr) == mod);
+  return mod;
+}
+
+static pid_t
+next_thread (Dwfl *dwfl, void *dwfl_arg __attribute__ ((unused)),
+	     void **thread_argp)
+{
+  if (*thread_argp != NULL)
+    return 0;
+  /* Put arbitrary non-NULL value into *THREAD_ARGP as a marker so that this
+     function returns non-zero PID only once.  */
+  *thread_argp = thread_argp;
+  return dwfl_pid (dwfl);
+}
+
+static bool
+set_initial_registers (Dwfl_Thread *thread,
+		       void *thread_arg __attribute__ ((unused)))
+{
+  pid_t child = dwfl_pid (dwfl_thread_dwfl (thread));
+
+  struct user_regs_struct user_regs;
+  long l = ptrace (PTRACE_GETREGS, child, NULL, &user_regs);
+  assert (errno == 0);
+  assert (l == 0);
+
+  Dwarf_Word dwarf_regs[17];
+  dwarf_regs[0] = user_regs.rax;
+  dwarf_regs[1] = user_regs.rdx;
+  dwarf_regs[2] = user_regs.rcx;
+  dwarf_regs[3] = user_regs.rbx;
+  dwarf_regs[4] = user_regs.rsi;
+  dwarf_regs[5] = user_regs.rdi;
+  dwarf_regs[6] = user_regs.rbp;
+  dwarf_regs[7] = user_regs.rsp;
+  dwarf_regs[8] = user_regs.r8;
+  dwarf_regs[9] = user_regs.r9;
+  dwarf_regs[10] = user_regs.r10;
+  dwarf_regs[11] = user_regs.r11;
+  dwarf_regs[12] = user_regs.r12;
+  dwarf_regs[13] = user_regs.r13;
+  dwarf_regs[14] = user_regs.r14;
+  dwarf_regs[15] = user_regs.r15;
+  dwarf_regs[16] = user_regs.rip;
+  bool ok = dwfl_thread_state_registers (thread, 0, 17, dwarf_regs);
+  assert (ok);
+
+  /* x86_64 has PC contained in its CFI subset of DWARF register set so
+     elfutils will figure out the real PC value from REGS.
+     So no need to explicitly call dwfl_thread_state_register_pc.  */
+
+  return true;
+}
+
+static const Dwfl_Thread_Callbacks callbacks =
+{
+  next_thread,
+  NULL, /* get_thread */
+  memory_read,
+  set_initial_registers,
+  NULL, /* detach */
+  NULL, /* thread_detach */
+};
+
+static int
+frame_callback (Dwfl_Frame *state, void *arg)
+{
+  unsigned *framenop = arg;
+  Dwarf_Addr pc;
+  bool isactivation;
+  if (! dwfl_frame_pc (state, &pc, &isactivation))
+    {
+      error (1, 0, "%s", dwfl_errmsg (-1));
+      return 1;
+    }
+  Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1);
+
+  /* Get PC->SYMNAME.  */
+  Dwfl *dwfl = dwfl_thread_dwfl (dwfl_frame_thread (state));
+  Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted);
+  if (mod == NULL)
+    mod = report_module (dwfl, dwfl_pid (dwfl), pc_adjusted);
+  const char *symname = NULL;
+  symname = dwfl_module_addrname (mod, pc_adjusted);
+
+  printf ("#%2u %#" PRIx64 "%4s\t%s\n", (*framenop)++, (uint64_t) pc,
+	  ! isactivation ? "- 1" : "", symname);
+  return DWARF_CB_OK;
+}
+
+static int
+thread_callback (Dwfl_Thread *thread, void *thread_arg __attribute__ ((unused)))
+{
+  unsigned frameno = 0;
+  switch (dwfl_thread_getframes (thread, frame_callback, &frameno))
+    {
+    case 0:
+      break;
+    case -1:
+      error (1, 0, "dwfl_thread_getframes: %s", dwfl_errmsg (-1));
+      break;
+    default:
+      abort ();
+    }
+  return DWARF_CB_OK;
+}
+
+int
+main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)))
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+  __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  elf_version (EV_CURRENT);
+
+  pid_t child = fork ();
+  switch (child)
+  {
+    case -1:
+      assert (errno == 0);
+      assert (0);
+    case 0:;
+      long l = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
+      assert (errno == 0);
+      assert (l == 0);
+      raise (SIGUSR1);
+      return 0;
+    default:
+      break;
+  }
+
+  int status;
+  pid_t pid = waitpid (child, &status, 0);
+  assert (errno == 0);
+  assert (pid == child);
+  assert (WIFSTOPPED (status));
+  assert (WSTOPSIG (status) == SIGUSR1);
+
+  static char *debuginfo_path;
+  static const Dwfl_Callbacks offline_callbacks =
+    {
+      .find_debuginfo = dwfl_standard_find_debuginfo,
+      .debuginfo_path = &debuginfo_path,
+      .section_address = dwfl_offline_section_address,
+      .find_elf = find_elf,
+    };
+  Dwfl *dwfl = dwfl_begin (&offline_callbacks);
+  assert (dwfl);
+
+  struct user_regs_struct user_regs;
+  long l = ptrace (PTRACE_GETREGS, child, NULL, &user_regs);
+  assert (errno == 0);
+  assert (l == 0);
+  report_module (dwfl, child, user_regs.rip);
+
+  bool ok = dwfl_attach_state (dwfl, EM_NONE, child, &callbacks, NULL);
+  assert (ok);
+
+  /* Multiple threads are not handled here.  */
+  int err = dwfl_getthreads (dwfl, thread_callback, NULL);
+  assert (! err);
+
+  dwfl_end (dwfl);
+  kill (child, SIGKILL);
+  pid = waitpid (child, &status, 0);
+  assert (errno == 0);
+  assert (pid == child);
+  assert (WIFSIGNALED (status));
+  assert (WTERMSIG (status) == SIGKILL);
+
+  return EXIT_SUCCESS;
+}
+
+#endif /* x86_64 */
diff --git a/third_party/elfutils/tests/backtrace-dwarf.c b/third_party/elfutils/tests/backtrace-dwarf.c
new file mode 100644
index 0000000..2dc8a9a
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace-dwarf.c
@@ -0,0 +1,170 @@
+/* Test program for unwinding of complicated DWARF expressions.
+   Copyright (C) 2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <signal.h>
+#include <inttypes.h>
+#include <stdio_ext.h>
+#include <locale.h>
+#include <errno.h>
+#include <error.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include ELFUTILS_HEADER(dwfl)
+
+#ifndef __linux__
+
+int
+main (int argc __attribute__ ((unused)), char **argv)
+{
+  fprintf (stderr, "%s: Unwinding not supported for this architecture\n",
+           argv[0]);
+  return 77;
+}
+
+#else /* __linux__ */
+#include <sys/ptrace.h>
+
+#define main cleanup_13_main
+#include "cleanup-13.c"
+#undef main
+
+static void
+report_pid (Dwfl *dwfl, pid_t pid)
+{
+  int result = dwfl_linux_proc_report (dwfl, pid);
+  if (result < 0)
+    error (2, 0, "dwfl_linux_proc_report: %s", dwfl_errmsg (-1));
+  else if (result > 0)
+    error (2, result, "dwfl_linux_proc_report");
+
+  if (dwfl_report_end (dwfl, NULL, NULL) != 0)
+    error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1));
+
+  result = dwfl_linux_proc_attach (dwfl, pid, true);
+  if (result < 0)
+    error (2, 0, "dwfl_linux_proc_attach: %s", dwfl_errmsg (-1));
+  else if (result > 0)
+    error (2, result, "dwfl_linux_proc_attach");
+}
+
+static Dwfl *
+pid_to_dwfl (pid_t pid)
+{
+  static char *debuginfo_path;
+  static const Dwfl_Callbacks proc_callbacks =
+    {
+      .find_debuginfo = dwfl_standard_find_debuginfo,
+      .debuginfo_path = &debuginfo_path,
+
+      .find_elf = dwfl_linux_proc_find_elf,
+    };
+  Dwfl *dwfl = dwfl_begin (&proc_callbacks);
+  if (dwfl == NULL)
+    error (2, 0, "dwfl_begin: %s", dwfl_errmsg (-1));
+  report_pid (dwfl, pid);
+  return dwfl;
+}
+
+static int
+frame_callback (Dwfl_Frame *state, void *frame_arg)
+{
+  Dwarf_Addr pc;
+  bool isactivation;
+  if (! dwfl_frame_pc (state, &pc, &isactivation))
+    {
+      error (0, 0, "%s", dwfl_errmsg (-1));
+      return DWARF_CB_ABORT;
+    }
+  Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1);
+
+  /* Get PC->SYMNAME.  */
+  Dwfl_Thread *thread = dwfl_frame_thread (state);
+  Dwfl *dwfl = dwfl_thread_dwfl (thread);
+  Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted);
+  const char *symname = NULL;
+  if (mod)
+    symname = dwfl_module_addrname (mod, pc_adjusted);
+
+  printf ("%#" PRIx64 "\t%s\n", (uint64_t) pc, symname);
+
+  if (symname && (strcmp (symname, "main") == 0
+		  || strcmp (symname, ".main") == 0))
+    {
+      kill (dwfl_pid (dwfl), SIGKILL);
+      exit (0);
+    }
+
+  return DWARF_CB_OK;
+}
+
+static int
+thread_callback (Dwfl_Thread *thread, void *thread_arg)
+{
+  dwfl_thread_getframes (thread, frame_callback, NULL);
+  /* frame_callback shall exit (0) on success.  */
+  error (1, 0, "dwfl_thread_getframes: %s", dwfl_errmsg (-1));
+  return DWARF_CB_ABORT;
+}
+
+int
+main (int argc __attribute__ ((unused)), char **argv)
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+  __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  elf_version (EV_CURRENT);
+
+  pid_t pid = fork ();
+  switch (pid)
+  {
+    case -1:
+      abort ();
+    case 0:;
+      long l = ptrace (PTRACE_TRACEME, 0, NULL, NULL);
+      assert (errno == 0);
+      assert (l == 0);
+      cleanup_13_main ();
+      abort ();
+    default:
+      break;
+  }
+
+  errno = 0;
+  int status;
+  pid_t got = waitpid (pid, &status, 0);
+  assert (errno == 0);
+  assert (got == pid);
+  assert (WIFSTOPPED (status));
+  assert (WSTOPSIG (status) == SIGABRT);
+
+  Dwfl *dwfl = pid_to_dwfl (pid);
+  dwfl_getthreads (dwfl, thread_callback, NULL);
+
+  /* There is an exit (0) call if we find the "main" frame,  */
+  error (1, 0, "dwfl_getthreads: %s", dwfl_errmsg (-1));
+}
+
+#endif /* ! __linux__ */
+
diff --git a/third_party/elfutils/tests/backtrace-subr.sh b/third_party/elfutils/tests/backtrace-subr.sh
new file mode 100644
index 0000000..e04a7ea
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace-subr.sh
@@ -0,0 +1,195 @@
+# Copyright (C) 2013, 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Verify one of the backtraced threads contains function 'main'.
+check_main()
+{
+  if grep -w main $1; then
+    return
+  fi
+  echo >&2 $2: no main
+  false
+}
+
+# Without proper ELF symbols resolution we could get inappropriate weak
+# symbol "gsignal" with the same address as the correct symbol "raise".
+# It was fixed by GIT commit 78dec228b3cfb2f9300cd0b682ebf416c9674c91 .
+# [patch] Improve ELF symbols preference (global > weak)
+# https://lists.fedorahosted.org/pipermail/elfutils-devel/2012-October/002624.html
+check_gsignal()
+{
+  if ! grep -w gsignal $1; then
+    return
+  fi
+  echo >&2 $2: found gsignal
+  false
+}
+
+
+# Makes sure we saw the function that initiated the backtrace
+# when the core was generated through the tests backtrace --gencore.
+# This might disappear when frame pointer chasing gone bad.
+check_backtracegen()
+{
+  if grep -w backtracegen $1; then
+    return
+  fi
+  echo >&2 $2: no backtracegen
+  false
+}
+
+# Verify the STDERR output does not contain unexpected errors.
+# In some cases we cannot reliably find out we got behind _start as some
+# operating system do not properly terminate CFI by undefined PC.
+# Ignore it here as it is a bug of OS, not a bug of elfutils.
+check_err()
+{
+  if [ $(egrep -v <$1 'dwfl_thread_getframes: (No DWARF information found|no matching address range|address out of range|Invalid register|\(null\))$' \
+         | wc -c) \
+       -eq 0 ]
+  then
+    return
+  fi
+  echo >&2 $2: neither empty nor just out of DWARF
+  false
+}
+
+check_all()
+{
+  bt=$1
+  err=$2
+  testname=$3
+  check_main $bt $testname
+  check_gsignal $bt $testname
+  check_err $err $testname
+}
+
+check_unsupported()
+{
+  err=$1
+  testname=$2
+  if grep -q ': Unwinding not supported for this architecture$' $err; then
+    echo >&2 $testname: arch not supported
+    exit 77
+  fi
+}
+
+check_native_unsupported()
+{
+  err=$1
+  testname=$2
+  check_unsupported $err $testname
+
+  # ARM is special. It is supported, but it doesn't use .eh_frame by default
+  # making the native tests fail unless debuginfo (for glibc) is installed
+  # and we can fall back on .debug_frame for the CFI.
+  case "`uname -m`" in
+    arm* )
+      if egrep 'dwfl_thread_getframes(.*)No DWARF information found' $err; then
+	echo >&2 $testname: arm needs debuginfo installed for all libraries
+	exit 77
+      fi
+    ;;
+  esac
+}
+
+check_core()
+{
+  arch=$1
+  testfiles backtrace.$arch.{exec,core}
+  tempfiles backtrace.$arch.{bt,err}
+  echo ./backtrace ./backtrace.$arch.{exec,core}
+  testrun ${abs_builddir}/backtrace -e ./backtrace.$arch.exec --core=./backtrace.$arch.core 1>backtrace.$arch.bt 2>backtrace.$arch.err || true
+  cat backtrace.$arch.{bt,err}
+  check_unsupported backtrace.$arch.err backtrace.$arch.core
+  check_all backtrace.$arch.{bt,err} backtrace.$arch.core
+  check_backtracegen backtrace.$arch.bt backtrace.$arch.core
+}
+
+# Backtrace live process.
+# Do not abort on non-zero exit code due to some warnings of ./backtrace
+# - see function check_err.
+check_native()
+{
+  child=$1
+  tempfiles $child.{bt,err}
+  (set +ex; testrun ${abs_builddir}/backtrace --backtrace-exec=${abs_builddir}/$child 1>$child.bt 2>$child.err; true)
+  cat $child.{bt,err}
+  check_native_unsupported $child.err $child
+  check_all $child.{bt,err} $child
+}
+
+# Backtrace core file.
+check_native_core()
+{
+# systemd-coredump/coredumpctl doesn't seem to like concurrent core dumps
+# use a lock file (fd 200) tests/core-dump-backtrace.lock
+(
+  child=$1
+
+  # Disable valgrind while dumping core.
+  SAVED_VALGRIND_CMD="$VALGRIND_CMD"
+  unset VALGRIND_CMD
+
+  # Wait for lock for 10 seconds or skip.
+  flock -x -w 10 200 || exit 77;
+
+  # Skip the test if we cannot adjust core ulimit.
+  pid="`ulimit -c unlimited || exit 77; set +ex; testrun ${abs_builddir}/$child --gencore; true`"
+  core="core.$pid"
+  # see if /proc/sys/kernel/core_uses_pid is set to 0
+  if [ -f core ]; then
+    mv core "$core"
+  fi
+  type -P coredumpctl && have_coredumpctl=1 || have_coredumpctl=0
+  if [ ! -f "$core" -a $have_coredumpctl -eq 1 ]; then
+    # Maybe systemd-coredump took it. But give it some time to dump first...
+    sleep 1
+    coredumpctl --output="$core" dump $pid || rm -f $core
+
+    # Try a couple of times after waiting some more if something went wrong...
+    if [ ! -f "$core" ]; then
+      sleep 2
+      coredumpctl --output="$core" dump $pid || rm -f $core
+    fi
+
+    if [ ! -f "$core" ]; then
+      sleep 3
+      coredumpctl --output="$core" dump $pid || rm -f $core
+    fi
+  fi
+  if [ ! -f "$core" ]; then
+    echo "No $core file generated";
+    exit 77;
+  fi
+
+  if [ "x$SAVED_VALGRIND_CMD" != "x" ]; then
+    VALGRIND_CMD="$SAVED_VALGRIND_CMD"
+    export VALGRIND_CMD
+  fi
+
+  # Do not abort on non-zero exit code due to some warnings of ./backtrace
+  # - see function check_err.
+  tempfiles $core{,.{bt,err}}
+  (set +ex; testrun ${abs_builddir}/backtrace -e ${abs_builddir}/$child --core=$core 1>$core.bt 2>$core.err; true)
+  cat $core.{bt,err}
+  check_native_unsupported $core.err $child-$core
+  check_all $core.{bt,err} $child-$core
+  rm $core{,.{bt,err}}
+) 200>${abs_builddir}/core-dump-backtrace.lock
+}
diff --git a/third_party/elfutils/tests/backtrace.aarch64.core.bz2 b/third_party/elfutils/tests/backtrace.aarch64.core.bz2
new file mode 100644
index 0000000..3082a5a
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.aarch64.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.aarch64.exec.bz2 b/third_party/elfutils/tests/backtrace.aarch64.exec.bz2
new file mode 100755
index 0000000..66216b5
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.aarch64.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.aarch64.fp.core.bz2 b/third_party/elfutils/tests/backtrace.aarch64.fp.core.bz2
new file mode 100644
index 0000000..ff86788
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.aarch64.fp.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.aarch64.fp.exec.bz2 b/third_party/elfutils/tests/backtrace.aarch64.fp.exec.bz2
new file mode 100644
index 0000000..9d06db1
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.aarch64.fp.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.c b/third_party/elfutils/tests/backtrace.c
new file mode 100644
index 0000000..f5dd761
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.c
@@ -0,0 +1,500 @@
+/* Test program for unwinding of frames.
+   Copyright (C) 2013, 2014, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <locale.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <error.h>
+#include <unistd.h>
+#include <dwarf.h>
+#ifdef __linux__
+#include <sys/resource.h>
+#include <sys/ptrace.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/user.h>
+#include <fcntl.h>
+#include <string.h>
+#include <argp.h>
+#include ELFUTILS_HEADER(dwfl)
+#endif
+
+#ifndef __linux__
+
+int
+main (int argc __attribute__ ((unused)), char **argv)
+{
+  fprintf (stderr, "%s: Unwinding not supported for this architecture\n",
+	   argv[0]);
+  return 77;
+}
+
+#else /* __linux__ */
+
+static int
+dump_modules (Dwfl_Module *mod, void **userdata __attribute__ ((unused)),
+	      const char *name, Dwarf_Addr start,
+	      void *arg __attribute__ ((unused)))
+{
+  Dwarf_Addr end;
+  dwfl_module_info (mod, NULL, NULL, &end, NULL, NULL, NULL, NULL);
+  printf ("%#" PRIx64 "\t%#" PRIx64 "\t%s\n", (uint64_t) start, (uint64_t) end,
+	  name);
+  return DWARF_CB_OK;
+}
+
+static bool use_raise_jmp_patching;
+static pid_t check_tid;
+
+static void
+callback_verify (pid_t tid, unsigned frameno, Dwarf_Addr pc,
+		 const char *symname, Dwfl *dwfl)
+{
+  static bool seen_main = false;
+  if (symname && *symname == '.')
+    symname++;
+  if (symname && strcmp (symname, "main") == 0)
+    seen_main = true;
+  if (pc == 0)
+    {
+      assert (seen_main);
+      return;
+    }
+  if (check_tid == 0)
+    check_tid = tid;
+  if (tid != check_tid)
+    {
+      // For the main thread we are only interested if we can unwind till
+      // we see the "main" symbol.
+      return;
+    }
+  Dwfl_Module *mod;
+  /* See case 4. Special case to help out simple frame pointer unwinders. */
+  static bool duplicate_sigusr2 = false;
+  if (duplicate_sigusr2)
+    frameno--;
+  static bool reduce_frameno = false;
+  if (reduce_frameno)
+    frameno--;
+  if (! use_raise_jmp_patching && frameno >= 2)
+    frameno += 2;
+  const char *symname2 = NULL;
+  switch (frameno)
+  {
+    case 0:
+      if (! reduce_frameno && symname
+	       && (strcmp (symname, "__kernel_vsyscall") == 0
+		   || strcmp (symname, "__libc_do_syscall") == 0))
+	reduce_frameno = true;
+      else
+	assert (symname && strcmp (symname, "raise") == 0);
+      break;
+    case 1:
+      assert (symname != NULL && strcmp (symname, "sigusr2") == 0);
+      break;
+    case 2: // x86_64 only
+      /* __restore_rt - glibc maybe does not have to have this symbol.  */
+      break;
+    case 3: // use_raise_jmp_patching
+      if (use_raise_jmp_patching)
+	{
+	  /* Verify we trapped on the very first instruction of jmp.  */
+	  assert (symname != NULL && strcmp (symname, "jmp") == 0);
+	  mod = dwfl_addrmodule (dwfl, pc - 1);
+	  if (mod)
+	    symname2 = dwfl_module_addrname (mod, pc - 1);
+	  assert (symname2 == NULL || strcmp (symname2, "jmp") != 0);
+	  break;
+	}
+      FALLTHROUGH;
+    case 4:
+      /* Some simple frame unwinders get this wrong and think sigusr2
+	 is calling itself again. Allow it and just pretend there is
+	 an extra sigusr2 frame. */
+      if (symname != NULL && strcmp (symname, "sigusr2") == 0)
+	{
+	  duplicate_sigusr2 = true;
+	  break;
+	}
+      assert (symname != NULL && strcmp (symname, "stdarg") == 0);
+      break;
+    case 5:
+      /* Verify we trapped on the very last instruction of child.  */
+      assert (symname != NULL && strcmp (symname, "backtracegen") == 0);
+      mod = dwfl_addrmodule (dwfl, pc);
+      if (mod)
+	symname2 = dwfl_module_addrname (mod, pc);
+
+      // Note that the following assert might in theory even fail on x86_64,
+      // there is no guarantee that the compiler doesn't reorder the
+      // instructions or even inserts some padding instructions at the end
+      // (which apparently happens on ppc64).
+      if (use_raise_jmp_patching)
+        assert (symname2 == NULL || strcmp (symname2, "backtracegen") != 0);
+      break;
+  }
+}
+
+static int
+frame_callback (Dwfl_Frame *state, void *frame_arg)
+{
+  int *framenop = frame_arg;
+  Dwarf_Addr pc;
+  bool isactivation;
+
+  if (*framenop > 16)
+    {
+      error (0, 0, "Too many frames: %d\n", *framenop);
+      return DWARF_CB_ABORT;
+    }
+
+  if (! dwfl_frame_pc (state, &pc, &isactivation))
+    {
+      error (0, 0, "%s", dwfl_errmsg (-1));
+      return DWARF_CB_ABORT;
+    }
+  Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1);
+
+  /* Get PC->SYMNAME.  */
+  Dwfl_Thread *thread = dwfl_frame_thread (state);
+  Dwfl *dwfl = dwfl_thread_dwfl (thread);
+  Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted);
+  const char *symname = NULL;
+  if (mod)
+    symname = dwfl_module_addrname (mod, pc_adjusted);
+
+  printf ("#%2d %#" PRIx64 "%4s\t%s\n", *framenop, (uint64_t) pc,
+	  ! isactivation ? "- 1" : "", symname);
+  pid_t tid = dwfl_thread_tid (thread);
+  callback_verify (tid, *framenop, pc, symname, dwfl);
+  (*framenop)++;
+
+  return DWARF_CB_OK;
+}
+
+static int
+thread_callback (Dwfl_Thread *thread, void *thread_arg __attribute__((unused)))
+{
+  printf ("TID %ld:\n", (long) dwfl_thread_tid (thread));
+  int frameno = 0;
+  switch (dwfl_thread_getframes (thread, frame_callback, &frameno))
+    {
+    case 0:
+      break;
+    case DWARF_CB_ABORT:
+      return DWARF_CB_ABORT;
+    case -1:
+      error (0, 0, "dwfl_thread_getframes: %s", dwfl_errmsg (-1));
+      /* All platforms do not have yet proper unwind termination.  */
+      break;
+    default:
+      abort ();
+    }
+  return DWARF_CB_OK;
+}
+
+static void
+dump (Dwfl *dwfl)
+{
+  ptrdiff_t ptrdiff = dwfl_getmodules (dwfl, dump_modules, NULL, 0);
+  assert (ptrdiff == 0);
+  bool err = false;
+  switch (dwfl_getthreads (dwfl, thread_callback, NULL))
+    {
+    case 0:
+      break;
+    case DWARF_CB_ABORT:
+      err = true;
+      break;
+    case -1:
+      error (0, 0, "dwfl_getthreads: %s", dwfl_errmsg (-1));
+      err = true;
+      break;
+    default:
+      abort ();
+    }
+  callback_verify (0, 0, 0, NULL, dwfl);
+  if (err)
+    exit (EXIT_FAILURE);
+}
+
+struct see_exec_module
+{
+  Dwfl_Module *mod;
+  char selfpath[PATH_MAX + 1];
+};
+
+static int
+see_exec_module (Dwfl_Module *mod, void **userdata __attribute__ ((unused)),
+		 const char *name __attribute__ ((unused)),
+		 Dwarf_Addr start __attribute__ ((unused)), void *arg)
+{
+  struct see_exec_module *data = arg;
+  if (strcmp (name, data->selfpath) != 0)
+    return DWARF_CB_OK;
+  assert (data->mod == NULL);
+  data->mod = mod;
+  return DWARF_CB_ABORT;
+}
+
+/* We used to do this on x86_64 only (see backtrace-child why we now don't):
+     PC will get changed to function 'jmp' by backtrace.c function
+     prepare_thread.  Then SIGUSR2 will be signalled to backtrace-child
+     which will invoke function sigusr2.
+     This is all done so that signal interrupts execution of the very first
+     instruction of a function.  Properly handled unwind should not slip into
+     the previous unrelated function.  */
+
+#ifdef __x86_64__
+/* #define RAISE_JMP_PATCHING 1 */
+#endif
+
+static void
+prepare_thread (pid_t pid2 __attribute__ ((unused)),
+		void (*jmp) (void) __attribute__ ((unused)))
+{
+#ifndef RAISE_JMP_PATCHING
+  abort ();
+#else /* RAISE_JMP_PATCHING */
+  long l;
+  struct user_regs_struct user_regs;
+  errno = 0;
+  l = ptrace (PTRACE_GETREGS, pid2, 0, (intptr_t) &user_regs);
+  assert (errno == 0);
+  assert (l == 0);
+  user_regs.rip = (intptr_t) jmp;
+  l = ptrace (PTRACE_SETREGS, pid2, 0, (intptr_t) &user_regs);
+  assert (errno == 0);
+  assert (l == 0);
+  l = ptrace (PTRACE_CONT, pid2, NULL, (void *) (intptr_t) SIGUSR2);
+  int status;
+  pid_t got = waitpid (pid2, &status, __WALL);
+  assert (errno == 0);
+  assert (got == pid2);
+  assert (WIFSTOPPED (status));
+  assert (WSTOPSIG (status) == SIGUSR1);
+#endif /* RAISE_JMP_PATCHING */
+}
+
+#include <asm/unistd.h>
+#include <unistd.h>
+#define tgkill(pid, tid, sig) syscall (__NR_tgkill, (pid), (tid), (sig))
+
+static void
+report_pid (Dwfl *dwfl, pid_t pid)
+{
+  int result = dwfl_linux_proc_report (dwfl, pid);
+  if (result < 0)
+    error (2, 0, "dwfl_linux_proc_report: %s", dwfl_errmsg (-1));
+  else if (result > 0)
+    error (2, result, "dwfl_linux_proc_report");
+
+  if (dwfl_report_end (dwfl, NULL, NULL) != 0)
+    error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1));
+
+  result = dwfl_linux_proc_attach (dwfl, pid, true);
+  if (result < 0)
+    error (2, 0, "dwfl_linux_proc_attach: %s", dwfl_errmsg (-1));
+  else if (result > 0)
+    error (2, result, "dwfl_linux_proc_attach");
+}
+
+static Dwfl *
+pid_to_dwfl (pid_t pid)
+{
+  static char *debuginfo_path;
+  static const Dwfl_Callbacks proc_callbacks =
+    {
+      .find_debuginfo = dwfl_standard_find_debuginfo,
+      .debuginfo_path = &debuginfo_path,
+
+      .find_elf = dwfl_linux_proc_find_elf,
+    };
+  Dwfl *dwfl = dwfl_begin (&proc_callbacks);
+  if (dwfl == NULL)
+    error (2, 0, "dwfl_begin: %s", dwfl_errmsg (-1));
+  report_pid (dwfl, pid);
+  return dwfl;
+}
+
+static void
+exec_dump (const char *exec)
+{
+  pid_t pid = fork ();
+  switch (pid)
+  {
+    case -1:
+      abort ();
+    case 0:
+      execl (exec, exec, "--ptraceme", NULL);
+      abort ();
+    default:
+      break;
+  }
+
+  /* Catch the main thread.  Catch it first otherwise the /proc evaluation of
+     PID may have caught still ourselves before executing execl above.  */
+  errno = 0;
+  int status;
+  pid_t got = waitpid (pid, &status, 0);
+  assert (errno == 0);
+  assert (got == pid);
+  assert (WIFSTOPPED (status));
+  // Main thread will signal SIGUSR2.  Other thread will signal SIGUSR1.
+  assert (WSTOPSIG (status) == SIGUSR2);
+
+  /* Catch the spawned thread.  Do not use __WCLONE as we could get racy
+     __WCLONE, probably despite pthread_create already had to be called the new
+     task is not yet alive enough for waitpid.  */
+  pid_t pid2 = waitpid (-1, &status, __WALL);
+  assert (errno == 0);
+  assert (pid2 > 0);
+  assert (pid2 != pid);
+  assert (WIFSTOPPED (status));
+  // Main thread will signal SIGUSR2.  Other thread will signal SIGUSR1.
+  assert (WSTOPSIG (status) == SIGUSR1);
+
+  Dwfl *dwfl = pid_to_dwfl (pid);
+  char *selfpathname;
+  int i = asprintf (&selfpathname, "/proc/%ld/exe", (long) pid);
+  assert (i > 0);
+  struct see_exec_module data;
+  ssize_t ssize = readlink (selfpathname, data.selfpath,
+			    sizeof (data.selfpath));
+  free (selfpathname);
+  assert (ssize > 0 && ssize < (ssize_t) sizeof (data.selfpath));
+  data.selfpath[ssize] = '\0';
+  data.mod = NULL;
+  dwfl_getmodules (dwfl, see_exec_module, &data, 0);
+  assert (data.mod != NULL);
+  GElf_Addr loadbase;
+  Elf *elf = dwfl_module_getelf (data.mod, &loadbase);
+  GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  assert (ehdr != NULL);
+  /* It is false also on x86_64 with i386 inferior.  */
+#ifndef RAISE_JMP_PATCHING
+  use_raise_jmp_patching = false;
+#else /* RAISE_JMP_PATCHING_ */
+  use_raise_jmp_patching = ehdr->e_machine == EM_X86_64;
+#endif /* __x86_64__ */
+  void (*jmp) (void) = 0;
+  if (use_raise_jmp_patching)
+    {
+      // Find inferior symbol named "jmp".
+      int nsym = dwfl_module_getsymtab (data.mod);
+      int symi;
+      for (symi = 1; symi < nsym; ++symi)
+	{
+	  GElf_Sym symbol;
+	  const char *symbol_name = dwfl_module_getsym (data.mod, symi, &symbol, NULL);
+	  if (symbol_name == NULL)
+	    continue;
+	  switch (GELF_ST_TYPE (symbol.st_info))
+	    {
+	    case STT_SECTION:
+	    case STT_FILE:
+	    case STT_TLS:
+	      continue;
+	    default:
+	      if (strcmp (symbol_name, "jmp") != 0)
+		continue;
+	      break;
+	    }
+	  /* LOADBASE is already applied here.  */
+	  jmp = (void (*) (void)) (uintptr_t) symbol.st_value;
+	  break;
+	}
+      assert (symi < nsym);
+      prepare_thread (pid2, jmp);
+    }
+  dwfl_end (dwfl);
+  check_tid = pid2;
+  dwfl = pid_to_dwfl (pid);
+  dump (dwfl);
+  dwfl_end (dwfl);
+}
+
+#define OPT_BACKTRACE_EXEC 0x100
+
+static const struct argp_option options[] =
+  {
+    { "backtrace-exec", OPT_BACKTRACE_EXEC, "EXEC", 0, N_("Run executable"), 0 },
+    { NULL, 0, NULL, 0, NULL, 0 }
+  };
+
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+  switch (key)
+    {
+    case ARGP_KEY_INIT:
+      state->child_inputs[0] = state->input;
+      break;
+
+    case OPT_BACKTRACE_EXEC:
+      exec_dump (arg);
+      exit (0);
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+int
+main (int argc __attribute__ ((unused)), char **argv)
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  __fsetlocking (stdin, FSETLOCKING_BYCALLER);
+  __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+  __fsetlocking (stderr, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  elf_version (EV_CURRENT);
+
+  Dwfl *dwfl = NULL;
+  const struct argp_child argp_children[] =
+    {
+      { .argp = dwfl_standard_argp () },
+      { .argp = NULL }
+    };
+  const struct argp argp =
+    {
+      options, parse_opt, NULL, NULL, argp_children, NULL, NULL
+    };
+  (void) argp_parse (&argp, argc, argv, 0, NULL, &dwfl);
+  assert (dwfl != NULL);
+  /* We want to make sure the dwfl was properly attached.  */
+  if (dwfl_pid (dwfl) < 0)
+    error (2, 0, "dwfl_pid: %s", dwfl_errmsg (-1));
+  dump (dwfl);
+  dwfl_end (dwfl);
+  return 0;
+}
+
+#endif /* ! __linux__ */
+
diff --git a/third_party/elfutils/tests/backtrace.i386.core.bz2 b/third_party/elfutils/tests/backtrace.i386.core.bz2
new file mode 100644
index 0000000..e120d9b
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.i386.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.i386.exec.bz2 b/third_party/elfutils/tests/backtrace.i386.exec.bz2
new file mode 100644
index 0000000..1b0f001
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.i386.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.i386.fp.core.bz2 b/third_party/elfutils/tests/backtrace.i386.fp.core.bz2
new file mode 100644
index 0000000..3c49e24
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.i386.fp.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.i386.fp.exec.bz2 b/third_party/elfutils/tests/backtrace.i386.fp.exec.bz2
new file mode 100755
index 0000000..cb4d32e
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.i386.fp.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.ppc.core.bz2 b/third_party/elfutils/tests/backtrace.ppc.core.bz2
new file mode 100644
index 0000000..3a025d2
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.ppc.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.ppc.exec.bz2 b/third_party/elfutils/tests/backtrace.ppc.exec.bz2
new file mode 100644
index 0000000..333c6be
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.ppc.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.ppc64le.fp.core.bz2 b/third_party/elfutils/tests/backtrace.ppc64le.fp.core.bz2
new file mode 100644
index 0000000..e63babf
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.ppc64le.fp.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.ppc64le.fp.exec.bz2 b/third_party/elfutils/tests/backtrace.ppc64le.fp.exec.bz2
new file mode 100755
index 0000000..ed1352a
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.ppc64le.fp.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.s390.core.bz2 b/third_party/elfutils/tests/backtrace.s390.core.bz2
new file mode 100644
index 0000000..db34694
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.s390.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.s390.exec.bz2 b/third_party/elfutils/tests/backtrace.s390.exec.bz2
new file mode 100644
index 0000000..4c1b4ae
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.s390.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.s390x.core.bz2 b/third_party/elfutils/tests/backtrace.s390x.core.bz2
new file mode 100644
index 0000000..61c23ec
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.s390x.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.s390x.exec.bz2 b/third_party/elfutils/tests/backtrace.s390x.exec.bz2
new file mode 100644
index 0000000..8009239
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.s390x.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.sparc.core.bz2 b/third_party/elfutils/tests/backtrace.sparc.core.bz2
new file mode 100644
index 0000000..ad37f75
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.sparc.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.sparc.exec.bz2 b/third_party/elfutils/tests/backtrace.sparc.exec.bz2
new file mode 100755
index 0000000..b049ec5
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.sparc.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.x32.core.bz2 b/third_party/elfutils/tests/backtrace.x32.core.bz2
new file mode 100644
index 0000000..c06d70a
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.x32.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.x32.exec.bz2 b/third_party/elfutils/tests/backtrace.x32.exec.bz2
new file mode 100644
index 0000000..e89401b
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.x32.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.x86_64.core.bz2 b/third_party/elfutils/tests/backtrace.x86_64.core.bz2
new file mode 100644
index 0000000..1f34e20
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.x86_64.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.x86_64.exec.bz2 b/third_party/elfutils/tests/backtrace.x86_64.exec.bz2
new file mode 100644
index 0000000..70a151b
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.x86_64.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.x86_64.fp.core.bz2 b/third_party/elfutils/tests/backtrace.x86_64.fp.core.bz2
new file mode 100644
index 0000000..e773ca2
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.x86_64.fp.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/backtrace.x86_64.fp.exec.bz2 b/third_party/elfutils/tests/backtrace.x86_64.fp.exec.bz2
new file mode 100644
index 0000000..0695845
--- /dev/null
+++ b/third_party/elfutils/tests/backtrace.x86_64.fp.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/buildid.c b/third_party/elfutils/tests/buildid.c
new file mode 100644
index 0000000..87c1877
--- /dev/null
+++ b/third_party/elfutils/tests/buildid.c
@@ -0,0 +1,81 @@
+/* Test program for dwelf_elf_gnu_build_id, print build ID.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <err.h>
+#include <errno.h>
+#include ELFUTILS_HEADER(elf)
+#include ELFUTILS_HEADER(dwelf)
+#include <stdio.h>
+#include <error.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int
+main (int argc, char *argv[])
+{
+  if (argc < 2)
+    error (EXIT_FAILURE, 0, "No input file given");
+
+  elf_version (EV_CURRENT);
+
+  for (int i = 1; i < argc; i++)
+    {
+      const char *file = argv[i];
+      int fd = open (file, O_RDONLY);
+      if (fd < 0)
+	error (EXIT_FAILURE, errno, "couldn't open file '%s'", file);
+
+      Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+      if (elf == NULL)
+	{
+	  printf("%s: elf_begin failed: %s\n", file, elf_errmsg (-1));
+	  close (fd);
+	  continue;
+	}
+
+      const void *build_id;
+      ssize_t len = dwelf_elf_gnu_build_id (elf, &build_id);
+      switch (len)
+	{
+	case 0:
+	  printf ("%s: <no NT_GNU_BUILD_ID note>\n", file);
+	  break;
+	case -1:
+	  errx (1, "dwelf_elf_gnu_build_id (%s): %s",
+		file, elf_errmsg (-1));
+	default:
+	  printf ("%s: build ID: ", file);
+	  const unsigned char *p = build_id;
+	  const unsigned char *end = p + len;
+	  while (p < end)
+	      printf("%02x", (unsigned)*p++);
+	  putchar('\n');
+	}
+
+      elf_end (elf);
+      close (fd);
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/cleanup-13.c b/third_party/elfutils/tests/cleanup-13.c
new file mode 100644
index 0000000..3919b91
--- /dev/null
+++ b/third_party/elfutils/tests/cleanup-13.c
@@ -0,0 +1,316 @@
+// http://gcc.gnu.org/viewcvs/gcc/trunk/gcc/testsuite/gcc.dg/cleanup-13.c?view=co&content-type=text%2Fplain
+
+/* HP-UX libunwind.so doesn't provide _UA_END_OF_STACK */
+/* { dg-do run } */
+/* { dg-options "-fexceptions" } */
+/* { dg-skip-if "" { "ia64-*-hpux11.*" }  { "*" } { "" } } */
+/* Verify DW_OP_* handling in the unwinder.  */
+
+#include <unwind.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* #define OP_addr(x) 0x06, ... */
+#define OP_deref 0x06,
+#define SLEB128(x) (x)&0x7f	/* Assume here the value is -0x40 ... 0x3f.  */
+#define ULEB128(x) (x)&0x7f	/* Assume here the value is 0 ... 0x7f.  */
+#define VAL1(x) (x)&0xff
+#if defined (__BIG_ENDIAN__)
+#define VAL2(x) ((x)>>8)&0xff,(x)&0xff
+#define VAL4(x) ((x)>>24)&0xff,((x)>>16)&0xff,((x)>>8)&0xff,(x)&0xff
+#define VAL8(x) ((x)>>56)&0xff,((x)>>48)&0xff,((x)>>40)&0xff,((x)>>32)&0xff,((x)>>24)&0xff,((x)>>16)&0xff,((x)>>8)&0xff,(x)&0xff
+#elif defined(__LITTLE_ENDIAN__) || defined(__x86_64__) || defined(__i386__)
+#define VAL2(x) (x)&0xff,((x)>>8)&0xff
+#define VAL4(x) (x)&0xff,((x)>>8)&0xff,((x)>>16)&0xff,((x)>>24)&0xff
+#define VAL8(x) (x)&0xff,((x)>>8)&0xff,((x)>>16)&0xff,((x)>>24)&0xff,((x)>>32)&0xff,((x)>>40)&0xff,((x)>>48)&0xff,((x)>>56)&0xff
+#endif
+#define OP_const1u(x) 0x08,VAL1(x),
+#define OP_const1s(x) 0x09,VAL1(x),
+#define OP_const2u(x) 0x0a,VAL2(x),
+#define OP_const2s(x) 0x0b,VAL2(x),
+#define OP_const4u(x) 0x0c,VAL4(x),
+#define OP_const4s(x) 0x0d,VAL4(x),
+#define OP_const8u(x) 0x0e,VAL8(x),
+#define OP_const8s(x) 0x0f,VAL8(x),
+#define OP_constu(x) 0x10,ULEB128(x),
+#define OP_consts(x) 0x11,SLEB128(x),
+#define OP_dup 0x12,
+#define OP_drop 0x13,
+#define OP_over 0x14,
+#define OP_pick(x) 0x15,VAL1(x),
+#define OP_swap 0x16,
+#define OP_rot 0x17,
+#define OP_xderef 0x18,
+#define OP_abs 0x19,
+#define OP_and 0x1a,
+#define OP_div 0x1b,
+#define OP_minus 0x1c,
+#define OP_mod 0x1d,
+#define OP_mul 0x1e,
+#define OP_neg 0x1f,
+#define OP_not 0x20,
+#define OP_or 0x21,
+#define OP_plus 0x22,
+#define OP_plus_uconst(x) 0x23,ULEB128(x),
+#define OP_shl 0x24,
+#define OP_shr 0x25,
+#define OP_shra 0x26,
+#define OP_xor 0x27,
+#define OP_bra(x) 0x28,VAL2(x),
+#define OP_eq 0x29,
+#define OP_ge 0x2a,
+#define OP_gt 0x2b,
+#define OP_le 0x2c,
+#define OP_lt 0x2d,
+#define OP_ne 0x2e,
+#define OP_skip(x) 0x2f,VAL2(x),
+#define OP_lit0 0x30,
+#define OP_lit1 0x31,
+#define OP_lit2 0x32,
+#define OP_lit3 0x33,
+#define OP_lit4 0x34,
+#define OP_lit5 0x35,
+#define OP_lit6 0x36,
+#define OP_lit7 0x37,
+#define OP_lit8 0x38,
+#define OP_lit9 0x39,
+#define OP_lit10 0x3a,
+#define OP_lit11 0x3b,
+#define OP_lit12 0x3c,
+#define OP_lit13 0x3d,
+#define OP_lit14 0x3e,
+#define OP_lit15 0x3f,
+#define OP_lit16 0x40,
+#define OP_lit17 0x41,
+#define OP_lit18 0x42,
+#define OP_lit19 0x43,
+#define OP_lit20 0x44,
+#define OP_lit21 0x45,
+#define OP_lit22 0x46,
+#define OP_lit23 0x47,
+#define OP_lit24 0x48,
+#define OP_lit25 0x49,
+#define OP_lit26 0x4a,
+#define OP_lit27 0x4b,
+#define OP_lit28 0x4c,
+#define OP_lit29 0x4d,
+#define OP_lit30 0x4e,
+#define OP_lit31 0x4f,
+#define OP_reg0 0x50,
+#define OP_reg1 0x51,
+#define OP_reg2 0x52,
+#define OP_reg3 0x53,
+#define OP_reg4 0x54,
+#define OP_reg5 0x55,
+#define OP_reg6 0x56,
+#define OP_reg7 0x57,
+#define OP_reg8 0x58,
+#define OP_reg9 0x59,
+#define OP_reg10 0x5a,
+#define OP_reg11 0x5b,
+#define OP_reg12 0x5c,
+#define OP_reg13 0x5d,
+#define OP_reg14 0x5e,
+#define OP_reg15 0x5f,
+#define OP_reg16 0x60,
+#define OP_reg17 0x61,
+#define OP_reg18 0x62,
+#define OP_reg19 0x63,
+#define OP_reg20 0x64,
+#define OP_reg21 0x65,
+#define OP_reg22 0x66,
+#define OP_reg23 0x67,
+#define OP_reg24 0x68,
+#define OP_reg25 0x69,
+#define OP_reg26 0x6a,
+#define OP_reg27 0x6b,
+#define OP_reg28 0x6c,
+#define OP_reg29 0x6d,
+#define OP_reg30 0x6e,
+#define OP_reg31 0x6f,
+#define OP_breg0(x) 0x70,SLEB128(x),
+#define OP_breg1(x) 0x71,SLEB128(x),
+#define OP_breg2(x) 0x72,SLEB128(x),
+#define OP_breg3(x) 0x73,SLEB128(x),
+#define OP_breg4(x) 0x74,SLEB128(x),
+#define OP_breg5(x) 0x75,SLEB128(x),
+#define OP_breg6(x) 0x76,SLEB128(x),
+#define OP_breg7(x) 0x77,SLEB128(x),
+#define OP_breg8(x) 0x78,SLEB128(x),
+#define OP_breg9(x) 0x79,SLEB128(x),
+#define OP_breg10(x) 0x7a,SLEB128(x),
+#define OP_breg11(x) 0x7b,SLEB128(x),
+#define OP_breg12(x) 0x7c,SLEB128(x),
+#define OP_breg13(x) 0x7d,SLEB128(x),
+#define OP_breg14(x) 0x7e,SLEB128(x),
+#define OP_breg15(x) 0x7f,SLEB128(x),
+#define OP_breg16(x) 0x80,SLEB128(x),
+#define OP_breg17(x) 0x81,SLEB128(x),
+#define OP_breg18(x) 0x82,SLEB128(x),
+#define OP_breg19(x) 0x83,SLEB128(x),
+#define OP_breg20(x) 0x84,SLEB128(x),
+#define OP_breg21(x) 0x85,SLEB128(x),
+#define OP_breg22(x) 0x86,SLEB128(x),
+#define OP_breg23(x) 0x87,SLEB128(x),
+#define OP_breg24(x) 0x88,SLEB128(x),
+#define OP_breg25(x) 0x89,SLEB128(x),
+#define OP_breg26(x) 0x8a,SLEB128(x),
+#define OP_breg27(x) 0x8b,SLEB128(x),
+#define OP_breg28(x) 0x8c,SLEB128(x),
+#define OP_breg29(x) 0x8d,SLEB128(x),
+#define OP_breg30(x) 0x8e,SLEB128(x),
+#define OP_breg31(x) 0x8f,SLEB128(x),
+#define OP_regx(x) 0x90,SLEB128(x),
+#define OP_fbreg(x) 0x91,SLEB128(x),
+#define OP_bregx(x,y) 0x92,ULEB128(x),SLEB128(y),
+#define OP_piece(x) 0x93,ULEB128(x),
+#define OP_deref_size(x) 0x94,VAL1(x),
+#define OP_xderef_size(x) 0x95,VAL1(x),
+#define OP_nop 0x96,
+#define OP_nop_termination 0x96
+#define OP_push_object_address 0x97,
+#define OP_call2(x) 0x98,VAL2(x),
+#define OP_call4(x) 0x99,VAL4(x),
+/* #define OP_call_ref(x) 0x9a,... */
+#define OP_form_tls_address(x) 0x9b,
+#define OP_call_frame_cfa 0x9c,
+#define OP_bit_piece(x) 0x9d,ULEB128(x),
+/* #define OP_implicit_value(x...) 0x9e,... */
+#define OP_stack_value 0x9f,
+#define OP_GNU_push_tls_address 0xe0,
+/* #define OP_GNU_encoded_addr(x...) 0xf1, */
+
+#define ASSERT_TOS_NON0 OP_bra(3) OP_skip(-3)
+#define ASSERT_TOS_0 OP_lit0 OP_eq ASSERT_TOS_NON0
+
+/* Initially there is CFA value on the stack, we want to
+   keep it there at the end.  */
+#define CFI_PROGRAM \
+OP_lit0 OP_nop ASSERT_TOS_0						\
+OP_lit1 ASSERT_TOS_NON0							\
+OP_lit1 OP_const1u(1) OP_eq ASSERT_TOS_NON0				\
+OP_lit16 OP_const2u(16) OP_eq ASSERT_TOS_NON0				\
+OP_lit31 OP_const4u(31) OP_ne ASSERT_TOS_0				\
+OP_lit1 OP_neg OP_const1s(-1) OP_eq ASSERT_TOS_NON0			\
+OP_lit16 OP_neg OP_const2s(-16) OP_ne ASSERT_TOS_0			\
+OP_lit31 OP_const4s(-31) OP_neg OP_ne ASSERT_TOS_0			\
+OP_lit7 OP_dup OP_plus_uconst(2) OP_lit9 OP_eq ASSERT_TOS_NON0		\
+  OP_lit7 OP_eq ASSERT_TOS_NON0						\
+OP_lit20 OP_lit1 OP_drop OP_lit20 OP_eq ASSERT_TOS_NON0			\
+OP_lit17 OP_lit19 OP_over OP_lit17 OP_eq ASSERT_TOS_NON0		\
+  OP_lit19 OP_eq ASSERT_TOS_NON0 OP_lit17 OP_eq ASSERT_TOS_NON0		\
+OP_lit1 OP_lit2 OP_lit3 OP_lit4 OP_pick(2) OP_lit2 OP_eq ASSERT_TOS_NON0\
+  OP_lit4 OP_eq ASSERT_TOS_NON0 OP_lit3 OP_eq ASSERT_TOS_NON0		\
+  OP_pick(0) OP_lit2 OP_eq ASSERT_TOS_NON0				\
+  OP_lit2 OP_eq ASSERT_TOS_NON0 OP_lit1 OP_eq ASSERT_TOS_NON0		\
+OP_lit6 OP_lit12 OP_swap OP_lit6 OP_eq ASSERT_TOS_NON0			\
+  OP_lit12 OP_eq ASSERT_TOS_NON0					\
+OP_lit7 OP_lit8 OP_lit9 OP_rot OP_lit8 OP_eq ASSERT_TOS_NON0		\
+  OP_lit7 OP_eq ASSERT_TOS_NON0 OP_lit9 OP_eq ASSERT_TOS_NON0		\
+OP_lit7 OP_abs OP_lit7 OP_eq ASSERT_TOS_NON0				\
+OP_const1s(-123) OP_abs OP_const1u(123) OP_eq ASSERT_TOS_NON0		\
+OP_lit3 OP_lit6 OP_and OP_lit2 OP_eq ASSERT_TOS_NON0			\
+OP_lit3 OP_lit6 OP_or OP_lit7 OP_eq ASSERT_TOS_NON0			\
+OP_lit17 OP_lit2 OP_minus OP_lit15 OP_eq ASSERT_TOS_NON0		\
+/* Divide is signed truncating toward zero.  */				\
+OP_const1s(-6) OP_const1s(-2) OP_div OP_lit3 OP_eq ASSERT_TOS_NON0	\
+OP_const1s(-7) OP_const1s(3) OP_div OP_const1s(-2)			\
+  OP_eq ASSERT_TOS_NON0							\
+/* Modulo is unsigned.  */						\
+OP_const1s(-6) OP_const1s(-4) OP_mod OP_const1s(-6)			\
+  OP_eq ASSERT_TOS_NON0							\
+OP_const1s(-6) OP_lit4 OP_mod OP_lit2 OP_eq ASSERT_TOS_NON0		\
+OP_lit6 OP_const1s(-4) OP_mod OP_lit6 OP_eq ASSERT_TOS_NON0		\
+/* Signed modulo can be implemented using "over over div mul minus".  */\
+OP_const1s(-6) OP_const1s(-4) OP_over OP_over OP_div OP_mul OP_minus	\
+  OP_const1s(-2) OP_eq ASSERT_TOS_NON0					\
+OP_const1s(-7) OP_lit3 OP_over OP_over OP_div OP_mul OP_minus		\
+  OP_const1s(-1) OP_eq ASSERT_TOS_NON0					\
+OP_lit7 OP_const1s(-3) OP_over OP_over OP_div OP_mul OP_minus		\
+  OP_lit1 OP_eq ASSERT_TOS_NON0						\
+OP_lit16 OP_lit31 OP_plus_uconst(1) OP_mul OP_const2u(512)		\
+  OP_eq ASSERT_TOS_NON0							\
+OP_lit5 OP_not OP_lit31 OP_and OP_lit26 OP_eq ASSERT_TOS_NON0		\
+OP_lit12 OP_lit31 OP_plus OP_const1u(43) OP_eq ASSERT_TOS_NON0		\
+OP_const1s(-6) OP_lit2 OP_plus OP_const1s(-4) OP_eq ASSERT_TOS_NON0	\
+OP_const1s(-6) OP_plus_uconst(3) OP_const1s(-3) OP_eq ASSERT_TOS_NON0	\
+OP_lit16 OP_lit4 OP_shl OP_const2u(256) OP_eq ASSERT_TOS_NON0		\
+OP_lit16 OP_lit3 OP_shr OP_lit2 OP_eq ASSERT_TOS_NON0			\
+OP_const1s(-16) OP_lit3 OP_shra OP_const1s(-2) OP_eq ASSERT_TOS_NON0	\
+OP_lit3 OP_lit6 OP_xor OP_lit5 OP_eq ASSERT_TOS_NON0			\
+OP_lit3 OP_lit6 OP_le ASSERT_TOS_NON0					\
+OP_lit3 OP_lit3 OP_le ASSERT_TOS_NON0					\
+OP_lit6 OP_lit3 OP_le ASSERT_TOS_0					\
+OP_lit3 OP_lit6 OP_lt ASSERT_TOS_NON0					\
+OP_lit3 OP_lit3 OP_lt ASSERT_TOS_0					\
+OP_lit6 OP_lit3 OP_lt ASSERT_TOS_0					\
+OP_lit3 OP_lit6 OP_ge ASSERT_TOS_0					\
+OP_lit3 OP_lit3 OP_ge ASSERT_TOS_NON0					\
+OP_lit6 OP_lit3 OP_ge ASSERT_TOS_NON0					\
+OP_lit3 OP_lit6 OP_gt ASSERT_TOS_0					\
+OP_lit3 OP_lit3 OP_gt ASSERT_TOS_0					\
+OP_lit6 OP_lit3 OP_gt ASSERT_TOS_NON0					\
+OP_const1s(-6) OP_lit1 OP_shr OP_lit0 OP_gt ASSERT_TOS_NON0		\
+OP_const1s(-6) OP_lit1 OP_shra OP_lit0 OP_lt ASSERT_TOS_NON0
+
+#define CFI_ESCAPE_VAL_2(VALUES...) #VALUES
+#define CFI_ESCAPE_VAL_1(VALUES...) CFI_ESCAPE_VAL_2(VALUES)
+#define CFI_ESCAPE_VAL(VALUES...) CFI_ESCAPE_VAL_1(VALUES)
+#define CFI_ESCAPE do { } while (0)
+#define CFI_ARCH_PROGRAM OP_nop_termination
+#ifdef __GCC_HAVE_DWARF2_CFI_ASM
+#if defined (__x86_64__)
+#undef CFI_ESCAPE
+#undef CFI_ARCH_PROGRAM
+#define CFI_ARCH_PROGRAM CFI_PROGRAM OP_lit8 OP_minus OP_nop_termination
+unsigned char cfi_arch_program[] = { CFI_ARCH_PROGRAM };
+extern char verify_it[sizeof (cfi_arch_program) - 0x80 < 0x3f80 ? 1 : -1];
+/* DW_CFA_expression %rip, uleb128(l2-l1), l1: program DW_OP_lit8 DW_OP_minus DW_OP_nop l2: */
+#define CFI_ESCAPE \
+  asm volatile (".cfi_escape 0x10, 0x10, (%P0&0x7f)+0x80, %P0>>7, " \
+		CFI_ESCAPE_VAL (CFI_ARCH_PROGRAM) \
+		: : "i" (sizeof (cfi_arch_program)))
+#elif defined (__i386__)
+#undef CFI_ESCAPE
+#undef CFI_ARCH_PROGRAM
+#define CFI_ARCH_PROGRAM CFI_PROGRAM OP_lit4 OP_minus OP_nop_termination
+unsigned char cfi_arch_program[] = { CFI_ARCH_PROGRAM };
+extern char verify_it[sizeof (cfi_arch_program) - 0x80 < 0x3f80 ? 1 : -1];
+/* DW_CFA_expression %eip, uleb128(l2-l1), l1: program DW_OP_lit4 DW_OP_minus DW_OP_nop l2: */
+#define CFI_ESCAPE \
+  asm volatile (".cfi_escape 0x10, 8, (%P0&0x7f)+0x80, %P0>>7, " \
+		CFI_ESCAPE_VAL (CFI_ARCH_PROGRAM) \
+		: : "i" (sizeof (cfi_arch_program)))
+#endif
+#endif
+
+/* The original GCC testcase tests the runtime unwinder using
+   _Unwind_ForcedUnwind, we just inspect the child when it aborts.  */
+
+static void force_unwind ()
+{
+  abort ();
+}
+
+static void handler (void *p __attribute__((unused)))
+{
+  exit (0);
+}
+
+__attribute__((noinline)) static void callme ()
+{
+  CFI_ESCAPE;
+  force_unwind ();
+}
+
+__attribute__((noinline)) static void doit ()
+{
+  char dummy __attribute__((cleanup (handler)));
+  callme ();
+}
+
+int main()
+{ 
+  doit ();
+  abort ();
+}
diff --git a/third_party/elfutils/tests/configure.ac b/third_party/elfutils/tests/configure.ac
new file mode 100644
index 0000000..ed51920
--- /dev/null
+++ b/third_party/elfutils/tests/configure.ac
@@ -0,0 +1,58 @@
+dnl Process this file with autoconf to produce a configure script.
+dnl Configure input file for elfutils test suite.		-*-autoconf-*-
+dnl
+dnl Copyright (C) 2005 Red Hat, Inc.
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation, version 2.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software Foundation,
+dnl Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+dnl
+AC_INIT([elfutils tests],[0.117],
+	[http://bugzilla.redhat.com/bugzilla/],
+	[elfutils-tests])
+
+AC_COPYRIGHT([Copyright (C) 2005 Red Hat, Inc.])
+AC_PREREQ(2.59)			dnl Minimum Autoconf version required.
+
+AM_INIT_AUTOMAKE([foreign 1.7])
+
+AC_CONFIG_SRCDIR([allfcts.c])
+AC_CONFIG_FILES([Makefile])
+AC_CONFIG_HEADERS([config.h])
+
+AC_PROG_CC
+
+AC_CACHE_CHECK([for gcc with C99 support], ac_cv_c99, [dnl
+old_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -std=gnu99"
+AC_COMPILE_IFELSE([dnl
+int foo (int a) { for (int i = 0; i < a; ++i) if (i % 4) break; int s = a; }],
+		  ac_cv_c99=yes, ac_cv_c99=no)
+CFLAGS="$old_CFLAGS"])
+AS_IF([test "x$ac_cv_c99" != xyes],
+      AC_MSG_ERROR([gcc with C99 support required]))
+
+AC_CHECK_HEADERS([libelf.h elfutils/libdw.h],,
+[AC_MSG_ERROR([elfutils-devel package not installed])])
+
+AC_CHECK_LIB([asm], [asm_begin], [have_libasm=yes], [have_libasm=no])
+AM_CONDITIONAL(HAVE_LIBASM, [test $have_libasm = yes])
+
+AM_CONDITIONAL(STANDALONE, true)
+AM_CONDITIONAL(BUILD_STATIC, false)
+AM_CONDITIONAL(TESTS_RPATH, false)
+AM_CONDITIONAL(GCOV, false)
+
+dnl Text of the config.h file.
+AH_BOTTOM([#define ELFUTILS_HEADER(name) <elfutils/lib##name.h>])
+
+AC_OUTPUT
diff --git a/third_party/elfutils/tests/coverage.sh b/third_party/elfutils/tests/coverage.sh
new file mode 100755
index 0000000..5cc353c
--- /dev/null
+++ b/third_party/elfutils/tests/coverage.sh
@@ -0,0 +1,40 @@
+#! /bin/bash
+
+if [ "x$1" = "x-v" ]; then
+  verbose=yes
+else
+  verbose=no
+fi
+
+cd ..
+
+for d in lib libasm libdw libdwfl libebl libelf backends src; do
+  tmp=$d-data
+  cd $d
+  unused=0
+  unused_files=
+  for f in *.gcno; do
+    base="$(basename $f .gcno)"
+    fc="$base.c"
+    gcda="$base.gcda"
+    if [ -f "$gcda" ]; then
+      gcov -n -a "$fc" |
+      gawk "/$d.$fc/ { getline; co=gensub(/.*:(.*)% .*/, \"\\\\1\", \"g\"); co=co+0.0; li=\$4+0; printf \"%-35s  %6.2f %5d\n\", \"$d/$fc\", co, li } " >> $tmp
+    else
+      unused=$(($unused + 1))
+      unused_files="$unused_files $fc"
+    fi
+  done
+  if [ -f $tmp ]; then
+    gawk "{ copct=\$2; co=(\$3*copct)/100; toco+=(co+0); toli += (\$3+0); } END { printf \"%-12s %6.2f%% covered       unused files: %3d\n\", \"$d\", (toco*100)/toli, \"$unused\" }" $tmp
+    rm -f $tmp
+  else
+    printf "%-12s   0.00%% covered       unused files: %3d\n" "$d" $unused
+  fi
+  if [ $verbose = yes ]; then
+    for f in $unused_files; do
+      printf '%-42s%s\n' '' $f
+    done
+  fi
+  cd ..
+done
diff --git a/third_party/elfutils/tests/debug-ranges-no-lowpc.o.bz2 b/third_party/elfutils/tests/debug-ranges-no-lowpc.o.bz2
new file mode 100644
index 0000000..871a3fb
--- /dev/null
+++ b/third_party/elfutils/tests/debug-ranges-no-lowpc.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/debug-ranges-no-lowpc.s b/third_party/elfutils/tests/debug-ranges-no-lowpc.s
new file mode 100644
index 0000000..879bce2
--- /dev/null
+++ b/third_party/elfutils/tests/debug-ranges-no-lowpc.s
@@ -0,0 +1,49 @@
+        .section .debug_info
+.Lcu1_begin:
+        .4byte        .Lcu1_end - .Lcu1_start
+.Lcu1_start:
+        .2byte        3                 /* Version */
+        .4byte        .Labbrev1_begin   /* Abbrevs */
+        .byte        8                  /* Pointer size */
+        .uleb128        2               /* Abbrev (DW_TAG_compile_unit) */
+        .4byte        0
+.Lcu1_end:
+        .section .note.gnu.build-id, "a", %note
+        .4byte        4
+        .4byte        8
+        .4byte        3
+        .ascii        "GNU\0"
+        .byte        0x01
+        .byte        0x02
+        .byte        0x03
+        .byte        0x04
+        .byte        0x05
+        .byte        0x06
+        .byte        0x07
+        .byte        0x08
+        .section .debug_abbrev
+.Labbrev1_begin:
+        .uleb128        2               /* Abbrev start */
+        .uleb128        0x11            /* DW_TAG_compile_unit */
+        .byte        0                  /* has_children */
+        .uleb128        0x55            /* DW_AT_ranges */
+        .uleb128        0x06            /* DW_FORM_data4 */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+
+	.section .debug_ranges
+
+	.8byte 0xffffffffffffffff
+	.8byte 0
+
+	.8byte 1
+	.8byte 2
+
+	.8byte 3
+	.8byte 4
+
+	.8byte 0
+	.8byte 0
+
diff --git a/third_party/elfutils/tests/debugaltlink.c b/third_party/elfutils/tests/debugaltlink.c
new file mode 100644
index 0000000..6d97d50
--- /dev/null
+++ b/third_party/elfutils/tests/debugaltlink.c
@@ -0,0 +1,83 @@
+/* Test program for dwelf_dwarf_gnu_debugaltlink, print name and build ID.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <err.h>
+#include <errno.h>
+#include ELFUTILS_HEADER(dw)
+#include ELFUTILS_HEADER(dwelf)
+#include <stdio.h>
+#include <error.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int
+main (int argc, char *argv[])
+{
+  if (argc < 2)
+    error (EXIT_FAILURE, 0, "No input file given");
+
+  elf_version (EV_CURRENT);
+
+  for (int i = 1; i < argc; i++)
+    {
+      const char *file = argv[i];
+      int fd = open (file, O_RDONLY);
+      if (fd < 0)
+	error (EXIT_FAILURE, errno, "couldn't open file '%s'", file);
+
+      Dwarf *dwarf = dwarf_begin (fd, DWARF_C_READ);
+      if (dwarf == NULL)
+	{
+	  printf("%s: dwarf_begin failed: %s\n", file, dwarf_errmsg (-1));
+	  close (fd);
+	  continue;
+	}
+
+      const char *name;
+      const void *build_id;
+      ssize_t ret = dwelf_dwarf_gnu_debugaltlink
+	(dwarf, &name, &build_id);
+      switch (ret)
+	{
+	case 0:
+	  printf ("%s: <no .gnu_debugaltlink section>\n", file);
+	  break;
+	case -1:
+	  errx (1, "dwelf_dwarf_gnu_debugaltlink (%s): %s",
+		file, dwarf_errmsg (-1));
+	default:
+	  printf ("%s: %s, build ID: ", file, name);
+	  const unsigned char *p = build_id;
+	  const unsigned char *end = p + ret;
+	  while (p < end)
+	      printf("%02x", (unsigned)*p++);
+	  putchar('\n');
+	}
+
+      dwarf_end (dwarf);
+      close (fd);
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/debuglink.c b/third_party/elfutils/tests/debuglink.c
new file mode 100644
index 0000000..935d102
--- /dev/null
+++ b/third_party/elfutils/tests/debuglink.c
@@ -0,0 +1,64 @@
+/* Test program for dwelf_elf_gnu_debuglink, print name and crc.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <errno.h>
+#include ELFUTILS_HEADER(dwelf)
+#include <stdio.h>
+#include <error.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int
+main (int argc, char *argv[])
+{
+  if (argc < 2)
+    error (EXIT_FAILURE, 0, "No input file given");
+
+  elf_version (EV_CURRENT);
+
+  for (int i = 1; i < argc; i++)
+    {
+      const char *file = argv[i];
+      int fd = open (file, O_RDONLY);
+      if (fd < 0)
+	error (EXIT_FAILURE, errno, "couldn't open file '%s'", file);
+
+      Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+      if (elf == NULL)
+	error (EXIT_FAILURE, 0, "elf_begin failed for '%s': %s",
+	       file, elf_errmsg (-1));
+
+      GElf_Word crc;
+      const char *debug = dwelf_elf_gnu_debuglink (elf, &crc);
+      if (debug == NULL)
+	printf ("%s: <no gnu_debuglink file>\n", file);
+      else
+	printf ("%s: %s, crc: %" PRIx32 "\n", file, debug, crc);
+
+      elf_end (elf);
+      close (fd);
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/deleted-lib.c b/third_party/elfutils/tests/deleted-lib.c
new file mode 100644
index 0000000..1ff411b
--- /dev/null
+++ b/third_party/elfutils/tests/deleted-lib.c
@@ -0,0 +1,27 @@
+/* Test program for opening already deleted running binaries.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <unistd.h>
+
+void
+libfunc (void)
+{
+  sleep (60000);
+  /* Avoid tail call optimization for the sleep call.  */
+  asm volatile ("");
+}
diff --git a/third_party/elfutils/tests/deleted.c b/third_party/elfutils/tests/deleted.c
new file mode 100644
index 0000000..6be35bc
--- /dev/null
+++ b/third_party/elfutils/tests/deleted.c
@@ -0,0 +1,58 @@
+/* Test program for opening already deleted running binaries.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+#include <error.h>
+#include <errno.h>
+#ifdef __linux__
+#include <sys/prctl.h>
+#endif
+
+extern void libfunc (void);
+
+int
+main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)))
+{
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  pid_t pid = fork ();
+  assert (pid != -1);
+  if (pid == 0)
+    {
+      int err = close (0);
+      assert (!err);
+      err = close (1);
+      assert (!err);
+      err = close (2);
+      assert (!err);
+      /* Make sure eu-stack -p works on this process even with
+	 "restricted ptrace".  */
+#ifdef PR_SET_PTRACER_ANY
+      prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
+#endif
+      libfunc ();
+      abort ();
+    }
+  printf ("%d\n", pid);
+  return EXIT_SUCCESS;
+}
diff --git a/third_party/elfutils/tests/dwarf-getmacros.c b/third_party/elfutils/tests/dwarf-getmacros.c
new file mode 100644
index 0000000..ac70248
--- /dev/null
+++ b/third_party/elfutils/tests/dwarf-getmacros.c
@@ -0,0 +1,144 @@
+/* Test program for dwarf_getmacros and related
+   Copyright (C) 2009, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include ELFUTILS_HEADER(dw)
+#include <dwarf.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <inttypes.h>
+
+static void include (Dwarf *dbg, Dwarf_Off macoff, ptrdiff_t token);
+
+static int
+mac (Dwarf_Macro *macro, void *dbg)
+{
+  static int level = 0;
+
+  unsigned int opcode;
+  dwarf_macro_opcode (macro, &opcode);
+  switch (opcode)
+    {
+    case DW_MACRO_import:
+      {
+	Dwarf_Attribute at;
+	int r = dwarf_macro_param (macro, 0, &at);
+	assert (r == 0);
+
+	Dwarf_Word w;
+	r = dwarf_formudata (&at, &w);
+	assert (r == 0);
+
+	printf ("%*sinclude %#" PRIx64 "\n", level, "", w);
+	++level;
+	include (dbg, w, DWARF_GETMACROS_START);
+	--level;
+	printf ("%*s/include\n", level, "");
+	break;
+      }
+
+    case DW_MACRO_start_file:
+      {
+	Dwarf_Files *files;
+	size_t nfiles;
+	if (dwarf_macro_getsrcfiles (dbg, macro, &files, &nfiles) < 0)
+	  printf ("dwarf_macro_getsrcfiles: %s\n",
+		  dwarf_errmsg (dwarf_errno ()));
+
+	Dwarf_Word w = 0;
+	dwarf_macro_param2 (macro, &w, NULL);
+
+	const char *name = dwarf_filesrc (files, (size_t) w, NULL, NULL);
+	printf ("%*sfile %s\n", level, "", name);
+	++level;
+	break;
+      }
+
+    case DW_MACRO_end_file:
+      {
+	--level;
+	printf ("%*s/file\n", level, "");
+	break;
+      }
+
+    case DW_MACINFO_define:
+    case DW_MACRO_define_strp:
+      {
+	const char *value;
+	dwarf_macro_param2 (macro, NULL, &value);
+	printf ("%*s%s\n", level, "", value);
+	break;
+      }
+
+    case DW_MACINFO_undef:
+    case DW_MACRO_undef_strp:
+      break;
+
+    default:
+      {
+	size_t paramcnt;
+	dwarf_macro_getparamcnt (macro, &paramcnt);
+	printf ("%*sopcode %u with %zd arguments\n",
+		level, "", opcode, paramcnt);
+	break;
+      }
+    }
+
+  return DWARF_CB_ABORT;
+}
+
+static void
+include (Dwarf *dbg, Dwarf_Off macoff, ptrdiff_t token)
+{
+  while ((token = dwarf_getmacros_off (dbg, macoff, mac, dbg, token)) != 0)
+    if (token == -1)
+      {
+	puts (dwarf_errmsg (dwarf_errno ()));
+	break;
+      }
+}
+
+int
+main (int argc, char *argv[])
+{
+  assert (argc >= 3);
+  const char *name = argv[1];
+  ptrdiff_t cuoff = strtol (argv[2], NULL, 0);
+  bool new_style = argc > 3;
+
+  int fd = open (name, O_RDONLY);
+  Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+
+  Dwarf_Die cudie_mem, *cudie = dwarf_offdie (dbg, cuoff, &cudie_mem);
+
+  for (ptrdiff_t off = new_style ? DWARF_GETMACROS_START : 0;
+       (off = dwarf_getmacros (cudie, mac, dbg, off)); )
+    if (off == -1)
+      {
+	puts (dwarf_errmsg (dwarf_errno ()));
+	break;
+      }
+
+  dwarf_end (dbg);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/dwarf-getstring.c b/third_party/elfutils/tests/dwarf-getstring.c
new file mode 100644
index 0000000..ffa3e37
--- /dev/null
+++ b/third_party/elfutils/tests/dwarf-getstring.c
@@ -0,0 +1,78 @@
+/* Copyright (C) 2011 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Marek Polacek <mpolacek@redhat.com>, 2011.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include ELFUTILS_HEADER(dwfl)
+#include <assert.h>
+#include <dwarf.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+int
+main (int argc, char *argv[])
+{
+  int cnt;
+
+  for (cnt = 1; cnt < argc; ++cnt)
+    {
+      Dwarf_Off offset = 0;
+      size_t len;
+
+      int fd = open (argv[cnt], O_RDONLY);
+      if (fd == -1)
+	{
+	  printf ("cannot open '%s': %m\n", argv[cnt]);
+	  return 1;
+	}
+
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if (dbg == NULL)
+	{
+	  printf ("%s not usable: %s\n", argv[cnt], dwarf_errmsg (-1));
+	  close (fd);
+	  return 1;
+	}
+
+      /* Try to use NULL Dwarf object.  */
+      const char *str = dwarf_getstring (NULL, offset, &len);
+      assert (str == NULL);
+
+      /* Use insane offset.  */
+      str = dwarf_getstring (dbg, ~0UL, &len);
+      assert (str == NULL);
+
+      /* Now do some real work.  */
+      for (int i = 0; i < 100; ++i)
+	{
+	  str = dwarf_getstring (dbg, offset, &len);
+	  puts (str);
+
+	  /* Advance.  */
+	  offset += len + 1;
+	}
+
+      dwarf_end (dbg);
+      close (fd);
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/dwarf-ranges.c b/third_party/elfutils/tests/dwarf-ranges.c
new file mode 100644
index 0000000..4bcf96c
--- /dev/null
+++ b/third_party/elfutils/tests/dwarf-ranges.c
@@ -0,0 +1,57 @@
+/* Test program for dwarf_ranges
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include ELFUTILS_HEADER(dw)
+#include <dwarf.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <inttypes.h>
+
+int
+main (int argc, char *argv[])
+{
+  assert (argc >= 3);
+  const char *name = argv[1];
+  ptrdiff_t cuoff = strtol (argv[2], NULL, 0);
+
+  int fd = open (name, O_RDONLY);
+  Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+
+  Dwarf_Die cudie_mem, *cudie = dwarf_offdie (dbg, cuoff, &cudie_mem);
+
+  Dwarf_Addr base, start, end;
+  for (ptrdiff_t off = 0;
+       (off = dwarf_ranges (cudie, off, &base, &start, &end)); )
+    if (off == -1)
+      {
+	puts (dwarf_errmsg (dwarf_errno ()));
+	break;
+      }
+    else
+      fprintf (stderr, "%"PRIx64"..%"PRIx64" (base %"PRIx64")\n",
+	       start, end, base);
+
+  dwarf_end (dbg);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/dwarf_default_lower_bound.c b/third_party/elfutils/tests/dwarf_default_lower_bound.c
new file mode 100644
index 0000000..d57424f
--- /dev/null
+++ b/third_party/elfutils/tests/dwarf_default_lower_bound.c
@@ -0,0 +1,83 @@
+/* Test all DW_LANG constants are handled by dwarf_default_lower_bound.
+
+   Copyright (C) 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include ELFUTILS_HEADER(dw)
+#include "../libdw/known-dwarf.h"
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static void
+test_lang (const char *name, int lang)
+{
+  Dwarf_Sword low;
+  int res = dwarf_default_lower_bound (lang, &low);
+
+  /* Assembler is special, it doesn't really have arrays.  */
+  if (lang == DW_LANG_Mips_Assembler)
+    {
+      if (res == 0)
+	{
+	  printf ("%s shouldn't have a known lower bound\n", name);
+	  exit (-1);
+	}
+      printf ("%s: <unknown>\n", name);
+      return;
+    }
+
+  if (res != 0)
+    {
+      printf ("dwarf_default_lower_bound failed (%d) for %s\n", res, name);
+      exit (-1);
+    }
+
+  /* All currently known lower bounds are either zero or one, but
+     they don't have to.  Update test once one is a different value.  */
+  if (low != 0 && low != 1)
+    {
+      printf ("unexpected lower bound %" PRId64 " for %s\n", low, name);
+      exit (-1);
+    }
+
+  printf ("%s: %" PRId64 "\n", name, low);
+}
+
+int
+main (int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused)))
+{
+  Dwarf_Sword low;
+  /* Bad language code must fail.  */
+  if (dwarf_default_lower_bound (-1, &low) == 0)
+    {
+      printf ("Bad lang code -1 succeeded (%" PRId64 ")\n", low);
+      exit (-1);
+    }
+
+  /* Test all known language codes.  */
+#define DWARF_ONE_KNOWN_DW_LANG(NAME, CODE) test_lang (#NAME, CODE);
+  DWARF_ALL_KNOWN_DW_LANG
+#undef DWARF_ONE_KNOWN_DW_LANG
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/dwelfgnucompressed.c b/third_party/elfutils/tests/dwelfgnucompressed.c
new file mode 100644
index 0000000..0132271
--- /dev/null
+++ b/third_party/elfutils/tests/dwelfgnucompressed.c
@@ -0,0 +1,104 @@
+/* Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include ELFUTILS_HEADER(elf)
+#include ELFUTILS_HEADER(dwelf)
+#include <gelf.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+  int result = 0;
+  int cnt;
+
+  elf_version (EV_CURRENT);
+
+  for (cnt = 1; cnt < argc; ++cnt)
+    {
+      int fd = open (argv[cnt], O_RDONLY);
+
+      Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+      if (elf == NULL)
+	{
+	  printf ("%s not usable %s\n", argv[cnt], elf_errmsg (-1));
+	  result = 1;
+	  close (fd);
+	  continue;
+	}
+
+      size_t shdrstrndx;
+      if (elf_getshdrstrndx (elf, &shdrstrndx) == -1)
+	{
+	  printf ("elf_getshdrstrnd failed %s\n", elf_errmsg (-1));
+	  result = 1;
+	  close (fd);
+	  continue;
+	}
+
+      Elf_Scn *scn = NULL;
+      while ((scn = elf_nextscn (elf, scn)) != NULL)
+	{
+	  int idx = elf_ndxscn (scn);
+	  GElf_Shdr shdr;
+	  if (gelf_getshdr (scn, &shdr) == NULL)
+	    {
+	      printf ("gelf_getshdr failed: %s\n", elf_errmsg (-1));
+	      result = 1;
+	      break;
+	    }
+
+	  const char *sname = elf_strptr (elf, shdrstrndx, shdr.sh_name);
+	  if (sname == NULL)
+	    {
+	      printf ("couldn't get section name: %s\n", elf_errmsg (-1));
+	      result = 1;
+	      break;
+	    }
+
+	  if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
+	    {
+	      ssize_t size;
+	      if ((size = dwelf_scn_gnu_compressed_size (scn)) == -1)
+		{
+		  printf ("dwelf_scn_gnu_compressed_size failed: %s\n",
+			  elf_errmsg (-1));
+		  result = 1;
+		  break;
+		}
+	      printf ("section %d: GNU Compressed size: %zx\n", idx, size);
+	    }
+	}
+
+      elf_end (elf);
+      close (fd);
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/dwfl-addr-sect.c b/third_party/elfutils/tests/dwfl-addr-sect.c
new file mode 100644
index 0000000..21e470a
--- /dev/null
+++ b/third_party/elfutils/tests/dwfl-addr-sect.c
@@ -0,0 +1,80 @@
+/* Test program for libdwfl ... foo
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+#include <locale.h>
+#include <argp.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+
+static int
+handle_address (Dwfl *dwfl, Dwarf_Addr address)
+{
+  Dwfl_Module *mod = dwfl_addrmodule (dwfl, address);
+  Dwarf_Addr adjusted = address;
+  Dwarf_Addr bias;
+  Elf_Scn *scn = dwfl_module_address_section (mod, &adjusted, &bias);
+  if (scn == NULL)
+    {
+      error (0, 0, "%#" PRIx64 ": dwfl_module_address_section: %s",
+	     address, dwfl_errmsg (-1));
+      return 1;
+    }
+  printf ("address %#" PRIx64 " => module \"%s\" section %zu + %#" PRIx64 "\n",
+	  address,
+	  dwfl_module_info (mod, NULL, NULL, NULL, NULL, NULL, NULL, NULL),
+	  elf_ndxscn (scn), adjusted);
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  int remaining;
+  Dwfl *dwfl = NULL;
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl);
+  assert (dwfl != NULL);
+
+  int result = 0;
+  for (; remaining < argc; ++remaining)
+    {
+      char *endp;
+      uintmax_t addr = strtoumax (argv[remaining], &endp, 0);
+      if (endp != argv[remaining])
+	result |= handle_address (dwfl, addr);
+      else
+	result = 1;
+    }
+
+  dwfl_end (dwfl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/dwfl-bug-addr-overflow.c b/third_party/elfutils/tests/dwfl-bug-addr-overflow.c
new file mode 100644
index 0000000..aa8030e
--- /dev/null
+++ b/third_party/elfutils/tests/dwfl-bug-addr-overflow.c
@@ -0,0 +1,73 @@
+/* Test program for libdwfl basic module tracking, relocation.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <error.h>
+#include <locale.h>
+#include ELFUTILS_HEADER(dwfl)
+
+
+static const Dwfl_Callbacks offline_callbacks =
+  {
+    .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
+    .section_address = INTUSE(dwfl_offline_section_address),
+  };
+
+
+int
+main (void)
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  Dwfl *dwfl = dwfl_begin (&offline_callbacks);
+  assert (dwfl != NULL);
+
+  Dwfl_Module *high = dwfl_report_module (dwfl, "high",
+					  UINT64_C (0xffffffff00010000),
+					  UINT64_C (0xffffffff00020000));
+  assert (high);
+  Dwfl_Module *low = dwfl_report_module (dwfl, "low",
+					 UINT64_C (0x00010000),
+					 UINT64_C (0x00020000));
+  assert (low);
+  Dwfl_Module *middle = dwfl_report_module (dwfl, "middle",
+					    UINT64_C (0xffff00010000),
+					    UINT64_C (0xffff00020000));
+  assert (middle);
+
+  int ret = dwfl_report_end (dwfl, NULL, NULL);
+  assert (ret == 0);
+
+  Dwfl_Module *mod = dwfl_addrmodule (dwfl, UINT64_C (0xffffffff00010123));
+  assert (mod == high);
+  mod = dwfl_addrmodule (dwfl, UINT64_C (0x00010123));
+  assert (mod == low);
+  mod = dwfl_addrmodule (dwfl, UINT64_C (0xffff00010123));
+  assert (mod == middle);
+
+  dwfl_end (dwfl);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/dwfl-bug-fd-leak.c b/third_party/elfutils/tests/dwfl-bug-fd-leak.c
new file mode 100644
index 0000000..689cdd7
--- /dev/null
+++ b/third_party/elfutils/tests/dwfl-bug-fd-leak.c
@@ -0,0 +1,116 @@
+/* Test program for libdwfl file decriptors leakage.
+   Copyright (C) 2007, 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <locale.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <error.h>
+#include <unistd.h>
+#include <dwarf.h>
+
+#ifndef __linux__
+int
+main (void)
+{
+  return 77; /* dwfl_linux_proc_report is linux specific.  */
+}
+#else
+
+#include <sys/resource.h>
+#include ELFUTILS_HEADER(dwfl)
+
+
+static Dwfl *
+elfutils_open (pid_t pid, Dwarf_Addr address)
+{
+  static char *debuginfo_path;
+  static const Dwfl_Callbacks proc_callbacks =
+    {
+      .find_debuginfo = dwfl_standard_find_debuginfo,
+      .debuginfo_path = &debuginfo_path,
+
+      .find_elf = dwfl_linux_proc_find_elf,
+    };
+  Dwfl *dwfl = dwfl_begin (&proc_callbacks);
+  if (dwfl == NULL)
+    error (2, 0, "dwfl_begin: %s", dwfl_errmsg (-1));
+
+  int result = dwfl_linux_proc_report (dwfl, pid);
+  if (result < 0)
+    error (2, 0, "dwfl_linux_proc_report: %s", dwfl_errmsg (-1));
+  else if (result > 0)
+    error (2, result, "dwfl_linux_proc_report");
+
+  if (dwfl_report_end (dwfl, NULL, NULL) != 0)
+    error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1));
+
+  Dwarf_Addr bias;
+  Dwarf *dbg = dwfl_addrdwarf (dwfl, address, &bias);
+  if (dbg != NULL)
+    {
+      Elf *elf = dwarf_getelf (dbg);
+      if (elf == NULL)
+	error (2, 0, "dwarf_getelf: %s", dwarf_errmsg (-1));
+    }
+  else
+    {
+      Dwfl_Module *module = dwfl_addrmodule (dwfl, address);
+      if (module == NULL)
+	error (2, 0, "dwfl_addrmodule: no module available for 0x%" PRIx64 "",
+	       address);
+      Elf *elf = dwfl_module_getelf (module, &bias);
+      if (elf == NULL)
+	error (2, 0, "dwfl_module_getelf: %s", dwfl_errmsg (-1));
+    }
+
+  return dwfl;
+}
+
+static void
+elfutils_close (Dwfl *dwfl)
+{
+  dwfl_end (dwfl);
+}
+
+int
+main (void)
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  struct rlimit fd_limit = { .rlim_cur = 32, .rlim_max = 32 };
+  if (setrlimit (RLIMIT_NOFILE, &fd_limit) < 0)
+    error (2, errno, "setrlimit");
+
+  for (int i = 0; i < 5000; ++i)
+    {
+      Dwfl *dwfl = elfutils_open (getpid (), (Dwarf_Addr) (uintptr_t) &main);
+      elfutils_close (dwfl);
+    }
+
+  return 0;
+}
+#endif
diff --git a/third_party/elfutils/tests/dwfl-bug-getmodules.c b/third_party/elfutils/tests/dwfl-bug-getmodules.c
new file mode 100644
index 0000000..1ee989f
--- /dev/null
+++ b/third_party/elfutils/tests/dwfl-bug-getmodules.c
@@ -0,0 +1,66 @@
+/* Test program for dwfl_getmodules bug.
+   Copyright (C) 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include ELFUTILS_HEADER(dwfl)
+
+#include <error.h>
+
+static const Dwfl_Callbacks callbacks =
+  {
+    .find_elf = dwfl_linux_proc_find_elf,
+    .find_debuginfo = dwfl_standard_find_debuginfo,
+  };
+
+static int
+iterate (Dwfl_Module *mod __attribute__ ((unused)),
+	 void **userdata __attribute__ ((unused)),
+	 const char *name __attribute__ ((unused)),
+	 Dwarf_Addr base, void *arg)
+{
+  if (base != 0x2000)
+    return DWARF_CB_OK;
+
+  if (dwfl_addrmodule (arg, 0x2100) == NULL)
+    error (1, 0, "dwfl_addrmodule: %s", dwfl_errmsg (-1));
+
+  return DWARF_CB_ABORT;
+}
+
+int
+main (void)
+{
+  Dwfl *dwfl = dwfl_begin (&callbacks);
+
+  dwfl_report_module (dwfl, "m1", 0, 0x1000);
+  dwfl_report_module (dwfl, "m2", 0x2000, 0x3000);
+  dwfl_report_module (dwfl, "m3", 0x4000, 0x5000);
+
+  dwfl_report_end (dwfl, NULL, NULL);
+
+  ptrdiff_t offset = dwfl_getmodules (dwfl, &iterate, dwfl, 0);
+  if (offset <= 0)
+    error (1, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
+
+  offset = dwfl_getmodules (dwfl, &iterate, NULL, offset);
+  if (offset != 0)
+    error (1, 0, "dwfl_getmodules (%d): %s", (int) offset, dwfl_errmsg (-1));
+
+  dwfl_end (dwfl);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/dwfl-bug-report.c b/third_party/elfutils/tests/dwfl-bug-report.c
new file mode 100644
index 0000000..80ff806
--- /dev/null
+++ b/third_party/elfutils/tests/dwfl-bug-report.c
@@ -0,0 +1,48 @@
+/* Test program for dwfl_report_end bug.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include ELFUTILS_HEADER(dwfl)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+static const Dwfl_Callbacks callbacks =
+  {
+    .find_elf = dwfl_linux_proc_find_elf,
+    .find_debuginfo = dwfl_standard_find_debuginfo,
+  };
+
+int
+main (void)
+{
+  Dwfl *dwfl = dwfl_begin (&callbacks);
+
+  for (int i = 0; i < 5; ++i)
+    {
+      dwfl_report_begin (dwfl);
+      dwfl_report_module (dwfl, "module1", 0, 10);
+      dwfl_report_end (dwfl, NULL, NULL);
+    }
+
+  dwfl_end (dwfl);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/dwfl-proc-attach.c b/third_party/elfutils/tests/dwfl-proc-attach.c
new file mode 100644
index 0000000..e7bb201
--- /dev/null
+++ b/third_party/elfutils/tests/dwfl-proc-attach.c
@@ -0,0 +1,103 @@
+/* Test dwfl_linux_proc_attach works without any modules.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <error.h>
+#include <unistd.h>
+#ifdef __linux__
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/user.h>
+#include <fcntl.h>
+#include <string.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <pthread.h>
+#endif
+
+#ifndef __linux__
+int
+main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)))
+{
+  printf ("dwfl_linux_proc_attach unsupported.\n");
+  return 77;
+}
+#else /* __linux__ */
+
+static pthread_t thread1;
+static pthread_t thread2;
+
+static void *
+sleeper (void* d __attribute__ ((unused)))
+{
+  sleep (60);
+  return NULL;
+}
+
+static char *debuginfo_path = NULL;
+
+static const Dwfl_Callbacks proc_callbacks =
+  {
+    .find_elf = dwfl_linux_proc_find_elf,
+    .find_debuginfo = dwfl_standard_find_debuginfo,
+    .debuginfo_path = &debuginfo_path,
+  };
+
+static int
+thread_callback (Dwfl_Thread *thread, void *thread_arg)
+{
+  int *threads = (int *) thread_arg;
+  pid_t tid = dwfl_thread_tid (thread);
+  printf ("thread tid: %d\n", tid);
+  (*threads)++;
+
+  return DWARF_CB_OK;
+}
+
+int
+main (int argc __attribute__ ((unused)),
+      char **argv __attribute__ ((unused)))
+{
+  /* Create two extra threads to iterate through.  */
+  int err;
+  if ((err = pthread_create (&thread1, NULL, sleeper, NULL)) != 0)
+    error (-1, err, "Couldn't create thread1");
+  if ((err = pthread_create (&thread2, NULL, sleeper, NULL)) != 0)
+    error (-1, err, "Couldn't create thread2");
+
+  Dwfl *dwfl = dwfl_begin (&proc_callbacks);
+  if (dwfl == NULL)
+    error (-1, 0, "dwfl_begin: %s", dwfl_errmsg (-1));
+
+  pid_t pid = getpid ();
+  /* This used to fail, since we don't have any modules yet.  */
+  if (dwfl_linux_proc_attach (dwfl, pid, false) < 0)
+    error (-1, 0, "dwfl_linux_proc_attach pid %d: %s", pid,
+	   dwfl_errmsg (-1));
+
+  /* Did we see all 3 threads?  */
+  int threads = 0;
+  if (dwfl_getthreads (dwfl, thread_callback, &threads) != DWARF_CB_OK)
+    error (-1, 0, "dwfl_getthreads failed: %s", dwfl_errmsg (-1));
+
+  return (threads == 3) ? 0 : -1;
+}
+
+#endif /* __linux__ */
diff --git a/third_party/elfutils/tests/dwfl-report-elf-align.c b/third_party/elfutils/tests/dwfl-report-elf-align.c
new file mode 100644
index 0000000..a4e97d3
--- /dev/null
+++ b/third_party/elfutils/tests/dwfl-report-elf-align.c
@@ -0,0 +1,72 @@
+/* Test program for dwfl_report_elf incorrect BASE alignment.
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <error.h>
+#include <locale.h>
+#include <string.h>
+#include <stdlib.h>
+#include ELFUTILS_HEADER(dwfl)
+
+
+static const Dwfl_Callbacks offline_callbacks =
+  {
+    .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
+    .section_address = INTUSE(dwfl_offline_section_address),
+  };
+
+
+int
+main (int argc, char **argv)
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  if (argc != 5)
+    error (1, 0, "dwfl-report-elf-align shlib.so base funcaddr funcname");
+    
+  Dwfl *dwfl = dwfl_begin (&offline_callbacks);
+  assert (dwfl != NULL);
+
+  char *endptr;
+  uintptr_t base = strtoull (argv[2], &endptr, 0);
+  assert (endptr && !*endptr);
+
+  Dwfl_Module *mod = dwfl_report_elf (dwfl, argv[1], argv[1], -1, base, false);
+  assert (mod != NULL);
+
+  uintptr_t funcaddr = strtoull (argv[3], &endptr, 0);
+  assert (endptr && !*endptr);
+
+  Dwfl_Module *mod_found = dwfl_addrmodule (dwfl, funcaddr);
+  assert (mod_found == mod);
+
+  const char *symname = dwfl_module_addrname (mod, funcaddr);
+  assert (symname != NULL);
+  assert (strcmp (symname, argv[4]) == 0);
+
+  dwfl_end (dwfl);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/dwfllines.c b/third_party/elfutils/tests/dwfllines.c
new file mode 100644
index 0000000..90379dd
--- /dev/null
+++ b/third_party/elfutils/tests/dwfllines.c
@@ -0,0 +1,164 @@
+/* Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <assert.h>
+#include ELFUTILS_HEADER(dw)
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+#include <argp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+
+int
+main (int argc, char *argv[])
+{
+  int cnt;
+
+  Dwfl *dwfl = NULL;
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &cnt, &dwfl);
+  assert (dwfl != NULL);
+
+  Dwarf_Die *cu = NULL;
+  Dwarf_Addr bias;
+  do
+    {
+      cu = dwfl_nextcu (dwfl, cu, &bias);
+      if (cu != NULL)
+	{
+	  Dwfl_Module *mod = dwfl_cumodule (cu);
+	  const char *modname = (dwfl_module_info (mod, NULL, NULL, NULL,
+						   NULL, NULL, NULL, NULL)
+				 ?: "<unknown>");
+	  const char *cuname = (dwarf_diename (cu) ?: "<unknown>");
+
+	  printf ("mod: %s CU: [%" PRIx64 "] %s\n", modname,
+		  dwarf_dieoffset (cu), cuname);
+
+	  size_t lines;
+	  if (dwfl_getsrclines (cu, &lines) != 0)
+	    continue; // No lines...
+
+	  for (size_t i = 0; i < lines; i++)
+	    {
+	      Dwfl_Line *line = dwfl_onesrcline (cu, i);
+
+	      Dwarf_Addr addr;
+	      int lineno;
+	      int colno;
+	      Dwarf_Word mtime;
+	      Dwarf_Word length;
+	      const char *src = dwfl_lineinfo (line, &addr, &lineno, &colno,
+					       &mtime, &length);
+
+	      Dwarf_Addr dw_bias;
+	      Dwarf_Line *dw_line = dwfl_dwarf_line (line, &dw_bias);
+	      assert (bias == dw_bias);
+
+	      Dwarf_Addr dw_addr;
+	      if (dwarf_lineaddr (dw_line, &dw_addr) != 0)
+		error (EXIT_FAILURE, 0, "dwarf_lineaddr: %s",
+		       dwarf_errmsg (-1));
+	      assert (addr == dw_addr + dw_bias);
+
+	      unsigned int dw_op_index;
+	      if (dwarf_lineop_index (dw_line, &dw_op_index) != 0)
+		error (EXIT_FAILURE, 0, "dwarf_lineop_index: %s",
+		       dwarf_errmsg (-1));
+
+	      int dw_lineno;
+	      if (dwarf_lineno (dw_line, &dw_lineno) != 0)
+		error (EXIT_FAILURE, 0, "dwarf_lineno: %s",
+		       dwarf_errmsg (-1));
+	      assert (lineno == dw_lineno);
+
+	      int dw_colno;
+	      if (dwarf_linecol (dw_line, &dw_colno) != 0)
+		error (EXIT_FAILURE, 0, "dwarf_lineno: %s",
+		       dwarf_errmsg (-1));
+	      assert (colno == dw_colno);
+
+	      bool begin;
+	      if (dwarf_linebeginstatement (dw_line, &begin) != 0)
+		error (EXIT_FAILURE, 0, "dwarf_linebeginstatement: %s",
+		       dwarf_errmsg (-1));
+
+	      bool end;
+	      if (dwarf_lineendsequence (dw_line, &end) != 0)
+		error (EXIT_FAILURE, 0, "dwarf_lineendsequence: %s",
+		       dwarf_errmsg (-1));
+
+	      bool pend;
+	      if (dwarf_lineprologueend (dw_line, &pend) != 0)
+		error (EXIT_FAILURE, 0, "dwarf_lineprologueend: %s",
+		       dwarf_errmsg (-1));
+
+	      bool ebegin;
+	      if (dwarf_lineepiloguebegin (dw_line, &ebegin) != 0)
+		error (EXIT_FAILURE, 0, "dwarf_lineepiloguebegin: %s",
+		       dwarf_errmsg (-1));
+
+	      bool block;
+	      if (dwarf_lineblock (dw_line, &block) != 0)
+		error (EXIT_FAILURE, 0, "dwarf_lineblock: %s",
+		       dwarf_errmsg (-1));
+
+	      unsigned int isa;
+	      if (dwarf_lineisa (dw_line, &isa) != 0)
+		error (EXIT_FAILURE, 0, "dwarf_lineisa: %s",
+		       dwarf_errmsg (-1));
+
+	      unsigned int disc;
+	      if (dwarf_linediscriminator (dw_line, &disc) != 0)
+		error (EXIT_FAILURE, 0, "dwarf_linediscriminator: %s",
+		       dwarf_errmsg (-1));
+
+	      const char *dw_src;
+	      Dwarf_Word dw_mtime;
+	      Dwarf_Word dw_length;
+	      dw_src = dwarf_linesrc (dw_line, &dw_mtime, &dw_length);
+	      assert (strcmp (src, dw_src) == 0);
+	      assert (mtime == dw_mtime);
+	      assert (length == dw_length);
+
+	      printf ("%zd %#" PRIx64 " %s:%d:%d\n"
+		      " time: %#" PRIX64 ", len: %" PRIu64
+		      ", idx: %d, b: %d, e: %d"
+		      ", pe: %d, eb: %d, block: %d"
+		      ", isa: %d, disc: %d\n",
+		      i, addr, src, lineno, colno, mtime, length,
+		      dw_op_index, begin, end, pend, ebegin, block, isa, disc);
+
+	      Dwarf_Die *linecu = dwfl_linecu (line);
+	      assert (cu == linecu);
+
+	      Dwfl_Module *linemod = dwfl_linemodule (line);
+	      assert (mod == linemod);
+	    }
+	}
+    }
+  while (cu != NULL);
+
+  dwfl_end (dwfl);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/dwflmodtest.c b/third_party/elfutils/tests/dwflmodtest.c
new file mode 100644
index 0000000..0027f96
--- /dev/null
+++ b/third_party/elfutils/tests/dwflmodtest.c
@@ -0,0 +1,287 @@
+/* Test program for libdwfl basic module tracking, relocation.
+   Copyright (C) 2005, 2007 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+#include <locale.h>
+#include <argp.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+
+static bool show_inlines;
+
+struct info
+{
+  Dwarf_Die *cudie;
+  Dwarf_Addr dwbias;
+};
+
+static int
+print_instance (Dwarf_Die *instance, void *arg)
+{
+  const struct info *info = arg;
+
+  printf ("    inlined");
+
+  Dwarf_Files *files;
+  if (dwarf_getsrcfiles (info->cudie, &files, NULL) == 0)
+    {
+      Dwarf_Attribute attr_mem;
+      Dwarf_Word val;
+      if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_file,
+				       &attr_mem), &val) == 0)
+	{
+	  const char *file = dwarf_filesrc (files, val, NULL, NULL);
+	  int lineno = 0, colno = 0;
+	  if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_line,
+					   &attr_mem), &val) == 0)
+	    lineno = val;
+	  if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_column,
+					   &attr_mem), &val) == 0)
+	    colno = val;
+	  if (lineno == 0)
+	    {
+	      if (file != NULL)
+		printf (" from %s", file);
+	    }
+	  else if (colno == 0)
+	    printf (" at %s:%u", file, lineno);
+	  else
+	    printf (" at %s:%u:%u", file, lineno, colno);
+	}
+    }
+
+  Dwarf_Addr lo = -1, hi = -1, entry = -1;
+  if (dwarf_lowpc (instance, &lo) == 0)
+    lo += info->dwbias;
+  else
+    printf (" (lowpc => %s)", dwarf_errmsg (-1));
+  if (dwarf_highpc (instance, &hi) == 0)
+    hi += info->dwbias;
+  else
+    printf (" (highpc => %s)", dwarf_errmsg (-1));
+
+  Dwarf_Attribute attr_mem;
+  Dwarf_Attribute *attr = dwarf_attr (instance, DW_AT_entry_pc, &attr_mem);
+  if (attr != NULL)
+    {
+      if (dwarf_formaddr (attr, &entry) == 0)
+	entry += info->dwbias;
+      else
+	printf (" (entrypc => %s)", dwarf_errmsg (-1));
+    }
+
+  if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1)
+    printf (" %#" PRIx64 "..%#" PRIx64, lo, hi);
+  if (entry != (Dwarf_Addr) -1)
+    printf (" => %#" PRIx64 "\n", entry);
+  else
+    puts ("");
+
+  return DWARF_CB_OK;
+}
+
+static void
+print_inline (Dwarf_Die *func, void *arg)
+{
+  if (dwarf_func_inline_instances (func, &print_instance, arg) != 0)
+    printf ("  error finding instances: %s\n", dwarf_errmsg (-1));
+}
+
+static int
+print_func (Dwarf_Die *func, void *arg)
+{
+  const struct info *info = arg;
+
+  const char *file = dwarf_decl_file (func);
+  int line = -1;
+  dwarf_decl_line (func, &line);
+  const char *fct = dwarf_diename (func);
+
+  printf ("  %s:%d: %s:", file, line, fct);
+
+  if (dwarf_func_inline (func))
+    {
+      puts (" inline function");
+      if (show_inlines)
+	print_inline (func, arg);
+    }
+  else
+    {
+      Dwarf_Addr lo = -1, hi = -1, entry = -1;
+      if (dwarf_lowpc (func, &lo) == 0)
+	lo += info->dwbias;
+      else
+	printf (" (lowpc => %s)", dwarf_errmsg (-1));
+      if (dwarf_highpc (func, &hi) == 0)
+	hi += info->dwbias;
+      else
+	printf (" (highpc => %s)", dwarf_errmsg (-1));
+      if (dwarf_entrypc (func, &entry) == 0)
+	entry += info->dwbias;
+      else
+	printf (" (entrypc => %s)", dwarf_errmsg (-1));
+
+      if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1
+	  || entry != (Dwarf_Addr) -1)
+	printf (" %#" PRIx64 "..%#" PRIx64 " => %#" PRIx64 "\n",
+		lo, hi, entry);
+      else
+	puts ("");
+    }
+
+  return DWARF_CB_OK;
+}
+
+static int
+list_module (Dwfl_Module *mod __attribute__ ((unused)),
+	     void **userdata __attribute__ ((unused)),
+	     const char *name, Dwarf_Addr base,
+	     void *arg __attribute__ ((unused)))
+{
+  Dwarf_Addr start;
+  Dwarf_Addr end;
+  const char *file;
+  const char *debug;
+  if (dwfl_module_info (mod, NULL, &start, &end,
+			NULL, NULL, &file, &debug) != name
+      || start != base)
+    abort ();
+  printf ("module: %30s %08" PRIx64 "..%08" PRIx64 " %s %s\n",
+	  name, start, end, file, debug);
+  return DWARF_CB_OK;
+}
+
+static int
+print_module (Dwfl_Module *mod __attribute__ ((unused)),
+	      void **userdata __attribute__ ((unused)),
+	      const char *name, Dwarf_Addr base,
+	      Dwarf *dw, Dwarf_Addr bias,
+	      void *arg)
+{
+  printf ("module: %30s %08" PRIx64 " %s %" PRIx64 " (%s)\n",
+	  name, base, dw == NULL ? "no" : "DWARF", bias, dwfl_errmsg (-1));
+
+  if (dw != NULL && *(const bool *) arg)
+    {
+      Dwarf_Off off = 0;
+      size_t cuhl;
+      Dwarf_Off noff;
+
+      while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
+	{
+	  Dwarf_Die die_mem;
+	  struct info info = { dwarf_offdie (dw, off + cuhl, &die_mem), bias };
+	  (void) dwarf_getfuncs (info.cudie, print_func, &info, 0);
+
+	  off = noff;
+	}
+    }
+
+  return DWARF_CB_OK;
+}
+
+static bool show_functions;
+
+/* gettext helper macro.  */
+#undef	N_
+#define N_(Str) Str
+
+static const struct argp_option options[] =
+  {
+    { "functions", 'f', NULL, 0, N_("Additionally show function names"), 0 },
+    { "inlines", 'i', NULL, 0, N_("Show instances of inlined functions"), 0 },
+    { NULL, 0, NULL, 0, NULL, 0 }
+  };
+
+static error_t
+parse_opt (int key, char *arg __attribute__ ((unused)),
+	   struct argp_state *state __attribute__ ((unused)))
+{
+  switch (key)
+    {
+    case ARGP_KEY_INIT:
+      state->child_inputs[0] = state->input;
+      break;
+
+    case 'f':
+      show_functions = true;
+      break;
+
+    case 'i':
+      show_inlines = show_functions = true;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
+
+int
+main (int argc, char **argv)
+{
+  /* We use no threads here which can interfere with handling a stream.  */
+  (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  Dwfl *dwfl = NULL;
+  const struct argp_child argp_children[] =
+    {
+      { .argp = dwfl_standard_argp () },
+      { .argp = NULL }
+    };
+  const struct argp argp =
+    {
+      options, parse_opt, NULL, NULL, argp_children, NULL, NULL
+    };
+  (void) argp_parse (&argp, argc, argv, 0, NULL, &dwfl);
+  assert (dwfl != NULL);
+
+  ptrdiff_t p = 0;
+  do
+    p = dwfl_getmodules (dwfl, &list_module, NULL, p);
+  while (p > 0);
+  if (p < 0)
+    error (2, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
+
+  do
+    p = dwfl_getdwarf (dwfl, &print_module, &show_functions, p);
+  while (p > 0);
+  if (p < 0)
+    error (2, 0, "dwfl_getdwarf: %s", dwfl_errmsg (-1));
+
+  p = 0;
+  do
+    p = dwfl_getmodules (dwfl, &list_module, NULL, p);
+  while (p > 0);
+  if (p < 0)
+    error (2, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
+
+  dwfl_end (dwfl);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/dwflsyms.c b/third_party/elfutils/tests/dwflsyms.c
new file mode 100644
index 0000000..49ac334
--- /dev/null
+++ b/third_party/elfutils/tests/dwflsyms.c
@@ -0,0 +1,226 @@
+/* Test program for libdwfl symbol resolving
+   Copyright (C) 2013 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <elf.h>
+#include <dwarf.h>
+#include <argp.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <error.h>
+#include <string.h>
+
+static const char *
+gelf_type (GElf_Sym *sym)
+{
+  switch (GELF_ST_TYPE (sym->st_info))
+    {
+    case STT_NOTYPE:
+      return "NOTYPE";
+    case STT_OBJECT:
+      return "OBJECT";
+    case STT_FUNC:
+      return "FUNC";
+    case STT_SECTION:
+      return "SECTION";
+    case STT_FILE:
+      return "FILE";
+    case STT_COMMON:
+      return "COMMON";
+    case STT_TLS:
+      return "TLS";
+    default:
+      return "UNKNOWN";
+    }
+}
+
+static const char *
+gelf_bind (GElf_Sym *sym)
+{
+  switch (GELF_ST_BIND (sym->st_info))
+    {
+    case STB_LOCAL:
+      return "LOCAL";
+    case STB_GLOBAL:
+      return "GLOBAL";
+    case STB_WEAK:
+      return "WEAK";
+    default:
+      return "UNKNOWN";
+    }
+}
+
+static int
+gelf_bind_order (GElf_Sym *sym)
+{
+  switch (GELF_ST_BIND (sym->st_info))
+    {
+    case STB_LOCAL:
+      return 1;
+    case STB_WEAK:
+      return 2;
+    case STB_GLOBAL:
+      return 3;
+    default:
+      return 0;
+    }
+}
+
+static const char *
+elf_section_name (Elf *elf, GElf_Word shndx)
+{
+  GElf_Ehdr ehdr;
+  GElf_Shdr shdr;
+  Elf_Scn *scn = elf_getscn (elf, shndx);
+  gelf_getshdr (scn, &shdr);
+  gelf_getehdr (elf, &ehdr);
+  return elf_strptr (elf, ehdr.e_shstrndx, shdr.sh_name);
+}
+
+bool
+addr_in_section (Elf *elf, GElf_Word shndx, GElf_Addr addr)
+{
+  GElf_Shdr shdr;
+  Elf_Scn *scn = elf_getscn (elf, shndx);
+  gelf_getshdr (scn, &shdr);
+  return addr >= shdr.sh_addr && addr < shdr.sh_addr + shdr.sh_size;
+}
+
+static int
+list_syms (struct Dwfl_Module *mod,
+	   void **user __attribute__ ((unused)), const char *mod_name,
+	   Dwarf_Addr low_addr __attribute__ ((unused)),
+	   void *arg __attribute__ ((unused)))
+{
+  int syms = dwfl_module_getsymtab (mod);
+  if (syms < 0)
+    {
+      printf ("%s: %s\n", mod_name, dwfl_errmsg (-1));
+      return DWARF_CB_OK;
+    }
+
+  for (int ndx = 0; ndx < syms; ndx++)
+    {
+      GElf_Sym sym;
+      GElf_Word shndxp;
+      Elf *elf;
+      Dwarf_Addr bias;
+      const char *name = dwfl_module_getsym (mod, ndx, &sym, &shndxp);
+
+      printf("%4d: %s\t%s\t%s (%" PRIu64 ") %#" PRIx64,
+	     ndx, gelf_type (&sym), gelf_bind (&sym), name,
+	     sym.st_size, sym.st_value);
+
+      /* The info variant doesn't adjust st_value but returns the (possible)
+	 adjusted value separately. */
+      GElf_Addr value;
+      GElf_Sym isym;
+      name = dwfl_module_getsym_info (mod, ndx, &isym, &value, &shndxp,
+				      &elf, &bias);
+
+      GElf_Ehdr ehdr;
+      gelf_getehdr (elf, &ehdr);
+
+      // getsym st_values might or might not be adjusted depending on section.
+      // For ET_REL the adjustment is section relative.
+      assert (sym.st_value == isym.st_value
+	      || sym.st_value == isym.st_value + bias
+	      || ehdr.e_type == ET_REL);
+
+      /* And the reverse, which works for function symbols at least.
+	 Note this only works because the st.value is adjusted by
+	 dwfl_module_getsym ().  */
+      if (GELF_ST_TYPE (sym.st_info) == STT_FUNC && shndxp != SHN_UNDEF)
+	{
+	  /* Make sure the adjusted value really falls in the elf section. */
+          assert (addr_in_section (elf, shndxp, sym.st_value - bias));
+
+	  GElf_Addr addr = value;
+	  GElf_Sym asym;
+	  GElf_Word ashndxp;
+	  Elf *aelf;
+	  Dwarf_Addr abias;
+	  GElf_Off off;
+	  const char *aname = dwfl_module_addrinfo (mod, addr, &off, &asym,
+						    &ashndxp, &aelf, &abias);
+
+	  /* Make sure the adjusted value really falls in the elf section. */
+          assert (addr_in_section (aelf, ashndxp, asym.st_value)
+		  || ehdr.e_type == ET_REL);
+
+	  /* Either they are the same symbol (name), the binding of
+	     asym is "stronger" (or equal) to sym or asym is more specific
+	     (has a lower address) than sym.  */
+	  assert ((strcmp (name, aname) == 0
+		   || gelf_bind_order (&asym) >= gelf_bind_order (&sym))
+		  && value <= sym.st_value);
+
+	  addr = sym.st_value;
+	  int res = dwfl_module_relocate_address (mod, &addr);
+	  assert (res != -1);
+	  if (shndxp < SHN_LORESERVE)
+	    printf(", rel: %#" PRIx64 " (%s)", addr,
+		   elf_section_name (elf, shndxp));
+	  else
+	    printf(", rel: %#" PRIx64 "", addr);
+
+	  /* Print the section of the actual value if different from sym.  */
+	  if (value != isym.st_value + bias && ehdr.e_type != ET_REL)
+	    {
+	      GElf_Addr ebias;
+	      addr = value;
+	      Elf_Scn *scn = dwfl_module_address_section (mod, &addr, &ebias);
+	      GElf_Shdr shdr_mem;
+	      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	      Elf *melf = dwfl_module_getelf (mod, &ebias);
+	      gelf_getehdr (melf, &ehdr);
+	      const char *sname = elf_strptr (melf, ehdr.e_shstrndx,
+					      shdr->sh_name);
+	      printf (" [%#" PRIx64 ", rel: %#" PRIx64 " (%s)]",
+		      value, addr, sname);
+	    }
+
+	}
+      printf ("\n");
+    }
+
+  return DWARF_CB_OK;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+  Dwfl *dwfl;
+  error_t res;
+
+  res = argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining, &dwfl);
+  assert (res == 0 && dwfl != NULL);
+
+  ptrdiff_t off = 0;
+  do
+    off = dwfl_getmodules (dwfl, list_syms, NULL, off);
+  while (off > 0);
+
+  dwfl_end (dwfl);
+
+  return off;
+}
diff --git a/third_party/elfutils/tests/early-offscn.c b/third_party/elfutils/tests/early-offscn.c
new file mode 100644
index 0000000..924cb9e
--- /dev/null
+++ b/third_party/elfutils/tests/early-offscn.c
@@ -0,0 +1,52 @@
+/* Copyright (C) 2008 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main (int argc, char *argv[])
+{
+  if (argc < 2)
+    error (1, 0, "Usage: %s FILE OFFSET", argv[0]);
+
+  /* Set the ELF version.  */
+  elf_version (EV_CURRENT);
+
+  /* Open the archive.  */
+  int fd = open (argv[1], O_RDONLY);
+  if (fd < 0)
+    error (1, errno, "cannot open '%s'", argv[1]);
+
+  Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    error (2, 0, "elf_begin: %s", elf_errmsg (-1));
+
+  Elf_Scn *scn = gelf_offscn (elf, strtoull (argv[2], NULL, 0));
+  if (scn == NULL)
+    error (3, 0, "gelf_offscn: %s", elf_errmsg (-1));
+
+  elf_end (elf);
+  return 0;
+}
diff --git a/third_party/elfutils/tests/ecp.c b/third_party/elfutils/tests/ecp.c
new file mode 100644
index 0000000..38a6859
--- /dev/null
+++ b/third_party/elfutils/tests/ecp.c
@@ -0,0 +1,99 @@
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main (int argc, char *argv[])
+{
+  if (argc < 3)
+    error (EXIT_FAILURE, 0, "usage: %s FROMNAME TONAME", argv[0]);
+
+  elf_version (EV_CURRENT);
+
+  int infd = open (argv[1], O_RDONLY);
+  if (infd == -1)
+    error (EXIT_FAILURE, errno, "cannot open input file '%s'", argv[1]);
+
+  Elf *inelf = elf_begin (infd, ELF_C_READ, NULL);
+  if (inelf == NULL)
+    error (EXIT_FAILURE, 0, "problems opening '%s' as ELF file: %s",
+	   argv[1], elf_errmsg (-1));
+
+  int outfd = creat (argv[2], 0666);
+  if (outfd == -1)
+    error (EXIT_FAILURE, errno, "cannot open output file '%s'", argv[2]);
+
+  Elf *outelf = elf_begin (outfd, ELF_C_WRITE, NULL);
+  if (outelf == NULL)
+    error (EXIT_FAILURE, 0, "problems opening '%s' as ELF file: %s",
+	   argv[2], elf_errmsg (-1));
+
+  gelf_newehdr (outelf, gelf_getclass (inelf));
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr;
+  gelf_update_ehdr (outelf, (ehdr = gelf_getehdr (inelf, &ehdr_mem)));
+
+  if (ehdr->e_phnum > 0)
+    {
+      int cnt;
+
+      if (gelf_newphdr (outelf, ehdr->e_phnum) == 0)
+	error (EXIT_FAILURE, 0, "cannot create program header: %s",
+	       elf_errmsg (-1));
+
+      for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
+	{
+	  GElf_Phdr phdr_mem;
+
+	  gelf_update_phdr (outelf, cnt, gelf_getphdr (inelf, cnt, &phdr_mem));
+	}
+    }
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (inelf, scn)) != NULL)
+    {
+      Elf_Scn *newscn = elf_newscn (outelf);
+
+      GElf_Shdr shdr_mem;
+      gelf_update_shdr (newscn, gelf_getshdr (scn, &shdr_mem));
+
+      *elf_newdata (newscn) = *elf_getdata (scn, NULL);
+    }
+
+  elf_flagelf (outelf, ELF_C_SET, ELF_F_LAYOUT);
+
+  if (elf_update (outelf, ELF_C_WRITE) == -1)
+    error (EXIT_FAILURE, 0, "elf_update failed: %s", elf_errmsg (-1));
+
+  elf_end (outelf);
+  close (outfd);
+
+  elf_end (inelf);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/elfgetchdr.c b/third_party/elfutils/tests/elfgetchdr.c
new file mode 100644
index 0000000..44ba178
--- /dev/null
+++ b/third_party/elfutils/tests/elfgetchdr.c
@@ -0,0 +1,124 @@
+/* Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <inttypes.h>
+
+#include ELFUTILS_HEADER(elf)
+#include ELFUTILS_HEADER(dwelf)
+#include <gelf.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+  int result = 0;
+  int cnt;
+
+  elf_version (EV_CURRENT);
+
+  for (cnt = 1; cnt < argc; ++cnt)
+    {
+      int fd = open (argv[cnt], O_RDONLY);
+
+      Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+      if (elf == NULL)
+	{
+	  printf ("%s not usable %s\n", argv[cnt], elf_errmsg (-1));
+	  result = 1;
+	  close (fd);
+	  continue;
+	}
+
+      size_t shdrstrndx;
+      if (elf_getshdrstrndx (elf, &shdrstrndx) == -1)
+	{
+	  printf ("elf_getshdrstrnd failed %s\n", elf_errmsg (-1));
+	  result = 1;
+	  close (fd);
+	  continue;
+	}
+
+      Elf_Scn *scn = NULL;
+      while ((scn = elf_nextscn (elf, scn)) != NULL)
+	{
+	  int idx = elf_ndxscn (scn);
+	  GElf_Shdr shdr;
+	  if (gelf_getshdr (scn, &shdr) == NULL)
+	    {
+	      printf ("gelf_getshdr failed: %s\n", elf_errmsg (-1));
+	      result = 1;
+	      break;
+	    }
+
+	  if ((shdr.sh_flags & SHF_COMPRESSED) != 0)
+	    {
+	      GElf_Chdr chdr;
+	      if (gelf_getchdr (scn, &chdr) == NULL)
+		{
+		  printf ("gelf_getchdr failed: %s\n", elf_errmsg (-1));
+		  result = 1;
+		  break;
+		}
+
+	      printf ("section %d: ELF Compressed ch_type: %" PRId32
+		      ", ch_size: %" PRIx64 ", ch_addralign: %" PRIx64 "\n",
+		      idx, chdr.ch_type, chdr.ch_size, chdr.ch_addralign);
+	    }
+	  else
+	    {
+	      const char *sname = elf_strptr (elf, shdrstrndx, shdr.sh_name);
+	      if (sname == NULL)
+		{
+		  printf ("couldn't get section name: %s\n", elf_errmsg (-1));
+		  result = 1;
+		  break;
+		}
+
+	      /* This duplicates what the dwelfgnucompressed testcase does.  */
+	      if (strncmp(".zdebug", sname, strlen (".zdebug")) == 0)
+		{
+		  ssize_t size;
+		  if ((size = dwelf_scn_gnu_compressed_size (scn)) == -1)
+		    {
+		      printf ("dwelf_scn_gnu_compressed_size failed: %s\n",
+			      elf_errmsg (-1));
+		      result = 1;
+		      break;
+		    }
+		  printf ("section %d: GNU Compressed size: %zx\n", idx, size);
+		}
+	      else
+		printf ("section %d: NOT Compressed\n", idx);
+	    }
+	}
+
+      elf_end (elf);
+      close (fd);
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/elfgetzdata.c b/third_party/elfutils/tests/elfgetzdata.c
new file mode 100644
index 0000000..82afbe5
--- /dev/null
+++ b/third_party/elfutils/tests/elfgetzdata.c
@@ -0,0 +1,113 @@
+/* Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include <gelf.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+int
+main (int argc, char *argv[])
+{
+  int result = 0;
+  int cnt;
+
+  if (argc < 3
+      || (strcmp (argv[1], "read") != 0
+          && strcmp (argv[1], "mmap") != 0))
+    {
+      printf ("Usage: (read|mmap) files...\n");
+      return -1;
+    }
+
+  bool mmap = strcmp (argv[1], "mmap") == 0;
+
+  elf_version (EV_CURRENT);
+
+  for (cnt = 2; cnt < argc; ++cnt)
+    {
+      int fd = open (argv[cnt], O_RDONLY);
+
+      Elf *elf = elf_begin (fd, mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL);
+      if (elf == NULL)
+	{
+	  printf ("%s not usable %s\n", argv[cnt], elf_errmsg (-1));
+	  result = 1;
+	  close (fd);
+	  continue;
+	}
+
+      /* To get the section names.  */
+      size_t strndx;
+      elf_getshdrstrndx (elf, &strndx);
+
+      Elf_Scn *scn = NULL;
+      while ((scn = elf_nextscn (elf, scn)) != NULL)
+	{
+	  size_t idx = elf_ndxscn (scn);
+	  GElf_Shdr mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &mem);
+	  const char *name = elf_strptr (elf, strndx, shdr->sh_name);
+	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
+	    {
+	      /* Real compressed section.  */
+	      if (elf_compress (scn, 0, 0) < 0)
+		{
+		  printf ("elf_compress failed for section %zd: %s\n",
+			  idx, elf_errmsg (-1));
+		  return -1;
+		}
+	      Elf_Data *d = elf_getdata (scn, NULL);
+	      printf ("%zd: %s, ELF compressed, size: %zx\n",
+		      idx, name, d->d_size);
+	    }
+	  else
+	    {
+	      /* Maybe an old GNU compressed .z section?  */
+	      if (name[0] == '.' && name[1] == 'z')
+		{
+		  if (elf_compress_gnu (scn, 0, 0) < 0)
+		    {
+		      printf ("elf_compress_gnu failed for section %zd: %s\n",
+			      idx, elf_errmsg (-1));
+		      return -1;
+		    }
+		  Elf_Data *d = elf_getdata (scn, NULL);
+		  printf ("%zd: %s, GNU compressed, size: %zx\n",
+			  idx, name, d->d_size);
+		}
+	      else
+		printf ("%zd: %s, NOT compressed\n", idx, name);
+	    }
+	}
+
+      elf_end (elf);
+      close (fd);
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/elfputzdata.c b/third_party/elfutils/tests/elfputzdata.c
new file mode 100644
index 0000000..66ab77b
--- /dev/null
+++ b/third_party/elfutils/tests/elfputzdata.c
@@ -0,0 +1,237 @@
+/* Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include <gelf.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+int
+main (int argc, char *argv[])
+{
+  int result = 0;
+  int cnt;
+
+  if (argc < 3
+      || (strcmp (argv[1], "elf") != 0
+	  && strcmp (argv[1], "gnu") != 0))
+    {
+      printf ("Usage: (elf|gnu) files...\n");
+      return -1;
+    }
+
+  int gnu;
+  if (strcmp (argv[1], "gnu") == 0)
+    gnu = 1;
+  else
+    gnu = 0;
+
+  elf_version (EV_CURRENT);
+
+  for (cnt = 2; cnt < argc; ++cnt)
+    {
+      int fd = open (argv[cnt], O_RDONLY);
+
+      Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+      if (elf == NULL)
+	{
+	  printf ("%s not usable %s\n", argv[cnt], elf_errmsg (-1));
+	  result = 1;
+	  close (fd);
+	  continue;
+	}
+
+      /* To get the section names.  */
+      size_t strndx;
+      elf_getshdrstrndx (elf, &strndx);
+
+      Elf_Scn *scn = NULL;
+      while ((scn = elf_nextscn (elf, scn)) != NULL)
+	{
+	  size_t idx = elf_ndxscn (scn);
+	  GElf_Shdr mem;
+	  GElf_Shdr *shdr = gelf_getshdr (scn, &mem);
+	  const char *name = elf_strptr (elf, strndx, shdr->sh_name);
+	  if (shdr->sh_type == SHT_NOBITS
+	      || (shdr->sh_flags & SHF_ALLOC) != 0)
+	    {
+	      printf ("Cannot compress %zd %s\n", idx, name);
+	    }
+	  else if ((shdr->sh_flags & SHF_COMPRESSED) != 0
+		   || strncmp (name, ".zdebug", strlen (".zdebug")) == 0)
+	    {
+	      printf ("Already compressed %zd %s\n", idx, name);
+	    }
+	  else
+	    {
+	      size_t orig_size = shdr->sh_size;
+	      printf ("Lets compress %zd %s, size: %" PRId64 "\n",
+		      idx, name, shdr->sh_size);
+	      Elf_Data *d = elf_getdata (scn, NULL);
+	      if (d == NULL)
+		{
+		  printf ("Couldn't get orig data for section %zd\n", idx);
+		  return -1;
+		}
+	      /* Make a copy so we can compare after
+		 compression/decompression.  */
+	      if (d->d_size != orig_size)
+		{
+		  printf ("Unexpected data size for orig section %zd\n", idx);
+		  return -1;
+		}
+	      char *orig_buf = malloc (d->d_size);
+	      if (orig_size > 0 && orig_buf == NULL)
+		{
+		  printf ("No memory to copy section %zd data\n", idx);
+		  return -1;
+		}
+	      if (orig_size > 0)
+		memcpy (orig_buf, d->d_buf, orig_size);
+
+	      bool forced = false;
+	      if (gnu)
+		{
+		  int res = elf_compress_gnu (scn, 1, 0);
+		  if (res == 0)
+		    {
+		      forced = true;
+		      res = elf_compress_gnu (scn, 1, ELF_CHF_FORCE);
+		    }
+		  if (res < 0)
+		    {
+		      printf ("elf_compress_gnu%sfailed for section %zd: %s\n",
+			      forced ? " (forced) " : " ",
+			      idx, elf_errmsg (-1));
+		      return -1;
+		    }
+		}
+	      else
+		{
+		  int res = elf_compress (scn, ELFCOMPRESS_ZLIB, 0);
+		  if (res == 0)
+		    {
+		      forced = true;
+		      res = elf_compress (scn, ELFCOMPRESS_ZLIB, ELF_CHF_FORCE);
+		    }
+		  if (res < 0)
+		    {
+		      printf ("elf_compress%sfailed for section %zd: %s\n",
+			      forced ? " (forced) " : " ",
+			      idx, elf_errmsg (-1));
+		      return -1;
+		    }
+		}
+	      GElf_Shdr newmem;
+	      GElf_Shdr *newshdr = gelf_getshdr (scn, &newmem);
+	      size_t new_size = newshdr->sh_size;
+	      d = elf_getdata (scn, NULL);
+	      // Don't check this, might depend on zlib implementation.
+	      // fprintf (stderr, "  new_size: %zd\n", new_size);
+	      if (d->d_size != new_size)
+		{
+		  printf ("Unexpected data size for compressed section %zd\n",
+			  idx);
+		  return -1;
+		}
+
+	      if (forced && new_size < orig_size)
+		{
+		  printf ("section %zd forced to compress, but size smaller\n",
+			  idx);
+		  return -1;
+		}
+
+	      if (! forced && new_size >= orig_size)
+		{
+		  printf ("section %zd compressed to bigger size\n",
+			  idx);
+		  return -1;
+		}
+
+	      if (new_size == orig_size
+		  && memcmp (orig_buf, d->d_buf, orig_size) == 0)
+		{
+		  printf ("section %zd didn't compress\n", idx);
+		  return -1;
+		}
+
+	      if (gnu)
+		{
+		  if (elf_compress_gnu (scn, 0, 0) < 0)
+		    {
+		      printf ("elf_[un]compress_gnu failed for section %zd: %s\n",
+			      idx, elf_errmsg (-1));
+		      return -1;
+		    }
+		}
+	      else
+		{
+		  if (elf_compress (scn, 0, 0) < 0)
+		    {
+		      printf ("elf_[un]compress failed for section %zd: %s\n",
+			      idx, elf_errmsg (-1));
+		      return -1;
+		    }
+		}
+	      GElf_Shdr newermem;
+	      GElf_Shdr *newershdr = gelf_getshdr (scn, &newermem);
+	      size_t newer_size = newershdr->sh_size;
+	      d = elf_getdata (scn, NULL);
+	      // fprintf (stderr, "  newer_size: %zd\n", newer_size);
+	      if (d->d_size != newer_size)
+		{
+		  printf ("Unexpected data size for compressed section %zd\n",
+			  idx);
+		  return -1;
+		}
+	      if (newer_size != orig_size
+		  && memcmp (orig_buf, d->d_buf, orig_size) != 0)
+		{
+		  printf ("section %zd didn't correctly uncompress\n", idx);
+		  return -1;
+		}
+	      free (orig_buf);
+	      // Recompress the string table, just to make sure
+	      // everything keeps working. See elf_strptr above.
+	      if (! gnu && idx == strndx
+		  && elf_compress (scn, ELFCOMPRESS_ZLIB, 0) < 0)
+		{
+		  printf ("couldn't recompress section header strings: %s\n",
+			  elf_errmsg (-1));
+		  return -1;
+		}
+	    }
+	}
+
+      elf_end (elf);
+      close (fd);
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/elfshphehdr.c b/third_party/elfutils/tests/elfshphehdr.c
new file mode 100644
index 0000000..8183937
--- /dev/null
+++ b/third_party/elfutils/tests/elfshphehdr.c
@@ -0,0 +1,182 @@
+/* Test program for adding section and program headers and ehdr updates.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include ELFUTILS_HEADER(elf)
+#include <gelf.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <stdbool.h>
+
+void
+check (const char *msg, bool statement)
+{
+  if (! statement)
+    {
+      fprintf (stderr, "%s FAILED\n", msg);
+      exit (-1);
+    }
+  else
+    fprintf (stderr, "%s OK\n", msg);
+}
+
+void
+check_elf (const char *msg, bool statement)
+{
+  if (! statement)
+    {
+      fprintf (stderr, "%s: %s\n", msg, elf_errmsg (-1));
+      exit (-1);
+    }
+  else
+    fprintf (stderr, "%s OK\n", msg);
+}
+
+void
+test (Elf *elf, int class, bool layout)
+{
+  fprintf (stderr, "testing ELF class: %d, layout: %d\n", class, layout);
+
+  check_elf ("gelf_newehdr", gelf_newehdr (elf, class) != 0);
+  check_elf ("gelf_getclass", gelf_getclass (elf) == class);
+
+  check_elf ("elf_flagelf", elf_flagelf (elf, layout ? ELF_C_SET : ELF_C_CLR,
+					 ELF_F_LAYOUT) != 0);
+
+  GElf_Ehdr ehdr;
+  check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL);
+  check ("e_shnum == 0", ehdr.e_shnum == 0);
+  check ("e_phnum == 0", ehdr.e_phnum == 0);
+  check ("e_shoff == 0", ehdr.e_shoff == 0);
+  check ("e_phoff == 0", ehdr.e_phoff == 0);
+
+  size_t shnum;
+  check_elf ("elf_getshdrnum", elf_getshdrnum (elf, &shnum) == 0);
+  check ("shnum == 0", shnum == 0);
+
+  size_t phnum;
+  check_elf ("elf_getphdrnum", elf_getphdrnum (elf, &phnum) == 0);
+  check ("phnum == 0", phnum == 0);
+
+  /* Lets fill in some info we are always responsible for.  */
+  ehdr.e_ident[EI_DATA] = ELFDATANONE; /* Ask for native encoding.  */
+  ehdr.e_type = ET_EXEC;
+  ehdr.e_machine = EM_386;
+  ehdr.e_version = EV_NONE; /* Ask for current version. */
+  check_elf ("gelf_update_ehdr", gelf_update_ehdr (elf, &ehdr) != 0);
+
+  check_elf ("elf_update", elf_update (elf, ELF_C_NULL) > 0);
+
+  check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL);
+  check ("EI_DATA", ehdr.e_ident[EI_DATA] != ELFDATANONE);
+  check ("e_version", ehdr.e_version == EV_CURRENT);
+
+  /* The sh/ph values shouldn't have changed.  */
+  check ("e_shnum == 0", ehdr.e_shnum == 0);
+  check ("e_phnum == 0", ehdr.e_phnum == 0);
+  check ("e_shoff == 0", ehdr.e_shoff == 0);
+  check ("e_phoff == 0", ehdr.e_phoff == 0);
+
+  check_elf ("elf_getshdrnum", elf_getshdrnum (elf, &shnum) == 0);
+  check ("shnum == 0", shnum == 0);
+
+  check_elf ("elf_getphdrnum", elf_getphdrnum (elf, &phnum) == 0);
+  check ("phnum == 0", phnum == 0);
+
+  /* Lets add a header.  */
+  check_elf ("elf_newscn", elf_newscn (elf) != NULL);
+  check_elf ("gelf_newphdr", gelf_newphdr (elf, 1) != 0);
+
+  /* If we are responsible for the layout ourselves we should also
+     tell where to put them.  */
+  if (layout)
+    {
+      check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL);
+      /* phdrs go right after the ehdr.  */
+      ehdr.e_phoff = ehdr.e_ehsize;
+      /* shdrs go right after the phdrs.  */
+      ehdr.e_shoff = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize;
+      check_elf ("gelf_update_ehdr", gelf_update_ehdr (elf, &ehdr) != 0);
+    }
+
+  check_elf ("elf_update", elf_update (elf, ELF_C_NULL) > 0);
+
+  check_elf ("elf_getshdrnum", elf_getshdrnum (elf, &shnum) == 0);
+  check ("shnum == 1", shnum == 2); /* section zero is also created.  */
+
+  check_elf ("elf_getphdrnum", elf_getphdrnum (elf, &phnum) == 0);
+  check ("phnum == 1", phnum == 1);
+
+  check_elf ("gelf_getehdr", gelf_getehdr (elf, &ehdr) != NULL);
+
+  check ("EI_DATA", ehdr.e_ident[EI_DATA] != ELFDATANONE);
+  check ("e_version", ehdr.e_version == EV_CURRENT);
+
+  check ("e_shnum == 2", ehdr.e_shnum == 2);
+  check ("e_phnum == 1", ehdr.e_phnum == 1);
+  check ("e_shoff != 0", ehdr.e_shoff != 0);
+  check ("e_phoff != 0", ehdr.e_phoff != 0);
+
+  size_t shentsize = (class == ELFCLASS32
+		      ? sizeof (Elf32_Shdr) : sizeof (Elf64_Shdr));
+  check ("e_shentsize", ehdr.e_shentsize == shentsize);
+  size_t phentsize = (class == ELFCLASS32
+		      ? sizeof (Elf32_Phdr) : sizeof (Elf64_Phdr));
+  check ("e_phentsize", ehdr.e_phentsize == phentsize);
+}
+
+int
+main (int argc __attribute__ ((unused)), char **argv __attribute ((unused)))
+{
+  elf_version (EV_CURRENT);
+
+  int fd = open("/dev/null", O_WRONLY);
+  check ("open", fd >= 0);
+
+  Elf *elf;
+
+  elf = elf_begin (fd, ELF_C_WRITE, NULL);
+  check_elf ("elf_begin", elf != NULL);
+  test (elf, ELFCLASS32, false);
+  elf_end (elf);
+
+  elf = elf_begin (fd, ELF_C_WRITE, NULL);
+  check_elf ("elf_begin", elf != NULL);
+  test (elf, ELFCLASS32, true);
+  elf_end (elf);
+
+  elf = elf_begin (fd, ELF_C_WRITE, NULL);
+  check_elf ("elf_begin", elf != NULL);
+  test (elf, ELFCLASS64, false);
+  elf_end (elf);
+
+  elf = elf_begin (fd, ELF_C_WRITE, NULL);
+  check_elf ("elf_begin", elf != NULL);
+  test (elf, ELFCLASS64, true);
+  elf_end (elf);
+
+  close (fd);
+  return 0;
+}
diff --git a/third_party/elfutils/tests/elfstrmerge.c b/third_party/elfutils/tests/elfstrmerge.c
new file mode 100644
index 0000000..3bb90c4
--- /dev/null
+++ b/third_party/elfutils/tests/elfstrmerge.c
@@ -0,0 +1,675 @@
+/* Merge string sections.
+   Copyright (C) 2015, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <error.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+#include <system.h>
+#include <gelf.h>
+#include ELFUTILS_HEADER(dwelf)
+#include "elf-knowledge.h"
+
+/* The original ELF file.  */
+static int fd = -1;
+static Elf *elf = NULL;
+static bool replace;
+
+/* The new ELF file.  */
+static char *fnew = NULL;
+static int fdnew = -1;
+static Elf *elfnew = NULL;
+
+/* The merged string table.  */
+static Dwelf_Strtab *strings = NULL;
+
+/* Section name strents.  */
+static Dwelf_Strent **scnstrents = NULL;
+
+/* Symbol name strends.  */
+static Dwelf_Strent **symstrents = NULL;
+
+/* New ELF file buffers.  */
+static Elf_Data newstrtabdata = { .d_buf = NULL };
+static size_t newshnums = 0;
+static void **newscnbufs = NULL;
+
+/* Release all files and resources allocated.  */
+static void
+release (void)
+{
+  /* The new string table.  */
+  if (strings != NULL)
+    dwelf_strtab_free (strings);
+
+  free (scnstrents);
+  free (symstrents);
+  free (newstrtabdata.d_buf);
+
+  /* Any new data buffers allocated.  */
+  for (size_t i = 0; i < newshnums; i++)
+    free (newscnbufs[i]);
+  free (newscnbufs);
+
+  /* The new ELF file.  */
+  if (fdnew != -1)
+    {
+      unlink (fnew);
+      elf_end (elfnew);
+      close (fdnew);
+    }
+  // Don't release, we might need it in the error message.
+  // if (replace)
+  //   free (fnew);
+
+  /* The original ELF file.  */
+  elf_end (elf);
+  close (fd);
+}
+
+/* The various ways we can fail... Cleanup and show some message to
+   the user.  The file name may be NULL.  */
+static void __attribute__ ((noreturn))
+fail (const char *msg, const char *fname)
+{
+  release ();
+  if (fname != NULL)
+    error (1, 0, "%s: %s", fname, msg);
+  else
+    error (1, 0, "%s", msg);
+  abort();
+}
+
+static void __attribute__ ((noreturn))
+fail_errno (const char *msg, const char *fname)
+{
+  release ();
+  if (fname != NULL)
+    error (1, errno, "%s: %s", fname, msg);
+  else
+    error (1, errno, "%s", msg);
+  abort();
+}
+
+static void __attribute__ ((noreturn))
+fail_idx (const char *msg, const char *fname, size_t idx)
+{
+  release ();
+  if (fname != NULL)
+    error (1, 0, "%s: %s %zd", fname, msg, idx);
+  else
+    error (1, 0, "%s %zd", msg, idx);
+  abort();
+}
+
+static void __attribute__ ((noreturn))
+fail_elf (const char *msg, const char *fname)
+{
+  release ();
+  if (fname != NULL)
+    error (1, 0, "%s: %s: %s", fname, msg, elf_errmsg (-1));
+  else
+    error (1, 0, "%s: %s", msg, elf_errmsg (-1));
+  abort();
+}
+
+static void __attribute__ ((noreturn))
+fail_elf_idx (const char *msg, const char *fname, size_t idx)
+{
+  release ();
+  if (fname != NULL)
+    error (1, 0, "%s: %s %zd: %s", fname, msg, idx, elf_errmsg (-1));
+  else
+    error (1, 0, "%s %zd: %s", msg, idx, elf_errmsg (-1));
+  abort();
+}
+
+int
+main (int argc, char **argv)
+{
+  elf_version (EV_CURRENT);
+
+  /* Basic command line handling.  Need to replace the input file?  */
+  if ((argc != 2 && argc != 4)
+      || (argc == 4 && strcmp (argv[1], "-o") != 0))
+    fail ("Usage argument: [-o <outputfile>] <inputfile>", NULL);
+  replace = argc == 2;
+
+  /* Get the ELF file.  */
+  const char *fname;
+  if (replace)
+    fname = argv[1];
+  else
+    fname = argv[3];
+  fd = open (fname, O_RDONLY);
+  if (fd < 0)
+    fail_errno ("couldn't open", fname);
+
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    fail_elf ("couldn't open ELF file for reading", fname);
+
+  GElf_Ehdr ehdr;
+  if (gelf_getehdr (elf, &ehdr) == NULL)
+    fail_elf ("Couldn't get ehdr", fname);
+
+  /* Get the section header string table.  */
+  size_t shdrstrndx;
+  if (elf_getshdrstrndx (elf, &shdrstrndx) != 0)
+    fail_elf ("couldn't get section header string table index", fname);
+
+  Elf_Scn *shdrstrscn = elf_getscn (elf, shdrstrndx);
+  GElf_Shdr shdrstrshdr_mem;
+  GElf_Shdr *shdrstrshdr = gelf_getshdr (shdrstrscn, &shdrstrshdr_mem);
+  if (shdrstrshdr == NULL)
+    fail_elf ("couldn't get section header string table section", fname);
+
+  if ((shdrstrshdr->sh_flags & SHF_ALLOC) != 0)
+    fail ("section header string table is an allocated section", fname);
+
+  /* Get the symtab section.  */
+  size_t symtabndx = 0;
+  Elf_Scn *symtabscn = NULL;
+  GElf_Shdr symtabshdr_mem;
+  GElf_Shdr *symtabshdr = NULL;
+  while ((symtabscn = elf_nextscn (elf, symtabscn)) != NULL)
+    {
+      symtabshdr = gelf_getshdr (symtabscn, &symtabshdr_mem);
+      if (symtabshdr == NULL)
+	fail_elf ("couldn't get shdr", fname);
+
+      if (symtabshdr->sh_type == SHT_SYMTAB)
+	{
+	  /* Just pick the first, we don't expect more than one. */
+	  symtabndx = elf_ndxscn (symtabscn);
+	  break;
+	}
+    }
+
+  if (symtabshdr == NULL)
+    fail ("No symtab found", fname);
+
+  if ((symtabshdr->sh_flags & SHF_ALLOC) != 0)
+    fail ("symtab is an allocated section", fname);
+
+  /* Get the strtab of the symtab.  */
+  size_t strtabndx = symtabshdr->sh_link;
+  Elf_Scn *strtabscn = elf_getscn (elf, strtabndx);
+  GElf_Shdr strtabshdr_mem;
+  GElf_Shdr *strtabshdr = gelf_getshdr (strtabscn, &strtabshdr_mem);
+  if (strtabshdr == NULL)
+    fail_elf ("Couldn't get strtab section", fname);
+
+  if (shdrstrndx == strtabndx)
+    {
+      error (0, 0, "%s: Nothing to do, shstrtab == strtab", fname);
+      release ();
+      return 0;
+    }
+
+  if ((strtabshdr->sh_flags & SHF_ALLOC) != 0)
+    fail ("strtab is an allocated section", fname);
+
+  size_t phnum;
+  if (elf_getphdrnum (elf, &phnum) != 0)
+    fail_elf ("Couldn't get number of phdrs", fname);
+
+  /* If there are phdrs we want to maintain the layout of the
+     allocated sections in the file.  */
+  bool layout = phnum != 0;
+
+  /* Create a new merged strings table that starts with the empty string.  */
+  strings = dwelf_strtab_init (true);
+  if (strings == NULL)
+    fail ("No memory to create merged string table", NULL);
+
+  /* Add the strings from all the sections.  */
+  size_t shdrnum;
+  if (elf_getshdrnum (elf, &shdrnum) != 0)
+    fail_elf ("Couldn't get number of sections", fname);
+  scnstrents = malloc (shdrnum * sizeof (Dwelf_Strent *));
+  if (scnstrents == NULL)
+    fail ("couldn't allocate memory for section strings", NULL);
+
+  /* While going through all sections keep track of last allocated
+     offset if needed to keep the layout.  We'll put any unallocated
+     sections behind those (strtab is unallocated and will change
+     size).  */
+  GElf_Off last_offset = 0;
+  if (layout)
+    last_offset = (ehdr.e_phoff
+		   + gelf_fsize (elf, ELF_T_PHDR, phnum, EV_CURRENT));
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      size_t scnnum = elf_ndxscn (scn);
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	fail_elf_idx ("couldn't get shdr", fname, scnnum);
+      /* Don't add the .shstrtab section itself, we'll not use it.  */
+      if (shdr->sh_name != 0 && scnnum != shdrstrndx)
+	{
+	  const char *sname = elf_strptr (elf, shdrstrndx, shdr->sh_name);
+	  if (sname == NULL)
+	    fail_elf_idx ("couldn't get section name", fname, scnnum);
+	  if ((scnstrents[scnnum] = dwelf_strtab_add (strings, sname)) == NULL)
+	    fail ("No memory to add to merged string table", NULL);
+	}
+
+      if (layout)
+	if ((shdr->sh_flags & SHF_ALLOC) != 0)
+	  {
+	    GElf_Off off = shdr->sh_offset + (shdr->sh_type != SHT_NOBITS
+					      ? shdr->sh_size : 0);
+	    if (last_offset < off)
+	      last_offset = off;
+	  }
+    }
+
+  /* Add the strings from all the symbols.  */
+  size_t elsize = gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT);
+  Elf_Data *symd = elf_getdata (symtabscn, NULL);
+  if (symd == NULL)
+    fail_elf ("couldn't get symtab data", fname);
+  size_t symsnum = symd->d_size / elsize;
+  symstrents = malloc (symsnum * sizeof (Dwelf_Strent *));
+  if (symstrents == NULL)
+    fail_errno ("Couldn't allocate memory for symbol strings", NULL);
+  for (size_t i = 0; i < symsnum; i++)
+    {
+      GElf_Sym sym_mem;
+      GElf_Sym *sym = gelf_getsym (symd, i, &sym_mem);
+      if (sym == NULL)
+	fail_elf_idx ("Couldn't get symbol", fname, i);
+      if (sym->st_name != 0)
+	{
+	  const char *sname = elf_strptr (elf, strtabndx, sym->st_name);
+	  if (sname == NULL)
+	    fail_elf_idx ("Couldn't get symbol name", fname, i);
+	  if ((symstrents[i] = dwelf_strtab_add (strings, sname)) == NULL)
+	    fail_idx ("No memory to add to merged string table symbol",
+		      fname, i);
+	}
+    }
+
+  /* We got all strings, build the new string table and store it as
+     new strtab.  */
+  dwelf_strtab_finalize (strings, &newstrtabdata);
+
+  /* We share at least the empty string so the result is at least 1
+     byte smaller.  */
+  if (newstrtabdata.d_size >= shdrstrshdr->sh_size + strtabshdr->sh_size)
+    fail ("Impossible, merged string table is larger", fname);
+
+  /* section index mapping and sanity checking.  */
+  size_t newsecndx (size_t secndx, const char *what, size_t widx,
+		    const char *member, size_t midx)
+  {
+    if (unlikely (secndx == 0 || secndx == shdrstrndx || secndx >= shdrnum))
+      {
+	/* Don't use fail... too specialized messages.  Call release
+	   outselves and then error.  Ignores midx if widx is
+	   zero.  */
+	release ();
+	if (widx == 0)
+	  error (1, 0, "%s: bad section index %zd in %s for %s",
+		 fname, secndx, what, member);
+	else if (midx == 0)
+	  error (1, 0, "%s: bad section index %zd in %s %zd for %s",
+		 fname, secndx, what, widx, member);
+	else
+	  error (1, 0, "%s: bad section index %zd in %s %zd for %s %zd",
+		 fname, secndx, what, widx, member, midx);
+      }
+
+    return secndx < shdrstrndx ? secndx : secndx - 1;
+  }
+
+  struct stat st;
+  if (fstat (fd, &st) != 0)
+    fail_errno("Couldn't fstat", fname);
+
+  /* Create a new (temporary) ELF file for the result.  */
+  if (replace)
+    {
+      size_t fname_len = strlen (fname);
+      fnew = malloc (fname_len + sizeof (".XXXXXX"));
+      if (fnew == NULL)
+	fail_errno ("couldn't allocate memory for new file name", NULL);
+      strcpy (mempcpy (fnew, fname, fname_len), ".XXXXXX");
+
+      fdnew = mkstemp (fnew);
+    }
+  else
+    {
+      fnew = argv[2];
+      fdnew = open (fnew, O_WRONLY | O_CREAT, st.st_mode & ALLPERMS);
+    }
+
+  if (fdnew < 0)
+    fail_errno ("couldn't create output file", fnew);
+
+  elfnew = elf_begin (fdnew, ELF_C_WRITE, NULL);
+  if (elfnew == NULL)
+    fail_elf ("couldn't open new ELF for writing", fnew);
+
+  /* Create the new ELF header and copy over all the data.  */
+  if (gelf_newehdr (elfnew, gelf_getclass (elf)) == 0)
+    fail_elf ("Couldn't create new ehdr", fnew);
+  GElf_Ehdr newehdr;
+  if (gelf_getehdr (elfnew, &newehdr) == NULL)
+    fail_elf ("Couldn't get ehdr", fnew);
+
+  newehdr.e_ident[EI_DATA] = ehdr.e_ident[EI_DATA];
+  newehdr.e_type = ehdr.e_type;
+  newehdr.e_machine = ehdr.e_machine;
+  newehdr.e_version = ehdr.e_version;
+  newehdr.e_entry = ehdr.e_entry;
+  newehdr.e_flags = ehdr.e_flags;
+
+  /* The new file uses the new strtab as shstrtab.  */
+  size_t newstrtabndx = newsecndx (strtabndx, "ehdr", 0, "e_shstrndx", 0);
+  if (newstrtabndx < SHN_LORESERVE)
+    newehdr.e_shstrndx = newstrtabndx;
+  else
+    {
+      Elf_Scn *zscn = elf_getscn (elfnew, 0);
+      GElf_Shdr zshdr_mem;
+      GElf_Shdr *zshdr = gelf_getshdr (zscn, &zshdr_mem);
+      if (zshdr == NULL)
+	fail_elf ("Couldn't get section zero", fnew);
+      zshdr->sh_link = strtabndx;
+      if (gelf_update_shdr (zscn, zshdr) == 0)
+	fail_elf ("Couldn't update section zero", fnew);
+      newehdr.e_shstrndx = SHN_XINDEX;
+    }
+
+  if (gelf_update_ehdr (elfnew, &newehdr) == 0)
+    fail ("Couldn't update ehdr", fnew);
+
+  /* Copy the program headers if any.  */
+  if (phnum != 0)
+    {
+      if (gelf_newphdr (elfnew, phnum) == 0)
+	fail_elf ("Couldn't create phdrs", fnew);
+
+      for (size_t cnt = 0; cnt < phnum; ++cnt)
+	{
+	  GElf_Phdr phdr_mem;
+	  GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &phdr_mem);
+	  if (phdr == NULL)
+	    fail_elf_idx ("Couldn't get phdr", fname, cnt);
+	  if (gelf_update_phdr (elfnew, cnt, phdr) == 0)
+	    fail_elf_idx ("Couldn't create phdr", fnew, cnt);
+	}
+    }
+
+  newshnums = shdrnum - 1;
+  newscnbufs = calloc (sizeof (void *), newshnums);
+  if (newscnbufs == NULL)
+    fail_errno ("Couldn't allocate memory for new section buffers", NULL);
+
+  /* Copy the sections, except the shstrtab, fill the strtab with the
+     combined strings and adjust section references.  */
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      size_t ndx = elf_ndxscn (scn);
+
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	fail_elf_idx ("Couldn't get shdr", fname, ndx);
+
+      /* Section zero is always created.  Skip the shtrtab.  */
+      if (ndx == 0 || ndx == shdrstrndx)
+	continue;
+
+      Elf_Scn *newscn = elf_newscn (elfnew);
+      if (newscn == NULL)
+	fail_elf_idx ("couldn't create new section", fnew, ndx);
+
+      GElf_Shdr newshdr;
+      newshdr.sh_name = (shdr->sh_name != 0
+			 ? dwelf_strent_off (scnstrents[ndx]) : 0);
+      newshdr.sh_type = shdr->sh_type;
+      newshdr.sh_flags = shdr->sh_flags;
+      newshdr.sh_addr = shdr->sh_addr;
+      newshdr.sh_size = shdr->sh_size;
+      if (shdr->sh_link != 0)
+	newshdr.sh_link = newsecndx (shdr->sh_link, "shdr", ndx, "sh_link", 0);
+      else
+	newshdr.sh_link = 0;
+      if (SH_INFO_LINK_P (shdr) && shdr->sh_info != 0)
+	newshdr.sh_info = newsecndx (shdr->sh_info, "shdr", ndx, "sh_info", 0);
+      else
+	newshdr.sh_info = shdr->sh_info;
+      newshdr.sh_entsize = shdr->sh_entsize;
+
+      /* Some sections need a new data buffer because they need to
+	 manipulate the original data.  Allocate and check here, so we
+	 have a list of all data buffers we might need to release when
+	 done.  */
+      void new_data_buf (Elf_Data *d)
+      {
+	size_t s = d->d_size;
+	if (s == 0)
+	  fail_idx ("Expected data in section", fname, ndx);
+	void *b = malloc (d->d_size);
+	if (b == NULL)
+	  fail_idx ("Couldn't allocated buffer for section", NULL, ndx);
+	newscnbufs[newsecndx (ndx, "section", ndx, "d_buf", 0)] = d->d_buf = b;
+      }
+
+      Elf_Data *newdata = elf_newdata (newscn);
+      if (newdata == NULL)
+	fail_elf_idx ("Couldn't create new data for section", fnew, ndx);
+      if (ndx == strtabndx)
+	*newdata = newstrtabdata;
+      else
+	{
+	  /* The symtab, dynsym, group and symtab_shndx sections
+	     contain section indexes. Symbol tables (symtab and
+	     dynsym) contain indexes to strings. Update both if
+	     necessary.  */
+	  Elf_Data *data = elf_getdata (scn, NULL);
+	  if (data == NULL)
+	    fail_elf_idx ("Couldn't get data from section", fname, ndx);
+	  *newdata = *data;
+	  switch (shdr->sh_type)
+	    {
+	    case SHT_SYMTAB:
+	    case SHT_DYNSYM:
+	      {
+		/* We need to update the section numbers of the
+		   symbols and if this symbol table uses the strtab
+		   section also the name indexes.  */
+		const bool update_name = shdr->sh_link == strtabndx;
+		if (update_name && ndx != symtabndx)
+		  fail ("Only one symbol table using strtab expected", fname);
+		new_data_buf (newdata);
+		size_t syms = (data->d_size
+			       / gelf_fsize (elf, ELF_T_SYM, 1, EV_CURRENT));
+		for (size_t i = 0; i < syms; i++)
+		  {
+		    GElf_Sym sym;
+		    if (gelf_getsym (data, i, &sym) == NULL)
+		      fail_elf_idx ("Couldn't get symbol", fname, i);
+
+		    if (GELF_ST_TYPE (sym.st_info) == STT_SECTION
+			&& sym.st_shndx == shdrstrndx)
+		      fprintf (stderr, "WARNING:"
+			       " symbol table [%zd] contains section symbol %zd"
+			       " for old shdrstrndx %zd\n", ndx, i, shdrstrndx);
+		    else if (sym.st_shndx != SHN_UNDEF
+			     && sym.st_shndx < SHN_LORESERVE)
+		      sym.st_shndx = newsecndx (sym.st_shndx, "section", ndx,
+						"symbol", i);
+		    if (update_name && sym.st_name != 0)
+		      sym.st_name = dwelf_strent_off (symstrents[i]);
+
+		    /* We explicitly don't update the SHNDX table at
+		       the same time, we do that below.  */
+		    if (gelf_update_sym (newdata, i, &sym) == 0)
+		      fail_elf_idx ("Couldn't update symbol", fnew, i);
+		  }
+	      }
+	      break;
+
+	    case SHT_GROUP:
+	      {
+		new_data_buf (newdata);
+		/* A section group contains Elf32_Words. The first
+		   word is a falg value, the rest of the words are
+		   indexes of the sections belonging to the group.  */
+		Elf32_Word *group = (Elf32_Word *) data->d_buf;
+		Elf32_Word *newgroup = (Elf32_Word *) newdata->d_buf;
+		size_t words = data->d_size / sizeof (Elf32_Word);
+		if (words == 0)
+		  fail_idx ("Not enough data in group section", fname, ndx);
+		newgroup[0] = group[0];
+		for (size_t i = 1; i < words; i++)
+		  newgroup[i] = newsecndx (group[i], "section", ndx,
+					   "group", i);
+	      }
+	      break;
+
+	    case SHT_SYMTAB_SHNDX:
+	      {
+		new_data_buf (newdata);
+		/* A SHNDX just contains an array of section indexes
+		   for the corresponding symbol table.  The entry is
+		   SHN_UNDEF unless the corresponding symbol is
+		   SHN_XINDEX.  */
+		Elf32_Word *shndx = (Elf32_Word *) data->d_buf;
+		Elf32_Word *newshndx = (Elf32_Word *) newdata->d_buf;
+		size_t words = data->d_size / sizeof (Elf32_Word);
+		for (size_t i = 0; i < words; i++)
+		  if (shndx[i] == SHN_UNDEF)
+		    newshndx[i] = SHN_UNDEF;
+		  else
+		    newshndx[i] = newsecndx (shndx[i], "section", ndx,
+					     "shndx", i);
+	      }
+	      break;
+
+	    case SHT_DYNAMIC:
+	      FALLTHROUGH;
+	      /* There are string indexes in here, but
+		 they (should) point to a allocated string table,
+		 which we don't alter.  */
+	    default:
+	      /* Nothing to do.  Section data doesn't contain section
+		 or strtab indexes.  */
+	      break;
+	    }
+	}
+
+      /* When we are responsible for the layout explicitly set
+	 sh_addralign, sh_size and sh_offset.  Otherwise libelf will
+	 calculate those from the Elf_Data.  */
+      if (layout)
+	{
+	  /* We have just one Elf_Data.  */
+	  newshdr.sh_size = newdata->d_size;
+	  newshdr.sh_addralign = newdata->d_align;
+
+	  /* Keep the offset of allocated sections so they are at the
+	     same place in the file. Add unallocated ones after the
+	     allocated ones.  */
+	  if ((shdr->sh_flags & SHF_ALLOC) != 0)
+	    newshdr.sh_offset = shdr->sh_offset;
+	  else
+	    {
+	      /* Zero means one.  No alignment constraints.  */
+	      size_t addralign = newshdr.sh_addralign ?: 1;
+	      last_offset = (last_offset + addralign - 1) & ~(addralign - 1);
+	      newshdr.sh_offset = last_offset;
+	      if (newshdr.sh_type != SHT_NOBITS)
+		last_offset += newshdr.sh_size;
+	    }
+	}
+      else
+	{
+	  newshdr.sh_addralign = 0;
+	  newshdr.sh_size = 0;
+	  newshdr.sh_offset = 0;
+	}
+
+      if (gelf_update_shdr (newscn, &newshdr) == 0)
+	fail_elf_idx ("Couldn't update section header", fnew, ndx);
+    }
+
+  /* If we have phdrs we want elf_update to layout the SHF_ALLOC
+     sections precisely as in the original file.  In that case we are
+     also responsible for setting phoff and shoff */
+  if (layout)
+    {
+      /* Position the shdrs after the last (unallocated) section.  */
+      if (gelf_getehdr (elfnew, &newehdr) == NULL)
+	fail_elf ("Couldn't get ehdr", fnew);
+      const size_t offsize = gelf_fsize (elf, ELF_T_OFF, 1, EV_CURRENT);
+      newehdr.e_shoff = ((last_offset + offsize - 1)
+			 & ~((GElf_Off) (offsize - 1)));
+
+      /* The phdrs go in the same place as in the original file.
+	 Normally right after the ELF header.  */
+      newehdr.e_phoff = ehdr.e_phoff;
+
+      if (gelf_update_ehdr (elfnew, &newehdr) == 0)
+	fail_elf ("Couldn't update ehdr", fnew);
+
+      elf_flagelf (elfnew, ELF_C_SET, ELF_F_LAYOUT);
+    }
+
+  if (elf_update (elfnew, ELF_C_WRITE) == -1)
+    fail_elf ("Couldn't write ELF", fnew);
+
+  elf_end (elfnew);
+  elfnew = NULL;
+
+  /* Try to match mode and owner.group of the original file.  */
+  if (fchmod (fdnew, st.st_mode & ALLPERMS) != 0)
+    error (0, errno, "Couldn't fchmod %s", fnew);
+  if (fchown (fdnew, st.st_uid, st.st_gid) != 0)
+    error (0, errno, "Couldn't fchown %s", fnew);
+
+  /* Finally replace the old file with the new merged strings file.  */
+  if (replace)
+    if (rename (fnew, fname) != 0)
+      fail_errno ("rename", fnew);
+
+  /* We are finally done with the new file, don't unlink it now.  */
+  close (fdnew);
+  if (replace)
+    free (fnew);
+  fnew = NULL;
+  fdnew = -1;
+
+  release ();
+  return 0;
+}
diff --git a/third_party/elfutils/tests/elfstrtab.c b/third_party/elfutils/tests/elfstrtab.c
new file mode 100644
index 0000000..c27d6cf
--- /dev/null
+++ b/third_party/elfutils/tests/elfstrtab.c
@@ -0,0 +1,396 @@
+/* Test program for elf_strptr function.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include ELFUTILS_HEADER(elf)
+#include <gelf.h>
+
+
+/* Index of last string added.  Returned by add_string ().  */
+static size_t stridx = 0;
+
+/* Some random strings.  */
+static char *str1;
+static size_t str1_off;
+static char *str2;
+static size_t str2_off;
+static char *str3;
+static size_t str3_off;
+
+/* First three strings we write out. They should always be there.  */
+static char *orig_str1;
+static size_t orig_str1_off;
+static char *orig_str2;
+static size_t orig_str2_off;
+static char *orig_str3;
+static size_t orig_str3_off;
+
+static void
+check_orig_strings (Elf *elf, int ndx, const char *msg)
+{
+  printf ("checking orig strings: %s\n", msg);
+
+  const char *str = elf_strptr (elf, ndx, 0);
+  printf ("\t'%s'\n", str);
+  if (str == NULL || strcmp ("", str) != 0)
+    exit (1);
+
+  str = elf_strptr (elf, ndx, 1);
+  printf ("\t'%s'\n", str);
+  if (str == NULL || strcmp (".strings", str) != 0)
+    exit (1);
+
+  str = elf_strptr (elf, ndx, orig_str1_off);
+  printf ("\t'%s'\n", str);
+  if (str == NULL || strcmp (orig_str1, str) != 0)
+    exit (1);
+
+  str = elf_strptr (elf, ndx, orig_str2_off);
+  printf ("\t'%s'\n", str);
+  if (str == NULL || strcmp (orig_str2, str) != 0)
+    exit (1);
+
+  str = elf_strptr (elf, ndx, orig_str3_off);
+  printf ("\t'%s'\n", str);
+  if (str == NULL || strcmp (orig_str3, str) != 0)
+    exit (1);
+}
+
+static void
+check_strings (Elf *elf, int ndx, const char *msg)
+{
+  check_orig_strings (elf, ndx, msg);
+
+  const char *str = elf_strptr (elf, ndx, str1_off);
+  printf ("\t'%s'\n", str);
+  if (str == NULL || strcmp (str1, str) != 0)
+    exit (1);
+
+  str = elf_strptr (elf, ndx, str2_off);
+  printf ("\t'%s'\n", str);
+  if (str == NULL || strcmp (str2, str) != 0)
+    exit (1);
+
+  str = elf_strptr (elf, ndx, str3_off);
+  printf ("\t'%s'\n", str);
+  if (str == NULL || strcmp (str3, str) != 0)
+    exit (1);
+}
+
+/* Adds a string and returns the offset in the section.  */
+static size_t
+add_string (Elf_Scn *scn, char *str)
+{
+  size_t lastidx = stridx;
+  size_t size = strlen (str) + 1;
+  
+  Elf_Data *data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot create data SHSTRTAB section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  data->d_buf = str;
+  data->d_type = ELF_T_BYTE;
+  data->d_size = size;
+  data->d_align = 1;
+  data->d_version = EV_CURRENT;
+
+  stridx += size;
+  printf ("add_string: '%s', stridx: %zd, lastidx: %zd\n",
+	  str, stridx, lastidx);
+  return lastidx;
+}
+
+static void
+check_elf (const char *fname, int class, int use_mmap)
+{
+  printf ("\nfname: %s\n", fname);
+  stridx = 0;
+
+  int fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s': %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  Elf *elf = elf_begin (fd, use_mmap ? ELF_C_WRITE_MMAP : ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Create an ELF header.
+  if (gelf_newehdr (elf, class) == 0)
+    {
+      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Initialize header.
+  ehdr->e_ident[EI_DATA] = class == ELFCLASS64 ? ELFDATA2LSB : ELFDATA2MSB;
+  ehdr->e_ident[EI_OSABI] = ELFOSABI_GNU;
+  ehdr->e_type = ET_NONE;
+  ehdr->e_machine = EM_X86_64;
+  ehdr->e_version = EV_CURRENT;
+
+  // Create strings section.
+  Elf_Scn *scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create strings section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Add an empty string to the table as NUL entry for section zero.
+  add_string (scn, "");
+
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for strings section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  shdr->sh_type = SHT_STRTAB;
+  shdr->sh_flags = 0;
+  shdr->sh_addr = 0;
+  shdr->sh_link = SHN_UNDEF;
+  shdr->sh_info = SHN_UNDEF;
+  shdr->sh_addralign = 1;
+  shdr->sh_entsize = 0;
+  shdr->sh_name = add_string (scn, ".strings");
+
+  // We have to store the section strtab index in the ELF header.
+  // So sections have actual names.
+  int ndx = elf_ndxscn (scn);
+  ehdr->e_shstrndx = ndx;
+
+  if (gelf_update_ehdr (elf, ehdr) == 0)
+    {
+      printf ("cannot update ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Add some random strings. These are the original ones. They should
+  // always be there (together with the empty "" and .strings section
+  // name strings.
+  orig_str1 = "elfutils";
+  orig_str1_off = add_string (scn, orig_str1);
+  orig_str2 = "strtabelf";
+  orig_str2_off = add_string (scn, orig_str2);
+  orig_str3 = "three";
+  orig_str3_off = add_string (scn, orig_str3);
+
+  // Finished strings section, update the header.
+  if (gelf_update_shdr (scn, shdr) == 0)
+    {
+      printf ("cannot update STRTAB section header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Let the library compute the internal structure information.
+  if (elf_update (elf, ELF_C_NULL) < 0)
+    {
+      printf ("failure in elf_update(NULL): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Check our strings are there.
+  check_orig_strings (elf, ndx, "first elf_update, before write");
+
+  // Write everything to disk.
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Check out strings are there.
+  check_orig_strings (elf, ndx, "first elf_update, after write");
+
+  // Add some more random strings.  These will not be written to disk.
+  scn = elf_getscn (elf, ndx);
+  if (scn == NULL)
+    {
+      printf ("couldn't re-get strings section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  str1 = "elfutils2";
+  str1_off = add_string (scn, str1);
+  str2 = "strtabelf2";
+  str2_off = add_string (scn, str2);
+  str3 = "three2";
+  str3_off = add_string (scn, str3);
+
+  // Update internal structure information again.
+  if (elf_update (elf, ELF_C_NULL) < 0)
+    {
+      printf ("failure in re-elf_update(NULL): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Check our new strings are there.
+  check_strings (elf, ndx, "first extra strings");
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  /* Read the ELF from disk now.  */
+  fd = open (fname, O_RDWR, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf = elf_begin (fd, use_mmap ? ELF_C_RDWR_MMAP : ELF_C_RDWR, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Are our strings there?  */
+  check_orig_strings (elf, ndx, "read ELF file, orig strings");
+
+  // Add some more random strings.
+  scn = elf_getscn (elf, ndx);
+  if (scn == NULL)
+    {
+      printf ("couldn't re-get strings section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for strings section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Reset stridx to end of section.
+  printf ("sh_size: %" PRIu64 "\n", shdr->sh_size);
+  stridx = shdr->sh_size;
+
+  str1 = "0123456789";
+  str1_off = add_string (scn, str1);
+  str2 = "supercalifragilisticexpialidocious";
+  str2_off = add_string (scn, str2);
+  str3 = "forty-two";
+  str3_off = add_string (scn, str3);
+
+  // Update internal structure information.
+  if (elf_update (elf, ELF_C_NULL) < 0)
+    {
+      printf ("failure in rw-elf_update(NULL): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Check our new strings are there.  */
+  check_strings (elf, ndx, "read file, added strings");
+
+  // Write updated ELF file.
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in re-elf_update(NULL): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  // And read it in one last time.
+  fd = open (fname, O_RDONLY, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf = elf_begin (fd, use_mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Are all our strings there?  */
+  check_strings (elf, ndx, "all together now");
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  unlink (fname);
+}
+
+int
+main (int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused)))
+{
+  elf_version (EV_CURRENT);
+
+  // Fill holes with something non-zero to more easily spot
+  // unterminated strings.
+  elf_fill ('X');
+
+  check_elf ("strtab.elf.32", ELFCLASS32, 0);
+  check_elf ("strtab.elf.32.mmap", ELFCLASS32, 1);
+  check_elf ("strtab.elf.64", ELFCLASS64, 0);
+  check_elf ("strtab.elf.64.mmap", ELFCLASS64, 1);
+
+  return 0;
+}
+
diff --git a/third_party/elfutils/tests/emptyfile.c b/third_party/elfutils/tests/emptyfile.c
new file mode 100644
index 0000000..6d08624
--- /dev/null
+++ b/third_party/elfutils/tests/emptyfile.c
@@ -0,0 +1,277 @@
+/* Test program for adding a section to an empty ELF file.
+   Copyright (C) 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include ELFUTILS_HEADER(elf)
+#include <gelf.h>
+
+
+/* Index of last string added.  Returned by add_string ().  */
+static size_t stridx = 0;
+
+/* Adds a string and returns the offset in the section.  */
+static size_t
+add_string (Elf_Scn *scn, char *str)
+{
+  size_t lastidx = stridx;
+  size_t size = strlen (str) + 1;
+
+  Elf_Data *data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot create data SHSTRTAB section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  data->d_buf = str;
+  data->d_type = ELF_T_BYTE;
+  data->d_size = size;
+  data->d_align = 1;
+  data->d_version = EV_CURRENT;
+
+  stridx += size;
+  printf ("add_string: '%s', stridx: %zd, lastidx: %zd\n",
+	  str, stridx, lastidx);
+  return lastidx;
+}
+
+static void
+check_elf (const char *fname, int class, int use_mmap)
+{
+  printf ("\nfname: %s\n", fname);
+  stridx = 0; // Reset strtab strings index
+
+  int fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s': %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  Elf *elf = elf_begin (fd, use_mmap ? ELF_C_WRITE_MMAP : ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Create an ELF header.
+  if (gelf_newehdr (elf, class) == 0)
+    {
+      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Initialize header.
+  ehdr->e_ident[EI_DATA] = class == ELFCLASS64 ? ELFDATA2LSB : ELFDATA2MSB;
+  ehdr->e_ident[EI_OSABI] = ELFOSABI_GNU;
+  ehdr->e_type = ET_NONE;
+  ehdr->e_machine = EM_X86_64;
+  ehdr->e_version = EV_CURRENT;
+
+  if (gelf_update_ehdr (elf, ehdr) == 0)
+    {
+      printf ("cannot update ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Write everything to disk.
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  /* Reread the ELF from disk now.  */
+  fd = open (fname, O_RDWR, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot (re)open `%s': %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf = elf_begin (fd, use_mmap ? ELF_C_RDWR_MMAP : ELF_C_RDWR, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // There are no sections yet.
+  if (elf_nextscn (elf, NULL) != NULL)
+    {
+      printf ("Empty elf had a section???\n");
+      exit (1);
+    }
+
+  // Create strtab section.
+  Elf_Scn *scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create strings section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Add an empty string to the table as NUL entry for section zero.
+  add_string (scn, "");
+
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for strings section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  shdr->sh_type = SHT_STRTAB;
+  shdr->sh_flags = 0;
+  shdr->sh_addr = 0;
+  shdr->sh_link = SHN_UNDEF;
+  shdr->sh_info = SHN_UNDEF;
+  shdr->sh_addralign = 1;
+  shdr->sh_entsize = 0;
+  shdr->sh_name = add_string (scn, ".strtab");
+
+  // We have to store the section strtab index in the ELF header.
+  // So sections have actual names.
+  int ndx = elf_ndxscn (scn);
+  ehdr->e_shstrndx = ndx;
+
+  if (gelf_update_ehdr (elf, ehdr) == 0)
+    {
+      printf ("cannot update ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Finished strtab section, update the header.
+  if (gelf_update_shdr (scn, shdr) == 0)
+    {
+      printf ("cannot update STRTAB section header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Write everything to disk.
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  // And read it in one last time.
+  fd = open (fname, O_RDONLY, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf = elf_begin (fd, use_mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Is our new section there?
+  scn = elf_nextscn (elf, NULL);
+  if (scn == NULL)
+    {
+      printf ("cannot get new section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for new section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  size_t shstrndx;
+  if (elf_getshdrstrndx (elf, &shstrndx) < 0)
+    {
+      printf ("elf_getshdrstrndx: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  const char *sname = elf_strptr (elf, shstrndx, shdr->sh_name);
+  if (sname == NULL || strcmp (sname, ".strtab") != 0)
+    {
+      printf ("Bad section name: %s\n", sname);
+      exit (1);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  unlink (fname);
+}
+
+int
+main (int argc __attribute__ ((unused)),
+      char *argv[] __attribute__ ((unused)))
+{
+  elf_version (EV_CURRENT);
+
+  check_elf ("empty.elf.32", ELFCLASS32, 0);
+  check_elf ("empty.elf.32.mmap", ELFCLASS32, 1);
+  check_elf ("empty.elf.64", ELFCLASS64, 0);
+  check_elf ("empty.elf.64.mmap", ELFCLASS64, 1);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/fillfile.c b/third_party/elfutils/tests/fillfile.c
new file mode 100644
index 0000000..915e249
--- /dev/null
+++ b/third_party/elfutils/tests/fillfile.c
@@ -0,0 +1,448 @@
+/* Test program for changing data in one section (but not others) with gaps.
+   Copyright (C) 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include ELFUTILS_HEADER(elf)
+#include <gelf.h>
+
+
+/* Index of last string added.  Returned by add_string ().  */
+static size_t stridx = 0;
+
+/* Adds a string and returns the offset in the section.  */
+static size_t
+add_strtab_entry (Elf_Scn *strtab, const char *str)
+{
+  size_t lastidx = stridx;
+  size_t size = strlen (str) + 1;
+
+  Elf_Data *data = elf_newdata (strtab);
+  if (data == NULL)
+    {
+      printf ("cannot create data SHSTRTAB section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  data->d_buf = (char *) str; /* Discards const, but we will not change. */
+  data->d_type = ELF_T_BYTE;
+  data->d_size = size;
+  data->d_align = 1;
+  data->d_version = EV_CURRENT;
+
+  stridx += size;
+  printf ("add_string: '%s', stridx: %zd, lastidx: %zd\n",
+	  str, stridx, lastidx);
+  return lastidx;
+}
+
+static Elf_Scn *
+create_strtab (Elf *elf)
+{
+  // Create strtab section.
+  Elf_Scn *scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create strings section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Add an empty string to the table as NUL entry for section zero.
+  add_strtab_entry (scn, "");
+
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for new strtab section: %s\n",
+	      elf_errmsg (-1));
+      exit (1);
+    }
+
+  shdr->sh_type = SHT_STRTAB;
+  shdr->sh_flags = 0;
+  shdr->sh_addr = 0;
+  shdr->sh_link = SHN_UNDEF;
+  shdr->sh_info = SHN_UNDEF;
+  shdr->sh_addralign = 1;
+  shdr->sh_entsize = 0;
+  shdr->sh_name = add_strtab_entry (scn, ".strtab");
+
+  // We have to store the section strtab index in the ELF header.
+  // So sections have actual names.
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  int ndx = elf_ndxscn (scn);
+  ehdr->e_shstrndx = ndx;
+
+  if (gelf_update_ehdr (elf, ehdr) == 0)
+    {
+      printf ("cannot update ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Finished strtab section, update the header.
+  if (gelf_update_shdr (scn, shdr) == 0)
+    {
+      printf ("cannot update STRTAB section header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  return scn;
+}
+
+static char sec_data[] = { 1, 2, 3, 4, 5 };
+static char new_data[] = { 5, 4, 3, 2, 1 };
+
+static void
+add_data_section (Elf *elf, Elf_Scn *strtab, const char *sname)
+{
+  printf ("Add data section %s\n", sname);
+  Elf_Scn *scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create strings section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for new %s section: %s\n",
+	      sname, elf_errmsg (-1));
+      exit (1);
+    }
+
+  shdr->sh_type = SHT_PROGBITS;
+  shdr->sh_flags = 0;
+  shdr->sh_addr = 0;
+  shdr->sh_link = SHN_UNDEF;
+  shdr->sh_info = SHN_UNDEF;
+  shdr->sh_addralign = 128;  // Large alignment to force gap between sections.
+  shdr->sh_entsize = 1;
+  shdr->sh_name = add_strtab_entry (strtab, sname);
+
+  if (gelf_update_shdr (scn, shdr) == 0)
+    {
+      printf ("cannot update %s section header: %s\n", sname, elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Add some data, but less than alignment. */
+  Elf_Data *data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot update %s section header: %s\n", sname, elf_errmsg (-1));
+      exit (1);
+    }
+  data->d_buf = sec_data;
+  data->d_size = 5;
+}
+
+static void
+check_data (const char *sname, Elf_Data *data, char *buf)
+{
+  printf ("check data %s [", sname);
+  for (int i = 0; i < 5; i++)
+    printf ("%d%s", buf[i], i < 4 ? "," : "");
+  printf ("]\n");
+  if (data == NULL || data->d_buf == NULL)
+    {
+      printf ("No data in section %s\n", sname);
+      exit (1);
+    }
+
+  if (data->d_size != 5 || memcmp (data->d_buf, buf, 5) != 0)
+    {
+      printf ("Wrong data in section %s [", sname);
+      for (size_t i = 0; i < data->d_size; i++)
+	printf ("%d%s", ((char *)data->d_buf)[i],
+		i < data->d_size - 1 ? "," : "");
+      printf ("]\n");
+      exit(1);
+    }
+}
+
+static void
+check_elf (const char *fname, int class, int use_mmap)
+{
+  printf ("\nfname: %s\n", fname);
+  stridx = 0; // Reset strtab strings index
+
+  int fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s': %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  Elf *elf = elf_begin (fd, use_mmap ? ELF_C_WRITE_MMAP : ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Create an ELF header.
+  if (gelf_newehdr (elf, class) == 0)
+    {
+      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Initialize header.
+  ehdr->e_ident[EI_DATA] = class == ELFCLASS64 ? ELFDATA2LSB : ELFDATA2MSB;
+  ehdr->e_ident[EI_OSABI] = ELFOSABI_GNU;
+  ehdr->e_type = ET_NONE;
+  ehdr->e_machine = EM_X86_64;
+  ehdr->e_version = EV_CURRENT;
+
+  if (gelf_update_ehdr (elf, ehdr) == 0)
+    {
+      printf ("cannot update ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  Elf_Scn *strtab = create_strtab (elf);
+  add_data_section (elf, strtab, ".data1");
+  add_data_section (elf, strtab, ".data2");
+  add_data_section (elf, strtab, ".data3");
+  add_data_section (elf, strtab, ".data4");
+
+  // Write everything to disk.
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  /* Reread the ELF from disk now.  */
+  printf ("Rereading %s\n", fname);
+  fd = open (fname, O_RDWR, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot (re)open `%s': %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf = elf_begin (fd, use_mmap ? ELF_C_RDWR_MMAP : ELF_C_RDWR, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* We are going to change some data (in-place), but want the layout
+     to stay exactly the same. */
+  elf_flagelf (elf, ELF_C_SET, ELF_F_LAYOUT);
+
+  size_t shdrstrndx;
+  if (elf_getshdrstrndx (elf, &shdrstrndx) != 0)
+    {
+      printf ("cannot get shdr str ndx\n");
+      exit (1);
+    }
+  printf ("shdrstrndx: %zd\n", shdrstrndx);
+
+  // Get third data section and change it.
+  Elf_Scn *checkscn = NULL;
+  Elf_Scn *scn = elf_nextscn (elf, NULL);
+  while (scn != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  printf ("cannot get header for section: %s\n", elf_errmsg (-1));
+	  exit (1);
+	}
+      const char *sname = elf_strptr (elf, shdrstrndx, shdr->sh_name);
+      if (sname != NULL && strcmp (".data3", sname) == 0)
+	checkscn = scn;
+
+      // Get all data, but don't really use it
+      // (this triggered the original bug).
+      Elf_Data *data = elf_getdata (scn, NULL);
+      if (data != NULL && data->d_buf != NULL && data->d_size == 0)
+	{
+	  printf ("Bad data...n");
+	  exit (1);
+	}
+      scn = elf_nextscn (elf, scn);
+    }
+
+  if (checkscn == NULL)
+    {
+      printf ("ELF file doesn't have a .data3 section\n");
+      exit (1);
+    }
+
+  Elf_Data *data = elf_getdata (checkscn, NULL);
+  check_data (".data3", data, sec_data);
+  memcpy (data->d_buf, new_data, 5);
+  elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
+
+  // Write everything to disk.
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  // And read it in one last time.
+  printf ("Rereading %s again\n", fname);
+  fd = open (fname, O_RDONLY, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf = elf_begin (fd, use_mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Get all .data sections and check them.
+  Elf_Scn *scn1 = NULL;
+  Elf_Scn *scn2 = NULL;
+  Elf_Scn *scn3 = NULL;
+  Elf_Scn *scn4 = NULL;
+  scn = elf_nextscn (elf, NULL);
+  while (scn != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      if (shdr == NULL)
+	{
+	  printf ("cannot get header for section: %s\n", elf_errmsg (-1));
+	  exit (1);
+	}
+      const char *sname = elf_strptr (elf, shdrstrndx, shdr->sh_name);
+      if (sname != NULL && strcmp (".data1", sname) == 0)
+	scn1 = scn;
+      else if (sname != NULL && strcmp (".data2", sname) == 0)
+	scn2 = scn;
+      else if (sname != NULL && strcmp (".data3", sname) == 0)
+	scn3 = scn;
+      else if (sname != NULL && strcmp (".data4", sname) == 0)
+	scn4 = scn;
+      scn = elf_nextscn (elf, scn);
+    }
+
+  if (scn1 == NULL)
+    {
+      printf ("ELF file doesn't have a .data1 section\n");
+      exit (1);
+    }
+  data = elf_getdata (scn1, NULL);
+  check_data (".data1", data, sec_data);
+
+  if (scn2 == NULL)
+    {
+      printf ("ELF file doesn't have a .data2 section\n");
+      exit (1);
+    }
+  data = elf_getdata (scn2, NULL);
+  check_data (".data2", data, sec_data);
+
+  if (scn3 == NULL)
+    {
+      printf ("ELF file doesn't have a .data3 section\n");
+      exit (1);
+    }
+  data = elf_getdata (scn3, NULL);
+  check_data (".data3", data, new_data);
+
+  if (scn4 == NULL)
+    {
+      printf ("ELF file doesn't have a .data4 section\n");
+      exit (1);
+    }
+  data = elf_getdata (scn4, NULL);
+  check_data (".data4", data, sec_data);
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  unlink (fname);
+}
+
+int
+main (int argc __attribute__ ((unused)),
+      char *argv[] __attribute__ ((unused)))
+{
+  elf_version (EV_CURRENT);
+
+  elf_fill (0xA);
+
+  check_elf ("fill.elf.32", ELFCLASS32, 0);
+  check_elf ("fill.elf.32.mmap", ELFCLASS32, 1);
+  check_elf ("fill.elf.64", ELFCLASS64, 0);
+  check_elf ("fill.elf.64.mmap", ELFCLASS64, 1);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/find-prologues.c b/third_party/elfutils/tests/find-prologues.c
new file mode 100644
index 0000000..ba8ae37
--- /dev/null
+++ b/third_party/elfutils/tests/find-prologues.c
@@ -0,0 +1,108 @@
+/* Test program for dwarf_entry_breakpoints.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+#include <argp.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <error.h>
+#include <string.h>
+#include <fnmatch.h>
+
+
+struct args
+{
+  Dwfl *dwfl;
+  Dwarf_Die *cu;
+  Dwarf_Addr dwbias;
+  char **argv;
+};
+
+static int
+handle_function (Dwarf_Die *func, void *arg)
+{
+  struct args *a = arg;
+
+  const char *name = dwarf_diename (func);
+  char **argv = a->argv;
+  if (argv[0] != NULL)
+    {
+      bool match;
+      do
+	match = fnmatch (*argv, name, 0) == 0;
+      while (!match && *++argv);
+      if (!match)
+	return 0;
+    }
+
+  if (dwarf_func_inline (func))
+    return 0;
+
+  Dwarf_Addr entrypc;
+  if (dwarf_entrypc (func, &entrypc) != 0)
+    error (EXIT_FAILURE, 0, "dwarf_entrypc: %s: %s",
+	   dwarf_diename (func), dwarf_errmsg (-1));
+  entrypc += a->dwbias;
+
+  printf ("%-16s %#.16" PRIx64, dwarf_diename (func), entrypc);
+
+  Dwarf_Addr *bkpts = NULL;
+  int result = dwarf_entry_breakpoints (func, &bkpts);
+  if (result <= 0)
+    printf ("\t%s\n", dwarf_errmsg (-1));
+  else
+    {
+      for (int i = 0; i < result; ++i)
+	printf (" %#.16" PRIx64 "%s", bkpts[i] + a->dwbias,
+		i == result - 1 ? "\n" : "");
+      free (bkpts);
+    }
+
+  return 0;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  struct args a = { .dwfl = NULL, .cu = NULL };
+
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining,
+		     &a.dwfl);
+  assert (a.dwfl != NULL);
+  a.argv = &argv[remaining];
+
+  int result = 0;
+
+  while ((a.cu = dwfl_nextcu (a.dwfl, a.cu, &a.dwbias)) != NULL)
+    dwarf_getfuncs (a.cu, &handle_function, &a, 0);
+
+  dwfl_end (a.dwfl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/funcretval.c b/third_party/elfutils/tests/funcretval.c
new file mode 100644
index 0000000..8d19d11
--- /dev/null
+++ b/third_party/elfutils/tests/funcretval.c
@@ -0,0 +1,106 @@
+/* Test program for dwfl_module_return_value_location.
+   Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+#include <argp.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <error.h>
+#include <string.h>
+#include <fnmatch.h>
+
+
+struct args
+{
+  Dwfl *dwfl;
+  Dwarf_Die *cu;
+  Dwarf_Addr dwbias;
+  char **argv;
+};
+
+static int
+handle_function (Dwarf_Die *funcdie, void *arg)
+{
+  struct args *a = arg;
+
+  const char *name = dwarf_diename (funcdie);
+  char **argv = a->argv;
+  if (argv[0] != NULL)
+    {
+      bool match;
+      do
+	match = fnmatch (*argv, name, 0) == 0;
+      while (!match && *++argv);
+      if (!match)
+	return 0;
+    }
+
+  printf ("(%s) %s: ", dwfl_module_info (dwfl_cumodule (a->cu), NULL,
+					 NULL, NULL,
+					 NULL, NULL,
+					 NULL, NULL), name);
+
+  const Dwarf_Op *locops;
+  int nlocops = dwfl_module_return_value_location (dwfl_cumodule (a->cu),
+						   funcdie, &locops);
+  if (nlocops < 0)
+    error (EXIT_FAILURE, 0, "dwfl_module_return_value_location: %s",
+	   dwfl_errmsg (-1));
+  else if (nlocops == 0)
+    puts ("returns no value");
+  else
+    {
+      printf ("return value location:");
+      for (int i = 0; i < nlocops; ++i)
+	printf (" {%#x, %#" PRIx64 "}", locops[i].atom, locops[i].number);
+      puts ("");
+    }
+
+  return 0;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  struct args a = { .dwfl = NULL, .cu = NULL };
+
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining,
+		     &a.dwfl);
+  assert (a.dwfl != NULL);
+  a.argv = &argv[remaining];
+
+  int result = 0;
+
+  while ((a.cu = dwfl_nextcu (a.dwfl, a.cu, &a.dwbias)) != NULL)
+    dwarf_getfuncs (a.cu, &handle_function, &a, 0);
+
+  dwfl_end (a.dwfl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/funcretval_test.c b/third_party/elfutils/tests/funcretval_test.c
new file mode 100644
index 0000000..7e20f52
--- /dev/null
+++ b/third_party/elfutils/tests/funcretval_test.c
@@ -0,0 +1,828 @@
+signed char fun_char (void) { return 5; }
+short fun_short (void) { return 6; }
+int fun_int (void) { return 7; }
+void *fun_ptr (void) { return &fun_ptr; }
+int fun_iptr (void) { return 8; }
+long fun_long (void) { return 9; }
+__int128 fun_int128 (void) { return 10; }
+
+typedef struct { int i[10]; } large_struct1_t;
+large_struct1_t fun_large_struct1 (void) {
+  large_struct1_t ret = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } };
+  return ret;
+}
+
+typedef struct { int i1; int i2; int i3; int i4; int i5;
+  int i6; int i7; int i8; int i9; int i10; } large_struct2_t;
+large_struct2_t fun_large_struct2 (void) {
+  large_struct2_t ret = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+  return ret;
+}
+
+float fun_float (void) { return 1.5; }
+float _Complex fun_float_complex (void) { return 1.5 + 2.5i; }
+
+double fun_double (void) { return 2.5; }
+double _Complex fun_double_complex (void) { return 2.5 + 3.5i; }
+
+long double fun_long_double (void) { return 3.5; }
+long double _Complex fun_long_double_complex (void) { return 4.5 + 5.5i; }
+
+#ifdef FLOAT128
+__float128 fun_float128 (void) { return 3.5; }
+#endif
+
+// 8 byte vectors.
+
+typedef signed char __attribute__ ((vector_size (8))) vec_char_8_t;
+vec_char_8_t fun_vec_char_8 (void) {
+  vec_char_8_t ret = { 1, 2, 3, 4, 5, 6, 7, 8 };
+  return ret;
+}
+
+typedef short __attribute__ ((vector_size (8))) vec_short_8_t;
+vec_short_8_t fun_vec_short_8 (void) {
+  vec_short_8_t ret = { 2, 3, 4, 5 };
+  return ret;
+}
+
+typedef int __attribute__ ((vector_size (8))) vec_int_8_t;
+vec_int_8_t fun_vec_int_8 (void) {
+  vec_int_8_t ret = { 3, 4 };
+  return ret;
+}
+
+typedef long __attribute__ ((vector_size (8))) vec_long_8_t;
+vec_long_8_t fun_vec_long_8 (void) {
+  vec_long_8_t ret = { 5 };
+  return ret;
+}
+
+typedef float __attribute__ ((vector_size (8))) vec_float_8_t;
+vec_float_8_t fun_vec_float_8 (void) {
+  vec_float_8_t ret = { 1.5, 2.5 };
+  return ret;
+}
+
+typedef double __attribute__ ((vector_size (8))) vec_double_8_t;
+#ifndef AARCH64_BUG_1032854
+// https://bugzilla.redhat.com/show_bug.cgi?id=1032854
+vec_double_8_t fun_vec_double_8 (void) {
+  vec_double_8_t ret = { 3.5 };
+  return ret;
+}
+#endif
+
+// 16 byte vectors.
+
+typedef signed char __attribute__ ((vector_size (16))) vec_char_16_t;
+vec_char_16_t fun_vec_char_16 (void) {
+  vec_char_16_t ret = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+  return ret;
+}
+
+typedef short __attribute__ ((vector_size (16))) vec_short_16_t;
+vec_short_16_t fun_vec_short_16 (void) {
+  vec_short_16_t ret = { 2, 3, 4, 5, 6, 7, 8 };
+  return ret;
+}
+
+typedef int __attribute__ ((vector_size (16))) vec_int_16_t;
+vec_int_16_t fun_vec_int_16 (void) {
+  vec_int_16_t ret = { 2, 3, 4 };
+  return ret;
+}
+
+typedef long __attribute__ ((vector_size (16))) vec_long_16_t;
+vec_long_16_t fun_vec_long_16 (void) {
+  vec_long_16_t ret = { 3, 4 };
+  return ret;
+}
+
+typedef __int128 __attribute__ ((vector_size (16))) vec_int128_16_t;
+vec_int128_16_t fun_vec_int128_16 (void) {
+  vec_int128_16_t ret = { 999 };
+  return ret;
+}
+
+typedef float __attribute__ ((vector_size (16))) vec_float_16_t;
+vec_float_16_t fun_vec_float_16 (void) {
+  vec_float_16_t ret = { 1.5, 2.5, 3.5, 4.5 };
+  return ret;
+}
+
+typedef double __attribute__ ((vector_size (16))) vec_double_16_t;
+vec_double_16_t fun_vec_double_16 (void) {
+  vec_double_16_t ret = { 2.5, 5 };
+  return ret;
+}
+
+#ifdef FLOAT128
+typedef __float128 __attribute__ ((vector_size (16))) vec_float128_16_t;
+vec_float128_16_t fun_vec_float128_16 (void) {
+  vec_float128_16_t ret = { 7.5 };
+  return ret;
+}
+#endif
+
+// Homogeneous floating-point aggregates.
+
+typedef struct { float f; } hfa1_float_t;
+hfa1_float_t fun_hfa1_float (void) {
+  hfa1_float_t ret = { 1.5 };
+  return ret;
+}
+
+typedef struct { double f; } hfa1_double_t;
+hfa1_double_t fun_hfa1_double (void) {
+  hfa1_double_t ret = { 3.0 };
+  return ret;
+}
+
+typedef struct { long double f; } hfa1_long_double_t;
+hfa1_long_double_t fun_hfa1_long_double (void) {
+  hfa1_long_double_t ret = { 3.0 };
+  return ret;
+}
+
+typedef struct { float f[1]; } hfa1_float_a_t;
+hfa1_float_a_t fun_hfa1_float_a (void) {
+  hfa1_float_a_t ret = { { 1.5 } };
+  return ret;
+}
+
+typedef struct { double f[1]; } hfa1_double_a_t;
+hfa1_double_a_t fun_hfa1_double_a (void) {
+  hfa1_double_a_t ret = { { 3.0 } };
+  return ret;
+}
+
+typedef struct { long double f[1]; } hfa1_long_double_a_t;
+hfa1_long_double_a_t fun_hfa1_long_double_a (void) {
+  hfa1_long_double_a_t ret = { { 3.0 } };
+  return ret;
+}
+
+typedef struct { float f; float g; } hfa2_float_t;
+hfa2_float_t fun_hfa2_float (void) {
+  hfa2_float_t ret = { 1.5, 3.0 };
+  return ret;
+}
+
+typedef struct { double f; double g; } hfa2_double_t;
+hfa2_double_t fun_hfa2_double (void) {
+  hfa2_double_t ret = { 3.0, 4.5 };
+  return ret;
+}
+
+typedef struct { long double f; long double g; } hfa2_long_double_t;
+hfa2_long_double_t fun_hfa2_long_double (void) {
+  hfa2_long_double_t ret = { 3.0, 4.5 };
+  return ret;
+}
+
+typedef struct { float f[2]; } hfa2_float_a_t;
+hfa2_float_a_t fun_hfa2_float_a (void) {
+  hfa2_float_a_t ret = { { 2.5, 3.5 } };
+  return ret;
+}
+
+typedef struct { double f[2]; } hfa2_double_a_t;
+hfa2_double_a_t fun_hfa2_double_a (void) {
+  hfa2_double_a_t ret = { { 3.0, 3.5 } };
+  return ret;
+}
+
+typedef struct { long double f[2]; } hfa2_long_double_a_t;
+hfa2_long_double_a_t fun_hfa2_long_double_a (void) {
+  hfa2_long_double_a_t ret = { { 3.0, 4.0 } };
+  return ret;
+}
+
+typedef struct { float f; float g; float h; } hfa3_float_t;
+hfa3_float_t fun_hfa3_float (void) {
+  hfa3_float_t ret = { 1.5, 3.0, 4.5 };
+  return ret;
+}
+
+typedef struct { double f; double g; double h; } hfa3_double_t;
+hfa3_double_t fun_hfa3_double (void) {
+  hfa3_double_t ret = { 3.0, 4.5, 9.5 };
+  return ret;
+}
+
+typedef struct { long double f; long double g; long double h; } hfa3_long_double_t;
+hfa3_long_double_t fun_hfa3_long_double (void) {
+  hfa3_long_double_t ret = { 3.0, 4.5, 9.5 };
+  return ret;
+}
+
+typedef struct { float f[3]; } hfa3_float_a_t;
+hfa3_float_a_t fun_hfa3_float_a (void) {
+  hfa3_float_a_t ret = { { 3.5, 4.5, 5.5 } };
+  return ret;
+}
+
+typedef struct { double f[3]; } hfa3_double_a_t;
+hfa3_double_a_t fun_hfa3_double_a (void) {
+  hfa3_double_a_t ret = { { 3.0, 3.5, 4.0 } };
+  return ret;
+}
+
+typedef struct { long double f[3]; } hfa3_long_double_a_t;
+hfa3_long_double_a_t fun_hfa3_long_double_a (void) {
+  hfa3_long_double_a_t ret = { { 3.0, 4.0, 5.0 } };
+  return ret;
+}
+
+typedef struct { float f; float g; float h; float i; } hfa4_float_t;
+hfa4_float_t fun_hfa4_float (void) {
+  hfa4_float_t ret = { 1.5, 3.5, 4.5, 9.5 };
+  return ret;
+}
+
+typedef struct { double f; double g; double h; double i; } hfa4_double_t;
+hfa4_double_t fun_hfa4_double (void) {
+  hfa4_double_t ret = { 3.5, 4.5, 9.5, 1.5 };
+  return ret;
+}
+
+typedef struct { long double f; long double g; long double h; long double i; } hfa4_long_double_t;
+hfa4_long_double_t fun_hfa4_long_double (void) {
+  hfa4_long_double_t ret = { 3.5, 4.5, 9.5, 1.5 };
+  return ret;
+}
+
+typedef struct { float f[4]; } hfa4_float_a_t;
+hfa4_float_a_t fun_hfa4_float_a (void) {
+  hfa4_float_a_t ret = { { 4.5, 5.5, 6.5, 7.5 } };
+  return ret;
+}
+
+typedef struct { double f[4]; } hfa4_double_a_t;
+hfa4_double_a_t fun_hfa4_double_a (void) {
+  hfa4_double_a_t ret = { { 3.0, 4.5, 5.0, 5.5 } };
+  return ret;
+}
+
+typedef struct { long double f[4]; } hfa4_long_double_a_t;
+hfa4_long_double_a_t fun_hfa4_long_double_a (void) {
+  hfa4_long_double_a_t ret = { { 3.0, 4.0, 5.0, 6.0 } };
+  return ret;
+}
+
+typedef struct { float f; float g; float h; float i; float j; } nfa5_float_t;
+nfa5_float_t fun_nfa5_float (void) {
+  nfa5_float_t ret = { 1.5, 3.5, 4.5, 9.5, 10.5 };
+  return ret;
+}
+
+typedef struct { double f; double g; double h; double i; double j; } nfa5_double_t;
+nfa5_double_t fun_nfa5_double (void) {
+  nfa5_double_t ret = { 3.5, 4.5, 9.5, 1.5, 2.5 };
+  return ret;
+}
+
+typedef struct { long double f; long double g; long double h; long double i; long double j; } nfa5_long_double_t;
+nfa5_long_double_t fun_nfa5_long_double (void) {
+  nfa5_long_double_t ret = { 3.5, 4.5, 9.5, 1.5, 2.5 };
+  return ret;
+}
+
+typedef struct { float f[5]; } nfa5_float_a_t;
+nfa5_float_a_t fun_nfa5_float_a (void) {
+  nfa5_float_a_t ret = { { 4.5, 5.5, 6.5, 7.5, 9.5 } };
+  return ret;
+}
+
+typedef struct { double f[5]; } nfa5_double_a_t;
+nfa5_double_a_t fun_nfa5_double_a (void) {
+  nfa5_double_a_t ret = { { 3.0, 4.5, 5.0, 5.5, 6.5 } };
+  return ret;
+}
+
+typedef struct { long double f[5]; } nfa5_long_double_a_t;
+nfa5_long_double_a_t fun_nfa5_long_double_a (void) {
+  nfa5_long_double_a_t ret = { { 3.0, 4.0, 5.0, 6.0, 7.0 } };
+  return ret;
+}
+
+#ifdef FLOAT128
+typedef struct { __float128 f; } hfa1_float128_t;
+hfa1_float128_t fun_hfa1_float128 (void) {
+  hfa1_float128_t ret = { 4.5 };
+  return ret;
+}
+
+typedef struct { __float128 f; __float128 g; } hfa2_float128_t;
+hfa2_float128_t fun_hfa2_float128 (void) {
+  hfa2_float128_t ret = { 4.5, 9.5 };
+  return ret;
+}
+
+typedef struct { __float128 f; __float128 g; __float128 h; } hfa3_float128_t;
+hfa3_float128_t fun_hfa3_float128 (void) {
+  hfa3_float128_t ret = { 4.5, 9.5, 12.5 };
+  return ret;
+}
+
+typedef struct { __float128 f; __float128 g; __float128 h; __float128 i; } hfa4_float128_t;
+hfa4_float128_t fun_hfa4_float128 (void) {
+  hfa4_float128_t ret = { 4.5, 9.5, 3.5, 1.5 };
+  return ret;
+}
+#endif
+
+// Homogeneous vector aggregates of 1 element.
+
+typedef struct { vec_char_8_t a; } hva1_vec_char_8_t;
+hva1_vec_char_8_t fun_hva1_vec_char_8 (void) {
+  hva1_vec_char_8_t ret = { { 1, 2, 3, 4, 5, 6, 7, 8 } };
+  return ret;
+}
+
+typedef struct { vec_short_8_t a; } hva1_vec_short_8_t;
+hva1_vec_short_8_t fun_hva1_vec_short_8 (void) {
+  hva1_vec_short_8_t ret = { { 2, 3, 4, 5 } };
+  return ret;
+}
+
+typedef struct { vec_int_8_t a; } hva1_vec_int_8_t;
+hva1_vec_int_8_t fun_hva1_vec_int_8 (void) {
+  hva1_vec_int_8_t ret = { { 3, 4 } };
+  return ret;
+}
+
+typedef struct { vec_long_8_t a; } hva1_vec_long_8_t;
+hva1_vec_long_8_t fun_hva1_vec_long_8 (void) {
+  hva1_vec_long_8_t ret = { { 5 } };
+  return ret;
+}
+
+typedef struct { vec_float_8_t a; } hva1_vec_float_8_t;
+hva1_vec_float_8_t fun_hva1_vec_float_8 (void) {
+  hva1_vec_float_8_t ret = { { 1.5, 2.5 } };
+  return ret;
+}
+
+typedef struct { vec_double_8_t a; } hva1_vec_double_8_t;
+hva1_vec_double_8_t fun_hva1_vec_double_8 (void) {
+  hva1_vec_double_8_t ret = { { 3.5 } };
+  return ret;
+}
+
+typedef struct { vec_char_16_t a; } hva1_vec_char_16_t;
+hva1_vec_char_16_t fun_hva1_vec_char_16_t (void) {
+  hva1_vec_char_16_t ret = { { 1, 2, 3, 4, 5, 6, 7, 8,
+			       9, 10, 11, 12, 13, 14, 15, 16 } };
+  return ret;
+}
+
+typedef struct { vec_short_16_t a; } hva1_vec_short_16_t;
+hva1_vec_short_16_t fun_hva1_vec_short_16_t (void) {
+  hva1_vec_short_16_t ret = { { 2, 3, 4, 5, 6, 7, 8, 9 } };
+  return ret;
+}
+
+typedef struct { vec_int_16_t a; } hva1_vec_int_16_t;
+hva1_vec_int_16_t fun_hva1_vec_int_16_t (void) {
+  hva1_vec_int_16_t ret = { { 3, 4, 5, 6 } };
+  return ret;
+}
+
+typedef struct { vec_long_16_t a; } hva1_vec_long_16_t;
+hva1_vec_long_16_t fun_hva1_vec_long_16_t (void) {
+  hva1_vec_long_16_t ret = { { 4, 5 } };
+  return ret;
+}
+
+typedef struct { vec_int128_16_t a; } hva1_vec_int128_16_t;
+hva1_vec_int128_16_t fun_hva1_vec_int128_16_t (void) {
+  hva1_vec_int128_16_t ret = { { 6 } };
+  return ret;
+}
+
+typedef struct { vec_float_16_t a; } hva1_vec_float_16_t;
+hva1_vec_float_16_t fun_hva1_vec_float_16_t (void) {
+  hva1_vec_float_16_t ret = { { 1.5, 2.5, 3.5, 4.5 } };
+  return ret;
+}
+
+typedef struct { vec_double_16_t a; } hva1_vec_double_16_t;
+hva1_vec_double_16_t fun_hva1_vec_double_16_t (void) {
+  hva1_vec_double_16_t ret = { { 2.5, 3.5 } };
+  return ret;
+}
+
+#ifdef FLOAT128
+typedef struct { vec_float128_16_t a; } hva1_vec_float128_16_t;
+hva1_vec_float128_16_t fun_hva1_vec_float128_16_t (void) {
+  hva1_vec_float128_16_t ret = { { 4.5 } };
+  return ret;
+}
+#endif
+
+// Homogeneous vector aggregates of 2 elements.
+
+typedef struct { vec_char_8_t a; vec_char_8_t b; } hva2_vec_char_8_t;
+hva2_vec_char_8_t fun_hva2_vec_char_8 (void) {
+  hva2_vec_char_8_t ret = { { 1, 2, 3, 4, 5, 6, 7, 8 },
+			    { 2, 3, 4, 5, 6, 7, 8, 9 } };
+  return ret;
+}
+
+typedef struct { vec_short_8_t a; vec_short_8_t b; } hva2_vec_short_8_t;
+hva2_vec_short_8_t fun_hva2_vec_short_8 (void) {
+  hva2_vec_short_8_t ret = { { 2, 3, 4, 5 },
+			     { 3, 4, 5, 6 } };
+  return ret;
+}
+
+typedef struct { vec_int_8_t a; vec_int_8_t b; } hva2_vec_int_8_t;
+hva2_vec_int_8_t fun_hva2_vec_int_8 (void) {
+  hva2_vec_int_8_t ret = { { 3, 4 },
+			   { 4, 5 } };
+  return ret;
+}
+
+typedef struct { vec_long_8_t a; vec_long_8_t b; } hva2_vec_long_8_t;
+hva2_vec_long_8_t fun_hva2_vec_long_8 (void) {
+  hva2_vec_long_8_t ret = { { 5 },
+			    { 6 } };
+  return ret;
+}
+
+typedef struct { vec_float_8_t a; vec_float_8_t b; } hva2_vec_float_8_t;
+hva2_vec_float_8_t fun_hva2_vec_float_8 (void) {
+  hva2_vec_float_8_t ret = { { 1.5, 2.5 },
+			     { 2.5, 3.5 } };
+  return ret;
+}
+
+typedef struct { vec_double_8_t a; vec_double_8_t b; } hva2_vec_double_8_t;
+hva2_vec_double_8_t fun_hva2_vec_double_8 (void) {
+  hva2_vec_double_8_t ret = { { 3.5 },
+			      { 4.5 } };
+  return ret;
+}
+
+typedef struct { vec_char_16_t a; vec_char_16_t b; } hva2_vec_char_16_t;
+hva2_vec_char_16_t fun_hva2_vec_char_16_t (void) {
+  hva2_vec_char_16_t ret = { { 1, 2, 3, 4, 5, 6, 7, 8,
+			       9, 10, 11, 12, 13, 14, 15, 16 },
+			     { 2, 3, 4, 5, 6, 7, 8, 9,
+			       10, 11, 12, 13, 14, 15, 16, 17 } };
+  return ret;
+}
+
+typedef struct { vec_short_16_t a; vec_short_16_t b; } hva2_vec_short_16_t;
+hva2_vec_short_16_t fun_hva2_vec_short_16_t (void) {
+  hva2_vec_short_16_t ret = { { 2, 3, 4, 5, 6, 7, 8, 9 },
+			      { 3, 4, 5, 6, 7, 8, 9, 10 } };
+  return ret;
+}
+
+typedef struct { vec_int_16_t a; vec_int_16_t b; } hva2_vec_int_16_t;
+hva2_vec_int_16_t fun_hva2_vec_int_16_t (void) {
+  hva2_vec_int_16_t ret = { { 3, 4, 5, 6 },
+			    { 4, 5, 6, 7 } };
+  return ret;
+}
+
+typedef struct { vec_long_16_t a; vec_long_16_t b; } hva2_vec_long_16_t;
+hva2_vec_long_16_t fun_hva2_vec_long_16_t (void) {
+  hva2_vec_long_16_t ret = { { 4, 5 },
+			     { 5, 6 } };
+  return ret;
+}
+
+typedef struct { vec_int128_16_t a; vec_int128_16_t b; } hva2_vec_int128_16_t;
+hva2_vec_int128_16_t fun_hva2_vec_int128_16_t (void) {
+  hva2_vec_int128_16_t ret = { { 6 },
+			       { 7 } };
+  return ret;
+}
+
+typedef struct { vec_float_16_t a; vec_float_16_t b; } hva2_vec_float_16_t;
+hva2_vec_float_16_t fun_hva2_vec_float_16_t (void) {
+  hva2_vec_float_16_t ret = { { 1.5, 2.5, 3.5, 4.5 },
+			      { 2.5, 3.5, 4.5, 5.5 } };
+  return ret;
+}
+
+typedef struct { vec_double_16_t a; vec_double_16_t b; } hva2_vec_double_16_t;
+hva2_vec_double_16_t fun_hva2_vec_double_16_t (void) {
+  hva2_vec_double_16_t ret = { { 2.5, 3.5 },
+			       { 3.5, 4.5 } };
+  return ret;
+}
+
+#ifdef FLOAT128
+typedef struct { vec_float128_16_t a; vec_float128_16_t b; } hva2_vec_float128_16_t;
+hva2_vec_float128_16_t fun_hva2_vec_float128_16_t (void) {
+  hva2_vec_float128_16_t ret = { { 4.5 },
+				 { 5.5 } };
+  return ret;
+}
+#endif
+
+// Homogeneous vector aggregates of 3 elements.
+
+typedef struct { vec_char_8_t a; vec_char_8_t b; vec_char_8_t c; } hva3_vec_char_8_t;
+hva3_vec_char_8_t fun_hva3_vec_char_8 (void) {
+  hva3_vec_char_8_t ret = { { 1, 2, 3, 4, 5, 6, 7, 8 },
+			    { 2, 3, 4, 5, 6, 7, 8, 9 },
+			    { 3, 4, 5, 6, 7, 8, 9, 10 } };
+  return ret;
+}
+
+typedef struct { vec_short_8_t a; vec_short_8_t b; vec_short_8_t c; } hva3_vec_short_8_t;
+hva3_vec_short_8_t fun_hva3_vec_short_8 (void) {
+  hva3_vec_short_8_t ret = { { 2, 3, 4, 5 },
+			     { 3, 4, 5, 6 },
+			     { 4, 5, 6, 7 } };
+  return ret;
+}
+
+typedef struct { vec_int_8_t a; vec_int_8_t b; vec_int_8_t c; } hva3_vec_int_8_t;
+hva3_vec_int_8_t fun_hva3_vec_int_8 (void) {
+  hva3_vec_int_8_t ret = { { 3, 4 },
+			   { 4, 5 },
+			   { 5, 6 } };
+  return ret;
+}
+
+typedef struct { vec_long_8_t a; vec_long_8_t b; vec_long_8_t c; } hva3_vec_long_8_t;
+hva3_vec_long_8_t fun_hva3_vec_long_8 (void) {
+  hva3_vec_long_8_t ret = { { 5 },
+			    { 6 },
+			    { 7 } };
+  return ret;
+}
+
+typedef struct { vec_float_8_t a; vec_float_8_t b; vec_float_8_t c; } hva3_vec_float_8_t;
+hva3_vec_float_8_t fun_hva3_vec_float_8 (void) {
+  hva3_vec_float_8_t ret = { { 1.5, 2.5 },
+			     { 2.5, 3.5 },
+			     { 3.5, 4.5 } };
+  return ret;
+}
+
+typedef struct { vec_double_8_t a; vec_double_8_t b; vec_double_8_t c; } hva3_vec_double_8_t;
+hva3_vec_double_8_t fun_hva3_vec_double_8 (void) {
+  hva3_vec_double_8_t ret = { { 3.5 },
+			      { 4.5 },
+			      { 5.5 } };
+  return ret;
+}
+
+typedef struct { vec_char_16_t a; vec_char_16_t b; vec_char_16_t c; } hva3_vec_char_16_t;
+hva3_vec_char_16_t fun_hva3_vec_char_16_t (void) {
+  hva3_vec_char_16_t ret = { { 1, 2, 3, 4, 5, 6, 7, 8,
+			       9, 10, 11, 12, 13, 14, 15, 16 },
+			     { 2, 3, 4, 5, 6, 7, 8, 9,
+			       10, 11, 12, 13, 14, 15, 16, 17 },
+			     { 3, 4, 5, 6, 7, 8, 9, 10,
+			       11, 12, 13, 14, 15, 16, 17, 18 } };
+  return ret;
+}
+
+typedef struct { vec_short_16_t a; vec_short_16_t b; vec_short_16_t c; } hva3_vec_short_16_t;
+hva3_vec_short_16_t fun_hva3_vec_short_16_t (void) {
+  hva3_vec_short_16_t ret = { { 2, 3, 4, 5, 6, 7, 8, 9 },
+			      { 3, 4, 5, 6, 7, 8, 9, 10 },
+			      { 4, 5, 6, 7, 8, 9, 10, 11 } };
+  return ret;
+}
+
+typedef struct { vec_int_16_t a; vec_int_16_t b; vec_int_16_t c; } hva3_vec_int_16_t;
+hva3_vec_int_16_t fun_hva3_vec_int_16_t (void) {
+  hva3_vec_int_16_t ret = { { 3, 4, 5, 6 },
+			    { 4, 5, 6, 7 },
+			    { 5, 6, 7, 8 } };
+  return ret;
+}
+
+typedef struct { vec_long_16_t a; vec_long_16_t b; vec_long_16_t c; } hva3_vec_long_16_t;
+hva3_vec_long_16_t fun_hva3_vec_long_16_t (void) {
+  hva3_vec_long_16_t ret = { { 3, 4 },
+			     { 4, 5 },
+			     { 5, 6 } };
+  return ret;
+}
+
+typedef struct { vec_int128_16_t a; vec_int128_16_t b; vec_int128_16_t c; } hva3_vec_int128_16_t;
+hva3_vec_int128_16_t fun_hva3_vec_int128_16_t (void) {
+  hva3_vec_int128_16_t ret = { { 6 },
+			       { 7 },
+			       { 8 } };
+  return ret;
+}
+
+typedef struct { vec_float_16_t a; vec_float_16_t b; vec_float_16_t c; } hva3_vec_float_16_t;
+hva3_vec_float_16_t fun_hva3_vec_float_16_t (void) {
+  hva3_vec_float_16_t ret = { { 1.5, 2.5, 3.5, 4.5 },
+			      { 2.5, 3.5, 4.5, 5.5 },
+			      { 3.5, 4.5, 5.5, 6.5 } };
+  return ret;
+}
+
+typedef struct { vec_double_16_t a; vec_double_16_t b; vec_double_16_t c; } hva3_vec_double_16_t;
+hva3_vec_double_16_t fun_hva3_vec_double_16_t (void) {
+  hva3_vec_double_16_t ret = { { 2.5, 3.5 },
+			       { 3.5, 4.5 },
+			       { 4.5, 5.5 } };
+  return ret;
+}
+
+#ifdef FLOAT128
+typedef struct { vec_float128_16_t a; vec_float128_16_t b; vec_float128_16_t c; } hva3_vec_float128_16_t;
+hva3_vec_float128_16_t fun_hva3_vec_float128_16_t (void) {
+  hva3_vec_float128_16_t ret = { { 4.5 },
+				 { 5.5 },
+				 { 6.5 } };
+  return ret;
+}
+#endif
+
+// Homogeneous vector aggregates of 3 elements.
+
+typedef struct { vec_char_8_t a; vec_char_8_t b; vec_char_8_t c; vec_char_8_t d; } hva4_vec_char_8_t;
+hva4_vec_char_8_t fun_hva4_vec_char_8 (void) {
+  hva4_vec_char_8_t ret = { { 1, 2, 3, 4, 5, 6, 7, 8 },
+			    { 2, 3, 4, 5, 6, 7, 8, 9 },
+			    { 3, 4, 5, 6, 7, 8, 9, 10 },
+			    { 4, 5, 6, 7, 8, 9, 10, 11 } };
+  return ret;
+}
+
+typedef struct { vec_short_8_t a; vec_short_8_t b; vec_short_8_t c; vec_short_8_t d; } hva4_vec_short_8_t;
+hva4_vec_short_8_t fun_hva4_vec_short_8 (void) {
+  hva4_vec_short_8_t ret = { { 2, 3, 4, 5 },
+			     { 3, 4, 5, 6 },
+			     { 4, 5, 6, 7 },
+			     { 5, 6, 7, 8 } };
+  return ret;
+}
+
+typedef struct { vec_int_8_t a; vec_int_8_t b; vec_int_8_t c; vec_int_8_t d; } hva4_vec_int_8_t;
+hva4_vec_int_8_t fun_hva4_vec_int_8 (void) {
+  hva4_vec_int_8_t ret = { { 3, 4 },
+			   { 4, 5 },
+			   { 5, 6 },
+			   { 6, 7 } };
+  return ret;
+}
+
+typedef struct { vec_long_8_t a; vec_long_8_t b; vec_long_8_t c; vec_long_8_t d; } hva4_vec_long_8_t;
+hva4_vec_long_8_t fun_hva4_vec_long_8 (void) {
+  hva4_vec_long_8_t ret = { { 5 },
+			    { 6 },
+			    { 7 },
+			    { 8 } };
+  return ret;
+}
+
+typedef struct { vec_float_8_t a; vec_float_8_t b; vec_float_8_t c; vec_float_8_t d; } hva4_vec_float_8_t;
+hva4_vec_float_8_t fun_hva4_vec_float_8 (void) {
+  hva4_vec_float_8_t ret = { { 1.5, 2.5 },
+			     { 2.5, 3.5 },
+			     { 3.5, 4.5 },
+			     { 4.5, 5.5 } };
+  return ret;
+}
+
+typedef struct { vec_double_8_t a; vec_double_8_t b; vec_double_8_t c; vec_double_8_t d; } hva4_vec_double_8_t;
+hva4_vec_double_8_t fun_hva4_vec_double_8 (void) {
+  hva4_vec_double_8_t ret = { { 3.5 },
+			      { 4.5 },
+			      { 5.5 },
+			      { 6.5 } };
+  return ret;
+}
+
+typedef struct { vec_char_16_t a; vec_char_16_t b; vec_char_16_t c; vec_char_16_t d; } hva4_vec_char_16_t;
+hva4_vec_char_16_t fun_hva4_vec_char_16_t (void) {
+  hva4_vec_char_16_t ret = { { 1, 2, 3, 4, 5, 6, 7, 8,
+			       9, 10, 11, 12, 13, 14, 15, 16 },
+			     { 2, 3, 4, 5, 6, 7, 8, 9,
+			       10, 11, 12, 13, 14, 15, 16, 17 },
+			     { 3, 4, 5, 6, 7, 8, 9, 10,
+			       11, 12, 13, 14, 15, 16, 17, 18 },
+			     { 4, 5, 6, 7, 8, 9, 10, 11,
+			       12, 13, 14, 15, 16, 17, 18, 19 } };
+  return ret;
+}
+
+typedef struct { vec_short_16_t a; vec_short_16_t b; vec_short_16_t c; vec_short_16_t d; } hva4_vec_short_16_t;
+hva4_vec_short_16_t fun_hva4_vec_short_16_t (void) {
+  hva4_vec_short_16_t ret = { { 2, 3, 4, 5, 6, 7, 8, 9 },
+			      { 3, 4, 5, 6, 7, 8, 9, 10 },
+			      { 4, 5, 6, 7, 8, 9, 10, 11 },
+			      { 5, 6, 7, 8, 9, 10, 11, 12 } };
+  return ret;
+}
+
+typedef struct { vec_int_16_t a; vec_int_16_t b; vec_int_16_t c; vec_int_16_t d; } hva4_vec_int_16_t;
+hva4_vec_int_16_t fun_hva4_vec_int_16_t (void) {
+  hva4_vec_int_16_t ret = { { 3, 4, 5, 6 },
+			    { 4, 5, 6, 7 },
+			    { 5, 6, 7, 8 },
+			    { 6, 7, 8, 9 } };
+  return ret;
+}
+
+typedef struct { vec_long_16_t a; vec_long_16_t b; vec_long_16_t c; vec_long_16_t d; } hva4_vec_long_16_t;
+hva4_vec_long_16_t fun_hva4_vec_long_16_t (void) {
+  hva4_vec_long_16_t ret = { { 3, 4 },
+			     { 4, 5 },
+			     { 5, 6 },
+			     { 6, 7 } };
+  return ret;
+}
+
+typedef struct { vec_int128_16_t a; vec_int128_16_t b; vec_int128_16_t c; vec_int128_16_t d; } hva4_vec_int128_16_t;
+hva4_vec_int128_16_t fun_hva4_vec_int128_16_t (void) {
+  hva4_vec_int128_16_t ret = { { 6 },
+			       { 7 },
+			       { 8 },
+			       { 9 } };
+  return ret;
+}
+
+typedef struct { vec_float_16_t a; vec_float_16_t b; vec_float_16_t c; vec_float_16_t d; } hva4_vec_float_16_t;
+hva4_vec_float_16_t fun_hva4_vec_float_16_t (void) {
+  hva4_vec_float_16_t ret = { { 1.5, 2.5, 3.5, 4.5 },
+			      { 2.5, 3.5, 4.5, 5.5 },
+			      { 3.5, 4.5, 5.5, 6.5 },
+			      { 4.5, 5.5, 6.5, 7.5 } };
+  return ret;
+}
+
+typedef struct { vec_double_16_t a; vec_double_16_t b; vec_double_16_t c; vec_double_16_t d; } hva4_vec_double_16_t;
+hva4_vec_double_16_t fun_hva4_vec_double_16_t (void) {
+  hva4_vec_double_16_t ret = { { 2.5, 3.5 },
+			       { 3.5, 4.5 },
+			       { 4.5, 5.5 },
+			       { 5.5, 6.5 } };
+  return ret;
+}
+
+#ifdef FLOAT128
+typedef struct { vec_float128_16_t a; vec_float128_16_t b; vec_float128_16_t c; vec_float128_16_t d; } hva4_vec_float128_16_t;
+hva4_vec_float128_16_t fun_hva4_vec_float128_16_t (void) {
+  hva4_vec_float128_16_t ret = { { 4.5 },
+				 { 5.5 },
+				 { 6.5 },
+				 { 7.5 } };
+  return ret;
+}
+#endif
+
+// Mixed HFA.
+typedef struct { float _Complex a; float b; } mixed_hfa3_cff_t;
+mixed_hfa3_cff_t fun_mixed_hfa3_cff (void) {
+  mixed_hfa3_cff_t ret = { 1.5 + 2.5i, 3.5 };
+  return ret;
+}
+
+typedef struct { double _Complex a; double b; } mixed_hfa3_cdd_t;
+mixed_hfa3_cdd_t fun_mixed_hfa3_cdd (void) {
+  mixed_hfa3_cdd_t ret = { 1.5 + 2.5i, 3.5 };
+  return ret;
+}
+
+typedef struct { long double _Complex a; long double b; } mixed_hfa3_cldld_t;
+mixed_hfa3_cldld_t fun_mixed_hfa3_cldld (void) {
+  mixed_hfa3_cldld_t ret = { 1.5 + 2.5i, 3.5 };
+  return ret;
+}
+
+typedef struct { float b; float _Complex a; } mixed_hfa3_fcf_t;
+mixed_hfa3_fcf_t fun_mixed_hfa3_fcf (void) {
+  mixed_hfa3_fcf_t ret = { 3.5, 1.5 + 2.5i };
+  return ret;
+}
+
+typedef struct { double b; double _Complex a; } mixed_hfa3_dcd_t;
+mixed_hfa3_dcd_t fun_mixed_hfa3_dcd (void) {
+  mixed_hfa3_dcd_t ret = { 3.5, 1.5 + 2.5i };
+  return ret;
+}
+
+typedef struct { long double b; long double _Complex a; } mixed_hfa3_ldcld_t;
+mixed_hfa3_ldcld_t fun_mixed_hfa3_ldcld (void) {
+  mixed_hfa3_ldcld_t ret = { 3.5, 1.5 + 2.5i };
+  return ret;
+}
+
+typedef struct { vec_float_8_t a; vec_short_8_t b; } mixed_hfa2_fltsht_t;
+mixed_hfa2_fltsht_t fun_mixed_hfa2_fltsht_t (void) {
+  mixed_hfa2_fltsht_t ret = { { 3.5, 4.5 }, { 1, 2, 3, 4 } };
+  return ret;
+}
+
+int main(int argc, char *argv[])
+{
+  return 0;
+}
diff --git a/third_party/elfutils/tests/funcretval_test_aarch64.bz2 b/third_party/elfutils/tests/funcretval_test_aarch64.bz2
new file mode 100755
index 0000000..5494e10
--- /dev/null
+++ b/third_party/elfutils/tests/funcretval_test_aarch64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/funcscopes.c b/third_party/elfutils/tests/funcscopes.c
new file mode 100644
index 0000000..9c90185
--- /dev/null
+++ b/third_party/elfutils/tests/funcscopes.c
@@ -0,0 +1,195 @@
+/* Test program for dwarf_getscopes.
+   Copyright (C) 2005, 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+#include <argp.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <error.h>
+#include <string.h>
+#include <fnmatch.h>
+
+
+static void
+paddr (const char *prefix, Dwarf_Addr addr, Dwfl_Line *line)
+{
+  const char *src;
+  int lineno, linecol;
+  if (line != NULL
+      && (src = dwfl_lineinfo (line, &addr, &lineno, &linecol,
+			       NULL, NULL)) != NULL)
+    {
+      if (linecol != 0)
+	printf ("%s%#" PRIx64 " (%s:%d:%d)",
+		prefix, addr, src, lineno, linecol);
+      else
+	printf ("%s%#" PRIx64 " (%s:%d)",
+		prefix, addr, src, lineno);
+    }
+  else
+    printf ("%s%#" PRIx64, prefix, addr);
+}
+
+
+static void
+print_vars (unsigned int indent, Dwarf_Die *die)
+{
+  Dwarf_Die child;
+  if (dwarf_child (die, &child) == 0)
+    do
+      switch (dwarf_tag (&child))
+	{
+	case DW_TAG_variable:
+	case DW_TAG_formal_parameter:
+	  printf ("%*s%-30s[%6" PRIx64 "]\n", indent, "",
+		  dwarf_diename (&child),
+		  (uint64_t) dwarf_dieoffset (&child));
+	  break;
+	default:
+	  break;
+	}
+    while (dwarf_siblingof (&child, &child) == 0);
+
+  Dwarf_Attribute attr_mem;
+  Dwarf_Die origin;
+  if (dwarf_hasattr (die, DW_AT_abstract_origin)
+      && dwarf_formref_die (dwarf_attr (die, DW_AT_abstract_origin, &attr_mem),
+			    &origin) != NULL
+      && dwarf_child (&origin, &child) == 0)
+    do
+      switch (dwarf_tag (&child))
+	{
+	case DW_TAG_variable:
+	case DW_TAG_formal_parameter:
+	  printf ("%*s%s (abstract)\n", indent, "",
+		  dwarf_diename (&child));
+	  break;
+	default:
+	  break;
+	}
+    while (dwarf_siblingof (&child, &child) == 0);
+}
+
+
+#define INDENT 4
+
+struct args
+{
+  Dwfl *dwfl;
+  Dwarf_Die *cu;
+  Dwarf_Addr dwbias;
+  char **argv;
+};
+
+static int
+handle_function (Dwarf_Die *funcdie, void *arg)
+{
+  struct args *a = arg;
+
+  const char *name = dwarf_diename (funcdie);
+  char **argv = a->argv;
+  if (argv[0] != NULL)
+    {
+      bool match;
+      do
+	match = fnmatch (*argv, name, 0) == 0;
+      while (!match && *++argv);
+      if (!match)
+	return 0;
+    }
+
+  Dwarf_Die *scopes;
+  int n = dwarf_getscopes_die (funcdie, &scopes);
+  if (n <= 0)
+    error (EXIT_FAILURE, 0, "dwarf_getscopes_die: %s", dwarf_errmsg (-1));
+  else
+    {
+      Dwarf_Addr start, end;
+      const char *fname;
+      const char *modname = dwfl_module_info (dwfl_cumodule (a->cu), NULL,
+					      &start, &end,
+					      NULL, NULL,
+					      &fname, NULL);
+      if (modname == NULL)
+	error (EXIT_FAILURE, 0, "dwfl_module_info: %s", dwarf_errmsg (-1));
+      if (modname[0] == '\0')
+	modname = fname;
+      printf ("%s: %#" PRIx64 " .. %#" PRIx64 "\n", modname, start, end);
+
+      unsigned int indent = 0;
+      while (n-- > 0)
+	{
+	  Dwarf_Die *const die = &scopes[n];
+
+	  indent += INDENT;
+	  printf ("%*s%s (%#x)", indent, "",
+		  dwarf_diename (die) ?: "<unnamed>",
+		  dwarf_tag (die));
+
+	  Dwarf_Addr lowpc, highpc;
+	  if (dwarf_lowpc (die, &lowpc) == 0
+	      && dwarf_highpc (die, &highpc) == 0)
+	    {
+	      lowpc += a->dwbias;
+	      highpc += a->dwbias;
+	      Dwfl_Line *loline = dwfl_getsrc (a->dwfl, lowpc);
+	      Dwfl_Line *hiline = dwfl_getsrc (a->dwfl, highpc - 1);
+	      paddr (": ", lowpc, loline);
+	      if (highpc != lowpc)
+		paddr (" .. ", highpc - 1, hiline == loline ? NULL : hiline);
+	    }
+	  puts ("");
+
+	  print_vars (indent + INDENT, die);
+	}
+      free (scopes);
+    }
+
+  return 0;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  struct args a = { .dwfl = NULL, .cu = NULL };
+
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining,
+		     &a.dwfl);
+  assert (a.dwfl != NULL);
+  a.argv = &argv[remaining];
+
+  int result = 0;
+
+  while ((a.cu = dwfl_nextcu (a.dwfl, a.cu, &a.dwbias)) != NULL)
+    dwarf_getfuncs (a.cu, &handle_function, &a, 0);
+
+  dwfl_end (a.dwfl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/get-aranges.c b/third_party/elfutils/tests/get-aranges.c
new file mode 100644
index 0000000..7f85cda
--- /dev/null
+++ b/third_party/elfutils/tests/get-aranges.c
@@ -0,0 +1,142 @@
+/* Copyright (C) 2002, 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <libelf.h>
+#include ELFUTILS_HEADER(dw)
+#include <stdio.h>
+#include <unistd.h>
+
+
+static const Dwarf_Addr testaddr[] =
+{
+  0x804842b, 0x804842c, 0x804843c, 0x8048459, 0x804845a,
+  0x804845b, 0x804845c, 0x8048460, 0x8048465, 0x8048466,
+  0x8048467, 0x8048468, 0x8048470, 0x8048471, 0x8048472
+};
+#define ntestaddr (sizeof (testaddr) / sizeof (testaddr[0]))
+
+
+int
+main (int argc, char *argv[])
+{
+  int result = 0;
+  int cnt;
+
+  for (cnt = 1; cnt < argc; ++cnt)
+    {
+      int fd = open (argv[cnt], O_RDONLY);
+
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if (dbg == NULL)
+	{
+	  printf ("%s not usable\n", argv[cnt]);
+	  result = 1;
+	  close (fd);
+	  continue;
+	}
+
+      Dwarf_Aranges *aranges;
+      size_t naranges;
+      if (dwarf_getaranges (dbg, &aranges, &naranges) != 0)
+	printf ("%s: cannot get aranges\n", argv[cnt]);
+      else
+	{
+	  for (size_t i = 0; i < ntestaddr; ++i)
+	    {
+	      Dwarf_Arange *found;
+
+	      found = dwarf_getarange_addr (aranges, testaddr[i]);
+	      if (found != NULL)
+		{
+		  Dwarf_Off cu_offset;
+
+		  if (dwarf_getarangeinfo (found, NULL, NULL, &cu_offset) != 0)
+		    {
+		      puts ("failed to get CU die offset");
+		      result = 1;
+		    }
+		  else
+		    {
+		      const char *cuname;
+		      Dwarf_Die cu_die;
+
+		      if (dwarf_offdie (dbg, cu_offset, &cu_die) == NULL
+			  || (cuname = dwarf_diename (&cu_die)) == NULL)
+			{
+			  puts ("failed to get CU die");
+			  result = 1;
+			}
+		      else
+			printf ("CU name: \"%s\"\n", cuname);
+		    }
+		}
+	      else
+		printf ("%#llx: not in range\n",
+			(unsigned long long int) testaddr[i]);
+	    }
+
+	  for (size_t i = 0; i < naranges; ++i)
+	    {
+	      Dwarf_Arange *arange = dwarf_onearange (aranges, i);
+	      if (arange == NULL)
+		{
+		  printf ("cannot get arange %zu: %s\n", i, dwarf_errmsg (-1));
+		  break;
+		}
+
+	      Dwarf_Addr start;
+	      Dwarf_Word length;
+	      Dwarf_Off cu_offset;
+
+	      if (dwarf_getarangeinfo (arange, &start, &length, &cu_offset)
+		  != 0)
+		{
+		  printf ("cannot get info from aranges[%zu]\n", i);
+		  result = 1;
+		}
+	      else
+		{
+		  printf (" [%2zu] start: %#llx, length: %llu, cu: %llu\n",
+			  i, (unsigned long long int) start,
+			  (unsigned long long int) length,
+			  (unsigned long long int) cu_offset);
+
+		  const char *cuname;
+		  Dwarf_Die cu_die;
+		  if (dwarf_offdie (dbg, cu_offset, &cu_die) == NULL
+		      || (cuname = dwarf_diename (&cu_die)) == NULL)
+		    {
+		      puts ("failed to get CU die");
+		      result = 1;
+		    }
+		  else
+		    printf ("CU name: \"%s\"\n", cuname);
+		}
+	    }
+	}
+
+      dwarf_end (dbg);
+      close (fd);
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/get-files.c b/third_party/elfutils/tests/get-files.c
new file mode 100644
index 0000000..0409173
--- /dev/null
+++ b/third_party/elfutils/tests/get-files.c
@@ -0,0 +1,107 @@
+/* Copyright (C) 2002, 2004, 2005, 2007 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <libelf.h>
+#include ELFUTILS_HEADER(dw)
+#include <stdio.h>
+#include <unistd.h>
+
+
+int
+main (int argc, char *argv[])
+{
+  int result = 0;
+  int cnt;
+
+  for (cnt = 1; cnt < argc; ++cnt)
+    {
+      int fd = open (argv[cnt], O_RDONLY);
+
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if (dbg == NULL)
+	{
+	  printf ("%s not usable\n", argv[cnt]);
+	  result = 1;
+	  if (fd != -1)
+	    close (fd);
+	  continue;
+	}
+
+      Dwarf_Off o = 0;
+      Dwarf_Off ncu;
+      Dwarf_Off ao;
+      size_t cuhl;
+      uint8_t asz;
+      uint8_t osz;
+      while (dwarf_nextcu (dbg, o, &ncu, &cuhl, &ao, &asz, &osz) == 0)
+	{
+	  printf ("cuhl = %zu, o = %llu, asz = %hhu, osz = %hhu, ncu = %llu\n",
+		  cuhl, (unsigned long long int) ao,
+		  asz, osz, (unsigned long long int) ncu);
+
+	  Dwarf_Die die_mem;
+	  Dwarf_Die *die = dwarf_offdie (dbg, o + cuhl, &die_mem);
+	  if (die == NULL)
+	    {
+	      printf ("%s: cannot get CU die\n", argv[cnt]);
+	      result = 1;
+	      break;
+	    }
+
+	  Dwarf_Files *files;
+	  size_t nfiles;
+	  if (dwarf_getsrcfiles (die, &files, &nfiles) != 0)
+	    {
+	      printf ("%s: cannot get files\n", argv[cnt]);
+	      result = 1;
+	      break;
+	    }
+
+	  const char *const *dirs;
+	  size_t ndirs;
+	  if (dwarf_getsrcdirs (files, &dirs, &ndirs) != 0)
+	    {
+	      printf ("%s: cannot get include directories\n", argv[cnt]);
+	      result = 1;
+	      break;
+	    }
+
+	  if (dirs[0] == NULL)
+	    puts (" dirs[0] = (null)");
+	  else
+	    printf (" dirs[0] = \"%s\"\n", dirs[0]);
+	  for (size_t i = 1; i < ndirs; ++i)
+	    printf (" dirs[%zu] = \"%s\"\n", i, dirs[i]);
+
+	  for (size_t i = 0; i < nfiles; ++i)
+	    printf (" file[%zu] = \"%s\"\n", i,
+		    dwarf_filesrc (files, i, NULL, NULL));
+
+	  o = ncu;
+	}
+
+      dwarf_end (dbg);
+      close (fd);
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/get-lines.c b/third_party/elfutils/tests/get-lines.c
new file mode 100644
index 0000000..188d016
--- /dev/null
+++ b/third_party/elfutils/tests/get-lines.c
@@ -0,0 +1,160 @@
+/* Copyright (C) 2002, 2004 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include ELFUTILS_HEADER(dw)
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+int
+main (int argc, char *argv[])
+{
+  int result = 0;
+  int cnt;
+
+  for (cnt = 1; cnt < argc; ++cnt)
+    {
+      int fd = open (argv[cnt], O_RDONLY);
+
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if  (dbg == NULL)
+	{
+	  printf ("%s not usable: %s\n", argv[cnt], dwarf_errmsg (-1));
+	  close  (fd);
+	  continue;
+	}
+
+      Dwarf_Off cuoff = 0;
+      Dwarf_Off old_cuoff = 0;
+      size_t hsize;
+      Dwarf_Off ao;
+      uint8_t asz;
+      uint8_t osz;
+      while (dwarf_nextcu (dbg, cuoff, &cuoff, &hsize, &ao, &asz, &osz) == 0)
+	{
+	  printf ("cuhl = %zu, o = %llu, asz = %hhu, osz = %hhu, ncu = %llu\n",
+		  hsize, (unsigned long long int) ao,
+		  asz, osz, (unsigned long long int) cuoff);
+
+	  /* Get the DIE for the CU.  */
+	  Dwarf_Die die;
+ 	  if (dwarf_offdie (dbg, old_cuoff + hsize, &die) == NULL)
+	    {
+	      /* Something went wrong.  */
+	      printf ("%s: cannot get CU die\n", argv[cnt]);
+	      result = 1;
+	      break;
+	    }
+	  old_cuoff = cuoff;
+
+	  Dwarf_Lines *lb;
+	  size_t nlb;
+	  if (dwarf_getsrclines (&die, &lb, &nlb) != 0)
+	    {
+	      printf ("%s: cannot get lines\n", argv[cnt]);
+	      result = 1;
+	      break;
+	    }
+
+	  printf (" %zu lines\n", nlb);
+
+	  for (size_t i = 0; i < nlb; ++i)
+	    {
+	      Dwarf_Line *l = dwarf_onesrcline (lb, i);
+	      if (l == NULL)
+		{
+		  printf ("%s: cannot get individual line\n", argv[cnt]);
+		  result = 1;
+		  break;
+		}
+
+	      Dwarf_Addr addr;
+	      if (dwarf_lineaddr (l, &addr) != 0)
+		addr = 0;
+	      const char *file = dwarf_linesrc (l, NULL, NULL);
+	      int line;
+	      if (dwarf_lineno (l, &line) != 0)
+		line = 0;
+
+	      printf ("%" PRIx64 ": %s:%d:", (uint64_t) addr,
+		      file ?: "???", line);
+
+	      /* Getting the file path through the Dwarf_Files should
+		 result in the same path.  */
+	      Dwarf_Files *files;
+	      size_t idx;
+	      if (dwarf_line_file (l, &files, &idx) != 0)
+		{
+		  printf ("%s: cannot get file from line (%zd): %s\n",
+			  argv[cnt], i, dwarf_errmsg (-1));
+		  result = 1;
+		  break;
+		}
+	      const char *path = dwarf_filesrc (files, idx, NULL, NULL);
+	      if ((path == NULL && file != NULL)
+		  || (path != NULL && file == NULL)
+		  || (strcmp (file, path) != 0))
+		{
+		  printf ("%s: line %zd srcline (%s) != file srcline (%s)\n",
+			  argv[cnt], i, file ?: "???", path ?: "???");
+		  result = 1;
+		  break;
+		}
+
+	      int column;
+	      if (dwarf_linecol (l, &column) != 0)
+		column = 0;
+	      if (column >= 0)
+		printf ("%d:", column);
+
+	      bool is_stmt;
+	      if (dwarf_linebeginstatement (l, &is_stmt) != 0)
+		is_stmt = false;
+	      bool end_sequence;
+	      if (dwarf_lineendsequence (l, &end_sequence) != 0)
+		end_sequence = false;
+	      bool basic_block;
+	      if (dwarf_lineblock (l, &basic_block) != 0)
+		basic_block = false;
+	      bool prologue_end;
+	      if (dwarf_lineprologueend (l, &prologue_end) != 0)
+		prologue_end = false;
+	      bool epilogue_begin;
+	      if (dwarf_lineepiloguebegin (l, &epilogue_begin) != 0)
+		epilogue_begin = false;
+
+	      printf (" is_stmt:%s, end_seq:%s, bb:%s, prologue:%s, epilogue:%s\n",
+		      is_stmt ? "yes" : "no", end_sequence ? "yes" : "no",
+		      basic_block ? "yes" : "no", prologue_end  ? "yes" : "no",
+		      epilogue_begin ? "yes" : "no");
+	    }
+	}
+
+      dwarf_end (dbg);
+      close (fd);
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/get-pubnames.c b/third_party/elfutils/tests/get-pubnames.c
new file mode 100644
index 0000000..4777f49
--- /dev/null
+++ b/third_party/elfutils/tests/get-pubnames.c
@@ -0,0 +1,98 @@
+/* Copyright (C) 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <libelf.h>
+#include ELFUTILS_HEADER(dw)
+#include <stdio.h>
+#include <unistd.h>
+
+
+static int globcnt;
+
+static int
+callback (Dwarf *dbg, Dwarf_Global *gl, void *arg __attribute__ ((unused)))
+{
+  int result = DWARF_CB_OK;
+
+  printf (" [%2d] \"%s\", die: %llu, cu: %llu\n",
+	  globcnt++, gl->name, (unsigned long long int) gl->die_offset,
+	  (unsigned long long int) gl->cu_offset);
+
+  Dwarf_Die cu_die;
+  const char *cuname;
+  if (dwarf_offdie (dbg, gl->cu_offset, &cu_die) == NULL
+      || (cuname = dwarf_diename (&cu_die)) == NULL)
+    {
+      puts ("failed to get CU die");
+      result = DWARF_CB_ABORT;
+    }
+  else
+    printf ("CU name: \"%s\"\n", cuname);
+
+  const char *diename;
+  Dwarf_Die die;
+  if (dwarf_offdie (dbg, gl->die_offset, &die) == NULL
+      || (diename = dwarf_diename (&die)) == NULL)
+    {
+      puts ("failed to get object die");
+      result = DWARF_CB_ABORT;
+    }
+  else
+    printf ("object name: \"%s\"\n", diename);
+
+  return result;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  int result = 0;
+  int cnt;
+
+  for (cnt = 1; cnt < argc; ++cnt)
+    {
+      int fd = open (argv[cnt], O_RDONLY);
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if (dbg == NULL)
+	{
+	  printf ("%s not usable: %s\n", argv[cnt], dwarf_errmsg (-1));
+	  result = 1;
+	  close (fd);
+	  continue;
+	}
+
+      globcnt = 0;
+
+      if (dwarf_getpubnames (dbg, callback, NULL, 0) != 0)
+	{
+	  printf ("dwarf_get_pubnames didn't return zero: %s\n",
+		  dwarf_errmsg (-1));
+	  result = 1;
+	}
+
+      dwarf_end (dbg);
+      close (fd);
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/getsrc_die.c b/third_party/elfutils/tests/getsrc_die.c
new file mode 100644
index 0000000..055aede
--- /dev/null
+++ b/third_party/elfutils/tests/getsrc_die.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include ELFUTILS_HEADER(dw)
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+int
+main (int argc, char *argv[])
+{
+  /* file addr+ */
+  int fd = open (argv[1], O_RDONLY);
+  Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+  if  (dbg == NULL)
+    error (-1, 0, "dwarf_begin (%s): %s\n", argv[1], dwarf_errmsg (-1));
+
+  for (int i = 2; i < argc; i++)
+    {
+      Dwarf_Addr addr;
+      char *endptr;
+      Dwarf_Die cudie;
+      Dwarf_Line *line;
+
+      errno = 0;
+      addr = strtoull (argv[i], &endptr, 16);
+      if (errno != 0)
+	error (-1, errno, "Cannot parrse '%s'", argv[1]);
+
+      if (dwarf_addrdie (dbg, addr, &cudie) == NULL)
+	error (-1, 0, "dwarf_addrdie (%s): %s", argv[i], dwarf_errmsg (-1));
+
+      line = dwarf_getsrc_die (&cudie, addr);
+      if (line == NULL)
+	error (-1, 0, "dwarf_getsrc_die (%s): %s", argv[i], dwarf_errmsg (-1));
+
+      const char *f = dwarf_linesrc (line, NULL, NULL);
+      int l;
+      if (dwarf_lineno (line, &l) != 0)
+	l = 0;
+
+      printf ("%s:%d\n", f ?: "???", l);
+    }
+
+  dwarf_end (dbg);
+  close (fd);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/hash.c b/third_party/elfutils/tests/hash.c
new file mode 100644
index 0000000..86b6ad8
--- /dev/null
+++ b/third_party/elfutils/tests/hash.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libelf.h>
+#include <stdio.h>
+
+
+static int
+check (const char *name, unsigned long int expected)
+{
+  unsigned long int actual = elf_hash (name);
+
+  return actual != expected;
+}
+
+
+int
+main (void)
+{
+  int status;
+
+  /* Check some names.  We know what the expected result is.  */
+  status = check ("_DYNAMIC", 165832675);
+  status |= check ("_GLOBAL_OFFSET_TABLE_", 102264335);
+
+  return status;
+}
diff --git a/third_party/elfutils/tests/hello_aarch64.ko.bz2 b/third_party/elfutils/tests/hello_aarch64.ko.bz2
new file mode 100644
index 0000000..431d89f
--- /dev/null
+++ b/third_party/elfutils/tests/hello_aarch64.ko.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/hello_i386.ko.bz2 b/third_party/elfutils/tests/hello_i386.ko.bz2
new file mode 100644
index 0000000..f89b292
--- /dev/null
+++ b/third_party/elfutils/tests/hello_i386.ko.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/hello_m68k.ko.bz2 b/third_party/elfutils/tests/hello_m68k.ko.bz2
new file mode 100644
index 0000000..2da3d17
--- /dev/null
+++ b/third_party/elfutils/tests/hello_m68k.ko.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/hello_ppc64.ko.bz2 b/third_party/elfutils/tests/hello_ppc64.ko.bz2
new file mode 100644
index 0000000..f4d3ff2
--- /dev/null
+++ b/third_party/elfutils/tests/hello_ppc64.ko.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/hello_s390.ko.bz2 b/third_party/elfutils/tests/hello_s390.ko.bz2
new file mode 100644
index 0000000..41525bf
--- /dev/null
+++ b/third_party/elfutils/tests/hello_s390.ko.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/hello_x86_64.ko.bz2 b/third_party/elfutils/tests/hello_x86_64.ko.bz2
new file mode 100644
index 0000000..ba06f91
--- /dev/null
+++ b/third_party/elfutils/tests/hello_x86_64.ko.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/lfs-symbols b/third_party/elfutils/tests/lfs-symbols
new file mode 100644
index 0000000..282a4ad
--- /dev/null
+++ b/third_party/elfutils/tests/lfs-symbols
@@ -0,0 +1,73 @@
+# Imported from lintian/data/binaries/lfs-symbols
+#
+# Exceptions:
+#   fts* - linux-kernel-modules.c is careful with FTS_NOSTAT
+
+# Manually maintained list of non-lfs symbols
+#
+# List was found by grepping around in /usr/include on an i386 system
+# with build-essential installed
+#
+# Please keep this sorted by key.
+
+__fxstat
+__fxstatat
+__lxstat
+__xstat
+aio_cancel
+aio_error
+aio_fsync
+aio_read
+aio_return
+aio_suspend
+aio_write
+alphasort
+creat
+fallocate
+fgetpos
+fopen
+freopen
+fseeko
+fsetpos
+fstatfs
+fstatvfs
+ftello
+ftruncate
+#fts_open
+#fts_read
+#fts_children
+#fts_set
+#fts_close
+ftw
+getdirentries
+getrlimit
+glob
+globfree
+lio_listio
+lockf
+lseek
+mkostemp
+mkostemps
+mkstemp
+mkstemps
+mmap
+nftw
+open
+openat
+posix_fadvise
+posix_fallocate
+pread
+preadv
+prlimit
+pwrite
+pwritev
+readdir
+readdir_r
+scandir
+sendfile
+setrlimit
+statfs
+statvfs
+tmpfile
+truncate
+versionsort
diff --git a/third_party/elfutils/tests/libtestfile_multi_shared.so.bz2 b/third_party/elfutils/tests/libtestfile_multi_shared.so.bz2
new file mode 100755
index 0000000..e9eb6a7
--- /dev/null
+++ b/third_party/elfutils/tests/libtestfile_multi_shared.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/line2addr.c b/third_party/elfutils/tests/line2addr.c
new file mode 100644
index 0000000..e0d65d3
--- /dev/null
+++ b/third_party/elfutils/tests/line2addr.c
@@ -0,0 +1,148 @@
+/* Copyright (C) 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <assert.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <argp.h>
+#include <stdio.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+
+
+static void
+print_address (Dwfl_Module *mod, Dwarf_Addr address)
+{
+  int n = dwfl_module_relocations (mod);
+  if (n < 0)
+    error (0, 0, "dwfl_module_relocations: %s", dwfl_errmsg (-1));
+  else if (n > 0)
+    {
+      int i = dwfl_module_relocate_address (mod, &address);
+      if (i < 0)
+	error (0, 0, "dwfl_module_relocate_address: %s", dwfl_errmsg (-1));
+      else
+	{
+	  const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
+						  NULL, NULL, NULL, NULL);
+	  const char *secname = dwfl_module_relocation_info (mod, i, NULL);
+	  if (n > 1 || secname[0] != '\0')
+	    printf ("%s(%s)+%#" PRIx64, modname, secname, address);
+	  else
+	    printf ("%s+%#" PRIx64, modname, address);
+	  return;
+	}
+    }
+
+  printf ("%#" PRIx64, address);
+}
+
+
+struct args
+{
+  const char *arg;
+  char *file;
+  int line;
+};
+
+static int
+handle_module (Dwfl_Module *mod __attribute__ ((unused)),
+	       void **udata __attribute__ ((unused)),
+	       const char *modname, Dwarf_Addr base __attribute__ ((unused)),
+	       Dwarf *dbg __attribute__ ((unused)),
+	       Dwarf_Addr bias __attribute__ ((unused)), void *arg)
+{
+  const struct args *const a = arg;
+
+  Dwfl_Line **lines = NULL;
+  size_t nlines = 0;
+
+  if (dwfl_module_getsrc_file (mod, a->file, a->line, 0, &lines, &nlines) == 0)
+    {
+      for (size_t inner = 0; inner < nlines; ++inner)
+	{
+	  Dwarf_Addr addr;
+	  int line = a->line, col = 0;
+	  const char *file = dwfl_lineinfo (lines[inner], &addr, &line, &col,
+					    NULL, NULL);
+	  if (file != NULL)
+	    {
+	      printf ("%s -> ", a->arg);
+	      print_address (mod, addr);
+	      if (modname[0] != '\0')
+		printf (" (%s:", modname);
+	      if (strcmp (file, a->file) || line != a->line || col != 0)
+		printf (" %s%s:%d", modname[0] != '\0' ? "" : "(",
+			file, line);
+	      if (col != 0)
+		printf (":%d", col);
+	      if (modname[0] != '\0'
+		  || strcmp (file, a->file) || line != a->line || col != 0)
+		puts (")");
+	      else
+		puts ("");
+	    }
+	}
+      free (lines);
+    }
+
+  return DWARF_CB_OK;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int cnt;
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  Dwfl *dwfl = NULL;
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &cnt, &dwfl);
+  assert (dwfl != NULL);
+
+  for (; cnt < argc; ++cnt)
+    {
+      struct args a = { .arg = argv[cnt] };
+
+      switch (sscanf (a.arg, "%m[^:]:%d", &a.file, &a.line))
+	{
+	default:
+	case 0:
+	  printf ("ignored %s\n", argv[cnt]);
+	  continue;
+	case 1:
+	  a.line = 0;
+	  break;
+	case 2:
+	  break;
+	}
+
+      (void) dwfl_getdwarf (dwfl, &handle_module, &a, 0);
+
+      free (a.file);
+    }
+
+  dwfl_end (dwfl);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/linkmap-cut-lib.so.bz2 b/third_party/elfutils/tests/linkmap-cut-lib.so.bz2
new file mode 100644
index 0000000..a1bda5c
--- /dev/null
+++ b/third_party/elfutils/tests/linkmap-cut-lib.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/linkmap-cut.bz2 b/third_party/elfutils/tests/linkmap-cut.bz2
new file mode 100644
index 0000000..f2ccd7c
--- /dev/null
+++ b/third_party/elfutils/tests/linkmap-cut.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/linkmap-cut.core.bz2 b/third_party/elfutils/tests/linkmap-cut.core.bz2
new file mode 100644
index 0000000..b55b2f2
--- /dev/null
+++ b/third_party/elfutils/tests/linkmap-cut.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/low_high_pc.c b/third_party/elfutils/tests/low_high_pc.c
new file mode 100644
index 0000000..d0f4302
--- /dev/null
+++ b/third_party/elfutils/tests/low_high_pc.c
@@ -0,0 +1,109 @@
+/* Test program for dwarf_lowpc and dwarf_highpc
+   Copyright (C) 2012 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <inttypes.h>
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+#include <argp.h>
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <error.h>
+#include <string.h>
+#include <fnmatch.h>
+
+struct args
+{
+  Dwfl *dwfl;
+  Dwarf_Die *cu;
+  Dwarf_Addr dwbias;
+  char **argv;
+  const char *file;
+};
+
+static struct args *args;
+
+static void
+fail(Dwarf_Off off, const char *name, const char *msg)
+{
+  printf("%s: [%" PRIx64 "] '%s' %s\n", args->file, off, name, msg);
+  exit(-1);
+}
+
+static int
+handle_die (Dwarf_Die *die, void *arg)
+{
+  args = arg;
+  Dwarf_Off off = dwarf_dieoffset (die);
+
+  const char *name = dwarf_diename (die);
+  if (name == NULL)
+    fail (off, "<no name>", "die without a name");
+
+  Dwarf_Addr lowpc = 0;
+  Dwarf_Addr highpc = 0;
+  if (dwarf_lowpc (die, &lowpc) != 0 && dwarf_hasattr (die, DW_AT_low_pc))
+    fail (off, name, "has DW_AT_low_pc but dwarf_lowpc fails");
+  if (dwarf_highpc (die, &highpc) != 0 && dwarf_hasattr (die, DW_AT_high_pc))
+    fail (off, name, "has DW_AT_high_pc but dwarf_highpc fails");
+
+  /* GCC < 4.7 had a bug where no code CUs got a highpc == lowpc.
+     Allow that, because it is not the main purpose of this test.  */
+  if (dwarf_hasattr (die, DW_AT_low_pc)
+      && dwarf_hasattr (die, DW_AT_high_pc)
+      && highpc <= lowpc
+      && ! (dwarf_tag (die) == DW_TAG_compile_unit && highpc == lowpc))
+    {
+      printf("lowpc: %" PRIx64 ", highpc: %" PRIx64 "lx\n", lowpc, highpc);
+      fail (off, name, "highpc <= lowpc");
+    }
+
+  return 0;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  int remaining;
+
+  /* Set locale.  */
+  (void) setlocale (LC_ALL, "");
+
+  struct args a = { .dwfl = NULL, .cu = NULL };
+
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining,
+		     &a.dwfl);
+  assert (a.dwfl != NULL);
+  a.argv = &argv[remaining];
+
+  int result = 0;
+
+  while ((a.cu = dwfl_nextcu (a.dwfl, a.cu, &a.dwbias)) != NULL)
+    {
+      a.file = dwarf_diename (a.cu);
+      handle_die (a.cu, &a);
+      dwarf_getfuncs (a.cu, &handle_die, &a, 0);
+    }
+
+  dwfl_end (a.dwfl);
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/msg_tst.c b/third_party/elfutils/tests/msg_tst.c
new file mode 100644
index 0000000..aa974d0
--- /dev/null
+++ b/third_party/elfutils/tests/msg_tst.c
@@ -0,0 +1,112 @@
+/* Copyright (C) 2002, 2005, 2006 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libelfP.h>
+
+static struct
+{
+  int id;
+  const char *expected;
+} libelf_msgs[ELF_E_NUM] =
+  {
+    { ELF_E_NOERROR, "no error" },
+    { ELF_E_UNKNOWN_ERROR, "unknown error" },
+    { ELF_E_UNKNOWN_VERSION, "unknown version" },
+    { ELF_E_UNKNOWN_TYPE, "unknown type" },
+    { ELF_E_INVALID_HANDLE, "invalid `Elf' handle" },
+    { ELF_E_SOURCE_SIZE, "invalid size of source operand" },
+    { ELF_E_DEST_SIZE, "invalid size of destination operand" },
+    { ELF_E_INVALID_ENCODING, "invalid encoding" },
+    { ELF_E_NOMEM, "out of memory" },
+    { ELF_E_INVALID_FILE, "invalid file descriptor" },
+    { ELF_E_INVALID_ELF, "invalid ELF file data" },
+    { ELF_E_INVALID_OP, "invalid operation" },
+    { ELF_E_NO_VERSION, "ELF version not set" },
+    { ELF_E_INVALID_CMD, "invalid command" },
+    { ELF_E_RANGE, "offset out of range" },
+    { ELF_E_ARCHIVE_FMAG, "invalid fmag field in archive header" },
+    { ELF_E_INVALID_ARCHIVE, "invalid archive file" },
+    { ELF_E_NO_ARCHIVE, "descriptor is not for an archive" },
+    { ELF_E_NO_INDEX, "no index available" },
+    { ELF_E_READ_ERROR, "cannot read data from file" },
+    { ELF_E_WRITE_ERROR, "cannot write data to file" },
+    { ELF_E_INVALID_CLASS, "invalid binary class" },
+    { ELF_E_INVALID_INDEX, "invalid section index" },
+    { ELF_E_INVALID_OPERAND, "invalid operand" },
+    { ELF_E_INVALID_SECTION, "invalid section" },
+    { ELF_E_INVALID_COMMAND, "invalid command" },
+    { ELF_E_WRONG_ORDER_EHDR, "executable header not created first" },
+    { ELF_E_FD_DISABLED, "file descriptor disabled" },
+    { ELF_E_FD_MISMATCH, "archive/member file descriptor mismatch" },
+    { ELF_E_OFFSET_RANGE, "offset out of range" },
+    { ELF_E_NOT_NUL_SECTION, "cannot manipulate null section" },
+    { ELF_E_DATA_MISMATCH, "data/scn mismatch" },
+    { ELF_E_INVALID_SECTION_HEADER, "invalid section header" },
+    { ELF_E_INVALID_DATA, "invalid data" },
+    { ELF_E_DATA_ENCODING, "unknown data encoding" },
+    { ELF_E_SECTION_TOO_SMALL, "section `sh_size' too small for data" },
+    { ELF_E_INVALID_ALIGN, "invalid section alignment" },
+    { ELF_E_INVALID_SHENTSIZE, "invalid section entry size" },
+    { ELF_E_UPDATE_RO, "update() for write on read-only file" },
+    { ELF_E_NOFILE, "no such file" },
+    { ELF_E_GROUP_NOT_REL,
+      "only relocatable files can contain section groups" },
+    { ELF_E_INVALID_PHDR,
+      "program header only allowed in executables, shared objects, \
+and core files" },
+    { ELF_E_NO_PHDR, "file has no program header" },
+    { ELF_E_INVALID_OFFSET, "invalid offset" },
+    { ELF_E_INVALID_SECTION_TYPE , "invalid section type" },
+    { ELF_E_INVALID_SECTION_FLAGS , "invalid section flags" },
+    { ELF_E_NOT_COMPRESSED, "section does not contain compressed data" },
+    { ELF_E_ALREADY_COMPRESSED, "section contains compressed data" },
+    { ELF_E_UNKNOWN_COMPRESSION_TYPE, "unknown compression type" },
+    { ELF_E_COMPRESS_ERROR, "cannot compress data" },
+    { ELF_E_DECOMPRESS_ERROR, "cannot decompress data" }
+  };
+
+
+int
+main (void)
+{
+  size_t cnt;
+  int result = EXIT_SUCCESS;
+
+  /* Clear the error state.  */
+  (void) elf_errno ();
+
+  /* Check all the messages of libelf.  */
+  for (cnt = 1; cnt < ELF_E_NUM; ++cnt)
+    {
+      const char *str = elf_errmsg (libelf_msgs[cnt].id);
+
+      if (strcmp (str, libelf_msgs[cnt].expected) != 0)
+	{
+	  printf ("libelf msg %zu: expected \"%s\", got \"%s\"\n",
+		  cnt, libelf_msgs[cnt].expected, str);
+	  result = EXIT_FAILURE;
+	}
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/newdata.c b/third_party/elfutils/tests/newdata.c
new file mode 100644
index 0000000..9af9956
--- /dev/null
+++ b/third_party/elfutils/tests/newdata.c
@@ -0,0 +1,403 @@
+/* Test program for elf_newdata function.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include ELFUTILS_HEADER(elf)
+#include <gelf.h>
+
+// Random data string (16 bytes).
+static char *DATA = "123456789ABCDEF";
+static size_t DATA_LEN = 16;
+
+static void
+add_section_data (Elf *elf, char *buf, size_t len)
+{
+  printf ("Adding %zd bytes.\n", len);
+
+  Elf_Scn *scn = elf_getscn (elf, 1);
+  if (scn == NULL)
+    {
+      printf ("couldn't get data section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  Elf_Data *data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot create newdata for section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  data->d_buf = buf;
+  data->d_type = ELF_T_BYTE;
+  data->d_size = len;
+  data->d_align = 1;
+  data->d_version = EV_CURRENT;
+
+  // Let the library compute the internal structure information.
+  if (elf_update (elf, ELF_C_NULL) < 0)
+    {
+      printf ("failure in elf_update(NULL): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+}
+
+static Elf *
+create_elf (int fd, int class, int use_mmap)
+{
+  Elf *elf = elf_begin (fd, use_mmap ? ELF_C_WRITE_MMAP : ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Create an ELF header.
+  if (gelf_newehdr (elf, class) == 0)
+    {
+      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Initialize header.
+  ehdr->e_ident[EI_DATA] = class == ELFCLASS32 ? ELFDATA2LSB : ELFDATA2MSB;
+  ehdr->e_ident[EI_OSABI] = ELFOSABI_GNU;
+  ehdr->e_type = ET_NONE;
+  ehdr->e_machine = class == ELFCLASS32 ? EM_PPC : EM_X86_64;
+  ehdr->e_version = EV_CURRENT;
+
+  // Update the ELF header.
+  if (gelf_update_ehdr (elf, ehdr) == 0)
+    {
+      printf ("cannot update ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Create a section.
+  Elf_Scn *scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create new section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for data section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  shdr->sh_type = SHT_PROGBITS;
+  shdr->sh_flags = 0;
+  shdr->sh_addr = 0;
+  shdr->sh_link = SHN_UNDEF;
+  shdr->sh_info = SHN_UNDEF;
+  shdr->sh_addralign = 1;
+  shdr->sh_entsize = 1;
+  shdr->sh_name = 0;
+
+  // Finish section, update the header.
+  if (gelf_update_shdr (scn, shdr) == 0)
+    {
+      printf ("cannot update header for DATA section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Add some data to the section.
+  add_section_data (elf, DATA, DATA_LEN);
+
+  // Write everything to disk.
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  return elf;
+}
+
+static Elf *
+read_elf (int fd, int use_mmap)
+{
+  printf ("Reading ELF file\n");
+  Elf *elf = elf_begin (fd, use_mmap ? ELF_C_RDWR_MMAP : ELF_C_RDWR, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor read-again: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  return elf;
+}
+
+static void
+check_section_size (Elf *elf, size_t size)
+{
+  Elf_Scn *scn = elf_getscn (elf, 1);
+  if (scn == NULL)
+    {
+      printf ("couldn't get data section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  GElf_Shdr shdr_mem;
+  GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for DATA section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (shdr->sh_size == size)
+    printf ("OK %zd bytes.\n", size);
+  else
+    {
+      printf ("BAD size, expected %zd, got %" PRIu64 "\n",
+	      size, shdr->sh_size);
+      exit (-1);
+    }
+}
+
+static void
+check_section_data (Elf *elf, char *data, size_t len, size_t times)
+{
+  Elf_Scn *scn = elf_getscn (elf, 1);
+  if (scn == NULL)
+    {
+      printf ("couldn't get data section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  Elf_Data *d = NULL;
+  for (size_t i = 0; i < times; i++)
+    {
+      if (d == NULL || i * len >= d->d_off + d->d_size)
+	{
+	  d = elf_getdata (scn, d);
+	  if (d == NULL)
+	    {
+	      printf ("cannot get data for section item %zd: %s\n",
+		      i, elf_errmsg (-1));
+	      exit (1);
+	    }
+	  else
+	    printf ("OK, section data item %zd (d_off: %" PRId64
+		    ", d_size: %zd)\n", i, d->d_off, d->d_size);
+	}
+      char *d_data = (char *) d->d_buf + (len * i) - d->d_off;
+      printf ("%zd data (d_off: %" PRId64
+	      ", len * i: %zd): (%p + %" PRId64 ") %s\n",
+	      i, d->d_off, len * i, d->d_buf, (len * i) - d->d_off, d_data);
+      if (memcmp (data, d_data, len) != 0)
+	{
+	  printf ("Got bad data in section for item %zd.\n", i);
+	  exit (1);
+	}
+    }
+}
+
+static void
+check_elf (int class, int use_mmap)
+{
+  static const char *fname;
+  if (class == ELFCLASS32)
+    fname = use_mmap ? "newdata.elf32.mmap" : "newdata.elf32";
+  else
+    fname = use_mmap ? "newdata.elf64.mmap" : "newdata.elf64";
+
+  printf ("\ncheck_elf: %s\n", fname);
+
+  int fd = open (fname, O_RDWR|O_CREAT|O_TRUNC, 00666);
+  if (fd == -1)
+    {
+      printf ("cannot create `%s': %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  Elf *elf = create_elf (fd, class, use_mmap);
+  check_section_size (elf, DATA_LEN);
+  check_section_data (elf, DATA, DATA_LEN, 1);
+
+  // Add some more data (won't be written to disk).
+  add_section_data (elf, DATA, DATA_LEN);
+  check_section_size (elf, 2 * DATA_LEN);
+  check_section_data (elf, DATA, DATA_LEN, 2);
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  // Read the ELF from disk now.  And add new data directly.
+  fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf = read_elf (fd, use_mmap);
+  check_section_size (elf, DATA_LEN);
+  // But don't check contents, that would read the data...
+
+  // Add some more data.
+  add_section_data (elf, DATA, DATA_LEN);
+  check_section_size (elf, 2 * DATA_LEN);
+  check_section_data (elf, DATA, DATA_LEN, 2);
+
+  // And some more.
+  add_section_data (elf, DATA, DATA_LEN);
+  check_section_size (elf, 3 * DATA_LEN);
+  check_section_data (elf, DATA, DATA_LEN, 3);
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  // Read the ELF from disk now.  And add new data after raw reading.
+  fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf = read_elf (fd, use_mmap);
+  check_section_size (elf, DATA_LEN);
+  // But don't check contents, that would read the data...
+
+  // Get raw data before adding new data.
+  Elf_Scn *scn = elf_getscn (elf, 1);
+  if (scn == NULL)
+    {
+      printf ("couldn't get data section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  printf ("elf_rawdata\n");
+  Elf_Data *data = elf_rawdata (scn, NULL);
+  if (data == NULL)
+    {
+      printf ("couldn't get raw data from section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (data->d_size != DATA_LEN)
+    {
+      printf ("Unexpected Elf_Data: %zd", data->d_size);
+      exit (1);
+    }
+
+  // Now add more data.
+  add_section_data (elf, DATA, DATA_LEN);
+  check_section_size (elf, 2 * DATA_LEN);
+  check_section_data (elf, DATA, DATA_LEN, 2);
+
+  // And some more.
+  add_section_data (elf, DATA, DATA_LEN);
+  check_section_size (elf, 3 * DATA_LEN);
+  check_section_data (elf, DATA, DATA_LEN, 3);
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  // Read the ELF from disk now.  And add new data after data reading.
+  fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf = read_elf (fd, use_mmap);
+  check_section_size (elf, DATA_LEN);
+  // Get (converted) data before adding new data.
+  check_section_data (elf, DATA, DATA_LEN, 1);
+
+  printf ("elf_getdata\n");
+
+  // Now add more data.
+  add_section_data (elf, DATA, DATA_LEN);
+  check_section_size (elf, 2 * DATA_LEN);
+  check_section_data (elf, DATA, DATA_LEN, 2);
+
+  // And some more.
+  add_section_data (elf, DATA, DATA_LEN);
+  check_section_size (elf, 3 * DATA_LEN);
+  check_section_data (elf, DATA, DATA_LEN, 3);
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  unlink (fname);
+}
+
+int
+main (int argc __attribute__ ((unused)), char *argv[] __attribute__ ((unused)))
+{
+  // Initialize libelf.
+  elf_version (EV_CURRENT);
+
+  // Fill holes with something non-zero to more easily spot bad data.
+  elf_fill ('X');
+
+  check_elf (ELFCLASS32, 0);
+  check_elf (ELFCLASS32, 1);
+  check_elf (ELFCLASS64, 0);
+  check_elf (ELFCLASS64, 1);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/newfile.c b/third_party/elfutils/tests/newfile.c
new file mode 100644
index 0000000..5eabdcb
--- /dev/null
+++ b/third_party/elfutils/tests/newfile.c
@@ -0,0 +1,170 @@
+/* Copyright (C) 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <libelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static void
+print_ehdr (Elf32_Ehdr *ehdr)
+{
+  int n;
+
+  for (n = 0; n < EI_NIDENT; ++n)
+    printf (" %02x", ehdr->e_ident[n]);
+
+  printf ("\ntype = %d\nmachine = %d\nversion = %d\nentry = %d\n"
+          "phoff = %d\nshoff = %d\nflags = %d\nehsize = %d\n"
+          "phentsize = %d\nphnum = %d\nshentsize = %d\nshnum = %d\n"
+          "shstrndx = %d\n",
+          ehdr->e_type,
+          ehdr->e_machine,
+          ehdr->e_version,
+          ehdr->e_entry,
+          ehdr->e_phoff,
+          ehdr->e_shoff,
+          ehdr->e_flags,
+          ehdr->e_ehsize,
+          ehdr->e_phentsize,
+          ehdr->e_phnum,
+          ehdr->e_shentsize,
+          ehdr->e_shnum,
+          ehdr->e_shstrndx);
+}
+
+int
+main (int argc, char *argv[] __attribute__ ((unused)))
+{
+  Elf *elf;
+  int result = 0;
+  int fd;
+  char fname[] = "newfile-XXXXXX";
+
+  fd = mkstemp (fname);
+  if (fd == -1)
+    {
+      printf ("cannot create temporary file: %m\n");
+      exit (1);
+    }
+  /* Remove the file when we exit.  */
+  unlink (fname);
+
+  elf_version (EV_CURRENT);
+  elf = elf_begin (fd, ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      printf ("elf_begin: %s\n", elf_errmsg (-1));
+      result = 1;
+    }
+  else
+    {
+      if (elf32_newehdr (elf) == NULL)
+	{
+	  printf ("elf32_newehdr: %s\n", elf_errmsg (-1));
+	  result = 1;
+	}
+      else
+        {
+	  Elf32_Ehdr *ehdr = elf32_getehdr (elf);
+
+	  if (ehdr == NULL)
+	    {
+	      printf ("elf32_getehdr: %s\n", elf_errmsg (-1));
+	      result = 1;
+	    }
+	  else
+	    {
+	      int i;
+
+	      if (argc > 1)
+		/* Use argc as a debugging flag.  */
+		print_ehdr (ehdr);
+
+	      /* Some tests.  */
+	      for (i = 0; i < EI_NIDENT; ++i)
+		if (ehdr->e_ident[i] != 0)
+		  {
+		    printf ("ehdr->e_ident[%d] != 0\n", i);
+		    result = 1;
+		    break;
+		  }
+
+#define VALUE_TEST(name, val) \
+	      if (ehdr->name != val)					      \
+	        {							      \
+		  printf ("ehdr->%s != %d\n", #name, val);		      \
+		  result = 1;						      \
+		}
+#define ZERO_TEST(name) VALUE_TEST (name, 0)
+	      ZERO_TEST (e_type);
+	      ZERO_TEST (e_machine);
+	      ZERO_TEST (e_version);
+	      ZERO_TEST (e_entry);
+	      ZERO_TEST (e_phoff);
+	      ZERO_TEST (e_shoff);
+	      ZERO_TEST (e_flags);
+	      ZERO_TEST (e_ehsize);
+	      ZERO_TEST (e_phentsize);
+	      ZERO_TEST (e_phnum);
+	      ZERO_TEST (e_shentsize);
+	      ZERO_TEST (e_shnum);
+	      ZERO_TEST (e_shstrndx);
+
+	      if (elf32_newphdr (elf, 10) == NULL)
+		{
+		  printf ("elf32_newphdr: %s\n", elf_errmsg (-1));
+		  result = 1;
+		}
+	      else
+		{
+		  if (argc > 1)
+		    print_ehdr (ehdr);
+
+		  ehdr = elf32_getehdr (elf);
+		  if (ehdr == NULL)
+		    {
+		      printf ("elf32_getehdr (#2): %s\n", elf_errmsg (-1));
+		      result = 1;
+		    }
+		  else
+		    {
+		      ZERO_TEST (e_type);
+		      ZERO_TEST (e_machine);
+		      ZERO_TEST (e_version);
+		      ZERO_TEST (e_entry);
+		      ZERO_TEST (e_phoff);
+		      ZERO_TEST (e_shoff);
+		      ZERO_TEST (e_flags);
+		      ZERO_TEST (e_ehsize);
+		      VALUE_TEST (e_phentsize, (int) sizeof (Elf32_Phdr));
+		      VALUE_TEST (e_phnum, 10);
+		      ZERO_TEST (e_shentsize);
+		      ZERO_TEST (e_shnum);
+		      ZERO_TEST (e_shstrndx);
+		    }
+		}
+	    }
+        }
+
+      (void) elf_end (elf);
+    }
+
+  return result;
+}
diff --git a/third_party/elfutils/tests/newscn.c b/third_party/elfutils/tests/newscn.c
new file mode 100644
index 0000000..466f2f6
--- /dev/null
+++ b/third_party/elfutils/tests/newscn.c
@@ -0,0 +1,66 @@
+/* Copyright (C) 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+int
+main (void)
+{
+  Elf *elf;
+  int fd;
+  Elf_Scn *section;
+
+  if (elf_version (EV_CURRENT) == EV_NONE)
+    {
+      fprintf (stderr, "library fd of date\n");
+      exit (1);
+    }
+
+  char name[] = "test.XXXXXX";
+  fd = mkstemp (name);
+  if (fd < 0)
+    {
+      fprintf (stderr, "Failed to open fdput file: %s\n", name);
+      exit (1);
+    }
+  unlink (name);
+
+  elf = elf_begin (fd, ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      fprintf (stderr, "Failed to elf_begin fdput file: %s\n", name);
+      exit (1);
+    }
+
+  section = elf_newscn (elf);
+  section = elf_nextscn (elf, section);
+  assert (section == NULL);
+
+  elf_end (elf);
+  close (fd);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/peel_type.c b/third_party/elfutils/tests/peel_type.c
new file mode 100644
index 0000000..bccce32
--- /dev/null
+++ b/third_party/elfutils/tests/peel_type.c
@@ -0,0 +1,119 @@
+/* Test program for dwarf_peel_type. Peels type of top-level vars.
+   Copyright (C) 2017 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <argp.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include ELFUTILS_HEADER(dw)
+#include ELFUTILS_HEADER(dwfl)
+#include <stdio.h>
+#include <unistd.h>
+#include <dwarf.h>
+
+#include "../libdw/known-dwarf.h"
+
+static const char *
+dwarf_tag_string (unsigned int tag)
+{
+  switch (tag)
+    {
+#define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_TAG
+#undef DWARF_ONE_KNOWN_DW_TAG
+    default:
+      return NULL;
+    }
+}
+
+void
+print_var_raw_type (Dwarf_Die *var)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Die type_mem;
+  Dwarf_Die *type;
+  const char *name = dwarf_diename (var);
+
+  type = dwarf_formref_die (dwarf_attr (var, DW_AT_type, &attr_mem),
+			    &type_mem);
+  if (type != NULL)
+    {
+      /* Test twice, once with a separate result DIE. Then with the
+	 DIE itself. The resulting tag should be the same. */
+      Dwarf_Die result_mem;
+      Dwarf_Die *result = &result_mem;
+      int res = dwarf_peel_type (type, result);
+      if (res < 0)
+        printf ("%s error peeling type: %s\n", name, dwarf_errmsg (-1));
+      else if (res > 0)
+	printf ("%s missing DW_TAG_TYPE, could peel further: %s\n",
+		name, dwarf_tag_string (dwarf_tag (result)));
+      else
+	{
+	  int tag = dwarf_tag (result);
+	  printf ("%s raw type %s\n", name, dwarf_tag_string (tag));
+	  res = dwarf_peel_type (type, type);
+	  if (res < 0)
+	    printf ("%s cannot peel type itself: %s\n", name,
+		    dwarf_errmsg (-1));
+	  else if (res > 0)
+	printf ("%s missing DW_TAG_TYPE, could peel type further: %s\n",
+		name, dwarf_tag_string (dwarf_tag (type)));
+	  else if (dwarf_tag (type) != tag)
+	    printf ("%s doesn't resolve the same: %s != %s\n", name,
+		    dwarf_tag_string (tag),
+		    dwarf_tag_string (dwarf_tag (type)));
+	}
+    }
+  else
+    printf ("%s has no type.\n", name);
+}
+
+int
+main (int argc, char *argv[])
+{
+
+  int remaining;
+  Dwfl *dwfl;
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining,
+                     &dwfl);
+  assert (dwfl != NULL);
+
+  Dwarf_Die *cu = NULL;
+  Dwarf_Addr dwbias;
+  while ((cu = dwfl_nextcu (dwfl, cu, &dwbias)) != NULL)
+    {
+      Dwarf_Die die_mem;
+      Dwarf_Die *die = &die_mem;
+      dwarf_child (cu, &die_mem);
+
+      while (1)
+	{
+	  if (dwarf_tag (die) == DW_TAG_variable)
+	    print_var_raw_type (die);
+
+	  if (dwarf_siblingof (die, &die_mem) != 0)
+	    break;
+	}
+    }
+
+  dwfl_end (dwfl);
+}
diff --git a/third_party/elfutils/tests/rdwrmmap.c b/third_party/elfutils/tests/rdwrmmap.c
new file mode 100644
index 0000000..6f027df
--- /dev/null
+++ b/third_party/elfutils/tests/rdwrmmap.c
@@ -0,0 +1,49 @@
+/* Copyright (C) 2006 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <error.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <libelf.h>
+
+int
+main (int argc __attribute__ ((unused)), char *argv[])
+{
+  int fd = open (argv[1], O_RDWR);
+  if (fd < 0)
+    error (2, errno, "open: %s", argv[1]);
+
+  if (elf_version (EV_CURRENT) == EV_NONE)
+    error (1, 0, "libelf version mismatch");
+
+  Elf *elf = elf_begin (fd, ELF_C_RDWR_MMAP, NULL);
+  if (elf == NULL)
+    error (1, 0, "elf_begin: %s", elf_errmsg (-1));
+
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    error (1, 0, "elf_update: %s", elf_errmsg (-1));
+
+  elf_end (elf);
+  close (fd);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/rerequest_tag.c b/third_party/elfutils/tests/rerequest_tag.c
new file mode 100644
index 0000000..b4d4627
--- /dev/null
+++ b/third_party/elfutils/tests/rerequest_tag.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 2011 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include ELFUTILS_HEADER(dw)
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+int
+main (int argc, char **argv)
+{
+  assert (argc > 1);
+
+  int i = open (argv[1], O_RDONLY);
+  assert (i >= 0);
+
+  Dwarf *dw = dwarf_begin (i, DWARF_C_READ);
+  assert (dw != NULL);
+
+  Dwarf_Die die_mem, *die;
+  die = dwarf_offdie (dw, 11, &die_mem);
+  assert (die == &die_mem);
+  assert (dwarf_tag (die) == 0);
+
+  die = dwarf_offdie (dw, 11, &die_mem);
+  assert (die == &die_mem);
+  assert (dwarf_tag (die) == 0);
+
+  dwarf_end (dw);
+  return 0;
+}
diff --git a/third_party/elfutils/tests/run-addr2line-alt-debugpath.sh b/third_party/elfutils/tests/run-addr2line-alt-debugpath.sh
new file mode 100755
index 0000000..b508700
--- /dev/null
+++ b/third_party/elfutils/tests/run-addr2line-alt-debugpath.sh
@@ -0,0 +1,67 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# See run-addr2line-i-test.sh
+testfiles testfile-inlines
+
+# Split off the debuginfo and put it under a separate subdir from the
+# original binary.  Use --debuginfo-path to connect the dots again.
+# Note that we use separate subdirs/roots for the binaries and debug files.
+abs_test_bindir=$(pwd)/bindir
+abs_test_debugdir=$(pwd)/debugdir
+
+mkdir ${abs_test_bindir}
+mkdir ${abs_test_bindir}/bin
+mkdir ${abs_test_debugdir}
+mkdir ${abs_test_debugdir}/bin
+
+testrun ${abs_top_builddir}/src/strip -f ${abs_test_debugdir}/bin/testfile-inlines.debug -o ${abs_test_bindir}/bin/testfile-inlines testfile-inlines
+
+# Can we find the separate debuginfo file now?
+testrun_compare ${abs_top_builddir}/src/addr2line --pretty-print -a -f -i -e ${abs_test_bindir}/bin/testfile-inlines --debuginfo-path=${abs_test_debugdir} 0x00000000000005a0 0x00000000000005a1 0x00000000000005b0 0x00000000000005b1 0x00000000000005c0 0x00000000000005d0 0x00000000000005e0 0x00000000000005e1 0x00000000000005f0 0x00000000000005f1 0x00000000000005f2 <<\EOF
+0x00000000000005a0: foobar at /tmp/x.cpp:5
+0x00000000000005a1: foobar at /tmp/x.cpp:6
+0x00000000000005b0: fubar at /tmp/x.cpp:10
+0x00000000000005b1: fubar at /tmp/x.cpp:11
+0x00000000000005c0: foobar at /tmp/x.cpp:5
+ (inlined by) bar at /tmp/x.cpp:15
+0x00000000000005d0: fubar at /tmp/x.cpp:10
+ (inlined by) baz at /tmp/x.cpp:20
+0x00000000000005e0: foobar at /tmp/x.cpp:5
+ (inlined by) bar at /tmp/x.cpp:15
+ (inlined by) _Z3foov at /tmp/x.cpp:25
+0x00000000000005e1: fubar at /tmp/x.cpp:10
+ (inlined by) baz at /tmp/x.cpp:20
+ (inlined by) _Z3foov at /tmp/x.cpp:26
+0x00000000000005f0: _Z2fuv at /tmp/x.cpp:31
+0x00000000000005f1: fubar at /tmp/x.cpp:10
+ (inlined by) _Z2fuv at /tmp/x.cpp:32
+0x00000000000005f2: foobar at /tmp/x.cpp:5
+ (inlined by) _Z2fuv at /tmp/x.cpp:33
+EOF
+
+# Cleanup
+rm ${abs_test_bindir}/bin/testfile-inlines
+rm ${abs_test_debugdir}/bin/testfile-inlines.debug
+rmdir ${abs_test_bindir}/bin
+rmdir ${abs_test_bindir}
+rmdir ${abs_test_debugdir}/bin
+rmdir ${abs_test_debugdir}
+
+exit 0
diff --git a/third_party/elfutils/tests/run-addr2line-i-demangle-test.sh b/third_party/elfutils/tests/run-addr2line-i-demangle-test.sh
new file mode 100755
index 0000000..1af8562
--- /dev/null
+++ b/third_party/elfutils/tests/run-addr2line-i-demangle-test.sh
@@ -0,0 +1,70 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if test -n "$ELFUTILS_DISABLE_DEMANGLE"; then
+  echo "demangler unsupported"
+  exit 77
+fi
+
+. $srcdir/test-subr.sh
+
+# See run-addr2line-i-test.sh for how to generate test files.
+testfiles testfile-inlines
+
+# All together now plus (demangled) function names.
+testrun_compare ${abs_top_builddir}/src/addr2line -C -f -i -e testfile-inlines 0x00000000000005a0 0x00000000000005a1 0x00000000000005b0 0x00000000000005b1 0x00000000000005c0 0x00000000000005d0 0x00000000000005e0 0x00000000000005e1 0x00000000000005f0 0x00000000000005f1 0x00000000000005f2 <<\EOF
+foobar
+/tmp/x.cpp:5
+foobar
+/tmp/x.cpp:6
+fubar
+/tmp/x.cpp:10
+fubar
+/tmp/x.cpp:11
+foobar inlined at /tmp/x.cpp:15 in bar()
+/tmp/x.cpp:5
+bar
+/tmp/x.cpp:15
+fubar inlined at /tmp/x.cpp:20 in baz()
+/tmp/x.cpp:10
+baz
+/tmp/x.cpp:20
+foobar inlined at /tmp/x.cpp:15 in foo()
+/tmp/x.cpp:5
+bar
+/tmp/x.cpp:15
+foo()
+/tmp/x.cpp:25
+fubar inlined at /tmp/x.cpp:20 in foo()
+/tmp/x.cpp:10
+baz
+/tmp/x.cpp:20
+foo()
+/tmp/x.cpp:26
+fu()
+/tmp/x.cpp:31
+fubar inlined at /tmp/x.cpp:32 in fu()
+/tmp/x.cpp:10
+fu()
+/tmp/x.cpp:32
+foobar inlined at /tmp/x.cpp:33 in fu()
+/tmp/x.cpp:5
+fu()
+/tmp/x.cpp:33
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-addr2line-i-lex-test.sh b/third_party/elfutils/tests/run-addr2line-i-lex-test.sh
new file mode 100755
index 0000000..c391fd9
--- /dev/null
+++ b/third_party/elfutils/tests/run-addr2line-i-lex-test.sh
@@ -0,0 +1,71 @@
+#! /bin/sh
+# Copyright (C) 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# // g++ x.cpp -g -fPIC -olibx.so -shared -O3 -fvisibility=hidden
+#
+# void foobar()
+# {
+#   __asm__ ( "nop" ::: );
+# }
+#
+# void foo()
+# {
+#   {
+#     void (*bar) () = foobar;
+#     bar();
+#   }
+# }
+
+testfiles testfile-lex-inlines
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-lex-inlines 0x0000000000000680 <<\EOF
+/tmp/x.cpp:5
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-lex-inlines 0x0000000000000681 <<\EOF
+/tmp/x.cpp:5
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-lex-inlines 0x0000000000000690 <<\EOF
+/tmp/x.cpp:5
+/tmp/x.cpp:12
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-lex-inlines 0x0000000000000691 <<\EOF
+/tmp/x.cpp:5
+/tmp/x.cpp:12
+EOF
+
+# All together now (plus function names).
+testrun_compare ${abs_top_builddir}/src/addr2line -f -i -e testfile-lex-inlines 0x0000000000000680 0x0000000000000681 0x0000000000000690 0x0000000000000691 <<\EOF
+_Z6foobarv
+/tmp/x.cpp:5
+_Z6foobarv
+/tmp/x.cpp:5
+foobar inlined at /tmp/x.cpp:12 in _Z3foov
+/tmp/x.cpp:5
+_Z3foov
+/tmp/x.cpp:12
+foobar inlined at /tmp/x.cpp:12 in _Z3foov
+/tmp/x.cpp:5
+_Z3foov
+/tmp/x.cpp:12
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-addr2line-i-test.sh b/third_party/elfutils/tests/run-addr2line-i-test.sh
new file mode 100755
index 0000000..d08f3cb
--- /dev/null
+++ b/third_party/elfutils/tests/run-addr2line-i-test.sh
@@ -0,0 +1,223 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# // g++ x.cpp -g -fPIC -olibx.so -shared -O3 -fvisibility=hidden
+#
+# void foobar()
+# {
+#   __asm__ ( "nop" ::: );
+# }
+#
+# void fubar()
+# {
+#   __asm__ ( "nop" ::: );
+# }
+#
+# void bar()
+# {
+#   foobar();
+# }
+#
+# void baz()
+# {
+#   fubar();
+# }
+#
+# void foo()
+# {
+#   bar();
+#   baz();
+# }
+#
+# void fu()
+# {
+#   __asm__ ( "nop" ::: );
+#   fubar();
+#   foobar();
+# }
+
+testfiles testfile-inlines
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-inlines 0x00000000000005a0 <<\EOF
+/tmp/x.cpp:5
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-inlines 0x00000000000005a1 <<\EOF
+/tmp/x.cpp:6
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-inlines 0x00000000000005b0 <<\EOF
+/tmp/x.cpp:10
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-inlines 0x00000000000005b1 <<\EOF
+/tmp/x.cpp:11
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-inlines 0x00000000000005c0 <<\EOF
+/tmp/x.cpp:5
+/tmp/x.cpp:15
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-inlines 0x00000000000005d0 <<\EOF
+/tmp/x.cpp:10
+/tmp/x.cpp:20
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-inlines 0x00000000000005e0 <<\EOF
+/tmp/x.cpp:5
+/tmp/x.cpp:15
+/tmp/x.cpp:25
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-inlines 0x00000000000005e1 <<\EOF
+/tmp/x.cpp:10
+/tmp/x.cpp:20
+/tmp/x.cpp:26
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-inlines 0x00000000000005f1 <<\EOF
+/tmp/x.cpp:10
+/tmp/x.cpp:32
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -i -e testfile-inlines 0x00000000000005f2 <<\EOF
+/tmp/x.cpp:5
+/tmp/x.cpp:33
+EOF
+
+# All together now (plus function names).
+testrun_compare ${abs_top_builddir}/src/addr2line -f -i -e testfile-inlines 0x00000000000005a0 0x00000000000005a1 0x00000000000005b0 0x00000000000005b1 0x00000000000005c0 0x00000000000005d0 0x00000000000005e0 0x00000000000005e1 0x00000000000005f0 0x00000000000005f1 0x00000000000005f2 <<\EOF
+foobar
+/tmp/x.cpp:5
+foobar
+/tmp/x.cpp:6
+fubar
+/tmp/x.cpp:10
+fubar
+/tmp/x.cpp:11
+foobar inlined at /tmp/x.cpp:15 in _Z3barv
+/tmp/x.cpp:5
+bar
+/tmp/x.cpp:15
+fubar inlined at /tmp/x.cpp:20 in _Z3bazv
+/tmp/x.cpp:10
+baz
+/tmp/x.cpp:20
+foobar inlined at /tmp/x.cpp:15 in _Z3foov
+/tmp/x.cpp:5
+bar
+/tmp/x.cpp:15
+_Z3foov
+/tmp/x.cpp:25
+fubar inlined at /tmp/x.cpp:20 in _Z3foov
+/tmp/x.cpp:10
+baz
+/tmp/x.cpp:20
+_Z3foov
+/tmp/x.cpp:26
+_Z2fuv
+/tmp/x.cpp:31
+fubar inlined at /tmp/x.cpp:32 in _Z2fuv
+/tmp/x.cpp:10
+_Z2fuv
+/tmp/x.cpp:32
+foobar inlined at /tmp/x.cpp:33 in _Z2fuv
+/tmp/x.cpp:5
+_Z2fuv
+/tmp/x.cpp:33
+EOF
+
+# All together now (plus function names plus addresses).
+testrun_compare ${abs_top_builddir}/src/addr2line -a -f -i -e testfile-inlines 0x00000000000005a0 0x00000000000005a1 0x00000000000005b0 0x00000000000005b1 0x00000000000005c0 0x00000000000005d0 0x00000000000005e0 0x00000000000005e1 0x00000000000005f0 0x00000000000005f1 0x00000000000005f2 <<\EOF
+0x00000000000005a0
+foobar
+/tmp/x.cpp:5
+0x00000000000005a1
+foobar
+/tmp/x.cpp:6
+0x00000000000005b0
+fubar
+/tmp/x.cpp:10
+0x00000000000005b1
+fubar
+/tmp/x.cpp:11
+0x00000000000005c0
+foobar inlined at /tmp/x.cpp:15 in _Z3barv
+/tmp/x.cpp:5
+bar
+/tmp/x.cpp:15
+0x00000000000005d0
+fubar inlined at /tmp/x.cpp:20 in _Z3bazv
+/tmp/x.cpp:10
+baz
+/tmp/x.cpp:20
+0x00000000000005e0
+foobar inlined at /tmp/x.cpp:15 in _Z3foov
+/tmp/x.cpp:5
+bar
+/tmp/x.cpp:15
+_Z3foov
+/tmp/x.cpp:25
+0x00000000000005e1
+fubar inlined at /tmp/x.cpp:20 in _Z3foov
+/tmp/x.cpp:10
+baz
+/tmp/x.cpp:20
+_Z3foov
+/tmp/x.cpp:26
+0x00000000000005f0
+_Z2fuv
+/tmp/x.cpp:31
+0x00000000000005f1
+fubar inlined at /tmp/x.cpp:32 in _Z2fuv
+/tmp/x.cpp:10
+_Z2fuv
+/tmp/x.cpp:32
+0x00000000000005f2
+foobar inlined at /tmp/x.cpp:33 in _Z2fuv
+/tmp/x.cpp:5
+_Z2fuv
+/tmp/x.cpp:33
+EOF
+
+# All together now (plus function names and addresses and pretty)
+testrun_compare ${abs_top_builddir}/src/addr2line --pretty-print -a -f -i -e testfile-inlines 0x00000000000005a0 0x00000000000005a1 0x00000000000005b0 0x00000000000005b1 0x00000000000005c0 0x00000000000005d0 0x00000000000005e0 0x00000000000005e1 0x00000000000005f0 0x00000000000005f1 0x00000000000005f2 <<\EOF
+0x00000000000005a0: foobar at /tmp/x.cpp:5
+0x00000000000005a1: foobar at /tmp/x.cpp:6
+0x00000000000005b0: fubar at /tmp/x.cpp:10
+0x00000000000005b1: fubar at /tmp/x.cpp:11
+0x00000000000005c0: foobar at /tmp/x.cpp:5
+ (inlined by) bar at /tmp/x.cpp:15
+0x00000000000005d0: fubar at /tmp/x.cpp:10
+ (inlined by) baz at /tmp/x.cpp:20
+0x00000000000005e0: foobar at /tmp/x.cpp:5
+ (inlined by) bar at /tmp/x.cpp:15
+ (inlined by) _Z3foov at /tmp/x.cpp:25
+0x00000000000005e1: fubar at /tmp/x.cpp:10
+ (inlined by) baz at /tmp/x.cpp:20
+ (inlined by) _Z3foov at /tmp/x.cpp:26
+0x00000000000005f0: _Z2fuv at /tmp/x.cpp:31
+0x00000000000005f1: fubar at /tmp/x.cpp:10
+ (inlined by) _Z2fuv at /tmp/x.cpp:32
+0x00000000000005f2: foobar at /tmp/x.cpp:5
+ (inlined by) _Z2fuv at /tmp/x.cpp:33
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-addr2line-test.sh b/third_party/elfutils/tests/run-addr2line-test.sh
new file mode 100755
index 0000000..1079c3e
--- /dev/null
+++ b/third_party/elfutils/tests/run-addr2line-test.sh
@@ -0,0 +1,116 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile
+tempfiles good.out stdin.nl stdin.nl.out stdin.nonl stdin.nonl.out foo.out
+tempfiles addr2line.out
+
+cat > good.out <<\EOF
+foo
+/home/drepper/gnu/new-bu/build/ttt/f.c:3
+bar
+/home/drepper/gnu/new-bu/build/ttt/b.c:4
+foo
+/home/drepper/gnu/new-bu/build/ttt/f.c:3
+bar
+/home/drepper/gnu/new-bu/build/ttt/b.c:4
+foo
+/home/drepper/gnu/new-bu/build/ttt/f.c:3
+bar
+/home/drepper/gnu/new-bu/build/ttt/b.c:4
+foo
+/home/drepper/gnu/new-bu/build/ttt/f.c:3
+bar
+/home/drepper/gnu/new-bu/build/ttt/b.c:4
+EOF
+
+echo "# Everything on the command line"
+cat good.out | testrun_compare ${abs_top_builddir}/src/addr2line -f -e testfile 0x08048468 0x0804845c foo bar foo+0x0 bar+0x0 foo-0x0 bar-0x0
+
+cat > stdin.nl <<\EOF
+0x08048468
+0x0804845c
+foo
+bar
+foo+0x0
+bar+0x0
+foo-0x0
+bar-0x0
+EOF
+
+echo "# Everything from stdin (with newlines)."
+cat stdin.nl | testrun ${abs_top_builddir}/src/addr2line -f -e testfile > stdin.nl.out || exit 1
+cmp good.out stdin.nl.out || exit 1
+
+cat > foo.out <<\EOF
+foo
+/home/drepper/gnu/new-bu/build/ttt/f.c:3
+EOF
+
+echo "# stdin without newline address, just EOF."
+echo -n "0x08048468" | testrun ${abs_top_builddir}/src/addr2line -f -e testfile > stdin.nonl.out || exit 1
+cmp foo.out stdin.nonl.out || exit 1
+
+echo "# stdin without newline symbol, just EOF."
+echo -n "foo" | testrun ${abs_top_builddir}/src/addr2line -f -e testfile > stdin.nl.out || exit 1
+cmp foo.out stdin.nonl.out || exit 1
+
+tempfiles good.addr.out
+
+cat > good.addr.out <<\EOF
+0x08048468
+foo
+/home/drepper/gnu/new-bu/build/ttt/f.c:3
+0x0804845c
+bar
+/home/drepper/gnu/new-bu/build/ttt/b.c:4
+0x08048468
+foo
+/home/drepper/gnu/new-bu/build/ttt/f.c:3
+0x0804845c
+bar
+/home/drepper/gnu/new-bu/build/ttt/b.c:4
+0x08048468
+foo
+/home/drepper/gnu/new-bu/build/ttt/f.c:3
+0x0804845c
+bar
+/home/drepper/gnu/new-bu/build/ttt/b.c:4
+0x08048468
+foo
+/home/drepper/gnu/new-bu/build/ttt/f.c:3
+0x0804845c
+bar
+/home/drepper/gnu/new-bu/build/ttt/b.c:4
+EOF
+
+echo "# Everything on the command line with addresses"
+cat good.addr.out | testrun_compare ${abs_top_builddir}/src/addr2line -a -f -e testfile 0x08048468 0x0804845c foo bar foo+0x0 bar+0x0 foo-0x0 bar-0x0
+
+echo "# Everything from stdin (with newlines) with addresses."
+cat stdin.nl | testrun ${abs_top_builddir}/src/addr2line -a -f -e testfile > stdin.nl.out || exit 1
+cmp good.addr.out stdin.nl.out || exit 1
+
+echo "# Pretty with functions and addresses."
+testrun_compare ${abs_top_builddir}/src/addr2line --pretty -a -f -e testfile 0x08048468 0x0804845c << EOF
+0x08048468: foo at /home/drepper/gnu/new-bu/build/ttt/f.c:3
+0x0804845c: bar at /home/drepper/gnu/new-bu/build/ttt/b.c:4
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-addrcfi.sh b/third_party/elfutils/tests/run-addrcfi.sh
new file mode 100755
index 0000000..376a6dc
--- /dev/null
+++ b/third_party/elfutils/tests/run-addrcfi.sh
@@ -0,0 +1,3749 @@
+#! /bin/sh
+# Copyright (C) 2013
+# Copyright (C) H.J. Lu <hjl.tools@gmail.com>, 2015.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Note some testfiles are also used in run-allregs.sh.
+
+# Shows return address, CFA location expression and register rules
+# from ABI's default CFI program as setup by arch ebl backend hook
+# abi_cfi unless overridden by CIE and FDE program at given address.
+
+# EM_386 (function main 0x080489b8)
+testfiles testfile11
+testrun_compare ${abs_builddir}/addrcfi -e testfile11 0x080489b8 <<\EOF
+.eh_frame has 0x80489b8 => [0x80489b8, 0x80489b9):
+	return address in reg8
+	CFA location expression: bregx(4,4)
+	integer reg0 (%eax): undefined
+	integer reg1 (%ecx): undefined
+	integer reg2 (%edx): undefined
+	integer reg3 (%ebx): same_value
+	integer reg4 (%esp): location expression: call_frame_cfa stack_value
+	integer reg5 (%ebp): same_value
+	integer reg6 (%esi): same_value
+	integer reg7 (%edi): same_value
+	integer reg8 (%eip): location expression: call_frame_cfa plus_uconst(-4)
+	integer reg9 (%eflags): undefined
+	integer reg10 (%trapno): undefined
+	x87 reg11 (%st0): undefined
+	x87 reg12 (%st1): undefined
+	x87 reg13 (%st2): undefined
+	x87 reg14 (%st3): undefined
+	x87 reg15 (%st4): undefined
+	x87 reg16 (%st5): undefined
+	x87 reg17 (%st6): undefined
+	x87 reg18 (%st7): undefined
+	SSE reg21 (%xmm0): undefined
+	SSE reg22 (%xmm1): undefined
+	SSE reg23 (%xmm2): undefined
+	SSE reg24 (%xmm3): undefined
+	SSE reg25 (%xmm4): undefined
+	SSE reg26 (%xmm5): undefined
+	SSE reg27 (%xmm6): undefined
+	SSE reg28 (%xmm7): undefined
+	MMX reg29 (%mm0): undefined
+	MMX reg30 (%mm1): undefined
+	MMX reg31 (%mm2): undefined
+	MMX reg32 (%mm3): undefined
+	MMX reg33 (%mm4): undefined
+	MMX reg34 (%mm5): undefined
+	MMX reg35 (%mm6): undefined
+	MMX reg36 (%mm7): undefined
+	FPU-control reg37 (%fctrl): undefined
+	FPU-control reg38 (%fstat): undefined
+	FPU-control reg39 (%mxcsr): undefined
+	segment reg40 (%es): same_value
+	segment reg41 (%cs): same_value
+	segment reg42 (%ss): same_value
+	segment reg43 (%ds): same_value
+	segment reg44 (%fs): same_value
+	segment reg45 (%gs): same_value
+.debug_frame has 0x80489b8 => [0x80489b8, 0x80489b9):
+	return address in reg8
+	CFA location expression: bregx(4,4)
+	integer reg0 (%eax): undefined
+	integer reg1 (%ecx): undefined
+	integer reg2 (%edx): undefined
+	integer reg3 (%ebx): same_value
+	integer reg4 (%esp): location expression: call_frame_cfa stack_value
+	integer reg5 (%ebp): same_value
+	integer reg6 (%esi): same_value
+	integer reg7 (%edi): same_value
+	integer reg8 (%eip): location expression: call_frame_cfa plus_uconst(-4)
+	integer reg9 (%eflags): undefined
+	integer reg10 (%trapno): undefined
+	x87 reg11 (%st0): undefined
+	x87 reg12 (%st1): undefined
+	x87 reg13 (%st2): undefined
+	x87 reg14 (%st3): undefined
+	x87 reg15 (%st4): undefined
+	x87 reg16 (%st5): undefined
+	x87 reg17 (%st6): undefined
+	x87 reg18 (%st7): undefined
+	SSE reg21 (%xmm0): undefined
+	SSE reg22 (%xmm1): undefined
+	SSE reg23 (%xmm2): undefined
+	SSE reg24 (%xmm3): undefined
+	SSE reg25 (%xmm4): undefined
+	SSE reg26 (%xmm5): undefined
+	SSE reg27 (%xmm6): undefined
+	SSE reg28 (%xmm7): undefined
+	MMX reg29 (%mm0): undefined
+	MMX reg30 (%mm1): undefined
+	MMX reg31 (%mm2): undefined
+	MMX reg32 (%mm3): undefined
+	MMX reg33 (%mm4): undefined
+	MMX reg34 (%mm5): undefined
+	MMX reg35 (%mm6): undefined
+	MMX reg36 (%mm7): undefined
+	FPU-control reg37 (%fctrl): undefined
+	FPU-control reg38 (%fstat): undefined
+	FPU-control reg39 (%mxcsr): undefined
+	segment reg40 (%es): same_value
+	segment reg41 (%cs): same_value
+	segment reg42 (%ss): same_value
+	segment reg43 (%ds): same_value
+	segment reg44 (%fs): same_value
+	segment reg45 (%gs): same_value
+EOF
+
+# EM_X86_64 (function foo 0x00000000000009d0)
+testfiles testfile12
+testrun_compare ${abs_builddir}/addrcfi -e testfile12 0x00000000000009d0 <<\EOF
+.eh_frame has 0x9d0 => [0x9d0, 0x9d1):
+	return address in reg16
+	CFA location expression: bregx(7,8)
+	integer reg0 (%rax): same_value
+	integer reg1 (%rdx): undefined
+	integer reg2 (%rcx): undefined
+	integer reg3 (%rbx): undefined
+	integer reg4 (%rsi): undefined
+	integer reg5 (%rdi): undefined
+	integer reg6 (%rbp): same_value
+	integer reg7 (%rsp): location expression: call_frame_cfa stack_value
+	integer reg8 (%r8): undefined
+	integer reg9 (%r9): undefined
+	integer reg10 (%r10): undefined
+	integer reg11 (%r11): undefined
+	integer reg12 (%r12): same_value
+	integer reg13 (%r13): same_value
+	integer reg14 (%r14): same_value
+	integer reg15 (%r15): same_value
+	integer reg16 (%rip): location expression: call_frame_cfa plus_uconst(-8)
+	SSE reg17 (%xmm0): undefined
+	SSE reg18 (%xmm1): undefined
+	SSE reg19 (%xmm2): undefined
+	SSE reg20 (%xmm3): undefined
+	SSE reg21 (%xmm4): undefined
+	SSE reg22 (%xmm5): undefined
+	SSE reg23 (%xmm6): undefined
+	SSE reg24 (%xmm7): undefined
+	SSE reg25 (%xmm8): undefined
+	SSE reg26 (%xmm9): undefined
+	SSE reg27 (%xmm10): undefined
+	SSE reg28 (%xmm11): undefined
+	SSE reg29 (%xmm12): undefined
+	SSE reg30 (%xmm13): undefined
+	SSE reg31 (%xmm14): undefined
+	SSE reg32 (%xmm15): undefined
+	x87 reg33 (%st0): undefined
+	x87 reg34 (%st1): undefined
+	x87 reg35 (%st2): undefined
+	x87 reg36 (%st3): undefined
+	x87 reg37 (%st4): undefined
+	x87 reg38 (%st5): undefined
+	x87 reg39 (%st6): undefined
+	x87 reg40 (%st7): undefined
+	MMX reg41 (%mm0): undefined
+	MMX reg42 (%mm1): undefined
+	MMX reg43 (%mm2): undefined
+	MMX reg44 (%mm3): undefined
+	MMX reg45 (%mm4): undefined
+	MMX reg46 (%mm5): undefined
+	MMX reg47 (%mm6): undefined
+	MMX reg48 (%mm7): undefined
+	integer reg49 (%rflags): undefined
+	segment reg50 (%es): undefined
+	segment reg51 (%cs): undefined
+	segment reg52 (%ss): undefined
+	segment reg53 (%ds): undefined
+	segment reg54 (%fs): undefined
+	segment reg55 (%gs): undefined
+	segment reg58 (%fs.base): undefined
+	segment reg59 (%gs.base): undefined
+	control reg62 (%tr): undefined
+	control reg63 (%ldtr): undefined
+	control reg64 (%mxcsr): undefined
+	control reg65 (%fcw): undefined
+	control reg66 (%fsw): undefined
+.debug_frame has 0x9d0 => [0x9d0, 0x9d1):
+	return address in reg16
+	CFA location expression: bregx(7,8)
+	integer reg0 (%rax): same_value
+	integer reg1 (%rdx): undefined
+	integer reg2 (%rcx): undefined
+	integer reg3 (%rbx): undefined
+	integer reg4 (%rsi): undefined
+	integer reg5 (%rdi): undefined
+	integer reg6 (%rbp): same_value
+	integer reg7 (%rsp): location expression: call_frame_cfa stack_value
+	integer reg8 (%r8): undefined
+	integer reg9 (%r9): undefined
+	integer reg10 (%r10): undefined
+	integer reg11 (%r11): undefined
+	integer reg12 (%r12): same_value
+	integer reg13 (%r13): same_value
+	integer reg14 (%r14): same_value
+	integer reg15 (%r15): same_value
+	integer reg16 (%rip): location expression: call_frame_cfa plus_uconst(-8)
+	SSE reg17 (%xmm0): undefined
+	SSE reg18 (%xmm1): undefined
+	SSE reg19 (%xmm2): undefined
+	SSE reg20 (%xmm3): undefined
+	SSE reg21 (%xmm4): undefined
+	SSE reg22 (%xmm5): undefined
+	SSE reg23 (%xmm6): undefined
+	SSE reg24 (%xmm7): undefined
+	SSE reg25 (%xmm8): undefined
+	SSE reg26 (%xmm9): undefined
+	SSE reg27 (%xmm10): undefined
+	SSE reg28 (%xmm11): undefined
+	SSE reg29 (%xmm12): undefined
+	SSE reg30 (%xmm13): undefined
+	SSE reg31 (%xmm14): undefined
+	SSE reg32 (%xmm15): undefined
+	x87 reg33 (%st0): undefined
+	x87 reg34 (%st1): undefined
+	x87 reg35 (%st2): undefined
+	x87 reg36 (%st3): undefined
+	x87 reg37 (%st4): undefined
+	x87 reg38 (%st5): undefined
+	x87 reg39 (%st6): undefined
+	x87 reg40 (%st7): undefined
+	MMX reg41 (%mm0): undefined
+	MMX reg42 (%mm1): undefined
+	MMX reg43 (%mm2): undefined
+	MMX reg44 (%mm3): undefined
+	MMX reg45 (%mm4): undefined
+	MMX reg46 (%mm5): undefined
+	MMX reg47 (%mm6): undefined
+	MMX reg48 (%mm7): undefined
+	integer reg49 (%rflags): undefined
+	segment reg50 (%es): undefined
+	segment reg51 (%cs): undefined
+	segment reg52 (%ss): undefined
+	segment reg53 (%ds): undefined
+	segment reg54 (%fs): undefined
+	segment reg55 (%gs): undefined
+	segment reg58 (%fs.base): undefined
+	segment reg59 (%gs.base): undefined
+	control reg62 (%tr): undefined
+	control reg63 (%ldtr): undefined
+	control reg64 (%mxcsr): undefined
+	control reg65 (%fcw): undefined
+	control reg66 (%fsw): undefined
+EOF
+
+# EM_PPC (function bar 0x100004c0)
+# Note. First only in .debug_frame, second only in .eh_frame.
+#
+# = bar.c =
+#
+# static int b1 = 1;
+# int b2 = 1;
+#
+# static int
+# foo (int a)
+# {
+#   return a + b2;
+# }
+#
+# int bar (int b)
+# {
+#   return b - foo (b - b1);
+# }
+#
+# = foo.c =
+#
+# extern int bar (int b);
+# extern int b2;
+#
+# int
+# main (int argc, char ** argv)
+# {
+#   return bar (argc + b2);
+# }
+#
+# gcc -g -O2 -m32 -c foo.c
+# gcc -g -O2 -m32 -c bar.c
+# gcc -g -O2 m32 -o testfileppc32 foo.o bar.o
+testfiles testfileppc32
+testrun_compare ${abs_builddir}/addrcfi -e testfileppc32 0x100004c0 <<\EOF
+dwarf_cfi_addrframe (.eh_frame): no matching address range
+.debug_frame has 0x100004c0 => [0x100004c0, 0x100004d0):
+	return address in reg65
+	CFA location expression: bregx(1)
+	integer reg0 (r0): undefined
+	integer reg1 (r1): location expression: call_frame_cfa stack_value
+	integer reg2 (r2): same_value
+	integer reg3 (r3): undefined
+	integer reg4 (r4): undefined
+	integer reg5 (r5): undefined
+	integer reg6 (r6): undefined
+	integer reg7 (r7): undefined
+	integer reg8 (r8): undefined
+	integer reg9 (r9): undefined
+	integer reg10 (r10): undefined
+	integer reg11 (r11): undefined
+	integer reg12 (r12): undefined
+	integer reg13 (r13): same_value
+	integer reg14 (r14): same_value
+	integer reg15 (r15): same_value
+	integer reg16 (r16): same_value
+	integer reg17 (r17): same_value
+	integer reg18 (r18): same_value
+	integer reg19 (r19): same_value
+	integer reg20 (r20): same_value
+	integer reg21 (r21): same_value
+	integer reg22 (r22): same_value
+	integer reg23 (r23): same_value
+	integer reg24 (r24): same_value
+	integer reg25 (r25): same_value
+	integer reg26 (r26): same_value
+	integer reg27 (r27): same_value
+	integer reg28 (r28): same_value
+	integer reg29 (r29): same_value
+	integer reg30 (r30): same_value
+	integer reg31 (r31): same_value
+	FPU reg32 (f0): undefined
+	FPU reg33 (f1): undefined
+	FPU reg34 (f2): undefined
+	FPU reg35 (f3): undefined
+	FPU reg36 (f4): undefined
+	FPU reg37 (f5): undefined
+	FPU reg38 (f6): undefined
+	FPU reg39 (f7): undefined
+	FPU reg40 (f8): undefined
+	FPU reg41 (f9): undefined
+	FPU reg42 (f10): undefined
+	FPU reg43 (f11): undefined
+	FPU reg44 (f12): undefined
+	FPU reg45 (f13): undefined
+	FPU reg46 (f14): undefined
+	FPU reg47 (f15): undefined
+	FPU reg48 (f16): undefined
+	FPU reg49 (f17): undefined
+	FPU reg50 (f18): undefined
+	FPU reg51 (f19): undefined
+	FPU reg52 (f20): undefined
+	FPU reg53 (f21): undefined
+	FPU reg54 (f22): undefined
+	FPU reg55 (f23): undefined
+	FPU reg56 (f24): undefined
+	FPU reg57 (f25): undefined
+	FPU reg58 (f26): undefined
+	FPU reg59 (f27): undefined
+	FPU reg60 (f28): undefined
+	FPU reg61 (f29): undefined
+	FPU reg62 (f30): undefined
+	FPU reg63 (f31): undefined
+	integer reg64 (cr): undefined
+	FPU reg65 (fpscr): same_value
+	integer reg66 (msr): undefined
+	vector reg67 (vscr): undefined
+	privileged reg70 (sr0): undefined
+	privileged reg71 (sr1): undefined
+	privileged reg72 (sr2): undefined
+	privileged reg73 (sr3): undefined
+	privileged reg74 (sr4): undefined
+	privileged reg75 (sr5): undefined
+	privileged reg76 (sr6): undefined
+	privileged reg77 (sr7): undefined
+	privileged reg78 (sr8): undefined
+	privileged reg79 (sr9): undefined
+	privileged reg80 (sr10): undefined
+	privileged reg81 (sr11): undefined
+	privileged reg82 (sr12): undefined
+	privileged reg83 (sr13): undefined
+	privileged reg84 (sr14): undefined
+	privileged reg85 (sr15): undefined
+	privileged reg100 (mq): undefined
+	privileged reg101 (xer): undefined
+	privileged reg102 (spr2): undefined
+	privileged reg103 (spr3): undefined
+	privileged reg104 (spr4): undefined
+	privileged reg105 (spr5): undefined
+	privileged reg106 (spr6): undefined
+	privileged reg107 (spr7): undefined
+	privileged reg108 (lr): undefined
+	privileged reg109 (ctr): undefined
+	privileged reg110 (spr10): undefined
+	privileged reg111 (spr11): undefined
+	privileged reg112 (spr12): undefined
+	privileged reg113 (spr13): undefined
+	privileged reg114 (tfhar): undefined
+	privileged reg115 (tfiar): undefined
+	privileged reg116 (texasr): undefined
+	privileged reg117 (spr17): undefined
+	privileged reg118 (dsisr): undefined
+	privileged reg119 (dar): undefined
+	privileged reg120 (spr20): undefined
+	privileged reg121 (spr21): undefined
+	privileged reg122 (dec): undefined
+	privileged reg123 (spr23): undefined
+	privileged reg124 (spr24): undefined
+	privileged reg125 (spr25): undefined
+	privileged reg126 (spr26): undefined
+	privileged reg127 (spr27): undefined
+	privileged reg128 (spr28): undefined
+	privileged reg129 (spr29): undefined
+	privileged reg130 (spr30): undefined
+	privileged reg131 (spr31): undefined
+	privileged reg132 (spr32): undefined
+	privileged reg133 (spr33): undefined
+	privileged reg134 (spr34): undefined
+	privileged reg135 (spr35): undefined
+	privileged reg136 (spr36): undefined
+	privileged reg137 (spr37): undefined
+	privileged reg138 (spr38): undefined
+	privileged reg139 (spr39): undefined
+	privileged reg140 (spr40): undefined
+	privileged reg141 (spr41): undefined
+	privileged reg142 (spr42): undefined
+	privileged reg143 (spr43): undefined
+	privileged reg144 (spr44): undefined
+	privileged reg145 (spr45): undefined
+	privileged reg146 (spr46): undefined
+	privileged reg147 (spr47): undefined
+	privileged reg148 (spr48): undefined
+	privileged reg149 (spr49): undefined
+	privileged reg150 (spr50): undefined
+	privileged reg151 (spr51): undefined
+	privileged reg152 (spr52): undefined
+	privileged reg153 (spr53): undefined
+	privileged reg154 (spr54): undefined
+	privileged reg155 (spr55): undefined
+	privileged reg156 (spr56): undefined
+	privileged reg157 (spr57): undefined
+	privileged reg158 (spr58): undefined
+	privileged reg159 (spr59): undefined
+	privileged reg160 (spr60): undefined
+	privileged reg161 (spr61): undefined
+	privileged reg162 (spr62): undefined
+	privileged reg163 (spr63): undefined
+	privileged reg164 (spr64): undefined
+	privileged reg165 (spr65): undefined
+	privileged reg166 (spr66): undefined
+	privileged reg167 (spr67): undefined
+	privileged reg168 (spr68): undefined
+	privileged reg169 (spr69): undefined
+	privileged reg170 (spr70): undefined
+	privileged reg171 (spr71): undefined
+	privileged reg172 (spr72): undefined
+	privileged reg173 (spr73): undefined
+	privileged reg174 (spr74): undefined
+	privileged reg175 (spr75): undefined
+	privileged reg176 (spr76): undefined
+	privileged reg177 (spr77): undefined
+	privileged reg178 (spr78): undefined
+	privileged reg179 (spr79): undefined
+	privileged reg180 (spr80): undefined
+	privileged reg181 (spr81): undefined
+	privileged reg182 (spr82): undefined
+	privileged reg183 (spr83): undefined
+	privileged reg184 (spr84): undefined
+	privileged reg185 (spr85): undefined
+	privileged reg186 (spr86): undefined
+	privileged reg187 (spr87): undefined
+	privileged reg188 (spr88): undefined
+	privileged reg189 (spr89): undefined
+	privileged reg190 (spr90): undefined
+	privileged reg191 (spr91): undefined
+	privileged reg192 (spr92): undefined
+	privileged reg193 (spr93): undefined
+	privileged reg194 (spr94): undefined
+	privileged reg195 (spr95): undefined
+	privileged reg196 (spr96): undefined
+	privileged reg197 (spr97): undefined
+	privileged reg198 (spr98): undefined
+	privileged reg199 (spr99): undefined
+	privileged reg200 (spr100): undefined
+	privileged reg201 (spr101): undefined
+	privileged reg202 (spr102): undefined
+	privileged reg203 (spr103): undefined
+	privileged reg204 (spr104): undefined
+	privileged reg205 (spr105): undefined
+	privileged reg206 (spr106): undefined
+	privileged reg207 (spr107): undefined
+	privileged reg208 (spr108): undefined
+	privileged reg209 (spr109): undefined
+	privileged reg210 (spr110): undefined
+	privileged reg211 (spr111): undefined
+	privileged reg212 (spr112): undefined
+	privileged reg213 (spr113): undefined
+	privileged reg214 (spr114): undefined
+	privileged reg215 (spr115): undefined
+	privileged reg216 (spr116): undefined
+	privileged reg217 (spr117): undefined
+	privileged reg218 (spr118): undefined
+	privileged reg219 (spr119): undefined
+	privileged reg220 (spr120): undefined
+	privileged reg221 (spr121): undefined
+	privileged reg222 (spr122): undefined
+	privileged reg223 (spr123): undefined
+	privileged reg224 (spr124): undefined
+	privileged reg225 (spr125): undefined
+	privileged reg226 (spr126): undefined
+	privileged reg227 (spr127): undefined
+	privileged reg228 (spr128): undefined
+	privileged reg229 (spr129): undefined
+	privileged reg230 (spr130): undefined
+	privileged reg231 (spr131): undefined
+	privileged reg232 (spr132): undefined
+	privileged reg233 (spr133): undefined
+	privileged reg234 (spr134): undefined
+	privileged reg235 (spr135): undefined
+	privileged reg236 (spr136): undefined
+	privileged reg237 (spr137): undefined
+	privileged reg238 (spr138): undefined
+	privileged reg239 (spr139): undefined
+	privileged reg240 (spr140): undefined
+	privileged reg241 (spr141): undefined
+	privileged reg242 (spr142): undefined
+	privileged reg243 (spr143): undefined
+	privileged reg244 (spr144): undefined
+	privileged reg245 (spr145): undefined
+	privileged reg246 (spr146): undefined
+	privileged reg247 (spr147): undefined
+	privileged reg248 (spr148): undefined
+	privileged reg249 (spr149): undefined
+	privileged reg250 (spr150): undefined
+	privileged reg251 (spr151): undefined
+	privileged reg252 (spr152): undefined
+	privileged reg253 (spr153): undefined
+	privileged reg254 (spr154): undefined
+	privileged reg255 (spr155): undefined
+	privileged reg256 (spr156): undefined
+	privileged reg257 (spr157): undefined
+	privileged reg258 (spr158): undefined
+	privileged reg259 (spr159): undefined
+	privileged reg260 (spr160): undefined
+	privileged reg261 (spr161): undefined
+	privileged reg262 (spr162): undefined
+	privileged reg263 (spr163): undefined
+	privileged reg264 (spr164): undefined
+	privileged reg265 (spr165): undefined
+	privileged reg266 (spr166): undefined
+	privileged reg267 (spr167): undefined
+	privileged reg268 (spr168): undefined
+	privileged reg269 (spr169): undefined
+	privileged reg270 (spr170): undefined
+	privileged reg271 (spr171): undefined
+	privileged reg272 (spr172): undefined
+	privileged reg273 (spr173): undefined
+	privileged reg274 (spr174): undefined
+	privileged reg275 (spr175): undefined
+	privileged reg276 (spr176): undefined
+	privileged reg277 (spr177): undefined
+	privileged reg278 (spr178): undefined
+	privileged reg279 (spr179): undefined
+	privileged reg280 (spr180): undefined
+	privileged reg281 (spr181): undefined
+	privileged reg282 (spr182): undefined
+	privileged reg283 (spr183): undefined
+	privileged reg284 (spr184): undefined
+	privileged reg285 (spr185): undefined
+	privileged reg286 (spr186): undefined
+	privileged reg287 (spr187): undefined
+	privileged reg288 (spr188): undefined
+	privileged reg289 (spr189): undefined
+	privileged reg290 (spr190): undefined
+	privileged reg291 (spr191): undefined
+	privileged reg292 (spr192): undefined
+	privileged reg293 (spr193): undefined
+	privileged reg294 (spr194): undefined
+	privileged reg295 (spr195): undefined
+	privileged reg296 (spr196): undefined
+	privileged reg297 (spr197): undefined
+	privileged reg298 (spr198): undefined
+	privileged reg299 (spr199): undefined
+	privileged reg300 (spr200): undefined
+	privileged reg301 (spr201): undefined
+	privileged reg302 (spr202): undefined
+	privileged reg303 (spr203): undefined
+	privileged reg304 (spr204): undefined
+	privileged reg305 (spr205): undefined
+	privileged reg306 (spr206): undefined
+	privileged reg307 (spr207): undefined
+	privileged reg308 (spr208): undefined
+	privileged reg309 (spr209): undefined
+	privileged reg310 (spr210): undefined
+	privileged reg311 (spr211): undefined
+	privileged reg312 (spr212): undefined
+	privileged reg313 (spr213): undefined
+	privileged reg314 (spr214): undefined
+	privileged reg315 (spr215): undefined
+	privileged reg316 (spr216): undefined
+	privileged reg317 (spr217): undefined
+	privileged reg318 (spr218): undefined
+	privileged reg319 (spr219): undefined
+	privileged reg320 (spr220): undefined
+	privileged reg321 (spr221): undefined
+	privileged reg322 (spr222): undefined
+	privileged reg323 (spr223): undefined
+	privileged reg324 (spr224): undefined
+	privileged reg325 (spr225): undefined
+	privileged reg326 (spr226): undefined
+	privileged reg327 (spr227): undefined
+	privileged reg328 (spr228): undefined
+	privileged reg329 (spr229): undefined
+	privileged reg330 (spr230): undefined
+	privileged reg331 (spr231): undefined
+	privileged reg332 (spr232): undefined
+	privileged reg333 (spr233): undefined
+	privileged reg334 (spr234): undefined
+	privileged reg335 (spr235): undefined
+	privileged reg336 (spr236): undefined
+	privileged reg337 (spr237): undefined
+	privileged reg338 (spr238): undefined
+	privileged reg339 (spr239): undefined
+	privileged reg340 (spr240): undefined
+	privileged reg341 (spr241): undefined
+	privileged reg342 (spr242): undefined
+	privileged reg343 (spr243): undefined
+	privileged reg344 (spr244): undefined
+	privileged reg345 (spr245): undefined
+	privileged reg346 (spr246): undefined
+	privileged reg347 (spr247): undefined
+	privileged reg348 (spr248): undefined
+	privileged reg349 (spr249): undefined
+	privileged reg350 (spr250): undefined
+	privileged reg351 (spr251): undefined
+	privileged reg352 (spr252): undefined
+	privileged reg353 (spr253): undefined
+	privileged reg354 (spr254): undefined
+	privileged reg355 (spr255): undefined
+	vector reg356 (vrsave): undefined
+	privileged reg357 (spr257): undefined
+	privileged reg358 (spr258): undefined
+	privileged reg359 (spr259): undefined
+	privileged reg360 (spr260): undefined
+	privileged reg361 (spr261): undefined
+	privileged reg362 (spr262): undefined
+	privileged reg363 (spr263): undefined
+	privileged reg364 (spr264): undefined
+	privileged reg365 (spr265): undefined
+	privileged reg366 (spr266): undefined
+	privileged reg367 (spr267): undefined
+	privileged reg368 (spr268): undefined
+	privileged reg369 (spr269): undefined
+	privileged reg370 (spr270): undefined
+	privileged reg371 (spr271): undefined
+	privileged reg372 (spr272): undefined
+	privileged reg373 (spr273): undefined
+	privileged reg374 (spr274): undefined
+	privileged reg375 (spr275): undefined
+	privileged reg376 (spr276): undefined
+	privileged reg377 (spr277): undefined
+	privileged reg378 (spr278): undefined
+	privileged reg379 (spr279): undefined
+	privileged reg380 (spr280): undefined
+	privileged reg381 (spr281): undefined
+	privileged reg382 (spr282): undefined
+	privileged reg383 (spr283): undefined
+	privileged reg384 (spr284): undefined
+	privileged reg385 (spr285): undefined
+	privileged reg386 (spr286): undefined
+	privileged reg387 (spr287): undefined
+	privileged reg388 (spr288): undefined
+	privileged reg389 (spr289): undefined
+	privileged reg390 (spr290): undefined
+	privileged reg391 (spr291): undefined
+	privileged reg392 (spr292): undefined
+	privileged reg393 (spr293): undefined
+	privileged reg394 (spr294): undefined
+	privileged reg395 (spr295): undefined
+	privileged reg396 (spr296): undefined
+	privileged reg397 (spr297): undefined
+	privileged reg398 (spr298): undefined
+	privileged reg399 (spr299): undefined
+	privileged reg400 (spr300): undefined
+	privileged reg401 (spr301): undefined
+	privileged reg402 (spr302): undefined
+	privileged reg403 (spr303): undefined
+	privileged reg404 (spr304): undefined
+	privileged reg405 (spr305): undefined
+	privileged reg406 (spr306): undefined
+	privileged reg407 (spr307): undefined
+	privileged reg408 (spr308): undefined
+	privileged reg409 (spr309): undefined
+	privileged reg410 (spr310): undefined
+	privileged reg411 (spr311): undefined
+	privileged reg412 (spr312): undefined
+	privileged reg413 (spr313): undefined
+	privileged reg414 (spr314): undefined
+	privileged reg415 (spr315): undefined
+	privileged reg416 (spr316): undefined
+	privileged reg417 (spr317): undefined
+	privileged reg418 (spr318): undefined
+	privileged reg419 (spr319): undefined
+	privileged reg420 (spr320): undefined
+	privileged reg421 (spr321): undefined
+	privileged reg422 (spr322): undefined
+	privileged reg423 (spr323): undefined
+	privileged reg424 (spr324): undefined
+	privileged reg425 (spr325): undefined
+	privileged reg426 (spr326): undefined
+	privileged reg427 (spr327): undefined
+	privileged reg428 (spr328): undefined
+	privileged reg429 (spr329): undefined
+	privileged reg430 (spr330): undefined
+	privileged reg431 (spr331): undefined
+	privileged reg432 (spr332): undefined
+	privileged reg433 (spr333): undefined
+	privileged reg434 (spr334): undefined
+	privileged reg435 (spr335): undefined
+	privileged reg436 (spr336): undefined
+	privileged reg437 (spr337): undefined
+	privileged reg438 (spr338): undefined
+	privileged reg439 (spr339): undefined
+	privileged reg440 (spr340): undefined
+	privileged reg441 (spr341): undefined
+	privileged reg442 (spr342): undefined
+	privileged reg443 (spr343): undefined
+	privileged reg444 (spr344): undefined
+	privileged reg445 (spr345): undefined
+	privileged reg446 (spr346): undefined
+	privileged reg447 (spr347): undefined
+	privileged reg448 (spr348): undefined
+	privileged reg449 (spr349): undefined
+	privileged reg450 (spr350): undefined
+	privileged reg451 (spr351): undefined
+	privileged reg452 (spr352): undefined
+	privileged reg453 (spr353): undefined
+	privileged reg454 (spr354): undefined
+	privileged reg455 (spr355): undefined
+	privileged reg456 (spr356): undefined
+	privileged reg457 (spr357): undefined
+	privileged reg458 (spr358): undefined
+	privileged reg459 (spr359): undefined
+	privileged reg460 (spr360): undefined
+	privileged reg461 (spr361): undefined
+	privileged reg462 (spr362): undefined
+	privileged reg463 (spr363): undefined
+	privileged reg464 (spr364): undefined
+	privileged reg465 (spr365): undefined
+	privileged reg466 (spr366): undefined
+	privileged reg467 (spr367): undefined
+	privileged reg468 (spr368): undefined
+	privileged reg469 (spr369): undefined
+	privileged reg470 (spr370): undefined
+	privileged reg471 (spr371): undefined
+	privileged reg472 (spr372): undefined
+	privileged reg473 (spr373): undefined
+	privileged reg474 (spr374): undefined
+	privileged reg475 (spr375): undefined
+	privileged reg476 (spr376): undefined
+	privileged reg477 (spr377): undefined
+	privileged reg478 (spr378): undefined
+	privileged reg479 (spr379): undefined
+	privileged reg480 (spr380): undefined
+	privileged reg481 (spr381): undefined
+	privileged reg482 (spr382): undefined
+	privileged reg483 (spr383): undefined
+	privileged reg484 (spr384): undefined
+	privileged reg485 (spr385): undefined
+	privileged reg486 (spr386): undefined
+	privileged reg487 (spr387): undefined
+	privileged reg488 (spr388): undefined
+	privileged reg489 (spr389): undefined
+	privileged reg490 (spr390): undefined
+	privileged reg491 (spr391): undefined
+	privileged reg492 (spr392): undefined
+	privileged reg493 (spr393): undefined
+	privileged reg494 (spr394): undefined
+	privileged reg495 (spr395): undefined
+	privileged reg496 (spr396): undefined
+	privileged reg497 (spr397): undefined
+	privileged reg498 (spr398): undefined
+	privileged reg499 (spr399): undefined
+	privileged reg500 (spr400): undefined
+	privileged reg501 (spr401): undefined
+	privileged reg502 (spr402): undefined
+	privileged reg503 (spr403): undefined
+	privileged reg504 (spr404): undefined
+	privileged reg505 (spr405): undefined
+	privileged reg506 (spr406): undefined
+	privileged reg507 (spr407): undefined
+	privileged reg508 (spr408): undefined
+	privileged reg509 (spr409): undefined
+	privileged reg510 (spr410): undefined
+	privileged reg511 (spr411): undefined
+	privileged reg512 (spr412): undefined
+	privileged reg513 (spr413): undefined
+	privileged reg514 (spr414): undefined
+	privileged reg515 (spr415): undefined
+	privileged reg516 (spr416): undefined
+	privileged reg517 (spr417): undefined
+	privileged reg518 (spr418): undefined
+	privileged reg519 (spr419): undefined
+	privileged reg520 (spr420): undefined
+	privileged reg521 (spr421): undefined
+	privileged reg522 (spr422): undefined
+	privileged reg523 (spr423): undefined
+	privileged reg524 (spr424): undefined
+	privileged reg525 (spr425): undefined
+	privileged reg526 (spr426): undefined
+	privileged reg527 (spr427): undefined
+	privileged reg528 (spr428): undefined
+	privileged reg529 (spr429): undefined
+	privileged reg530 (spr430): undefined
+	privileged reg531 (spr431): undefined
+	privileged reg532 (spr432): undefined
+	privileged reg533 (spr433): undefined
+	privileged reg534 (spr434): undefined
+	privileged reg535 (spr435): undefined
+	privileged reg536 (spr436): undefined
+	privileged reg537 (spr437): undefined
+	privileged reg538 (spr438): undefined
+	privileged reg539 (spr439): undefined
+	privileged reg540 (spr440): undefined
+	privileged reg541 (spr441): undefined
+	privileged reg542 (spr442): undefined
+	privileged reg543 (spr443): undefined
+	privileged reg544 (spr444): undefined
+	privileged reg545 (spr445): undefined
+	privileged reg546 (spr446): undefined
+	privileged reg547 (spr447): undefined
+	privileged reg548 (spr448): undefined
+	privileged reg549 (spr449): undefined
+	privileged reg550 (spr450): undefined
+	privileged reg551 (spr451): undefined
+	privileged reg552 (spr452): undefined
+	privileged reg553 (spr453): undefined
+	privileged reg554 (spr454): undefined
+	privileged reg555 (spr455): undefined
+	privileged reg556 (spr456): undefined
+	privileged reg557 (spr457): undefined
+	privileged reg558 (spr458): undefined
+	privileged reg559 (spr459): undefined
+	privileged reg560 (spr460): undefined
+	privileged reg561 (spr461): undefined
+	privileged reg562 (spr462): undefined
+	privileged reg563 (spr463): undefined
+	privileged reg564 (spr464): undefined
+	privileged reg565 (spr465): undefined
+	privileged reg566 (spr466): undefined
+	privileged reg567 (spr467): undefined
+	privileged reg568 (spr468): undefined
+	privileged reg569 (spr469): undefined
+	privileged reg570 (spr470): undefined
+	privileged reg571 (spr471): undefined
+	privileged reg572 (spr472): undefined
+	privileged reg573 (spr473): undefined
+	privileged reg574 (spr474): undefined
+	privileged reg575 (spr475): undefined
+	privileged reg576 (spr476): undefined
+	privileged reg577 (spr477): undefined
+	privileged reg578 (spr478): undefined
+	privileged reg579 (spr479): undefined
+	privileged reg580 (spr480): undefined
+	privileged reg581 (spr481): undefined
+	privileged reg582 (spr482): undefined
+	privileged reg583 (spr483): undefined
+	privileged reg584 (spr484): undefined
+	privileged reg585 (spr485): undefined
+	privileged reg586 (spr486): undefined
+	privileged reg587 (spr487): undefined
+	privileged reg588 (spr488): undefined
+	privileged reg589 (spr489): undefined
+	privileged reg590 (spr490): undefined
+	privileged reg591 (spr491): undefined
+	privileged reg592 (spr492): undefined
+	privileged reg593 (spr493): undefined
+	privileged reg594 (spr494): undefined
+	privileged reg595 (spr495): undefined
+	privileged reg596 (spr496): undefined
+	privileged reg597 (spr497): undefined
+	privileged reg598 (spr498): undefined
+	privileged reg599 (spr499): undefined
+	privileged reg600 (spr500): undefined
+	privileged reg601 (spr501): undefined
+	privileged reg602 (spr502): undefined
+	privileged reg603 (spr503): undefined
+	privileged reg604 (spr504): undefined
+	privileged reg605 (spr505): undefined
+	privileged reg606 (spr506): undefined
+	privileged reg607 (spr507): undefined
+	privileged reg608 (spr508): undefined
+	privileged reg609 (spr509): undefined
+	privileged reg610 (spr510): undefined
+	privileged reg611 (spr511): undefined
+	vector reg612 (spefscr): undefined
+	privileged reg613 (spr513): undefined
+	privileged reg614 (spr514): undefined
+	privileged reg615 (spr515): undefined
+	privileged reg616 (spr516): undefined
+	privileged reg617 (spr517): undefined
+	privileged reg618 (spr518): undefined
+	privileged reg619 (spr519): undefined
+	privileged reg620 (spr520): undefined
+	privileged reg621 (spr521): undefined
+	privileged reg622 (spr522): undefined
+	privileged reg623 (spr523): undefined
+	privileged reg624 (spr524): undefined
+	privileged reg625 (spr525): undefined
+	privileged reg626 (spr526): undefined
+	privileged reg627 (spr527): undefined
+	privileged reg628 (spr528): undefined
+	privileged reg629 (spr529): undefined
+	privileged reg630 (spr530): undefined
+	privileged reg631 (spr531): undefined
+	privileged reg632 (spr532): undefined
+	privileged reg633 (spr533): undefined
+	privileged reg634 (spr534): undefined
+	privileged reg635 (spr535): undefined
+	privileged reg636 (spr536): undefined
+	privileged reg637 (spr537): undefined
+	privileged reg638 (spr538): undefined
+	privileged reg639 (spr539): undefined
+	privileged reg640 (spr540): undefined
+	privileged reg641 (spr541): undefined
+	privileged reg642 (spr542): undefined
+	privileged reg643 (spr543): undefined
+	privileged reg644 (spr544): undefined
+	privileged reg645 (spr545): undefined
+	privileged reg646 (spr546): undefined
+	privileged reg647 (spr547): undefined
+	privileged reg648 (spr548): undefined
+	privileged reg649 (spr549): undefined
+	privileged reg650 (spr550): undefined
+	privileged reg651 (spr551): undefined
+	privileged reg652 (spr552): undefined
+	privileged reg653 (spr553): undefined
+	privileged reg654 (spr554): undefined
+	privileged reg655 (spr555): undefined
+	privileged reg656 (spr556): undefined
+	privileged reg657 (spr557): undefined
+	privileged reg658 (spr558): undefined
+	privileged reg659 (spr559): undefined
+	privileged reg660 (spr560): undefined
+	privileged reg661 (spr561): undefined
+	privileged reg662 (spr562): undefined
+	privileged reg663 (spr563): undefined
+	privileged reg664 (spr564): undefined
+	privileged reg665 (spr565): undefined
+	privileged reg666 (spr566): undefined
+	privileged reg667 (spr567): undefined
+	privileged reg668 (spr568): undefined
+	privileged reg669 (spr569): undefined
+	privileged reg670 (spr570): undefined
+	privileged reg671 (spr571): undefined
+	privileged reg672 (spr572): undefined
+	privileged reg673 (spr573): undefined
+	privileged reg674 (spr574): undefined
+	privileged reg675 (spr575): undefined
+	privileged reg676 (spr576): undefined
+	privileged reg677 (spr577): undefined
+	privileged reg678 (spr578): undefined
+	privileged reg679 (spr579): undefined
+	privileged reg680 (spr580): undefined
+	privileged reg681 (spr581): undefined
+	privileged reg682 (spr582): undefined
+	privileged reg683 (spr583): undefined
+	privileged reg684 (spr584): undefined
+	privileged reg685 (spr585): undefined
+	privileged reg686 (spr586): undefined
+	privileged reg687 (spr587): undefined
+	privileged reg688 (spr588): undefined
+	privileged reg689 (spr589): undefined
+	privileged reg690 (spr590): undefined
+	privileged reg691 (spr591): undefined
+	privileged reg692 (spr592): undefined
+	privileged reg693 (spr593): undefined
+	privileged reg694 (spr594): undefined
+	privileged reg695 (spr595): undefined
+	privileged reg696 (spr596): undefined
+	privileged reg697 (spr597): undefined
+	privileged reg698 (spr598): undefined
+	privileged reg699 (spr599): undefined
+	privileged reg700 (spr600): undefined
+	privileged reg701 (spr601): undefined
+	privileged reg702 (spr602): undefined
+	privileged reg703 (spr603): undefined
+	privileged reg704 (spr604): undefined
+	privileged reg705 (spr605): undefined
+	privileged reg706 (spr606): undefined
+	privileged reg707 (spr607): undefined
+	privileged reg708 (spr608): undefined
+	privileged reg709 (spr609): undefined
+	privileged reg710 (spr610): undefined
+	privileged reg711 (spr611): undefined
+	privileged reg712 (spr612): undefined
+	privileged reg713 (spr613): undefined
+	privileged reg714 (spr614): undefined
+	privileged reg715 (spr615): undefined
+	privileged reg716 (spr616): undefined
+	privileged reg717 (spr617): undefined
+	privileged reg718 (spr618): undefined
+	privileged reg719 (spr619): undefined
+	privileged reg720 (spr620): undefined
+	privileged reg721 (spr621): undefined
+	privileged reg722 (spr622): undefined
+	privileged reg723 (spr623): undefined
+	privileged reg724 (spr624): undefined
+	privileged reg725 (spr625): undefined
+	privileged reg726 (spr626): undefined
+	privileged reg727 (spr627): undefined
+	privileged reg728 (spr628): undefined
+	privileged reg729 (spr629): undefined
+	privileged reg730 (spr630): undefined
+	privileged reg731 (spr631): undefined
+	privileged reg732 (spr632): undefined
+	privileged reg733 (spr633): undefined
+	privileged reg734 (spr634): undefined
+	privileged reg735 (spr635): undefined
+	privileged reg736 (spr636): undefined
+	privileged reg737 (spr637): undefined
+	privileged reg738 (spr638): undefined
+	privileged reg739 (spr639): undefined
+	privileged reg740 (spr640): undefined
+	privileged reg741 (spr641): undefined
+	privileged reg742 (spr642): undefined
+	privileged reg743 (spr643): undefined
+	privileged reg744 (spr644): undefined
+	privileged reg745 (spr645): undefined
+	privileged reg746 (spr646): undefined
+	privileged reg747 (spr647): undefined
+	privileged reg748 (spr648): undefined
+	privileged reg749 (spr649): undefined
+	privileged reg750 (spr650): undefined
+	privileged reg751 (spr651): undefined
+	privileged reg752 (spr652): undefined
+	privileged reg753 (spr653): undefined
+	privileged reg754 (spr654): undefined
+	privileged reg755 (spr655): undefined
+	privileged reg756 (spr656): undefined
+	privileged reg757 (spr657): undefined
+	privileged reg758 (spr658): undefined
+	privileged reg759 (spr659): undefined
+	privileged reg760 (spr660): undefined
+	privileged reg761 (spr661): undefined
+	privileged reg762 (spr662): undefined
+	privileged reg763 (spr663): undefined
+	privileged reg764 (spr664): undefined
+	privileged reg765 (spr665): undefined
+	privileged reg766 (spr666): undefined
+	privileged reg767 (spr667): undefined
+	privileged reg768 (spr668): undefined
+	privileged reg769 (spr669): undefined
+	privileged reg770 (spr670): undefined
+	privileged reg771 (spr671): undefined
+	privileged reg772 (spr672): undefined
+	privileged reg773 (spr673): undefined
+	privileged reg774 (spr674): undefined
+	privileged reg775 (spr675): undefined
+	privileged reg776 (spr676): undefined
+	privileged reg777 (spr677): undefined
+	privileged reg778 (spr678): undefined
+	privileged reg779 (spr679): undefined
+	privileged reg780 (spr680): undefined
+	privileged reg781 (spr681): undefined
+	privileged reg782 (spr682): undefined
+	privileged reg783 (spr683): undefined
+	privileged reg784 (spr684): undefined
+	privileged reg785 (spr685): undefined
+	privileged reg786 (spr686): undefined
+	privileged reg787 (spr687): undefined
+	privileged reg788 (spr688): undefined
+	privileged reg789 (spr689): undefined
+	privileged reg790 (spr690): undefined
+	privileged reg791 (spr691): undefined
+	privileged reg792 (spr692): undefined
+	privileged reg793 (spr693): undefined
+	privileged reg794 (spr694): undefined
+	privileged reg795 (spr695): undefined
+	privileged reg796 (spr696): undefined
+	privileged reg797 (spr697): undefined
+	privileged reg798 (spr698): undefined
+	privileged reg799 (spr699): undefined
+	privileged reg800 (spr700): undefined
+	privileged reg801 (spr701): undefined
+	privileged reg802 (spr702): undefined
+	privileged reg803 (spr703): undefined
+	privileged reg804 (spr704): undefined
+	privileged reg805 (spr705): undefined
+	privileged reg806 (spr706): undefined
+	privileged reg807 (spr707): undefined
+	privileged reg808 (spr708): undefined
+	privileged reg809 (spr709): undefined
+	privileged reg810 (spr710): undefined
+	privileged reg811 (spr711): undefined
+	privileged reg812 (spr712): undefined
+	privileged reg813 (spr713): undefined
+	privileged reg814 (spr714): undefined
+	privileged reg815 (spr715): undefined
+	privileged reg816 (spr716): undefined
+	privileged reg817 (spr717): undefined
+	privileged reg818 (spr718): undefined
+	privileged reg819 (spr719): undefined
+	privileged reg820 (spr720): undefined
+	privileged reg821 (spr721): undefined
+	privileged reg822 (spr722): undefined
+	privileged reg823 (spr723): undefined
+	privileged reg824 (spr724): undefined
+	privileged reg825 (spr725): undefined
+	privileged reg826 (spr726): undefined
+	privileged reg827 (spr727): undefined
+	privileged reg828 (spr728): undefined
+	privileged reg829 (spr729): undefined
+	privileged reg830 (spr730): undefined
+	privileged reg831 (spr731): undefined
+	privileged reg832 (spr732): undefined
+	privileged reg833 (spr733): undefined
+	privileged reg834 (spr734): undefined
+	privileged reg835 (spr735): undefined
+	privileged reg836 (spr736): undefined
+	privileged reg837 (spr737): undefined
+	privileged reg838 (spr738): undefined
+	privileged reg839 (spr739): undefined
+	privileged reg840 (spr740): undefined
+	privileged reg841 (spr741): undefined
+	privileged reg842 (spr742): undefined
+	privileged reg843 (spr743): undefined
+	privileged reg844 (spr744): undefined
+	privileged reg845 (spr745): undefined
+	privileged reg846 (spr746): undefined
+	privileged reg847 (spr747): undefined
+	privileged reg848 (spr748): undefined
+	privileged reg849 (spr749): undefined
+	privileged reg850 (spr750): undefined
+	privileged reg851 (spr751): undefined
+	privileged reg852 (spr752): undefined
+	privileged reg853 (spr753): undefined
+	privileged reg854 (spr754): undefined
+	privileged reg855 (spr755): undefined
+	privileged reg856 (spr756): undefined
+	privileged reg857 (spr757): undefined
+	privileged reg858 (spr758): undefined
+	privileged reg859 (spr759): undefined
+	privileged reg860 (spr760): undefined
+	privileged reg861 (spr761): undefined
+	privileged reg862 (spr762): undefined
+	privileged reg863 (spr763): undefined
+	privileged reg864 (spr764): undefined
+	privileged reg865 (spr765): undefined
+	privileged reg866 (spr766): undefined
+	privileged reg867 (spr767): undefined
+	privileged reg868 (spr768): undefined
+	privileged reg869 (spr769): undefined
+	privileged reg870 (spr770): undefined
+	privileged reg871 (spr771): undefined
+	privileged reg872 (spr772): undefined
+	privileged reg873 (spr773): undefined
+	privileged reg874 (spr774): undefined
+	privileged reg875 (spr775): undefined
+	privileged reg876 (spr776): undefined
+	privileged reg877 (spr777): undefined
+	privileged reg878 (spr778): undefined
+	privileged reg879 (spr779): undefined
+	privileged reg880 (spr780): undefined
+	privileged reg881 (spr781): undefined
+	privileged reg882 (spr782): undefined
+	privileged reg883 (spr783): undefined
+	privileged reg884 (spr784): undefined
+	privileged reg885 (spr785): undefined
+	privileged reg886 (spr786): undefined
+	privileged reg887 (spr787): undefined
+	privileged reg888 (spr788): undefined
+	privileged reg889 (spr789): undefined
+	privileged reg890 (spr790): undefined
+	privileged reg891 (spr791): undefined
+	privileged reg892 (spr792): undefined
+	privileged reg893 (spr793): undefined
+	privileged reg894 (spr794): undefined
+	privileged reg895 (spr795): undefined
+	privileged reg896 (spr796): undefined
+	privileged reg897 (spr797): undefined
+	privileged reg898 (spr798): undefined
+	privileged reg899 (spr799): undefined
+	privileged reg900 (spr800): undefined
+	privileged reg901 (spr801): undefined
+	privileged reg902 (spr802): undefined
+	privileged reg903 (spr803): undefined
+	privileged reg904 (spr804): undefined
+	privileged reg905 (spr805): undefined
+	privileged reg906 (spr806): undefined
+	privileged reg907 (spr807): undefined
+	privileged reg908 (spr808): undefined
+	privileged reg909 (spr809): undefined
+	privileged reg910 (spr810): undefined
+	privileged reg911 (spr811): undefined
+	privileged reg912 (spr812): undefined
+	privileged reg913 (spr813): undefined
+	privileged reg914 (spr814): undefined
+	privileged reg915 (spr815): undefined
+	privileged reg916 (spr816): undefined
+	privileged reg917 (spr817): undefined
+	privileged reg918 (spr818): undefined
+	privileged reg919 (spr819): undefined
+	privileged reg920 (spr820): undefined
+	privileged reg921 (spr821): undefined
+	privileged reg922 (spr822): undefined
+	privileged reg923 (spr823): undefined
+	privileged reg924 (spr824): undefined
+	privileged reg925 (spr825): undefined
+	privileged reg926 (spr826): undefined
+	privileged reg927 (spr827): undefined
+	privileged reg928 (spr828): undefined
+	privileged reg929 (spr829): undefined
+	privileged reg930 (spr830): undefined
+	privileged reg931 (spr831): undefined
+	privileged reg932 (spr832): undefined
+	privileged reg933 (spr833): undefined
+	privileged reg934 (spr834): undefined
+	privileged reg935 (spr835): undefined
+	privileged reg936 (spr836): undefined
+	privileged reg937 (spr837): undefined
+	privileged reg938 (spr838): undefined
+	privileged reg939 (spr839): undefined
+	privileged reg940 (spr840): undefined
+	privileged reg941 (spr841): undefined
+	privileged reg942 (spr842): undefined
+	privileged reg943 (spr843): undefined
+	privileged reg944 (spr844): undefined
+	privileged reg945 (spr845): undefined
+	privileged reg946 (spr846): undefined
+	privileged reg947 (spr847): undefined
+	privileged reg948 (spr848): undefined
+	privileged reg949 (spr849): undefined
+	privileged reg950 (spr850): undefined
+	privileged reg951 (spr851): undefined
+	privileged reg952 (spr852): undefined
+	privileged reg953 (spr853): undefined
+	privileged reg954 (spr854): undefined
+	privileged reg955 (spr855): undefined
+	privileged reg956 (spr856): undefined
+	privileged reg957 (spr857): undefined
+	privileged reg958 (spr858): undefined
+	privileged reg959 (spr859): undefined
+	privileged reg960 (spr860): undefined
+	privileged reg961 (spr861): undefined
+	privileged reg962 (spr862): undefined
+	privileged reg963 (spr863): undefined
+	privileged reg964 (spr864): undefined
+	privileged reg965 (spr865): undefined
+	privileged reg966 (spr866): undefined
+	privileged reg967 (spr867): undefined
+	privileged reg968 (spr868): undefined
+	privileged reg969 (spr869): undefined
+	privileged reg970 (spr870): undefined
+	privileged reg971 (spr871): undefined
+	privileged reg972 (spr872): undefined
+	privileged reg973 (spr873): undefined
+	privileged reg974 (spr874): undefined
+	privileged reg975 (spr875): undefined
+	privileged reg976 (spr876): undefined
+	privileged reg977 (spr877): undefined
+	privileged reg978 (spr878): undefined
+	privileged reg979 (spr879): undefined
+	privileged reg980 (spr880): undefined
+	privileged reg981 (spr881): undefined
+	privileged reg982 (spr882): undefined
+	privileged reg983 (spr883): undefined
+	privileged reg984 (spr884): undefined
+	privileged reg985 (spr885): undefined
+	privileged reg986 (spr886): undefined
+	privileged reg987 (spr887): undefined
+	privileged reg988 (spr888): undefined
+	privileged reg989 (spr889): undefined
+	privileged reg990 (spr890): undefined
+	privileged reg991 (spr891): undefined
+	privileged reg992 (spr892): undefined
+	privileged reg993 (spr893): undefined
+	privileged reg994 (spr894): undefined
+	privileged reg995 (spr895): undefined
+	privileged reg996 (spr896): undefined
+	privileged reg997 (spr897): undefined
+	privileged reg998 (spr898): undefined
+	privileged reg999 (spr899): undefined
+	vector reg1124 (vr0): undefined
+	vector reg1125 (vr1): undefined
+	vector reg1126 (vr2): undefined
+	vector reg1127 (vr3): undefined
+	vector reg1128 (vr4): undefined
+	vector reg1129 (vr5): undefined
+	vector reg1130 (vr6): undefined
+	vector reg1131 (vr7): undefined
+	vector reg1132 (vr8): undefined
+	vector reg1133 (vr9): undefined
+	vector reg1134 (vr10): undefined
+	vector reg1135 (vr11): undefined
+	vector reg1136 (vr12): undefined
+	vector reg1137 (vr13): undefined
+	vector reg1138 (vr14): undefined
+	vector reg1139 (vr15): undefined
+	vector reg1140 (vr16): undefined
+	vector reg1141 (vr17): undefined
+	vector reg1142 (vr18): undefined
+	vector reg1143 (vr19): undefined
+	vector reg1144 (vr20): undefined
+	vector reg1145 (vr21): undefined
+	vector reg1146 (vr22): undefined
+	vector reg1147 (vr23): undefined
+	vector reg1148 (vr24): undefined
+	vector reg1149 (vr25): undefined
+	vector reg1150 (vr26): undefined
+	vector reg1151 (vr27): undefined
+	vector reg1152 (vr28): undefined
+	vector reg1153 (vr29): undefined
+	vector reg1154 (vr30): undefined
+	vector reg1155 (vr31): undefined
+EOF
+
+testrun_compare ${abs_builddir}/addrcfi -e testfileppc32 0x100004d2 <<\EOF
+.eh_frame has 0x100004d2 => [0x100004d0, 0x100004d4):
+	return address in reg65
+	CFA location expression: bregx(1)
+	integer reg0 (r0): undefined
+	integer reg1 (r1): location expression: call_frame_cfa stack_value
+	integer reg2 (r2): same_value
+	integer reg3 (r3): undefined
+	integer reg4 (r4): undefined
+	integer reg5 (r5): undefined
+	integer reg6 (r6): undefined
+	integer reg7 (r7): undefined
+	integer reg8 (r8): undefined
+	integer reg9 (r9): undefined
+	integer reg10 (r10): undefined
+	integer reg11 (r11): undefined
+	integer reg12 (r12): undefined
+	integer reg13 (r13): same_value
+	integer reg14 (r14): same_value
+	integer reg15 (r15): same_value
+	integer reg16 (r16): same_value
+	integer reg17 (r17): same_value
+	integer reg18 (r18): same_value
+	integer reg19 (r19): same_value
+	integer reg20 (r20): same_value
+	integer reg21 (r21): same_value
+	integer reg22 (r22): same_value
+	integer reg23 (r23): same_value
+	integer reg24 (r24): same_value
+	integer reg25 (r25): same_value
+	integer reg26 (r26): same_value
+	integer reg27 (r27): same_value
+	integer reg28 (r28): same_value
+	integer reg29 (r29): same_value
+	integer reg30 (r30): same_value
+	integer reg31 (r31): same_value
+	FPU reg32 (f0): undefined
+	FPU reg33 (f1): undefined
+	FPU reg34 (f2): undefined
+	FPU reg35 (f3): undefined
+	FPU reg36 (f4): undefined
+	FPU reg37 (f5): undefined
+	FPU reg38 (f6): undefined
+	FPU reg39 (f7): undefined
+	FPU reg40 (f8): undefined
+	FPU reg41 (f9): undefined
+	FPU reg42 (f10): undefined
+	FPU reg43 (f11): undefined
+	FPU reg44 (f12): undefined
+	FPU reg45 (f13): undefined
+	FPU reg46 (f14): undefined
+	FPU reg47 (f15): undefined
+	FPU reg48 (f16): undefined
+	FPU reg49 (f17): undefined
+	FPU reg50 (f18): undefined
+	FPU reg51 (f19): undefined
+	FPU reg52 (f20): undefined
+	FPU reg53 (f21): undefined
+	FPU reg54 (f22): undefined
+	FPU reg55 (f23): undefined
+	FPU reg56 (f24): undefined
+	FPU reg57 (f25): undefined
+	FPU reg58 (f26): undefined
+	FPU reg59 (f27): undefined
+	FPU reg60 (f28): undefined
+	FPU reg61 (f29): undefined
+	FPU reg62 (f30): undefined
+	FPU reg63 (f31): undefined
+	integer reg64 (cr): undefined
+	FPU reg65 (fpscr): same_value
+	integer reg66 (msr): undefined
+	vector reg67 (vscr): undefined
+	privileged reg70 (sr0): undefined
+	privileged reg71 (sr1): undefined
+	privileged reg72 (sr2): undefined
+	privileged reg73 (sr3): undefined
+	privileged reg74 (sr4): undefined
+	privileged reg75 (sr5): undefined
+	privileged reg76 (sr6): undefined
+	privileged reg77 (sr7): undefined
+	privileged reg78 (sr8): undefined
+	privileged reg79 (sr9): undefined
+	privileged reg80 (sr10): undefined
+	privileged reg81 (sr11): undefined
+	privileged reg82 (sr12): undefined
+	privileged reg83 (sr13): undefined
+	privileged reg84 (sr14): undefined
+	privileged reg85 (sr15): undefined
+	privileged reg100 (mq): undefined
+	privileged reg101 (xer): undefined
+	privileged reg102 (spr2): undefined
+	privileged reg103 (spr3): undefined
+	privileged reg104 (spr4): undefined
+	privileged reg105 (spr5): undefined
+	privileged reg106 (spr6): undefined
+	privileged reg107 (spr7): undefined
+	privileged reg108 (lr): undefined
+	privileged reg109 (ctr): undefined
+	privileged reg110 (spr10): undefined
+	privileged reg111 (spr11): undefined
+	privileged reg112 (spr12): undefined
+	privileged reg113 (spr13): undefined
+	privileged reg114 (tfhar): undefined
+	privileged reg115 (tfiar): undefined
+	privileged reg116 (texasr): undefined
+	privileged reg117 (spr17): undefined
+	privileged reg118 (dsisr): undefined
+	privileged reg119 (dar): undefined
+	privileged reg120 (spr20): undefined
+	privileged reg121 (spr21): undefined
+	privileged reg122 (dec): undefined
+	privileged reg123 (spr23): undefined
+	privileged reg124 (spr24): undefined
+	privileged reg125 (spr25): undefined
+	privileged reg126 (spr26): undefined
+	privileged reg127 (spr27): undefined
+	privileged reg128 (spr28): undefined
+	privileged reg129 (spr29): undefined
+	privileged reg130 (spr30): undefined
+	privileged reg131 (spr31): undefined
+	privileged reg132 (spr32): undefined
+	privileged reg133 (spr33): undefined
+	privileged reg134 (spr34): undefined
+	privileged reg135 (spr35): undefined
+	privileged reg136 (spr36): undefined
+	privileged reg137 (spr37): undefined
+	privileged reg138 (spr38): undefined
+	privileged reg139 (spr39): undefined
+	privileged reg140 (spr40): undefined
+	privileged reg141 (spr41): undefined
+	privileged reg142 (spr42): undefined
+	privileged reg143 (spr43): undefined
+	privileged reg144 (spr44): undefined
+	privileged reg145 (spr45): undefined
+	privileged reg146 (spr46): undefined
+	privileged reg147 (spr47): undefined
+	privileged reg148 (spr48): undefined
+	privileged reg149 (spr49): undefined
+	privileged reg150 (spr50): undefined
+	privileged reg151 (spr51): undefined
+	privileged reg152 (spr52): undefined
+	privileged reg153 (spr53): undefined
+	privileged reg154 (spr54): undefined
+	privileged reg155 (spr55): undefined
+	privileged reg156 (spr56): undefined
+	privileged reg157 (spr57): undefined
+	privileged reg158 (spr58): undefined
+	privileged reg159 (spr59): undefined
+	privileged reg160 (spr60): undefined
+	privileged reg161 (spr61): undefined
+	privileged reg162 (spr62): undefined
+	privileged reg163 (spr63): undefined
+	privileged reg164 (spr64): undefined
+	privileged reg165 (spr65): undefined
+	privileged reg166 (spr66): undefined
+	privileged reg167 (spr67): undefined
+	privileged reg168 (spr68): undefined
+	privileged reg169 (spr69): undefined
+	privileged reg170 (spr70): undefined
+	privileged reg171 (spr71): undefined
+	privileged reg172 (spr72): undefined
+	privileged reg173 (spr73): undefined
+	privileged reg174 (spr74): undefined
+	privileged reg175 (spr75): undefined
+	privileged reg176 (spr76): undefined
+	privileged reg177 (spr77): undefined
+	privileged reg178 (spr78): undefined
+	privileged reg179 (spr79): undefined
+	privileged reg180 (spr80): undefined
+	privileged reg181 (spr81): undefined
+	privileged reg182 (spr82): undefined
+	privileged reg183 (spr83): undefined
+	privileged reg184 (spr84): undefined
+	privileged reg185 (spr85): undefined
+	privileged reg186 (spr86): undefined
+	privileged reg187 (spr87): undefined
+	privileged reg188 (spr88): undefined
+	privileged reg189 (spr89): undefined
+	privileged reg190 (spr90): undefined
+	privileged reg191 (spr91): undefined
+	privileged reg192 (spr92): undefined
+	privileged reg193 (spr93): undefined
+	privileged reg194 (spr94): undefined
+	privileged reg195 (spr95): undefined
+	privileged reg196 (spr96): undefined
+	privileged reg197 (spr97): undefined
+	privileged reg198 (spr98): undefined
+	privileged reg199 (spr99): undefined
+	privileged reg200 (spr100): undefined
+	privileged reg201 (spr101): undefined
+	privileged reg202 (spr102): undefined
+	privileged reg203 (spr103): undefined
+	privileged reg204 (spr104): undefined
+	privileged reg205 (spr105): undefined
+	privileged reg206 (spr106): undefined
+	privileged reg207 (spr107): undefined
+	privileged reg208 (spr108): undefined
+	privileged reg209 (spr109): undefined
+	privileged reg210 (spr110): undefined
+	privileged reg211 (spr111): undefined
+	privileged reg212 (spr112): undefined
+	privileged reg213 (spr113): undefined
+	privileged reg214 (spr114): undefined
+	privileged reg215 (spr115): undefined
+	privileged reg216 (spr116): undefined
+	privileged reg217 (spr117): undefined
+	privileged reg218 (spr118): undefined
+	privileged reg219 (spr119): undefined
+	privileged reg220 (spr120): undefined
+	privileged reg221 (spr121): undefined
+	privileged reg222 (spr122): undefined
+	privileged reg223 (spr123): undefined
+	privileged reg224 (spr124): undefined
+	privileged reg225 (spr125): undefined
+	privileged reg226 (spr126): undefined
+	privileged reg227 (spr127): undefined
+	privileged reg228 (spr128): undefined
+	privileged reg229 (spr129): undefined
+	privileged reg230 (spr130): undefined
+	privileged reg231 (spr131): undefined
+	privileged reg232 (spr132): undefined
+	privileged reg233 (spr133): undefined
+	privileged reg234 (spr134): undefined
+	privileged reg235 (spr135): undefined
+	privileged reg236 (spr136): undefined
+	privileged reg237 (spr137): undefined
+	privileged reg238 (spr138): undefined
+	privileged reg239 (spr139): undefined
+	privileged reg240 (spr140): undefined
+	privileged reg241 (spr141): undefined
+	privileged reg242 (spr142): undefined
+	privileged reg243 (spr143): undefined
+	privileged reg244 (spr144): undefined
+	privileged reg245 (spr145): undefined
+	privileged reg246 (spr146): undefined
+	privileged reg247 (spr147): undefined
+	privileged reg248 (spr148): undefined
+	privileged reg249 (spr149): undefined
+	privileged reg250 (spr150): undefined
+	privileged reg251 (spr151): undefined
+	privileged reg252 (spr152): undefined
+	privileged reg253 (spr153): undefined
+	privileged reg254 (spr154): undefined
+	privileged reg255 (spr155): undefined
+	privileged reg256 (spr156): undefined
+	privileged reg257 (spr157): undefined
+	privileged reg258 (spr158): undefined
+	privileged reg259 (spr159): undefined
+	privileged reg260 (spr160): undefined
+	privileged reg261 (spr161): undefined
+	privileged reg262 (spr162): undefined
+	privileged reg263 (spr163): undefined
+	privileged reg264 (spr164): undefined
+	privileged reg265 (spr165): undefined
+	privileged reg266 (spr166): undefined
+	privileged reg267 (spr167): undefined
+	privileged reg268 (spr168): undefined
+	privileged reg269 (spr169): undefined
+	privileged reg270 (spr170): undefined
+	privileged reg271 (spr171): undefined
+	privileged reg272 (spr172): undefined
+	privileged reg273 (spr173): undefined
+	privileged reg274 (spr174): undefined
+	privileged reg275 (spr175): undefined
+	privileged reg276 (spr176): undefined
+	privileged reg277 (spr177): undefined
+	privileged reg278 (spr178): undefined
+	privileged reg279 (spr179): undefined
+	privileged reg280 (spr180): undefined
+	privileged reg281 (spr181): undefined
+	privileged reg282 (spr182): undefined
+	privileged reg283 (spr183): undefined
+	privileged reg284 (spr184): undefined
+	privileged reg285 (spr185): undefined
+	privileged reg286 (spr186): undefined
+	privileged reg287 (spr187): undefined
+	privileged reg288 (spr188): undefined
+	privileged reg289 (spr189): undefined
+	privileged reg290 (spr190): undefined
+	privileged reg291 (spr191): undefined
+	privileged reg292 (spr192): undefined
+	privileged reg293 (spr193): undefined
+	privileged reg294 (spr194): undefined
+	privileged reg295 (spr195): undefined
+	privileged reg296 (spr196): undefined
+	privileged reg297 (spr197): undefined
+	privileged reg298 (spr198): undefined
+	privileged reg299 (spr199): undefined
+	privileged reg300 (spr200): undefined
+	privileged reg301 (spr201): undefined
+	privileged reg302 (spr202): undefined
+	privileged reg303 (spr203): undefined
+	privileged reg304 (spr204): undefined
+	privileged reg305 (spr205): undefined
+	privileged reg306 (spr206): undefined
+	privileged reg307 (spr207): undefined
+	privileged reg308 (spr208): undefined
+	privileged reg309 (spr209): undefined
+	privileged reg310 (spr210): undefined
+	privileged reg311 (spr211): undefined
+	privileged reg312 (spr212): undefined
+	privileged reg313 (spr213): undefined
+	privileged reg314 (spr214): undefined
+	privileged reg315 (spr215): undefined
+	privileged reg316 (spr216): undefined
+	privileged reg317 (spr217): undefined
+	privileged reg318 (spr218): undefined
+	privileged reg319 (spr219): undefined
+	privileged reg320 (spr220): undefined
+	privileged reg321 (spr221): undefined
+	privileged reg322 (spr222): undefined
+	privileged reg323 (spr223): undefined
+	privileged reg324 (spr224): undefined
+	privileged reg325 (spr225): undefined
+	privileged reg326 (spr226): undefined
+	privileged reg327 (spr227): undefined
+	privileged reg328 (spr228): undefined
+	privileged reg329 (spr229): undefined
+	privileged reg330 (spr230): undefined
+	privileged reg331 (spr231): undefined
+	privileged reg332 (spr232): undefined
+	privileged reg333 (spr233): undefined
+	privileged reg334 (spr234): undefined
+	privileged reg335 (spr235): undefined
+	privileged reg336 (spr236): undefined
+	privileged reg337 (spr237): undefined
+	privileged reg338 (spr238): undefined
+	privileged reg339 (spr239): undefined
+	privileged reg340 (spr240): undefined
+	privileged reg341 (spr241): undefined
+	privileged reg342 (spr242): undefined
+	privileged reg343 (spr243): undefined
+	privileged reg344 (spr244): undefined
+	privileged reg345 (spr245): undefined
+	privileged reg346 (spr246): undefined
+	privileged reg347 (spr247): undefined
+	privileged reg348 (spr248): undefined
+	privileged reg349 (spr249): undefined
+	privileged reg350 (spr250): undefined
+	privileged reg351 (spr251): undefined
+	privileged reg352 (spr252): undefined
+	privileged reg353 (spr253): undefined
+	privileged reg354 (spr254): undefined
+	privileged reg355 (spr255): undefined
+	vector reg356 (vrsave): undefined
+	privileged reg357 (spr257): undefined
+	privileged reg358 (spr258): undefined
+	privileged reg359 (spr259): undefined
+	privileged reg360 (spr260): undefined
+	privileged reg361 (spr261): undefined
+	privileged reg362 (spr262): undefined
+	privileged reg363 (spr263): undefined
+	privileged reg364 (spr264): undefined
+	privileged reg365 (spr265): undefined
+	privileged reg366 (spr266): undefined
+	privileged reg367 (spr267): undefined
+	privileged reg368 (spr268): undefined
+	privileged reg369 (spr269): undefined
+	privileged reg370 (spr270): undefined
+	privileged reg371 (spr271): undefined
+	privileged reg372 (spr272): undefined
+	privileged reg373 (spr273): undefined
+	privileged reg374 (spr274): undefined
+	privileged reg375 (spr275): undefined
+	privileged reg376 (spr276): undefined
+	privileged reg377 (spr277): undefined
+	privileged reg378 (spr278): undefined
+	privileged reg379 (spr279): undefined
+	privileged reg380 (spr280): undefined
+	privileged reg381 (spr281): undefined
+	privileged reg382 (spr282): undefined
+	privileged reg383 (spr283): undefined
+	privileged reg384 (spr284): undefined
+	privileged reg385 (spr285): undefined
+	privileged reg386 (spr286): undefined
+	privileged reg387 (spr287): undefined
+	privileged reg388 (spr288): undefined
+	privileged reg389 (spr289): undefined
+	privileged reg390 (spr290): undefined
+	privileged reg391 (spr291): undefined
+	privileged reg392 (spr292): undefined
+	privileged reg393 (spr293): undefined
+	privileged reg394 (spr294): undefined
+	privileged reg395 (spr295): undefined
+	privileged reg396 (spr296): undefined
+	privileged reg397 (spr297): undefined
+	privileged reg398 (spr298): undefined
+	privileged reg399 (spr299): undefined
+	privileged reg400 (spr300): undefined
+	privileged reg401 (spr301): undefined
+	privileged reg402 (spr302): undefined
+	privileged reg403 (spr303): undefined
+	privileged reg404 (spr304): undefined
+	privileged reg405 (spr305): undefined
+	privileged reg406 (spr306): undefined
+	privileged reg407 (spr307): undefined
+	privileged reg408 (spr308): undefined
+	privileged reg409 (spr309): undefined
+	privileged reg410 (spr310): undefined
+	privileged reg411 (spr311): undefined
+	privileged reg412 (spr312): undefined
+	privileged reg413 (spr313): undefined
+	privileged reg414 (spr314): undefined
+	privileged reg415 (spr315): undefined
+	privileged reg416 (spr316): undefined
+	privileged reg417 (spr317): undefined
+	privileged reg418 (spr318): undefined
+	privileged reg419 (spr319): undefined
+	privileged reg420 (spr320): undefined
+	privileged reg421 (spr321): undefined
+	privileged reg422 (spr322): undefined
+	privileged reg423 (spr323): undefined
+	privileged reg424 (spr324): undefined
+	privileged reg425 (spr325): undefined
+	privileged reg426 (spr326): undefined
+	privileged reg427 (spr327): undefined
+	privileged reg428 (spr328): undefined
+	privileged reg429 (spr329): undefined
+	privileged reg430 (spr330): undefined
+	privileged reg431 (spr331): undefined
+	privileged reg432 (spr332): undefined
+	privileged reg433 (spr333): undefined
+	privileged reg434 (spr334): undefined
+	privileged reg435 (spr335): undefined
+	privileged reg436 (spr336): undefined
+	privileged reg437 (spr337): undefined
+	privileged reg438 (spr338): undefined
+	privileged reg439 (spr339): undefined
+	privileged reg440 (spr340): undefined
+	privileged reg441 (spr341): undefined
+	privileged reg442 (spr342): undefined
+	privileged reg443 (spr343): undefined
+	privileged reg444 (spr344): undefined
+	privileged reg445 (spr345): undefined
+	privileged reg446 (spr346): undefined
+	privileged reg447 (spr347): undefined
+	privileged reg448 (spr348): undefined
+	privileged reg449 (spr349): undefined
+	privileged reg450 (spr350): undefined
+	privileged reg451 (spr351): undefined
+	privileged reg452 (spr352): undefined
+	privileged reg453 (spr353): undefined
+	privileged reg454 (spr354): undefined
+	privileged reg455 (spr355): undefined
+	privileged reg456 (spr356): undefined
+	privileged reg457 (spr357): undefined
+	privileged reg458 (spr358): undefined
+	privileged reg459 (spr359): undefined
+	privileged reg460 (spr360): undefined
+	privileged reg461 (spr361): undefined
+	privileged reg462 (spr362): undefined
+	privileged reg463 (spr363): undefined
+	privileged reg464 (spr364): undefined
+	privileged reg465 (spr365): undefined
+	privileged reg466 (spr366): undefined
+	privileged reg467 (spr367): undefined
+	privileged reg468 (spr368): undefined
+	privileged reg469 (spr369): undefined
+	privileged reg470 (spr370): undefined
+	privileged reg471 (spr371): undefined
+	privileged reg472 (spr372): undefined
+	privileged reg473 (spr373): undefined
+	privileged reg474 (spr374): undefined
+	privileged reg475 (spr375): undefined
+	privileged reg476 (spr376): undefined
+	privileged reg477 (spr377): undefined
+	privileged reg478 (spr378): undefined
+	privileged reg479 (spr379): undefined
+	privileged reg480 (spr380): undefined
+	privileged reg481 (spr381): undefined
+	privileged reg482 (spr382): undefined
+	privileged reg483 (spr383): undefined
+	privileged reg484 (spr384): undefined
+	privileged reg485 (spr385): undefined
+	privileged reg486 (spr386): undefined
+	privileged reg487 (spr387): undefined
+	privileged reg488 (spr388): undefined
+	privileged reg489 (spr389): undefined
+	privileged reg490 (spr390): undefined
+	privileged reg491 (spr391): undefined
+	privileged reg492 (spr392): undefined
+	privileged reg493 (spr393): undefined
+	privileged reg494 (spr394): undefined
+	privileged reg495 (spr395): undefined
+	privileged reg496 (spr396): undefined
+	privileged reg497 (spr397): undefined
+	privileged reg498 (spr398): undefined
+	privileged reg499 (spr399): undefined
+	privileged reg500 (spr400): undefined
+	privileged reg501 (spr401): undefined
+	privileged reg502 (spr402): undefined
+	privileged reg503 (spr403): undefined
+	privileged reg504 (spr404): undefined
+	privileged reg505 (spr405): undefined
+	privileged reg506 (spr406): undefined
+	privileged reg507 (spr407): undefined
+	privileged reg508 (spr408): undefined
+	privileged reg509 (spr409): undefined
+	privileged reg510 (spr410): undefined
+	privileged reg511 (spr411): undefined
+	privileged reg512 (spr412): undefined
+	privileged reg513 (spr413): undefined
+	privileged reg514 (spr414): undefined
+	privileged reg515 (spr415): undefined
+	privileged reg516 (spr416): undefined
+	privileged reg517 (spr417): undefined
+	privileged reg518 (spr418): undefined
+	privileged reg519 (spr419): undefined
+	privileged reg520 (spr420): undefined
+	privileged reg521 (spr421): undefined
+	privileged reg522 (spr422): undefined
+	privileged reg523 (spr423): undefined
+	privileged reg524 (spr424): undefined
+	privileged reg525 (spr425): undefined
+	privileged reg526 (spr426): undefined
+	privileged reg527 (spr427): undefined
+	privileged reg528 (spr428): undefined
+	privileged reg529 (spr429): undefined
+	privileged reg530 (spr430): undefined
+	privileged reg531 (spr431): undefined
+	privileged reg532 (spr432): undefined
+	privileged reg533 (spr433): undefined
+	privileged reg534 (spr434): undefined
+	privileged reg535 (spr435): undefined
+	privileged reg536 (spr436): undefined
+	privileged reg537 (spr437): undefined
+	privileged reg538 (spr438): undefined
+	privileged reg539 (spr439): undefined
+	privileged reg540 (spr440): undefined
+	privileged reg541 (spr441): undefined
+	privileged reg542 (spr442): undefined
+	privileged reg543 (spr443): undefined
+	privileged reg544 (spr444): undefined
+	privileged reg545 (spr445): undefined
+	privileged reg546 (spr446): undefined
+	privileged reg547 (spr447): undefined
+	privileged reg548 (spr448): undefined
+	privileged reg549 (spr449): undefined
+	privileged reg550 (spr450): undefined
+	privileged reg551 (spr451): undefined
+	privileged reg552 (spr452): undefined
+	privileged reg553 (spr453): undefined
+	privileged reg554 (spr454): undefined
+	privileged reg555 (spr455): undefined
+	privileged reg556 (spr456): undefined
+	privileged reg557 (spr457): undefined
+	privileged reg558 (spr458): undefined
+	privileged reg559 (spr459): undefined
+	privileged reg560 (spr460): undefined
+	privileged reg561 (spr461): undefined
+	privileged reg562 (spr462): undefined
+	privileged reg563 (spr463): undefined
+	privileged reg564 (spr464): undefined
+	privileged reg565 (spr465): undefined
+	privileged reg566 (spr466): undefined
+	privileged reg567 (spr467): undefined
+	privileged reg568 (spr468): undefined
+	privileged reg569 (spr469): undefined
+	privileged reg570 (spr470): undefined
+	privileged reg571 (spr471): undefined
+	privileged reg572 (spr472): undefined
+	privileged reg573 (spr473): undefined
+	privileged reg574 (spr474): undefined
+	privileged reg575 (spr475): undefined
+	privileged reg576 (spr476): undefined
+	privileged reg577 (spr477): undefined
+	privileged reg578 (spr478): undefined
+	privileged reg579 (spr479): undefined
+	privileged reg580 (spr480): undefined
+	privileged reg581 (spr481): undefined
+	privileged reg582 (spr482): undefined
+	privileged reg583 (spr483): undefined
+	privileged reg584 (spr484): undefined
+	privileged reg585 (spr485): undefined
+	privileged reg586 (spr486): undefined
+	privileged reg587 (spr487): undefined
+	privileged reg588 (spr488): undefined
+	privileged reg589 (spr489): undefined
+	privileged reg590 (spr490): undefined
+	privileged reg591 (spr491): undefined
+	privileged reg592 (spr492): undefined
+	privileged reg593 (spr493): undefined
+	privileged reg594 (spr494): undefined
+	privileged reg595 (spr495): undefined
+	privileged reg596 (spr496): undefined
+	privileged reg597 (spr497): undefined
+	privileged reg598 (spr498): undefined
+	privileged reg599 (spr499): undefined
+	privileged reg600 (spr500): undefined
+	privileged reg601 (spr501): undefined
+	privileged reg602 (spr502): undefined
+	privileged reg603 (spr503): undefined
+	privileged reg604 (spr504): undefined
+	privileged reg605 (spr505): undefined
+	privileged reg606 (spr506): undefined
+	privileged reg607 (spr507): undefined
+	privileged reg608 (spr508): undefined
+	privileged reg609 (spr509): undefined
+	privileged reg610 (spr510): undefined
+	privileged reg611 (spr511): undefined
+	vector reg612 (spefscr): undefined
+	privileged reg613 (spr513): undefined
+	privileged reg614 (spr514): undefined
+	privileged reg615 (spr515): undefined
+	privileged reg616 (spr516): undefined
+	privileged reg617 (spr517): undefined
+	privileged reg618 (spr518): undefined
+	privileged reg619 (spr519): undefined
+	privileged reg620 (spr520): undefined
+	privileged reg621 (spr521): undefined
+	privileged reg622 (spr522): undefined
+	privileged reg623 (spr523): undefined
+	privileged reg624 (spr524): undefined
+	privileged reg625 (spr525): undefined
+	privileged reg626 (spr526): undefined
+	privileged reg627 (spr527): undefined
+	privileged reg628 (spr528): undefined
+	privileged reg629 (spr529): undefined
+	privileged reg630 (spr530): undefined
+	privileged reg631 (spr531): undefined
+	privileged reg632 (spr532): undefined
+	privileged reg633 (spr533): undefined
+	privileged reg634 (spr534): undefined
+	privileged reg635 (spr535): undefined
+	privileged reg636 (spr536): undefined
+	privileged reg637 (spr537): undefined
+	privileged reg638 (spr538): undefined
+	privileged reg639 (spr539): undefined
+	privileged reg640 (spr540): undefined
+	privileged reg641 (spr541): undefined
+	privileged reg642 (spr542): undefined
+	privileged reg643 (spr543): undefined
+	privileged reg644 (spr544): undefined
+	privileged reg645 (spr545): undefined
+	privileged reg646 (spr546): undefined
+	privileged reg647 (spr547): undefined
+	privileged reg648 (spr548): undefined
+	privileged reg649 (spr549): undefined
+	privileged reg650 (spr550): undefined
+	privileged reg651 (spr551): undefined
+	privileged reg652 (spr552): undefined
+	privileged reg653 (spr553): undefined
+	privileged reg654 (spr554): undefined
+	privileged reg655 (spr555): undefined
+	privileged reg656 (spr556): undefined
+	privileged reg657 (spr557): undefined
+	privileged reg658 (spr558): undefined
+	privileged reg659 (spr559): undefined
+	privileged reg660 (spr560): undefined
+	privileged reg661 (spr561): undefined
+	privileged reg662 (spr562): undefined
+	privileged reg663 (spr563): undefined
+	privileged reg664 (spr564): undefined
+	privileged reg665 (spr565): undefined
+	privileged reg666 (spr566): undefined
+	privileged reg667 (spr567): undefined
+	privileged reg668 (spr568): undefined
+	privileged reg669 (spr569): undefined
+	privileged reg670 (spr570): undefined
+	privileged reg671 (spr571): undefined
+	privileged reg672 (spr572): undefined
+	privileged reg673 (spr573): undefined
+	privileged reg674 (spr574): undefined
+	privileged reg675 (spr575): undefined
+	privileged reg676 (spr576): undefined
+	privileged reg677 (spr577): undefined
+	privileged reg678 (spr578): undefined
+	privileged reg679 (spr579): undefined
+	privileged reg680 (spr580): undefined
+	privileged reg681 (spr581): undefined
+	privileged reg682 (spr582): undefined
+	privileged reg683 (spr583): undefined
+	privileged reg684 (spr584): undefined
+	privileged reg685 (spr585): undefined
+	privileged reg686 (spr586): undefined
+	privileged reg687 (spr587): undefined
+	privileged reg688 (spr588): undefined
+	privileged reg689 (spr589): undefined
+	privileged reg690 (spr590): undefined
+	privileged reg691 (spr591): undefined
+	privileged reg692 (spr592): undefined
+	privileged reg693 (spr593): undefined
+	privileged reg694 (spr594): undefined
+	privileged reg695 (spr595): undefined
+	privileged reg696 (spr596): undefined
+	privileged reg697 (spr597): undefined
+	privileged reg698 (spr598): undefined
+	privileged reg699 (spr599): undefined
+	privileged reg700 (spr600): undefined
+	privileged reg701 (spr601): undefined
+	privileged reg702 (spr602): undefined
+	privileged reg703 (spr603): undefined
+	privileged reg704 (spr604): undefined
+	privileged reg705 (spr605): undefined
+	privileged reg706 (spr606): undefined
+	privileged reg707 (spr607): undefined
+	privileged reg708 (spr608): undefined
+	privileged reg709 (spr609): undefined
+	privileged reg710 (spr610): undefined
+	privileged reg711 (spr611): undefined
+	privileged reg712 (spr612): undefined
+	privileged reg713 (spr613): undefined
+	privileged reg714 (spr614): undefined
+	privileged reg715 (spr615): undefined
+	privileged reg716 (spr616): undefined
+	privileged reg717 (spr617): undefined
+	privileged reg718 (spr618): undefined
+	privileged reg719 (spr619): undefined
+	privileged reg720 (spr620): undefined
+	privileged reg721 (spr621): undefined
+	privileged reg722 (spr622): undefined
+	privileged reg723 (spr623): undefined
+	privileged reg724 (spr624): undefined
+	privileged reg725 (spr625): undefined
+	privileged reg726 (spr626): undefined
+	privileged reg727 (spr627): undefined
+	privileged reg728 (spr628): undefined
+	privileged reg729 (spr629): undefined
+	privileged reg730 (spr630): undefined
+	privileged reg731 (spr631): undefined
+	privileged reg732 (spr632): undefined
+	privileged reg733 (spr633): undefined
+	privileged reg734 (spr634): undefined
+	privileged reg735 (spr635): undefined
+	privileged reg736 (spr636): undefined
+	privileged reg737 (spr637): undefined
+	privileged reg738 (spr638): undefined
+	privileged reg739 (spr639): undefined
+	privileged reg740 (spr640): undefined
+	privileged reg741 (spr641): undefined
+	privileged reg742 (spr642): undefined
+	privileged reg743 (spr643): undefined
+	privileged reg744 (spr644): undefined
+	privileged reg745 (spr645): undefined
+	privileged reg746 (spr646): undefined
+	privileged reg747 (spr647): undefined
+	privileged reg748 (spr648): undefined
+	privileged reg749 (spr649): undefined
+	privileged reg750 (spr650): undefined
+	privileged reg751 (spr651): undefined
+	privileged reg752 (spr652): undefined
+	privileged reg753 (spr653): undefined
+	privileged reg754 (spr654): undefined
+	privileged reg755 (spr655): undefined
+	privileged reg756 (spr656): undefined
+	privileged reg757 (spr657): undefined
+	privileged reg758 (spr658): undefined
+	privileged reg759 (spr659): undefined
+	privileged reg760 (spr660): undefined
+	privileged reg761 (spr661): undefined
+	privileged reg762 (spr662): undefined
+	privileged reg763 (spr663): undefined
+	privileged reg764 (spr664): undefined
+	privileged reg765 (spr665): undefined
+	privileged reg766 (spr666): undefined
+	privileged reg767 (spr667): undefined
+	privileged reg768 (spr668): undefined
+	privileged reg769 (spr669): undefined
+	privileged reg770 (spr670): undefined
+	privileged reg771 (spr671): undefined
+	privileged reg772 (spr672): undefined
+	privileged reg773 (spr673): undefined
+	privileged reg774 (spr674): undefined
+	privileged reg775 (spr675): undefined
+	privileged reg776 (spr676): undefined
+	privileged reg777 (spr677): undefined
+	privileged reg778 (spr678): undefined
+	privileged reg779 (spr679): undefined
+	privileged reg780 (spr680): undefined
+	privileged reg781 (spr681): undefined
+	privileged reg782 (spr682): undefined
+	privileged reg783 (spr683): undefined
+	privileged reg784 (spr684): undefined
+	privileged reg785 (spr685): undefined
+	privileged reg786 (spr686): undefined
+	privileged reg787 (spr687): undefined
+	privileged reg788 (spr688): undefined
+	privileged reg789 (spr689): undefined
+	privileged reg790 (spr690): undefined
+	privileged reg791 (spr691): undefined
+	privileged reg792 (spr692): undefined
+	privileged reg793 (spr693): undefined
+	privileged reg794 (spr694): undefined
+	privileged reg795 (spr695): undefined
+	privileged reg796 (spr696): undefined
+	privileged reg797 (spr697): undefined
+	privileged reg798 (spr698): undefined
+	privileged reg799 (spr699): undefined
+	privileged reg800 (spr700): undefined
+	privileged reg801 (spr701): undefined
+	privileged reg802 (spr702): undefined
+	privileged reg803 (spr703): undefined
+	privileged reg804 (spr704): undefined
+	privileged reg805 (spr705): undefined
+	privileged reg806 (spr706): undefined
+	privileged reg807 (spr707): undefined
+	privileged reg808 (spr708): undefined
+	privileged reg809 (spr709): undefined
+	privileged reg810 (spr710): undefined
+	privileged reg811 (spr711): undefined
+	privileged reg812 (spr712): undefined
+	privileged reg813 (spr713): undefined
+	privileged reg814 (spr714): undefined
+	privileged reg815 (spr715): undefined
+	privileged reg816 (spr716): undefined
+	privileged reg817 (spr717): undefined
+	privileged reg818 (spr718): undefined
+	privileged reg819 (spr719): undefined
+	privileged reg820 (spr720): undefined
+	privileged reg821 (spr721): undefined
+	privileged reg822 (spr722): undefined
+	privileged reg823 (spr723): undefined
+	privileged reg824 (spr724): undefined
+	privileged reg825 (spr725): undefined
+	privileged reg826 (spr726): undefined
+	privileged reg827 (spr727): undefined
+	privileged reg828 (spr728): undefined
+	privileged reg829 (spr729): undefined
+	privileged reg830 (spr730): undefined
+	privileged reg831 (spr731): undefined
+	privileged reg832 (spr732): undefined
+	privileged reg833 (spr733): undefined
+	privileged reg834 (spr734): undefined
+	privileged reg835 (spr735): undefined
+	privileged reg836 (spr736): undefined
+	privileged reg837 (spr737): undefined
+	privileged reg838 (spr738): undefined
+	privileged reg839 (spr739): undefined
+	privileged reg840 (spr740): undefined
+	privileged reg841 (spr741): undefined
+	privileged reg842 (spr742): undefined
+	privileged reg843 (spr743): undefined
+	privileged reg844 (spr744): undefined
+	privileged reg845 (spr745): undefined
+	privileged reg846 (spr746): undefined
+	privileged reg847 (spr747): undefined
+	privileged reg848 (spr748): undefined
+	privileged reg849 (spr749): undefined
+	privileged reg850 (spr750): undefined
+	privileged reg851 (spr751): undefined
+	privileged reg852 (spr752): undefined
+	privileged reg853 (spr753): undefined
+	privileged reg854 (spr754): undefined
+	privileged reg855 (spr755): undefined
+	privileged reg856 (spr756): undefined
+	privileged reg857 (spr757): undefined
+	privileged reg858 (spr758): undefined
+	privileged reg859 (spr759): undefined
+	privileged reg860 (spr760): undefined
+	privileged reg861 (spr761): undefined
+	privileged reg862 (spr762): undefined
+	privileged reg863 (spr763): undefined
+	privileged reg864 (spr764): undefined
+	privileged reg865 (spr765): undefined
+	privileged reg866 (spr766): undefined
+	privileged reg867 (spr767): undefined
+	privileged reg868 (spr768): undefined
+	privileged reg869 (spr769): undefined
+	privileged reg870 (spr770): undefined
+	privileged reg871 (spr771): undefined
+	privileged reg872 (spr772): undefined
+	privileged reg873 (spr773): undefined
+	privileged reg874 (spr774): undefined
+	privileged reg875 (spr775): undefined
+	privileged reg876 (spr776): undefined
+	privileged reg877 (spr777): undefined
+	privileged reg878 (spr778): undefined
+	privileged reg879 (spr779): undefined
+	privileged reg880 (spr780): undefined
+	privileged reg881 (spr781): undefined
+	privileged reg882 (spr782): undefined
+	privileged reg883 (spr783): undefined
+	privileged reg884 (spr784): undefined
+	privileged reg885 (spr785): undefined
+	privileged reg886 (spr786): undefined
+	privileged reg887 (spr787): undefined
+	privileged reg888 (spr788): undefined
+	privileged reg889 (spr789): undefined
+	privileged reg890 (spr790): undefined
+	privileged reg891 (spr791): undefined
+	privileged reg892 (spr792): undefined
+	privileged reg893 (spr793): undefined
+	privileged reg894 (spr794): undefined
+	privileged reg895 (spr795): undefined
+	privileged reg896 (spr796): undefined
+	privileged reg897 (spr797): undefined
+	privileged reg898 (spr798): undefined
+	privileged reg899 (spr799): undefined
+	privileged reg900 (spr800): undefined
+	privileged reg901 (spr801): undefined
+	privileged reg902 (spr802): undefined
+	privileged reg903 (spr803): undefined
+	privileged reg904 (spr804): undefined
+	privileged reg905 (spr805): undefined
+	privileged reg906 (spr806): undefined
+	privileged reg907 (spr807): undefined
+	privileged reg908 (spr808): undefined
+	privileged reg909 (spr809): undefined
+	privileged reg910 (spr810): undefined
+	privileged reg911 (spr811): undefined
+	privileged reg912 (spr812): undefined
+	privileged reg913 (spr813): undefined
+	privileged reg914 (spr814): undefined
+	privileged reg915 (spr815): undefined
+	privileged reg916 (spr816): undefined
+	privileged reg917 (spr817): undefined
+	privileged reg918 (spr818): undefined
+	privileged reg919 (spr819): undefined
+	privileged reg920 (spr820): undefined
+	privileged reg921 (spr821): undefined
+	privileged reg922 (spr822): undefined
+	privileged reg923 (spr823): undefined
+	privileged reg924 (spr824): undefined
+	privileged reg925 (spr825): undefined
+	privileged reg926 (spr826): undefined
+	privileged reg927 (spr827): undefined
+	privileged reg928 (spr828): undefined
+	privileged reg929 (spr829): undefined
+	privileged reg930 (spr830): undefined
+	privileged reg931 (spr831): undefined
+	privileged reg932 (spr832): undefined
+	privileged reg933 (spr833): undefined
+	privileged reg934 (spr834): undefined
+	privileged reg935 (spr835): undefined
+	privileged reg936 (spr836): undefined
+	privileged reg937 (spr837): undefined
+	privileged reg938 (spr838): undefined
+	privileged reg939 (spr839): undefined
+	privileged reg940 (spr840): undefined
+	privileged reg941 (spr841): undefined
+	privileged reg942 (spr842): undefined
+	privileged reg943 (spr843): undefined
+	privileged reg944 (spr844): undefined
+	privileged reg945 (spr845): undefined
+	privileged reg946 (spr846): undefined
+	privileged reg947 (spr847): undefined
+	privileged reg948 (spr848): undefined
+	privileged reg949 (spr849): undefined
+	privileged reg950 (spr850): undefined
+	privileged reg951 (spr851): undefined
+	privileged reg952 (spr852): undefined
+	privileged reg953 (spr853): undefined
+	privileged reg954 (spr854): undefined
+	privileged reg955 (spr855): undefined
+	privileged reg956 (spr856): undefined
+	privileged reg957 (spr857): undefined
+	privileged reg958 (spr858): undefined
+	privileged reg959 (spr859): undefined
+	privileged reg960 (spr860): undefined
+	privileged reg961 (spr861): undefined
+	privileged reg962 (spr862): undefined
+	privileged reg963 (spr863): undefined
+	privileged reg964 (spr864): undefined
+	privileged reg965 (spr865): undefined
+	privileged reg966 (spr866): undefined
+	privileged reg967 (spr867): undefined
+	privileged reg968 (spr868): undefined
+	privileged reg969 (spr869): undefined
+	privileged reg970 (spr870): undefined
+	privileged reg971 (spr871): undefined
+	privileged reg972 (spr872): undefined
+	privileged reg973 (spr873): undefined
+	privileged reg974 (spr874): undefined
+	privileged reg975 (spr875): undefined
+	privileged reg976 (spr876): undefined
+	privileged reg977 (spr877): undefined
+	privileged reg978 (spr878): undefined
+	privileged reg979 (spr879): undefined
+	privileged reg980 (spr880): undefined
+	privileged reg981 (spr881): undefined
+	privileged reg982 (spr882): undefined
+	privileged reg983 (spr883): undefined
+	privileged reg984 (spr884): undefined
+	privileged reg985 (spr885): undefined
+	privileged reg986 (spr886): undefined
+	privileged reg987 (spr887): undefined
+	privileged reg988 (spr888): undefined
+	privileged reg989 (spr889): undefined
+	privileged reg990 (spr890): undefined
+	privileged reg991 (spr891): undefined
+	privileged reg992 (spr892): undefined
+	privileged reg993 (spr893): undefined
+	privileged reg994 (spr894): undefined
+	privileged reg995 (spr895): undefined
+	privileged reg996 (spr896): undefined
+	privileged reg997 (spr897): undefined
+	privileged reg998 (spr898): undefined
+	privileged reg999 (spr899): undefined
+	vector reg1124 (vr0): undefined
+	vector reg1125 (vr1): undefined
+	vector reg1126 (vr2): undefined
+	vector reg1127 (vr3): undefined
+	vector reg1128 (vr4): undefined
+	vector reg1129 (vr5): undefined
+	vector reg1130 (vr6): undefined
+	vector reg1131 (vr7): undefined
+	vector reg1132 (vr8): undefined
+	vector reg1133 (vr9): undefined
+	vector reg1134 (vr10): undefined
+	vector reg1135 (vr11): undefined
+	vector reg1136 (vr12): undefined
+	vector reg1137 (vr13): undefined
+	vector reg1138 (vr14): undefined
+	vector reg1139 (vr15): undefined
+	vector reg1140 (vr16): undefined
+	vector reg1141 (vr17): undefined
+	vector reg1142 (vr18): undefined
+	vector reg1143 (vr19): undefined
+	vector reg1144 (vr20): undefined
+	vector reg1145 (vr21): undefined
+	vector reg1146 (vr22): undefined
+	vector reg1147 (vr23): undefined
+	vector reg1148 (vr24): undefined
+	vector reg1149 (vr25): undefined
+	vector reg1150 (vr26): undefined
+	vector reg1151 (vr27): undefined
+	vector reg1152 (vr28): undefined
+	vector reg1153 (vr29): undefined
+	vector reg1154 (vr30): undefined
+	vector reg1155 (vr31): undefined
+dwarf_cfi_addrframe (.debug_frame): no matching address range
+EOF
+
+# EM_PPC64 (function bar 0x00000000100005b0)
+# Note. Only in .debug_frame, not in .eh_frame.
+# Same as testfileppc32 but without -m32.
+testfiles testfileppc64
+testrun_compare ${abs_builddir}/addrcfi -e testfileppc64 0x00000000100005b0 <<\EOF
+dwarf_cfi_addrframe (.eh_frame): no matching address range
+.debug_frame has 0x100005b0 => [0x100005b0, 0x100005d0):
+	return address in reg65
+	CFA location expression: bregx(1)
+	integer reg0 (r0): undefined
+	integer reg1 (r1): location expression: call_frame_cfa stack_value
+	integer reg2 (r2): same_value
+	integer reg3 (r3): undefined
+	integer reg4 (r4): undefined
+	integer reg5 (r5): undefined
+	integer reg6 (r6): undefined
+	integer reg7 (r7): undefined
+	integer reg8 (r8): undefined
+	integer reg9 (r9): undefined
+	integer reg10 (r10): undefined
+	integer reg11 (r11): undefined
+	integer reg12 (r12): undefined
+	integer reg13 (r13): same_value
+	integer reg14 (r14): same_value
+	integer reg15 (r15): same_value
+	integer reg16 (r16): same_value
+	integer reg17 (r17): same_value
+	integer reg18 (r18): same_value
+	integer reg19 (r19): same_value
+	integer reg20 (r20): same_value
+	integer reg21 (r21): same_value
+	integer reg22 (r22): same_value
+	integer reg23 (r23): same_value
+	integer reg24 (r24): same_value
+	integer reg25 (r25): same_value
+	integer reg26 (r26): same_value
+	integer reg27 (r27): same_value
+	integer reg28 (r28): same_value
+	integer reg29 (r29): same_value
+	integer reg30 (r30): same_value
+	integer reg31 (r31): same_value
+	FPU reg32 (f0): undefined
+	FPU reg33 (f1): undefined
+	FPU reg34 (f2): undefined
+	FPU reg35 (f3): undefined
+	FPU reg36 (f4): undefined
+	FPU reg37 (f5): undefined
+	FPU reg38 (f6): undefined
+	FPU reg39 (f7): undefined
+	FPU reg40 (f8): undefined
+	FPU reg41 (f9): undefined
+	FPU reg42 (f10): undefined
+	FPU reg43 (f11): undefined
+	FPU reg44 (f12): undefined
+	FPU reg45 (f13): undefined
+	FPU reg46 (f14): undefined
+	FPU reg47 (f15): undefined
+	FPU reg48 (f16): undefined
+	FPU reg49 (f17): undefined
+	FPU reg50 (f18): undefined
+	FPU reg51 (f19): undefined
+	FPU reg52 (f20): undefined
+	FPU reg53 (f21): undefined
+	FPU reg54 (f22): undefined
+	FPU reg55 (f23): undefined
+	FPU reg56 (f24): undefined
+	FPU reg57 (f25): undefined
+	FPU reg58 (f26): undefined
+	FPU reg59 (f27): undefined
+	FPU reg60 (f28): undefined
+	FPU reg61 (f29): undefined
+	FPU reg62 (f30): undefined
+	FPU reg63 (f31): undefined
+	integer reg64 (cr): undefined
+	FPU reg65 (fpscr): same_value
+	integer reg66 (msr): undefined
+	vector reg67 (vscr): undefined
+	privileged reg70 (sr0): undefined
+	privileged reg71 (sr1): undefined
+	privileged reg72 (sr2): undefined
+	privileged reg73 (sr3): undefined
+	privileged reg74 (sr4): undefined
+	privileged reg75 (sr5): undefined
+	privileged reg76 (sr6): undefined
+	privileged reg77 (sr7): undefined
+	privileged reg78 (sr8): undefined
+	privileged reg79 (sr9): undefined
+	privileged reg80 (sr10): undefined
+	privileged reg81 (sr11): undefined
+	privileged reg82 (sr12): undefined
+	privileged reg83 (sr13): undefined
+	privileged reg84 (sr14): undefined
+	privileged reg85 (sr15): undefined
+	privileged reg100 (spr0): undefined
+	privileged reg101 (xer): undefined
+	privileged reg102 (spr2): undefined
+	privileged reg103 (spr3): undefined
+	privileged reg104 (spr4): undefined
+	privileged reg105 (spr5): undefined
+	privileged reg106 (spr6): undefined
+	privileged reg107 (spr7): undefined
+	privileged reg108 (lr): undefined
+	privileged reg109 (ctr): undefined
+	privileged reg110 (spr10): undefined
+	privileged reg111 (spr11): undefined
+	privileged reg112 (spr12): undefined
+	privileged reg113 (spr13): undefined
+	privileged reg114 (tfhar): undefined
+	privileged reg115 (tfiar): undefined
+	privileged reg116 (texasr): undefined
+	privileged reg117 (spr17): undefined
+	privileged reg118 (dsisr): undefined
+	privileged reg119 (dar): undefined
+	privileged reg120 (spr20): undefined
+	privileged reg121 (spr21): undefined
+	privileged reg122 (dec): undefined
+	privileged reg123 (spr23): undefined
+	privileged reg124 (spr24): undefined
+	privileged reg125 (spr25): undefined
+	privileged reg126 (spr26): undefined
+	privileged reg127 (spr27): undefined
+	privileged reg128 (spr28): undefined
+	privileged reg129 (spr29): undefined
+	privileged reg130 (spr30): undefined
+	privileged reg131 (spr31): undefined
+	privileged reg132 (spr32): undefined
+	privileged reg133 (spr33): undefined
+	privileged reg134 (spr34): undefined
+	privileged reg135 (spr35): undefined
+	privileged reg136 (spr36): undefined
+	privileged reg137 (spr37): undefined
+	privileged reg138 (spr38): undefined
+	privileged reg139 (spr39): undefined
+	privileged reg140 (spr40): undefined
+	privileged reg141 (spr41): undefined
+	privileged reg142 (spr42): undefined
+	privileged reg143 (spr43): undefined
+	privileged reg144 (spr44): undefined
+	privileged reg145 (spr45): undefined
+	privileged reg146 (spr46): undefined
+	privileged reg147 (spr47): undefined
+	privileged reg148 (spr48): undefined
+	privileged reg149 (spr49): undefined
+	privileged reg150 (spr50): undefined
+	privileged reg151 (spr51): undefined
+	privileged reg152 (spr52): undefined
+	privileged reg153 (spr53): undefined
+	privileged reg154 (spr54): undefined
+	privileged reg155 (spr55): undefined
+	privileged reg156 (spr56): undefined
+	privileged reg157 (spr57): undefined
+	privileged reg158 (spr58): undefined
+	privileged reg159 (spr59): undefined
+	privileged reg160 (spr60): undefined
+	privileged reg161 (spr61): undefined
+	privileged reg162 (spr62): undefined
+	privileged reg163 (spr63): undefined
+	privileged reg164 (spr64): undefined
+	privileged reg165 (spr65): undefined
+	privileged reg166 (spr66): undefined
+	privileged reg167 (spr67): undefined
+	privileged reg168 (spr68): undefined
+	privileged reg169 (spr69): undefined
+	privileged reg170 (spr70): undefined
+	privileged reg171 (spr71): undefined
+	privileged reg172 (spr72): undefined
+	privileged reg173 (spr73): undefined
+	privileged reg174 (spr74): undefined
+	privileged reg175 (spr75): undefined
+	privileged reg176 (spr76): undefined
+	privileged reg177 (spr77): undefined
+	privileged reg178 (spr78): undefined
+	privileged reg179 (spr79): undefined
+	privileged reg180 (spr80): undefined
+	privileged reg181 (spr81): undefined
+	privileged reg182 (spr82): undefined
+	privileged reg183 (spr83): undefined
+	privileged reg184 (spr84): undefined
+	privileged reg185 (spr85): undefined
+	privileged reg186 (spr86): undefined
+	privileged reg187 (spr87): undefined
+	privileged reg188 (spr88): undefined
+	privileged reg189 (spr89): undefined
+	privileged reg190 (spr90): undefined
+	privileged reg191 (spr91): undefined
+	privileged reg192 (spr92): undefined
+	privileged reg193 (spr93): undefined
+	privileged reg194 (spr94): undefined
+	privileged reg195 (spr95): undefined
+	privileged reg196 (spr96): undefined
+	privileged reg197 (spr97): undefined
+	privileged reg198 (spr98): undefined
+	privileged reg199 (spr99): undefined
+	privileged reg200 (spr100): undefined
+	privileged reg201 (spr101): undefined
+	privileged reg202 (spr102): undefined
+	privileged reg203 (spr103): undefined
+	privileged reg204 (spr104): undefined
+	privileged reg205 (spr105): undefined
+	privileged reg206 (spr106): undefined
+	privileged reg207 (spr107): undefined
+	privileged reg208 (spr108): undefined
+	privileged reg209 (spr109): undefined
+	privileged reg210 (spr110): undefined
+	privileged reg211 (spr111): undefined
+	privileged reg212 (spr112): undefined
+	privileged reg213 (spr113): undefined
+	privileged reg214 (spr114): undefined
+	privileged reg215 (spr115): undefined
+	privileged reg216 (spr116): undefined
+	privileged reg217 (spr117): undefined
+	privileged reg218 (spr118): undefined
+	privileged reg219 (spr119): undefined
+	privileged reg220 (spr120): undefined
+	privileged reg221 (spr121): undefined
+	privileged reg222 (spr122): undefined
+	privileged reg223 (spr123): undefined
+	privileged reg224 (spr124): undefined
+	privileged reg225 (spr125): undefined
+	privileged reg226 (spr126): undefined
+	privileged reg227 (spr127): undefined
+	privileged reg228 (spr128): undefined
+	privileged reg229 (spr129): undefined
+	privileged reg230 (spr130): undefined
+	privileged reg231 (spr131): undefined
+	privileged reg232 (spr132): undefined
+	privileged reg233 (spr133): undefined
+	privileged reg234 (spr134): undefined
+	privileged reg235 (spr135): undefined
+	privileged reg236 (spr136): undefined
+	privileged reg237 (spr137): undefined
+	privileged reg238 (spr138): undefined
+	privileged reg239 (spr139): undefined
+	privileged reg240 (spr140): undefined
+	privileged reg241 (spr141): undefined
+	privileged reg242 (spr142): undefined
+	privileged reg243 (spr143): undefined
+	privileged reg244 (spr144): undefined
+	privileged reg245 (spr145): undefined
+	privileged reg246 (spr146): undefined
+	privileged reg247 (spr147): undefined
+	privileged reg248 (spr148): undefined
+	privileged reg249 (spr149): undefined
+	privileged reg250 (spr150): undefined
+	privileged reg251 (spr151): undefined
+	privileged reg252 (spr152): undefined
+	privileged reg253 (spr153): undefined
+	privileged reg254 (spr154): undefined
+	privileged reg255 (spr155): undefined
+	privileged reg256 (spr156): undefined
+	privileged reg257 (spr157): undefined
+	privileged reg258 (spr158): undefined
+	privileged reg259 (spr159): undefined
+	privileged reg260 (spr160): undefined
+	privileged reg261 (spr161): undefined
+	privileged reg262 (spr162): undefined
+	privileged reg263 (spr163): undefined
+	privileged reg264 (spr164): undefined
+	privileged reg265 (spr165): undefined
+	privileged reg266 (spr166): undefined
+	privileged reg267 (spr167): undefined
+	privileged reg268 (spr168): undefined
+	privileged reg269 (spr169): undefined
+	privileged reg270 (spr170): undefined
+	privileged reg271 (spr171): undefined
+	privileged reg272 (spr172): undefined
+	privileged reg273 (spr173): undefined
+	privileged reg274 (spr174): undefined
+	privileged reg275 (spr175): undefined
+	privileged reg276 (spr176): undefined
+	privileged reg277 (spr177): undefined
+	privileged reg278 (spr178): undefined
+	privileged reg279 (spr179): undefined
+	privileged reg280 (spr180): undefined
+	privileged reg281 (spr181): undefined
+	privileged reg282 (spr182): undefined
+	privileged reg283 (spr183): undefined
+	privileged reg284 (spr184): undefined
+	privileged reg285 (spr185): undefined
+	privileged reg286 (spr186): undefined
+	privileged reg287 (spr187): undefined
+	privileged reg288 (spr188): undefined
+	privileged reg289 (spr189): undefined
+	privileged reg290 (spr190): undefined
+	privileged reg291 (spr191): undefined
+	privileged reg292 (spr192): undefined
+	privileged reg293 (spr193): undefined
+	privileged reg294 (spr194): undefined
+	privileged reg295 (spr195): undefined
+	privileged reg296 (spr196): undefined
+	privileged reg297 (spr197): undefined
+	privileged reg298 (spr198): undefined
+	privileged reg299 (spr199): undefined
+	privileged reg300 (spr200): undefined
+	privileged reg301 (spr201): undefined
+	privileged reg302 (spr202): undefined
+	privileged reg303 (spr203): undefined
+	privileged reg304 (spr204): undefined
+	privileged reg305 (spr205): undefined
+	privileged reg306 (spr206): undefined
+	privileged reg307 (spr207): undefined
+	privileged reg308 (spr208): undefined
+	privileged reg309 (spr209): undefined
+	privileged reg310 (spr210): undefined
+	privileged reg311 (spr211): undefined
+	privileged reg312 (spr212): undefined
+	privileged reg313 (spr213): undefined
+	privileged reg314 (spr214): undefined
+	privileged reg315 (spr215): undefined
+	privileged reg316 (spr216): undefined
+	privileged reg317 (spr217): undefined
+	privileged reg318 (spr218): undefined
+	privileged reg319 (spr219): undefined
+	privileged reg320 (spr220): undefined
+	privileged reg321 (spr221): undefined
+	privileged reg322 (spr222): undefined
+	privileged reg323 (spr223): undefined
+	privileged reg324 (spr224): undefined
+	privileged reg325 (spr225): undefined
+	privileged reg326 (spr226): undefined
+	privileged reg327 (spr227): undefined
+	privileged reg328 (spr228): undefined
+	privileged reg329 (spr229): undefined
+	privileged reg330 (spr230): undefined
+	privileged reg331 (spr231): undefined
+	privileged reg332 (spr232): undefined
+	privileged reg333 (spr233): undefined
+	privileged reg334 (spr234): undefined
+	privileged reg335 (spr235): undefined
+	privileged reg336 (spr236): undefined
+	privileged reg337 (spr237): undefined
+	privileged reg338 (spr238): undefined
+	privileged reg339 (spr239): undefined
+	privileged reg340 (spr240): undefined
+	privileged reg341 (spr241): undefined
+	privileged reg342 (spr242): undefined
+	privileged reg343 (spr243): undefined
+	privileged reg344 (spr244): undefined
+	privileged reg345 (spr245): undefined
+	privileged reg346 (spr246): undefined
+	privileged reg347 (spr247): undefined
+	privileged reg348 (spr248): undefined
+	privileged reg349 (spr249): undefined
+	privileged reg350 (spr250): undefined
+	privileged reg351 (spr251): undefined
+	privileged reg352 (spr252): undefined
+	privileged reg353 (spr253): undefined
+	privileged reg354 (spr254): undefined
+	privileged reg355 (spr255): undefined
+	vector reg356 (vrsave): undefined
+	privileged reg357 (spr257): undefined
+	privileged reg358 (spr258): undefined
+	privileged reg359 (spr259): undefined
+	privileged reg360 (spr260): undefined
+	privileged reg361 (spr261): undefined
+	privileged reg362 (spr262): undefined
+	privileged reg363 (spr263): undefined
+	privileged reg364 (spr264): undefined
+	privileged reg365 (spr265): undefined
+	privileged reg366 (spr266): undefined
+	privileged reg367 (spr267): undefined
+	privileged reg368 (spr268): undefined
+	privileged reg369 (spr269): undefined
+	privileged reg370 (spr270): undefined
+	privileged reg371 (spr271): undefined
+	privileged reg372 (spr272): undefined
+	privileged reg373 (spr273): undefined
+	privileged reg374 (spr274): undefined
+	privileged reg375 (spr275): undefined
+	privileged reg376 (spr276): undefined
+	privileged reg377 (spr277): undefined
+	privileged reg378 (spr278): undefined
+	privileged reg379 (spr279): undefined
+	privileged reg380 (spr280): undefined
+	privileged reg381 (spr281): undefined
+	privileged reg382 (spr282): undefined
+	privileged reg383 (spr283): undefined
+	privileged reg384 (spr284): undefined
+	privileged reg385 (spr285): undefined
+	privileged reg386 (spr286): undefined
+	privileged reg387 (spr287): undefined
+	privileged reg388 (spr288): undefined
+	privileged reg389 (spr289): undefined
+	privileged reg390 (spr290): undefined
+	privileged reg391 (spr291): undefined
+	privileged reg392 (spr292): undefined
+	privileged reg393 (spr293): undefined
+	privileged reg394 (spr294): undefined
+	privileged reg395 (spr295): undefined
+	privileged reg396 (spr296): undefined
+	privileged reg397 (spr297): undefined
+	privileged reg398 (spr298): undefined
+	privileged reg399 (spr299): undefined
+	privileged reg400 (spr300): undefined
+	privileged reg401 (spr301): undefined
+	privileged reg402 (spr302): undefined
+	privileged reg403 (spr303): undefined
+	privileged reg404 (spr304): undefined
+	privileged reg405 (spr305): undefined
+	privileged reg406 (spr306): undefined
+	privileged reg407 (spr307): undefined
+	privileged reg408 (spr308): undefined
+	privileged reg409 (spr309): undefined
+	privileged reg410 (spr310): undefined
+	privileged reg411 (spr311): undefined
+	privileged reg412 (spr312): undefined
+	privileged reg413 (spr313): undefined
+	privileged reg414 (spr314): undefined
+	privileged reg415 (spr315): undefined
+	privileged reg416 (spr316): undefined
+	privileged reg417 (spr317): undefined
+	privileged reg418 (spr318): undefined
+	privileged reg419 (spr319): undefined
+	privileged reg420 (spr320): undefined
+	privileged reg421 (spr321): undefined
+	privileged reg422 (spr322): undefined
+	privileged reg423 (spr323): undefined
+	privileged reg424 (spr324): undefined
+	privileged reg425 (spr325): undefined
+	privileged reg426 (spr326): undefined
+	privileged reg427 (spr327): undefined
+	privileged reg428 (spr328): undefined
+	privileged reg429 (spr329): undefined
+	privileged reg430 (spr330): undefined
+	privileged reg431 (spr331): undefined
+	privileged reg432 (spr332): undefined
+	privileged reg433 (spr333): undefined
+	privileged reg434 (spr334): undefined
+	privileged reg435 (spr335): undefined
+	privileged reg436 (spr336): undefined
+	privileged reg437 (spr337): undefined
+	privileged reg438 (spr338): undefined
+	privileged reg439 (spr339): undefined
+	privileged reg440 (spr340): undefined
+	privileged reg441 (spr341): undefined
+	privileged reg442 (spr342): undefined
+	privileged reg443 (spr343): undefined
+	privileged reg444 (spr344): undefined
+	privileged reg445 (spr345): undefined
+	privileged reg446 (spr346): undefined
+	privileged reg447 (spr347): undefined
+	privileged reg448 (spr348): undefined
+	privileged reg449 (spr349): undefined
+	privileged reg450 (spr350): undefined
+	privileged reg451 (spr351): undefined
+	privileged reg452 (spr352): undefined
+	privileged reg453 (spr353): undefined
+	privileged reg454 (spr354): undefined
+	privileged reg455 (spr355): undefined
+	privileged reg456 (spr356): undefined
+	privileged reg457 (spr357): undefined
+	privileged reg458 (spr358): undefined
+	privileged reg459 (spr359): undefined
+	privileged reg460 (spr360): undefined
+	privileged reg461 (spr361): undefined
+	privileged reg462 (spr362): undefined
+	privileged reg463 (spr363): undefined
+	privileged reg464 (spr364): undefined
+	privileged reg465 (spr365): undefined
+	privileged reg466 (spr366): undefined
+	privileged reg467 (spr367): undefined
+	privileged reg468 (spr368): undefined
+	privileged reg469 (spr369): undefined
+	privileged reg470 (spr370): undefined
+	privileged reg471 (spr371): undefined
+	privileged reg472 (spr372): undefined
+	privileged reg473 (spr373): undefined
+	privileged reg474 (spr374): undefined
+	privileged reg475 (spr375): undefined
+	privileged reg476 (spr376): undefined
+	privileged reg477 (spr377): undefined
+	privileged reg478 (spr378): undefined
+	privileged reg479 (spr379): undefined
+	privileged reg480 (spr380): undefined
+	privileged reg481 (spr381): undefined
+	privileged reg482 (spr382): undefined
+	privileged reg483 (spr383): undefined
+	privileged reg484 (spr384): undefined
+	privileged reg485 (spr385): undefined
+	privileged reg486 (spr386): undefined
+	privileged reg487 (spr387): undefined
+	privileged reg488 (spr388): undefined
+	privileged reg489 (spr389): undefined
+	privileged reg490 (spr390): undefined
+	privileged reg491 (spr391): undefined
+	privileged reg492 (spr392): undefined
+	privileged reg493 (spr393): undefined
+	privileged reg494 (spr394): undefined
+	privileged reg495 (spr395): undefined
+	privileged reg496 (spr396): undefined
+	privileged reg497 (spr397): undefined
+	privileged reg498 (spr398): undefined
+	privileged reg499 (spr399): undefined
+	privileged reg500 (spr400): undefined
+	privileged reg501 (spr401): undefined
+	privileged reg502 (spr402): undefined
+	privileged reg503 (spr403): undefined
+	privileged reg504 (spr404): undefined
+	privileged reg505 (spr405): undefined
+	privileged reg506 (spr406): undefined
+	privileged reg507 (spr407): undefined
+	privileged reg508 (spr408): undefined
+	privileged reg509 (spr409): undefined
+	privileged reg510 (spr410): undefined
+	privileged reg511 (spr411): undefined
+	privileged reg512 (spr412): undefined
+	privileged reg513 (spr413): undefined
+	privileged reg514 (spr414): undefined
+	privileged reg515 (spr415): undefined
+	privileged reg516 (spr416): undefined
+	privileged reg517 (spr417): undefined
+	privileged reg518 (spr418): undefined
+	privileged reg519 (spr419): undefined
+	privileged reg520 (spr420): undefined
+	privileged reg521 (spr421): undefined
+	privileged reg522 (spr422): undefined
+	privileged reg523 (spr423): undefined
+	privileged reg524 (spr424): undefined
+	privileged reg525 (spr425): undefined
+	privileged reg526 (spr426): undefined
+	privileged reg527 (spr427): undefined
+	privileged reg528 (spr428): undefined
+	privileged reg529 (spr429): undefined
+	privileged reg530 (spr430): undefined
+	privileged reg531 (spr431): undefined
+	privileged reg532 (spr432): undefined
+	privileged reg533 (spr433): undefined
+	privileged reg534 (spr434): undefined
+	privileged reg535 (spr435): undefined
+	privileged reg536 (spr436): undefined
+	privileged reg537 (spr437): undefined
+	privileged reg538 (spr438): undefined
+	privileged reg539 (spr439): undefined
+	privileged reg540 (spr440): undefined
+	privileged reg541 (spr441): undefined
+	privileged reg542 (spr442): undefined
+	privileged reg543 (spr443): undefined
+	privileged reg544 (spr444): undefined
+	privileged reg545 (spr445): undefined
+	privileged reg546 (spr446): undefined
+	privileged reg547 (spr447): undefined
+	privileged reg548 (spr448): undefined
+	privileged reg549 (spr449): undefined
+	privileged reg550 (spr450): undefined
+	privileged reg551 (spr451): undefined
+	privileged reg552 (spr452): undefined
+	privileged reg553 (spr453): undefined
+	privileged reg554 (spr454): undefined
+	privileged reg555 (spr455): undefined
+	privileged reg556 (spr456): undefined
+	privileged reg557 (spr457): undefined
+	privileged reg558 (spr458): undefined
+	privileged reg559 (spr459): undefined
+	privileged reg560 (spr460): undefined
+	privileged reg561 (spr461): undefined
+	privileged reg562 (spr462): undefined
+	privileged reg563 (spr463): undefined
+	privileged reg564 (spr464): undefined
+	privileged reg565 (spr465): undefined
+	privileged reg566 (spr466): undefined
+	privileged reg567 (spr467): undefined
+	privileged reg568 (spr468): undefined
+	privileged reg569 (spr469): undefined
+	privileged reg570 (spr470): undefined
+	privileged reg571 (spr471): undefined
+	privileged reg572 (spr472): undefined
+	privileged reg573 (spr473): undefined
+	privileged reg574 (spr474): undefined
+	privileged reg575 (spr475): undefined
+	privileged reg576 (spr476): undefined
+	privileged reg577 (spr477): undefined
+	privileged reg578 (spr478): undefined
+	privileged reg579 (spr479): undefined
+	privileged reg580 (spr480): undefined
+	privileged reg581 (spr481): undefined
+	privileged reg582 (spr482): undefined
+	privileged reg583 (spr483): undefined
+	privileged reg584 (spr484): undefined
+	privileged reg585 (spr485): undefined
+	privileged reg586 (spr486): undefined
+	privileged reg587 (spr487): undefined
+	privileged reg588 (spr488): undefined
+	privileged reg589 (spr489): undefined
+	privileged reg590 (spr490): undefined
+	privileged reg591 (spr491): undefined
+	privileged reg592 (spr492): undefined
+	privileged reg593 (spr493): undefined
+	privileged reg594 (spr494): undefined
+	privileged reg595 (spr495): undefined
+	privileged reg596 (spr496): undefined
+	privileged reg597 (spr497): undefined
+	privileged reg598 (spr498): undefined
+	privileged reg599 (spr499): undefined
+	privileged reg600 (spr500): undefined
+	privileged reg601 (spr501): undefined
+	privileged reg602 (spr502): undefined
+	privileged reg603 (spr503): undefined
+	privileged reg604 (spr504): undefined
+	privileged reg605 (spr505): undefined
+	privileged reg606 (spr506): undefined
+	privileged reg607 (spr507): undefined
+	privileged reg608 (spr508): undefined
+	privileged reg609 (spr509): undefined
+	privileged reg610 (spr510): undefined
+	privileged reg611 (spr511): undefined
+	vector reg612 (spefscr): undefined
+	privileged reg613 (spr513): undefined
+	privileged reg614 (spr514): undefined
+	privileged reg615 (spr515): undefined
+	privileged reg616 (spr516): undefined
+	privileged reg617 (spr517): undefined
+	privileged reg618 (spr518): undefined
+	privileged reg619 (spr519): undefined
+	privileged reg620 (spr520): undefined
+	privileged reg621 (spr521): undefined
+	privileged reg622 (spr522): undefined
+	privileged reg623 (spr523): undefined
+	privileged reg624 (spr524): undefined
+	privileged reg625 (spr525): undefined
+	privileged reg626 (spr526): undefined
+	privileged reg627 (spr527): undefined
+	privileged reg628 (spr528): undefined
+	privileged reg629 (spr529): undefined
+	privileged reg630 (spr530): undefined
+	privileged reg631 (spr531): undefined
+	privileged reg632 (spr532): undefined
+	privileged reg633 (spr533): undefined
+	privileged reg634 (spr534): undefined
+	privileged reg635 (spr535): undefined
+	privileged reg636 (spr536): undefined
+	privileged reg637 (spr537): undefined
+	privileged reg638 (spr538): undefined
+	privileged reg639 (spr539): undefined
+	privileged reg640 (spr540): undefined
+	privileged reg641 (spr541): undefined
+	privileged reg642 (spr542): undefined
+	privileged reg643 (spr543): undefined
+	privileged reg644 (spr544): undefined
+	privileged reg645 (spr545): undefined
+	privileged reg646 (spr546): undefined
+	privileged reg647 (spr547): undefined
+	privileged reg648 (spr548): undefined
+	privileged reg649 (spr549): undefined
+	privileged reg650 (spr550): undefined
+	privileged reg651 (spr551): undefined
+	privileged reg652 (spr552): undefined
+	privileged reg653 (spr553): undefined
+	privileged reg654 (spr554): undefined
+	privileged reg655 (spr555): undefined
+	privileged reg656 (spr556): undefined
+	privileged reg657 (spr557): undefined
+	privileged reg658 (spr558): undefined
+	privileged reg659 (spr559): undefined
+	privileged reg660 (spr560): undefined
+	privileged reg661 (spr561): undefined
+	privileged reg662 (spr562): undefined
+	privileged reg663 (spr563): undefined
+	privileged reg664 (spr564): undefined
+	privileged reg665 (spr565): undefined
+	privileged reg666 (spr566): undefined
+	privileged reg667 (spr567): undefined
+	privileged reg668 (spr568): undefined
+	privileged reg669 (spr569): undefined
+	privileged reg670 (spr570): undefined
+	privileged reg671 (spr571): undefined
+	privileged reg672 (spr572): undefined
+	privileged reg673 (spr573): undefined
+	privileged reg674 (spr574): undefined
+	privileged reg675 (spr575): undefined
+	privileged reg676 (spr576): undefined
+	privileged reg677 (spr577): undefined
+	privileged reg678 (spr578): undefined
+	privileged reg679 (spr579): undefined
+	privileged reg680 (spr580): undefined
+	privileged reg681 (spr581): undefined
+	privileged reg682 (spr582): undefined
+	privileged reg683 (spr583): undefined
+	privileged reg684 (spr584): undefined
+	privileged reg685 (spr585): undefined
+	privileged reg686 (spr586): undefined
+	privileged reg687 (spr587): undefined
+	privileged reg688 (spr588): undefined
+	privileged reg689 (spr589): undefined
+	privileged reg690 (spr590): undefined
+	privileged reg691 (spr591): undefined
+	privileged reg692 (spr592): undefined
+	privileged reg693 (spr593): undefined
+	privileged reg694 (spr594): undefined
+	privileged reg695 (spr595): undefined
+	privileged reg696 (spr596): undefined
+	privileged reg697 (spr597): undefined
+	privileged reg698 (spr598): undefined
+	privileged reg699 (spr599): undefined
+	privileged reg700 (spr600): undefined
+	privileged reg701 (spr601): undefined
+	privileged reg702 (spr602): undefined
+	privileged reg703 (spr603): undefined
+	privileged reg704 (spr604): undefined
+	privileged reg705 (spr605): undefined
+	privileged reg706 (spr606): undefined
+	privileged reg707 (spr607): undefined
+	privileged reg708 (spr608): undefined
+	privileged reg709 (spr609): undefined
+	privileged reg710 (spr610): undefined
+	privileged reg711 (spr611): undefined
+	privileged reg712 (spr612): undefined
+	privileged reg713 (spr613): undefined
+	privileged reg714 (spr614): undefined
+	privileged reg715 (spr615): undefined
+	privileged reg716 (spr616): undefined
+	privileged reg717 (spr617): undefined
+	privileged reg718 (spr618): undefined
+	privileged reg719 (spr619): undefined
+	privileged reg720 (spr620): undefined
+	privileged reg721 (spr621): undefined
+	privileged reg722 (spr622): undefined
+	privileged reg723 (spr623): undefined
+	privileged reg724 (spr624): undefined
+	privileged reg725 (spr625): undefined
+	privileged reg726 (spr626): undefined
+	privileged reg727 (spr627): undefined
+	privileged reg728 (spr628): undefined
+	privileged reg729 (spr629): undefined
+	privileged reg730 (spr630): undefined
+	privileged reg731 (spr631): undefined
+	privileged reg732 (spr632): undefined
+	privileged reg733 (spr633): undefined
+	privileged reg734 (spr634): undefined
+	privileged reg735 (spr635): undefined
+	privileged reg736 (spr636): undefined
+	privileged reg737 (spr637): undefined
+	privileged reg738 (spr638): undefined
+	privileged reg739 (spr639): undefined
+	privileged reg740 (spr640): undefined
+	privileged reg741 (spr641): undefined
+	privileged reg742 (spr642): undefined
+	privileged reg743 (spr643): undefined
+	privileged reg744 (spr644): undefined
+	privileged reg745 (spr645): undefined
+	privileged reg746 (spr646): undefined
+	privileged reg747 (spr647): undefined
+	privileged reg748 (spr648): undefined
+	privileged reg749 (spr649): undefined
+	privileged reg750 (spr650): undefined
+	privileged reg751 (spr651): undefined
+	privileged reg752 (spr652): undefined
+	privileged reg753 (spr653): undefined
+	privileged reg754 (spr654): undefined
+	privileged reg755 (spr655): undefined
+	privileged reg756 (spr656): undefined
+	privileged reg757 (spr657): undefined
+	privileged reg758 (spr658): undefined
+	privileged reg759 (spr659): undefined
+	privileged reg760 (spr660): undefined
+	privileged reg761 (spr661): undefined
+	privileged reg762 (spr662): undefined
+	privileged reg763 (spr663): undefined
+	privileged reg764 (spr664): undefined
+	privileged reg765 (spr665): undefined
+	privileged reg766 (spr666): undefined
+	privileged reg767 (spr667): undefined
+	privileged reg768 (spr668): undefined
+	privileged reg769 (spr669): undefined
+	privileged reg770 (spr670): undefined
+	privileged reg771 (spr671): undefined
+	privileged reg772 (spr672): undefined
+	privileged reg773 (spr673): undefined
+	privileged reg774 (spr674): undefined
+	privileged reg775 (spr675): undefined
+	privileged reg776 (spr676): undefined
+	privileged reg777 (spr677): undefined
+	privileged reg778 (spr678): undefined
+	privileged reg779 (spr679): undefined
+	privileged reg780 (spr680): undefined
+	privileged reg781 (spr681): undefined
+	privileged reg782 (spr682): undefined
+	privileged reg783 (spr683): undefined
+	privileged reg784 (spr684): undefined
+	privileged reg785 (spr685): undefined
+	privileged reg786 (spr686): undefined
+	privileged reg787 (spr687): undefined
+	privileged reg788 (spr688): undefined
+	privileged reg789 (spr689): undefined
+	privileged reg790 (spr690): undefined
+	privileged reg791 (spr691): undefined
+	privileged reg792 (spr692): undefined
+	privileged reg793 (spr693): undefined
+	privileged reg794 (spr694): undefined
+	privileged reg795 (spr695): undefined
+	privileged reg796 (spr696): undefined
+	privileged reg797 (spr697): undefined
+	privileged reg798 (spr698): undefined
+	privileged reg799 (spr699): undefined
+	privileged reg800 (spr700): undefined
+	privileged reg801 (spr701): undefined
+	privileged reg802 (spr702): undefined
+	privileged reg803 (spr703): undefined
+	privileged reg804 (spr704): undefined
+	privileged reg805 (spr705): undefined
+	privileged reg806 (spr706): undefined
+	privileged reg807 (spr707): undefined
+	privileged reg808 (spr708): undefined
+	privileged reg809 (spr709): undefined
+	privileged reg810 (spr710): undefined
+	privileged reg811 (spr711): undefined
+	privileged reg812 (spr712): undefined
+	privileged reg813 (spr713): undefined
+	privileged reg814 (spr714): undefined
+	privileged reg815 (spr715): undefined
+	privileged reg816 (spr716): undefined
+	privileged reg817 (spr717): undefined
+	privileged reg818 (spr718): undefined
+	privileged reg819 (spr719): undefined
+	privileged reg820 (spr720): undefined
+	privileged reg821 (spr721): undefined
+	privileged reg822 (spr722): undefined
+	privileged reg823 (spr723): undefined
+	privileged reg824 (spr724): undefined
+	privileged reg825 (spr725): undefined
+	privileged reg826 (spr726): undefined
+	privileged reg827 (spr727): undefined
+	privileged reg828 (spr728): undefined
+	privileged reg829 (spr729): undefined
+	privileged reg830 (spr730): undefined
+	privileged reg831 (spr731): undefined
+	privileged reg832 (spr732): undefined
+	privileged reg833 (spr733): undefined
+	privileged reg834 (spr734): undefined
+	privileged reg835 (spr735): undefined
+	privileged reg836 (spr736): undefined
+	privileged reg837 (spr737): undefined
+	privileged reg838 (spr738): undefined
+	privileged reg839 (spr739): undefined
+	privileged reg840 (spr740): undefined
+	privileged reg841 (spr741): undefined
+	privileged reg842 (spr742): undefined
+	privileged reg843 (spr743): undefined
+	privileged reg844 (spr744): undefined
+	privileged reg845 (spr745): undefined
+	privileged reg846 (spr746): undefined
+	privileged reg847 (spr747): undefined
+	privileged reg848 (spr748): undefined
+	privileged reg849 (spr749): undefined
+	privileged reg850 (spr750): undefined
+	privileged reg851 (spr751): undefined
+	privileged reg852 (spr752): undefined
+	privileged reg853 (spr753): undefined
+	privileged reg854 (spr754): undefined
+	privileged reg855 (spr755): undefined
+	privileged reg856 (spr756): undefined
+	privileged reg857 (spr757): undefined
+	privileged reg858 (spr758): undefined
+	privileged reg859 (spr759): undefined
+	privileged reg860 (spr760): undefined
+	privileged reg861 (spr761): undefined
+	privileged reg862 (spr762): undefined
+	privileged reg863 (spr763): undefined
+	privileged reg864 (spr764): undefined
+	privileged reg865 (spr765): undefined
+	privileged reg866 (spr766): undefined
+	privileged reg867 (spr767): undefined
+	privileged reg868 (spr768): undefined
+	privileged reg869 (spr769): undefined
+	privileged reg870 (spr770): undefined
+	privileged reg871 (spr771): undefined
+	privileged reg872 (spr772): undefined
+	privileged reg873 (spr773): undefined
+	privileged reg874 (spr774): undefined
+	privileged reg875 (spr775): undefined
+	privileged reg876 (spr776): undefined
+	privileged reg877 (spr777): undefined
+	privileged reg878 (spr778): undefined
+	privileged reg879 (spr779): undefined
+	privileged reg880 (spr780): undefined
+	privileged reg881 (spr781): undefined
+	privileged reg882 (spr782): undefined
+	privileged reg883 (spr783): undefined
+	privileged reg884 (spr784): undefined
+	privileged reg885 (spr785): undefined
+	privileged reg886 (spr786): undefined
+	privileged reg887 (spr787): undefined
+	privileged reg888 (spr788): undefined
+	privileged reg889 (spr789): undefined
+	privileged reg890 (spr790): undefined
+	privileged reg891 (spr791): undefined
+	privileged reg892 (spr792): undefined
+	privileged reg893 (spr793): undefined
+	privileged reg894 (spr794): undefined
+	privileged reg895 (spr795): undefined
+	privileged reg896 (spr796): undefined
+	privileged reg897 (spr797): undefined
+	privileged reg898 (spr798): undefined
+	privileged reg899 (spr799): undefined
+	privileged reg900 (spr800): undefined
+	privileged reg901 (spr801): undefined
+	privileged reg902 (spr802): undefined
+	privileged reg903 (spr803): undefined
+	privileged reg904 (spr804): undefined
+	privileged reg905 (spr805): undefined
+	privileged reg906 (spr806): undefined
+	privileged reg907 (spr807): undefined
+	privileged reg908 (spr808): undefined
+	privileged reg909 (spr809): undefined
+	privileged reg910 (spr810): undefined
+	privileged reg911 (spr811): undefined
+	privileged reg912 (spr812): undefined
+	privileged reg913 (spr813): undefined
+	privileged reg914 (spr814): undefined
+	privileged reg915 (spr815): undefined
+	privileged reg916 (spr816): undefined
+	privileged reg917 (spr817): undefined
+	privileged reg918 (spr818): undefined
+	privileged reg919 (spr819): undefined
+	privileged reg920 (spr820): undefined
+	privileged reg921 (spr821): undefined
+	privileged reg922 (spr822): undefined
+	privileged reg923 (spr823): undefined
+	privileged reg924 (spr824): undefined
+	privileged reg925 (spr825): undefined
+	privileged reg926 (spr826): undefined
+	privileged reg927 (spr827): undefined
+	privileged reg928 (spr828): undefined
+	privileged reg929 (spr829): undefined
+	privileged reg930 (spr830): undefined
+	privileged reg931 (spr831): undefined
+	privileged reg932 (spr832): undefined
+	privileged reg933 (spr833): undefined
+	privileged reg934 (spr834): undefined
+	privileged reg935 (spr835): undefined
+	privileged reg936 (spr836): undefined
+	privileged reg937 (spr837): undefined
+	privileged reg938 (spr838): undefined
+	privileged reg939 (spr839): undefined
+	privileged reg940 (spr840): undefined
+	privileged reg941 (spr841): undefined
+	privileged reg942 (spr842): undefined
+	privileged reg943 (spr843): undefined
+	privileged reg944 (spr844): undefined
+	privileged reg945 (spr845): undefined
+	privileged reg946 (spr846): undefined
+	privileged reg947 (spr847): undefined
+	privileged reg948 (spr848): undefined
+	privileged reg949 (spr849): undefined
+	privileged reg950 (spr850): undefined
+	privileged reg951 (spr851): undefined
+	privileged reg952 (spr852): undefined
+	privileged reg953 (spr853): undefined
+	privileged reg954 (spr854): undefined
+	privileged reg955 (spr855): undefined
+	privileged reg956 (spr856): undefined
+	privileged reg957 (spr857): undefined
+	privileged reg958 (spr858): undefined
+	privileged reg959 (spr859): undefined
+	privileged reg960 (spr860): undefined
+	privileged reg961 (spr861): undefined
+	privileged reg962 (spr862): undefined
+	privileged reg963 (spr863): undefined
+	privileged reg964 (spr864): undefined
+	privileged reg965 (spr865): undefined
+	privileged reg966 (spr866): undefined
+	privileged reg967 (spr867): undefined
+	privileged reg968 (spr868): undefined
+	privileged reg969 (spr869): undefined
+	privileged reg970 (spr870): undefined
+	privileged reg971 (spr871): undefined
+	privileged reg972 (spr872): undefined
+	privileged reg973 (spr873): undefined
+	privileged reg974 (spr874): undefined
+	privileged reg975 (spr875): undefined
+	privileged reg976 (spr876): undefined
+	privileged reg977 (spr877): undefined
+	privileged reg978 (spr878): undefined
+	privileged reg979 (spr879): undefined
+	privileged reg980 (spr880): undefined
+	privileged reg981 (spr881): undefined
+	privileged reg982 (spr882): undefined
+	privileged reg983 (spr883): undefined
+	privileged reg984 (spr884): undefined
+	privileged reg985 (spr885): undefined
+	privileged reg986 (spr886): undefined
+	privileged reg987 (spr887): undefined
+	privileged reg988 (spr888): undefined
+	privileged reg989 (spr889): undefined
+	privileged reg990 (spr890): undefined
+	privileged reg991 (spr891): undefined
+	privileged reg992 (spr892): undefined
+	privileged reg993 (spr893): undefined
+	privileged reg994 (spr894): undefined
+	privileged reg995 (spr895): undefined
+	privileged reg996 (spr896): undefined
+	privileged reg997 (spr897): undefined
+	privileged reg998 (spr898): undefined
+	privileged reg999 (spr899): undefined
+	vector reg1124 (vr0): undefined
+	vector reg1125 (vr1): undefined
+	vector reg1126 (vr2): undefined
+	vector reg1127 (vr3): undefined
+	vector reg1128 (vr4): undefined
+	vector reg1129 (vr5): undefined
+	vector reg1130 (vr6): undefined
+	vector reg1131 (vr7): undefined
+	vector reg1132 (vr8): undefined
+	vector reg1133 (vr9): undefined
+	vector reg1134 (vr10): undefined
+	vector reg1135 (vr11): undefined
+	vector reg1136 (vr12): undefined
+	vector reg1137 (vr13): undefined
+	vector reg1138 (vr14): undefined
+	vector reg1139 (vr15): undefined
+	vector reg1140 (vr16): undefined
+	vector reg1141 (vr17): undefined
+	vector reg1142 (vr18): undefined
+	vector reg1143 (vr19): undefined
+	vector reg1144 (vr20): undefined
+	vector reg1145 (vr21): undefined
+	vector reg1146 (vr22): undefined
+	vector reg1147 (vr23): undefined
+	vector reg1148 (vr24): undefined
+	vector reg1149 (vr25): undefined
+	vector reg1150 (vr26): undefined
+	vector reg1151 (vr27): undefined
+	vector reg1152 (vr28): undefined
+	vector reg1153 (vr29): undefined
+	vector reg1154 (vr30): undefined
+	vector reg1155 (vr31): undefined
+EOF
+
+# EM_S390 (ELFCLASS32) (function bar 0x4004d8)
+# Note. Only in .eh_frame, there is no .debug_frame.
+# Same as PPC above but with -m31.
+testfiles testfiles390
+testrun_compare ${abs_builddir}/addrcfi -e testfiles390 0x4004d8 <<\EOF
+.eh_frame has 0x4004d8 => [0x4004d8, 0x4004e8):
+	return address in reg14
+	CFA location expression: bregx(15,96)
+	integer reg0 (%r0): undefined
+	integer reg1 (%r1): undefined
+	integer reg2 (%r2): undefined
+	integer reg3 (%r3): undefined
+	integer reg4 (%r4): undefined
+	integer reg5 (%r5): undefined
+	integer reg6 (%r6): same_value
+	integer reg7 (%r7): same_value
+	integer reg8 (%r8): same_value
+	integer reg9 (%r9): same_value
+	integer reg10 (%r10): same_value
+	integer reg11 (%r11): same_value
+	integer reg12 (%r12): same_value
+	integer reg13 (%r13): same_value
+	integer reg14 (%r14): same_value
+	integer reg15 (%r15): same_value
+	FPU reg16 (%f0): undefined
+	FPU reg17 (%f2): undefined
+	FPU reg18 (%f4): undefined
+	FPU reg19 (%f6): undefined
+	FPU reg20 (%f1): undefined
+	FPU reg21 (%f3): undefined
+	FPU reg22 (%f5): undefined
+	FPU reg23 (%f7): undefined
+	FPU reg24 (%f8): same_value
+	FPU reg25 (%f10): same_value
+	FPU reg26 (%f12): same_value
+	FPU reg27 (%f14): same_value
+	FPU reg28 (%f9): same_value
+	FPU reg29 (%f11): same_value
+	FPU reg30 (%f13): same_value
+	FPU reg31 (%f15): same_value
+	control reg32 (%c0): undefined
+	control reg33 (%c1): undefined
+	control reg34 (%c2): undefined
+	control reg35 (%c3): undefined
+	control reg36 (%c4): undefined
+	control reg37 (%c5): undefined
+	control reg38 (%c6): undefined
+	control reg39 (%c7): undefined
+	control reg40 (%c8): undefined
+	control reg41 (%c9): undefined
+	control reg42 (%c10): undefined
+	control reg43 (%c11): undefined
+	control reg44 (%c12): undefined
+	control reg45 (%c13): undefined
+	control reg46 (%c14): undefined
+	control reg47 (%c15): undefined
+	access reg48 (%a0): undefined
+	access reg49 (%a1): undefined
+	access reg50 (%a2): undefined
+	access reg51 (%a3): undefined
+	access reg52 (%a4): undefined
+	access reg53 (%a5): undefined
+	access reg54 (%a6): undefined
+	access reg55 (%a7): undefined
+	access reg56 (%a8): undefined
+	access reg57 (%a9): undefined
+	access reg58 (%a10): undefined
+	access reg59 (%a11): undefined
+	access reg60 (%a12): undefined
+	access reg61 (%a13): undefined
+	access reg62 (%a14): undefined
+	access reg63 (%a15): undefined
+	control reg64 (%pswm): undefined
+	control reg65 (%pswa): undefined
+handle_cfi no CFI (.debug_frame): no error
+EOF
+
+# EM_S390 (ELFCLASS64) (function bar 0x0000000080000510)
+# Note. Only in .eh_frame, there is no .debug_frame.
+# Same as s390 above but without -m31.
+testfiles testfiles390x
+testrun_compare ${abs_builddir}/addrcfi -e testfiles390x 0x0000000080000510 <<\EOF
+.eh_frame has 0x80000510 => [0x80000510, 0x80000524):
+	return address in reg14
+	CFA location expression: bregx(15,160)
+	integer reg0 (%r0): undefined
+	integer reg1 (%r1): undefined
+	integer reg2 (%r2): undefined
+	integer reg3 (%r3): undefined
+	integer reg4 (%r4): undefined
+	integer reg5 (%r5): undefined
+	integer reg6 (%r6): same_value
+	integer reg7 (%r7): same_value
+	integer reg8 (%r8): same_value
+	integer reg9 (%r9): same_value
+	integer reg10 (%r10): same_value
+	integer reg11 (%r11): same_value
+	integer reg12 (%r12): same_value
+	integer reg13 (%r13): same_value
+	integer reg14 (%r14): same_value
+	integer reg15 (%r15): same_value
+	FPU reg16 (%f0): undefined
+	FPU reg17 (%f2): undefined
+	FPU reg18 (%f4): undefined
+	FPU reg19 (%f6): undefined
+	FPU reg20 (%f1): undefined
+	FPU reg21 (%f3): undefined
+	FPU reg22 (%f5): undefined
+	FPU reg23 (%f7): undefined
+	FPU reg24 (%f8): same_value
+	FPU reg25 (%f10): same_value
+	FPU reg26 (%f12): same_value
+	FPU reg27 (%f14): same_value
+	FPU reg28 (%f9): same_value
+	FPU reg29 (%f11): same_value
+	FPU reg30 (%f13): same_value
+	FPU reg31 (%f15): same_value
+	control reg32 (%c0): undefined
+	control reg33 (%c1): undefined
+	control reg34 (%c2): undefined
+	control reg35 (%c3): undefined
+	control reg36 (%c4): undefined
+	control reg37 (%c5): undefined
+	control reg38 (%c6): undefined
+	control reg39 (%c7): undefined
+	control reg40 (%c8): undefined
+	control reg41 (%c9): undefined
+	control reg42 (%c10): undefined
+	control reg43 (%c11): undefined
+	control reg44 (%c12): undefined
+	control reg45 (%c13): undefined
+	control reg46 (%c14): undefined
+	control reg47 (%c15): undefined
+	access reg48 (%a0): undefined
+	access reg49 (%a1): undefined
+	access reg50 (%a2): undefined
+	access reg51 (%a3): undefined
+	access reg52 (%a4): undefined
+	access reg53 (%a5): undefined
+	access reg54 (%a6): undefined
+	access reg55 (%a7): undefined
+	access reg56 (%a8): undefined
+	access reg57 (%a9): undefined
+	access reg58 (%a10): undefined
+	access reg59 (%a11): undefined
+	access reg60 (%a12): undefined
+	access reg61 (%a13): undefined
+	access reg62 (%a14): undefined
+	access reg63 (%a15): undefined
+	control reg64 (%pswm): undefined
+	control reg65 (%pswa): undefined
+handle_cfi no CFI (.debug_frame): no error
+EOF
+
+# EM_ARM (function bar 0x00008510)
+# Note. Only in .debug_frame, the .eh_frame is actually empty.
+# Same as s390 and ppc above.
+testfiles testfilearm
+testrun_compare ${abs_builddir}/addrcfi -e testfilearm 0x00008510 <<\EOF
+dwarf_cfi_addrframe (.eh_frame): no matching address range
+.debug_frame has 0x8510 => [0x8510, 0x8524):
+	return address in reg14
+	CFA location expression: bregx(13)
+	integer reg0 (r0): undefined
+	integer reg1 (r1): undefined
+	integer reg2 (r2): undefined
+	integer reg3 (r3): undefined
+	integer reg4 (r4): same_value
+	integer reg5 (r5): same_value
+	integer reg6 (r6): same_value
+	integer reg7 (r7): same_value
+	integer reg8 (r8): same_value
+	integer reg9 (r9): undefined
+	integer reg10 (r10): same_value
+	integer reg11 (r11): same_value
+	integer reg12 (r12): undefined
+	integer reg13 (sp): location expression: call_frame_cfa stack_value
+	integer reg14 (lr): same_value
+	integer reg15 (pc): location expression: regx(14)
+	FPA reg16 (f0): undefined
+	FPA reg17 (f1): undefined
+	FPA reg18 (f2): undefined
+	FPA reg19 (f3): undefined
+	FPA reg20 (f4): undefined
+	FPA reg21 (f5): undefined
+	FPA reg22 (f6): undefined
+	FPA reg23 (f7): undefined
+	FPA reg96 (f0): undefined
+	FPA reg97 (f1): undefined
+	FPA reg98 (f2): undefined
+	FPA reg99 (f3): undefined
+	FPA reg100 (f4): undefined
+	FPA reg101 (f5): undefined
+	FPA reg102 (f6): undefined
+	FPA reg103 (f7): undefined
+	integer reg128 (spsr): undefined
+	VFP reg256 (d0): undefined
+	VFP reg257 (d1): undefined
+	VFP reg258 (d2): undefined
+	VFP reg259 (d3): undefined
+	VFP reg260 (d4): undefined
+	VFP reg261 (d5): undefined
+	VFP reg262 (d6): undefined
+	VFP reg263 (d7): undefined
+	VFP reg264 (d8): same_value
+	VFP reg265 (d9): same_value
+	VFP reg266 (d10): same_value
+	VFP reg267 (d11): same_value
+	VFP reg268 (d12): same_value
+	VFP reg269 (d13): same_value
+	VFP reg270 (d14): same_value
+	VFP reg271 (d15): same_value
+	VFP reg272 (d16): undefined
+	VFP reg273 (d17): undefined
+	VFP reg274 (d18): undefined
+	VFP reg275 (d19): undefined
+	VFP reg276 (d20): undefined
+	VFP reg277 (d21): undefined
+	VFP reg278 (d22): undefined
+	VFP reg279 (d23): undefined
+	VFP reg280 (d24): undefined
+	VFP reg281 (d25): undefined
+	VFP reg282 (d26): undefined
+	VFP reg283 (d27): undefined
+	VFP reg284 (d28): undefined
+	VFP reg285 (d29): undefined
+	VFP reg286 (d30): undefined
+	VFP reg287 (d31): undefined
+EOF
+
+# EM_AARCH64 (function bar 0x400550)
+# Same as arm, 390 and ppc above.
+# Note missing coverage in .eh_frame.
+testfiles testfileaarch64
+testrun_compare ${abs_builddir}/addrcfi -e testfileaarch64 0x400550 <<\EOF
+dwarf_cfi_addrframe (.eh_frame): no matching address range
+.debug_frame has 0x400550 => [0x400550, 0x400568):
+	return address in reg30
+	CFA location expression: bregx(31)
+	integer reg0 (x0): undefined
+	integer reg1 (x1): undefined
+	integer reg2 (x2): undefined
+	integer reg3 (x3): undefined
+	integer reg4 (x4): undefined
+	integer reg5 (x5): undefined
+	integer reg6 (x6): undefined
+	integer reg7 (x7): undefined
+	integer reg8 (x8): undefined
+	integer reg9 (x9): undefined
+	integer reg10 (x10): undefined
+	integer reg11 (x11): undefined
+	integer reg12 (x12): undefined
+	integer reg13 (x13): undefined
+	integer reg14 (x14): undefined
+	integer reg15 (x15): undefined
+	integer reg16 (x16): undefined
+	integer reg17 (x17): undefined
+	integer reg18 (x18): undefined
+	integer reg19 (x19): same_value
+	integer reg20 (x20): same_value
+	integer reg21 (x21): same_value
+	integer reg22 (x22): same_value
+	integer reg23 (x23): same_value
+	integer reg24 (x24): same_value
+	integer reg25 (x25): same_value
+	integer reg26 (x26): same_value
+	integer reg27 (x27): same_value
+	integer reg28 (x28): same_value
+	integer reg29 (x29): same_value
+	integer reg30 (x30): same_value
+	integer reg31 (sp): undefined
+	integer reg33 (elr): undefined
+	FP/SIMD reg64 (v0): undefined
+	FP/SIMD reg65 (v1): undefined
+	FP/SIMD reg66 (v2): undefined
+	FP/SIMD reg67 (v3): undefined
+	FP/SIMD reg68 (v4): undefined
+	FP/SIMD reg69 (v5): undefined
+	FP/SIMD reg70 (v6): undefined
+	FP/SIMD reg71 (v7): undefined
+	FP/SIMD reg72 (v8): same_value
+	FP/SIMD reg73 (v9): same_value
+	FP/SIMD reg74 (v10): same_value
+	FP/SIMD reg75 (v11): same_value
+	FP/SIMD reg76 (v12): same_value
+	FP/SIMD reg77 (v13): same_value
+	FP/SIMD reg78 (v14): same_value
+	FP/SIMD reg79 (v15): same_value
+	FP/SIMD reg80 (v16): undefined
+	FP/SIMD reg81 (v17): undefined
+	FP/SIMD reg82 (v18): undefined
+	FP/SIMD reg83 (v19): undefined
+	FP/SIMD reg84 (v20): undefined
+	FP/SIMD reg85 (v21): undefined
+	FP/SIMD reg86 (v22): undefined
+	FP/SIMD reg87 (v23): undefined
+	FP/SIMD reg88 (v24): undefined
+	FP/SIMD reg89 (v25): undefined
+	FP/SIMD reg90 (v26): undefined
+	FP/SIMD reg91 (v27): undefined
+	FP/SIMD reg92 (v28): undefined
+	FP/SIMD reg93 (v29): undefined
+	FP/SIMD reg94 (v30): undefined
+	FP/SIMD reg95 (v31): undefined
+EOF
+
+# EM_X86_64/ELFCLASS32 (function bar 0x00400390)
+#
+# Note. Only in .eh_frame, there is no .debug_frame.
+# Same as PPC above but with -mx32.
+testfiles testfile-x32
+testrun_compare ${abs_builddir}/addrcfi -e testfile-x32 0x00400390 <<\EOF
+.eh_frame has 0x400390 => [0x400390, 0x40039c):
+	return address in reg16
+	CFA location expression: bregx(7,8)
+	integer reg0 (%rax): same_value
+	integer reg1 (%rdx): undefined
+	integer reg2 (%rcx): undefined
+	integer reg3 (%rbx): undefined
+	integer reg4 (%rsi): undefined
+	integer reg5 (%rdi): undefined
+	integer reg6 (%rbp): same_value
+	integer reg7 (%rsp): location expression: call_frame_cfa stack_value
+	integer reg8 (%r8): undefined
+	integer reg9 (%r9): undefined
+	integer reg10 (%r10): undefined
+	integer reg11 (%r11): undefined
+	integer reg12 (%r12): same_value
+	integer reg13 (%r13): same_value
+	integer reg14 (%r14): same_value
+	integer reg15 (%r15): same_value
+	integer reg16 (%rip): location expression: call_frame_cfa plus_uconst(-8)
+	SSE reg17 (%xmm0): undefined
+	SSE reg18 (%xmm1): undefined
+	SSE reg19 (%xmm2): undefined
+	SSE reg20 (%xmm3): undefined
+	SSE reg21 (%xmm4): undefined
+	SSE reg22 (%xmm5): undefined
+	SSE reg23 (%xmm6): undefined
+	SSE reg24 (%xmm7): undefined
+	SSE reg25 (%xmm8): undefined
+	SSE reg26 (%xmm9): undefined
+	SSE reg27 (%xmm10): undefined
+	SSE reg28 (%xmm11): undefined
+	SSE reg29 (%xmm12): undefined
+	SSE reg30 (%xmm13): undefined
+	SSE reg31 (%xmm14): undefined
+	SSE reg32 (%xmm15): undefined
+	x87 reg33 (%st0): undefined
+	x87 reg34 (%st1): undefined
+	x87 reg35 (%st2): undefined
+	x87 reg36 (%st3): undefined
+	x87 reg37 (%st4): undefined
+	x87 reg38 (%st5): undefined
+	x87 reg39 (%st6): undefined
+	x87 reg40 (%st7): undefined
+	MMX reg41 (%mm0): undefined
+	MMX reg42 (%mm1): undefined
+	MMX reg43 (%mm2): undefined
+	MMX reg44 (%mm3): undefined
+	MMX reg45 (%mm4): undefined
+	MMX reg46 (%mm5): undefined
+	MMX reg47 (%mm6): undefined
+	MMX reg48 (%mm7): undefined
+	integer reg49 (%rflags): undefined
+	segment reg50 (%es): undefined
+	segment reg51 (%cs): undefined
+	segment reg52 (%ss): undefined
+	segment reg53 (%ds): undefined
+	segment reg54 (%fs): undefined
+	segment reg55 (%gs): undefined
+	segment reg58 (%fs.base): undefined
+	segment reg59 (%gs.base): undefined
+	control reg62 (%tr): undefined
+	control reg63 (%ldtr): undefined
+	control reg64 (%mxcsr): undefined
+	control reg65 (%fcw): undefined
+	control reg66 (%fsw): undefined
+handle_cfi no CFI (.debug_frame): no error
+EOF
diff --git a/third_party/elfutils/tests/run-addrname-test.sh b/third_party/elfutils/tests/run-addrname-test.sh
new file mode 100755
index 0000000..90e19df
--- /dev/null
+++ b/third_party/elfutils/tests/run-addrname-test.sh
@@ -0,0 +1,360 @@
+#! /bin/sh
+# Copyright (C) 2007, 2008 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile34 testfile38 testfile41 testfile49
+
+testrun_compare ${abs_top_builddir}/src/addr2line -f -e testfile34 \
+				 0x08048074 0x08048075 0x08048076 \
+				 0x08049078 0x08048080 0x08049080 <<\EOF
+foo
+??:0
+bar
+??:0
+_etext
+??:0
+data1
+??:0
+??
+??:0
+_end
+??:0
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile38 0x02 0x10a 0x211 0x31a <<\EOF
+t1_global_outer+0x2
+??:0
+t2_global_symbol+0x2
+??:0
+t3_global_after_0+0x1
+??:0
+(.text)+0x31a
+??:0
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile41 0x1 0x104 <<\EOF
+small_global_at_large_global+0x1
+??:0
+small_global_first_at_large_global+0x1
+??:0
+EOF
+
+testfiles testfile12 testfile14
+tempfiles testmaps
+
+cat > testmaps <<EOF
+00400000-00401000 r-xp 00000000 fd:01 4006812                            `pwd`/testfile14
+00500000-00501000 rw-p 00000000 fd:01 4006812                            `pwd`/testfile14
+01000000-01001000 r-xp 00000000 fd:01 1234567				 `pwd`/testfile12
+01100000-01011000 rw-p 00000000 fd:01 1234567				 `pwd`/testfile12
+2aaaaaaab000-2aaaaaaad000 rw-p 2aaaaaaab000 00:00 0 
+2aaaaaae2000-2aaaaaae3000 rw-p 2aaaaaae2000 00:00 0 
+7fff61068000-7fff6107d000 rw-p 7ffffffea000 00:00 0                      [stack]
+7fff611fe000-7fff61200000 r-xp 7fff611fe000 00:00 0                      [vdso]
+ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -M testmaps 0x40047c 0x10009db <<\EOF
+caller+0x14
+/home/drepper/local/elfutils-build/20050425/v.c:11
+foo+0xb
+/home/drepper/local/elfutils-build/20030710/u.c:5
+EOF
+
+#	.section .text
+#	nop #0
+#sizeless_foo:
+#	nop #1
+#	nop #2
+#sized_bar:
+#	nop #3
+#	nop #4
+#sizeless_baz:
+#	nop #5
+#	nop #6
+#	.size sized_bar, . - sized_bar
+#	nop #7
+#	nop #8
+#sizeless_x:
+#	nop #9
+#	.org 0x100
+#	nop #0
+#	.globl global_outer
+#global_outer:
+#	nop #1
+#	nop #2
+#	.globl global_in_global
+#global_in_global:
+#	nop #3
+#	nop #4
+#	.size global_in_global, . - global_in_global
+#local_in_global:
+#	nop #5 
+#	nop #6 
+#	.size local_in_global, . - local_in_global
+#	nop #7
+#	nop #8
+#.Lsizeless1:
+#	nop #9
+#	nop #10
+#	.size global_outer, . - global_outer
+#	nop #11
+#	.org 0x200
+#	nop #0
+#local_outer:
+#	nop #1
+#	nop #2
+#	.globl global_in_local
+#global_in_local:
+#	nop #3
+#	nop #4
+#	.size global_in_local, . - global_in_local
+#local_in_local:
+#	nop #5 
+#	nop #6 
+#	.size local_in_local, . - local_in_local
+#	nop #7
+#	nop #8
+#.Lsizeless2:
+#	nop #9
+#	nop #10
+#	.size local_outer, . - local_outer
+#	nop #11
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile49 \
+    		0 1 2 3 4 5 6 7 8 9 \
+		0x100 0x101 0x102 0x103 0x104 0x105 \
+		0x106 0x107 0x108 0x109 0x10a 0x10b \
+		0x200 0x201 0x202 0x203 0x204 0x205 \
+		0x206 0x207 0x208 0x209 0x20a 0x20b <<\EOF
+(.text)+0
+??:0
+sizeless_foo
+??:0
+sizeless_foo+0x1
+??:0
+sized_bar
+??:0
+sized_bar+0x1
+??:0
+sized_bar+0x2
+??:0
+sized_bar+0x3
+??:0
+(.text)+0x7
+??:0
+(.text)+0x8
+??:0
+sizeless_x
+??:0
+sizeless_x+0xf7
+??:0
+global_outer
+??:0
+global_outer+0x1
+??:0
+global_in_global
+??:0
+global_in_global+0x1
+??:0
+global_outer+0x4
+??:0
+global_outer+0x5
+??:0
+global_outer+0x6
+??:0
+global_outer+0x7
+??:0
+global_outer+0x8
+??:0
+global_outer+0x9
+??:0
+(.text)+0x10b
+??:0
+(.text)+0x200
+??:0
+local_outer
+??:0
+local_outer+0x1
+??:0
+global_in_local
+??:0
+global_in_local+0x1
+??:0
+local_in_local
+??:0
+local_in_local+0x1
+??:0
+local_outer+0x6
+??:0
+local_outer+0x7
+??:0
+local_outer+0x8
+??:0
+local_outer+0x9
+??:0
+(.text)+0x20b
+??:0
+EOF
+
+#	.macro global label size
+#\label:	.globl \label
+#	.size \label, \size
+#	.endm
+#	.macro weak label size
+#\label:	.weak \label
+#	.size \label, \size
+#	.endm
+#	.macro local label size
+#\label:	.size \label, \size
+#	.endm
+#	.macro offset val
+#	.ifne (. - _start) - \val
+#	.err
+#	.endif
+#	.byte \val
+#	.endm
+#
+#_start:
+#	offset 0
+#
+#	local glocal, 1
+#	weak gweak, 1
+#	global gglobal1, 2
+#	global gglobal2, 1
+#	global gglobal3, 1
+#	offset 1
+#	/* Symbols end here.  */
+#	offset 2
+#	/* gglobal1 ends here.  */
+#	offset 3
+#
+#	local g0local, 0
+#	weak g0weak, 0
+#	global g0global1, 0
+#	global g0global2, 0
+#	offset 4
+#
+#	local wlocal, 1
+#	weak wweak1, 2
+#	weak wweak2, 1
+#	weak wweak3, 1
+#	offset 5
+#	/* Symbols end here.  */
+#	offset 6
+#	/* wweak1 ends here.  */
+#	offset 7
+#
+#	local w0local, 0
+#	weak w0weak1, 0
+#	weak w0weak2, 0
+#	offset 8
+#
+#	local llocal1, 2
+#	local llocal2, 1
+#	local llocal3, 1
+#	offset 9
+#	/* Symbols end here.  */
+#	offset 10
+#	/* llocal1 ends here.  */
+#	offset 11
+#
+#	local l0local1, 0
+#	local l0local2, 0
+#	offset 12
+testfiles testfile64
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile64 1 4 5 8 9 c <<\EOF
+gglobal2
+??:0
+g0global2
+??:0
+wweak2
+??:0
+w0weak2
+??:0
+llocal2
+??:0
+l0local2
+??:0
+EOF
+
+testfiles testfile65
+testrun_compare ${abs_top_builddir}/src/addr2line -S --core=testfile65 0x7fff94bffa30 <<\EOF
+__vdso_time
+??:0
+EOF
+
+#	.section	".text"
+#	.globl _start
+#	.section	".opd","aw"
+#_start:	.quad	.L._start,.TOC.@tocbase
+#	.previous
+#	.type	_start, @function
+#.L._start:
+#	.byte	0x7d, 0x82, 0x10, 0x08
+#	.size	_start,.-.L._start
+testfiles testfile66 testfile66.core
+testrun_compare ${abs_top_builddir}/src/addr2line -x -e testfile66 _start 0x2d8 0x2db 0x2dc 0x103d0 0x103d3 0x103d4<<EOF
+_start (.text)
+??:0
+_start (.text)
+??:0
+_start+0x3 (.text)
+??:0
+()+0x2dc
+??:0
+_start (.opd)
+??:0
+_start+0x3 (.opd)
+??:0
+()+0x103d4
+??:0
+EOF
+testrun_compare ${abs_top_builddir}/src/addr2line -x -e testfile66 --core=testfile66.core _start 0x461b02d8 0x461c03d0<<\EOF
+_start (.text)
+??:0
+_start (.text)
+??:0
+_start (.opd)
+??:0
+EOF
+
+testfiles testfile69.core testfile69.so
+testrun_compare ${abs_top_builddir}/src/addr2line --core=./testfile69.core -S 0x7f0bc6a33535 0x7f0bc6a33546 <<\EOF
+libstatic+0x9
+??:0
+libglobal+0x9
+??:0
+EOF
+
+testfiles testfile70.exec testfile70.core
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile70.exec --core=testfile70.core 0x7ff2cfe9b6b5 <<\EOF
+main+0x9
+??:0
+EOF
+testrun_compare ${abs_top_builddir}/src/addr2line -S --core=testfile70.core -e testfile70.exec 0x7ff2cfe9b6b5 <<\EOF
+main+0x9
+??:0
+EOF
+
+testfiles test-core-lib.so test-core.core test-core.exec
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e test-core.exec --core=test-core.core 0x7f67f2aaf619 <<\EOF
+libfunc+0x9
+??:0
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-addrscopes.sh b/third_party/elfutils/tests/run-addrscopes.sh
new file mode 100755
index 0000000..8f1bf0e
--- /dev/null
+++ b/third_party/elfutils/tests/run-addrscopes.sh
@@ -0,0 +1,43 @@
+#! /bin/sh
+# Copyright (C) 2005, 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile22
+
+testrun_compare ${abs_builddir}/addrscopes -e testfile22 0x8048353 <<\EOF
+0x8048353:
+    tests/foo.c (0x11): 0x8048348 (tests/foo.c:5) .. 0x804837c (tests/foo.c:16)
+        global                        [    be]
+        function (0x2e): 0x8048348 (tests/foo.c:5) .. 0x8048359 (tests/foo.c:11)
+            local                         [    8f]
+EOF
+
+test_cleanup
+
+testfiles testfile24
+testrun_compare ${abs_builddir}/addrscopes -e testfile24 0x804834e <<\EOF
+0x804834e:
+    inline-test.c (0x11): 0x8048348 (/home/roland/build/stock-elfutils/inline-test.c:7) .. 0x8048360 (/home/roland/build/stock-elfutils/inline-test.c:16)
+        add (0x1d): 0x804834e (/home/roland/build/stock-elfutils/inline-test.c:3) .. 0x804834f
+            y                             [    9d]
+            x                             [    a2]
+            x (abstract)
+            y (abstract)
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-aggregate-size.sh b/third_party/elfutils/tests/run-aggregate-size.sh
new file mode 100755
index 0000000..08d57bb
--- /dev/null
+++ b/third_party/elfutils/tests/run-aggregate-size.sh
@@ -0,0 +1,113 @@
+#! /bin/sh
+# Copyright (C) 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# char c;
+# int i;
+# long l;
+#
+# void *v;
+#
+# struct s
+# {
+#   char *a;
+#   int i;
+# } s;
+#
+# char ca[16];
+# int ia[32];
+# void *va[64];
+# struct s sa[8];
+
+# On x86_64 (LP64):
+# gcc -g -c -o testfile-sizes1.o sizes.c
+# clang -g -c -o testfile-sizes2.o sizes.c
+
+# const char c;
+# volatile int i;
+# const volatile long l;
+#
+# void * restrict v;
+#
+# struct s
+# {
+#   const char *a;
+#   volatile int i;
+# } s;
+#
+# const char ca[16];
+# volatile int ia[32];
+# const volatile void * const volatile restrict va[64];
+# struct s sa[8];
+# double d3d[3][4][5];
+#
+# typedef const int foo;
+# typedef volatile foo bar;
+# foo f;
+# bar b;
+#
+# gcc -std=c99 -g -c -o testfile-sizes3.o sizes.c
+
+# The file testfile-size4.o is hand-crafted.
+
+testfiles testfile-sizes1.o testfile-sizes2.o testfile-sizes3.o testfile-sizes4.o
+
+testrun_compare ${abs_builddir}/aggregate_size -e testfile-sizes1.o <<\EOF
+c size 1
+i size 4
+l size 8
+v size 8
+s size 16
+ca size 16
+ia size 128
+va size 512
+sa size 128
+EOF
+
+testrun_compare ${abs_builddir}/aggregate_size -e testfile-sizes2.o <<\EOF
+c size 1
+i size 4
+l size 8
+v size 8
+s size 16
+ca size 16
+ia size 128
+va size 512
+sa size 128
+EOF
+
+testrun_compare ${abs_builddir}/aggregate_size -e testfile-sizes3.o <<\EOF
+c size 1
+i size 4
+l size 8
+v size 8
+s size 16
+ca size 16
+ia size 128
+va size 512
+sa size 128
+d3d size 480
+f size 4
+b size 4
+EOF
+
+testrun_compare ${abs_builddir}/aggregate_size -e testfile-sizes4.o <<\EOF
+v size 257
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-alldts.sh b/third_party/elfutils/tests/run-alldts.sh
new file mode 100755
index 0000000..6a9a9ec
--- /dev/null
+++ b/third_party/elfutils/tests/run-alldts.sh
@@ -0,0 +1,98 @@
+#! /bin/sh
+# Copyright (C) 2011 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+tempfiles testfile-alldts
+
+# This will produce "testfile-alldts" file
+testrun ${abs_builddir}/alldts
+
+testrun_compare ${abs_top_builddir}/src/readelf -d testfile-alldts <<\EOF
+
+Dynamic segment contains 66 entries:
+ Addr: 0x000001a0  Offset: 0x000078  Link to section: [ 0] ''
+  Type              Value
+  NULL              
+  NEEDED            Shared library: [(null)]
+  PLTRELSZ          3735928559 (bytes)
+  PLTGOT            0xdeadbeef
+  HASH              0xdeadbeef
+  STRTAB            0xdeadbeef
+  SYMTAB            0xdeadbeef
+  RELA              0xdeadbeef
+  RELASZ            3735928559 (bytes)
+  RELAENT           3735928559 (bytes)
+  STRSZ             3735928559 (bytes)
+  SYMENT            3735928559 (bytes)
+  INIT              0xdeadbeef
+  FINI              0xdeadbeef
+  SONAME            Library soname: [(null)]
+  RPATH             Library rpath: [(null)]
+  SYMBOLIC          0xdeadbeef
+  REL               0xdeadbeef
+  RELSZ             3735928559 (bytes)
+  RELENT            3735928559 (bytes)
+  PLTREL            ???
+  DEBUG             
+  TEXTREL           
+  JMPREL            0xdeadbeef
+  BIND_NOW          
+  INIT_ARRAY        0xdeadbeef
+  FINI_ARRAY        0xdeadbeef
+  INIT_ARRAYSZ      3735928559 (bytes)
+  FINI_ARRAYSZ      3735928559 (bytes)
+  RUNPATH           Library runpath: [(null)]
+  FLAGS             ORIGIN SYMBOLIC TEXTREL BIND_NOW 0xdeadbee0
+  PREINIT_ARRAY     0xdeadbeef
+  PREINIT_ARRAY     0xdeadbeef
+  PREINIT_ARRAYSZ   0xdeadbeef
+  VERSYM            0xdeadbeef
+  GNU_PRELINKED     0xdeadbeef
+  GNU_CONFLICTSZ    3735928559 (bytes)
+  GNU_LIBLISTSZ     3735928559 (bytes)
+  CHECKSUM          0xdeadbeef
+  PLTPADSZ          3735928559 (bytes)
+  MOVEENT           3735928559 (bytes)
+  MOVESZ            3735928559 (bytes)
+  FEATURE_1         PARINIT CONFEXP 0xdeadbeec
+  POSFLAG_1         LAZYLOAD GROUPPERM 0xdeadbeec
+  SYMINSZ           3735928559 (bytes)
+  SYMINENT          3735928559 (bytes)
+  GNU_HASH          0xdeadbeef
+  TLSDESC_PLT       0xdeadbeef
+  TLSDESC_GOT       0xdeadbeef
+  GNU_CONFLICT      0xdeadbeef
+  GNU_LIBLIST       0xdeadbeef
+  CONFIG            0xdeadbeef
+  DEPAUDIT          0xdeadbeef
+  AUDIT             0xdeadbeef
+  PLTPAD            0xdeadbeef
+  MOVETAB           0xdeadbeef
+  SYMINFO           0xdeadbeef
+  RELACOUNT         3735928559
+  RELCOUNT          3735928559
+  FLAGS_1           NOW GLOBAL GROUP NODELETE INITFIRST NOOPEN ORIGIN TRANS INTERPOSE NODEFLIB NODUMP CONFALT DISPRELDNE DISPRELPND 0xdeac0000
+  VERDEF            0xdeadbeef
+  VERDEFNUM         3735928559
+  VERNEED           0xdeadbeef
+  VERNEEDNUM        3735928559
+  AUXILIARY         0xdeadbeef
+  FILTER            0xdeadbeef
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-allfcts-multi.sh b/third_party/elfutils/tests/run-allfcts-multi.sh
new file mode 100755
index 0000000..ef7bb30
--- /dev/null
+++ b/third_party/elfutils/tests/run-allfcts-multi.sh
@@ -0,0 +1,72 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# See run-readelf-dwz-multi.sh
+testfiles libtestfile_multi_shared.so testfile_multi_main testfile_multi.dwz
+testfiles testfile-dwzstr testfile-dwzstr.multi
+
+testrun_compare ${abs_builddir}/allfcts testfile_multi_main libtestfile_multi_shared.so testfile-dwzstr <<\EOF
+/home/mark/src/tests/dwz/main.c:3:main
+/home/mark/src/tests/dwz/shared.c:3:call_foo
+/home/mark/src/tests/main.c:8:main
+EOF
+
+# - test-offset-loop.c
+#
+# #include <stdbool.h>
+# #include <string.h>
+# #include <errno.h>
+# void padding (int x, int y, int z) { }
+# static inline bool is_error (int err) { return err != 0; }
+# static inline int get_errno (void) { return errno; }
+# int main () { return is_error (get_errno ()); }
+#
+# gcc -g -O2 test-offset-loop.c -o test-offset-loop
+# cp test-offset-loop test-offset-loop2
+# dwz test-offset-loop test-offset-loop2 -m test-offset-loop.alt
+
+testfiles test-offset-loop test-offset-loop.alt
+tempfiles allfcts.out
+
+# Use head to capture output because the output could be infinite...
+testrun ${abs_builddir}/allfcts test-offset-loop | head -n 20 > allfcts.out
+testrun_compare cat allfcts.out <<\EOF
+/tmp/test-offset-loop.c:6:get_errno
+/tmp/test-offset-loop.c:5:is_error
+/tmp/test-offset-loop.c:4:padding
+/tmp/test-offset-loop.c:7:main
+EOF
+
+# allfcts has a too simple mechanism for setting the alt file.
+# check that if we don't set it, things still work (because libdw will
+# find the alt file for us).
+mkdir subdir
+mv test-offset-loop test-offset-loop.alt subdir/
+testrun ${abs_builddir}/allfcts subdir/test-offset-loop > allfcts.out
+testrun_compare cat allfcts.out <<\EOF
+Warning: no alt file found.
+/tmp/test-offset-loop.c:6:get_errno
+/tmp/test-offset-loop.c:5:is_error
+/tmp/test-offset-loop.c:4:padding
+/tmp/test-offset-loop.c:7:main
+EOF
+
+rm -rf subdir
+
+exit 0
diff --git a/third_party/elfutils/tests/run-allfcts.sh b/third_party/elfutils/tests/run-allfcts.sh
new file mode 100755
index 0000000..6eaf13c
--- /dev/null
+++ b/third_party/elfutils/tests/run-allfcts.sh
@@ -0,0 +1,94 @@
+#! /bin/sh
+# Copyright (C) 2005, 2013 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile testfile2 testfile8
+
+testrun_compare ${abs_builddir}/allfcts testfile testfile2 testfile8 <<\EOF
+/home/drepper/gnu/new-bu/build/ttt/m.c:5:main
+/home/drepper/gnu/new-bu/build/ttt/b.c:4:bar
+/home/drepper/gnu/new-bu/build/ttt/f.c:3:foo
+/shoggoth/drepper/b.c:4:bar
+/shoggoth/drepper/f.c:3:foo
+/shoggoth/drepper/m.c:5:main
+/home/drepper/gnu/elfutils/build/src/../../src/strip.c:107:main
+/home/drepper/gnu/elfutils/build/src/../../src/strip.c:159:print_version
+/home/drepper/gnu/elfutils/build/src/../../src/strip.c:173:parse_opt
+/home/drepper/gnu/elfutils/build/src/../../src/strip.c:201:more_help
+/home/drepper/gnu/elfutils/build/src/../../src/strip.c:217:process_file
+/usr/include/sys/stat.h:375:stat64
+/home/drepper/gnu/elfutils/build/src/../../src/strip.c:291:crc32_file
+/home/drepper/gnu/elfutils/build/src/../../src/strip.c:313:handle_elf
+EOF
+
+# = nested_funcs.c =
+#
+# static int
+# foo (int x)
+# {
+#   int bar (int y)
+#   {
+#     return x - y;
+#   }
+# 
+#   return bar (x * 2);
+# }
+#
+# int
+# main (int argc, char ** argv)
+# {
+#   return foo (argc);
+# }
+#
+# gcc -g -o nested_funcs nested_funcs.c
+
+# = class_func.cxx =
+#
+# namespace foobar
+# {
+#   class Foo
+#   {
+#   public:
+#     int bar(int x);
+#   };
+#
+#   int Foo::bar(int x) { return x - 42; }
+# };
+#
+# int
+# main (int argc, char **argv)
+# {
+#   foobar::Foo foo;
+#
+#   return foo.bar (42);
+# }
+#
+# clang++ -g -o class_func class_func.cxx
+
+testfiles testfile_nested_funcs testfile_class_func
+
+testrun_compare ${abs_builddir}/allfcts testfile_nested_funcs testfile_class_func <<\EOF
+/home/mark/src/tests/nested/nested_funcs.c:2:foo
+/home/mark/src/tests/nested/nested_funcs.c:4:bar
+/home/mark/src/tests/nested/nested_funcs.c:13:main
+/home/mark/src/tests/nested/class_func.cxx:6:bar
+/home/mark/src/tests/nested/class_func.cxx:13:main
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-allregs.sh b/third_party/elfutils/tests/run-allregs.sh
new file mode 100755
index 0000000..7ddd452
--- /dev/null
+++ b/third_party/elfutils/tests/run-allregs.sh
@@ -0,0 +1,2905 @@
+#! /bin/sh
+# Copyright (C) 2005, 2006, 2007, 2012, 2013 Red Hat, Inc.
+# Copyright (C) H.J. Lu <hjl.tools@gmail.com>, 2015.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+regs_test()
+{
+  tempfiles good.regs
+  cat > good.regs
+  testfiles "$@"
+  for f; do testrun_compare ${abs_builddir}/allregs -e $f < good.regs; done
+  test_cleanup
+}
+
+regs_test testfile11 <<\EOF
+integer registers:
+	  0: %eax (eax), signed 32 bits
+	  1: %ecx (ecx), signed 32 bits
+	  2: %edx (edx), signed 32 bits
+	  3: %ebx (ebx), signed 32 bits
+	  4: %esp (esp), address 32 bits
+	  5: %ebp (ebp), address 32 bits
+	  6: %esi (esi), signed 32 bits
+	  7: %edi (edi), signed 32 bits
+	  8: %eip (eip), address 32 bits
+	  9: %eflags (eflags), unsigned 32 bits
+	 10: %trapno (trapno), unsigned 32 bits
+FPU-control registers:
+	 37: %fctrl (fctrl), unsigned 16 bits
+	 38: %fstat (fstat), unsigned 16 bits
+	 39: %mxcsr (mxcsr), unsigned 32 bits
+MMX registers:
+	 29: %mm0 (mm0), unsigned 64 bits
+	 30: %mm1 (mm1), unsigned 64 bits
+	 31: %mm2 (mm2), unsigned 64 bits
+	 32: %mm3 (mm3), unsigned 64 bits
+	 33: %mm4 (mm4), unsigned 64 bits
+	 34: %mm5 (mm5), unsigned 64 bits
+	 35: %mm6 (mm6), unsigned 64 bits
+	 36: %mm7 (mm7), unsigned 64 bits
+SSE registers:
+	 21: %xmm0 (xmm0), unsigned 128 bits
+	 22: %xmm1 (xmm1), unsigned 128 bits
+	 23: %xmm2 (xmm2), unsigned 128 bits
+	 24: %xmm3 (xmm3), unsigned 128 bits
+	 25: %xmm4 (xmm4), unsigned 128 bits
+	 26: %xmm5 (xmm5), unsigned 128 bits
+	 27: %xmm6 (xmm6), unsigned 128 bits
+	 28: %xmm7 (xmm7), unsigned 128 bits
+segment registers:
+	 40: %es (es), unsigned 16 bits
+	 41: %cs (cs), unsigned 16 bits
+	 42: %ss (ss), unsigned 16 bits
+	 43: %ds (ds), unsigned 16 bits
+	 44: %fs (fs), unsigned 16 bits
+	 45: %gs (gs), unsigned 16 bits
+x87 registers:
+	 11: %st0 (st0), float 80 bits
+	 12: %st1 (st1), float 80 bits
+	 13: %st2 (st2), float 80 bits
+	 14: %st3 (st3), float 80 bits
+	 15: %st4 (st4), float 80 bits
+	 16: %st5 (st5), float 80 bits
+	 17: %st6 (st6), float 80 bits
+	 18: %st7 (st7), float 80 bits
+EOF
+
+regs_test testfile12 <<\EOF
+integer registers:
+	  0: %rax (rax), signed 64 bits
+	  1: %rdx (rdx), signed 64 bits
+	  2: %rcx (rcx), signed 64 bits
+	  3: %rbx (rbx), signed 64 bits
+	  4: %rsi (rsi), signed 64 bits
+	  5: %rdi (rdi), signed 64 bits
+	  6: %rbp (rbp), address 64 bits
+	  7: %rsp (rsp), address 64 bits
+	  8: %r8 (r8), signed 64 bits
+	  9: %r9 (r9), signed 64 bits
+	 10: %r10 (r10), signed 64 bits
+	 11: %r11 (r11), signed 64 bits
+	 12: %r12 (r12), signed 64 bits
+	 13: %r13 (r13), signed 64 bits
+	 14: %r14 (r14), signed 64 bits
+	 15: %r15 (r15), signed 64 bits
+	 16: %rip (rip), address 64 bits
+	 49: %rflags (rflags), unsigned 64 bits
+MMX registers:
+	 41: %mm0 (mm0), unsigned 64 bits
+	 42: %mm1 (mm1), unsigned 64 bits
+	 43: %mm2 (mm2), unsigned 64 bits
+	 44: %mm3 (mm3), unsigned 64 bits
+	 45: %mm4 (mm4), unsigned 64 bits
+	 46: %mm5 (mm5), unsigned 64 bits
+	 47: %mm6 (mm6), unsigned 64 bits
+	 48: %mm7 (mm7), unsigned 64 bits
+SSE registers:
+	 17: %xmm0 (xmm0), unsigned 128 bits
+	 18: %xmm1 (xmm1), unsigned 128 bits
+	 19: %xmm2 (xmm2), unsigned 128 bits
+	 20: %xmm3 (xmm3), unsigned 128 bits
+	 21: %xmm4 (xmm4), unsigned 128 bits
+	 22: %xmm5 (xmm5), unsigned 128 bits
+	 23: %xmm6 (xmm6), unsigned 128 bits
+	 24: %xmm7 (xmm7), unsigned 128 bits
+	 25: %xmm8 (xmm8), unsigned 128 bits
+	 26: %xmm9 (xmm9), unsigned 128 bits
+	 27: %xmm10 (xmm10), unsigned 128 bits
+	 28: %xmm11 (xmm11), unsigned 128 bits
+	 29: %xmm12 (xmm12), unsigned 128 bits
+	 30: %xmm13 (xmm13), unsigned 128 bits
+	 31: %xmm14 (xmm14), unsigned 128 bits
+	 32: %xmm15 (xmm15), unsigned 128 bits
+control registers:
+	 62: %tr (tr), unsigned 64 bits
+	 63: %ldtr (ldtr), unsigned 64 bits
+	 64: %mxcsr (mxcsr), unsigned 64 bits
+	 65: %fcw (fcw), unsigned 16 bits
+	 66: %fsw (fsw), unsigned 16 bits
+segment registers:
+	 50: %es (es), unsigned 16 bits
+	 51: %cs (cs), unsigned 16 bits
+	 52: %ss (ss), unsigned 16 bits
+	 53: %ds (ds), unsigned 16 bits
+	 54: %fs (fs), unsigned 16 bits
+	 55: %gs (gs), unsigned 16 bits
+	 58: %fs.base (fs.base), address 64 bits
+	 59: %gs.base (gs.base), address 64 bits
+x87 registers:
+	 33: %st0 (st0), float 80 bits
+	 34: %st1 (st1), float 80 bits
+	 35: %st2 (st2), float 80 bits
+	 36: %st3 (st3), float 80 bits
+	 37: %st4 (st4), float 80 bits
+	 38: %st5 (st5), float 80 bits
+	 39: %st6 (st6), float 80 bits
+	 40: %st7 (st7), float 80 bits
+EOF
+
+regs_test testfile2 <<\EOF
+integer registers:
+	  0: r0 (r0), signed 32 bits
+	  1: r1 (r1), signed 32 bits
+	  2: r2 (r2), signed 32 bits
+	  3: r3 (r3), signed 32 bits
+	  4: r4 (r4), signed 32 bits
+	  5: r5 (r5), signed 32 bits
+	  6: r6 (r6), signed 32 bits
+	  7: r7 (r7), signed 32 bits
+	  8: r8 (r8), signed 32 bits
+	  9: r9 (r9), signed 32 bits
+	 10: r10 (r10), signed 32 bits
+	 11: r11 (r11), signed 32 bits
+	 12: r12 (r12), signed 32 bits
+	 13: r13 (r13), signed 32 bits
+	 14: r14 (r14), signed 32 bits
+	 15: r15 (r15), signed 32 bits
+	 16: r16 (r16), signed 32 bits
+	 17: r17 (r17), signed 32 bits
+	 18: r18 (r18), signed 32 bits
+	 19: r19 (r19), signed 32 bits
+	 20: r20 (r20), signed 32 bits
+	 21: r21 (r21), signed 32 bits
+	 22: r22 (r22), signed 32 bits
+	 23: r23 (r23), signed 32 bits
+	 24: r24 (r24), signed 32 bits
+	 25: r25 (r25), signed 32 bits
+	 26: r26 (r26), signed 32 bits
+	 27: r27 (r27), signed 32 bits
+	 28: r28 (r28), signed 32 bits
+	 29: r29 (r29), signed 32 bits
+	 30: r30 (r30), signed 32 bits
+	 31: r31 (r31), signed 32 bits
+	 64: cr (cr), unsigned 32 bits
+	 66: msr (msr), unsigned 32 bits
+FPU registers:
+	 32: f0 (f0), float 64 bits
+	 33: f1 (f1), float 64 bits
+	 34: f2 (f2), float 64 bits
+	 35: f3 (f3), float 64 bits
+	 36: f4 (f4), float 64 bits
+	 37: f5 (f5), float 64 bits
+	 38: f6 (f6), float 64 bits
+	 39: f7 (f7), float 64 bits
+	 40: f8 (f8), float 64 bits
+	 41: f9 (f9), float 64 bits
+	 42: f10 (f10), float 64 bits
+	 43: f11 (f11), float 64 bits
+	 44: f12 (f12), float 64 bits
+	 45: f13 (f13), float 64 bits
+	 46: f14 (f14), float 64 bits
+	 47: f15 (f15), float 64 bits
+	 48: f16 (f16), float 64 bits
+	 49: f17 (f17), float 64 bits
+	 50: f18 (f18), float 64 bits
+	 51: f19 (f19), float 64 bits
+	 52: f20 (f20), float 64 bits
+	 53: f21 (f21), float 64 bits
+	 54: f22 (f22), float 64 bits
+	 55: f23 (f23), float 64 bits
+	 56: f24 (f24), float 64 bits
+	 57: f25 (f25), float 64 bits
+	 58: f26 (f26), float 64 bits
+	 59: f27 (f27), float 64 bits
+	 60: f28 (f28), float 64 bits
+	 61: f29 (f29), float 64 bits
+	 62: f30 (f30), float 64 bits
+	 63: f31 (f31), float 64 bits
+	 65: fpscr (fpscr), unsigned 32 bits
+privileged registers:
+	 70: sr0 (sr0), unsigned 32 bits
+	 71: sr1 (sr1), unsigned 32 bits
+	 72: sr2 (sr2), unsigned 32 bits
+	 73: sr3 (sr3), unsigned 32 bits
+	 74: sr4 (sr4), unsigned 32 bits
+	 75: sr5 (sr5), unsigned 32 bits
+	 76: sr6 (sr6), unsigned 32 bits
+	 77: sr7 (sr7), unsigned 32 bits
+	 78: sr8 (sr8), unsigned 32 bits
+	 79: sr9 (sr9), unsigned 32 bits
+	 80: sr10 (sr10), unsigned 32 bits
+	 81: sr11 (sr11), unsigned 32 bits
+	 82: sr12 (sr12), unsigned 32 bits
+	 83: sr13 (sr13), unsigned 32 bits
+	 84: sr14 (sr14), unsigned 32 bits
+	 85: sr15 (sr15), unsigned 32 bits
+	100: mq (mq), unsigned 32 bits
+	101: xer (xer), unsigned 32 bits
+	102: spr2 (spr2), unsigned 32 bits
+	103: spr3 (spr3), unsigned 32 bits
+	104: spr4 (spr4), unsigned 32 bits
+	105: spr5 (spr5), unsigned 32 bits
+	106: spr6 (spr6), unsigned 32 bits
+	107: spr7 (spr7), unsigned 32 bits
+	108: lr (lr), unsigned 32 bits
+	109: ctr (ctr), unsigned 32 bits
+	110: spr10 (spr10), unsigned 32 bits
+	111: spr11 (spr11), unsigned 32 bits
+	112: spr12 (spr12), unsigned 32 bits
+	113: spr13 (spr13), unsigned 32 bits
+	114: tfhar (tfhar), unsigned 32 bits
+	115: tfiar (tfiar), unsigned 32 bits
+	116: texasr (texasr), unsigned 32 bits
+	117: spr17 (spr17), unsigned 32 bits
+	118: dsisr (dsisr), unsigned 32 bits
+	119: dar (dar), unsigned 32 bits
+	120: spr20 (spr20), unsigned 32 bits
+	121: spr21 (spr21), unsigned 32 bits
+	122: dec (dec), unsigned 32 bits
+	123: spr23 (spr23), unsigned 32 bits
+	124: spr24 (spr24), unsigned 32 bits
+	125: spr25 (spr25), unsigned 32 bits
+	126: spr26 (spr26), unsigned 32 bits
+	127: spr27 (spr27), unsigned 32 bits
+	128: spr28 (spr28), unsigned 32 bits
+	129: spr29 (spr29), unsigned 32 bits
+	130: spr30 (spr30), unsigned 32 bits
+	131: spr31 (spr31), unsigned 32 bits
+	132: spr32 (spr32), unsigned 32 bits
+	133: spr33 (spr33), unsigned 32 bits
+	134: spr34 (spr34), unsigned 32 bits
+	135: spr35 (spr35), unsigned 32 bits
+	136: spr36 (spr36), unsigned 32 bits
+	137: spr37 (spr37), unsigned 32 bits
+	138: spr38 (spr38), unsigned 32 bits
+	139: spr39 (spr39), unsigned 32 bits
+	140: spr40 (spr40), unsigned 32 bits
+	141: spr41 (spr41), unsigned 32 bits
+	142: spr42 (spr42), unsigned 32 bits
+	143: spr43 (spr43), unsigned 32 bits
+	144: spr44 (spr44), unsigned 32 bits
+	145: spr45 (spr45), unsigned 32 bits
+	146: spr46 (spr46), unsigned 32 bits
+	147: spr47 (spr47), unsigned 32 bits
+	148: spr48 (spr48), unsigned 32 bits
+	149: spr49 (spr49), unsigned 32 bits
+	150: spr50 (spr50), unsigned 32 bits
+	151: spr51 (spr51), unsigned 32 bits
+	152: spr52 (spr52), unsigned 32 bits
+	153: spr53 (spr53), unsigned 32 bits
+	154: spr54 (spr54), unsigned 32 bits
+	155: spr55 (spr55), unsigned 32 bits
+	156: spr56 (spr56), unsigned 32 bits
+	157: spr57 (spr57), unsigned 32 bits
+	158: spr58 (spr58), unsigned 32 bits
+	159: spr59 (spr59), unsigned 32 bits
+	160: spr60 (spr60), unsigned 32 bits
+	161: spr61 (spr61), unsigned 32 bits
+	162: spr62 (spr62), unsigned 32 bits
+	163: spr63 (spr63), unsigned 32 bits
+	164: spr64 (spr64), unsigned 32 bits
+	165: spr65 (spr65), unsigned 32 bits
+	166: spr66 (spr66), unsigned 32 bits
+	167: spr67 (spr67), unsigned 32 bits
+	168: spr68 (spr68), unsigned 32 bits
+	169: spr69 (spr69), unsigned 32 bits
+	170: spr70 (spr70), unsigned 32 bits
+	171: spr71 (spr71), unsigned 32 bits
+	172: spr72 (spr72), unsigned 32 bits
+	173: spr73 (spr73), unsigned 32 bits
+	174: spr74 (spr74), unsigned 32 bits
+	175: spr75 (spr75), unsigned 32 bits
+	176: spr76 (spr76), unsigned 32 bits
+	177: spr77 (spr77), unsigned 32 bits
+	178: spr78 (spr78), unsigned 32 bits
+	179: spr79 (spr79), unsigned 32 bits
+	180: spr80 (spr80), unsigned 32 bits
+	181: spr81 (spr81), unsigned 32 bits
+	182: spr82 (spr82), unsigned 32 bits
+	183: spr83 (spr83), unsigned 32 bits
+	184: spr84 (spr84), unsigned 32 bits
+	185: spr85 (spr85), unsigned 32 bits
+	186: spr86 (spr86), unsigned 32 bits
+	187: spr87 (spr87), unsigned 32 bits
+	188: spr88 (spr88), unsigned 32 bits
+	189: spr89 (spr89), unsigned 32 bits
+	190: spr90 (spr90), unsigned 32 bits
+	191: spr91 (spr91), unsigned 32 bits
+	192: spr92 (spr92), unsigned 32 bits
+	193: spr93 (spr93), unsigned 32 bits
+	194: spr94 (spr94), unsigned 32 bits
+	195: spr95 (spr95), unsigned 32 bits
+	196: spr96 (spr96), unsigned 32 bits
+	197: spr97 (spr97), unsigned 32 bits
+	198: spr98 (spr98), unsigned 32 bits
+	199: spr99 (spr99), unsigned 32 bits
+	200: spr100 (spr100), unsigned 32 bits
+	201: spr101 (spr101), unsigned 32 bits
+	202: spr102 (spr102), unsigned 32 bits
+	203: spr103 (spr103), unsigned 32 bits
+	204: spr104 (spr104), unsigned 32 bits
+	205: spr105 (spr105), unsigned 32 bits
+	206: spr106 (spr106), unsigned 32 bits
+	207: spr107 (spr107), unsigned 32 bits
+	208: spr108 (spr108), unsigned 32 bits
+	209: spr109 (spr109), unsigned 32 bits
+	210: spr110 (spr110), unsigned 32 bits
+	211: spr111 (spr111), unsigned 32 bits
+	212: spr112 (spr112), unsigned 32 bits
+	213: spr113 (spr113), unsigned 32 bits
+	214: spr114 (spr114), unsigned 32 bits
+	215: spr115 (spr115), unsigned 32 bits
+	216: spr116 (spr116), unsigned 32 bits
+	217: spr117 (spr117), unsigned 32 bits
+	218: spr118 (spr118), unsigned 32 bits
+	219: spr119 (spr119), unsigned 32 bits
+	220: spr120 (spr120), unsigned 32 bits
+	221: spr121 (spr121), unsigned 32 bits
+	222: spr122 (spr122), unsigned 32 bits
+	223: spr123 (spr123), unsigned 32 bits
+	224: spr124 (spr124), unsigned 32 bits
+	225: spr125 (spr125), unsigned 32 bits
+	226: spr126 (spr126), unsigned 32 bits
+	227: spr127 (spr127), unsigned 32 bits
+	228: spr128 (spr128), unsigned 32 bits
+	229: spr129 (spr129), unsigned 32 bits
+	230: spr130 (spr130), unsigned 32 bits
+	231: spr131 (spr131), unsigned 32 bits
+	232: spr132 (spr132), unsigned 32 bits
+	233: spr133 (spr133), unsigned 32 bits
+	234: spr134 (spr134), unsigned 32 bits
+	235: spr135 (spr135), unsigned 32 bits
+	236: spr136 (spr136), unsigned 32 bits
+	237: spr137 (spr137), unsigned 32 bits
+	238: spr138 (spr138), unsigned 32 bits
+	239: spr139 (spr139), unsigned 32 bits
+	240: spr140 (spr140), unsigned 32 bits
+	241: spr141 (spr141), unsigned 32 bits
+	242: spr142 (spr142), unsigned 32 bits
+	243: spr143 (spr143), unsigned 32 bits
+	244: spr144 (spr144), unsigned 32 bits
+	245: spr145 (spr145), unsigned 32 bits
+	246: spr146 (spr146), unsigned 32 bits
+	247: spr147 (spr147), unsigned 32 bits
+	248: spr148 (spr148), unsigned 32 bits
+	249: spr149 (spr149), unsigned 32 bits
+	250: spr150 (spr150), unsigned 32 bits
+	251: spr151 (spr151), unsigned 32 bits
+	252: spr152 (spr152), unsigned 32 bits
+	253: spr153 (spr153), unsigned 32 bits
+	254: spr154 (spr154), unsigned 32 bits
+	255: spr155 (spr155), unsigned 32 bits
+	256: spr156 (spr156), unsigned 32 bits
+	257: spr157 (spr157), unsigned 32 bits
+	258: spr158 (spr158), unsigned 32 bits
+	259: spr159 (spr159), unsigned 32 bits
+	260: spr160 (spr160), unsigned 32 bits
+	261: spr161 (spr161), unsigned 32 bits
+	262: spr162 (spr162), unsigned 32 bits
+	263: spr163 (spr163), unsigned 32 bits
+	264: spr164 (spr164), unsigned 32 bits
+	265: spr165 (spr165), unsigned 32 bits
+	266: spr166 (spr166), unsigned 32 bits
+	267: spr167 (spr167), unsigned 32 bits
+	268: spr168 (spr168), unsigned 32 bits
+	269: spr169 (spr169), unsigned 32 bits
+	270: spr170 (spr170), unsigned 32 bits
+	271: spr171 (spr171), unsigned 32 bits
+	272: spr172 (spr172), unsigned 32 bits
+	273: spr173 (spr173), unsigned 32 bits
+	274: spr174 (spr174), unsigned 32 bits
+	275: spr175 (spr175), unsigned 32 bits
+	276: spr176 (spr176), unsigned 32 bits
+	277: spr177 (spr177), unsigned 32 bits
+	278: spr178 (spr178), unsigned 32 bits
+	279: spr179 (spr179), unsigned 32 bits
+	280: spr180 (spr180), unsigned 32 bits
+	281: spr181 (spr181), unsigned 32 bits
+	282: spr182 (spr182), unsigned 32 bits
+	283: spr183 (spr183), unsigned 32 bits
+	284: spr184 (spr184), unsigned 32 bits
+	285: spr185 (spr185), unsigned 32 bits
+	286: spr186 (spr186), unsigned 32 bits
+	287: spr187 (spr187), unsigned 32 bits
+	288: spr188 (spr188), unsigned 32 bits
+	289: spr189 (spr189), unsigned 32 bits
+	290: spr190 (spr190), unsigned 32 bits
+	291: spr191 (spr191), unsigned 32 bits
+	292: spr192 (spr192), unsigned 32 bits
+	293: spr193 (spr193), unsigned 32 bits
+	294: spr194 (spr194), unsigned 32 bits
+	295: spr195 (spr195), unsigned 32 bits
+	296: spr196 (spr196), unsigned 32 bits
+	297: spr197 (spr197), unsigned 32 bits
+	298: spr198 (spr198), unsigned 32 bits
+	299: spr199 (spr199), unsigned 32 bits
+	300: spr200 (spr200), unsigned 32 bits
+	301: spr201 (spr201), unsigned 32 bits
+	302: spr202 (spr202), unsigned 32 bits
+	303: spr203 (spr203), unsigned 32 bits
+	304: spr204 (spr204), unsigned 32 bits
+	305: spr205 (spr205), unsigned 32 bits
+	306: spr206 (spr206), unsigned 32 bits
+	307: spr207 (spr207), unsigned 32 bits
+	308: spr208 (spr208), unsigned 32 bits
+	309: spr209 (spr209), unsigned 32 bits
+	310: spr210 (spr210), unsigned 32 bits
+	311: spr211 (spr211), unsigned 32 bits
+	312: spr212 (spr212), unsigned 32 bits
+	313: spr213 (spr213), unsigned 32 bits
+	314: spr214 (spr214), unsigned 32 bits
+	315: spr215 (spr215), unsigned 32 bits
+	316: spr216 (spr216), unsigned 32 bits
+	317: spr217 (spr217), unsigned 32 bits
+	318: spr218 (spr218), unsigned 32 bits
+	319: spr219 (spr219), unsigned 32 bits
+	320: spr220 (spr220), unsigned 32 bits
+	321: spr221 (spr221), unsigned 32 bits
+	322: spr222 (spr222), unsigned 32 bits
+	323: spr223 (spr223), unsigned 32 bits
+	324: spr224 (spr224), unsigned 32 bits
+	325: spr225 (spr225), unsigned 32 bits
+	326: spr226 (spr226), unsigned 32 bits
+	327: spr227 (spr227), unsigned 32 bits
+	328: spr228 (spr228), unsigned 32 bits
+	329: spr229 (spr229), unsigned 32 bits
+	330: spr230 (spr230), unsigned 32 bits
+	331: spr231 (spr231), unsigned 32 bits
+	332: spr232 (spr232), unsigned 32 bits
+	333: spr233 (spr233), unsigned 32 bits
+	334: spr234 (spr234), unsigned 32 bits
+	335: spr235 (spr235), unsigned 32 bits
+	336: spr236 (spr236), unsigned 32 bits
+	337: spr237 (spr237), unsigned 32 bits
+	338: spr238 (spr238), unsigned 32 bits
+	339: spr239 (spr239), unsigned 32 bits
+	340: spr240 (spr240), unsigned 32 bits
+	341: spr241 (spr241), unsigned 32 bits
+	342: spr242 (spr242), unsigned 32 bits
+	343: spr243 (spr243), unsigned 32 bits
+	344: spr244 (spr244), unsigned 32 bits
+	345: spr245 (spr245), unsigned 32 bits
+	346: spr246 (spr246), unsigned 32 bits
+	347: spr247 (spr247), unsigned 32 bits
+	348: spr248 (spr248), unsigned 32 bits
+	349: spr249 (spr249), unsigned 32 bits
+	350: spr250 (spr250), unsigned 32 bits
+	351: spr251 (spr251), unsigned 32 bits
+	352: spr252 (spr252), unsigned 32 bits
+	353: spr253 (spr253), unsigned 32 bits
+	354: spr254 (spr254), unsigned 32 bits
+	355: spr255 (spr255), unsigned 32 bits
+	357: spr257 (spr257), unsigned 32 bits
+	358: spr258 (spr258), unsigned 32 bits
+	359: spr259 (spr259), unsigned 32 bits
+	360: spr260 (spr260), unsigned 32 bits
+	361: spr261 (spr261), unsigned 32 bits
+	362: spr262 (spr262), unsigned 32 bits
+	363: spr263 (spr263), unsigned 32 bits
+	364: spr264 (spr264), unsigned 32 bits
+	365: spr265 (spr265), unsigned 32 bits
+	366: spr266 (spr266), unsigned 32 bits
+	367: spr267 (spr267), unsigned 32 bits
+	368: spr268 (spr268), unsigned 32 bits
+	369: spr269 (spr269), unsigned 32 bits
+	370: spr270 (spr270), unsigned 32 bits
+	371: spr271 (spr271), unsigned 32 bits
+	372: spr272 (spr272), unsigned 32 bits
+	373: spr273 (spr273), unsigned 32 bits
+	374: spr274 (spr274), unsigned 32 bits
+	375: spr275 (spr275), unsigned 32 bits
+	376: spr276 (spr276), unsigned 32 bits
+	377: spr277 (spr277), unsigned 32 bits
+	378: spr278 (spr278), unsigned 32 bits
+	379: spr279 (spr279), unsigned 32 bits
+	380: spr280 (spr280), unsigned 32 bits
+	381: spr281 (spr281), unsigned 32 bits
+	382: spr282 (spr282), unsigned 32 bits
+	383: spr283 (spr283), unsigned 32 bits
+	384: spr284 (spr284), unsigned 32 bits
+	385: spr285 (spr285), unsigned 32 bits
+	386: spr286 (spr286), unsigned 32 bits
+	387: spr287 (spr287), unsigned 32 bits
+	388: spr288 (spr288), unsigned 32 bits
+	389: spr289 (spr289), unsigned 32 bits
+	390: spr290 (spr290), unsigned 32 bits
+	391: spr291 (spr291), unsigned 32 bits
+	392: spr292 (spr292), unsigned 32 bits
+	393: spr293 (spr293), unsigned 32 bits
+	394: spr294 (spr294), unsigned 32 bits
+	395: spr295 (spr295), unsigned 32 bits
+	396: spr296 (spr296), unsigned 32 bits
+	397: spr297 (spr297), unsigned 32 bits
+	398: spr298 (spr298), unsigned 32 bits
+	399: spr299 (spr299), unsigned 32 bits
+	400: spr300 (spr300), unsigned 32 bits
+	401: spr301 (spr301), unsigned 32 bits
+	402: spr302 (spr302), unsigned 32 bits
+	403: spr303 (spr303), unsigned 32 bits
+	404: spr304 (spr304), unsigned 32 bits
+	405: spr305 (spr305), unsigned 32 bits
+	406: spr306 (spr306), unsigned 32 bits
+	407: spr307 (spr307), unsigned 32 bits
+	408: spr308 (spr308), unsigned 32 bits
+	409: spr309 (spr309), unsigned 32 bits
+	410: spr310 (spr310), unsigned 32 bits
+	411: spr311 (spr311), unsigned 32 bits
+	412: spr312 (spr312), unsigned 32 bits
+	413: spr313 (spr313), unsigned 32 bits
+	414: spr314 (spr314), unsigned 32 bits
+	415: spr315 (spr315), unsigned 32 bits
+	416: spr316 (spr316), unsigned 32 bits
+	417: spr317 (spr317), unsigned 32 bits
+	418: spr318 (spr318), unsigned 32 bits
+	419: spr319 (spr319), unsigned 32 bits
+	420: spr320 (spr320), unsigned 32 bits
+	421: spr321 (spr321), unsigned 32 bits
+	422: spr322 (spr322), unsigned 32 bits
+	423: spr323 (spr323), unsigned 32 bits
+	424: spr324 (spr324), unsigned 32 bits
+	425: spr325 (spr325), unsigned 32 bits
+	426: spr326 (spr326), unsigned 32 bits
+	427: spr327 (spr327), unsigned 32 bits
+	428: spr328 (spr328), unsigned 32 bits
+	429: spr329 (spr329), unsigned 32 bits
+	430: spr330 (spr330), unsigned 32 bits
+	431: spr331 (spr331), unsigned 32 bits
+	432: spr332 (spr332), unsigned 32 bits
+	433: spr333 (spr333), unsigned 32 bits
+	434: spr334 (spr334), unsigned 32 bits
+	435: spr335 (spr335), unsigned 32 bits
+	436: spr336 (spr336), unsigned 32 bits
+	437: spr337 (spr337), unsigned 32 bits
+	438: spr338 (spr338), unsigned 32 bits
+	439: spr339 (spr339), unsigned 32 bits
+	440: spr340 (spr340), unsigned 32 bits
+	441: spr341 (spr341), unsigned 32 bits
+	442: spr342 (spr342), unsigned 32 bits
+	443: spr343 (spr343), unsigned 32 bits
+	444: spr344 (spr344), unsigned 32 bits
+	445: spr345 (spr345), unsigned 32 bits
+	446: spr346 (spr346), unsigned 32 bits
+	447: spr347 (spr347), unsigned 32 bits
+	448: spr348 (spr348), unsigned 32 bits
+	449: spr349 (spr349), unsigned 32 bits
+	450: spr350 (spr350), unsigned 32 bits
+	451: spr351 (spr351), unsigned 32 bits
+	452: spr352 (spr352), unsigned 32 bits
+	453: spr353 (spr353), unsigned 32 bits
+	454: spr354 (spr354), unsigned 32 bits
+	455: spr355 (spr355), unsigned 32 bits
+	456: spr356 (spr356), unsigned 32 bits
+	457: spr357 (spr357), unsigned 32 bits
+	458: spr358 (spr358), unsigned 32 bits
+	459: spr359 (spr359), unsigned 32 bits
+	460: spr360 (spr360), unsigned 32 bits
+	461: spr361 (spr361), unsigned 32 bits
+	462: spr362 (spr362), unsigned 32 bits
+	463: spr363 (spr363), unsigned 32 bits
+	464: spr364 (spr364), unsigned 32 bits
+	465: spr365 (spr365), unsigned 32 bits
+	466: spr366 (spr366), unsigned 32 bits
+	467: spr367 (spr367), unsigned 32 bits
+	468: spr368 (spr368), unsigned 32 bits
+	469: spr369 (spr369), unsigned 32 bits
+	470: spr370 (spr370), unsigned 32 bits
+	471: spr371 (spr371), unsigned 32 bits
+	472: spr372 (spr372), unsigned 32 bits
+	473: spr373 (spr373), unsigned 32 bits
+	474: spr374 (spr374), unsigned 32 bits
+	475: spr375 (spr375), unsigned 32 bits
+	476: spr376 (spr376), unsigned 32 bits
+	477: spr377 (spr377), unsigned 32 bits
+	478: spr378 (spr378), unsigned 32 bits
+	479: spr379 (spr379), unsigned 32 bits
+	480: spr380 (spr380), unsigned 32 bits
+	481: spr381 (spr381), unsigned 32 bits
+	482: spr382 (spr382), unsigned 32 bits
+	483: spr383 (spr383), unsigned 32 bits
+	484: spr384 (spr384), unsigned 32 bits
+	485: spr385 (spr385), unsigned 32 bits
+	486: spr386 (spr386), unsigned 32 bits
+	487: spr387 (spr387), unsigned 32 bits
+	488: spr388 (spr388), unsigned 32 bits
+	489: spr389 (spr389), unsigned 32 bits
+	490: spr390 (spr390), unsigned 32 bits
+	491: spr391 (spr391), unsigned 32 bits
+	492: spr392 (spr392), unsigned 32 bits
+	493: spr393 (spr393), unsigned 32 bits
+	494: spr394 (spr394), unsigned 32 bits
+	495: spr395 (spr395), unsigned 32 bits
+	496: spr396 (spr396), unsigned 32 bits
+	497: spr397 (spr397), unsigned 32 bits
+	498: spr398 (spr398), unsigned 32 bits
+	499: spr399 (spr399), unsigned 32 bits
+	500: spr400 (spr400), unsigned 32 bits
+	501: spr401 (spr401), unsigned 32 bits
+	502: spr402 (spr402), unsigned 32 bits
+	503: spr403 (spr403), unsigned 32 bits
+	504: spr404 (spr404), unsigned 32 bits
+	505: spr405 (spr405), unsigned 32 bits
+	506: spr406 (spr406), unsigned 32 bits
+	507: spr407 (spr407), unsigned 32 bits
+	508: spr408 (spr408), unsigned 32 bits
+	509: spr409 (spr409), unsigned 32 bits
+	510: spr410 (spr410), unsigned 32 bits
+	511: spr411 (spr411), unsigned 32 bits
+	512: spr412 (spr412), unsigned 32 bits
+	513: spr413 (spr413), unsigned 32 bits
+	514: spr414 (spr414), unsigned 32 bits
+	515: spr415 (spr415), unsigned 32 bits
+	516: spr416 (spr416), unsigned 32 bits
+	517: spr417 (spr417), unsigned 32 bits
+	518: spr418 (spr418), unsigned 32 bits
+	519: spr419 (spr419), unsigned 32 bits
+	520: spr420 (spr420), unsigned 32 bits
+	521: spr421 (spr421), unsigned 32 bits
+	522: spr422 (spr422), unsigned 32 bits
+	523: spr423 (spr423), unsigned 32 bits
+	524: spr424 (spr424), unsigned 32 bits
+	525: spr425 (spr425), unsigned 32 bits
+	526: spr426 (spr426), unsigned 32 bits
+	527: spr427 (spr427), unsigned 32 bits
+	528: spr428 (spr428), unsigned 32 bits
+	529: spr429 (spr429), unsigned 32 bits
+	530: spr430 (spr430), unsigned 32 bits
+	531: spr431 (spr431), unsigned 32 bits
+	532: spr432 (spr432), unsigned 32 bits
+	533: spr433 (spr433), unsigned 32 bits
+	534: spr434 (spr434), unsigned 32 bits
+	535: spr435 (spr435), unsigned 32 bits
+	536: spr436 (spr436), unsigned 32 bits
+	537: spr437 (spr437), unsigned 32 bits
+	538: spr438 (spr438), unsigned 32 bits
+	539: spr439 (spr439), unsigned 32 bits
+	540: spr440 (spr440), unsigned 32 bits
+	541: spr441 (spr441), unsigned 32 bits
+	542: spr442 (spr442), unsigned 32 bits
+	543: spr443 (spr443), unsigned 32 bits
+	544: spr444 (spr444), unsigned 32 bits
+	545: spr445 (spr445), unsigned 32 bits
+	546: spr446 (spr446), unsigned 32 bits
+	547: spr447 (spr447), unsigned 32 bits
+	548: spr448 (spr448), unsigned 32 bits
+	549: spr449 (spr449), unsigned 32 bits
+	550: spr450 (spr450), unsigned 32 bits
+	551: spr451 (spr451), unsigned 32 bits
+	552: spr452 (spr452), unsigned 32 bits
+	553: spr453 (spr453), unsigned 32 bits
+	554: spr454 (spr454), unsigned 32 bits
+	555: spr455 (spr455), unsigned 32 bits
+	556: spr456 (spr456), unsigned 32 bits
+	557: spr457 (spr457), unsigned 32 bits
+	558: spr458 (spr458), unsigned 32 bits
+	559: spr459 (spr459), unsigned 32 bits
+	560: spr460 (spr460), unsigned 32 bits
+	561: spr461 (spr461), unsigned 32 bits
+	562: spr462 (spr462), unsigned 32 bits
+	563: spr463 (spr463), unsigned 32 bits
+	564: spr464 (spr464), unsigned 32 bits
+	565: spr465 (spr465), unsigned 32 bits
+	566: spr466 (spr466), unsigned 32 bits
+	567: spr467 (spr467), unsigned 32 bits
+	568: spr468 (spr468), unsigned 32 bits
+	569: spr469 (spr469), unsigned 32 bits
+	570: spr470 (spr470), unsigned 32 bits
+	571: spr471 (spr471), unsigned 32 bits
+	572: spr472 (spr472), unsigned 32 bits
+	573: spr473 (spr473), unsigned 32 bits
+	574: spr474 (spr474), unsigned 32 bits
+	575: spr475 (spr475), unsigned 32 bits
+	576: spr476 (spr476), unsigned 32 bits
+	577: spr477 (spr477), unsigned 32 bits
+	578: spr478 (spr478), unsigned 32 bits
+	579: spr479 (spr479), unsigned 32 bits
+	580: spr480 (spr480), unsigned 32 bits
+	581: spr481 (spr481), unsigned 32 bits
+	582: spr482 (spr482), unsigned 32 bits
+	583: spr483 (spr483), unsigned 32 bits
+	584: spr484 (spr484), unsigned 32 bits
+	585: spr485 (spr485), unsigned 32 bits
+	586: spr486 (spr486), unsigned 32 bits
+	587: spr487 (spr487), unsigned 32 bits
+	588: spr488 (spr488), unsigned 32 bits
+	589: spr489 (spr489), unsigned 32 bits
+	590: spr490 (spr490), unsigned 32 bits
+	591: spr491 (spr491), unsigned 32 bits
+	592: spr492 (spr492), unsigned 32 bits
+	593: spr493 (spr493), unsigned 32 bits
+	594: spr494 (spr494), unsigned 32 bits
+	595: spr495 (spr495), unsigned 32 bits
+	596: spr496 (spr496), unsigned 32 bits
+	597: spr497 (spr497), unsigned 32 bits
+	598: spr498 (spr498), unsigned 32 bits
+	599: spr499 (spr499), unsigned 32 bits
+	600: spr500 (spr500), unsigned 32 bits
+	601: spr501 (spr501), unsigned 32 bits
+	602: spr502 (spr502), unsigned 32 bits
+	603: spr503 (spr503), unsigned 32 bits
+	604: spr504 (spr504), unsigned 32 bits
+	605: spr505 (spr505), unsigned 32 bits
+	606: spr506 (spr506), unsigned 32 bits
+	607: spr507 (spr507), unsigned 32 bits
+	608: spr508 (spr508), unsigned 32 bits
+	609: spr509 (spr509), unsigned 32 bits
+	610: spr510 (spr510), unsigned 32 bits
+	611: spr511 (spr511), unsigned 32 bits
+	613: spr513 (spr513), unsigned 32 bits
+	614: spr514 (spr514), unsigned 32 bits
+	615: spr515 (spr515), unsigned 32 bits
+	616: spr516 (spr516), unsigned 32 bits
+	617: spr517 (spr517), unsigned 32 bits
+	618: spr518 (spr518), unsigned 32 bits
+	619: spr519 (spr519), unsigned 32 bits
+	620: spr520 (spr520), unsigned 32 bits
+	621: spr521 (spr521), unsigned 32 bits
+	622: spr522 (spr522), unsigned 32 bits
+	623: spr523 (spr523), unsigned 32 bits
+	624: spr524 (spr524), unsigned 32 bits
+	625: spr525 (spr525), unsigned 32 bits
+	626: spr526 (spr526), unsigned 32 bits
+	627: spr527 (spr527), unsigned 32 bits
+	628: spr528 (spr528), unsigned 32 bits
+	629: spr529 (spr529), unsigned 32 bits
+	630: spr530 (spr530), unsigned 32 bits
+	631: spr531 (spr531), unsigned 32 bits
+	632: spr532 (spr532), unsigned 32 bits
+	633: spr533 (spr533), unsigned 32 bits
+	634: spr534 (spr534), unsigned 32 bits
+	635: spr535 (spr535), unsigned 32 bits
+	636: spr536 (spr536), unsigned 32 bits
+	637: spr537 (spr537), unsigned 32 bits
+	638: spr538 (spr538), unsigned 32 bits
+	639: spr539 (spr539), unsigned 32 bits
+	640: spr540 (spr540), unsigned 32 bits
+	641: spr541 (spr541), unsigned 32 bits
+	642: spr542 (spr542), unsigned 32 bits
+	643: spr543 (spr543), unsigned 32 bits
+	644: spr544 (spr544), unsigned 32 bits
+	645: spr545 (spr545), unsigned 32 bits
+	646: spr546 (spr546), unsigned 32 bits
+	647: spr547 (spr547), unsigned 32 bits
+	648: spr548 (spr548), unsigned 32 bits
+	649: spr549 (spr549), unsigned 32 bits
+	650: spr550 (spr550), unsigned 32 bits
+	651: spr551 (spr551), unsigned 32 bits
+	652: spr552 (spr552), unsigned 32 bits
+	653: spr553 (spr553), unsigned 32 bits
+	654: spr554 (spr554), unsigned 32 bits
+	655: spr555 (spr555), unsigned 32 bits
+	656: spr556 (spr556), unsigned 32 bits
+	657: spr557 (spr557), unsigned 32 bits
+	658: spr558 (spr558), unsigned 32 bits
+	659: spr559 (spr559), unsigned 32 bits
+	660: spr560 (spr560), unsigned 32 bits
+	661: spr561 (spr561), unsigned 32 bits
+	662: spr562 (spr562), unsigned 32 bits
+	663: spr563 (spr563), unsigned 32 bits
+	664: spr564 (spr564), unsigned 32 bits
+	665: spr565 (spr565), unsigned 32 bits
+	666: spr566 (spr566), unsigned 32 bits
+	667: spr567 (spr567), unsigned 32 bits
+	668: spr568 (spr568), unsigned 32 bits
+	669: spr569 (spr569), unsigned 32 bits
+	670: spr570 (spr570), unsigned 32 bits
+	671: spr571 (spr571), unsigned 32 bits
+	672: spr572 (spr572), unsigned 32 bits
+	673: spr573 (spr573), unsigned 32 bits
+	674: spr574 (spr574), unsigned 32 bits
+	675: spr575 (spr575), unsigned 32 bits
+	676: spr576 (spr576), unsigned 32 bits
+	677: spr577 (spr577), unsigned 32 bits
+	678: spr578 (spr578), unsigned 32 bits
+	679: spr579 (spr579), unsigned 32 bits
+	680: spr580 (spr580), unsigned 32 bits
+	681: spr581 (spr581), unsigned 32 bits
+	682: spr582 (spr582), unsigned 32 bits
+	683: spr583 (spr583), unsigned 32 bits
+	684: spr584 (spr584), unsigned 32 bits
+	685: spr585 (spr585), unsigned 32 bits
+	686: spr586 (spr586), unsigned 32 bits
+	687: spr587 (spr587), unsigned 32 bits
+	688: spr588 (spr588), unsigned 32 bits
+	689: spr589 (spr589), unsigned 32 bits
+	690: spr590 (spr590), unsigned 32 bits
+	691: spr591 (spr591), unsigned 32 bits
+	692: spr592 (spr592), unsigned 32 bits
+	693: spr593 (spr593), unsigned 32 bits
+	694: spr594 (spr594), unsigned 32 bits
+	695: spr595 (spr595), unsigned 32 bits
+	696: spr596 (spr596), unsigned 32 bits
+	697: spr597 (spr597), unsigned 32 bits
+	698: spr598 (spr598), unsigned 32 bits
+	699: spr599 (spr599), unsigned 32 bits
+	700: spr600 (spr600), unsigned 32 bits
+	701: spr601 (spr601), unsigned 32 bits
+	702: spr602 (spr602), unsigned 32 bits
+	703: spr603 (spr603), unsigned 32 bits
+	704: spr604 (spr604), unsigned 32 bits
+	705: spr605 (spr605), unsigned 32 bits
+	706: spr606 (spr606), unsigned 32 bits
+	707: spr607 (spr607), unsigned 32 bits
+	708: spr608 (spr608), unsigned 32 bits
+	709: spr609 (spr609), unsigned 32 bits
+	710: spr610 (spr610), unsigned 32 bits
+	711: spr611 (spr611), unsigned 32 bits
+	712: spr612 (spr612), unsigned 32 bits
+	713: spr613 (spr613), unsigned 32 bits
+	714: spr614 (spr614), unsigned 32 bits
+	715: spr615 (spr615), unsigned 32 bits
+	716: spr616 (spr616), unsigned 32 bits
+	717: spr617 (spr617), unsigned 32 bits
+	718: spr618 (spr618), unsigned 32 bits
+	719: spr619 (spr619), unsigned 32 bits
+	720: spr620 (spr620), unsigned 32 bits
+	721: spr621 (spr621), unsigned 32 bits
+	722: spr622 (spr622), unsigned 32 bits
+	723: spr623 (spr623), unsigned 32 bits
+	724: spr624 (spr624), unsigned 32 bits
+	725: spr625 (spr625), unsigned 32 bits
+	726: spr626 (spr626), unsigned 32 bits
+	727: spr627 (spr627), unsigned 32 bits
+	728: spr628 (spr628), unsigned 32 bits
+	729: spr629 (spr629), unsigned 32 bits
+	730: spr630 (spr630), unsigned 32 bits
+	731: spr631 (spr631), unsigned 32 bits
+	732: spr632 (spr632), unsigned 32 bits
+	733: spr633 (spr633), unsigned 32 bits
+	734: spr634 (spr634), unsigned 32 bits
+	735: spr635 (spr635), unsigned 32 bits
+	736: spr636 (spr636), unsigned 32 bits
+	737: spr637 (spr637), unsigned 32 bits
+	738: spr638 (spr638), unsigned 32 bits
+	739: spr639 (spr639), unsigned 32 bits
+	740: spr640 (spr640), unsigned 32 bits
+	741: spr641 (spr641), unsigned 32 bits
+	742: spr642 (spr642), unsigned 32 bits
+	743: spr643 (spr643), unsigned 32 bits
+	744: spr644 (spr644), unsigned 32 bits
+	745: spr645 (spr645), unsigned 32 bits
+	746: spr646 (spr646), unsigned 32 bits
+	747: spr647 (spr647), unsigned 32 bits
+	748: spr648 (spr648), unsigned 32 bits
+	749: spr649 (spr649), unsigned 32 bits
+	750: spr650 (spr650), unsigned 32 bits
+	751: spr651 (spr651), unsigned 32 bits
+	752: spr652 (spr652), unsigned 32 bits
+	753: spr653 (spr653), unsigned 32 bits
+	754: spr654 (spr654), unsigned 32 bits
+	755: spr655 (spr655), unsigned 32 bits
+	756: spr656 (spr656), unsigned 32 bits
+	757: spr657 (spr657), unsigned 32 bits
+	758: spr658 (spr658), unsigned 32 bits
+	759: spr659 (spr659), unsigned 32 bits
+	760: spr660 (spr660), unsigned 32 bits
+	761: spr661 (spr661), unsigned 32 bits
+	762: spr662 (spr662), unsigned 32 bits
+	763: spr663 (spr663), unsigned 32 bits
+	764: spr664 (spr664), unsigned 32 bits
+	765: spr665 (spr665), unsigned 32 bits
+	766: spr666 (spr666), unsigned 32 bits
+	767: spr667 (spr667), unsigned 32 bits
+	768: spr668 (spr668), unsigned 32 bits
+	769: spr669 (spr669), unsigned 32 bits
+	770: spr670 (spr670), unsigned 32 bits
+	771: spr671 (spr671), unsigned 32 bits
+	772: spr672 (spr672), unsigned 32 bits
+	773: spr673 (spr673), unsigned 32 bits
+	774: spr674 (spr674), unsigned 32 bits
+	775: spr675 (spr675), unsigned 32 bits
+	776: spr676 (spr676), unsigned 32 bits
+	777: spr677 (spr677), unsigned 32 bits
+	778: spr678 (spr678), unsigned 32 bits
+	779: spr679 (spr679), unsigned 32 bits
+	780: spr680 (spr680), unsigned 32 bits
+	781: spr681 (spr681), unsigned 32 bits
+	782: spr682 (spr682), unsigned 32 bits
+	783: spr683 (spr683), unsigned 32 bits
+	784: spr684 (spr684), unsigned 32 bits
+	785: spr685 (spr685), unsigned 32 bits
+	786: spr686 (spr686), unsigned 32 bits
+	787: spr687 (spr687), unsigned 32 bits
+	788: spr688 (spr688), unsigned 32 bits
+	789: spr689 (spr689), unsigned 32 bits
+	790: spr690 (spr690), unsigned 32 bits
+	791: spr691 (spr691), unsigned 32 bits
+	792: spr692 (spr692), unsigned 32 bits
+	793: spr693 (spr693), unsigned 32 bits
+	794: spr694 (spr694), unsigned 32 bits
+	795: spr695 (spr695), unsigned 32 bits
+	796: spr696 (spr696), unsigned 32 bits
+	797: spr697 (spr697), unsigned 32 bits
+	798: spr698 (spr698), unsigned 32 bits
+	799: spr699 (spr699), unsigned 32 bits
+	800: spr700 (spr700), unsigned 32 bits
+	801: spr701 (spr701), unsigned 32 bits
+	802: spr702 (spr702), unsigned 32 bits
+	803: spr703 (spr703), unsigned 32 bits
+	804: spr704 (spr704), unsigned 32 bits
+	805: spr705 (spr705), unsigned 32 bits
+	806: spr706 (spr706), unsigned 32 bits
+	807: spr707 (spr707), unsigned 32 bits
+	808: spr708 (spr708), unsigned 32 bits
+	809: spr709 (spr709), unsigned 32 bits
+	810: spr710 (spr710), unsigned 32 bits
+	811: spr711 (spr711), unsigned 32 bits
+	812: spr712 (spr712), unsigned 32 bits
+	813: spr713 (spr713), unsigned 32 bits
+	814: spr714 (spr714), unsigned 32 bits
+	815: spr715 (spr715), unsigned 32 bits
+	816: spr716 (spr716), unsigned 32 bits
+	817: spr717 (spr717), unsigned 32 bits
+	818: spr718 (spr718), unsigned 32 bits
+	819: spr719 (spr719), unsigned 32 bits
+	820: spr720 (spr720), unsigned 32 bits
+	821: spr721 (spr721), unsigned 32 bits
+	822: spr722 (spr722), unsigned 32 bits
+	823: spr723 (spr723), unsigned 32 bits
+	824: spr724 (spr724), unsigned 32 bits
+	825: spr725 (spr725), unsigned 32 bits
+	826: spr726 (spr726), unsigned 32 bits
+	827: spr727 (spr727), unsigned 32 bits
+	828: spr728 (spr728), unsigned 32 bits
+	829: spr729 (spr729), unsigned 32 bits
+	830: spr730 (spr730), unsigned 32 bits
+	831: spr731 (spr731), unsigned 32 bits
+	832: spr732 (spr732), unsigned 32 bits
+	833: spr733 (spr733), unsigned 32 bits
+	834: spr734 (spr734), unsigned 32 bits
+	835: spr735 (spr735), unsigned 32 bits
+	836: spr736 (spr736), unsigned 32 bits
+	837: spr737 (spr737), unsigned 32 bits
+	838: spr738 (spr738), unsigned 32 bits
+	839: spr739 (spr739), unsigned 32 bits
+	840: spr740 (spr740), unsigned 32 bits
+	841: spr741 (spr741), unsigned 32 bits
+	842: spr742 (spr742), unsigned 32 bits
+	843: spr743 (spr743), unsigned 32 bits
+	844: spr744 (spr744), unsigned 32 bits
+	845: spr745 (spr745), unsigned 32 bits
+	846: spr746 (spr746), unsigned 32 bits
+	847: spr747 (spr747), unsigned 32 bits
+	848: spr748 (spr748), unsigned 32 bits
+	849: spr749 (spr749), unsigned 32 bits
+	850: spr750 (spr750), unsigned 32 bits
+	851: spr751 (spr751), unsigned 32 bits
+	852: spr752 (spr752), unsigned 32 bits
+	853: spr753 (spr753), unsigned 32 bits
+	854: spr754 (spr754), unsigned 32 bits
+	855: spr755 (spr755), unsigned 32 bits
+	856: spr756 (spr756), unsigned 32 bits
+	857: spr757 (spr757), unsigned 32 bits
+	858: spr758 (spr758), unsigned 32 bits
+	859: spr759 (spr759), unsigned 32 bits
+	860: spr760 (spr760), unsigned 32 bits
+	861: spr761 (spr761), unsigned 32 bits
+	862: spr762 (spr762), unsigned 32 bits
+	863: spr763 (spr763), unsigned 32 bits
+	864: spr764 (spr764), unsigned 32 bits
+	865: spr765 (spr765), unsigned 32 bits
+	866: spr766 (spr766), unsigned 32 bits
+	867: spr767 (spr767), unsigned 32 bits
+	868: spr768 (spr768), unsigned 32 bits
+	869: spr769 (spr769), unsigned 32 bits
+	870: spr770 (spr770), unsigned 32 bits
+	871: spr771 (spr771), unsigned 32 bits
+	872: spr772 (spr772), unsigned 32 bits
+	873: spr773 (spr773), unsigned 32 bits
+	874: spr774 (spr774), unsigned 32 bits
+	875: spr775 (spr775), unsigned 32 bits
+	876: spr776 (spr776), unsigned 32 bits
+	877: spr777 (spr777), unsigned 32 bits
+	878: spr778 (spr778), unsigned 32 bits
+	879: spr779 (spr779), unsigned 32 bits
+	880: spr780 (spr780), unsigned 32 bits
+	881: spr781 (spr781), unsigned 32 bits
+	882: spr782 (spr782), unsigned 32 bits
+	883: spr783 (spr783), unsigned 32 bits
+	884: spr784 (spr784), unsigned 32 bits
+	885: spr785 (spr785), unsigned 32 bits
+	886: spr786 (spr786), unsigned 32 bits
+	887: spr787 (spr787), unsigned 32 bits
+	888: spr788 (spr788), unsigned 32 bits
+	889: spr789 (spr789), unsigned 32 bits
+	890: spr790 (spr790), unsigned 32 bits
+	891: spr791 (spr791), unsigned 32 bits
+	892: spr792 (spr792), unsigned 32 bits
+	893: spr793 (spr793), unsigned 32 bits
+	894: spr794 (spr794), unsigned 32 bits
+	895: spr795 (spr795), unsigned 32 bits
+	896: spr796 (spr796), unsigned 32 bits
+	897: spr797 (spr797), unsigned 32 bits
+	898: spr798 (spr798), unsigned 32 bits
+	899: spr799 (spr799), unsigned 32 bits
+	900: spr800 (spr800), unsigned 32 bits
+	901: spr801 (spr801), unsigned 32 bits
+	902: spr802 (spr802), unsigned 32 bits
+	903: spr803 (spr803), unsigned 32 bits
+	904: spr804 (spr804), unsigned 32 bits
+	905: spr805 (spr805), unsigned 32 bits
+	906: spr806 (spr806), unsigned 32 bits
+	907: spr807 (spr807), unsigned 32 bits
+	908: spr808 (spr808), unsigned 32 bits
+	909: spr809 (spr809), unsigned 32 bits
+	910: spr810 (spr810), unsigned 32 bits
+	911: spr811 (spr811), unsigned 32 bits
+	912: spr812 (spr812), unsigned 32 bits
+	913: spr813 (spr813), unsigned 32 bits
+	914: spr814 (spr814), unsigned 32 bits
+	915: spr815 (spr815), unsigned 32 bits
+	916: spr816 (spr816), unsigned 32 bits
+	917: spr817 (spr817), unsigned 32 bits
+	918: spr818 (spr818), unsigned 32 bits
+	919: spr819 (spr819), unsigned 32 bits
+	920: spr820 (spr820), unsigned 32 bits
+	921: spr821 (spr821), unsigned 32 bits
+	922: spr822 (spr822), unsigned 32 bits
+	923: spr823 (spr823), unsigned 32 bits
+	924: spr824 (spr824), unsigned 32 bits
+	925: spr825 (spr825), unsigned 32 bits
+	926: spr826 (spr826), unsigned 32 bits
+	927: spr827 (spr827), unsigned 32 bits
+	928: spr828 (spr828), unsigned 32 bits
+	929: spr829 (spr829), unsigned 32 bits
+	930: spr830 (spr830), unsigned 32 bits
+	931: spr831 (spr831), unsigned 32 bits
+	932: spr832 (spr832), unsigned 32 bits
+	933: spr833 (spr833), unsigned 32 bits
+	934: spr834 (spr834), unsigned 32 bits
+	935: spr835 (spr835), unsigned 32 bits
+	936: spr836 (spr836), unsigned 32 bits
+	937: spr837 (spr837), unsigned 32 bits
+	938: spr838 (spr838), unsigned 32 bits
+	939: spr839 (spr839), unsigned 32 bits
+	940: spr840 (spr840), unsigned 32 bits
+	941: spr841 (spr841), unsigned 32 bits
+	942: spr842 (spr842), unsigned 32 bits
+	943: spr843 (spr843), unsigned 32 bits
+	944: spr844 (spr844), unsigned 32 bits
+	945: spr845 (spr845), unsigned 32 bits
+	946: spr846 (spr846), unsigned 32 bits
+	947: spr847 (spr847), unsigned 32 bits
+	948: spr848 (spr848), unsigned 32 bits
+	949: spr849 (spr849), unsigned 32 bits
+	950: spr850 (spr850), unsigned 32 bits
+	951: spr851 (spr851), unsigned 32 bits
+	952: spr852 (spr852), unsigned 32 bits
+	953: spr853 (spr853), unsigned 32 bits
+	954: spr854 (spr854), unsigned 32 bits
+	955: spr855 (spr855), unsigned 32 bits
+	956: spr856 (spr856), unsigned 32 bits
+	957: spr857 (spr857), unsigned 32 bits
+	958: spr858 (spr858), unsigned 32 bits
+	959: spr859 (spr859), unsigned 32 bits
+	960: spr860 (spr860), unsigned 32 bits
+	961: spr861 (spr861), unsigned 32 bits
+	962: spr862 (spr862), unsigned 32 bits
+	963: spr863 (spr863), unsigned 32 bits
+	964: spr864 (spr864), unsigned 32 bits
+	965: spr865 (spr865), unsigned 32 bits
+	966: spr866 (spr866), unsigned 32 bits
+	967: spr867 (spr867), unsigned 32 bits
+	968: spr868 (spr868), unsigned 32 bits
+	969: spr869 (spr869), unsigned 32 bits
+	970: spr870 (spr870), unsigned 32 bits
+	971: spr871 (spr871), unsigned 32 bits
+	972: spr872 (spr872), unsigned 32 bits
+	973: spr873 (spr873), unsigned 32 bits
+	974: spr874 (spr874), unsigned 32 bits
+	975: spr875 (spr875), unsigned 32 bits
+	976: spr876 (spr876), unsigned 32 bits
+	977: spr877 (spr877), unsigned 32 bits
+	978: spr878 (spr878), unsigned 32 bits
+	979: spr879 (spr879), unsigned 32 bits
+	980: spr880 (spr880), unsigned 32 bits
+	981: spr881 (spr881), unsigned 32 bits
+	982: spr882 (spr882), unsigned 32 bits
+	983: spr883 (spr883), unsigned 32 bits
+	984: spr884 (spr884), unsigned 32 bits
+	985: spr885 (spr885), unsigned 32 bits
+	986: spr886 (spr886), unsigned 32 bits
+	987: spr887 (spr887), unsigned 32 bits
+	988: spr888 (spr888), unsigned 32 bits
+	989: spr889 (spr889), unsigned 32 bits
+	990: spr890 (spr890), unsigned 32 bits
+	991: spr891 (spr891), unsigned 32 bits
+	992: spr892 (spr892), unsigned 32 bits
+	993: spr893 (spr893), unsigned 32 bits
+	994: spr894 (spr894), unsigned 32 bits
+	995: spr895 (spr895), unsigned 32 bits
+	996: spr896 (spr896), unsigned 32 bits
+	997: spr897 (spr897), unsigned 32 bits
+	998: spr898 (spr898), unsigned 32 bits
+	999: spr899 (spr899), unsigned 32 bits
+vector registers:
+	 67: vscr (vscr), unsigned 32 bits
+	356: vrsave (vrsave), unsigned 32 bits
+	612: spefscr (spefscr), unsigned 32 bits
+	1124: vr0 (vr0), unsigned 128 bits
+	1125: vr1 (vr1), unsigned 128 bits
+	1126: vr2 (vr2), unsigned 128 bits
+	1127: vr3 (vr3), unsigned 128 bits
+	1128: vr4 (vr4), unsigned 128 bits
+	1129: vr5 (vr5), unsigned 128 bits
+	1130: vr6 (vr6), unsigned 128 bits
+	1131: vr7 (vr7), unsigned 128 bits
+	1132: vr8 (vr8), unsigned 128 bits
+	1133: vr9 (vr9), unsigned 128 bits
+	1134: vr10 (vr10), unsigned 128 bits
+	1135: vr11 (vr11), unsigned 128 bits
+	1136: vr12 (vr12), unsigned 128 bits
+	1137: vr13 (vr13), unsigned 128 bits
+	1138: vr14 (vr14), unsigned 128 bits
+	1139: vr15 (vr15), unsigned 128 bits
+	1140: vr16 (vr16), unsigned 128 bits
+	1141: vr17 (vr17), unsigned 128 bits
+	1142: vr18 (vr18), unsigned 128 bits
+	1143: vr19 (vr19), unsigned 128 bits
+	1144: vr20 (vr20), unsigned 128 bits
+	1145: vr21 (vr21), unsigned 128 bits
+	1146: vr22 (vr22), unsigned 128 bits
+	1147: vr23 (vr23), unsigned 128 bits
+	1148: vr24 (vr24), unsigned 128 bits
+	1149: vr25 (vr25), unsigned 128 bits
+	1150: vr26 (vr26), unsigned 128 bits
+	1151: vr27 (vr27), unsigned 128 bits
+	1152: vr28 (vr28), unsigned 128 bits
+	1153: vr29 (vr29), unsigned 128 bits
+	1154: vr30 (vr30), unsigned 128 bits
+	1155: vr31 (vr31), unsigned 128 bits
+EOF
+
+regs_test testfile23 <<\EOF
+integer registers:
+	  0: r0 (r0), signed 64 bits
+	  1: r1 (r1), signed 64 bits
+	  2: r2 (r2), signed 64 bits
+	  3: r3 (r3), signed 64 bits
+	  4: r4 (r4), signed 64 bits
+	  5: r5 (r5), signed 64 bits
+	  6: r6 (r6), signed 64 bits
+	  7: r7 (r7), signed 64 bits
+	  8: r8 (r8), signed 64 bits
+	  9: r9 (r9), signed 64 bits
+	 10: r10 (r10), signed 64 bits
+	 11: r11 (r11), signed 64 bits
+	 12: r12 (r12), signed 64 bits
+	 13: r13 (r13), signed 64 bits
+	 14: r14 (r14), signed 64 bits
+	 15: r15 (r15), signed 64 bits
+	 16: r16 (r16), signed 64 bits
+	 17: r17 (r17), signed 64 bits
+	 18: r18 (r18), signed 64 bits
+	 19: r19 (r19), signed 64 bits
+	 20: r20 (r20), signed 64 bits
+	 21: r21 (r21), signed 64 bits
+	 22: r22 (r22), signed 64 bits
+	 23: r23 (r23), signed 64 bits
+	 24: r24 (r24), signed 64 bits
+	 25: r25 (r25), signed 64 bits
+	 26: r26 (r26), signed 64 bits
+	 27: r27 (r27), signed 64 bits
+	 28: r28 (r28), signed 64 bits
+	 29: r29 (r29), signed 64 bits
+	 30: r30 (r30), signed 64 bits
+	 31: r31 (r31), signed 64 bits
+	 64: cr (cr), unsigned 64 bits
+	 66: msr (msr), unsigned 64 bits
+FPU registers:
+	 32: f0 (f0), float 64 bits
+	 33: f1 (f1), float 64 bits
+	 34: f2 (f2), float 64 bits
+	 35: f3 (f3), float 64 bits
+	 36: f4 (f4), float 64 bits
+	 37: f5 (f5), float 64 bits
+	 38: f6 (f6), float 64 bits
+	 39: f7 (f7), float 64 bits
+	 40: f8 (f8), float 64 bits
+	 41: f9 (f9), float 64 bits
+	 42: f10 (f10), float 64 bits
+	 43: f11 (f11), float 64 bits
+	 44: f12 (f12), float 64 bits
+	 45: f13 (f13), float 64 bits
+	 46: f14 (f14), float 64 bits
+	 47: f15 (f15), float 64 bits
+	 48: f16 (f16), float 64 bits
+	 49: f17 (f17), float 64 bits
+	 50: f18 (f18), float 64 bits
+	 51: f19 (f19), float 64 bits
+	 52: f20 (f20), float 64 bits
+	 53: f21 (f21), float 64 bits
+	 54: f22 (f22), float 64 bits
+	 55: f23 (f23), float 64 bits
+	 56: f24 (f24), float 64 bits
+	 57: f25 (f25), float 64 bits
+	 58: f26 (f26), float 64 bits
+	 59: f27 (f27), float 64 bits
+	 60: f28 (f28), float 64 bits
+	 61: f29 (f29), float 64 bits
+	 62: f30 (f30), float 64 bits
+	 63: f31 (f31), float 64 bits
+	 65: fpscr (fpscr), unsigned 64 bits
+privileged registers:
+	 70: sr0 (sr0), unsigned 64 bits
+	 71: sr1 (sr1), unsigned 64 bits
+	 72: sr2 (sr2), unsigned 64 bits
+	 73: sr3 (sr3), unsigned 64 bits
+	 74: sr4 (sr4), unsigned 64 bits
+	 75: sr5 (sr5), unsigned 64 bits
+	 76: sr6 (sr6), unsigned 64 bits
+	 77: sr7 (sr7), unsigned 64 bits
+	 78: sr8 (sr8), unsigned 64 bits
+	 79: sr9 (sr9), unsigned 64 bits
+	 80: sr10 (sr10), unsigned 64 bits
+	 81: sr11 (sr11), unsigned 64 bits
+	 82: sr12 (sr12), unsigned 64 bits
+	 83: sr13 (sr13), unsigned 64 bits
+	 84: sr14 (sr14), unsigned 64 bits
+	 85: sr15 (sr15), unsigned 64 bits
+	100: spr0 (spr0), unsigned 64 bits
+	101: xer (xer), unsigned 64 bits
+	102: spr2 (spr2), unsigned 64 bits
+	103: spr3 (spr3), unsigned 64 bits
+	104: spr4 (spr4), unsigned 64 bits
+	105: spr5 (spr5), unsigned 64 bits
+	106: spr6 (spr6), unsigned 64 bits
+	107: spr7 (spr7), unsigned 64 bits
+	108: lr (lr), unsigned 64 bits
+	109: ctr (ctr), unsigned 64 bits
+	110: spr10 (spr10), unsigned 64 bits
+	111: spr11 (spr11), unsigned 64 bits
+	112: spr12 (spr12), unsigned 64 bits
+	113: spr13 (spr13), unsigned 64 bits
+	114: tfhar (tfhar), unsigned 64 bits
+	115: tfiar (tfiar), unsigned 64 bits
+	116: texasr (texasr), unsigned 64 bits
+	117: spr17 (spr17), unsigned 64 bits
+	118: dsisr (dsisr), unsigned 64 bits
+	119: dar (dar), unsigned 64 bits
+	120: spr20 (spr20), unsigned 64 bits
+	121: spr21 (spr21), unsigned 64 bits
+	122: dec (dec), unsigned 64 bits
+	123: spr23 (spr23), unsigned 64 bits
+	124: spr24 (spr24), unsigned 64 bits
+	125: spr25 (spr25), unsigned 64 bits
+	126: spr26 (spr26), unsigned 64 bits
+	127: spr27 (spr27), unsigned 64 bits
+	128: spr28 (spr28), unsigned 64 bits
+	129: spr29 (spr29), unsigned 64 bits
+	130: spr30 (spr30), unsigned 64 bits
+	131: spr31 (spr31), unsigned 64 bits
+	132: spr32 (spr32), unsigned 64 bits
+	133: spr33 (spr33), unsigned 64 bits
+	134: spr34 (spr34), unsigned 64 bits
+	135: spr35 (spr35), unsigned 64 bits
+	136: spr36 (spr36), unsigned 64 bits
+	137: spr37 (spr37), unsigned 64 bits
+	138: spr38 (spr38), unsigned 64 bits
+	139: spr39 (spr39), unsigned 64 bits
+	140: spr40 (spr40), unsigned 64 bits
+	141: spr41 (spr41), unsigned 64 bits
+	142: spr42 (spr42), unsigned 64 bits
+	143: spr43 (spr43), unsigned 64 bits
+	144: spr44 (spr44), unsigned 64 bits
+	145: spr45 (spr45), unsigned 64 bits
+	146: spr46 (spr46), unsigned 64 bits
+	147: spr47 (spr47), unsigned 64 bits
+	148: spr48 (spr48), unsigned 64 bits
+	149: spr49 (spr49), unsigned 64 bits
+	150: spr50 (spr50), unsigned 64 bits
+	151: spr51 (spr51), unsigned 64 bits
+	152: spr52 (spr52), unsigned 64 bits
+	153: spr53 (spr53), unsigned 64 bits
+	154: spr54 (spr54), unsigned 64 bits
+	155: spr55 (spr55), unsigned 64 bits
+	156: spr56 (spr56), unsigned 64 bits
+	157: spr57 (spr57), unsigned 64 bits
+	158: spr58 (spr58), unsigned 64 bits
+	159: spr59 (spr59), unsigned 64 bits
+	160: spr60 (spr60), unsigned 64 bits
+	161: spr61 (spr61), unsigned 64 bits
+	162: spr62 (spr62), unsigned 64 bits
+	163: spr63 (spr63), unsigned 64 bits
+	164: spr64 (spr64), unsigned 64 bits
+	165: spr65 (spr65), unsigned 64 bits
+	166: spr66 (spr66), unsigned 64 bits
+	167: spr67 (spr67), unsigned 64 bits
+	168: spr68 (spr68), unsigned 64 bits
+	169: spr69 (spr69), unsigned 64 bits
+	170: spr70 (spr70), unsigned 64 bits
+	171: spr71 (spr71), unsigned 64 bits
+	172: spr72 (spr72), unsigned 64 bits
+	173: spr73 (spr73), unsigned 64 bits
+	174: spr74 (spr74), unsigned 64 bits
+	175: spr75 (spr75), unsigned 64 bits
+	176: spr76 (spr76), unsigned 64 bits
+	177: spr77 (spr77), unsigned 64 bits
+	178: spr78 (spr78), unsigned 64 bits
+	179: spr79 (spr79), unsigned 64 bits
+	180: spr80 (spr80), unsigned 64 bits
+	181: spr81 (spr81), unsigned 64 bits
+	182: spr82 (spr82), unsigned 64 bits
+	183: spr83 (spr83), unsigned 64 bits
+	184: spr84 (spr84), unsigned 64 bits
+	185: spr85 (spr85), unsigned 64 bits
+	186: spr86 (spr86), unsigned 64 bits
+	187: spr87 (spr87), unsigned 64 bits
+	188: spr88 (spr88), unsigned 64 bits
+	189: spr89 (spr89), unsigned 64 bits
+	190: spr90 (spr90), unsigned 64 bits
+	191: spr91 (spr91), unsigned 64 bits
+	192: spr92 (spr92), unsigned 64 bits
+	193: spr93 (spr93), unsigned 64 bits
+	194: spr94 (spr94), unsigned 64 bits
+	195: spr95 (spr95), unsigned 64 bits
+	196: spr96 (spr96), unsigned 64 bits
+	197: spr97 (spr97), unsigned 64 bits
+	198: spr98 (spr98), unsigned 64 bits
+	199: spr99 (spr99), unsigned 64 bits
+	200: spr100 (spr100), unsigned 64 bits
+	201: spr101 (spr101), unsigned 64 bits
+	202: spr102 (spr102), unsigned 64 bits
+	203: spr103 (spr103), unsigned 64 bits
+	204: spr104 (spr104), unsigned 64 bits
+	205: spr105 (spr105), unsigned 64 bits
+	206: spr106 (spr106), unsigned 64 bits
+	207: spr107 (spr107), unsigned 64 bits
+	208: spr108 (spr108), unsigned 64 bits
+	209: spr109 (spr109), unsigned 64 bits
+	210: spr110 (spr110), unsigned 64 bits
+	211: spr111 (spr111), unsigned 64 bits
+	212: spr112 (spr112), unsigned 64 bits
+	213: spr113 (spr113), unsigned 64 bits
+	214: spr114 (spr114), unsigned 64 bits
+	215: spr115 (spr115), unsigned 64 bits
+	216: spr116 (spr116), unsigned 64 bits
+	217: spr117 (spr117), unsigned 64 bits
+	218: spr118 (spr118), unsigned 64 bits
+	219: spr119 (spr119), unsigned 64 bits
+	220: spr120 (spr120), unsigned 64 bits
+	221: spr121 (spr121), unsigned 64 bits
+	222: spr122 (spr122), unsigned 64 bits
+	223: spr123 (spr123), unsigned 64 bits
+	224: spr124 (spr124), unsigned 64 bits
+	225: spr125 (spr125), unsigned 64 bits
+	226: spr126 (spr126), unsigned 64 bits
+	227: spr127 (spr127), unsigned 64 bits
+	228: spr128 (spr128), unsigned 64 bits
+	229: spr129 (spr129), unsigned 64 bits
+	230: spr130 (spr130), unsigned 64 bits
+	231: spr131 (spr131), unsigned 64 bits
+	232: spr132 (spr132), unsigned 64 bits
+	233: spr133 (spr133), unsigned 64 bits
+	234: spr134 (spr134), unsigned 64 bits
+	235: spr135 (spr135), unsigned 64 bits
+	236: spr136 (spr136), unsigned 64 bits
+	237: spr137 (spr137), unsigned 64 bits
+	238: spr138 (spr138), unsigned 64 bits
+	239: spr139 (spr139), unsigned 64 bits
+	240: spr140 (spr140), unsigned 64 bits
+	241: spr141 (spr141), unsigned 64 bits
+	242: spr142 (spr142), unsigned 64 bits
+	243: spr143 (spr143), unsigned 64 bits
+	244: spr144 (spr144), unsigned 64 bits
+	245: spr145 (spr145), unsigned 64 bits
+	246: spr146 (spr146), unsigned 64 bits
+	247: spr147 (spr147), unsigned 64 bits
+	248: spr148 (spr148), unsigned 64 bits
+	249: spr149 (spr149), unsigned 64 bits
+	250: spr150 (spr150), unsigned 64 bits
+	251: spr151 (spr151), unsigned 64 bits
+	252: spr152 (spr152), unsigned 64 bits
+	253: spr153 (spr153), unsigned 64 bits
+	254: spr154 (spr154), unsigned 64 bits
+	255: spr155 (spr155), unsigned 64 bits
+	256: spr156 (spr156), unsigned 64 bits
+	257: spr157 (spr157), unsigned 64 bits
+	258: spr158 (spr158), unsigned 64 bits
+	259: spr159 (spr159), unsigned 64 bits
+	260: spr160 (spr160), unsigned 64 bits
+	261: spr161 (spr161), unsigned 64 bits
+	262: spr162 (spr162), unsigned 64 bits
+	263: spr163 (spr163), unsigned 64 bits
+	264: spr164 (spr164), unsigned 64 bits
+	265: spr165 (spr165), unsigned 64 bits
+	266: spr166 (spr166), unsigned 64 bits
+	267: spr167 (spr167), unsigned 64 bits
+	268: spr168 (spr168), unsigned 64 bits
+	269: spr169 (spr169), unsigned 64 bits
+	270: spr170 (spr170), unsigned 64 bits
+	271: spr171 (spr171), unsigned 64 bits
+	272: spr172 (spr172), unsigned 64 bits
+	273: spr173 (spr173), unsigned 64 bits
+	274: spr174 (spr174), unsigned 64 bits
+	275: spr175 (spr175), unsigned 64 bits
+	276: spr176 (spr176), unsigned 64 bits
+	277: spr177 (spr177), unsigned 64 bits
+	278: spr178 (spr178), unsigned 64 bits
+	279: spr179 (spr179), unsigned 64 bits
+	280: spr180 (spr180), unsigned 64 bits
+	281: spr181 (spr181), unsigned 64 bits
+	282: spr182 (spr182), unsigned 64 bits
+	283: spr183 (spr183), unsigned 64 bits
+	284: spr184 (spr184), unsigned 64 bits
+	285: spr185 (spr185), unsigned 64 bits
+	286: spr186 (spr186), unsigned 64 bits
+	287: spr187 (spr187), unsigned 64 bits
+	288: spr188 (spr188), unsigned 64 bits
+	289: spr189 (spr189), unsigned 64 bits
+	290: spr190 (spr190), unsigned 64 bits
+	291: spr191 (spr191), unsigned 64 bits
+	292: spr192 (spr192), unsigned 64 bits
+	293: spr193 (spr193), unsigned 64 bits
+	294: spr194 (spr194), unsigned 64 bits
+	295: spr195 (spr195), unsigned 64 bits
+	296: spr196 (spr196), unsigned 64 bits
+	297: spr197 (spr197), unsigned 64 bits
+	298: spr198 (spr198), unsigned 64 bits
+	299: spr199 (spr199), unsigned 64 bits
+	300: spr200 (spr200), unsigned 64 bits
+	301: spr201 (spr201), unsigned 64 bits
+	302: spr202 (spr202), unsigned 64 bits
+	303: spr203 (spr203), unsigned 64 bits
+	304: spr204 (spr204), unsigned 64 bits
+	305: spr205 (spr205), unsigned 64 bits
+	306: spr206 (spr206), unsigned 64 bits
+	307: spr207 (spr207), unsigned 64 bits
+	308: spr208 (spr208), unsigned 64 bits
+	309: spr209 (spr209), unsigned 64 bits
+	310: spr210 (spr210), unsigned 64 bits
+	311: spr211 (spr211), unsigned 64 bits
+	312: spr212 (spr212), unsigned 64 bits
+	313: spr213 (spr213), unsigned 64 bits
+	314: spr214 (spr214), unsigned 64 bits
+	315: spr215 (spr215), unsigned 64 bits
+	316: spr216 (spr216), unsigned 64 bits
+	317: spr217 (spr217), unsigned 64 bits
+	318: spr218 (spr218), unsigned 64 bits
+	319: spr219 (spr219), unsigned 64 bits
+	320: spr220 (spr220), unsigned 64 bits
+	321: spr221 (spr221), unsigned 64 bits
+	322: spr222 (spr222), unsigned 64 bits
+	323: spr223 (spr223), unsigned 64 bits
+	324: spr224 (spr224), unsigned 64 bits
+	325: spr225 (spr225), unsigned 64 bits
+	326: spr226 (spr226), unsigned 64 bits
+	327: spr227 (spr227), unsigned 64 bits
+	328: spr228 (spr228), unsigned 64 bits
+	329: spr229 (spr229), unsigned 64 bits
+	330: spr230 (spr230), unsigned 64 bits
+	331: spr231 (spr231), unsigned 64 bits
+	332: spr232 (spr232), unsigned 64 bits
+	333: spr233 (spr233), unsigned 64 bits
+	334: spr234 (spr234), unsigned 64 bits
+	335: spr235 (spr235), unsigned 64 bits
+	336: spr236 (spr236), unsigned 64 bits
+	337: spr237 (spr237), unsigned 64 bits
+	338: spr238 (spr238), unsigned 64 bits
+	339: spr239 (spr239), unsigned 64 bits
+	340: spr240 (spr240), unsigned 64 bits
+	341: spr241 (spr241), unsigned 64 bits
+	342: spr242 (spr242), unsigned 64 bits
+	343: spr243 (spr243), unsigned 64 bits
+	344: spr244 (spr244), unsigned 64 bits
+	345: spr245 (spr245), unsigned 64 bits
+	346: spr246 (spr246), unsigned 64 bits
+	347: spr247 (spr247), unsigned 64 bits
+	348: spr248 (spr248), unsigned 64 bits
+	349: spr249 (spr249), unsigned 64 bits
+	350: spr250 (spr250), unsigned 64 bits
+	351: spr251 (spr251), unsigned 64 bits
+	352: spr252 (spr252), unsigned 64 bits
+	353: spr253 (spr253), unsigned 64 bits
+	354: spr254 (spr254), unsigned 64 bits
+	355: spr255 (spr255), unsigned 64 bits
+	357: spr257 (spr257), unsigned 64 bits
+	358: spr258 (spr258), unsigned 64 bits
+	359: spr259 (spr259), unsigned 64 bits
+	360: spr260 (spr260), unsigned 64 bits
+	361: spr261 (spr261), unsigned 64 bits
+	362: spr262 (spr262), unsigned 64 bits
+	363: spr263 (spr263), unsigned 64 bits
+	364: spr264 (spr264), unsigned 64 bits
+	365: spr265 (spr265), unsigned 64 bits
+	366: spr266 (spr266), unsigned 64 bits
+	367: spr267 (spr267), unsigned 64 bits
+	368: spr268 (spr268), unsigned 64 bits
+	369: spr269 (spr269), unsigned 64 bits
+	370: spr270 (spr270), unsigned 64 bits
+	371: spr271 (spr271), unsigned 64 bits
+	372: spr272 (spr272), unsigned 64 bits
+	373: spr273 (spr273), unsigned 64 bits
+	374: spr274 (spr274), unsigned 64 bits
+	375: spr275 (spr275), unsigned 64 bits
+	376: spr276 (spr276), unsigned 64 bits
+	377: spr277 (spr277), unsigned 64 bits
+	378: spr278 (spr278), unsigned 64 bits
+	379: spr279 (spr279), unsigned 64 bits
+	380: spr280 (spr280), unsigned 64 bits
+	381: spr281 (spr281), unsigned 64 bits
+	382: spr282 (spr282), unsigned 64 bits
+	383: spr283 (spr283), unsigned 64 bits
+	384: spr284 (spr284), unsigned 64 bits
+	385: spr285 (spr285), unsigned 64 bits
+	386: spr286 (spr286), unsigned 64 bits
+	387: spr287 (spr287), unsigned 64 bits
+	388: spr288 (spr288), unsigned 64 bits
+	389: spr289 (spr289), unsigned 64 bits
+	390: spr290 (spr290), unsigned 64 bits
+	391: spr291 (spr291), unsigned 64 bits
+	392: spr292 (spr292), unsigned 64 bits
+	393: spr293 (spr293), unsigned 64 bits
+	394: spr294 (spr294), unsigned 64 bits
+	395: spr295 (spr295), unsigned 64 bits
+	396: spr296 (spr296), unsigned 64 bits
+	397: spr297 (spr297), unsigned 64 bits
+	398: spr298 (spr298), unsigned 64 bits
+	399: spr299 (spr299), unsigned 64 bits
+	400: spr300 (spr300), unsigned 64 bits
+	401: spr301 (spr301), unsigned 64 bits
+	402: spr302 (spr302), unsigned 64 bits
+	403: spr303 (spr303), unsigned 64 bits
+	404: spr304 (spr304), unsigned 64 bits
+	405: spr305 (spr305), unsigned 64 bits
+	406: spr306 (spr306), unsigned 64 bits
+	407: spr307 (spr307), unsigned 64 bits
+	408: spr308 (spr308), unsigned 64 bits
+	409: spr309 (spr309), unsigned 64 bits
+	410: spr310 (spr310), unsigned 64 bits
+	411: spr311 (spr311), unsigned 64 bits
+	412: spr312 (spr312), unsigned 64 bits
+	413: spr313 (spr313), unsigned 64 bits
+	414: spr314 (spr314), unsigned 64 bits
+	415: spr315 (spr315), unsigned 64 bits
+	416: spr316 (spr316), unsigned 64 bits
+	417: spr317 (spr317), unsigned 64 bits
+	418: spr318 (spr318), unsigned 64 bits
+	419: spr319 (spr319), unsigned 64 bits
+	420: spr320 (spr320), unsigned 64 bits
+	421: spr321 (spr321), unsigned 64 bits
+	422: spr322 (spr322), unsigned 64 bits
+	423: spr323 (spr323), unsigned 64 bits
+	424: spr324 (spr324), unsigned 64 bits
+	425: spr325 (spr325), unsigned 64 bits
+	426: spr326 (spr326), unsigned 64 bits
+	427: spr327 (spr327), unsigned 64 bits
+	428: spr328 (spr328), unsigned 64 bits
+	429: spr329 (spr329), unsigned 64 bits
+	430: spr330 (spr330), unsigned 64 bits
+	431: spr331 (spr331), unsigned 64 bits
+	432: spr332 (spr332), unsigned 64 bits
+	433: spr333 (spr333), unsigned 64 bits
+	434: spr334 (spr334), unsigned 64 bits
+	435: spr335 (spr335), unsigned 64 bits
+	436: spr336 (spr336), unsigned 64 bits
+	437: spr337 (spr337), unsigned 64 bits
+	438: spr338 (spr338), unsigned 64 bits
+	439: spr339 (spr339), unsigned 64 bits
+	440: spr340 (spr340), unsigned 64 bits
+	441: spr341 (spr341), unsigned 64 bits
+	442: spr342 (spr342), unsigned 64 bits
+	443: spr343 (spr343), unsigned 64 bits
+	444: spr344 (spr344), unsigned 64 bits
+	445: spr345 (spr345), unsigned 64 bits
+	446: spr346 (spr346), unsigned 64 bits
+	447: spr347 (spr347), unsigned 64 bits
+	448: spr348 (spr348), unsigned 64 bits
+	449: spr349 (spr349), unsigned 64 bits
+	450: spr350 (spr350), unsigned 64 bits
+	451: spr351 (spr351), unsigned 64 bits
+	452: spr352 (spr352), unsigned 64 bits
+	453: spr353 (spr353), unsigned 64 bits
+	454: spr354 (spr354), unsigned 64 bits
+	455: spr355 (spr355), unsigned 64 bits
+	456: spr356 (spr356), unsigned 64 bits
+	457: spr357 (spr357), unsigned 64 bits
+	458: spr358 (spr358), unsigned 64 bits
+	459: spr359 (spr359), unsigned 64 bits
+	460: spr360 (spr360), unsigned 64 bits
+	461: spr361 (spr361), unsigned 64 bits
+	462: spr362 (spr362), unsigned 64 bits
+	463: spr363 (spr363), unsigned 64 bits
+	464: spr364 (spr364), unsigned 64 bits
+	465: spr365 (spr365), unsigned 64 bits
+	466: spr366 (spr366), unsigned 64 bits
+	467: spr367 (spr367), unsigned 64 bits
+	468: spr368 (spr368), unsigned 64 bits
+	469: spr369 (spr369), unsigned 64 bits
+	470: spr370 (spr370), unsigned 64 bits
+	471: spr371 (spr371), unsigned 64 bits
+	472: spr372 (spr372), unsigned 64 bits
+	473: spr373 (spr373), unsigned 64 bits
+	474: spr374 (spr374), unsigned 64 bits
+	475: spr375 (spr375), unsigned 64 bits
+	476: spr376 (spr376), unsigned 64 bits
+	477: spr377 (spr377), unsigned 64 bits
+	478: spr378 (spr378), unsigned 64 bits
+	479: spr379 (spr379), unsigned 64 bits
+	480: spr380 (spr380), unsigned 64 bits
+	481: spr381 (spr381), unsigned 64 bits
+	482: spr382 (spr382), unsigned 64 bits
+	483: spr383 (spr383), unsigned 64 bits
+	484: spr384 (spr384), unsigned 64 bits
+	485: spr385 (spr385), unsigned 64 bits
+	486: spr386 (spr386), unsigned 64 bits
+	487: spr387 (spr387), unsigned 64 bits
+	488: spr388 (spr388), unsigned 64 bits
+	489: spr389 (spr389), unsigned 64 bits
+	490: spr390 (spr390), unsigned 64 bits
+	491: spr391 (spr391), unsigned 64 bits
+	492: spr392 (spr392), unsigned 64 bits
+	493: spr393 (spr393), unsigned 64 bits
+	494: spr394 (spr394), unsigned 64 bits
+	495: spr395 (spr395), unsigned 64 bits
+	496: spr396 (spr396), unsigned 64 bits
+	497: spr397 (spr397), unsigned 64 bits
+	498: spr398 (spr398), unsigned 64 bits
+	499: spr399 (spr399), unsigned 64 bits
+	500: spr400 (spr400), unsigned 64 bits
+	501: spr401 (spr401), unsigned 64 bits
+	502: spr402 (spr402), unsigned 64 bits
+	503: spr403 (spr403), unsigned 64 bits
+	504: spr404 (spr404), unsigned 64 bits
+	505: spr405 (spr405), unsigned 64 bits
+	506: spr406 (spr406), unsigned 64 bits
+	507: spr407 (spr407), unsigned 64 bits
+	508: spr408 (spr408), unsigned 64 bits
+	509: spr409 (spr409), unsigned 64 bits
+	510: spr410 (spr410), unsigned 64 bits
+	511: spr411 (spr411), unsigned 64 bits
+	512: spr412 (spr412), unsigned 64 bits
+	513: spr413 (spr413), unsigned 64 bits
+	514: spr414 (spr414), unsigned 64 bits
+	515: spr415 (spr415), unsigned 64 bits
+	516: spr416 (spr416), unsigned 64 bits
+	517: spr417 (spr417), unsigned 64 bits
+	518: spr418 (spr418), unsigned 64 bits
+	519: spr419 (spr419), unsigned 64 bits
+	520: spr420 (spr420), unsigned 64 bits
+	521: spr421 (spr421), unsigned 64 bits
+	522: spr422 (spr422), unsigned 64 bits
+	523: spr423 (spr423), unsigned 64 bits
+	524: spr424 (spr424), unsigned 64 bits
+	525: spr425 (spr425), unsigned 64 bits
+	526: spr426 (spr426), unsigned 64 bits
+	527: spr427 (spr427), unsigned 64 bits
+	528: spr428 (spr428), unsigned 64 bits
+	529: spr429 (spr429), unsigned 64 bits
+	530: spr430 (spr430), unsigned 64 bits
+	531: spr431 (spr431), unsigned 64 bits
+	532: spr432 (spr432), unsigned 64 bits
+	533: spr433 (spr433), unsigned 64 bits
+	534: spr434 (spr434), unsigned 64 bits
+	535: spr435 (spr435), unsigned 64 bits
+	536: spr436 (spr436), unsigned 64 bits
+	537: spr437 (spr437), unsigned 64 bits
+	538: spr438 (spr438), unsigned 64 bits
+	539: spr439 (spr439), unsigned 64 bits
+	540: spr440 (spr440), unsigned 64 bits
+	541: spr441 (spr441), unsigned 64 bits
+	542: spr442 (spr442), unsigned 64 bits
+	543: spr443 (spr443), unsigned 64 bits
+	544: spr444 (spr444), unsigned 64 bits
+	545: spr445 (spr445), unsigned 64 bits
+	546: spr446 (spr446), unsigned 64 bits
+	547: spr447 (spr447), unsigned 64 bits
+	548: spr448 (spr448), unsigned 64 bits
+	549: spr449 (spr449), unsigned 64 bits
+	550: spr450 (spr450), unsigned 64 bits
+	551: spr451 (spr451), unsigned 64 bits
+	552: spr452 (spr452), unsigned 64 bits
+	553: spr453 (spr453), unsigned 64 bits
+	554: spr454 (spr454), unsigned 64 bits
+	555: spr455 (spr455), unsigned 64 bits
+	556: spr456 (spr456), unsigned 64 bits
+	557: spr457 (spr457), unsigned 64 bits
+	558: spr458 (spr458), unsigned 64 bits
+	559: spr459 (spr459), unsigned 64 bits
+	560: spr460 (spr460), unsigned 64 bits
+	561: spr461 (spr461), unsigned 64 bits
+	562: spr462 (spr462), unsigned 64 bits
+	563: spr463 (spr463), unsigned 64 bits
+	564: spr464 (spr464), unsigned 64 bits
+	565: spr465 (spr465), unsigned 64 bits
+	566: spr466 (spr466), unsigned 64 bits
+	567: spr467 (spr467), unsigned 64 bits
+	568: spr468 (spr468), unsigned 64 bits
+	569: spr469 (spr469), unsigned 64 bits
+	570: spr470 (spr470), unsigned 64 bits
+	571: spr471 (spr471), unsigned 64 bits
+	572: spr472 (spr472), unsigned 64 bits
+	573: spr473 (spr473), unsigned 64 bits
+	574: spr474 (spr474), unsigned 64 bits
+	575: spr475 (spr475), unsigned 64 bits
+	576: spr476 (spr476), unsigned 64 bits
+	577: spr477 (spr477), unsigned 64 bits
+	578: spr478 (spr478), unsigned 64 bits
+	579: spr479 (spr479), unsigned 64 bits
+	580: spr480 (spr480), unsigned 64 bits
+	581: spr481 (spr481), unsigned 64 bits
+	582: spr482 (spr482), unsigned 64 bits
+	583: spr483 (spr483), unsigned 64 bits
+	584: spr484 (spr484), unsigned 64 bits
+	585: spr485 (spr485), unsigned 64 bits
+	586: spr486 (spr486), unsigned 64 bits
+	587: spr487 (spr487), unsigned 64 bits
+	588: spr488 (spr488), unsigned 64 bits
+	589: spr489 (spr489), unsigned 64 bits
+	590: spr490 (spr490), unsigned 64 bits
+	591: spr491 (spr491), unsigned 64 bits
+	592: spr492 (spr492), unsigned 64 bits
+	593: spr493 (spr493), unsigned 64 bits
+	594: spr494 (spr494), unsigned 64 bits
+	595: spr495 (spr495), unsigned 64 bits
+	596: spr496 (spr496), unsigned 64 bits
+	597: spr497 (spr497), unsigned 64 bits
+	598: spr498 (spr498), unsigned 64 bits
+	599: spr499 (spr499), unsigned 64 bits
+	600: spr500 (spr500), unsigned 64 bits
+	601: spr501 (spr501), unsigned 64 bits
+	602: spr502 (spr502), unsigned 64 bits
+	603: spr503 (spr503), unsigned 64 bits
+	604: spr504 (spr504), unsigned 64 bits
+	605: spr505 (spr505), unsigned 64 bits
+	606: spr506 (spr506), unsigned 64 bits
+	607: spr507 (spr507), unsigned 64 bits
+	608: spr508 (spr508), unsigned 64 bits
+	609: spr509 (spr509), unsigned 64 bits
+	610: spr510 (spr510), unsigned 64 bits
+	611: spr511 (spr511), unsigned 64 bits
+	613: spr513 (spr513), unsigned 64 bits
+	614: spr514 (spr514), unsigned 64 bits
+	615: spr515 (spr515), unsigned 64 bits
+	616: spr516 (spr516), unsigned 64 bits
+	617: spr517 (spr517), unsigned 64 bits
+	618: spr518 (spr518), unsigned 64 bits
+	619: spr519 (spr519), unsigned 64 bits
+	620: spr520 (spr520), unsigned 64 bits
+	621: spr521 (spr521), unsigned 64 bits
+	622: spr522 (spr522), unsigned 64 bits
+	623: spr523 (spr523), unsigned 64 bits
+	624: spr524 (spr524), unsigned 64 bits
+	625: spr525 (spr525), unsigned 64 bits
+	626: spr526 (spr526), unsigned 64 bits
+	627: spr527 (spr527), unsigned 64 bits
+	628: spr528 (spr528), unsigned 64 bits
+	629: spr529 (spr529), unsigned 64 bits
+	630: spr530 (spr530), unsigned 64 bits
+	631: spr531 (spr531), unsigned 64 bits
+	632: spr532 (spr532), unsigned 64 bits
+	633: spr533 (spr533), unsigned 64 bits
+	634: spr534 (spr534), unsigned 64 bits
+	635: spr535 (spr535), unsigned 64 bits
+	636: spr536 (spr536), unsigned 64 bits
+	637: spr537 (spr537), unsigned 64 bits
+	638: spr538 (spr538), unsigned 64 bits
+	639: spr539 (spr539), unsigned 64 bits
+	640: spr540 (spr540), unsigned 64 bits
+	641: spr541 (spr541), unsigned 64 bits
+	642: spr542 (spr542), unsigned 64 bits
+	643: spr543 (spr543), unsigned 64 bits
+	644: spr544 (spr544), unsigned 64 bits
+	645: spr545 (spr545), unsigned 64 bits
+	646: spr546 (spr546), unsigned 64 bits
+	647: spr547 (spr547), unsigned 64 bits
+	648: spr548 (spr548), unsigned 64 bits
+	649: spr549 (spr549), unsigned 64 bits
+	650: spr550 (spr550), unsigned 64 bits
+	651: spr551 (spr551), unsigned 64 bits
+	652: spr552 (spr552), unsigned 64 bits
+	653: spr553 (spr553), unsigned 64 bits
+	654: spr554 (spr554), unsigned 64 bits
+	655: spr555 (spr555), unsigned 64 bits
+	656: spr556 (spr556), unsigned 64 bits
+	657: spr557 (spr557), unsigned 64 bits
+	658: spr558 (spr558), unsigned 64 bits
+	659: spr559 (spr559), unsigned 64 bits
+	660: spr560 (spr560), unsigned 64 bits
+	661: spr561 (spr561), unsigned 64 bits
+	662: spr562 (spr562), unsigned 64 bits
+	663: spr563 (spr563), unsigned 64 bits
+	664: spr564 (spr564), unsigned 64 bits
+	665: spr565 (spr565), unsigned 64 bits
+	666: spr566 (spr566), unsigned 64 bits
+	667: spr567 (spr567), unsigned 64 bits
+	668: spr568 (spr568), unsigned 64 bits
+	669: spr569 (spr569), unsigned 64 bits
+	670: spr570 (spr570), unsigned 64 bits
+	671: spr571 (spr571), unsigned 64 bits
+	672: spr572 (spr572), unsigned 64 bits
+	673: spr573 (spr573), unsigned 64 bits
+	674: spr574 (spr574), unsigned 64 bits
+	675: spr575 (spr575), unsigned 64 bits
+	676: spr576 (spr576), unsigned 64 bits
+	677: spr577 (spr577), unsigned 64 bits
+	678: spr578 (spr578), unsigned 64 bits
+	679: spr579 (spr579), unsigned 64 bits
+	680: spr580 (spr580), unsigned 64 bits
+	681: spr581 (spr581), unsigned 64 bits
+	682: spr582 (spr582), unsigned 64 bits
+	683: spr583 (spr583), unsigned 64 bits
+	684: spr584 (spr584), unsigned 64 bits
+	685: spr585 (spr585), unsigned 64 bits
+	686: spr586 (spr586), unsigned 64 bits
+	687: spr587 (spr587), unsigned 64 bits
+	688: spr588 (spr588), unsigned 64 bits
+	689: spr589 (spr589), unsigned 64 bits
+	690: spr590 (spr590), unsigned 64 bits
+	691: spr591 (spr591), unsigned 64 bits
+	692: spr592 (spr592), unsigned 64 bits
+	693: spr593 (spr593), unsigned 64 bits
+	694: spr594 (spr594), unsigned 64 bits
+	695: spr595 (spr595), unsigned 64 bits
+	696: spr596 (spr596), unsigned 64 bits
+	697: spr597 (spr597), unsigned 64 bits
+	698: spr598 (spr598), unsigned 64 bits
+	699: spr599 (spr599), unsigned 64 bits
+	700: spr600 (spr600), unsigned 64 bits
+	701: spr601 (spr601), unsigned 64 bits
+	702: spr602 (spr602), unsigned 64 bits
+	703: spr603 (spr603), unsigned 64 bits
+	704: spr604 (spr604), unsigned 64 bits
+	705: spr605 (spr605), unsigned 64 bits
+	706: spr606 (spr606), unsigned 64 bits
+	707: spr607 (spr607), unsigned 64 bits
+	708: spr608 (spr608), unsigned 64 bits
+	709: spr609 (spr609), unsigned 64 bits
+	710: spr610 (spr610), unsigned 64 bits
+	711: spr611 (spr611), unsigned 64 bits
+	712: spr612 (spr612), unsigned 64 bits
+	713: spr613 (spr613), unsigned 64 bits
+	714: spr614 (spr614), unsigned 64 bits
+	715: spr615 (spr615), unsigned 64 bits
+	716: spr616 (spr616), unsigned 64 bits
+	717: spr617 (spr617), unsigned 64 bits
+	718: spr618 (spr618), unsigned 64 bits
+	719: spr619 (spr619), unsigned 64 bits
+	720: spr620 (spr620), unsigned 64 bits
+	721: spr621 (spr621), unsigned 64 bits
+	722: spr622 (spr622), unsigned 64 bits
+	723: spr623 (spr623), unsigned 64 bits
+	724: spr624 (spr624), unsigned 64 bits
+	725: spr625 (spr625), unsigned 64 bits
+	726: spr626 (spr626), unsigned 64 bits
+	727: spr627 (spr627), unsigned 64 bits
+	728: spr628 (spr628), unsigned 64 bits
+	729: spr629 (spr629), unsigned 64 bits
+	730: spr630 (spr630), unsigned 64 bits
+	731: spr631 (spr631), unsigned 64 bits
+	732: spr632 (spr632), unsigned 64 bits
+	733: spr633 (spr633), unsigned 64 bits
+	734: spr634 (spr634), unsigned 64 bits
+	735: spr635 (spr635), unsigned 64 bits
+	736: spr636 (spr636), unsigned 64 bits
+	737: spr637 (spr637), unsigned 64 bits
+	738: spr638 (spr638), unsigned 64 bits
+	739: spr639 (spr639), unsigned 64 bits
+	740: spr640 (spr640), unsigned 64 bits
+	741: spr641 (spr641), unsigned 64 bits
+	742: spr642 (spr642), unsigned 64 bits
+	743: spr643 (spr643), unsigned 64 bits
+	744: spr644 (spr644), unsigned 64 bits
+	745: spr645 (spr645), unsigned 64 bits
+	746: spr646 (spr646), unsigned 64 bits
+	747: spr647 (spr647), unsigned 64 bits
+	748: spr648 (spr648), unsigned 64 bits
+	749: spr649 (spr649), unsigned 64 bits
+	750: spr650 (spr650), unsigned 64 bits
+	751: spr651 (spr651), unsigned 64 bits
+	752: spr652 (spr652), unsigned 64 bits
+	753: spr653 (spr653), unsigned 64 bits
+	754: spr654 (spr654), unsigned 64 bits
+	755: spr655 (spr655), unsigned 64 bits
+	756: spr656 (spr656), unsigned 64 bits
+	757: spr657 (spr657), unsigned 64 bits
+	758: spr658 (spr658), unsigned 64 bits
+	759: spr659 (spr659), unsigned 64 bits
+	760: spr660 (spr660), unsigned 64 bits
+	761: spr661 (spr661), unsigned 64 bits
+	762: spr662 (spr662), unsigned 64 bits
+	763: spr663 (spr663), unsigned 64 bits
+	764: spr664 (spr664), unsigned 64 bits
+	765: spr665 (spr665), unsigned 64 bits
+	766: spr666 (spr666), unsigned 64 bits
+	767: spr667 (spr667), unsigned 64 bits
+	768: spr668 (spr668), unsigned 64 bits
+	769: spr669 (spr669), unsigned 64 bits
+	770: spr670 (spr670), unsigned 64 bits
+	771: spr671 (spr671), unsigned 64 bits
+	772: spr672 (spr672), unsigned 64 bits
+	773: spr673 (spr673), unsigned 64 bits
+	774: spr674 (spr674), unsigned 64 bits
+	775: spr675 (spr675), unsigned 64 bits
+	776: spr676 (spr676), unsigned 64 bits
+	777: spr677 (spr677), unsigned 64 bits
+	778: spr678 (spr678), unsigned 64 bits
+	779: spr679 (spr679), unsigned 64 bits
+	780: spr680 (spr680), unsigned 64 bits
+	781: spr681 (spr681), unsigned 64 bits
+	782: spr682 (spr682), unsigned 64 bits
+	783: spr683 (spr683), unsigned 64 bits
+	784: spr684 (spr684), unsigned 64 bits
+	785: spr685 (spr685), unsigned 64 bits
+	786: spr686 (spr686), unsigned 64 bits
+	787: spr687 (spr687), unsigned 64 bits
+	788: spr688 (spr688), unsigned 64 bits
+	789: spr689 (spr689), unsigned 64 bits
+	790: spr690 (spr690), unsigned 64 bits
+	791: spr691 (spr691), unsigned 64 bits
+	792: spr692 (spr692), unsigned 64 bits
+	793: spr693 (spr693), unsigned 64 bits
+	794: spr694 (spr694), unsigned 64 bits
+	795: spr695 (spr695), unsigned 64 bits
+	796: spr696 (spr696), unsigned 64 bits
+	797: spr697 (spr697), unsigned 64 bits
+	798: spr698 (spr698), unsigned 64 bits
+	799: spr699 (spr699), unsigned 64 bits
+	800: spr700 (spr700), unsigned 64 bits
+	801: spr701 (spr701), unsigned 64 bits
+	802: spr702 (spr702), unsigned 64 bits
+	803: spr703 (spr703), unsigned 64 bits
+	804: spr704 (spr704), unsigned 64 bits
+	805: spr705 (spr705), unsigned 64 bits
+	806: spr706 (spr706), unsigned 64 bits
+	807: spr707 (spr707), unsigned 64 bits
+	808: spr708 (spr708), unsigned 64 bits
+	809: spr709 (spr709), unsigned 64 bits
+	810: spr710 (spr710), unsigned 64 bits
+	811: spr711 (spr711), unsigned 64 bits
+	812: spr712 (spr712), unsigned 64 bits
+	813: spr713 (spr713), unsigned 64 bits
+	814: spr714 (spr714), unsigned 64 bits
+	815: spr715 (spr715), unsigned 64 bits
+	816: spr716 (spr716), unsigned 64 bits
+	817: spr717 (spr717), unsigned 64 bits
+	818: spr718 (spr718), unsigned 64 bits
+	819: spr719 (spr719), unsigned 64 bits
+	820: spr720 (spr720), unsigned 64 bits
+	821: spr721 (spr721), unsigned 64 bits
+	822: spr722 (spr722), unsigned 64 bits
+	823: spr723 (spr723), unsigned 64 bits
+	824: spr724 (spr724), unsigned 64 bits
+	825: spr725 (spr725), unsigned 64 bits
+	826: spr726 (spr726), unsigned 64 bits
+	827: spr727 (spr727), unsigned 64 bits
+	828: spr728 (spr728), unsigned 64 bits
+	829: spr729 (spr729), unsigned 64 bits
+	830: spr730 (spr730), unsigned 64 bits
+	831: spr731 (spr731), unsigned 64 bits
+	832: spr732 (spr732), unsigned 64 bits
+	833: spr733 (spr733), unsigned 64 bits
+	834: spr734 (spr734), unsigned 64 bits
+	835: spr735 (spr735), unsigned 64 bits
+	836: spr736 (spr736), unsigned 64 bits
+	837: spr737 (spr737), unsigned 64 bits
+	838: spr738 (spr738), unsigned 64 bits
+	839: spr739 (spr739), unsigned 64 bits
+	840: spr740 (spr740), unsigned 64 bits
+	841: spr741 (spr741), unsigned 64 bits
+	842: spr742 (spr742), unsigned 64 bits
+	843: spr743 (spr743), unsigned 64 bits
+	844: spr744 (spr744), unsigned 64 bits
+	845: spr745 (spr745), unsigned 64 bits
+	846: spr746 (spr746), unsigned 64 bits
+	847: spr747 (spr747), unsigned 64 bits
+	848: spr748 (spr748), unsigned 64 bits
+	849: spr749 (spr749), unsigned 64 bits
+	850: spr750 (spr750), unsigned 64 bits
+	851: spr751 (spr751), unsigned 64 bits
+	852: spr752 (spr752), unsigned 64 bits
+	853: spr753 (spr753), unsigned 64 bits
+	854: spr754 (spr754), unsigned 64 bits
+	855: spr755 (spr755), unsigned 64 bits
+	856: spr756 (spr756), unsigned 64 bits
+	857: spr757 (spr757), unsigned 64 bits
+	858: spr758 (spr758), unsigned 64 bits
+	859: spr759 (spr759), unsigned 64 bits
+	860: spr760 (spr760), unsigned 64 bits
+	861: spr761 (spr761), unsigned 64 bits
+	862: spr762 (spr762), unsigned 64 bits
+	863: spr763 (spr763), unsigned 64 bits
+	864: spr764 (spr764), unsigned 64 bits
+	865: spr765 (spr765), unsigned 64 bits
+	866: spr766 (spr766), unsigned 64 bits
+	867: spr767 (spr767), unsigned 64 bits
+	868: spr768 (spr768), unsigned 64 bits
+	869: spr769 (spr769), unsigned 64 bits
+	870: spr770 (spr770), unsigned 64 bits
+	871: spr771 (spr771), unsigned 64 bits
+	872: spr772 (spr772), unsigned 64 bits
+	873: spr773 (spr773), unsigned 64 bits
+	874: spr774 (spr774), unsigned 64 bits
+	875: spr775 (spr775), unsigned 64 bits
+	876: spr776 (spr776), unsigned 64 bits
+	877: spr777 (spr777), unsigned 64 bits
+	878: spr778 (spr778), unsigned 64 bits
+	879: spr779 (spr779), unsigned 64 bits
+	880: spr780 (spr780), unsigned 64 bits
+	881: spr781 (spr781), unsigned 64 bits
+	882: spr782 (spr782), unsigned 64 bits
+	883: spr783 (spr783), unsigned 64 bits
+	884: spr784 (spr784), unsigned 64 bits
+	885: spr785 (spr785), unsigned 64 bits
+	886: spr786 (spr786), unsigned 64 bits
+	887: spr787 (spr787), unsigned 64 bits
+	888: spr788 (spr788), unsigned 64 bits
+	889: spr789 (spr789), unsigned 64 bits
+	890: spr790 (spr790), unsigned 64 bits
+	891: spr791 (spr791), unsigned 64 bits
+	892: spr792 (spr792), unsigned 64 bits
+	893: spr793 (spr793), unsigned 64 bits
+	894: spr794 (spr794), unsigned 64 bits
+	895: spr795 (spr795), unsigned 64 bits
+	896: spr796 (spr796), unsigned 64 bits
+	897: spr797 (spr797), unsigned 64 bits
+	898: spr798 (spr798), unsigned 64 bits
+	899: spr799 (spr799), unsigned 64 bits
+	900: spr800 (spr800), unsigned 64 bits
+	901: spr801 (spr801), unsigned 64 bits
+	902: spr802 (spr802), unsigned 64 bits
+	903: spr803 (spr803), unsigned 64 bits
+	904: spr804 (spr804), unsigned 64 bits
+	905: spr805 (spr805), unsigned 64 bits
+	906: spr806 (spr806), unsigned 64 bits
+	907: spr807 (spr807), unsigned 64 bits
+	908: spr808 (spr808), unsigned 64 bits
+	909: spr809 (spr809), unsigned 64 bits
+	910: spr810 (spr810), unsigned 64 bits
+	911: spr811 (spr811), unsigned 64 bits
+	912: spr812 (spr812), unsigned 64 bits
+	913: spr813 (spr813), unsigned 64 bits
+	914: spr814 (spr814), unsigned 64 bits
+	915: spr815 (spr815), unsigned 64 bits
+	916: spr816 (spr816), unsigned 64 bits
+	917: spr817 (spr817), unsigned 64 bits
+	918: spr818 (spr818), unsigned 64 bits
+	919: spr819 (spr819), unsigned 64 bits
+	920: spr820 (spr820), unsigned 64 bits
+	921: spr821 (spr821), unsigned 64 bits
+	922: spr822 (spr822), unsigned 64 bits
+	923: spr823 (spr823), unsigned 64 bits
+	924: spr824 (spr824), unsigned 64 bits
+	925: spr825 (spr825), unsigned 64 bits
+	926: spr826 (spr826), unsigned 64 bits
+	927: spr827 (spr827), unsigned 64 bits
+	928: spr828 (spr828), unsigned 64 bits
+	929: spr829 (spr829), unsigned 64 bits
+	930: spr830 (spr830), unsigned 64 bits
+	931: spr831 (spr831), unsigned 64 bits
+	932: spr832 (spr832), unsigned 64 bits
+	933: spr833 (spr833), unsigned 64 bits
+	934: spr834 (spr834), unsigned 64 bits
+	935: spr835 (spr835), unsigned 64 bits
+	936: spr836 (spr836), unsigned 64 bits
+	937: spr837 (spr837), unsigned 64 bits
+	938: spr838 (spr838), unsigned 64 bits
+	939: spr839 (spr839), unsigned 64 bits
+	940: spr840 (spr840), unsigned 64 bits
+	941: spr841 (spr841), unsigned 64 bits
+	942: spr842 (spr842), unsigned 64 bits
+	943: spr843 (spr843), unsigned 64 bits
+	944: spr844 (spr844), unsigned 64 bits
+	945: spr845 (spr845), unsigned 64 bits
+	946: spr846 (spr846), unsigned 64 bits
+	947: spr847 (spr847), unsigned 64 bits
+	948: spr848 (spr848), unsigned 64 bits
+	949: spr849 (spr849), unsigned 64 bits
+	950: spr850 (spr850), unsigned 64 bits
+	951: spr851 (spr851), unsigned 64 bits
+	952: spr852 (spr852), unsigned 64 bits
+	953: spr853 (spr853), unsigned 64 bits
+	954: spr854 (spr854), unsigned 64 bits
+	955: spr855 (spr855), unsigned 64 bits
+	956: spr856 (spr856), unsigned 64 bits
+	957: spr857 (spr857), unsigned 64 bits
+	958: spr858 (spr858), unsigned 64 bits
+	959: spr859 (spr859), unsigned 64 bits
+	960: spr860 (spr860), unsigned 64 bits
+	961: spr861 (spr861), unsigned 64 bits
+	962: spr862 (spr862), unsigned 64 bits
+	963: spr863 (spr863), unsigned 64 bits
+	964: spr864 (spr864), unsigned 64 bits
+	965: spr865 (spr865), unsigned 64 bits
+	966: spr866 (spr866), unsigned 64 bits
+	967: spr867 (spr867), unsigned 64 bits
+	968: spr868 (spr868), unsigned 64 bits
+	969: spr869 (spr869), unsigned 64 bits
+	970: spr870 (spr870), unsigned 64 bits
+	971: spr871 (spr871), unsigned 64 bits
+	972: spr872 (spr872), unsigned 64 bits
+	973: spr873 (spr873), unsigned 64 bits
+	974: spr874 (spr874), unsigned 64 bits
+	975: spr875 (spr875), unsigned 64 bits
+	976: spr876 (spr876), unsigned 64 bits
+	977: spr877 (spr877), unsigned 64 bits
+	978: spr878 (spr878), unsigned 64 bits
+	979: spr879 (spr879), unsigned 64 bits
+	980: spr880 (spr880), unsigned 64 bits
+	981: spr881 (spr881), unsigned 64 bits
+	982: spr882 (spr882), unsigned 64 bits
+	983: spr883 (spr883), unsigned 64 bits
+	984: spr884 (spr884), unsigned 64 bits
+	985: spr885 (spr885), unsigned 64 bits
+	986: spr886 (spr886), unsigned 64 bits
+	987: spr887 (spr887), unsigned 64 bits
+	988: spr888 (spr888), unsigned 64 bits
+	989: spr889 (spr889), unsigned 64 bits
+	990: spr890 (spr890), unsigned 64 bits
+	991: spr891 (spr891), unsigned 64 bits
+	992: spr892 (spr892), unsigned 64 bits
+	993: spr893 (spr893), unsigned 64 bits
+	994: spr894 (spr894), unsigned 64 bits
+	995: spr895 (spr895), unsigned 64 bits
+	996: spr896 (spr896), unsigned 64 bits
+	997: spr897 (spr897), unsigned 64 bits
+	998: spr898 (spr898), unsigned 64 bits
+	999: spr899 (spr899), unsigned 64 bits
+vector registers:
+	 67: vscr (vscr), unsigned 32 bits
+	356: vrsave (vrsave), unsigned 32 bits
+	612: spefscr (spefscr), unsigned 32 bits
+	1124: vr0 (vr0), unsigned 128 bits
+	1125: vr1 (vr1), unsigned 128 bits
+	1126: vr2 (vr2), unsigned 128 bits
+	1127: vr3 (vr3), unsigned 128 bits
+	1128: vr4 (vr4), unsigned 128 bits
+	1129: vr5 (vr5), unsigned 128 bits
+	1130: vr6 (vr6), unsigned 128 bits
+	1131: vr7 (vr7), unsigned 128 bits
+	1132: vr8 (vr8), unsigned 128 bits
+	1133: vr9 (vr9), unsigned 128 bits
+	1134: vr10 (vr10), unsigned 128 bits
+	1135: vr11 (vr11), unsigned 128 bits
+	1136: vr12 (vr12), unsigned 128 bits
+	1137: vr13 (vr13), unsigned 128 bits
+	1138: vr14 (vr14), unsigned 128 bits
+	1139: vr15 (vr15), unsigned 128 bits
+	1140: vr16 (vr16), unsigned 128 bits
+	1141: vr17 (vr17), unsigned 128 bits
+	1142: vr18 (vr18), unsigned 128 bits
+	1143: vr19 (vr19), unsigned 128 bits
+	1144: vr20 (vr20), unsigned 128 bits
+	1145: vr21 (vr21), unsigned 128 bits
+	1146: vr22 (vr22), unsigned 128 bits
+	1147: vr23 (vr23), unsigned 128 bits
+	1148: vr24 (vr24), unsigned 128 bits
+	1149: vr25 (vr25), unsigned 128 bits
+	1150: vr26 (vr26), unsigned 128 bits
+	1151: vr27 (vr27), unsigned 128 bits
+	1152: vr28 (vr28), unsigned 128 bits
+	1153: vr29 (vr29), unsigned 128 bits
+	1154: vr30 (vr30), unsigned 128 bits
+	1155: vr31 (vr31), unsigned 128 bits
+EOF
+
+regs_test testfile26 <<\EOF
+integer registers:
+	  0: %r0 (r0), signed 32 bits
+	  1: %r1 (r1), signed 32 bits
+	  2: %r2 (r2), signed 32 bits
+	  3: %r3 (r3), signed 32 bits
+	  4: %r4 (r4), signed 32 bits
+	  5: %r5 (r5), signed 32 bits
+	  6: %r6 (r6), signed 32 bits
+	  7: %r7 (r7), signed 32 bits
+	  8: %r8 (r8), signed 32 bits
+	  9: %r9 (r9), signed 32 bits
+	 10: %r10 (r10), signed 32 bits
+	 11: %r11 (r11), signed 32 bits
+	 12: %r12 (r12), signed 32 bits
+	 13: %r13 (r13), signed 32 bits
+	 14: %r14 (r14), signed 32 bits
+	 15: %r15 (r15), signed 32 bits
+FPU registers:
+	 16: %f0 (f0), float 64 bits
+	 17: %f2 (f2), float 64 bits
+	 18: %f4 (f4), float 64 bits
+	 19: %f6 (f6), float 64 bits
+	 20: %f1 (f1), float 64 bits
+	 21: %f3 (f3), float 64 bits
+	 22: %f5 (f5), float 64 bits
+	 23: %f7 (f7), float 64 bits
+	 24: %f8 (f8), float 64 bits
+	 25: %f10 (f10), float 64 bits
+	 26: %f12 (f12), float 64 bits
+	 27: %f14 (f14), float 64 bits
+	 28: %f9 (f9), float 64 bits
+	 29: %f11 (f11), float 64 bits
+	 30: %f13 (f13), float 64 bits
+	 31: %f15 (f15), float 64 bits
+access registers:
+	 48: %a0 (a0), unsigned 32 bits
+	 49: %a1 (a1), unsigned 32 bits
+	 50: %a2 (a2), unsigned 32 bits
+	 51: %a3 (a3), unsigned 32 bits
+	 52: %a4 (a4), unsigned 32 bits
+	 53: %a5 (a5), unsigned 32 bits
+	 54: %a6 (a6), unsigned 32 bits
+	 55: %a7 (a7), unsigned 32 bits
+	 56: %a8 (a8), unsigned 32 bits
+	 57: %a9 (a9), unsigned 32 bits
+	 58: %a10 (a10), unsigned 32 bits
+	 59: %a11 (a11), unsigned 32 bits
+	 60: %a12 (a12), unsigned 32 bits
+	 61: %a13 (a13), unsigned 32 bits
+	 62: %a14 (a14), unsigned 32 bits
+	 63: %a15 (a15), unsigned 32 bits
+control registers:
+	 32: %c0 (c0), unsigned 32 bits
+	 33: %c1 (c1), unsigned 32 bits
+	 34: %c2 (c2), unsigned 32 bits
+	 35: %c3 (c3), unsigned 32 bits
+	 36: %c4 (c4), unsigned 32 bits
+	 37: %c5 (c5), unsigned 32 bits
+	 38: %c6 (c6), unsigned 32 bits
+	 39: %c7 (c7), unsigned 32 bits
+	 40: %c8 (c8), unsigned 32 bits
+	 41: %c9 (c9), unsigned 32 bits
+	 42: %c10 (c10), unsigned 32 bits
+	 43: %c11 (c11), unsigned 32 bits
+	 44: %c12 (c12), unsigned 32 bits
+	 45: %c13 (c13), unsigned 32 bits
+	 46: %c14 (c14), unsigned 32 bits
+	 47: %c15 (c15), unsigned 32 bits
+	 64: %pswm (pswm), unsigned 32 bits
+	 65: %pswa (pswa), address 32 bits
+EOF
+
+regs_test testfile27 <<\EOF
+integer registers:
+	  0: %r0 (r0), signed 64 bits
+	  1: %r1 (r1), signed 64 bits
+	  2: %r2 (r2), signed 64 bits
+	  3: %r3 (r3), signed 64 bits
+	  4: %r4 (r4), signed 64 bits
+	  5: %r5 (r5), signed 64 bits
+	  6: %r6 (r6), signed 64 bits
+	  7: %r7 (r7), signed 64 bits
+	  8: %r8 (r8), signed 64 bits
+	  9: %r9 (r9), signed 64 bits
+	 10: %r10 (r10), signed 64 bits
+	 11: %r11 (r11), signed 64 bits
+	 12: %r12 (r12), signed 64 bits
+	 13: %r13 (r13), signed 64 bits
+	 14: %r14 (r14), signed 64 bits
+	 15: %r15 (r15), signed 64 bits
+FPU registers:
+	 16: %f0 (f0), float 64 bits
+	 17: %f2 (f2), float 64 bits
+	 18: %f4 (f4), float 64 bits
+	 19: %f6 (f6), float 64 bits
+	 20: %f1 (f1), float 64 bits
+	 21: %f3 (f3), float 64 bits
+	 22: %f5 (f5), float 64 bits
+	 23: %f7 (f7), float 64 bits
+	 24: %f8 (f8), float 64 bits
+	 25: %f10 (f10), float 64 bits
+	 26: %f12 (f12), float 64 bits
+	 27: %f14 (f14), float 64 bits
+	 28: %f9 (f9), float 64 bits
+	 29: %f11 (f11), float 64 bits
+	 30: %f13 (f13), float 64 bits
+	 31: %f15 (f15), float 64 bits
+access registers:
+	 48: %a0 (a0), unsigned 32 bits
+	 49: %a1 (a1), unsigned 32 bits
+	 50: %a2 (a2), unsigned 32 bits
+	 51: %a3 (a3), unsigned 32 bits
+	 52: %a4 (a4), unsigned 32 bits
+	 53: %a5 (a5), unsigned 32 bits
+	 54: %a6 (a6), unsigned 32 bits
+	 55: %a7 (a7), unsigned 32 bits
+	 56: %a8 (a8), unsigned 32 bits
+	 57: %a9 (a9), unsigned 32 bits
+	 58: %a10 (a10), unsigned 32 bits
+	 59: %a11 (a11), unsigned 32 bits
+	 60: %a12 (a12), unsigned 32 bits
+	 61: %a13 (a13), unsigned 32 bits
+	 62: %a14 (a14), unsigned 32 bits
+	 63: %a15 (a15), unsigned 32 bits
+control registers:
+	 32: %c0 (c0), unsigned 64 bits
+	 33: %c1 (c1), unsigned 64 bits
+	 34: %c2 (c2), unsigned 64 bits
+	 35: %c3 (c3), unsigned 64 bits
+	 36: %c4 (c4), unsigned 64 bits
+	 37: %c5 (c5), unsigned 64 bits
+	 38: %c6 (c6), unsigned 64 bits
+	 39: %c7 (c7), unsigned 64 bits
+	 40: %c8 (c8), unsigned 64 bits
+	 41: %c9 (c9), unsigned 64 bits
+	 42: %c10 (c10), unsigned 64 bits
+	 43: %c11 (c11), unsigned 64 bits
+	 44: %c12 (c12), unsigned 64 bits
+	 45: %c13 (c13), unsigned 64 bits
+	 46: %c14 (c14), unsigned 64 bits
+	 47: %c15 (c15), unsigned 64 bits
+	 64: %pswm (pswm), unsigned 64 bits
+	 65: %pswa (pswa), address 64 bits
+EOF
+
+regs_test testfile30 <<\EOF
+integer registers:
+	  0: %g0 (g0), signed 32 bits
+	  1: %g1 (g1), signed 32 bits
+	  2: %g2 (g2), signed 32 bits
+	  3: %g3 (g3), signed 32 bits
+	  4: %g4 (g4), signed 32 bits
+	  5: %g5 (g5), signed 32 bits
+	  6: %g6 (g6), signed 32 bits
+	  7: %g7 (g7), signed 32 bits
+	  8: %o0 (o0), signed 32 bits
+	  9: %o1 (o1), signed 32 bits
+	 10: %o2 (o2), signed 32 bits
+	 11: %o3 (o3), signed 32 bits
+	 12: %o4 (o4), signed 32 bits
+	 13: %o5 (o5), signed 32 bits
+	 14: %o6 (o6), address 32 bits
+	 15: %o7 (o7), signed 32 bits
+	 16: %l0 (l0), signed 32 bits
+	 17: %l1 (l1), signed 32 bits
+	 18: %l2 (l2), signed 32 bits
+	 19: %l3 (l3), signed 32 bits
+	 20: %l4 (l4), signed 32 bits
+	 21: %l5 (l5), signed 32 bits
+	 22: %l6 (l6), signed 32 bits
+	 23: %l7 (l7), signed 32 bits
+	 24: %i0 (i0), signed 32 bits
+	 25: %i1 (i1), signed 32 bits
+	 26: %i2 (i2), signed 32 bits
+	 27: %i3 (i3), signed 32 bits
+	 28: %i4 (i4), signed 32 bits
+	 29: %i5 (i5), signed 32 bits
+	 30: %i6 (i6), address 32 bits
+	 31: %i7 (i7), signed 32 bits
+FPU registers:
+	 32: %f0 (f0), float 32 bits
+	 33: %f1 (f1), float 32 bits
+	 34: %f2 (f2), float 32 bits
+	 35: %f3 (f3), float 32 bits
+	 36: %f4 (f4), float 32 bits
+	 37: %f5 (f5), float 32 bits
+	 38: %f6 (f6), float 32 bits
+	 39: %f7 (f7), float 32 bits
+	 40: %f8 (f8), float 32 bits
+	 41: %f9 (f9), float 32 bits
+	 42: %f10 (f10), float 32 bits
+	 43: %f11 (f11), float 32 bits
+	 44: %f12 (f12), float 32 bits
+	 45: %f13 (f13), float 32 bits
+	 46: %f14 (f14), float 32 bits
+	 47: %f15 (f15), float 32 bits
+	 48: %f16 (f16), float 32 bits
+	 49: %f17 (f17), float 32 bits
+	 50: %f18 (f18), float 32 bits
+	 51: %f19 (f19), float 32 bits
+	 52: %f20 (f20), float 32 bits
+	 53: %f21 (f21), float 32 bits
+	 54: %f22 (f22), float 32 bits
+	 55: %f23 (f23), float 32 bits
+	 56: %f24 (f24), float 32 bits
+	 57: %f25 (f25), float 32 bits
+	 58: %f26 (f26), float 32 bits
+	 59: %f27 (f27), float 32 bits
+	 60: %f28 (f28), float 32 bits
+	 61: %f29 (f29), float 32 bits
+	 62: %f30 (f30), float 32 bits
+	 63: %f31 (f31), float 32 bits
+control registers:
+	 64: %y (y), unsigned 32 bits
+	 65: %psr (psr), unsigned 32 bits
+	 66: %wim (wim), unsigned 32 bits
+	 67: %tbr (tbr), unsigned 32 bits
+	 68: %pc (pc), address 32 bits
+	 69: %npc (npc), address 32 bits
+	 70: %fsr (fsr), unsigned 32 bits
+	 71: %csr (csr), unsigned 32 bits
+EOF
+
+regs_test testfile31 <<\EOF
+integer registers:
+	  0: %g0 (g0), signed 64 bits
+	  1: %g1 (g1), signed 64 bits
+	  2: %g2 (g2), signed 64 bits
+	  3: %g3 (g3), signed 64 bits
+	  4: %g4 (g4), signed 64 bits
+	  5: %g5 (g5), signed 64 bits
+	  6: %g6 (g6), signed 64 bits
+	  7: %g7 (g7), signed 64 bits
+	  8: %o0 (o0), signed 64 bits
+	  9: %o1 (o1), signed 64 bits
+	 10: %o2 (o2), signed 64 bits
+	 11: %o3 (o3), signed 64 bits
+	 12: %o4 (o4), signed 64 bits
+	 13: %o5 (o5), signed 64 bits
+	 14: %o6 (o6), address 64 bits
+	 15: %o7 (o7), signed 64 bits
+	 16: %l0 (l0), signed 64 bits
+	 17: %l1 (l1), signed 64 bits
+	 18: %l2 (l2), signed 64 bits
+	 19: %l3 (l3), signed 64 bits
+	 20: %l4 (l4), signed 64 bits
+	 21: %l5 (l5), signed 64 bits
+	 22: %l6 (l6), signed 64 bits
+	 23: %l7 (l7), signed 64 bits
+	 24: %i0 (i0), signed 64 bits
+	 25: %i1 (i1), signed 64 bits
+	 26: %i2 (i2), signed 64 bits
+	 27: %i3 (i3), signed 64 bits
+	 28: %i4 (i4), signed 64 bits
+	 29: %i5 (i5), signed 64 bits
+	 30: %i6 (i6), address 64 bits
+	 31: %i7 (i7), signed 64 bits
+FPU registers:
+	 32: %f0 (f0), float 32 bits
+	 33: %f1 (f1), float 32 bits
+	 34: %f2 (f2), float 32 bits
+	 35: %f3 (f3), float 32 bits
+	 36: %f4 (f4), float 32 bits
+	 37: %f5 (f5), float 32 bits
+	 38: %f6 (f6), float 32 bits
+	 39: %f7 (f7), float 32 bits
+	 40: %f8 (f8), float 32 bits
+	 41: %f9 (f9), float 32 bits
+	 42: %f10 (f10), float 32 bits
+	 43: %f11 (f11), float 32 bits
+	 44: %f12 (f12), float 32 bits
+	 45: %f13 (f13), float 32 bits
+	 46: %f14 (f14), float 32 bits
+	 47: %f15 (f15), float 32 bits
+	 48: %f16 (f16), float 32 bits
+	 49: %f17 (f17), float 32 bits
+	 50: %f18 (f18), float 32 bits
+	 51: %f19 (f19), float 32 bits
+	 52: %f20 (f20), float 32 bits
+	 53: %f21 (f21), float 32 bits
+	 54: %f22 (f22), float 32 bits
+	 55: %f23 (f23), float 32 bits
+	 56: %f24 (f24), float 32 bits
+	 57: %f25 (f25), float 32 bits
+	 58: %f26 (f26), float 32 bits
+	 59: %f27 (f27), float 32 bits
+	 60: %f28 (f28), float 32 bits
+	 61: %f29 (f29), float 32 bits
+	 62: %f30 (f30), float 32 bits
+	 63: %f31 (f31), float 32 bits
+	 64: %f32 (f32), float 64 bits
+	 65: %f34 (f34), float 64 bits
+	 66: %f36 (f36), float 64 bits
+	 67: %f38 (f38), float 64 bits
+	 68: %f40 (f40), float 64 bits
+	 69: %f42 (f42), float 64 bits
+	 70: %f44 (f44), float 64 bits
+	 71: %f46 (f46), float 64 bits
+	 72: %f48 (f48), float 64 bits
+	 73: %f50 (f50), float 64 bits
+	 74: %f52 (f52), float 64 bits
+	 75: %f54 (f54), float 64 bits
+	 76: %f56 (f56), float 64 bits
+	 77: %f58 (f58), float 64 bits
+	 78: %f60 (f60), float 64 bits
+	 79: %f62 (f62), float 64 bits
+control registers:
+	 80: %pc (pc), address 64 bits
+	 81: %npc (npc), address 64 bits
+	 82: %state (state), unsigned 64 bits
+	 83: %fsr (fsr), unsigned 64 bits
+	 84: %fprs (fprs), unsigned 64 bits
+	 85: %y (y), unsigned 64 bits
+EOF
+
+regs_test testfile10 <<\EOF
+integer registers:
+	  0: $v0 (v0), signed 64 bits
+	  1: $t0 (t0), signed 64 bits
+	  2: $t1 (t1), signed 64 bits
+	  3: $t2 (t2), signed 64 bits
+	  4: $t3 (t3), signed 64 bits
+	  5: $t4 (t4), signed 64 bits
+	  6: $t5 (t5), signed 64 bits
+	  7: $t6 (t6), signed 64 bits
+	  8: $t7 (t7), signed 64 bits
+	  9: $s0 (s0), signed 64 bits
+	 10: $s1 (s1), signed 64 bits
+	 11: $s2 (s2), signed 64 bits
+	 12: $s3 (s3), signed 64 bits
+	 13: $s4 (s4), signed 64 bits
+	 14: $s5 (s5), signed 64 bits
+	 15: $s6 (s6), signed 64 bits
+	 16: $a0 (a0), signed 64 bits
+	 17: $a1 (a1), signed 64 bits
+	 18: $a2 (a2), signed 64 bits
+	 19: $a3 (a3), signed 64 bits
+	 20: $a4 (a4), signed 64 bits
+	 21: $a5 (a5), signed 64 bits
+	 22: $t8 (t8), signed 64 bits
+	 23: $t9 (t9), signed 64 bits
+	 24: $t10 (t10), signed 64 bits
+	 25: $t11 (t11), signed 64 bits
+	 26: $ra (ra), address 64 bits
+	 27: $t12 (t12), signed 64 bits
+	 28: $at (at), signed 64 bits
+	 29: $gp (gp), address 64 bits
+	 30: $sp (sp), address 64 bits
+	 31: $zero (zero), signed 64 bits
+	 64: $pc (pc), address 64 bits
+	 66: $unique (unique), address 64 bits
+FPU registers:
+	 32: $f0 (f0), float 64 bits
+	 33: $f1 (f1), float 64 bits
+	 34: $f2 (f2), float 64 bits
+	 35: $f3 (f3), float 64 bits
+	 36: $f4 (f4), float 64 bits
+	 37: $f5 (f5), float 64 bits
+	 38: $f6 (f6), float 64 bits
+	 39: $f7 (f7), float 64 bits
+	 40: $f8 (f8), float 64 bits
+	 41: $f9 (f9), float 64 bits
+	 42: $f10 (f10), float 64 bits
+	 43: $f11 (f11), float 64 bits
+	 44: $f12 (f12), float 64 bits
+	 45: $f13 (f13), float 64 bits
+	 46: $f14 (f14), float 64 bits
+	 47: $f15 (f15), float 64 bits
+	 48: $f16 (f16), float 64 bits
+	 49: $f17 (f17), float 64 bits
+	 50: $f18 (f18), float 64 bits
+	 51: $f19 (f19), float 64 bits
+	 52: $f20 (f20), float 64 bits
+	 53: $f21 (f21), float 64 bits
+	 54: $f22 (f22), float 64 bits
+	 55: $f23 (f23), float 64 bits
+	 56: $f24 (f24), float 64 bits
+	 57: $f25 (f25), float 64 bits
+	 58: $f26 (f26), float 64 bits
+	 59: $f27 (f27), float 64 bits
+	 60: $f28 (f28), float 64 bits
+	 61: $f29 (f29), float 64 bits
+	 62: $f30 (f30), float 64 bits
+	 63: $fpcr (fpcr), unsigned 64 bits
+EOF
+
+regs_test testfile60 <<\EOF
+integer registers:
+	  0: r0 (r0), signed 64 bits
+	  1: r1 (r1), signed 64 bits
+	  2: r2 (r2), signed 64 bits
+	  3: r3 (r3), signed 64 bits
+	  4: r4 (r4), signed 64 bits
+	  5: r5 (r5), signed 64 bits
+	  6: r6 (r6), signed 64 bits
+	  7: r7 (r7), signed 64 bits
+	  8: r8 (r8), signed 64 bits
+	  9: r9 (r9), signed 64 bits
+	 10: r10 (r10), signed 64 bits
+	 11: r11 (r11), signed 64 bits
+	 12: r12 (r12), signed 64 bits
+	 13: r13 (r13), signed 64 bits
+	 14: r14 (r14), signed 64 bits
+	 15: r15 (r15), signed 64 bits
+	 16: r16 (r16), signed 64 bits
+	 17: r17 (r17), signed 64 bits
+	 18: r18 (r18), signed 64 bits
+	 19: r19 (r19), signed 64 bits
+	 20: r20 (r20), signed 64 bits
+	 21: r21 (r21), signed 64 bits
+	 22: r22 (r22), signed 64 bits
+	 23: r23 (r23), signed 64 bits
+	 24: r24 (r24), signed 64 bits
+	 25: r25 (r25), signed 64 bits
+	 26: r26 (r26), signed 64 bits
+	 27: r27 (r27), signed 64 bits
+	 28: r28 (r28), signed 64 bits
+	 29: r29 (r29), signed 64 bits
+	 30: r30 (r30), signed 64 bits
+	 31: r31 (r31), signed 64 bits
+	 32: r32 (r32), signed 64 bits
+	 33: r33 (r33), signed 64 bits
+	 34: r34 (r34), signed 64 bits
+	 35: r35 (r35), signed 64 bits
+	 36: r36 (r36), signed 64 bits
+	 37: r37 (r37), signed 64 bits
+	 38: r38 (r38), signed 64 bits
+	 39: r39 (r39), signed 64 bits
+	 40: r40 (r40), signed 64 bits
+	 41: r41 (r41), signed 64 bits
+	 42: r42 (r42), signed 64 bits
+	 43: r43 (r43), signed 64 bits
+	 44: r44 (r44), signed 64 bits
+	 45: r45 (r45), signed 64 bits
+	 46: r46 (r46), signed 64 bits
+	 47: r47 (r47), signed 64 bits
+	 48: r48 (r48), signed 64 bits
+	 49: r49 (r49), signed 64 bits
+	 50: r50 (r50), signed 64 bits
+	 51: r51 (r51), signed 64 bits
+	 52: r52 (r52), signed 64 bits
+	 53: tp (tp), address 64 bits
+	 54: sp (sp), address 64 bits
+	 55: lr (lr), address 64 bits
+	 56: sn (sn), unsigned 64 bits
+	 57: idn0 (idn0), unsigned 64 bits
+	 58: idn1 (idn1), unsigned 64 bits
+	 59: udn0 (udn0), unsigned 64 bits
+	 60: udn1 (udn1), unsigned 64 bits
+	 61: udn2 (udn2), unsigned 64 bits
+	 62: udn3 (udn3), unsigned 64 bits
+	 63: zero (zero), unsigned 64 bits
+	 64: pc (pc), address 64 bits
+EOF
+
+regs_test testfile61 <<\EOF
+integer registers:
+	  0: r0 (r0), signed 32 bits
+	  1: r1 (r1), signed 32 bits
+	  2: r2 (r2), signed 32 bits
+	  3: r3 (r3), signed 32 bits
+	  4: r4 (r4), signed 32 bits
+	  5: r5 (r5), signed 32 bits
+	  6: r6 (r6), signed 32 bits
+	  7: r7 (r7), signed 32 bits
+	  8: r8 (r8), signed 32 bits
+	  9: r9 (r9), signed 32 bits
+	 10: r10 (r10), signed 32 bits
+	 11: r11 (r11), signed 32 bits
+	 12: r12 (r12), signed 32 bits
+	 13: sp (sp), address 32 bits
+	 14: lr (lr), address 32 bits
+	 15: pc (pc), address 32 bits
+	128: spsr (spsr), unsigned 32 bits
+FPA registers:
+	 16: f0 (f0), float 96 bits
+	 17: f1 (f1), float 96 bits
+	 18: f2 (f2), float 96 bits
+	 19: f3 (f3), float 96 bits
+	 20: f4 (f4), float 96 bits
+	 21: f5 (f5), float 96 bits
+	 22: f6 (f6), float 96 bits
+	 23: f7 (f7), float 96 bits
+	 96: f0 (f0), float 96 bits
+	 97: f1 (f1), float 96 bits
+	 98: f2 (f2), float 96 bits
+	 99: f3 (f3), float 96 bits
+	100: f4 (f4), float 96 bits
+	101: f5 (f5), float 96 bits
+	102: f6 (f6), float 96 bits
+	103: f7 (f7), float 96 bits
+VFP registers:
+	256: d0 (d0), float 64 bits
+	257: d1 (d1), float 64 bits
+	258: d2 (d2), float 64 bits
+	259: d3 (d3), float 64 bits
+	260: d4 (d4), float 64 bits
+	261: d5 (d5), float 64 bits
+	262: d6 (d6), float 64 bits
+	263: d7 (d7), float 64 bits
+	264: d8 (d8), float 64 bits
+	265: d9 (d9), float 64 bits
+	266: d10 (d10), float 64 bits
+	267: d11 (d11), float 64 bits
+	268: d12 (d12), float 64 bits
+	269: d13 (d13), float 64 bits
+	270: d14 (d14), float 64 bits
+	271: d15 (d15), float 64 bits
+	272: d16 (d16), float 64 bits
+	273: d17 (d17), float 64 bits
+	274: d18 (d18), float 64 bits
+	275: d19 (d19), float 64 bits
+	276: d20 (d20), float 64 bits
+	277: d21 (d21), float 64 bits
+	278: d22 (d22), float 64 bits
+	279: d23 (d23), float 64 bits
+	280: d24 (d24), float 64 bits
+	281: d25 (d25), float 64 bits
+	282: d26 (d26), float 64 bits
+	283: d27 (d27), float 64 bits
+	284: d28 (d28), float 64 bits
+	285: d29 (d29), float 64 bits
+	286: d30 (d30), float 64 bits
+	287: d31 (d31), float 64 bits
+EOF
+
+# See run-readelf-mixed-corenote.sh for instructions to regenerate
+# this core file.
+regs_test testfile_aarch64_core <<\EOF
+integer registers:
+	  0: x0 (x0), signed 64 bits
+	  1: x1 (x1), signed 64 bits
+	  2: x2 (x2), signed 64 bits
+	  3: x3 (x3), signed 64 bits
+	  4: x4 (x4), signed 64 bits
+	  5: x5 (x5), signed 64 bits
+	  6: x6 (x6), signed 64 bits
+	  7: x7 (x7), signed 64 bits
+	  8: x8 (x8), signed 64 bits
+	  9: x9 (x9), signed 64 bits
+	 10: x10 (x10), signed 64 bits
+	 11: x11 (x11), signed 64 bits
+	 12: x12 (x12), signed 64 bits
+	 13: x13 (x13), signed 64 bits
+	 14: x14 (x14), signed 64 bits
+	 15: x15 (x15), signed 64 bits
+	 16: x16 (x16), signed 64 bits
+	 17: x17 (x17), signed 64 bits
+	 18: x18 (x18), signed 64 bits
+	 19: x19 (x19), signed 64 bits
+	 20: x20 (x20), signed 64 bits
+	 21: x21 (x21), signed 64 bits
+	 22: x22 (x22), signed 64 bits
+	 23: x23 (x23), signed 64 bits
+	 24: x24 (x24), signed 64 bits
+	 25: x25 (x25), signed 64 bits
+	 26: x26 (x26), signed 64 bits
+	 27: x27 (x27), signed 64 bits
+	 28: x28 (x28), signed 64 bits
+	 29: x29 (x29), signed 64 bits
+	 30: x30 (x30), signed 64 bits
+	 31: sp (sp), address 64 bits
+	 33: elr (elr), address 64 bits
+FP/SIMD registers:
+	 64: v0 (v0), unsigned 128 bits
+	 65: v1 (v1), unsigned 128 bits
+	 66: v2 (v2), unsigned 128 bits
+	 67: v3 (v3), unsigned 128 bits
+	 68: v4 (v4), unsigned 128 bits
+	 69: v5 (v5), unsigned 128 bits
+	 70: v6 (v6), unsigned 128 bits
+	 71: v7 (v7), unsigned 128 bits
+	 72: v8 (v8), unsigned 128 bits
+	 73: v9 (v9), unsigned 128 bits
+	 74: v10 (v10), unsigned 128 bits
+	 75: v11 (v11), unsigned 128 bits
+	 76: v12 (v12), unsigned 128 bits
+	 77: v13 (v13), unsigned 128 bits
+	 78: v14 (v14), unsigned 128 bits
+	 79: v15 (v15), unsigned 128 bits
+	 80: v16 (v16), unsigned 128 bits
+	 81: v17 (v17), unsigned 128 bits
+	 82: v18 (v18), unsigned 128 bits
+	 83: v19 (v19), unsigned 128 bits
+	 84: v20 (v20), unsigned 128 bits
+	 85: v21 (v21), unsigned 128 bits
+	 86: v22 (v22), unsigned 128 bits
+	 87: v23 (v23), unsigned 128 bits
+	 88: v24 (v24), unsigned 128 bits
+	 89: v25 (v25), unsigned 128 bits
+	 90: v26 (v26), unsigned 128 bits
+	 91: v27 (v27), unsigned 128 bits
+	 92: v28 (v28), unsigned 128 bits
+	 93: v29 (v29), unsigned 128 bits
+	 94: v30 (v30), unsigned 128 bits
+	 95: v31 (v31), unsigned 128 bits
+EOF
+
+# See run-readelf-mixed-corenote.sh for instructions to regenerate
+# this core file.
+regs_test testfile-x32-core <<\EOF
+integer registers:
+	  0: %rax (rax), signed 64 bits
+	  1: %rdx (rdx), signed 64 bits
+	  2: %rcx (rcx), signed 64 bits
+	  3: %rbx (rbx), signed 64 bits
+	  4: %rsi (rsi), signed 64 bits
+	  5: %rdi (rdi), signed 64 bits
+	  6: %rbp (rbp), address 64 bits
+	  7: %rsp (rsp), address 64 bits
+	  8: %r8 (r8), signed 64 bits
+	  9: %r9 (r9), signed 64 bits
+	 10: %r10 (r10), signed 64 bits
+	 11: %r11 (r11), signed 64 bits
+	 12: %r12 (r12), signed 64 bits
+	 13: %r13 (r13), signed 64 bits
+	 14: %r14 (r14), signed 64 bits
+	 15: %r15 (r15), signed 64 bits
+	 16: %rip (rip), address 64 bits
+	 49: %rflags (rflags), unsigned 64 bits
+MMX registers:
+	 41: %mm0 (mm0), unsigned 64 bits
+	 42: %mm1 (mm1), unsigned 64 bits
+	 43: %mm2 (mm2), unsigned 64 bits
+	 44: %mm3 (mm3), unsigned 64 bits
+	 45: %mm4 (mm4), unsigned 64 bits
+	 46: %mm5 (mm5), unsigned 64 bits
+	 47: %mm6 (mm6), unsigned 64 bits
+	 48: %mm7 (mm7), unsigned 64 bits
+SSE registers:
+	 17: %xmm0 (xmm0), unsigned 128 bits
+	 18: %xmm1 (xmm1), unsigned 128 bits
+	 19: %xmm2 (xmm2), unsigned 128 bits
+	 20: %xmm3 (xmm3), unsigned 128 bits
+	 21: %xmm4 (xmm4), unsigned 128 bits
+	 22: %xmm5 (xmm5), unsigned 128 bits
+	 23: %xmm6 (xmm6), unsigned 128 bits
+	 24: %xmm7 (xmm7), unsigned 128 bits
+	 25: %xmm8 (xmm8), unsigned 128 bits
+	 26: %xmm9 (xmm9), unsigned 128 bits
+	 27: %xmm10 (xmm10), unsigned 128 bits
+	 28: %xmm11 (xmm11), unsigned 128 bits
+	 29: %xmm12 (xmm12), unsigned 128 bits
+	 30: %xmm13 (xmm13), unsigned 128 bits
+	 31: %xmm14 (xmm14), unsigned 128 bits
+	 32: %xmm15 (xmm15), unsigned 128 bits
+control registers:
+	 62: %tr (tr), unsigned 64 bits
+	 63: %ldtr (ldtr), unsigned 64 bits
+	 64: %mxcsr (mxcsr), unsigned 64 bits
+	 65: %fcw (fcw), unsigned 16 bits
+	 66: %fsw (fsw), unsigned 16 bits
+segment registers:
+	 50: %es (es), unsigned 16 bits
+	 51: %cs (cs), unsigned 16 bits
+	 52: %ss (ss), unsigned 16 bits
+	 53: %ds (ds), unsigned 16 bits
+	 54: %fs (fs), unsigned 16 bits
+	 55: %gs (gs), unsigned 16 bits
+	 58: %fs.base (fs.base), address 64 bits
+	 59: %gs.base (gs.base), address 64 bits
+x87 registers:
+	 33: %st0 (st0), float 80 bits
+	 34: %st1 (st1), float 80 bits
+	 35: %st2 (st2), float 80 bits
+	 36: %st3 (st3), float 80 bits
+	 37: %st4 (st4), float 80 bits
+	 38: %st5 (st5), float 80 bits
+	 39: %st6 (st6), float 80 bits
+	 40: %st7 (st7), float 80 bits
+EOF
+
+# See run-readelf-mixed-corenote.sh for instructions to regenerate
+# this core file.
+regs_test testfile-m68k-core <<\EOF
+integer registers:
+	  0: %d0 (d0), signed 32 bits
+	  1: %d1 (d1), signed 32 bits
+	  2: %d2 (d2), signed 32 bits
+	  3: %d3 (d3), signed 32 bits
+	  4: %d4 (d4), signed 32 bits
+	  5: %d5 (d5), signed 32 bits
+	  6: %d6 (d6), signed 32 bits
+	  7: %d7 (d7), signed 32 bits
+	  8: %a0 (a0), address 32 bits
+	  9: %a1 (a1), address 32 bits
+	 10: %a2 (a2), address 32 bits
+	 11: %a3 (a3), address 32 bits
+	 12: %a4 (a4), address 32 bits
+	 13: %a5 (a5), address 32 bits
+	 14: %a6 (a6), address 32 bits
+	 15: %a7 (a7), address 32 bits
+	 24: %pc (pc), address 32 bits
+FPU registers:
+	 16: %fp0 (fp0), float 96 bits
+	 17: %fp1 (fp1), float 96 bits
+	 18: %fp2 (fp2), float 96 bits
+	 19: %fp3 (fp3), float 96 bits
+	 20: %fp4 (fp4), float 96 bits
+	 21: %fp5 (fp5), float 96 bits
+	 22: %fp6 (fp6), float 96 bits
+	 23: %fp7 (fp7), float 96 bits
+EOF
+exit 0
diff --git a/third_party/elfutils/tests/run-ar.sh b/third_party/elfutils/tests/run-ar.sh
new file mode 100755
index 0000000..fb9394d
--- /dev/null
+++ b/third_party/elfutils/tests/run-ar.sh
@@ -0,0 +1,40 @@
+#! /bin/bash
+# Copyright (C) 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+tempfiles objects.list test.ar
+
+echo Make a sorted list of the just build src .o files.
+(cd ${abs_top_builddir}/src; ls *.o | sort) > objects.list
+cat objects.list
+
+echo Create a new ar file with the .o files.
+testrun ${abs_top_builddir}/src/ar -r test.ar \
+	$(echo ${abs_top_builddir}/src/*.o | sort)
+
+echo List the ar file contents.
+testrun_compare ${abs_top_builddir}/src/ar -t test.ar < objects.list
+
+echo Delete all objects again.
+testrun ${abs_top_builddir}/src/ar -d test.ar $(cat objects.list)
+
+echo Check new ar file is now empty
+testrun_compare ${abs_top_builddir}/src/ar -t test.ar << EOF
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-arextract.sh b/third_party/elfutils/tests/run-arextract.sh
new file mode 100755
index 0000000..44f4a52
--- /dev/null
+++ b/third_party/elfutils/tests/run-arextract.sh
@@ -0,0 +1,40 @@
+#! /bin/sh
+# Copyright (C) 1999, 2000, 2002, 2005, 2006 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+tempfiles arextract.test
+
+archive=${abs_top_builddir}/libelf/libelf.a
+if test -f $archive; then
+    # The file is really available (i.e., no shared-only built).
+    echo -n "Extracting symbols... $ac_c"
+
+    # The files we are looking at.
+    for f in ${abs_top_builddir}/libelf/*.o; do
+	testrun ${abs_builddir}/arextract $archive `basename $f` arextract.test || exit 1
+	cmp $f arextract.test || {
+	    echo "Extraction of $1 failed"
+	    exit 1
+	}
+    done
+
+    echo "done"
+fi
+
+exit 0
diff --git a/third_party/elfutils/tests/run-arsymtest.sh b/third_party/elfutils/tests/run-arsymtest.sh
new file mode 100755
index 0000000..b0fdfcd
--- /dev/null
+++ b/third_party/elfutils/tests/run-arsymtest.sh
@@ -0,0 +1,47 @@
+#! /bin/sh
+# Copyright (C) 1999, 2000, 2002, 2006 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+lib=${abs_top_builddir}/libelf/libelf.a
+okfile=arsymtest.ok
+tmpfile=arsymtest.tmp
+testfile=arsymtest.test
+
+tempfiles $okfile $tmpfile $testfile
+
+result=77
+if test -f $lib; then
+    # Generate list using `nm' we check against.
+    ${NM} -s $lib |
+    sed -e '1,/^Arch/d' -e '/^$/,$d' |
+    sort > $okfile
+
+    # Now run our program using libelf.
+    testrun ${abs_builddir}/arsymtest $lib $tmpfile || exit 1
+    sort $tmpfile > $testfile
+
+    # Compare the outputs.
+    if cmp $okfile $testfile; then
+	result=0
+    else
+	result=1
+    fi
+fi
+
+exit $result
diff --git a/third_party/elfutils/tests/run-backtrace-core-aarch64.sh b/third_party/elfutils/tests/run-backtrace-core-aarch64.sh
new file mode 100755
index 0000000..a29a661
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-core-aarch64.sh
@@ -0,0 +1,23 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+# backtrace.aarch64.exe is a -static binary of backtrace-child.
+# backtrace.aarch64.core was generated by running the static backtrace-child
+# with --gencore.
+check_core aarch64
diff --git a/third_party/elfutils/tests/run-backtrace-core-i386.sh b/third_party/elfutils/tests/run-backtrace-core-i386.sh
new file mode 100755
index 0000000..7294ec3
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-core-i386.sh
@@ -0,0 +1,20 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+check_core i386
diff --git a/third_party/elfutils/tests/run-backtrace-core-ppc.sh b/third_party/elfutils/tests/run-backtrace-core-ppc.sh
new file mode 100755
index 0000000..555ac35
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-core-ppc.sh
@@ -0,0 +1,29 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+# executable generated by:
+#
+# gcc -D_GNU_SOURCE -I. -I.. -I../lib -m32 -pthread -static -g \
+#     -o backtrace.ppc.exec backtrace-child.c
+#
+# core generated by:
+#
+# ./backtrace.ppc.exec --gencore
+
+check_core ppc
diff --git a/third_party/elfutils/tests/run-backtrace-core-s390.sh b/third_party/elfutils/tests/run-backtrace-core-s390.sh
new file mode 100755
index 0000000..d3b6dc9
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-core-s390.sh
@@ -0,0 +1,20 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+check_core s390
diff --git a/third_party/elfutils/tests/run-backtrace-core-s390x.sh b/third_party/elfutils/tests/run-backtrace-core-s390x.sh
new file mode 100755
index 0000000..c3e236d
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-core-s390x.sh
@@ -0,0 +1,20 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+check_core s390x
diff --git a/third_party/elfutils/tests/run-backtrace-core-sparc.sh b/third_party/elfutils/tests/run-backtrace-core-sparc.sh
new file mode 100755
index 0000000..60399ba
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-core-sparc.sh
@@ -0,0 +1,20 @@
+#! /bin/bash
+# Copyright (C) 2015 Oracle, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+check_core sparc
diff --git a/third_party/elfutils/tests/run-backtrace-core-x32.sh b/third_party/elfutils/tests/run-backtrace-core-x32.sh
new file mode 100755
index 0000000..2ad76bc
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-core-x32.sh
@@ -0,0 +1,23 @@
+#! /bin/bash
+# Copyright (C) H.J. Lu <hjl.tools@gmail.com>, 2015.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+# backtrace.x32.exec is created by
+# gcc -mx32 -static -o backtrace.x32.exec backtrace_child-backtrace-child.o -lpthread
+# backtrace.x32.core was generated by running "backtrace.x32.exec --gencore"
+check_core x32
diff --git a/third_party/elfutils/tests/run-backtrace-core-x86_64.sh b/third_party/elfutils/tests/run-backtrace-core-x86_64.sh
new file mode 100755
index 0000000..d00cd6d
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-core-x86_64.sh
@@ -0,0 +1,20 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+check_core x86_64
diff --git a/third_party/elfutils/tests/run-backtrace-data.sh b/third_party/elfutils/tests/run-backtrace-data.sh
new file mode 100755
index 0000000..34a4f01
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-data.sh
@@ -0,0 +1,28 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+# This test really cannot be run under valgrind, it tries to introspect
+# its own maps and registers and will find valgrinds instead.
+unset VALGRIND_CMD
+
+tempfiles data.{bt,err}
+(set +ex; testrun ${abs_builddir}/backtrace-data 1>data.bt 2>data.err; true)
+cat data.{bt,err}
+check_unsupported data.err data
+check_all data.{bt,err} data
diff --git a/third_party/elfutils/tests/run-backtrace-demangle.sh b/third_party/elfutils/tests/run-backtrace-demangle.sh
new file mode 100755
index 0000000..2d25324
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-demangle.sh
@@ -0,0 +1,58 @@
+#! /bin/bash
+# Copyright (C) 2014, 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if test -n "$ELFUTILS_DISABLE_DEMANGLE"; then
+  echo "demangler unsupported"
+  exit 77
+fi
+
+. $srcdir/backtrace-subr.sh
+
+child=testfile-backtrace-demangle
+testfiles $child{,.core}
+tempfiles $child.{bt,err}
+
+# Disable valgrind while dumping because of a bug unmapping libc.so.
+# https://bugs.kde.org/show_bug.cgi?id=327427
+SAVED_VALGRIND_CMD="$VALGRIND_CMD"
+unset VALGRIND_CMD
+
+# There can be more than 3 frames, but depending on the system/installed
+# glibc we might not be able to unwind fully till the end.
+# cxxfunc -> f -> main
+# Expect to see the top two and a warning that there are more frames
+# (exit code 1)
+testrun ${abs_top_builddir}/src/stack -n 2 -e $child --core $child.core >$child.bt 2>$child.err || exitcode=$?
+cat $child.{bt,err}
+
+if [ "x$SAVED_VALGRIND_CMD" != "x" ]; then
+  VALGRIND_CMD="$SAVED_VALGRIND_CMD"
+  export VALGRIND_CMD
+fi
+
+if test $exitcode != 1 || ! grep "shown max number of frames" $child.err; then
+  echo >&2 $2: expected more than 2 frames
+  false
+fi
+if ! grep -w f $child.bt; then
+  echo >&2 $2: no f
+  false
+fi
+if ! grep ' cxxfunc(int)' $child.bt; then
+  echo >&2 $2: no cxxfunc
+  false
+fi
diff --git a/third_party/elfutils/tests/run-backtrace-dwarf.sh b/third_party/elfutils/tests/run-backtrace-dwarf.sh
new file mode 100755
index 0000000..8834048
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-dwarf.sh
@@ -0,0 +1,30 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+# This test really cannot be run under valgrind, it tries to introspect
+# itself through ptrace and will find bits and pieces of valgrind.
+# On top of that valgrind also tries to read all the unwind info and
+# will warn and complain about various opcodes it doesn't understand...
+unset VALGRIND_CMD
+
+tempfiles dwarf.{bt,err}
+(set +ex; testrun ${abs_builddir}/backtrace-dwarf 1>dwarf.bt 2>dwarf.err; true)
+cat dwarf.{bt,err}
+check_native_unsupported dwarf.err dwarf
+check_main dwarf.bt dwarf
diff --git a/third_party/elfutils/tests/run-backtrace-fp-core-aarch64.sh b/third_party/elfutils/tests/run-backtrace-fp-core-aarch64.sh
new file mode 100755
index 0000000..fda88d3
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-fp-core-aarch64.sh
@@ -0,0 +1,28 @@
+#! /bin/bash
+# Copyright (C) 2017 The Qt Company
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+# The binary is generated by compiling with eh_frame CFI, but with frame
+# pointers.
+#
+# gcc -static -O2 -fno-omit-frame-pointer -fno-asynchronous-unwind-tables \
+#     -D_GNU_SOURCE -pthread -o tests/backtrace.aarch64.fp.exec -I. -Ilib \
+#     tests/backtrace-child.c
+# The core is generated by calling the binary with --gencore
+
+check_core aarch64.fp
diff --git a/third_party/elfutils/tests/run-backtrace-fp-core-i386.sh b/third_party/elfutils/tests/run-backtrace-fp-core-i386.sh
new file mode 100755
index 0000000..c58ff53
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-fp-core-i386.sh
@@ -0,0 +1,29 @@
+#! /bin/bash
+# Copyright (C) 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+# The binary is generated by compiling backtrace-child without unwind
+# information, but with -fno-omit-frame-pointer.
+#
+# gcc -static -O2 -fno-omit-frame-pointer -fno-asynchronous-unwind-tables \
+#     -D_GNU_SOURCE -pthread -o tests/backtrace.i386.fp.exec -I. -Ilib \
+#     tests/backtrace-child.c
+#
+# The core is generated by calling tests/backtrace.i386.fp.exec --gencore
+
+check_core i386.fp
diff --git a/third_party/elfutils/tests/run-backtrace-fp-core-ppc64le.sh b/third_party/elfutils/tests/run-backtrace-fp-core-ppc64le.sh
new file mode 100755
index 0000000..326ca34
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-fp-core-ppc64le.sh
@@ -0,0 +1,29 @@
+#! /bin/bash
+# Copyright (C) 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+# The binary is generated by compiling backtrace-child without unwind
+# information, but with -fno-omit-frame-pointer.
+#
+# gcc -static -O2 -fno-omit-frame-pointer -fno-asynchronous-unwind-tables \
+#     -D_GNU_SOURCE -pthread -o tests/backtrace.ppc64le.fp.exec -I. -Ilib \
+#     tests/backtrace-child.c
+#
+# The core is generated by calling tests/backtrace.ppc64le.fp.exec --gencore
+
+check_core ppc64le.fp
diff --git a/third_party/elfutils/tests/run-backtrace-fp-core-x86_64.sh b/third_party/elfutils/tests/run-backtrace-fp-core-x86_64.sh
new file mode 100755
index 0000000..348eb18
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-fp-core-x86_64.sh
@@ -0,0 +1,29 @@
+#! /bin/bash
+# Copyright (C) 2017 The Qt Company
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+# The binary is generated by compiling with eh_frame CFI, but with frame
+# pointers.
+#
+# gcc -static -O2 -fno-omit-frame-pointer -fno-asynchronous-unwind-tables \
+#     -D_GNU_SOURCE -pthread -o tests/backtrace.x86_64.fp.exec -I. -Ilib \
+#     tests/backtrace-child.c
+#
+# The core is generated by calling the binary with --gencore
+
+check_core x86_64.fp
diff --git a/third_party/elfutils/tests/run-backtrace-native-biarch.sh b/third_party/elfutils/tests/run-backtrace-native-biarch.sh
new file mode 100755
index 0000000..2afe38a
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-native-biarch.sh
@@ -0,0 +1,25 @@
+#! /bin/bash
+# Copyright (C) 2013, 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if test -n "$ELFUTILS_DISABLE_BIARCH"; then
+  echo "biarch testing disabled"
+  exit 77
+fi
+
+. $srcdir/backtrace-subr.sh
+
+check_native backtrace-child-biarch
diff --git a/third_party/elfutils/tests/run-backtrace-native-core-biarch.sh b/third_party/elfutils/tests/run-backtrace-native-core-biarch.sh
new file mode 100755
index 0000000..02552ce
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-native-core-biarch.sh
@@ -0,0 +1,25 @@
+#! /bin/bash
+# Copyright (C) 2013, 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if test -n "$ELFUTILS_DISABLE_BIARCH"; then
+  echo "biarch testing disabled"
+  exit 77
+fi
+
+. $srcdir/backtrace-subr.sh
+
+check_native_core backtrace-child-biarch
diff --git a/third_party/elfutils/tests/run-backtrace-native-core.sh b/third_party/elfutils/tests/run-backtrace-native-core.sh
new file mode 100755
index 0000000..cb025a5
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-native-core.sh
@@ -0,0 +1,20 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+check_native_core backtrace-child
diff --git a/third_party/elfutils/tests/run-backtrace-native.sh b/third_party/elfutils/tests/run-backtrace-native.sh
new file mode 100755
index 0000000..ddae345
--- /dev/null
+++ b/third_party/elfutils/tests/run-backtrace-native.sh
@@ -0,0 +1,20 @@
+#! /bin/bash
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+check_native backtrace-child
diff --git a/third_party/elfutils/tests/run-bug1-test.sh b/third_party/elfutils/tests/run-bug1-test.sh
new file mode 100755
index 0000000..1e78a18
--- /dev/null
+++ b/third_party/elfutils/tests/run-bug1-test.sh
@@ -0,0 +1,34 @@
+#! /bin/sh
+# Copyright (C) 2006 Red Hat, Inc.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2006.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile28 testfile28.rdwr
+
+testrun ${abs_builddir}/rdwrmmap testfile28
+
+cmp testfile28 testfile28.rdwr
+
+test_cleanup
+
+testfiles testfile29 testfile29.rdwr
+
+testrun ${abs_builddir}/rdwrmmap testfile29
+
+cmp testfile29 testfile29.rdwr
+
+exit 0
diff --git a/third_party/elfutils/tests/run-buildid.sh b/third_party/elfutils/tests/run-buildid.sh
new file mode 100755
index 0000000..31cec24
--- /dev/null
+++ b/third_party/elfutils/tests/run-buildid.sh
@@ -0,0 +1,38 @@
+#! /bin/sh
+# Copyright (C) 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Just some random testfiles, four with, one without build-id,
+# and one without shdrs forcing reading the notes through phdrs.
+# eu-strip --strip-sections -g --output=testfile42_noshdrs testfile42
+# See also run-debugaltlink.sh.
+testfiles testfile42 testfile_multi.dwz testfile-dwzstr.multi \
+    test-offset-loop.alt testfile14 testfile42_noshdrs
+
+testrun_compare  ${abs_builddir}/buildid testfile42 testfile42_noshdrs \
+    testfile_multi.dwz testfile-dwzstr.multi \
+    test-offset-loop.alt testfile14 <<\EOF
+testfile42: build ID: d826d96c4d097bdc5c254b1f7344a907e36b0439
+testfile42_noshdrs: build ID: d826d96c4d097bdc5c254b1f7344a907e36b0439
+testfile_multi.dwz: build ID: a0d6c06e0d912d74033b6fe2808753cae8f6f594
+testfile-dwzstr.multi: build ID: 6da22627dae55c1d62cf9122827c665e240a056b
+test-offset-loop.alt: build ID: 066bbf1a7bc5676f5015ee1966a088f23bdb83ae
+testfile14: <no NT_GNU_BUILD_ID note>
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-compress-test.sh b/third_party/elfutils/tests/run-compress-test.sh
new file mode 100755
index 0000000..a6a298f
--- /dev/null
+++ b/third_party/elfutils/tests/run-compress-test.sh
@@ -0,0 +1,102 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# uncompress -> gnucompress -> uncompress -> elfcompress -> uncompress
+testrun_elfcompress_file()
+{
+    infile="$1"
+    uncompressedfile="${infile}.uncompressed"
+    tempfiles "$uncompressedfile"
+    
+    echo "uncompress $infile -> $uncompressedfile"
+    testrun ${abs_top_builddir}/src/elfcompress -v -t none -o ${uncompressedfile} ${infile}
+    testrun ${abs_top_builddir}/src/elflint --gnu-ld ${uncompressedfile}
+
+    SIZE_uncompressed=$(stat -c%s $uncompressedfile)
+
+    gnucompressedfile="${infile}.gnu"
+    tempfiles "$gnucompressedfile"
+    echo "compress gnu $uncompressedfile -> $gnucompressedfile"
+    testrun ${abs_top_builddir}/src/elfcompress -v -t gnu -o ${gnucompressedfile} ${uncompressedfile}
+    testrun ${abs_top_builddir}/src/elflint --gnu-ld ${gnucompressedfile}
+
+    SIZE_gnucompressed=$(stat -c%s $gnucompressedfile)
+    test $SIZE_gnucompressed -lt $SIZE_uncompressed ||
+	{ echo "*** failure $gnucompressedfile not smaller"; exit -1; }
+    
+    gnuuncompressedfile="${infile}.gnu.uncompressed"
+    tempfiles "$gnuuncompressedfile"
+    echo "uncompress $gnucompressedfile -> $gnuuncompressedfile"
+    testrun ${abs_top_builddir}/src/elfcompress -v -t none -o ${gnuuncompressedfile} ${gnucompressedfile}
+    testrun ${abs_top_builddir}/src/elfcmp ${uncompressedfile} ${gnuuncompressedfile}
+
+    elfcompressedfile="${infile}.gabi"
+    tempfiles "$elfcompressedfile"
+    echo "compress gabi $uncompressedfile -> $elfcompressedfile"
+    testrun ${abs_top_builddir}/src/elfcompress -v -t zlib -o ${elfcompressedfile} ${uncompressedfile}
+    testrun ${abs_top_builddir}/src/elflint --gnu-ld ${elfcompressedfile}
+
+    SIZE_elfcompressed=$(stat -c%s $elfcompressedfile)
+    test $SIZE_elfcompressed -lt $SIZE_uncompressed ||
+	{ echo "*** failure $elfcompressedfile not smaller"; exit -1; }
+    
+    elfuncompressedfile="${infile}.gabi.uncompressed"
+    tempfiles "$elfuncompressedfile"
+    echo "uncompress $elfcompressedfile -> $elfuncompressedfile"
+    testrun ${abs_top_builddir}/src/elfcompress -v -t none -o ${elfuncompressedfile} ${elfcompressedfile}
+    testrun ${abs_top_builddir}/src/elfcmp ${uncompressedfile} ${elfuncompressedfile}
+}
+
+testrun_elfcompress()
+{
+    testfile="$1"
+    testfiles ${testfile}
+    testrun_elfcompress_file ${testfile}
+
+    # Merge the string tables to make things a little more interesting.
+    mergedfile="${testfile}.merged"
+    tempfiles ${mergedfile}
+    echo "merging string tables ${testfile} -> ${mergedfile}"
+    testrun ${abs_top_builddir}/tests/elfstrmerge -o ${mergedfile} ${testfile}
+    testrun_elfcompress_file ${mergedfile}
+}
+
+# Random ELF32 testfile
+testrun_elfcompress testfile4
+
+# Random ELF64 testfile
+testrun_elfcompress testfile12
+
+# Random ELF64BE testfile
+testrun_elfcompress testfileppc64
+
+# Random ELF32BE testfile
+testrun_elfcompress testfileppc32
+
+# Already compressed files
+testrun_elfcompress testfile-zgnu64
+testrun_elfcompress testfile-zgnu64be
+testrun_elfcompress testfile-zgabi64
+testrun_elfcompress testfile-zgabi64be
+testrun_elfcompress testfile-zgnu32
+testrun_elfcompress testfile-zgnu32be
+testrun_elfcompress testfile-zgabi32
+testrun_elfcompress testfile-zgabi32be
+
+exit 0
diff --git a/third_party/elfutils/tests/run-debugaltlink.sh b/third_party/elfutils/tests/run-debugaltlink.sh
new file mode 100755
index 0000000..fa7dd26
--- /dev/null
+++ b/third_party/elfutils/tests/run-debugaltlink.sh
@@ -0,0 +1,34 @@
+#! /bin/sh
+# Copyright (C) 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Just some random testfiles, four with, one without .gnu_debugaltlink
+testfiles testfile42 testfile_multi_main testfile-dwzstr \
+    test-offset-loop libtestfile_multi_shared.so
+
+testrun_compare  ${abs_builddir}/debugaltlink testfile42 \
+    testfile_multi_main testfile-dwzstr \
+    test-offset-loop libtestfile_multi_shared.so <<\EOF
+testfile42: <no .gnu_debugaltlink section>
+testfile_multi_main: testfile_multi.dwz, build ID: a0d6c06e0d912d74033b6fe2808753cae8f6f594
+testfile-dwzstr: testfile-dwzstr.multi, build ID: 6da22627dae55c1d62cf9122827c665e240a056b
+test-offset-loop: test-offset-loop.alt, build ID: 066bbf1a7bc5676f5015ee1966a088f23bdb83ae
+libtestfile_multi_shared.so: testfile_multi.dwz, build ID: a0d6c06e0d912d74033b6fe2808753cae8f6f594
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-debuglink.sh b/third_party/elfutils/tests/run-debuglink.sh
new file mode 100755
index 0000000..42a816c
--- /dev/null
+++ b/third_party/elfutils/tests/run-debuglink.sh
@@ -0,0 +1,29 @@
+#! /bin/sh
+# Copyright (C) 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Just some random testfiles, two with, one without .gnu_debuglink
+testfiles testfile36 testfile52-32.so testfile42
+
+testrun_compare  ${abs_builddir}/debuglink testfile36 testfile52-32.so testfile42 <<\EOF
+testfile36: testfile36.debug, crc: 8c5c20a3
+testfile52-32.so: testfile52-32.so.debug, crc: b835a71d
+testfile42: <no gnu_debuglink file>
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-deleted.sh b/third_party/elfutils/tests/run-deleted.sh
new file mode 100755
index 0000000..0f64762
--- /dev/null
+++ b/third_party/elfutils/tests/run-deleted.sh
@@ -0,0 +1,52 @@
+#! /bin/bash
+# Copyright (C) 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/backtrace-subr.sh
+
+tempfiles deleted deleted-lib.so
+cp -p ${abs_builddir}/deleted ${abs_builddir}/deleted-lib.so .
+
+# We don't want to run the deleted process under valgrind then
+# stack will see the valgrind process backtrace.
+OLD_VALGRIND_CMD="$VALGRIND_CMD"
+unset VALGRIND_CMD
+
+pid=$(testrun ${abs_builddir}/deleted)
+sleep 1
+rm -f deleted deleted-lib.so
+tempfiles bt bt.err
+
+set VALGRIND_CMD="$OLD_VALGRIND_CMD"
+# It may have non-zero exit code with:
+# .../elfutils/src/stack: dwfl_thread_getframes tid 26376 at 0x4006c8 in .../elfutils/tests/deleted: no matching address range
+testrun ${abs_top_builddir}/src/stack -p $pid 1>bt 2>bt.err || true
+cat bt bt.err
+kill -9 $pid
+wait
+check_native_unsupported bt.err deleted
+if grep -q -E ': dwfl_linux_proc_attach pid ([[:digit:]]+): Function not implemented$' bt.err; then
+  echo >&2 deleted: OS not supported
+  exit 77
+fi
+# For PPC64 we need access to the OPD table which we get through the shdrs
+# (see backends/ppc64_init.c) but for the deleted-lib we only have phdrs.
+# So we don't have the name of the function. But since we should find
+# the EH_FRAME through phdrs just fine, we can unwind into main.
+if test "`uname -m`" != "ppc64"; then
+  grep -qw libfunc bt
+fi
+grep -qw main bt
diff --git a/third_party/elfutils/tests/run-disasm-bpf.sh b/third_party/elfutils/tests/run-disasm-bpf.sh
new file mode 100755
index 0000000..8ca89d5
--- /dev/null
+++ b/third_party/elfutils/tests/run-disasm-bpf.sh
@@ -0,0 +1,63 @@
+#! /bin/sh
+# Copyright (C) 2016 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# This test file is created with
+#
+# #include <linux/bpf.h>
+# #include <stdio.h>
+#
+# int main()
+# {
+#   int i;
+#
+#   printf("\t.text\n");
+#
+#   for (i = 0; i < 256; ++i)
+#     if (i == (BPF_LD | BPF_IMM | BPF_DW))
+#       printf("\t.byte\t%d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n", i);
+#     else
+#       {
+#         int regs = 0;
+#         switch (BPF_CLASS(i))
+#           {
+#           case BPF_ALU:
+#           case BPF_ALU64:
+#             if (BPF_SRC(i) == BPF_X
+#                 && BPF_OP(i) != BPF_NEG
+#                 && BPF_OP(i) != BPF_END)
+#               regs = 0x21;
+#             break;
+#           case BPF_LDX:
+#           case BPF_STX:
+#             regs = 0x21;
+#             break;
+#           }
+#         printf("\t.byte\t%d, %d, 0, 0, 0, 0, 0, 0\n", i, regs);
+#       }
+#
+#   return 0;
+# }
+#
+# $ ./a.out | as -o z1.o
+# $ objcopy -j .text z1.o z2.o
+#
+# Then emacs hexl edit e_machine to 0xf7.
+
+testfiles testfile-bpf-dis1.o testfile-bpf-dis1.expect
+testrun_compare ${abs_top_builddir}/src/objdump -d testfile-bpf-dis1.o < testfile-bpf-dis1.expect
diff --git a/third_party/elfutils/tests/run-disasm-x86-64.sh b/third_party/elfutils/tests/run-disasm-x86-64.sh
new file mode 100755
index 0000000..a6be62b
--- /dev/null
+++ b/third_party/elfutils/tests/run-disasm-x86-64.sh
@@ -0,0 +1,28 @@
+#! /bin/sh
+# Copyright (C) 2007, 2008 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Run x86-64 test.
+case "`uname -m`" in
+  x86_64)
+    tempfiles testfile45.o
+    testfiles testfile45.S testfile45.expect
+    gcc -m64 -c -o testfile45.o testfile45.S
+    testrun_compare ${abs_top_builddir}/src/objdump -d testfile45.o < testfile45.expect
+    ;;
+esac
diff --git a/third_party/elfutils/tests/run-disasm-x86.sh b/third_party/elfutils/tests/run-disasm-x86.sh
new file mode 100755
index 0000000..28a3df7
--- /dev/null
+++ b/third_party/elfutils/tests/run-disasm-x86.sh
@@ -0,0 +1,28 @@
+#! /bin/sh
+# Copyright (C) 2007, 2008 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Run x86 test.
+case "`uname -m`" in
+  x86_64 | i?86 )
+    tempfiles testfile44.o
+    testfiles testfile44.S testfile44.expect
+    gcc -m32 -c -o testfile44.o testfile44.S
+    testrun_compare ${abs_top_builddir}/src/objdump -d testfile44.o < testfile44.expect
+    ;;
+esac
diff --git a/third_party/elfutils/tests/run-dwarf-getmacros.sh b/third_party/elfutils/tests/run-dwarf-getmacros.sh
new file mode 100755
index 0000000..0a488fa
--- /dev/null
+++ b/third_party/elfutils/tests/run-dwarf-getmacros.sh
@@ -0,0 +1,710 @@
+#! /bin/sh
+# Copyright (C) 2009, 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile51
+
+testrun_compare ${abs_builddir}/dwarf-getmacros testfile51 0xb <<\EOF
+file /home/petr/proj/elfutils/pending/elfutils/tests/decom/x.c
+ __STDC__ 1
+ __STDC_HOSTED__ 1
+ __GNUC__ 4
+ __GNUC_MINOR__ 3
+ __GNUC_PATCHLEVEL__ 2
+ __GNUC_RH_RELEASE__ 7
+ __SIZE_TYPE__ long unsigned int
+ __PTRDIFF_TYPE__ long int
+ __WCHAR_TYPE__ int
+ __WINT_TYPE__ unsigned int
+ __INTMAX_TYPE__ long int
+ __UINTMAX_TYPE__ long unsigned int
+ __GXX_ABI_VERSION 1002
+ __SCHAR_MAX__ 127
+ __SHRT_MAX__ 32767
+ __INT_MAX__ 2147483647
+ __LONG_MAX__ 9223372036854775807L
+ __LONG_LONG_MAX__ 9223372036854775807LL
+ __WCHAR_MAX__ 2147483647
+ __CHAR_BIT__ 8
+ __INTMAX_MAX__ 9223372036854775807L
+ __FLT_EVAL_METHOD__ 0
+ __DEC_EVAL_METHOD__ 2
+ __FLT_RADIX__ 2
+ __FLT_MANT_DIG__ 24
+ __FLT_DIG__ 6
+ __FLT_MIN_EXP__ (-125)
+ __FLT_MIN_10_EXP__ (-37)
+ __FLT_MAX_EXP__ 128
+ __FLT_MAX_10_EXP__ 38
+ __FLT_MAX__ 3.40282347e+38F
+ __FLT_MIN__ 1.17549435e-38F
+ __FLT_EPSILON__ 1.19209290e-7F
+ __FLT_DENORM_MIN__ 1.40129846e-45F
+ __FLT_HAS_DENORM__ 1
+ __FLT_HAS_INFINITY__ 1
+ __FLT_HAS_QUIET_NAN__ 1
+ __DBL_MANT_DIG__ 53
+ __DBL_DIG__ 15
+ __DBL_MIN_EXP__ (-1021)
+ __DBL_MIN_10_EXP__ (-307)
+ __DBL_MAX_EXP__ 1024
+ __DBL_MAX_10_EXP__ 308
+ __DBL_MAX__ 1.7976931348623157e+308
+ __DBL_MIN__ 2.2250738585072014e-308
+ __DBL_EPSILON__ 2.2204460492503131e-16
+ __DBL_DENORM_MIN__ 4.9406564584124654e-324
+ __DBL_HAS_DENORM__ 1
+ __DBL_HAS_INFINITY__ 1
+ __DBL_HAS_QUIET_NAN__ 1
+ __LDBL_MANT_DIG__ 64
+ __LDBL_DIG__ 18
+ __LDBL_MIN_EXP__ (-16381)
+ __LDBL_MIN_10_EXP__ (-4931)
+ __LDBL_MAX_EXP__ 16384
+ __LDBL_MAX_10_EXP__ 4932
+ __DECIMAL_DIG__ 21
+ __LDBL_MAX__ 1.18973149535723176502e+4932L
+ __LDBL_MIN__ 3.36210314311209350626e-4932L
+ __LDBL_EPSILON__ 1.08420217248550443401e-19L
+ __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
+ __LDBL_HAS_DENORM__ 1
+ __LDBL_HAS_INFINITY__ 1
+ __LDBL_HAS_QUIET_NAN__ 1
+ __DEC32_MANT_DIG__ 7
+ __DEC32_MIN_EXP__ (-95)
+ __DEC32_MAX_EXP__ 96
+ __DEC32_MIN__ 1E-95DF
+ __DEC32_MAX__ 9.999999E96DF
+ __DEC32_EPSILON__ 1E-6DF
+ __DEC32_DEN__ 0.000001E-95DF
+ __DEC64_MANT_DIG__ 16
+ __DEC64_MIN_EXP__ (-383)
+ __DEC64_MAX_EXP__ 384
+ __DEC64_MIN__ 1E-383DD
+ __DEC64_MAX__ 9.999999999999999E384DD
+ __DEC64_EPSILON__ 1E-15DD
+ __DEC64_DEN__ 0.000000000000001E-383DD
+ __DEC128_MANT_DIG__ 34
+ __DEC128_MIN_EXP__ (-6143)
+ __DEC128_MAX_EXP__ 6144
+ __DEC128_MIN__ 1E-6143DL
+ __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
+ __DEC128_EPSILON__ 1E-33DL
+ __DEC128_DEN__ 0.000000000000000000000000000000001E-6143DL
+ __REGISTER_PREFIX__ 
+ __USER_LABEL_PREFIX__ 
+ __VERSION__ "4.3.2 20081105 (Red Hat 4.3.2-7)"
+ __GNUC_GNU_INLINE__ 1
+ _LP64 1
+ __LP64__ 1
+ __NO_INLINE__ 1
+ __FINITE_MATH_ONLY__ 0
+ __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+ __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+ __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+ __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+ __SIZEOF_INT__ 4
+ __SIZEOF_LONG__ 8
+ __SIZEOF_LONG_LONG__ 8
+ __SIZEOF_SHORT__ 2
+ __SIZEOF_FLOAT__ 4
+ __SIZEOF_DOUBLE__ 8
+ __SIZEOF_LONG_DOUBLE__ 16
+ __SIZEOF_SIZE_T__ 8
+ __SIZEOF_WCHAR_T__ 4
+ __SIZEOF_WINT_T__ 4
+ __SIZEOF_PTRDIFF_T__ 8
+ __SIZEOF_POINTER__ 8
+ __amd64 1
+ __amd64__ 1
+ __x86_64 1
+ __x86_64__ 1
+ __k8 1
+ __k8__ 1
+ __MMX__ 1
+ __SSE__ 1
+ __SSE2__ 1
+ __SSE_MATH__ 1
+ __SSE2_MATH__ 1
+ __gnu_linux__ 1
+ __linux 1
+ __linux__ 1
+ linux 1
+ __unix 1
+ __unix__ 1
+ unix 1
+ __ELF__ 1
+ __DECIMAL_BID_FORMAT__ 1
+ macro1 ble
+/file
+EOF
+
+testrun_compare ${abs_builddir}/dwarf-getmacros testfile51 0x84 <<\EOF
+file /home/petr/proj/elfutils/pending/elfutils/tests/decom/y.c
+ __STDC__ 1
+ __STDC_HOSTED__ 1
+ __GNUC__ 4
+ __GNUC_MINOR__ 3
+ __GNUC_PATCHLEVEL__ 2
+ __GNUC_RH_RELEASE__ 7
+ __SIZE_TYPE__ long unsigned int
+ __PTRDIFF_TYPE__ long int
+ __WCHAR_TYPE__ int
+ __WINT_TYPE__ unsigned int
+ __INTMAX_TYPE__ long int
+ __UINTMAX_TYPE__ long unsigned int
+ __GXX_ABI_VERSION 1002
+ __SCHAR_MAX__ 127
+ __SHRT_MAX__ 32767
+ __INT_MAX__ 2147483647
+ __LONG_MAX__ 9223372036854775807L
+ __LONG_LONG_MAX__ 9223372036854775807LL
+ __WCHAR_MAX__ 2147483647
+ __CHAR_BIT__ 8
+ __INTMAX_MAX__ 9223372036854775807L
+ __FLT_EVAL_METHOD__ 0
+ __DEC_EVAL_METHOD__ 2
+ __FLT_RADIX__ 2
+ __FLT_MANT_DIG__ 24
+ __FLT_DIG__ 6
+ __FLT_MIN_EXP__ (-125)
+ __FLT_MIN_10_EXP__ (-37)
+ __FLT_MAX_EXP__ 128
+ __FLT_MAX_10_EXP__ 38
+ __FLT_MAX__ 3.40282347e+38F
+ __FLT_MIN__ 1.17549435e-38F
+ __FLT_EPSILON__ 1.19209290e-7F
+ __FLT_DENORM_MIN__ 1.40129846e-45F
+ __FLT_HAS_DENORM__ 1
+ __FLT_HAS_INFINITY__ 1
+ __FLT_HAS_QUIET_NAN__ 1
+ __DBL_MANT_DIG__ 53
+ __DBL_DIG__ 15
+ __DBL_MIN_EXP__ (-1021)
+ __DBL_MIN_10_EXP__ (-307)
+ __DBL_MAX_EXP__ 1024
+ __DBL_MAX_10_EXP__ 308
+ __DBL_MAX__ 1.7976931348623157e+308
+ __DBL_MIN__ 2.2250738585072014e-308
+ __DBL_EPSILON__ 2.2204460492503131e-16
+ __DBL_DENORM_MIN__ 4.9406564584124654e-324
+ __DBL_HAS_DENORM__ 1
+ __DBL_HAS_INFINITY__ 1
+ __DBL_HAS_QUIET_NAN__ 1
+ __LDBL_MANT_DIG__ 64
+ __LDBL_DIG__ 18
+ __LDBL_MIN_EXP__ (-16381)
+ __LDBL_MIN_10_EXP__ (-4931)
+ __LDBL_MAX_EXP__ 16384
+ __LDBL_MAX_10_EXP__ 4932
+ __DECIMAL_DIG__ 21
+ __LDBL_MAX__ 1.18973149535723176502e+4932L
+ __LDBL_MIN__ 3.36210314311209350626e-4932L
+ __LDBL_EPSILON__ 1.08420217248550443401e-19L
+ __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
+ __LDBL_HAS_DENORM__ 1
+ __LDBL_HAS_INFINITY__ 1
+ __LDBL_HAS_QUIET_NAN__ 1
+ __DEC32_MANT_DIG__ 7
+ __DEC32_MIN_EXP__ (-95)
+ __DEC32_MAX_EXP__ 96
+ __DEC32_MIN__ 1E-95DF
+ __DEC32_MAX__ 9.999999E96DF
+ __DEC32_EPSILON__ 1E-6DF
+ __DEC32_DEN__ 0.000001E-95DF
+ __DEC64_MANT_DIG__ 16
+ __DEC64_MIN_EXP__ (-383)
+ __DEC64_MAX_EXP__ 384
+ __DEC64_MIN__ 1E-383DD
+ __DEC64_MAX__ 9.999999999999999E384DD
+ __DEC64_EPSILON__ 1E-15DD
+ __DEC64_DEN__ 0.000000000000001E-383DD
+ __DEC128_MANT_DIG__ 34
+ __DEC128_MIN_EXP__ (-6143)
+ __DEC128_MAX_EXP__ 6144
+ __DEC128_MIN__ 1E-6143DL
+ __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
+ __DEC128_EPSILON__ 1E-33DL
+ __DEC128_DEN__ 0.000000000000000000000000000000001E-6143DL
+ __REGISTER_PREFIX__ 
+ __USER_LABEL_PREFIX__ 
+ __VERSION__ "4.3.2 20081105 (Red Hat 4.3.2-7)"
+ __GNUC_GNU_INLINE__ 1
+ _LP64 1
+ __LP64__ 1
+ __NO_INLINE__ 1
+ __FINITE_MATH_ONLY__ 0
+ __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+ __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+ __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+ __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+ __SIZEOF_INT__ 4
+ __SIZEOF_LONG__ 8
+ __SIZEOF_LONG_LONG__ 8
+ __SIZEOF_SHORT__ 2
+ __SIZEOF_FLOAT__ 4
+ __SIZEOF_DOUBLE__ 8
+ __SIZEOF_LONG_DOUBLE__ 16
+ __SIZEOF_SIZE_T__ 8
+ __SIZEOF_WCHAR_T__ 4
+ __SIZEOF_WINT_T__ 4
+ __SIZEOF_PTRDIFF_T__ 8
+ __SIZEOF_POINTER__ 8
+ __amd64 1
+ __amd64__ 1
+ __x86_64 1
+ __x86_64__ 1
+ __k8 1
+ __k8__ 1
+ __MMX__ 1
+ __SSE__ 1
+ __SSE2__ 1
+ __SSE_MATH__ 1
+ __SSE2_MATH__ 1
+ __gnu_linux__ 1
+ __linux 1
+ __linux__ 1
+ linux 1
+ __unix 1
+ __unix__ 1
+ unix 1
+ __ELF__ 1
+ __DECIMAL_BID_FORMAT__ 1
+ macro2 ble
+/file
+EOF
+
+testfiles testfile-macros
+
+testrun_compare ${abs_builddir}/dwarf-getmacros testfile-macros 0xb <<\EOF
+__STDC__ 1
+__STDC_HOSTED__ 1
+__GNUC__ 4
+__GNUC_MINOR__ 7
+__GNUC_PATCHLEVEL__ 0
+__VERSION__ "4.7.0 20120507 (Red Hat 4.7.0-5)"
+__GNUC_RH_RELEASE__ 5
+__ATOMIC_RELAXED 0
+__ATOMIC_SEQ_CST 5
+__ATOMIC_ACQUIRE 2
+__ATOMIC_RELEASE 3
+__ATOMIC_ACQ_REL 4
+__ATOMIC_CONSUME 1
+__FINITE_MATH_ONLY__ 0
+_LP64 1
+__LP64__ 1
+__SIZEOF_INT__ 4
+__SIZEOF_LONG__ 8
+__SIZEOF_LONG_LONG__ 8
+__SIZEOF_SHORT__ 2
+__SIZEOF_FLOAT__ 4
+__SIZEOF_DOUBLE__ 8
+__SIZEOF_LONG_DOUBLE__ 16
+__SIZEOF_SIZE_T__ 8
+__CHAR_BIT__ 8
+__BIGGEST_ALIGNMENT__ 16
+__ORDER_LITTLE_ENDIAN__ 1234
+__ORDER_BIG_ENDIAN__ 4321
+__ORDER_PDP_ENDIAN__ 3412
+__BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+__FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
+__SIZEOF_POINTER__ 8
+__SIZE_TYPE__ long unsigned int
+__PTRDIFF_TYPE__ long int
+__WCHAR_TYPE__ int
+__WINT_TYPE__ unsigned int
+__INTMAX_TYPE__ long int
+__UINTMAX_TYPE__ long unsigned int
+__CHAR16_TYPE__ short unsigned int
+__CHAR32_TYPE__ unsigned int
+__SIG_ATOMIC_TYPE__ int
+__INT8_TYPE__ signed char
+__INT16_TYPE__ short int
+__INT32_TYPE__ int
+__INT64_TYPE__ long int
+__UINT8_TYPE__ unsigned char
+__UINT16_TYPE__ short unsigned int
+__UINT32_TYPE__ unsigned int
+__UINT64_TYPE__ long unsigned int
+__INT_LEAST8_TYPE__ signed char
+__INT_LEAST16_TYPE__ short int
+__INT_LEAST32_TYPE__ int
+__INT_LEAST64_TYPE__ long int
+__UINT_LEAST8_TYPE__ unsigned char
+__UINT_LEAST16_TYPE__ short unsigned int
+__UINT_LEAST32_TYPE__ unsigned int
+__UINT_LEAST64_TYPE__ long unsigned int
+__INT_FAST8_TYPE__ signed char
+__INT_FAST16_TYPE__ long int
+__INT_FAST32_TYPE__ long int
+__INT_FAST64_TYPE__ long int
+__UINT_FAST8_TYPE__ unsigned char
+__UINT_FAST16_TYPE__ long unsigned int
+__UINT_FAST32_TYPE__ long unsigned int
+__UINT_FAST64_TYPE__ long unsigned int
+__INTPTR_TYPE__ long int
+__UINTPTR_TYPE__ long unsigned int
+__GXX_ABI_VERSION 1002
+__SCHAR_MAX__ 127
+__SHRT_MAX__ 32767
+__INT_MAX__ 2147483647
+__LONG_MAX__ 9223372036854775807L
+__LONG_LONG_MAX__ 9223372036854775807LL
+__WCHAR_MAX__ 2147483647
+__WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
+__WINT_MAX__ 4294967295U
+__WINT_MIN__ 0U
+__PTRDIFF_MAX__ 9223372036854775807L
+__SIZE_MAX__ 18446744073709551615UL
+__INTMAX_MAX__ 9223372036854775807L
+__INTMAX_C(c) c ## L
+__UINTMAX_MAX__ 18446744073709551615UL
+__UINTMAX_C(c) c ## UL
+__SIG_ATOMIC_MAX__ 2147483647
+__SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1)
+__INT8_MAX__ 127
+__INT16_MAX__ 32767
+__INT32_MAX__ 2147483647
+__INT64_MAX__ 9223372036854775807L
+__UINT8_MAX__ 255
+__UINT16_MAX__ 65535
+__UINT32_MAX__ 4294967295U
+__UINT64_MAX__ 18446744073709551615UL
+__INT_LEAST8_MAX__ 127
+__INT8_C(c) c
+__INT_LEAST16_MAX__ 32767
+__INT16_C(c) c
+__INT_LEAST32_MAX__ 2147483647
+__INT32_C(c) c
+__INT_LEAST64_MAX__ 9223372036854775807L
+__INT64_C(c) c ## L
+__UINT_LEAST8_MAX__ 255
+__UINT8_C(c) c
+__UINT_LEAST16_MAX__ 65535
+__UINT16_C(c) c
+__UINT_LEAST32_MAX__ 4294967295U
+__UINT32_C(c) c ## U
+__UINT_LEAST64_MAX__ 18446744073709551615UL
+__UINT64_C(c) c ## UL
+__INT_FAST8_MAX__ 127
+__INT_FAST16_MAX__ 9223372036854775807L
+__INT_FAST32_MAX__ 9223372036854775807L
+__INT_FAST64_MAX__ 9223372036854775807L
+__UINT_FAST8_MAX__ 255
+__UINT_FAST16_MAX__ 18446744073709551615UL
+__UINT_FAST32_MAX__ 18446744073709551615UL
+__UINT_FAST64_MAX__ 18446744073709551615UL
+__INTPTR_MAX__ 9223372036854775807L
+__UINTPTR_MAX__ 18446744073709551615UL
+__FLT_EVAL_METHOD__ 0
+__DEC_EVAL_METHOD__ 2
+__FLT_RADIX__ 2
+__FLT_MANT_DIG__ 24
+__FLT_DIG__ 6
+__FLT_MIN_EXP__ (-125)
+__FLT_MIN_10_EXP__ (-37)
+__FLT_MAX_EXP__ 128
+__FLT_MAX_10_EXP__ 38
+__FLT_DECIMAL_DIG__ 9
+__FLT_MAX__ 3.40282346638528859812e+38F
+__FLT_MIN__ 1.17549435082228750797e-38F
+__FLT_EPSILON__ 1.19209289550781250000e-7F
+__FLT_DENORM_MIN__ 1.40129846432481707092e-45F
+__FLT_HAS_DENORM__ 1
+__FLT_HAS_INFINITY__ 1
+__FLT_HAS_QUIET_NAN__ 1
+__DBL_MANT_DIG__ 53
+__DBL_DIG__ 15
+__DBL_MIN_EXP__ (-1021)
+__DBL_MIN_10_EXP__ (-307)
+__DBL_MAX_EXP__ 1024
+__DBL_MAX_10_EXP__ 308
+__DBL_DECIMAL_DIG__ 17
+__DBL_MAX__ ((double)1.79769313486231570815e+308L)
+__DBL_MIN__ ((double)2.22507385850720138309e-308L)
+__DBL_EPSILON__ ((double)2.22044604925031308085e-16L)
+__DBL_DENORM_MIN__ ((double)4.94065645841246544177e-324L)
+__DBL_HAS_DENORM__ 1
+__DBL_HAS_INFINITY__ 1
+__DBL_HAS_QUIET_NAN__ 1
+__LDBL_MANT_DIG__ 64
+__LDBL_DIG__ 18
+__LDBL_MIN_EXP__ (-16381)
+__LDBL_MIN_10_EXP__ (-4931)
+__LDBL_MAX_EXP__ 16384
+__LDBL_MAX_10_EXP__ 4932
+__DECIMAL_DIG__ 21
+__LDBL_MAX__ 1.18973149535723176502e+4932L
+__LDBL_MIN__ 3.36210314311209350626e-4932L
+__LDBL_EPSILON__ 1.08420217248550443401e-19L
+__LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
+__LDBL_HAS_DENORM__ 1
+__LDBL_HAS_INFINITY__ 1
+__LDBL_HAS_QUIET_NAN__ 1
+__DEC32_MANT_DIG__ 7
+__DEC32_MIN_EXP__ (-94)
+__DEC32_MAX_EXP__ 97
+__DEC32_MIN__ 1E-95DF
+__DEC32_MAX__ 9.999999E96DF
+__DEC32_EPSILON__ 1E-6DF
+__DEC32_SUBNORMAL_MIN__ 0.000001E-95DF
+__DEC64_MANT_DIG__ 16
+__DEC64_MIN_EXP__ (-382)
+__DEC64_MAX_EXP__ 385
+__DEC64_MIN__ 1E-383DD
+__DEC64_MAX__ 9.999999999999999E384DD
+__DEC64_EPSILON__ 1E-15DD
+__DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD
+__DEC128_MANT_DIG__ 34
+__DEC128_MIN_EXP__ (-6142)
+__DEC128_MAX_EXP__ 6145
+__DEC128_MIN__ 1E-6143DL
+__DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
+__DEC128_EPSILON__ 1E-33DL
+__DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL
+__REGISTER_PREFIX__ 
+__USER_LABEL_PREFIX__ 
+__GNUC_GNU_INLINE__ 1
+__NO_INLINE__ 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+__GCC_ATOMIC_BOOL_LOCK_FREE 2
+__GCC_ATOMIC_CHAR_LOCK_FREE 2
+__GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+__GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+__GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
+__GCC_ATOMIC_SHORT_LOCK_FREE 2
+__GCC_ATOMIC_INT_LOCK_FREE 2
+__GCC_ATOMIC_LONG_LOCK_FREE 2
+__GCC_ATOMIC_LLONG_LOCK_FREE 2
+__GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+__GCC_ATOMIC_POINTER_LOCK_FREE 2
+__GCC_HAVE_DWARF2_CFI_ASM 1
+__PRAGMA_REDEFINE_EXTNAME 1
+__SIZEOF_INT128__ 16
+__SIZEOF_WCHAR_T__ 4
+__SIZEOF_WINT_T__ 4
+__SIZEOF_PTRDIFF_T__ 8
+__amd64 1
+__amd64__ 1
+__x86_64 1
+__x86_64__ 1
+__k8 1
+__k8__ 1
+__MMX__ 1
+__SSE__ 1
+__SSE2__ 1
+__SSE_MATH__ 1
+__SSE2_MATH__ 1
+__gnu_linux__ 1
+__linux 1
+__linux__ 1
+linux 1
+__unix 1
+__unix__ 1
+unix 1
+__ELF__ 1
+__DECIMAL_BID_FORMAT__ 1
+file /home/mark/src/tests/macro.c
+ file /usr/include/string.h
+  _STRING_H 1
+  file /usr/include/features.h
+   include 0x5d8
+    _FEATURES_H 1
+    __KERNEL_STRICT_NAMES 
+    __USE_ANSI 1
+    __GNUC_PREREQ(maj,min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+    _BSD_SOURCE 1
+    _SVID_SOURCE 1
+    _POSIX_SOURCE 1
+    _POSIX_C_SOURCE 200809L
+    __USE_POSIX_IMPLICITLY 1
+    __USE_POSIX 1
+    __USE_POSIX2 1
+    __USE_POSIX199309 1
+    __USE_POSIX199506 1
+    __USE_XOPEN2K 1
+    __USE_ISOC95 1
+    __USE_ISOC99 1
+    __USE_XOPEN2K8 1
+    _ATFILE_SOURCE 1
+    __USE_MISC 1
+    __USE_BSD 1
+    __USE_SVID 1
+    __USE_ATFILE 1
+    __USE_FORTIFY_LEVEL 0
+   /include
+   file /usr/include/stdc-predef.h
+    include 0x733
+     _STDC_PREDEF_H 1
+     __STDC_IEC_559__ 1
+     __STDC_IEC_559_COMPLEX__ 1
+     __STDC_ISO_10646__ 201103L
+     __STDC_NO_THREADS__ 1
+    /include
+   /file
+   include 0x755
+    __GNU_LIBRARY__ 6
+    __GLIBC__ 2
+    __GLIBC_MINOR__ 15
+    __GLIBC_PREREQ(maj,min) ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
+    __GLIBC_HAVE_LONG_LONG 1
+   /include
+   file /usr/include/sys/cdefs.h
+    include 0x783
+     _SYS_CDEFS_H 1
+     __LEAF , __leaf__
+     __LEAF_ATTR __attribute__ ((__leaf__))
+     __THROW __attribute__ ((__nothrow__ __LEAF))
+     __THROWNL __attribute__ ((__nothrow__))
+     __NTH(fct) __attribute__ ((__nothrow__ __LEAF)) fct
+     __P(args) args
+     __PMT(args) args
+     __CONCAT(x,y) x ## y
+     __STRING(x) #x
+     __ptr_t void *
+     __long_double_t long double
+     __BEGIN_DECLS 
+     __END_DECLS 
+     __BEGIN_NAMESPACE_STD 
+     __END_NAMESPACE_STD 
+     __USING_NAMESPACE_STD(name) 
+     __BEGIN_NAMESPACE_C99 
+     __END_NAMESPACE_C99 
+     __USING_NAMESPACE_C99(name) 
+     __bounded 
+     __unbounded 
+     __ptrvalue 
+     __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
+     __bos0(ptr) __builtin_object_size (ptr, 0)
+     __fortify_function __extern_always_inline __attribute_artificial__
+     __warndecl(name,msg) extern void name (void) __attribute__((__warning__ (msg)))
+     __warnattr(msg) __attribute__((__warning__ (msg)))
+     __errordecl(name,msg) extern void name (void) __attribute__((__error__ (msg)))
+     __flexarr []
+     __REDIRECT(name,proto,alias) name proto __asm__ (__ASMNAME (#alias))
+     __REDIRECT_NTH(name,proto,alias) name proto __asm__ (__ASMNAME (#alias)) __THROW
+     __REDIRECT_NTHNL(name,proto,alias) name proto __asm__ (__ASMNAME (#alias)) __THROWNL
+     __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+     __ASMNAME2(prefix,cname) __STRING (prefix) cname
+     __attribute_malloc__ __attribute__ ((__malloc__))
+     __attribute_pure__ __attribute__ ((__pure__))
+     __attribute_const__ __attribute__ ((__const__))
+     __attribute_used__ __attribute__ ((__used__))
+     __attribute_noinline__ __attribute__ ((__noinline__))
+     __attribute_deprecated__ __attribute__ ((__deprecated__))
+     __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))
+     __attribute_format_strfmon__(a,b) __attribute__ ((__format__ (__strfmon__, a, b)))
+     __nonnull(params) __attribute__ ((__nonnull__ params))
+     __attribute_warn_unused_result__ __attribute__ ((__warn_unused_result__))
+     __wur 
+     __always_inline __inline __attribute__ ((__always_inline__))
+     __attribute_artificial__ __attribute__ ((__artificial__))
+     __extern_inline extern __inline
+     __extern_always_inline extern __always_inline
+     __va_arg_pack() __builtin_va_arg_pack ()
+     __va_arg_pack_len() __builtin_va_arg_pack_len ()
+     __restrict_arr __restrict
+     __glibc_unlikely(cond) __builtin_expect((cond), 0)
+    /include
+    file /usr/include/bits/wordsize.h
+     include 0x8fa
+      __WORDSIZE 64
+      __WORDSIZE_TIME64_COMPAT32 1
+      __SYSCALL_WORDSIZE 64
+     /include
+    /file
+    include 0x910
+     __LDBL_REDIR1(name,proto,alias) name proto
+     __LDBL_REDIR(name,proto) name proto
+     __LDBL_REDIR1_NTH(name,proto,alias) name proto __THROW
+     __LDBL_REDIR_NTH(name,proto) name proto __THROW
+     __LDBL_REDIR_DECL(name) 
+     __REDIRECT_LDBL(name,proto,alias) __REDIRECT (name, proto, alias)
+     __REDIRECT_NTH_LDBL(name,proto,alias) __REDIRECT_NTH (name, proto, alias)
+    /include
+   /file
+   file /usr/include/gnu/stubs.h
+    file /usr/include/gnu/stubs-64.h
+     include 0x945
+      __stub_bdflush 
+      __stub_chflags 
+      __stub_fattach 
+      __stub_fchflags 
+      __stub_fdetach 
+      __stub_getmsg 
+      __stub_gtty 
+      __stub_lchmod 
+      __stub_putmsg 
+      __stub_revoke 
+      __stub_setlogin 
+      __stub_sigreturn 
+      __stub_sstk 
+      __stub_stty 
+     /include
+    /file
+   /file
+  /file
+  include 0x99d
+   __need_size_t 
+   __need_NULL 
+  /include
+  file /usr/lib/gcc/x86_64-redhat-linux/4.7.0/include/stddef.h
+   include 0x9ad
+    __size_t__ 
+    __SIZE_T__ 
+    _SIZE_T 
+    _SYS_SIZE_T_H 
+    _T_SIZE_ 
+    _T_SIZE 
+    __SIZE_T 
+    _SIZE_T_ 
+    _BSD_SIZE_T_ 
+    _SIZE_T_DEFINED_ 
+    _SIZE_T_DEFINED 
+    _BSD_SIZE_T_DEFINED_ 
+    _SIZE_T_DECLARED 
+    ___int_size_t_h 
+    _GCC_SIZE_T 
+    _SIZET_ 
+    __size_t 
+    NULL ((void *)0)
+   /include
+  /file
+  file /usr/include/xlocale.h
+   _XLOCALE_H 1
+  /file
+ /file
+ HELLO "world"
+/file
+EOF
+
+testfiles testfile-macros-0xff
+testrun_compare ${abs_builddir}/dwarf-getmacros testfile-macros-0xff 0xb <<\EOF
+invalid opcode
+EOF
+testrun_compare ${abs_builddir}/dwarf-getmacros testfile-macros-0xff 0xb '' <<\EOF
+opcode 255 with 0 arguments
+file /home/petr/proj/elfutils/master/elfutils/x.c
+ FOO 0
+/file
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-dwarf-getstring.sh b/third_party/elfutils/tests/run-dwarf-getstring.sh
new file mode 100755
index 0000000..f18f628
--- /dev/null
+++ b/third_party/elfutils/tests/run-dwarf-getstring.sh
@@ -0,0 +1,125 @@
+#! /bin/sh
+# Copyright (C) 2011 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile11
+
+testrun_compare ${abs_builddir}/dwarf-getstring testfile11 <<\EOF
+_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_
+itimerspec
+_G_int32_t
+_IO_last_state
+antiquities
+_ZNSbIwSt11char_traitsIwESaIwEEpLEw
+insert
+_ZNSbIwSt11char_traitsIwESaIwEE12_M_leak_hardEv
+__lockkind
+_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv
+_ZNSs7_M_leakEv
+_M_ref_count
+_ZNSt11char_traitsIwE6assignEPwjw
+_ZNKSs13find_first_ofEPKcj
+._14
+._15
+._16
+._17
+_ZNKSs16find_last_not_ofEPKcj
+_G_iconv_t
+_ZN10__gnu_test9gnu_obj_2IlEaSERKS1_
+_ZN11random_dataaSERKS_
+_ZNSt11char_traitsIcE7not_eofERKi
+__class_type_info
+tm_sec
+_ZNKSbIwSt11char_traitsIwESaIwEE5c_strEv
+__rlim64_t
+seek
+pthread_mutex_t
+_ZNSs5eraseEN9__gnu_cxx17__normal_iteratorIPcSsEE
+_ZNSsaSEc
+__not_va_list__
+_ZNKSs12find_last_ofEPKcj
+_ZNSs7replaceEN9__gnu_cxx17__normal_iteratorIPcSsEES2_S2_S2_
+__gconv_info
+_ZNSt11__ios_flags12_S_showpointE
+output_iterator_tag
+gnu_obj_2<long int>
+_ZNSs6insertEjRKSsjj
+_ZN13__type_traitsIbEaSERKS0_
+_ZNKSbIwSt11char_traitsIwESaIwEE4copyEPwjj
+_ZNSs9_M_mutateEjjj
+__ios_flags
+short unsigned int
+_ZNKSs4findEPKcj
+compare
+_ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_
+tm_yday
+unsigned char
+__stacksize
+__gconv_init_fct
+_IO_FILE
+__counter
+._26
+._27
+bidirectional_iterator_tag
+._29
+it_value
+const_iterator
+_ZNSt11__ios_flags6_S_outE
+_M_set_leaked
+_Is_integer<unsigned int>
+__value
+timeval
+_IO_jump_t
+_ZN11sched_paramaSERKS_
+__normal_iterator<char*,std::basic_string<char, std::char_traits<char>, std::allocator<char> > >
+_ZNSs4_Rep7_M_grabERKSaIcES2_
+_wide_vtable
+__codecvt_destr
+_STL_mutex_lock
+_ZNSt24__default_alloc_templateILb1ELi0EE17_S_freelist_indexEj
+_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjjw
+_ZN17__gconv_step_dataaSERKS_
+__w_stopval
+__int64_t
+__type_traits<double>
+~_Lock
+_ZNKSbIwSt11char_traitsIwESaIwEE5beginEv
+ptrdiff_t
+test
+_Integral
+cookie_seek_function_t
+__vmi_class_type_info
+_ZNSs7replaceEjjjc
+__int32_t
+register_t
+~_STL_auto_lock
+_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjj
+__arg
+_ZNSs7replaceEjjPKcj
+_ZNSbIwSt11char_traitsIwESaIwEE7replaceEjjRKS2_jj
+_ZNKSbIwSt11char_traitsIwESaIwEE12find_last_ofEPKwjj
+_ZN11_Is_integerImEaSERKS0_
+__default_alloc_template
+_S_hex
+__statep
+_ZNSt11char_traitsIwE2ltERKwS2_
+_M_p
+_ZNKSs4sizeEv
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-dwarf-ranges.sh b/third_party/elfutils/tests/run-dwarf-ranges.sh
new file mode 100755
index 0000000..d202ed3
--- /dev/null
+++ b/third_party/elfutils/tests/run-dwarf-ranges.sh
@@ -0,0 +1,27 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles debug-ranges-no-lowpc.o
+
+testrun_compare ${abs_builddir}/dwarf-ranges debug-ranges-no-lowpc.o 0xb <<\EOF
+1..2 (base 0)
+3..4 (base 0)
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-dwelfgnucompressed.sh b/third_party/elfutils/tests/run-dwelfgnucompressed.sh
new file mode 100755
index 0000000..b93a56f
--- /dev/null
+++ b/third_party/elfutils/tests/run-dwelfgnucompressed.sh
@@ -0,0 +1,108 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# = funcs.s =
+# .globl testfunc
+# testfunc:
+# 	nop
+# 	ret
+# .type testfunc, @function
+# .size testfunc, .-testfunc
+#
+# .globl testfunc2
+# testfunc2:
+# 	call testfunc
+# 	nop
+# 	nop
+# 	ret
+# .type testfunc2, @function
+# .size testfunc2, .-testfunc2
+#
+# .globl functest3
+# functest3:
+# 	jmp local
+# 	nop
+# 	nop
+# local:
+# 	call testfunc2
+# 	ret
+# .type functest3, @function
+# .size functest3, .-functest3
+
+# = start.s =
+# .global _start
+# _start:
+# 	call functest3
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	ret
+# .type _start, @function
+# .size _start, .-_start
+
+# gas --compress-debug-sections=zlib-gnu -32 -g -o start.o start.s
+# gas --compress-debug-sections=zlib-gnu -32 -g -o funcs.o funcs.s
+# ld --compress-debug-sections=zlib-gnu -melf_i386 -g -o zgnu32 funcs.o start.o
+
+# gas --compress-debug-sections=zlib-gnu -64 -g -o start.o start.s
+# gas --compress-debug-sections=zlib-gnu -64 -g -o funcs.o funcs.s
+# ld --compress-debug-sections=zlib-gnu -g -o zgnu32 funcs.o start.o
+
+testfiles testfile-zgnu64
+testrun_compare ${abs_top_builddir}/tests/dwelfgnucompressed testfile-zgnu64 <<\EOF
+section 2: GNU Compressed size: 60
+section 3: GNU Compressed size: aa
+section 5: GNU Compressed size: 8d
+EOF
+
+testfiles testfile-zgnu64be
+testrun_compare ${abs_top_builddir}/tests/dwelfgnucompressed testfile-zgnu64be <<\EOF
+section 3: GNU Compressed size: 60
+section 4: GNU Compressed size: 7e
+section 6: GNU Compressed size: 8d
+EOF
+
+testfiles testfile-zgnu32
+testrun_compare ${abs_top_builddir}/tests/dwelfgnucompressed testfile-zgnu32 <<\EOF
+section 2: GNU Compressed size: 40
+section 3: GNU Compressed size: 9a
+section 5: GNU Compressed size: 85
+EOF
+
+testfiles testfile-zgnu32be
+testrun_compare ${abs_top_builddir}/tests/dwelfgnucompressed testfile-zgnu32be <<\EOF
+section 3: GNU Compressed size: 40
+section 4: GNU Compressed size: 6e
+section 6: GNU Compressed size: 85
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-dwfl-addr-sect.sh b/third_party/elfutils/tests/run-dwfl-addr-sect.sh
new file mode 100755
index 0000000..80da008
--- /dev/null
+++ b/third_party/elfutils/tests/run-dwfl-addr-sect.sh
@@ -0,0 +1,32 @@
+#! /bin/sh
+# Copyright (C) 2007-2009 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile43 testfile50
+
+testrun_compare ${abs_builddir}/dwfl-addr-sect -e testfile43 0x64 0x8 0x98 <<\EOF
+address 0x64 => module "" section 4 + 0
+address 0x8 => module "" section 1 + 0x8
+address 0x98 => module "" section 7 + 0
+EOF
+
+testrun_compare ${abs_builddir}/dwfl-addr-sect -e testfile50 0x1 <<\EOF
+address 0x1 => module "" section 1 + 0x1
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-dwfl-bug-offline-rel.sh b/third_party/elfutils/tests/run-dwfl-bug-offline-rel.sh
new file mode 100755
index 0000000..fa476c4
--- /dev/null
+++ b/third_party/elfutils/tests/run-dwfl-bug-offline-rel.sh
@@ -0,0 +1,28 @@
+#! /bin/sh
+# Copyright (C) 2007 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile36 testfile36.debug
+
+testrun_compare ${abs_builddir}/dwflmodtest -e testfile36 <<\EOF
+module:                                00000000..00002308 testfile36 (null)
+module:                                00000000 DWARF 0 (no error)
+module:                                00000000..00002308 testfile36 testfile36.debug
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-dwfl-report-elf-align.sh b/third_party/elfutils/tests/run-dwfl-report-elf-align.sh
new file mode 100755
index 0000000..3849753
--- /dev/null
+++ b/third_party/elfutils/tests/run-dwfl-report-elf-align.sh
@@ -0,0 +1,44 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile-dwfl-report-elf-align-shlib.so
+
+# /proc/PID/maps when the process was running:
+# 7f3560c92000-7f3560c93000 r-xp 00000000 fd:02 25037063 testfile-dwfl-report-elf-align-shlib.so
+# 7f3560c93000-7f3560e92000 ---p 00001000 fd:02 25037063 testfile-dwfl-report-elf-align-shlib.so
+# 7f3560e92000-7f3560e93000 rw-p 00000000 fd:02 25037063 testfile-dwfl-report-elf-align-shlib.so
+# testfile-dwfl-report-elf-align-shlib.so:
+# Program Headers:
+#   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+#   LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x00065c 0x00065c R E 0x200000
+#   LOAD           0x000660 0x0000000000200660 0x0000000000200660 0x0001f0 0x000200 RW  0x200000
+# Symbol table '.dynsym' contains 12 entries:
+#    Num:    Value          Size Type    Bind   Vis      Ndx Name
+#      8: 000000000000057c    11 FUNC    GLOBAL DEFAULT   11 shlib
+# GDB output showing proper relocation:
+# #1  0x00007f3560c92585 in shlib () from ./testfile-dwfl-report-elf-align-shlib.so
+#
+# 0x7f3560c92000 is VMA address of first byte of testfile-dwfl-report-elf-align-shlib.so.
+# 0x7f3560c92585 = 0x7f3560c92000 + 0x585
+# where 0x585 is any address inside the shlib function: 0x57c .. 0x57c + 11 -1
+
+testrun ${abs_builddir}/dwfl-report-elf-align ./testfile-dwfl-report-elf-align-shlib.so \
+				0x7f3560c92000 0x7f3560c92585 shlib
+
+exit 0
diff --git a/third_party/elfutils/tests/run-dwfllines.sh b/third_party/elfutils/tests/run-dwfllines.sh
new file mode 100755
index 0000000..b384de0
--- /dev/null
+++ b/third_party/elfutils/tests/run-dwfllines.sh
@@ -0,0 +1,88 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile testfile2
+
+testrun_compare ${abs_builddir}/dwfllines -e testfile <<\EOF
+mod:  CU: [b] m.c
+0 0x804842c /home/drepper/gnu/new-bu/build/ttt/m.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x8048432 /home/drepper/gnu/new-bu/build/ttt/m.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x804844d /home/drepper/gnu/new-bu/build/ttt/m.c:7:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x8048458 /home/drepper/gnu/new-bu/build/ttt/m.c:8:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+4 0x804845a /home/drepper/gnu/new-bu/build/ttt/m.c:8:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+mod:  CU: [ca] b.c
+0 0x804845c /home/drepper/gnu/new-bu/build/ttt/b.c:4:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x804845f /home/drepper/gnu/new-bu/build/ttt/b.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x8048464 /home/drepper/gnu/new-bu/build/ttt/b.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x8048466 /home/drepper/gnu/new-bu/build/ttt/b.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+mod:  CU: [15fc] f.c
+0 0x8048468 /home/drepper/gnu/new-bu/build/ttt/f.c:3:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x804846b /home/drepper/gnu/new-bu/build/ttt/f.c:4:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x8048470 /home/drepper/gnu/new-bu/build/ttt/f.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x8048472 /home/drepper/gnu/new-bu/build/ttt/f.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+EOF
+
+testrun_compare ${abs_builddir}/dwfllines -e testfile2 <<\EOF
+mod:  CU: [b] b.c
+0 0x10000470 /shoggoth/drepper/b.c:4:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x1000047c /shoggoth/drepper/b.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x10000480 /shoggoth/drepper/b.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x10000490 /shoggoth/drepper/b.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+mod:  CU: [97d] f.c
+0 0x10000490 /shoggoth/drepper/f.c:3:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x1000049c /shoggoth/drepper/f.c:4:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x100004a0 /shoggoth/drepper/f.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x100004b0 /shoggoth/drepper/f.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+mod:  CU: [9e4] m.c
+0 0x100004b0 /shoggoth/drepper/m.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x100004cc /shoggoth/drepper/m.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x100004e8 /shoggoth/drepper/m.c:7:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x100004f4 /shoggoth/drepper/m.c:8:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+4 0x10000514 /shoggoth/drepper/m.c:8:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+EOF
+
+testrun_on_self_quiet ${abs_builddir}/dwfllines -e
+
+exit 0
diff --git a/third_party/elfutils/tests/run-dwflsyms.sh b/third_party/elfutils/tests/run-dwflsyms.sh
new file mode 100755
index 0000000..9726bcf
--- /dev/null
+++ b/third_party/elfutils/tests/run-dwflsyms.sh
@@ -0,0 +1,826 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Tests dwfl_module_{addrsym,getsym,relocate_address}
+# See run-readelf-s.sh for how to generate test binaries.
+# In addition, *_pl files were created from their base file
+# with prelink -N, and *_plr with prelink -r 0x4200000000.
+
+testfiles testfilebaztab
+testfiles testfilebazdbg testfilebazdbg.debug
+testfiles testfilebazdbg_pl
+testfiles testfilebazdbg_plr
+testfiles testfilebazdyn
+testfiles testfilebazmdb
+testfiles testfilebazmin
+testfiles testfilebazmin_pl
+testfiles testfilebazmin_plr
+testfiles testfilebasmin
+testfiles testfilebaxmin
+
+tempfiles testfile.dynsym.in testfile.symtab.in testfile.minsym.in dwflsyms.out
+tempfiles testfile.symtab_pl.in testfile.minsym_pl.in 
+
+cat > testfile.symtab.in <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x238
+   2: SECTION	LOCAL	 (0) 0x254
+   3: SECTION	LOCAL	 (0) 0x274
+   4: SECTION	LOCAL	 (0) 0x298
+   5: SECTION	LOCAL	 (0) 0x2d8
+   6: SECTION	LOCAL	 (0) 0x428
+   7: SECTION	LOCAL	 (0) 0x4f2
+   8: SECTION	LOCAL	 (0) 0x510
+   9: SECTION	LOCAL	 (0) 0x530
+  10: SECTION	LOCAL	 (0) 0x638
+  11: SECTION	LOCAL	 (0) 0x680
+  12: SECTION	LOCAL	 (0) 0x6a0
+  13: SECTION	LOCAL	 (0) 0x6e0
+  14: SECTION	LOCAL	 (0) 0x8f4
+  15: SECTION	LOCAL	 (0) 0x900
+  16: SECTION	LOCAL	 (0) 0x904
+  17: SECTION	LOCAL	 (0) 0x948
+  18: SECTION	LOCAL	 (0) 0x200dd0
+  19: SECTION	LOCAL	 (0) 0x200dd8
+  20: SECTION	LOCAL	 (0) 0x200de0
+  21: SECTION	LOCAL	 (0) 0x200de8
+  22: SECTION	LOCAL	 (0) 0x200df0
+  23: SECTION	LOCAL	 (0) 0x200fc0
+  24: SECTION	LOCAL	 (0) 0x201000
+  25: SECTION	LOCAL	 (0) 0x201030
+  26: SECTION	LOCAL	 (0) 0x20103c
+  27: SECTION	LOCAL	 (0) 0
+  28: SECTION	LOCAL	 (0) 0
+  29: SECTION	LOCAL	 (0) 0
+  30: SECTION	LOCAL	 (0) 0
+  31: SECTION	LOCAL	 (0) 0
+  32: SECTION	LOCAL	 (0) 0
+  33: FILE	LOCAL	crtstuff.c (0) 0
+  34: OBJECT	LOCAL	__JCR_LIST__ (0) 0x200de0
+  35: FUNC	LOCAL	deregister_tm_clones (0) 0x710, rel: 0x710 (.text)
+  36: FUNC	LOCAL	register_tm_clones (0) 0x740, rel: 0x740 (.text)
+  37: FUNC	LOCAL	__do_global_dtors_aux (0) 0x780, rel: 0x780 (.text)
+  38: OBJECT	LOCAL	completed.6137 (1) 0x20103c
+  39: OBJECT	LOCAL	__do_global_dtors_aux_fini_array_entry (0) 0x200dd8
+  40: FUNC	LOCAL	frame_dummy (0) 0x7c0, rel: 0x7c0 (.text)
+  41: OBJECT	LOCAL	__frame_dummy_init_array_entry (0) 0x200dd0
+  42: FILE	LOCAL	foo.c (0) 0
+  43: FILE	LOCAL	bar.c (0) 0
+  44: OBJECT	LOCAL	b1 (4) 0x201034
+  45: FUNC	LOCAL	foo (20) 0x814, rel: 0x814 (.text)
+  46: FILE	LOCAL	crtstuff.c (0) 0
+  47: OBJECT	LOCAL	__FRAME_END__ (0) 0xa58
+  48: OBJECT	LOCAL	__JCR_END__ (0) 0x200de0
+  49: FILE	LOCAL	 (0) 0
+  50: NOTYPE	LOCAL	__init_array_end (0) 0x200dd8
+  51: OBJECT	LOCAL	_DYNAMIC (0) 0x200df0
+  52: NOTYPE	LOCAL	__init_array_start (0) 0x200dd0
+  53: OBJECT	LOCAL	_GLOBAL_OFFSET_TABLE_ (0) 0x201000
+  54: FUNC	GLOBAL	__libc_csu_fini (2) 0x8f0, rel: 0x8f0 (.text)
+  55: NOTYPE	WEAK	_ITM_deregisterTMCloneTable (0) 0
+  56: NOTYPE	WEAK	data_start (0) 0x201030
+  57: NOTYPE	GLOBAL	_edata (0) 0x20103c
+  58: FUNC	GLOBAL	bar (44) 0x828, rel: 0x828 (.text)
+  59: FUNC	GLOBAL	_fini (0) 0x8f4, rel: 0x8f4 (.fini)
+  60: FUNC	GLOBAL	__libc_start_main@@GLIBC_2.2.5 (0) 0
+  61: NOTYPE	GLOBAL	__data_start (0) 0x201030
+  62: NOTYPE	WEAK	__gmon_start__ (0) 0
+  63: OBJECT	GLOBAL	__dso_handle (0) 0x200de8
+  64: OBJECT	GLOBAL	_IO_stdin_used (4) 0x900
+  65: OBJECT	GLOBAL	b2 (4) 0x201038
+  66: FUNC	GLOBAL	__libc_csu_init (137) 0x860, rel: 0x860 (.text)
+  67: NOTYPE	GLOBAL	_end (0) 0x201040
+  68: FUNC	GLOBAL	_start (0) 0x6e0, rel: 0x6e0 (.text)
+  69: NOTYPE	GLOBAL	__bss_start (0) 0x20103c
+  70: FUNC	GLOBAL	main (35) 0x7f0, rel: 0x7f0 (.text)
+  71: NOTYPE	WEAK	_Jv_RegisterClasses (0) 0
+  72: OBJECT	GLOBAL	__TMC_END__ (0) 0x201040
+  73: NOTYPE	WEAK	_ITM_registerTMCloneTable (0) 0
+  74: FUNC	WEAK	__cxa_finalize@@GLIBC_2.2.5 (0) 0
+  75: FUNC	GLOBAL	_init (0) 0x680, rel: 0x680 (.init)
+EOF
+
+cat > testfile.symtab_pl.in <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x3000000238
+   2: SECTION	LOCAL	 (0) 0x3000000254
+   3: SECTION	LOCAL	 (0) 0x3000000274
+   4: SECTION	LOCAL	 (0) 0x3000000298
+   5: SECTION	LOCAL	 (0) 0x30000002d8
+   6: SECTION	LOCAL	 (0) 0x3000000428
+   7: SECTION	LOCAL	 (0) 0x30000004f2
+   8: SECTION	LOCAL	 (0) 0x3000000510
+   9: SECTION	LOCAL	 (0) 0x3000000530
+  10: SECTION	LOCAL	 (0) 0x3000000638
+  11: SECTION	LOCAL	 (0) 0x3000000680
+  12: SECTION	LOCAL	 (0) 0x30000006a0
+  13: SECTION	LOCAL	 (0) 0x30000006e0
+  14: SECTION	LOCAL	 (0) 0x30000008f4
+  15: SECTION	LOCAL	 (0) 0x3000000900
+  16: SECTION	LOCAL	 (0) 0x3000000904
+  17: SECTION	LOCAL	 (0) 0x3000000948
+  18: SECTION	LOCAL	 (0) 0x3000200dd0
+  19: SECTION	LOCAL	 (0) 0x3000200dd8
+  20: SECTION	LOCAL	 (0) 0x3000200de0
+  21: SECTION	LOCAL	 (0) 0x3000200de8
+  22: SECTION	LOCAL	 (0) 0x3000200df0
+  23: SECTION	LOCAL	 (0) 0x3000200fc0
+  24: SECTION	LOCAL	 (0) 0x3000201000
+  25: SECTION	LOCAL	 (0) 0x3000201030
+  26: SECTION	LOCAL	 (0) 0x300020103c
+  27: SECTION	LOCAL	 (0) 0
+  28: SECTION	LOCAL	 (0) 0
+  29: SECTION	LOCAL	 (0) 0
+  30: SECTION	LOCAL	 (0) 0
+  31: SECTION	LOCAL	 (0) 0
+  32: SECTION	LOCAL	 (0) 0
+  33: FILE	LOCAL	crtstuff.c (0) 0
+  34: OBJECT	LOCAL	__JCR_LIST__ (0) 0x3000200de0
+  35: FUNC	LOCAL	deregister_tm_clones (0) 0x3000000710, rel: 0x710 (.text)
+  36: FUNC	LOCAL	register_tm_clones (0) 0x3000000740, rel: 0x740 (.text)
+  37: FUNC	LOCAL	__do_global_dtors_aux (0) 0x3000000780, rel: 0x780 (.text)
+  38: OBJECT	LOCAL	completed.6137 (1) 0x300020103c
+  39: OBJECT	LOCAL	__do_global_dtors_aux_fini_array_entry (0) 0x3000200dd8
+  40: FUNC	LOCAL	frame_dummy (0) 0x30000007c0, rel: 0x7c0 (.text)
+  41: OBJECT	LOCAL	__frame_dummy_init_array_entry (0) 0x3000200dd0
+  42: FILE	LOCAL	foo.c (0) 0
+  43: FILE	LOCAL	bar.c (0) 0
+  44: OBJECT	LOCAL	b1 (4) 0x3000201034
+  45: FUNC	LOCAL	foo (20) 0x3000000814, rel: 0x814 (.text)
+  46: FILE	LOCAL	crtstuff.c (0) 0
+  47: OBJECT	LOCAL	__FRAME_END__ (0) 0x3000000a58
+  48: OBJECT	LOCAL	__JCR_END__ (0) 0x3000200de0
+  49: FILE	LOCAL	 (0) 0
+  50: NOTYPE	LOCAL	__init_array_end (0) 0x3000200dd8
+  51: OBJECT	LOCAL	_DYNAMIC (0) 0x3000200df0
+  52: NOTYPE	LOCAL	__init_array_start (0) 0x3000200dd0
+  53: OBJECT	LOCAL	_GLOBAL_OFFSET_TABLE_ (0) 0x3000201000
+  54: FUNC	GLOBAL	__libc_csu_fini (2) 0x30000008f0, rel: 0x8f0 (.text)
+  55: NOTYPE	WEAK	_ITM_deregisterTMCloneTable (0) 0
+  56: NOTYPE	WEAK	data_start (0) 0x3000201030
+  57: NOTYPE	GLOBAL	_edata (0) 0x300020103c
+  58: FUNC	GLOBAL	bar (44) 0x3000000828, rel: 0x828 (.text)
+  59: FUNC	GLOBAL	_fini (0) 0x30000008f4, rel: 0x8f4 (.fini)
+  60: FUNC	GLOBAL	__libc_start_main@@GLIBC_2.2.5 (0) 0
+  61: NOTYPE	GLOBAL	__data_start (0) 0x3000201030
+  62: NOTYPE	WEAK	__gmon_start__ (0) 0
+  63: OBJECT	GLOBAL	__dso_handle (0) 0x3000200de8
+  64: OBJECT	GLOBAL	_IO_stdin_used (4) 0x3000000900
+  65: OBJECT	GLOBAL	b2 (4) 0x3000201038
+  66: FUNC	GLOBAL	__libc_csu_init (137) 0x3000000860, rel: 0x860 (.text)
+  67: NOTYPE	GLOBAL	_end (0) 0x3000201040
+  68: FUNC	GLOBAL	_start (0) 0x30000006e0, rel: 0x6e0 (.text)
+  69: NOTYPE	GLOBAL	__bss_start (0) 0x300020103c
+  70: FUNC	GLOBAL	main (35) 0x30000007f0, rel: 0x7f0 (.text)
+  71: NOTYPE	WEAK	_Jv_RegisterClasses (0) 0
+  72: OBJECT	GLOBAL	__TMC_END__ (0) 0x3000201040
+  73: NOTYPE	WEAK	_ITM_registerTMCloneTable (0) 0
+  74: FUNC	WEAK	__cxa_finalize@@GLIBC_2.2.5 (0) 0
+  75: FUNC	GLOBAL	_init (0) 0x3000000680, rel: 0x680 (.init)
+EOF
+
+cat > testfile.dynsym.in <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x238
+   2: NOTYPE	WEAK	_ITM_deregisterTMCloneTable (0) 0
+   3: FUNC	GLOBAL	__libc_start_main (0) 0
+   4: NOTYPE	WEAK	__gmon_start__ (0) 0
+   5: NOTYPE	WEAK	_Jv_RegisterClasses (0) 0
+   6: NOTYPE	WEAK	_ITM_registerTMCloneTable (0) 0
+   7: FUNC	WEAK	__cxa_finalize (0) 0
+   8: NOTYPE	GLOBAL	_edata (0) 0x20103c
+   9: NOTYPE	GLOBAL	_end (0) 0x201040
+  10: FUNC	GLOBAL	__libc_csu_init (137) 0x860, rel: 0x860 (.text)
+  11: NOTYPE	GLOBAL	__bss_start (0) 0x20103c
+  12: FUNC	GLOBAL	main (35) 0x7f0, rel: 0x7f0 (.text)
+  13: FUNC	GLOBAL	__libc_csu_fini (2) 0x8f0, rel: 0x8f0 (.text)
+EOF
+
+cat > testfile.minsym.in <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x238
+   2: FUNC	LOCAL	deregister_tm_clones (0) 0x710, rel: 0x710 (.text)
+   3: FUNC	LOCAL	register_tm_clones (0) 0x740, rel: 0x740 (.text)
+   4: FUNC	LOCAL	__do_global_dtors_aux (0) 0x780, rel: 0x780 (.text)
+   5: OBJECT	LOCAL	__do_global_dtors_aux_fini_array_entry (0) 0x200dd8
+   6: FUNC	LOCAL	frame_dummy (0) 0x7c0, rel: 0x7c0 (.text)
+   7: OBJECT	LOCAL	__frame_dummy_init_array_entry (0) 0x200dd0
+   8: FUNC	LOCAL	foo (20) 0x814, rel: 0x814 (.text)
+   9: NOTYPE	LOCAL	__init_array_end (0) 0x200dd8
+  10: NOTYPE	LOCAL	__init_array_start (0) 0x200dd0
+  11: SECTION	LOCAL	 (0) 0x238
+  12: SECTION	LOCAL	 (0) 0x254
+  13: SECTION	LOCAL	 (0) 0x274
+  14: SECTION	LOCAL	 (0) 0x298
+  15: SECTION	LOCAL	 (0) 0x2d8
+  16: SECTION	LOCAL	 (0) 0x428
+  17: SECTION	LOCAL	 (0) 0x4f2
+  18: SECTION	LOCAL	 (0) 0x510
+  19: SECTION	LOCAL	 (0) 0x530
+  20: SECTION	LOCAL	 (0) 0x638
+  21: SECTION	LOCAL	 (0) 0x680
+  22: SECTION	LOCAL	 (0) 0x6a0
+  23: SECTION	LOCAL	 (0) 0x6e0
+  24: SECTION	LOCAL	 (0) 0x8f4
+  25: SECTION	LOCAL	 (0) 0x900
+  26: SECTION	LOCAL	 (0) 0x904
+  27: SECTION	LOCAL	 (0) 0x948
+  28: SECTION	LOCAL	 (0) 0x200dd0
+  29: SECTION	LOCAL	 (0) 0x200dd8
+  30: SECTION	LOCAL	 (0) 0x200de0
+  31: SECTION	LOCAL	 (0) 0x200de8
+  32: SECTION	LOCAL	 (0) 0x200df0
+  33: SECTION	LOCAL	 (0) 0x200fc0
+  34: SECTION	LOCAL	 (0) 0x201000
+  35: SECTION	LOCAL	 (0) 0x201030
+  36: SECTION	LOCAL	 (0) 0x20103c
+  37: NOTYPE	WEAK	_ITM_deregisterTMCloneTable (0) 0
+  38: FUNC	GLOBAL	__libc_start_main (0) 0
+  39: NOTYPE	WEAK	__gmon_start__ (0) 0
+  40: NOTYPE	WEAK	_Jv_RegisterClasses (0) 0
+  41: NOTYPE	WEAK	_ITM_registerTMCloneTable (0) 0
+  42: FUNC	WEAK	__cxa_finalize (0) 0
+  43: NOTYPE	GLOBAL	_edata (0) 0x20103c
+  44: NOTYPE	GLOBAL	_end (0) 0x201040
+  45: FUNC	GLOBAL	__libc_csu_init (137) 0x860, rel: 0x860 (.text)
+  46: NOTYPE	GLOBAL	__bss_start (0) 0x20103c
+  47: FUNC	GLOBAL	main (35) 0x7f0, rel: 0x7f0 (.text)
+  48: FUNC	GLOBAL	__libc_csu_fini (2) 0x8f0, rel: 0x8f0 (.text)
+  49: FUNC	GLOBAL	bar (44) 0x828, rel: 0x828 (.text)
+  50: FUNC	GLOBAL	_fini (0) 0x8f4, rel: 0x8f4 (.fini)
+  51: FUNC	GLOBAL	_start (0) 0x6e0, rel: 0x6e0 (.text)
+  52: FUNC	GLOBAL	_init (0) 0x680, rel: 0x680 (.init)
+EOF
+
+cat > testfile.minsym_pl.in <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x3000000238
+   2: FUNC	LOCAL	deregister_tm_clones (0) 0x3000000710, rel: 0x710 (.text)
+   3: FUNC	LOCAL	register_tm_clones (0) 0x3000000740, rel: 0x740 (.text)
+   4: FUNC	LOCAL	__do_global_dtors_aux (0) 0x3000000780, rel: 0x780 (.text)
+   5: OBJECT	LOCAL	__do_global_dtors_aux_fini_array_entry (0) 0x3000200dd8
+   6: FUNC	LOCAL	frame_dummy (0) 0x30000007c0, rel: 0x7c0 (.text)
+   7: OBJECT	LOCAL	__frame_dummy_init_array_entry (0) 0x3000200dd0
+   8: FUNC	LOCAL	foo (20) 0x3000000814, rel: 0x814 (.text)
+   9: NOTYPE	LOCAL	__init_array_end (0) 0x3000200dd8
+  10: NOTYPE	LOCAL	__init_array_start (0) 0x3000200dd0
+  11: SECTION	LOCAL	 (0) 0x3000000238
+  12: SECTION	LOCAL	 (0) 0x3000000254
+  13: SECTION	LOCAL	 (0) 0x3000000274
+  14: SECTION	LOCAL	 (0) 0x3000000298
+  15: SECTION	LOCAL	 (0) 0x30000002d8
+  16: SECTION	LOCAL	 (0) 0x3000000428
+  17: SECTION	LOCAL	 (0) 0x30000004f2
+  18: SECTION	LOCAL	 (0) 0x3000000510
+  19: SECTION	LOCAL	 (0) 0x3000000530
+  20: SECTION	LOCAL	 (0) 0x3000000638
+  21: SECTION	LOCAL	 (0) 0x3000000680
+  22: SECTION	LOCAL	 (0) 0x30000006a0
+  23: SECTION	LOCAL	 (0) 0x30000006e0
+  24: SECTION	LOCAL	 (0) 0x30000008f4
+  25: SECTION	LOCAL	 (0) 0x3000000900
+  26: SECTION	LOCAL	 (0) 0x3000000904
+  27: SECTION	LOCAL	 (0) 0x3000000948
+  28: SECTION	LOCAL	 (0) 0x3000200dd0
+  29: SECTION	LOCAL	 (0) 0x3000200dd8
+  30: SECTION	LOCAL	 (0) 0x3000200de0
+  31: SECTION	LOCAL	 (0) 0x3000200de8
+  32: SECTION	LOCAL	 (0) 0x3000200df0
+  33: SECTION	LOCAL	 (0) 0x3000200fc0
+  34: SECTION	LOCAL	 (0) 0x3000201000
+  35: SECTION	LOCAL	 (0) 0x3000201030
+  36: SECTION	LOCAL	 (0) 0x300020103c
+  37: NOTYPE	WEAK	_ITM_deregisterTMCloneTable (0) 0
+  38: FUNC	GLOBAL	__libc_start_main (0) 0
+  39: NOTYPE	WEAK	__gmon_start__ (0) 0
+  40: NOTYPE	WEAK	_Jv_RegisterClasses (0) 0
+  41: NOTYPE	WEAK	_ITM_registerTMCloneTable (0) 0
+  42: FUNC	WEAK	__cxa_finalize (0) 0
+  43: NOTYPE	GLOBAL	_edata (0) 0x300020103c
+  44: NOTYPE	GLOBAL	_end (0) 0x3000201040
+  45: FUNC	GLOBAL	__libc_csu_init (137) 0x3000000860, rel: 0x860 (.text)
+  46: NOTYPE	GLOBAL	__bss_start (0) 0x300020103c
+  47: FUNC	GLOBAL	main (35) 0x30000007f0, rel: 0x7f0 (.text)
+  48: FUNC	GLOBAL	__libc_csu_fini (2) 0x30000008f0, rel: 0x8f0 (.text)
+  49: FUNC	GLOBAL	bar (44) 0x3000000828, rel: 0x828 (.text)
+  50: FUNC	GLOBAL	_fini (0) 0x30000008f4, rel: 0x8f4 (.fini)
+  51: FUNC	GLOBAL	_start (0) 0x30000006e0, rel: 0x6e0 (.text)
+  52: FUNC	GLOBAL	_init (0) 0x3000000680, rel: 0x680 (.init)
+EOF
+
+cat testfile.symtab.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebaztab
+
+cat testfile.symtab.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazdbg
+
+cat testfile.symtab_pl.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazdbg_pl
+
+sed s/0x3000/0x4200/g testfile.symtab_pl.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazdbg_plr
+
+cat testfile.dynsym.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazdyn
+
+cat testfile.symtab.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazmdb
+
+cat testfile.minsym.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazmin
+
+cat testfile.minsym_pl.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazmin_pl
+
+sed s/0x3000/0x4200/g testfile.minsym_pl.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazmin_plr
+
+testrun_compare ${abs_builddir}/dwflsyms -e testfilebasmin <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: FUNC	LOCAL	foo (18) 0x400168, rel: 0x400168 (.text)
+   2: SECTION	LOCAL	 (0) 0x400120
+   3: SECTION	LOCAL	 (0) 0x400144
+   4: SECTION	LOCAL	 (0) 0x4001c0
+   5: SECTION	LOCAL	 (0) 0x600258
+   6: FUNC	GLOBAL	_start (21) 0x4001a8, rel: 0x4001a8 (.text)
+   7: FUNC	GLOBAL	main (33) 0x400144, rel: 0x400144 (.text)
+   8: FUNC	GLOBAL	bar (44) 0x40017a, rel: 0x40017a (.text)
+EOF
+
+testrun_compare ${abs_builddir}/dwflsyms -e testfilebaxmin <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: FUNC	LOCAL	deregister_tm_clones (0) 0x400430, rel: 0x400430 (.text)
+   2: FUNC	LOCAL	register_tm_clones (0) 0x400460, rel: 0x400460 (.text)
+   3: FUNC	LOCAL	__do_global_dtors_aux (0) 0x4004a0, rel: 0x4004a0 (.text)
+   4: OBJECT	LOCAL	__do_global_dtors_aux_fini_array_entry (0) 0x600e18
+   5: FUNC	LOCAL	frame_dummy (0) 0x4004c0, rel: 0x4004c0 (.text)
+   6: OBJECT	LOCAL	__frame_dummy_init_array_entry (0) 0x600e10
+   7: FUNC	LOCAL	foo (20) 0x4004f0, rel: 0x4004f0 (.text)
+   8: NOTYPE	LOCAL	__init_array_end (0) 0x600e18
+   9: NOTYPE	LOCAL	__init_array_start (0) 0x600e10
+  10: SECTION	LOCAL	 (0) 0x400238
+  11: SECTION	LOCAL	 (0) 0x400254
+  12: SECTION	LOCAL	 (0) 0x400274
+  13: SECTION	LOCAL	 (0) 0x400298
+  14: SECTION	LOCAL	 (0) 0x4002b8
+  15: SECTION	LOCAL	 (0) 0x400300
+  16: SECTION	LOCAL	 (0) 0x400338
+  17: SECTION	LOCAL	 (0) 0x400340
+  18: SECTION	LOCAL	 (0) 0x400360
+  19: SECTION	LOCAL	 (0) 0x400378
+  20: SECTION	LOCAL	 (0) 0x4003a8
+  21: SECTION	LOCAL	 (0) 0x4003d0
+  22: SECTION	LOCAL	 (0) 0x400400
+  23: SECTION	LOCAL	 (0) 0x4005c4
+  24: SECTION	LOCAL	 (0) 0x4005d0
+  25: SECTION	LOCAL	 (0) 0x4005e0
+  26: SECTION	LOCAL	 (0) 0x400628
+  27: SECTION	LOCAL	 (0) 0x600e10
+  28: SECTION	LOCAL	 (0) 0x600e18
+  29: SECTION	LOCAL	 (0) 0x600e20
+  30: SECTION	LOCAL	 (0) 0x600e28
+  31: SECTION	LOCAL	 (0) 0x600ff8
+  32: SECTION	LOCAL	 (0) 0x601000
+  33: SECTION	LOCAL	 (0) 0x601028
+  34: SECTION	LOCAL	 (0) 0x601034
+  35: FUNC	GLOBAL	__libc_start_main (0) 0
+  36: NOTYPE	WEAK	__gmon_start__ (0) 0
+  37: FUNC	GLOBAL	__libc_csu_fini (2) 0x4005c0, rel: 0x4005c0 (.text)
+  38: FUNC	GLOBAL	bar (40) 0x400504, rel: 0x400504 (.text)
+  39: FUNC	GLOBAL	_fini (0) 0x4005c4, rel: 0x4005c4 (.fini)
+  40: FUNC	GLOBAL	__libc_csu_init (101) 0x400550, rel: 0x400550 (.text)
+  41: FUNC	GLOBAL	_start (0) 0x400400, rel: 0x400400 (.text)
+  42: FUNC	GLOBAL	main (35) 0x40052c, rel: 0x40052c (.text)
+  43: FUNC	GLOBAL	_init (0) 0x4003a8, rel: 0x4003a8 (.init)
+EOF
+
+testfiles testfile66
+testrun_compare ${abs_builddir}/dwflsyms -e testfile66 <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x190
+   2: SECTION	LOCAL	 (0) 0x1a4
+   3: SECTION	LOCAL	 (0) 0x1c8
+   4: SECTION	LOCAL	 (0) 0x1f8
+   5: SECTION	LOCAL	 (0) 0x288
+   6: SECTION	LOCAL	 (0) 0x2a8
+   7: SECTION	LOCAL	 (0) 0x2d8
+   8: SECTION	LOCAL	 (0) 0x102e0
+   9: SECTION	LOCAL	 (0) 0x103d0
+  10: SECTION	LOCAL	 (0) 0x103e8
+  11: SECTION	LOCAL	 (0) 0x103e8
+  12: OBJECT	LOCAL	_DYNAMIC (0) 0x102e0
+  13: FUNC	GLOBAL	_start (4) 0x103d0, rel: 0x103d0 (.opd) [0x2d8, rel: 0 (.text)]
+  14: NOTYPE	GLOBAL	__bss_start (0) 0x103f0
+  15: NOTYPE	GLOBAL	_edata (0) 0x103f0
+  16: NOTYPE	GLOBAL	_end (0) 0x103f0
+EOF
+
+testfiles testfile66.core
+testrun_compare ${abs_builddir}/dwflsyms -e testfile66 --core=testfile66.core <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0xfffb1af0410
+   2: NOTYPE	GLOBAL	__kernel_datapage_offset (0) 0xfffb1af05dc
+   3: OBJECT	GLOBAL	LINUX_2.6.15 (0) 0
+   4: NOTYPE	GLOBAL	__kernel_clock_getres (64) 0xfffb1af052c
+   5: NOTYPE	GLOBAL	__kernel_get_tbfreq (24) 0xfffb1af0620
+   6: NOTYPE	GLOBAL	__kernel_gettimeofday (84) 0xfffb1af0440
+   7: NOTYPE	GLOBAL	__kernel_sync_dicache (20) 0xfffb1af06c4
+   8: NOTYPE	GLOBAL	__kernel_sync_dicache_p5 (20) 0xfffb1af06c4
+   9: NOTYPE	GLOBAL	__kernel_sigtramp_rt64 (12) 0xfffb1af0418
+  10: NOTYPE	GLOBAL	__kernel_clock_gettime (152) 0xfffb1af0494
+  11: NOTYPE	GLOBAL	__kernel_get_syscall_map (44) 0xfffb1af05f4
+ld64.so.1: Callback returned failure
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x461b0190
+   2: SECTION	LOCAL	 (0) 0x461b01a4
+   3: SECTION	LOCAL	 (0) 0x461b01c8
+   4: SECTION	LOCAL	 (0) 0x461b01f8
+   5: SECTION	LOCAL	 (0) 0x461b0288
+   6: SECTION	LOCAL	 (0) 0x461b02a8
+   7: SECTION	LOCAL	 (0) 0x461b02d8
+   8: SECTION	LOCAL	 (0) 0x461c02e0
+   9: SECTION	LOCAL	 (0) 0x461c03d0
+  10: SECTION	LOCAL	 (0) 0x461c03e8
+  11: SECTION	LOCAL	 (0) 0x461c03e8
+  12: OBJECT	LOCAL	_DYNAMIC (0) 0x102e0
+  13: FUNC	GLOBAL	_start (4) 0x461c03d0, rel: 0x103d0 (.opd) [0x461b02d8, rel: 0 (.text)]
+  14: NOTYPE	GLOBAL	__bss_start (0) 0x103f0
+  15: NOTYPE	GLOBAL	_edata (0) 0x103f0
+  16: NOTYPE	GLOBAL	_end (0) 0x103f0
+EOF
+
+# Test the already present dot-prefixed names do not get duplicated.
+testfiles hello_ppc64.ko
+testrun_compare ${abs_builddir}/dwflsyms -e hello_ppc64.ko <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0
+   2: SECTION	LOCAL	 (0) 0x94
+   3: SECTION	LOCAL	 (0) 0xba
+   4: SECTION	LOCAL	 (0) 0xd0
+   5: SECTION	LOCAL	 (0) 0x13a
+   6: SECTION	LOCAL	 (0) 0x13a
+   7: SECTION	LOCAL	 (0) 0x150
+   8: SECTION	LOCAL	 (0) 0x170
+   9: SECTION	LOCAL	 (0) 0x188
+  10: SECTION	LOCAL	 (0) 0x410
+  11: SECTION	LOCAL	 (0) 0x434
+  12: SECTION	LOCAL	 (0) 0x438
+  13: SECTION	LOCAL	 (0) 0x438
+  14: SECTION	LOCAL	 (0) 0
+  15: SECTION	LOCAL	 (0) 0
+  16: SECTION	LOCAL	 (0) 0
+  17: SECTION	LOCAL	 (0) 0
+  18: SECTION	LOCAL	 (0) 0
+  19: SECTION	LOCAL	 (0) 0
+  20: SECTION	LOCAL	 (0) 0
+  21: SECTION	LOCAL	 (0) 0
+  22: SECTION	LOCAL	 (0) 0
+  23: SECTION	LOCAL	 (0) 0
+  24: FILE	LOCAL	init.c (0) 0
+  25: FILE	LOCAL	exit.c (0) 0
+  26: FILE	LOCAL	hello.mod.c (0) 0
+  27: OBJECT	LOCAL	__mod_srcversion23 (35) 0xd0
+  28: OBJECT	LOCAL	__module_depends (9) 0xf8
+  29: OBJECT	LOCAL	__mod_vermagic5 (50) 0x108
+  30: OBJECT	GLOBAL	__this_module (648) 0x188
+  31: FUNC	GLOBAL	.cleanup_module (72) 0x4c, rel: 0x4c (.text)
+  32: FUNC	GLOBAL	cleanup_module (24) 0x160, rel: 0x10 (.opd)
+  33: NOTYPE	GLOBAL	.printk (0) 0
+  34: FUNC	GLOBAL	init_module (24) 0x150, rel: 0 (.opd)
+  35: NOTYPE	GLOBAL	._mcount (0) 0
+  36: FUNC	GLOBAL	.init_module (76) 0, rel: 0 (.text)
+  37: NOTYPE	GLOBAL	_mcount (0) 0
+EOF
+
+# Same test files as above, but now generated on ppc64.
+# ppc64 uses function descriptors to make things more "interesting".
+
+testfiles testfilebaztabppc64
+testfiles testfilebazdbgppc64 testfilebazdbgppc64.debug
+testfiles testfilebazdbgppc64_pl
+testfiles testfilebazdbgppc64_plr
+testfiles testfilebazdynppc64
+testfiles testfilebazmdbppc64
+testfiles testfilebazminppc64
+testfiles testfilebazminppc64_pl
+testfiles testfilebazminppc64_plr
+
+cat > testfile.symtab.in <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x238
+   2: SECTION	LOCAL	 (0) 0x24c
+   3: SECTION	LOCAL	 (0) 0x26c
+   4: SECTION	LOCAL	 (0) 0x290
+   5: SECTION	LOCAL	 (0) 0x2c0
+   6: SECTION	LOCAL	 (0) 0x3e0
+   7: SECTION	LOCAL	 (0) 0x488
+   8: SECTION	LOCAL	 (0) 0x4a0
+   9: SECTION	LOCAL	 (0) 0x4c0
+  10: SECTION	LOCAL	 (0) 0x820
+  11: SECTION	LOCAL	 (0) 0x850
+  12: SECTION	LOCAL	 (0) 0x8a0
+  13: SECTION	LOCAL	 (0) 0xd30
+  14: SECTION	LOCAL	 (0) 0xd4c
+  15: SECTION	LOCAL	 (0) 0xd50
+  16: SECTION	LOCAL	 (0) 0xd70
+  17: SECTION	LOCAL	 (0) 0x1fde0
+  18: SECTION	LOCAL	 (0) 0x1fde8
+  19: SECTION	LOCAL	 (0) 0x1fdf0
+  20: SECTION	LOCAL	 (0) 0x1fdf8
+  21: SECTION	LOCAL	 (0) 0x1fe20
+  22: SECTION	LOCAL	 (0) 0x20000
+  23: SECTION	LOCAL	 (0) 0x20010
+  24: SECTION	LOCAL	 (0) 0x200d8
+  25: SECTION	LOCAL	 (0) 0x20110
+  26: SECTION	LOCAL	 (0) 0x20158
+  27: SECTION	LOCAL	 (0) 0
+  28: SECTION	LOCAL	 (0) 0
+  29: SECTION	LOCAL	 (0) 0
+  30: SECTION	LOCAL	 (0) 0
+  31: SECTION	LOCAL	 (0) 0
+  32: SECTION	LOCAL	 (0) 0
+  33: SECTION	LOCAL	 (0) 0
+  34: FILE	LOCAL	crtstuff.c (0) 0
+  35: OBJECT	LOCAL	__JCR_LIST__ (0) 0x1fdf0
+  36: FUNC	LOCAL	deregister_tm_clones (0) 0x20040, rel: 0x20040 (.opd) [0x910, rel: 0x70 (.text)]
+  37: FUNC	LOCAL	register_tm_clones (0) 0x20050, rel: 0x20050 (.opd) [0x980, rel: 0xe0 (.text)]
+  38: FUNC	LOCAL	__do_global_dtors_aux (0) 0x20060, rel: 0x20060 (.opd) [0x9f0, rel: 0x150 (.text)]
+  39: OBJECT	LOCAL	completed.7711 (1) 0x20158
+  40: OBJECT	LOCAL	__do_global_dtors_aux_fini_array_entry (0) 0x1fde8
+  41: FUNC	LOCAL	frame_dummy (0) 0x20070, rel: 0x20070 (.opd) [0xa50, rel: 0x1b0 (.text)]
+  42: OBJECT	LOCAL	__frame_dummy_init_array_entry (0) 0x1fde0
+  43: FILE	LOCAL	foo.c (0) 0
+  44: FILE	LOCAL	bar.c (0) 0
+  45: OBJECT	LOCAL	b1 (4) 0x20004
+  46: FUNC	LOCAL	foo (76) 0x20090, rel: 0x20090 (.opd) [0xb34, rel: 0x294 (.text)]
+  47: FILE	LOCAL	crtstuff.c (0) 0
+  48: OBJECT	LOCAL	__FRAME_END__ (0) 0xe18
+  49: OBJECT	LOCAL	__JCR_END__ (0) 0x1fdf0
+  50: FILE	LOCAL	 (0) 0
+  51: NOTYPE	LOCAL	__glink_PLTresolve (0) 0xce8
+  52: NOTYPE	LOCAL	00000011.plt_call.__libc_start_main@@GLIBC_2.3 (0) 0x8a0
+  53: NOTYPE	LOCAL	00000011.plt_call.__cxa_finalize@@GLIBC_2.3 (0) 0x8b4
+  54: NOTYPE	LOCAL	__init_array_end (0) 0x1fde8
+  55: OBJECT	LOCAL	_DYNAMIC (0) 0x1fe20
+  56: NOTYPE	LOCAL	__init_array_start (0) 0x1fde0
+  57: FUNC	GLOBAL	__libc_csu_fini (16) 0x200c0, rel: 0x200c0 (.opd) [0xcd0, rel: 0x430 (.text)]
+  58: FUNC	GLOBAL	__libc_start_main@@GLIBC_2.3 (0) 0
+  59: NOTYPE	WEAK	_ITM_deregisterTMCloneTable (0) 0
+  60: NOTYPE	WEAK	data_start (0) 0x20000
+  61: NOTYPE	GLOBAL	_edata (0) 0x20110
+  62: FUNC	GLOBAL	bar (116) 0x200a0, rel: 0x200a0 (.opd) [0xb80, rel: 0x2e0 (.text)]
+  63: FUNC	GLOBAL	_fini (0) 0x20030, rel: 0x20030 (.opd) [0xd30, rel: 0 (.fini)]
+  64: NOTYPE	GLOBAL	__data_start (0) 0x20000
+  65: NOTYPE	WEAK	__gmon_start__ (0) 0
+  66: OBJECT	GLOBAL	__dso_handle (0) 0x1fe18
+  67: OBJECT	GLOBAL	_IO_stdin_used (4) 0xd4c
+  68: OBJECT	GLOBAL	b2 (4) 0x20008
+  69: FUNC	WEAK	__cxa_finalize@@GLIBC_2.3 (0) 0
+  70: FUNC	GLOBAL	__libc_csu_init (204) 0x200b0, rel: 0x200b0 (.opd) [0xc00, rel: 0x360 (.text)]
+  71: NOTYPE	GLOBAL	_end (0) 0x20160
+  72: FUNC	GLOBAL	_start (60) 0x20010, rel: 0x20010 (.opd) [0x8c8, rel: 0x28 (.text)]
+  73: NOTYPE	GLOBAL	__bss_start (0) 0x20110
+  74: FUNC	GLOBAL	main (128) 0x20080, rel: 0x20080 (.opd) [0xab4, rel: 0x214 (.text)]
+  75: NOTYPE	WEAK	_Jv_RegisterClasses (0) 0
+  76: OBJECT	GLOBAL	__TMC_END__ (0) 0x20010
+  77: NOTYPE	WEAK	_ITM_registerTMCloneTable (0) 0
+  78: FUNC	GLOBAL	_init (0) 0x20020, rel: 0x20020 (.opd) [0x850, rel: 0 (.init)]
+EOF
+
+cat > testfile.symtab_pl.in <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x8001000238
+   2: SECTION	LOCAL	 (0) 0x800100024c
+   3: SECTION	LOCAL	 (0) 0x800100026c
+   4: SECTION	LOCAL	 (0) 0x8001000290
+   5: SECTION	LOCAL	 (0) 0x80010002c0
+   6: SECTION	LOCAL	 (0) 0x80010003e0
+   7: SECTION	LOCAL	 (0) 0x8001000488
+   8: SECTION	LOCAL	 (0) 0x80010004a0
+   9: SECTION	LOCAL	 (0) 0x80010004c0
+  10: SECTION	LOCAL	 (0) 0x8001000820
+  11: SECTION	LOCAL	 (0) 0x8001000850
+  12: SECTION	LOCAL	 (0) 0x80010008a0
+  13: SECTION	LOCAL	 (0) 0x8001000d30
+  14: SECTION	LOCAL	 (0) 0x8001000d4c
+  15: SECTION	LOCAL	 (0) 0x8001000d50
+  16: SECTION	LOCAL	 (0) 0x8001000d70
+  17: SECTION	LOCAL	 (0) 0x800101fde0
+  18: SECTION	LOCAL	 (0) 0x800101fde8
+  19: SECTION	LOCAL	 (0) 0x800101fdf0
+  20: SECTION	LOCAL	 (0) 0x800101fdf8
+  21: SECTION	LOCAL	 (0) 0x800101fe20
+  22: SECTION	LOCAL	 (0) 0x8001020000
+  23: SECTION	LOCAL	 (0) 0x8001020010
+  24: SECTION	LOCAL	 (0) 0x80010200d8
+  25: SECTION	LOCAL	 (0) 0x8001020110
+  26: SECTION	LOCAL	 (0) 0x8001020158
+  27: SECTION	LOCAL	 (0) 0
+  28: SECTION	LOCAL	 (0) 0
+  29: SECTION	LOCAL	 (0) 0
+  30: SECTION	LOCAL	 (0) 0
+  31: SECTION	LOCAL	 (0) 0
+  32: SECTION	LOCAL	 (0) 0
+  33: SECTION	LOCAL	 (0) 0
+  34: FILE	LOCAL	crtstuff.c (0) 0
+  35: OBJECT	LOCAL	__JCR_LIST__ (0) 0x800101fdf0
+  36: FUNC	LOCAL	deregister_tm_clones (0) 0x8001020040, rel: 0x20040 (.opd) [0x8001000910, rel: 0x70 (.text)]
+  37: FUNC	LOCAL	register_tm_clones (0) 0x8001020050, rel: 0x20050 (.opd) [0x8001000980, rel: 0xe0 (.text)]
+  38: FUNC	LOCAL	__do_global_dtors_aux (0) 0x8001020060, rel: 0x20060 (.opd) [0x80010009f0, rel: 0x150 (.text)]
+  39: OBJECT	LOCAL	completed.7711 (1) 0x8001020158
+  40: OBJECT	LOCAL	__do_global_dtors_aux_fini_array_entry (0) 0x800101fde8
+  41: FUNC	LOCAL	frame_dummy (0) 0x8001020070, rel: 0x20070 (.opd) [0x8001000a50, rel: 0x1b0 (.text)]
+  42: OBJECT	LOCAL	__frame_dummy_init_array_entry (0) 0x800101fde0
+  43: FILE	LOCAL	foo.c (0) 0
+  44: FILE	LOCAL	bar.c (0) 0
+  45: OBJECT	LOCAL	b1 (4) 0x8001020004
+  46: FUNC	LOCAL	foo (76) 0x8001020090, rel: 0x20090 (.opd) [0x8001000b34, rel: 0x294 (.text)]
+  47: FILE	LOCAL	crtstuff.c (0) 0
+  48: OBJECT	LOCAL	__FRAME_END__ (0) 0x8001000e18
+  49: OBJECT	LOCAL	__JCR_END__ (0) 0x800101fdf0
+  50: FILE	LOCAL	 (0) 0
+  51: NOTYPE	LOCAL	__glink_PLTresolve (0) 0x8001000ce8
+  52: NOTYPE	LOCAL	00000011.plt_call.__libc_start_main@@GLIBC_2.3 (0) 0x80010008a0
+  53: NOTYPE	LOCAL	00000011.plt_call.__cxa_finalize@@GLIBC_2.3 (0) 0x80010008b4
+  54: NOTYPE	LOCAL	__init_array_end (0) 0x800101fde8
+  55: OBJECT	LOCAL	_DYNAMIC (0) 0x800101fe20
+  56: NOTYPE	LOCAL	__init_array_start (0) 0x800101fde0
+  57: FUNC	GLOBAL	__libc_csu_fini (16) 0x80010200c0, rel: 0x200c0 (.opd) [0x8001000cd0, rel: 0x430 (.text)]
+  58: FUNC	GLOBAL	__libc_start_main@@GLIBC_2.3 (0) 0
+  59: NOTYPE	WEAK	_ITM_deregisterTMCloneTable (0) 0
+  60: NOTYPE	WEAK	data_start (0) 0x8001020000
+  61: NOTYPE	GLOBAL	_edata (0) 0x8001020110
+  62: FUNC	GLOBAL	bar (116) 0x80010200a0, rel: 0x200a0 (.opd) [0x8001000b80, rel: 0x2e0 (.text)]
+  63: FUNC	GLOBAL	_fini (0) 0x8001020030, rel: 0x20030 (.opd) [0x8001000d30, rel: 0 (.fini)]
+  64: NOTYPE	GLOBAL	__data_start (0) 0x8001020000
+  65: NOTYPE	WEAK	__gmon_start__ (0) 0
+  66: OBJECT	GLOBAL	__dso_handle (0) 0x800101fe18
+  67: OBJECT	GLOBAL	_IO_stdin_used (4) 0x8001000d4c
+  68: OBJECT	GLOBAL	b2 (4) 0x8001020008
+  69: FUNC	WEAK	__cxa_finalize@@GLIBC_2.3 (0) 0
+  70: FUNC	GLOBAL	__libc_csu_init (204) 0x80010200b0, rel: 0x200b0 (.opd) [0x8001000c00, rel: 0x360 (.text)]
+  71: NOTYPE	GLOBAL	_end (0) 0x8001020160
+  72: FUNC	GLOBAL	_start (60) 0x8001020010, rel: 0x20010 (.opd) [0x80010008c8, rel: 0x28 (.text)]
+  73: NOTYPE	GLOBAL	__bss_start (0) 0x8001020110
+  74: FUNC	GLOBAL	main (128) 0x8001020080, rel: 0x20080 (.opd) [0x8001000ab4, rel: 0x214 (.text)]
+  75: NOTYPE	WEAK	_Jv_RegisterClasses (0) 0
+  76: OBJECT	GLOBAL	__TMC_END__ (0) 0x8001020010
+  77: NOTYPE	WEAK	_ITM_registerTMCloneTable (0) 0
+  78: FUNC	GLOBAL	_init (0) 0x8001020020, rel: 0x20020 (.opd) [0x8001000850, rel: 0 (.init)]
+EOF
+
+cat > testfile.dynsym.in <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x238
+   2: SECTION	LOCAL	 (0) 0x1fdf0
+   3: FUNC	GLOBAL	__libc_start_main (0) 0
+   4: NOTYPE	WEAK	_ITM_deregisterTMCloneTable (0) 0
+   5: NOTYPE	WEAK	__gmon_start__ (0) 0
+   6: FUNC	WEAK	__cxa_finalize (0) 0
+   7: NOTYPE	WEAK	_Jv_RegisterClasses (0) 0
+   8: NOTYPE	WEAK	_ITM_registerTMCloneTable (0) 0
+   9: NOTYPE	GLOBAL	_edata (0) 0x20110
+  10: NOTYPE	GLOBAL	_end (0) 0x20160
+  11: NOTYPE	GLOBAL	__bss_start (0) 0x20110
+EOF
+
+cat > testfile.minsym.in <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x238
+   2: SECTION	LOCAL	 (0) 0x1fdf0
+   3: OBJECT	LOCAL	__do_global_dtors_aux_fini_array_entry (0) 0x1fde8
+   4: OBJECT	LOCAL	__frame_dummy_init_array_entry (0) 0x1fde0
+   5: NOTYPE	LOCAL	__glink_PLTresolve (0) 0xce8
+   6: NOTYPE	LOCAL	00000011.plt_call.__libc_start_main@@GLIBC_2.3 (0) 0x8a0
+   7: NOTYPE	LOCAL	00000011.plt_call.__cxa_finalize@@GLIBC_2.3 (0) 0x8b4
+   8: NOTYPE	LOCAL	__init_array_end (0) 0x1fde8
+   9: NOTYPE	LOCAL	__init_array_start (0) 0x1fde0
+  10: SECTION	LOCAL	 (0) 0x238
+  11: SECTION	LOCAL	 (0) 0x24c
+  12: SECTION	LOCAL	 (0) 0x26c
+  13: SECTION	LOCAL	 (0) 0x290
+  14: SECTION	LOCAL	 (0) 0x2c0
+  15: SECTION	LOCAL	 (0) 0x3e0
+  16: SECTION	LOCAL	 (0) 0x488
+  17: SECTION	LOCAL	 (0) 0x4a0
+  18: SECTION	LOCAL	 (0) 0x4c0
+  19: SECTION	LOCAL	 (0) 0x820
+  20: SECTION	LOCAL	 (0) 0x850
+  21: SECTION	LOCAL	 (0) 0x8a0
+  22: SECTION	LOCAL	 (0) 0xd30
+  23: SECTION	LOCAL	 (0) 0xd4c
+  24: SECTION	LOCAL	 (0) 0xd50
+  25: SECTION	LOCAL	 (0) 0xd70
+  26: SECTION	LOCAL	 (0) 0x1fde0
+  27: SECTION	LOCAL	 (0) 0x1fde8
+  28: SECTION	LOCAL	 (0) 0x1fdf0
+  29: SECTION	LOCAL	 (0) 0x1fdf8
+  30: SECTION	LOCAL	 (0) 0x1fe20
+  31: SECTION	LOCAL	 (0) 0x20000
+  32: SECTION	LOCAL	 (0) 0x20010
+  33: SECTION	LOCAL	 (0) 0x200d8
+  34: SECTION	LOCAL	 (0) 0x20110
+  35: SECTION	LOCAL	 (0) 0x20158
+  36: FUNC	GLOBAL	__libc_start_main (0) 0
+  37: NOTYPE	WEAK	_ITM_deregisterTMCloneTable (0) 0
+  38: NOTYPE	WEAK	__gmon_start__ (0) 0
+  39: FUNC	WEAK	__cxa_finalize (0) 0
+  40: NOTYPE	WEAK	_Jv_RegisterClasses (0) 0
+  41: NOTYPE	WEAK	_ITM_registerTMCloneTable (0) 0
+  42: NOTYPE	GLOBAL	_edata (0) 0x20110
+  43: NOTYPE	GLOBAL	_end (0) 0x20160
+  44: NOTYPE	GLOBAL	__bss_start (0) 0x20110
+EOF
+
+cat > testfile.minsym_pl.in <<\EOF
+   0: NOTYPE	LOCAL	 (0) 0
+   1: SECTION	LOCAL	 (0) 0x8001000238
+   2: SECTION	LOCAL	 (0) 0x800101fdf0
+   3: OBJECT	LOCAL	__do_global_dtors_aux_fini_array_entry (0) 0x800101fde8
+   4: OBJECT	LOCAL	__frame_dummy_init_array_entry (0) 0x800101fde0
+   5: NOTYPE	LOCAL	__glink_PLTresolve (0) 0x8001000ce8
+   6: NOTYPE	LOCAL	00000011.plt_call.__libc_start_main@@GLIBC_2.3 (0) 0x80010008a0
+   7: NOTYPE	LOCAL	00000011.plt_call.__cxa_finalize@@GLIBC_2.3 (0) 0x80010008b4
+   8: NOTYPE	LOCAL	__init_array_end (0) 0x800101fde8
+   9: NOTYPE	LOCAL	__init_array_start (0) 0x800101fde0
+  10: SECTION	LOCAL	 (0) 0x8001000238
+  11: SECTION	LOCAL	 (0) 0x800100024c
+  12: SECTION	LOCAL	 (0) 0x800100026c
+  13: SECTION	LOCAL	 (0) 0x8001000290
+  14: SECTION	LOCAL	 (0) 0x80010002c0
+  15: SECTION	LOCAL	 (0) 0x80010003e0
+  16: SECTION	LOCAL	 (0) 0x8001000488
+  17: SECTION	LOCAL	 (0) 0x80010004a0
+  18: SECTION	LOCAL	 (0) 0x80010004c0
+  19: SECTION	LOCAL	 (0) 0x8001000820
+  20: SECTION	LOCAL	 (0) 0x8001000850
+  21: SECTION	LOCAL	 (0) 0x80010008a0
+  22: SECTION	LOCAL	 (0) 0x8001000d30
+  23: SECTION	LOCAL	 (0) 0x8001000d4c
+  24: SECTION	LOCAL	 (0) 0x8001000d50
+  25: SECTION	LOCAL	 (0) 0x8001000d70
+  26: SECTION	LOCAL	 (0) 0x800101fde0
+  27: SECTION	LOCAL	 (0) 0x800101fde8
+  28: SECTION	LOCAL	 (0) 0x800101fdf0
+  29: SECTION	LOCAL	 (0) 0x800101fdf8
+  30: SECTION	LOCAL	 (0) 0x800101fe20
+  31: SECTION	LOCAL	 (0) 0x8001020000
+  32: SECTION	LOCAL	 (0) 0x8001020010
+  33: SECTION	LOCAL	 (0) 0x80010200d8
+  34: SECTION	LOCAL	 (0) 0x8001020110
+  35: SECTION	LOCAL	 (0) 0x8001020158
+  36: FUNC	GLOBAL	__libc_start_main (0) 0
+  37: NOTYPE	WEAK	_ITM_deregisterTMCloneTable (0) 0
+  38: NOTYPE	WEAK	__gmon_start__ (0) 0
+  39: FUNC	WEAK	__cxa_finalize (0) 0
+  40: NOTYPE	WEAK	_Jv_RegisterClasses (0) 0
+  41: NOTYPE	WEAK	_ITM_registerTMCloneTable (0) 0
+  42: NOTYPE	GLOBAL	_edata (0) 0x8001020110
+  43: NOTYPE	GLOBAL	_end (0) 0x8001020160
+  44: NOTYPE	GLOBAL	__bss_start (0) 0x8001020110
+EOF
+
+cat testfile.symtab.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebaztabppc64
+
+cat testfile.symtab.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazdbgppc64
+
+cat testfile.symtab_pl.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazdbgppc64_pl
+
+sed s/0x8001/0x4200/g testfile.symtab_pl.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazdbgppc64_plr
+
+cat testfile.dynsym.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazdynppc64
+
+cat testfile.symtab.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazmdbppc64
+
+cat testfile.minsym.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazminppc64
+
+cat testfile.minsym_pl.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazminppc64_pl
+
+sed s/0x8001/0x4200/g testfile.minsym_pl.in \
+  | testrun_compare ${abs_builddir}/dwflsyms -e testfilebazminppc64_plr
+
+exit 0
diff --git a/third_party/elfutils/tests/run-early-offscn.sh b/third_party/elfutils/tests/run-early-offscn.sh
new file mode 100755
index 0000000..3757bcf
--- /dev/null
+++ b/third_party/elfutils/tests/run-early-offscn.sh
@@ -0,0 +1,24 @@
+#! /bin/sh
+# Copyright (C) 2008 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile
+
+testrun ${abs_builddir}/early-offscn testfile 0x500
+
+exit 0
diff --git a/third_party/elfutils/tests/run-ecp-test.sh b/third_party/elfutils/tests/run-ecp-test.sh
new file mode 100755
index 0000000..d5e376a
--- /dev/null
+++ b/third_party/elfutils/tests/run-ecp-test.sh
@@ -0,0 +1,28 @@
+#! /bin/sh
+# Copyright (C) 2002, 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Jakub Jelinek <jakub@redhat.com>, 2002.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile10
+tempfiles testfile10.tmp
+
+testrun ${abs_builddir}/ecp testfile10 testfile10.tmp
+
+cmp testfile10 testfile10.tmp
+
+exit 0
diff --git a/third_party/elfutils/tests/run-ecp-test2.sh b/third_party/elfutils/tests/run-ecp-test2.sh
new file mode 100755
index 0000000..864e0a5
--- /dev/null
+++ b/third_party/elfutils/tests/run-ecp-test2.sh
@@ -0,0 +1,26 @@
+#! /bin/sh
+# Copyright (C) 2002, 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Jakub Jelinek <jakub@redhat.com>, 2002.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile2
+tempfiles testfile2.tmp
+
+testrun ${abs_builddir}/ecp testfile2 testfile2.tmp
+
+exit 0
diff --git a/third_party/elfutils/tests/run-elf_cntl_gelf_getshdr.sh b/third_party/elfutils/tests/run-elf_cntl_gelf_getshdr.sh
new file mode 100755
index 0000000..94b477c
--- /dev/null
+++ b/third_party/elfutils/tests/run-elf_cntl_gelf_getshdr.sh
@@ -0,0 +1,30 @@
+#! /bin/sh
+# Copyright (C) 2012 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+tempfiles test_shdr.out
+
+# However we open the elf file, the shdrs should be the same.
+testrun ${abs_builddir}/test-elf_cntl_gelf_getshdr READ ${abs_builddir}/test-elf_cntl_gelf_getshdr \
+  > test_shdr.out
+
+testrun_compare ${abs_builddir}/test-elf_cntl_gelf_getshdr MMAP ${abs_builddir}/test-elf_cntl_gelf_getshdr \
+  < test_shdr.out
+
+testrun_compare ${abs_builddir}/test-elf_cntl_gelf_getshdr FDREAD ${abs_builddir}/test-elf_cntl_gelf_getshdr \
+  < test_shdr.out
diff --git a/third_party/elfutils/tests/run-elfgetchdr.sh b/third_party/elfutils/tests/run-elfgetchdr.sh
new file mode 100755
index 0000000..7a422f3
--- /dev/null
+++ b/third_party/elfutils/tests/run-elfgetchdr.sh
@@ -0,0 +1,188 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# = funcs.s =
+# .globl testfunc
+# testfunc:
+# 	nop
+# 	ret
+# .type testfunc, @function
+# .size testfunc, .-testfunc
+#
+# .globl testfunc2
+# testfunc2:
+# 	call testfunc
+# 	nop
+# 	nop
+# 	ret
+# .type testfunc2, @function
+# .size testfunc2, .-testfunc2
+#
+# .globl functest3
+# functest3:
+# 	jmp local
+# 	nop
+# 	nop
+# local:
+# 	call testfunc2
+# 	ret
+# .type functest3, @function
+# .size functest3, .-functest3
+
+# = start.s =
+# .global _start
+# _start:
+# 	call functest3
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	nop
+# 	ret
+# .type _start, @function
+# .size _start, .-_start
+
+# gas --compress-debug-sections=zlib-gnu -32 -g -o start.o start.s
+# gas --compress-debug-sections=zlib-gnu -32 -g -o funcs.o funcs.s
+# ld --compress-debug-sections=zlib-gnu -melf_i386 -g -o zgnu32 funcs.o start.o
+
+# gas --compress-debug-sections=zlib-gnu -64 -g -o start.o start.s
+# gas --compress-debug-sections=zlib-gnu -64 -g -o funcs.o funcs.s
+# ld --compress-debug-sections=zlib-gnu -g -o zgnu64 funcs.o start.o
+
+# gas --compress-debug-sections=zlib-gabi -32 -g -o start.o start.s
+# gas --compress-debug-sections=zlib-gabi -32 -g -o funcs.o funcs.s
+# ld --compress-debug-sections=zlib-gabi -melf_i386 -g -o zgabi32 funcs.o start.o
+
+# gas --compress-debug-sections=zlib-gabi -64 -g -o start.o start.s
+# gas --compress-debug-sections=zlib-gabi -64 -g -o funcs.o funcs.s
+# ld --compress-debug-sections=zlib-gabi -g -o zgabi64 funcs.o start.o
+
+testfiles testfile-zgnu64
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgnu64 <<\EOF
+section 1: NOT Compressed
+section 2: GNU Compressed size: 60
+section 3: GNU Compressed size: aa
+section 4: NOT Compressed
+section 5: GNU Compressed size: 8d
+section 6: NOT Compressed
+section 7: NOT Compressed
+section 8: NOT Compressed
+EOF
+
+testfiles testfile-zgabi64
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgabi64 <<\EOF
+section 1: NOT Compressed
+section 2: ELF Compressed ch_type: 1, ch_size: 60, ch_addralign: 10
+section 3: ELF Compressed ch_type: 1, ch_size: aa, ch_addralign: 1
+section 4: NOT Compressed
+section 5: ELF Compressed ch_type: 1, ch_size: 8d, ch_addralign: 1
+section 6: NOT Compressed
+section 7: NOT Compressed
+section 8: NOT Compressed
+EOF
+
+testfiles testfile-zgnu32
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgnu32 <<\EOF
+section 1: NOT Compressed
+section 2: GNU Compressed size: 40
+section 3: GNU Compressed size: 9a
+section 4: NOT Compressed
+section 5: GNU Compressed size: 85
+section 6: NOT Compressed
+section 7: NOT Compressed
+section 8: NOT Compressed
+EOF
+
+testfiles testfile-zgabi32
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgabi32 <<\EOF
+section 1: NOT Compressed
+section 2: ELF Compressed ch_type: 1, ch_size: 40, ch_addralign: 8
+section 3: ELF Compressed ch_type: 1, ch_size: 9a, ch_addralign: 1
+section 4: NOT Compressed
+section 5: ELF Compressed ch_type: 1, ch_size: 85, ch_addralign: 1
+section 6: NOT Compressed
+section 7: NOT Compressed
+section 8: NOT Compressed
+EOF
+
+testfiles testfile-zgnu64be
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgnu64be <<\EOF
+section 1: NOT Compressed
+section 2: NOT Compressed
+section 3: GNU Compressed size: 60
+section 4: GNU Compressed size: 7e
+section 5: NOT Compressed
+section 6: GNU Compressed size: 8d
+section 7: NOT Compressed
+section 8: NOT Compressed
+section 9: NOT Compressed
+EOF
+
+testfiles testfile-zgabi64be
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgabi64be <<\EOF
+section 1: NOT Compressed
+section 2: NOT Compressed
+section 3: ELF Compressed ch_type: 1, ch_size: 60, ch_addralign: 10
+section 4: ELF Compressed ch_type: 1, ch_size: 7e, ch_addralign: 1
+section 5: NOT Compressed
+section 6: ELF Compressed ch_type: 1, ch_size: 8d, ch_addralign: 1
+section 7: NOT Compressed
+section 8: NOT Compressed
+section 9: NOT Compressed
+EOF
+
+testfiles testfile-zgnu32be
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgnu32be <<\EOF
+section 1: NOT Compressed
+section 2: NOT Compressed
+section 3: GNU Compressed size: 40
+section 4: GNU Compressed size: 6e
+section 5: NOT Compressed
+section 6: GNU Compressed size: 85
+section 7: NOT Compressed
+section 8: NOT Compressed
+section 9: NOT Compressed
+EOF
+
+testfiles testfile-zgabi32be
+testrun_compare ${abs_top_builddir}/tests/elfgetchdr testfile-zgabi32be <<\EOF
+section 1: NOT Compressed
+section 2: NOT Compressed
+section 3: ELF Compressed ch_type: 1, ch_size: 40, ch_addralign: 8
+section 4: ELF Compressed ch_type: 1, ch_size: 6e, ch_addralign: 1
+section 5: NOT Compressed
+section 6: ELF Compressed ch_type: 1, ch_size: 85, ch_addralign: 1
+section 7: NOT Compressed
+section 8: NOT Compressed
+section 9: NOT Compressed
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-elfgetzdata.sh b/third_party/elfutils/tests/run-elfgetzdata.sh
new file mode 100755
index 0000000..e2df308
--- /dev/null
+++ b/third_party/elfutils/tests/run-elfgetzdata.sh
@@ -0,0 +1,214 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# See run-elfgetchdr.sh for testfiles.
+
+testfiles testfile-zgnu64
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgnu64 <<\EOF
+1: .text, NOT compressed
+2: .zdebug_aranges, GNU compressed, size: 60
+3: .zdebug_info, GNU compressed, size: aa
+4: .debug_abbrev, NOT compressed
+5: .zdebug_line, GNU compressed, size: 8d
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgnu64 <<\EOF
+1: .text, NOT compressed
+2: .zdebug_aranges, GNU compressed, size: 60
+3: .zdebug_info, GNU compressed, size: aa
+4: .debug_abbrev, NOT compressed
+5: .zdebug_line, GNU compressed, size: 8d
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
+testfiles testfile-zgnu64be
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgnu64be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .zdebug_aranges, GNU compressed, size: 60
+4: .zdebug_info, GNU compressed, size: 7e
+5: .debug_abbrev, NOT compressed
+6: .zdebug_line, GNU compressed, size: 8d
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgnu64be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .zdebug_aranges, GNU compressed, size: 60
+4: .zdebug_info, GNU compressed, size: 7e
+5: .debug_abbrev, NOT compressed
+6: .zdebug_line, GNU compressed, size: 8d
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
+testfiles testfile-zgabi64
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgabi64 <<\EOF
+1: .text, NOT compressed
+2: .debug_aranges, ELF compressed, size: 60
+3: .debug_info, ELF compressed, size: aa
+4: .debug_abbrev, NOT compressed
+5: .debug_line, ELF compressed, size: 8d
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgabi64 <<\EOF
+1: .text, NOT compressed
+2: .debug_aranges, ELF compressed, size: 60
+3: .debug_info, ELF compressed, size: aa
+4: .debug_abbrev, NOT compressed
+5: .debug_line, ELF compressed, size: 8d
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
+testfiles testfile-zgabi64be
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgabi64be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .debug_aranges, ELF compressed, size: 60
+4: .debug_info, ELF compressed, size: 7e
+5: .debug_abbrev, NOT compressed
+6: .debug_line, ELF compressed, size: 8d
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgabi64be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .debug_aranges, ELF compressed, size: 60
+4: .debug_info, ELF compressed, size: 7e
+5: .debug_abbrev, NOT compressed
+6: .debug_line, ELF compressed, size: 8d
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
+testfiles testfile-zgnu32
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgnu32 <<\EOF
+1: .text, NOT compressed
+2: .zdebug_aranges, GNU compressed, size: 40
+3: .zdebug_info, GNU compressed, size: 9a
+4: .debug_abbrev, NOT compressed
+5: .zdebug_line, GNU compressed, size: 85
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgnu32 <<\EOF
+1: .text, NOT compressed
+2: .zdebug_aranges, GNU compressed, size: 40
+3: .zdebug_info, GNU compressed, size: 9a
+4: .debug_abbrev, NOT compressed
+5: .zdebug_line, GNU compressed, size: 85
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
+testfiles testfile-zgnu32be
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgnu32be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .zdebug_aranges, GNU compressed, size: 40
+4: .zdebug_info, GNU compressed, size: 6e
+5: .debug_abbrev, NOT compressed
+6: .zdebug_line, GNU compressed, size: 85
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgnu32be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .zdebug_aranges, GNU compressed, size: 40
+4: .zdebug_info, GNU compressed, size: 6e
+5: .debug_abbrev, NOT compressed
+6: .zdebug_line, GNU compressed, size: 85
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
+testfiles testfile-zgabi32
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgabi32 <<\EOF
+1: .text, NOT compressed
+2: .debug_aranges, ELF compressed, size: 40
+3: .debug_info, ELF compressed, size: 9a
+4: .debug_abbrev, NOT compressed
+5: .debug_line, ELF compressed, size: 85
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgabi32 <<\EOF
+1: .text, NOT compressed
+2: .debug_aranges, ELF compressed, size: 40
+3: .debug_info, ELF compressed, size: 9a
+4: .debug_abbrev, NOT compressed
+5: .debug_line, ELF compressed, size: 85
+6: .shstrtab, NOT compressed
+7: .symtab, NOT compressed
+8: .strtab, NOT compressed
+EOF
+
+testfiles testfile-zgabi32be
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata read testfile-zgabi32be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .debug_aranges, ELF compressed, size: 40
+4: .debug_info, ELF compressed, size: 6e
+5: .debug_abbrev, NOT compressed
+6: .debug_line, ELF compressed, size: 85
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfgetzdata mmap testfile-zgabi32be <<\EOF
+1: .text, NOT compressed
+2: .eh_frame, NOT compressed
+3: .debug_aranges, ELF compressed, size: 40
+4: .debug_info, ELF compressed, size: 6e
+5: .debug_abbrev, NOT compressed
+6: .debug_line, ELF compressed, size: 85
+7: .shstrtab, NOT compressed
+8: .symtab, NOT compressed
+9: .strtab, NOT compressed
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-elflint-self.sh b/third_party/elfutils/tests/run-elflint-self.sh
new file mode 100755
index 0000000..58fa7d0
--- /dev/null
+++ b/third_party/elfutils/tests/run-elflint-self.sh
@@ -0,0 +1,22 @@
+#! /bin/sh
+# Copyright (C) 2005, 2007, 2017 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testrun_on_self ${abs_top_builddir}/src/elflint --quiet --gnu-ld
+testrun_on_self_compressed ${abs_top_builddir}/src/elflint --quiet --gnu-ld
diff --git a/third_party/elfutils/tests/run-elflint-test.sh b/third_party/elfutils/tests/run-elflint-test.sh
new file mode 100755
index 0000000..caf172a
--- /dev/null
+++ b/third_party/elfutils/tests/run-elflint-test.sh
@@ -0,0 +1,60 @@
+#! /bin/sh
+# Copyright (C) 2005, 2007, 2008, 2015 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile18
+
+testrun_compare ${abs_top_builddir}/src/elflint --gnu-ld testfile18 <<\EOF
+section [ 8] '.rela.dyn': relocation 1: copy relocation against symbol of type FUNC
+EOF
+
+testfiles testfile32
+testrun ${abs_top_builddir}/src/elflint -q testfile32
+
+testfiles testfile33
+testrun ${abs_top_builddir}/src/elflint -q testfile33
+
+testfiles testfile42
+testrun ${abs_top_builddir}/src/elflint -q --gnu-ld testfile42
+
+# Contains debuginfo, compress it, recheck
+tempfiles testfile42z
+testrun ${abs_top_builddir}/src/elfcompress -f -q -o testfile42z testfile42
+testrun ${abs_top_builddir}/src/elflint -q --gnu-ld testfile42z
+
+testfiles testfile46
+testrun ${abs_top_builddir}/src/elflint -q testfile46
+
+# see also run-readelf-d.sh
+testfiles testlib_dynseg.so
+testrun ${abs_top_builddir}/src/elflint -q --gnu-ld testlib_dynseg.so
+
+# s390x has SHT_HASH with sh_entsize 8 (really should be 4, but see common.h)
+# This was wrongly checked when comparing .gnu.hash and .hash.
+# Simple "int main (int argc, char **argv) { return 0; }"
+# gcc -Xlinker --hash-style=both -o testfile-s390x-hash-both s390x-hash-both.c
+testfiles testfile-s390x-hash-both
+testrun ${abs_top_builddir}/src/elflint -q --gnu-ld testfile-s390x-hash-both
+
+# Compress the symtab/strtab just because and recheck
+tempfiles testfile-s390x-hash-bothz
+testrun ${abs_top_builddir}/src/elfcompress -f -q --name='.s??tab' -o testfile-s390x-hash-bothz testfile-s390x-hash-both
+testrun ${abs_top_builddir}/src/elflint -q --gnu-ld testfile-s390x-hash-bothz
+
+exit 0
diff --git a/third_party/elfutils/tests/run-elfputzdata.sh b/third_party/elfutils/tests/run-elfputzdata.sh
new file mode 100755
index 0000000..b882b3f
--- /dev/null
+++ b/third_party/elfutils/tests/run-elfputzdata.sh
@@ -0,0 +1,340 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Random ELF32 testfile
+testfiles testfile4
+
+testrun_compare ${abs_top_builddir}/tests/elfputzdata gnu testfile4 <<\EOF
+Cannot compress 1 .interp
+Cannot compress 2 .note.ABI-tag
+Cannot compress 3 .hash
+Cannot compress 4 .dynsym
+Cannot compress 5 .dynstr
+Cannot compress 6 .gnu.version
+Cannot compress 7 .gnu.version_r
+Cannot compress 8 .rel.got
+Cannot compress 9 .rel.plt
+Cannot compress 10 .init
+Cannot compress 11 .plt
+Cannot compress 12 .text
+Cannot compress 13 .fini
+Cannot compress 14 .rodata
+Cannot compress 15 .data
+Cannot compress 16 .eh_frame
+Cannot compress 17 .gcc_except_table
+Cannot compress 18 .ctors
+Cannot compress 19 .dtors
+Cannot compress 20 .got
+Cannot compress 21 .dynamic
+Lets compress 22 .sbss, size: 0
+Cannot compress 23 .bss
+Lets compress 24 .stab, size: 21540
+Lets compress 25 .stabstr, size: 57297
+Lets compress 26 .comment, size: 648
+Lets compress 27 .debug_aranges, size: 56
+Lets compress 28 .debug_pubnames, size: 93
+Lets compress 29 .debug_info, size: 960
+Lets compress 30 .debug_abbrev, size: 405
+Lets compress 31 .debug_line, size: 189
+Lets compress 32 .note, size: 240
+Lets compress 33 .shstrtab, size: 320
+Lets compress 34 .symtab, size: 5488
+Lets compress 35 .strtab, size: 5727
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfputzdata elf testfile4 <<\EOF
+Cannot compress 1 .interp
+Cannot compress 2 .note.ABI-tag
+Cannot compress 3 .hash
+Cannot compress 4 .dynsym
+Cannot compress 5 .dynstr
+Cannot compress 6 .gnu.version
+Cannot compress 7 .gnu.version_r
+Cannot compress 8 .rel.got
+Cannot compress 9 .rel.plt
+Cannot compress 10 .init
+Cannot compress 11 .plt
+Cannot compress 12 .text
+Cannot compress 13 .fini
+Cannot compress 14 .rodata
+Cannot compress 15 .data
+Cannot compress 16 .eh_frame
+Cannot compress 17 .gcc_except_table
+Cannot compress 18 .ctors
+Cannot compress 19 .dtors
+Cannot compress 20 .got
+Cannot compress 21 .dynamic
+Lets compress 22 .sbss, size: 0
+Cannot compress 23 .bss
+Lets compress 24 .stab, size: 21540
+Lets compress 25 .stabstr, size: 57297
+Lets compress 26 .comment, size: 648
+Lets compress 27 .debug_aranges, size: 56
+Lets compress 28 .debug_pubnames, size: 93
+Lets compress 29 .debug_info, size: 960
+Lets compress 30 .debug_abbrev, size: 405
+Lets compress 31 .debug_line, size: 189
+Lets compress 32 .note, size: 240
+Lets compress 33 .shstrtab, size: 320
+Lets compress 34 .symtab, size: 5488
+Lets compress 35 .strtab, size: 5727
+EOF
+
+# Random ELF64 testfile
+testfiles testfile12
+
+testrun_compare ${abs_top_builddir}/tests/elfputzdata gnu testfile12 <<\EOF
+Cannot compress 1 .hash
+Cannot compress 2 .dynsym
+Cannot compress 3 .dynstr
+Cannot compress 4 .gnu.version
+Cannot compress 5 .gnu.version_r
+Cannot compress 6 .rela.dyn
+Cannot compress 7 .rela.plt
+Cannot compress 8 .init
+Cannot compress 9 .plt
+Cannot compress 10 .text
+Cannot compress 11 .fini
+Cannot compress 12 .rodata
+Cannot compress 13 .eh_frame_hdr
+Cannot compress 14 .eh_frame
+Cannot compress 15 .data
+Cannot compress 16 .dynamic
+Cannot compress 17 .ctors
+Cannot compress 18 .dtors
+Cannot compress 19 .jcr
+Cannot compress 20 .got
+Cannot compress 21 .bss
+Lets compress 22 .comment, size: 246
+Lets compress 23 .debug_aranges, size: 192
+Lets compress 24 .debug_pubnames, size: 26
+Lets compress 25 .debug_info, size: 3468
+Lets compress 26 .debug_abbrev, size: 341
+Lets compress 27 .debug_line, size: 709
+Lets compress 28 .debug_frame, size: 56
+Lets compress 29 .debug_str, size: 2235
+Lets compress 30 .debug_macinfo, size: 10518
+Lets compress 31 .shstrtab, size: 308
+Lets compress 32 .symtab, size: 1944
+Lets compress 33 .strtab, size: 757
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfputzdata elf testfile12 <<\EOF
+Cannot compress 1 .hash
+Cannot compress 2 .dynsym
+Cannot compress 3 .dynstr
+Cannot compress 4 .gnu.version
+Cannot compress 5 .gnu.version_r
+Cannot compress 6 .rela.dyn
+Cannot compress 7 .rela.plt
+Cannot compress 8 .init
+Cannot compress 9 .plt
+Cannot compress 10 .text
+Cannot compress 11 .fini
+Cannot compress 12 .rodata
+Cannot compress 13 .eh_frame_hdr
+Cannot compress 14 .eh_frame
+Cannot compress 15 .data
+Cannot compress 16 .dynamic
+Cannot compress 17 .ctors
+Cannot compress 18 .dtors
+Cannot compress 19 .jcr
+Cannot compress 20 .got
+Cannot compress 21 .bss
+Lets compress 22 .comment, size: 246
+Lets compress 23 .debug_aranges, size: 192
+Lets compress 24 .debug_pubnames, size: 26
+Lets compress 25 .debug_info, size: 3468
+Lets compress 26 .debug_abbrev, size: 341
+Lets compress 27 .debug_line, size: 709
+Lets compress 28 .debug_frame, size: 56
+Lets compress 29 .debug_str, size: 2235
+Lets compress 30 .debug_macinfo, size: 10518
+Lets compress 31 .shstrtab, size: 308
+Lets compress 32 .symtab, size: 1944
+Lets compress 33 .strtab, size: 757
+EOF
+
+# Random ELF64BE testfile
+testfiles testfileppc64
+
+testrun_compare ${abs_top_builddir}/tests/elfputzdata gnu testfileppc64 <<\EOF
+Cannot compress 1 .interp
+Cannot compress 2 .note.ABI-tag
+Cannot compress 3 .note.gnu.build-id
+Cannot compress 4 .gnu.hash
+Cannot compress 5 .dynsym
+Cannot compress 6 .dynstr
+Cannot compress 7 .gnu.version
+Cannot compress 8 .gnu.version_r
+Cannot compress 9 .rela.plt
+Cannot compress 10 .init
+Cannot compress 11 .text
+Cannot compress 12 .fini
+Cannot compress 13 .rodata
+Cannot compress 14 .eh_frame_hdr
+Cannot compress 15 .eh_frame
+Cannot compress 16 .init_array
+Cannot compress 17 .fini_array
+Cannot compress 18 .jcr
+Cannot compress 19 .dynamic
+Cannot compress 20 .data
+Cannot compress 21 .opd
+Cannot compress 22 .got
+Cannot compress 23 .plt
+Cannot compress 24 .bss
+Lets compress 25 .comment, size: 88
+Lets compress 26 .debug_aranges, size: 96
+Lets compress 27 .debug_info, size: 363
+Lets compress 28 .debug_abbrev, size: 315
+Lets compress 29 .debug_line, size: 119
+Lets compress 30 .debug_frame, size: 96
+Lets compress 31 .debug_str, size: 174
+Lets compress 32 .debug_loc, size: 171
+Lets compress 33 .debug_ranges, size: 32
+Lets compress 34 .shstrtab, size: 352
+Lets compress 35 .symtab, size: 1800
+Lets compress 36 .strtab, size: 602
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfputzdata elf testfileppc64 <<\EOF
+Cannot compress 1 .interp
+Cannot compress 2 .note.ABI-tag
+Cannot compress 3 .note.gnu.build-id
+Cannot compress 4 .gnu.hash
+Cannot compress 5 .dynsym
+Cannot compress 6 .dynstr
+Cannot compress 7 .gnu.version
+Cannot compress 8 .gnu.version_r
+Cannot compress 9 .rela.plt
+Cannot compress 10 .init
+Cannot compress 11 .text
+Cannot compress 12 .fini
+Cannot compress 13 .rodata
+Cannot compress 14 .eh_frame_hdr
+Cannot compress 15 .eh_frame
+Cannot compress 16 .init_array
+Cannot compress 17 .fini_array
+Cannot compress 18 .jcr
+Cannot compress 19 .dynamic
+Cannot compress 20 .data
+Cannot compress 21 .opd
+Cannot compress 22 .got
+Cannot compress 23 .plt
+Cannot compress 24 .bss
+Lets compress 25 .comment, size: 88
+Lets compress 26 .debug_aranges, size: 96
+Lets compress 27 .debug_info, size: 363
+Lets compress 28 .debug_abbrev, size: 315
+Lets compress 29 .debug_line, size: 119
+Lets compress 30 .debug_frame, size: 96
+Lets compress 31 .debug_str, size: 174
+Lets compress 32 .debug_loc, size: 171
+Lets compress 33 .debug_ranges, size: 32
+Lets compress 34 .shstrtab, size: 352
+Lets compress 35 .symtab, size: 1800
+Lets compress 36 .strtab, size: 602
+EOF
+
+# Random ELF32BE testfile
+testfiles testfileppc32
+
+testrun_compare ${abs_top_builddir}/tests/elfputzdata gnu testfileppc32 <<\EOF
+Cannot compress 1 .interp
+Cannot compress 2 .note.ABI-tag
+Cannot compress 3 .note.gnu.build-id
+Cannot compress 4 .gnu.hash
+Cannot compress 5 .dynsym
+Cannot compress 6 .dynstr
+Cannot compress 7 .gnu.version
+Cannot compress 8 .gnu.version_r
+Cannot compress 9 .rela.dyn
+Cannot compress 10 .rela.plt
+Cannot compress 11 .init
+Cannot compress 12 .text
+Cannot compress 13 .fini
+Cannot compress 14 .rodata
+Cannot compress 15 .eh_frame_hdr
+Cannot compress 16 .eh_frame
+Cannot compress 17 .init_array
+Cannot compress 18 .fini_array
+Cannot compress 19 .jcr
+Cannot compress 20 .got2
+Cannot compress 21 .dynamic
+Cannot compress 22 .got
+Cannot compress 23 .plt
+Cannot compress 24 .data
+Cannot compress 25 .sdata
+Cannot compress 26 .bss
+Lets compress 27 .comment, size: 88
+Lets compress 28 .debug_aranges, size: 64
+Lets compress 29 .debug_info, size: 319
+Lets compress 30 .debug_abbrev, size: 318
+Lets compress 31 .debug_line, size: 109
+Lets compress 32 .debug_frame, size: 64
+Lets compress 33 .debug_str, size: 179
+Lets compress 34 .debug_loc, size: 99
+Lets compress 35 .debug_ranges, size: 16
+Lets compress 36 .shstrtab, size: 370
+Lets compress 37 .symtab, size: 1232
+Lets compress 38 .strtab, size: 569
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/elfputzdata elf testfileppc32 <<\EOF
+Cannot compress 1 .interp
+Cannot compress 2 .note.ABI-tag
+Cannot compress 3 .note.gnu.build-id
+Cannot compress 4 .gnu.hash
+Cannot compress 5 .dynsym
+Cannot compress 6 .dynstr
+Cannot compress 7 .gnu.version
+Cannot compress 8 .gnu.version_r
+Cannot compress 9 .rela.dyn
+Cannot compress 10 .rela.plt
+Cannot compress 11 .init
+Cannot compress 12 .text
+Cannot compress 13 .fini
+Cannot compress 14 .rodata
+Cannot compress 15 .eh_frame_hdr
+Cannot compress 16 .eh_frame
+Cannot compress 17 .init_array
+Cannot compress 18 .fini_array
+Cannot compress 19 .jcr
+Cannot compress 20 .got2
+Cannot compress 21 .dynamic
+Cannot compress 22 .got
+Cannot compress 23 .plt
+Cannot compress 24 .data
+Cannot compress 25 .sdata
+Cannot compress 26 .bss
+Lets compress 27 .comment, size: 88
+Lets compress 28 .debug_aranges, size: 64
+Lets compress 29 .debug_info, size: 319
+Lets compress 30 .debug_abbrev, size: 318
+Lets compress 31 .debug_line, size: 109
+Lets compress 32 .debug_frame, size: 64
+Lets compress 33 .debug_str, size: 179
+Lets compress 34 .debug_loc, size: 99
+Lets compress 35 .debug_ranges, size: 16
+Lets compress 36 .shstrtab, size: 370
+Lets compress 37 .symtab, size: 1232
+Lets compress 38 .strtab, size: 569
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-elfstrmerge-test.sh b/third_party/elfutils/tests/run-elfstrmerge-test.sh
new file mode 100755
index 0000000..d08b6fc
--- /dev/null
+++ b/third_party/elfutils/tests/run-elfstrmerge-test.sh
@@ -0,0 +1,40 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Merge string tables of file and check result with elflint.
+testrun_elfcompress()
+{
+    testfile="$1"
+    testfiles ${testfile}
+
+    mergedfile="${testfile}.merged"
+    tempfiles ${mergedfile}
+
+    echo "merging string tables ${testfile} -> ${mergedfile}"
+    testrun ${abs_top_builddir}/tests/elfstrmerge -o ${mergedfile} ${testfile}
+    testrun ${abs_top_builddir}/src/elflint --gnu-ld ${mergedfile}
+}
+
+# Random ELF32 testfile with extra STT_SECTION symbols
+testrun_elfcompress testfile4
+
+# Random ELF64 testfile with extra STT_SECTION symbols
+testrun_elfcompress testfile12
+
+exit 0
diff --git a/third_party/elfutils/tests/run-exprlocs-self.sh b/third_party/elfutils/tests/run-exprlocs-self.sh
new file mode 100755
index 0000000..73d3ab9
--- /dev/null
+++ b/third_party/elfutils/tests/run-exprlocs-self.sh
@@ -0,0 +1,22 @@
+#! /bin/sh
+# Copyright (C) 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Just makes sure exprlocs doesn't crash, triggers self-check/asserts
+# or leaks memory under valgrind.
+testrun_on_self_quiet ${abs_top_builddir}/tests/varlocs --exprlocs -e
diff --git a/third_party/elfutils/tests/run-exprlocs.sh b/third_party/elfutils/tests/run-exprlocs.sh
new file mode 100755
index 0000000..379ca52
--- /dev/null
+++ b/third_party/elfutils/tests/run-exprlocs.sh
@@ -0,0 +1,180 @@
+#! /bin/sh
+# Copyright (C) 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77589
+#
+# program repro
+#   type small_stride
+#      character*40 long_string
+#      integer      small_pad
+#   end type small_stride
+#   type(small_stride), dimension (20), target :: unpleasant
+#   character*40, pointer, dimension(:):: c40pt
+#   integer i
+#   do i = 0,19
+#      unpleasant(i+1)%small_pad = i+1
+#      unpleasant(i+1)%long_string = char (ichar('0') + i) // '-hello'
+#   end do
+#   c40pt => unpleasant%long_string
+#   print *, c40pt  ! break-here
+# end program repro
+#
+# Needs GCC7+
+# gfortran -o testfile-stridex dwarf-stridex.f90 -Wall -g
+
+testfiles testfile-stridex
+
+testrun_compare ${abs_top_builddir}/tests/varlocs --exprlocs -e testfile-stridex <<\EOF
+module 'testfile-stridex'
+[b] CU 'dwarf-stridex.f90'@400717
+  producer (strp)
+  language (data1)
+  identifier_case (data1)
+  name (strp)
+  comp_dir (strp)
+  low_pc (addr)
+  high_pc (data8)
+  stmt_list (sec_offset)
+  [2e] base_type "integer(kind=8)"
+    byte_size (data1)
+    encoding (data1)
+    name (strp)
+  [35] structure_type "small_stride"
+    name (strp)
+    byte_size (data1)
+    decl_file (data1)
+    decl_line (data1)
+    sibling (ref4)
+    [41] member "long_string"
+      name (strp)
+      decl_file (data1)
+      decl_line (data1)
+      type (ref4)
+      data_member_location (data1) {plus_uconst(0)}
+    [4d] member "small_pad"
+      name (strp)
+      decl_file (data1)
+      decl_line (data1)
+      type (ref4)
+      data_member_location (data1) {plus_uconst(40)}
+  [5a] string_type
+    byte_size (data1)
+  [5c] base_type "integer(kind=4)"
+    byte_size (data1)
+    encoding (data1)
+    name (strp)
+  [63] const_type
+    type (ref4)
+  [68] subprogram "main"
+    external (flag_present)
+    name (strp)
+    decl_file (data1)
+    decl_line (data1)
+    type (ref4)
+    low_pc (addr)
+    high_pc (data8)
+    frame_base (exprloc) {call_frame_cfa {bregx(7,8)}}
+    GNU_all_tail_call_sites (flag_present)
+    sibling (ref4)
+    [89] formal_parameter "argc"
+      name (strp)
+      decl_file (data1)
+      decl_line (data1)
+      type (ref4)
+      location (exprloc) {fbreg(-20)}
+    [97] formal_parameter "argv"
+      name (strp)
+      decl_file (data1)
+      decl_line (data1)
+      type (ref4)
+      location (exprloc) {fbreg(-32), deref}
+  [a7] pointer_type
+    byte_size (data1)
+    type (ref4)
+  [ad] base_type "character(kind=1)"
+    byte_size (data1)
+    encoding (data1)
+    name (strp)
+  [b4] subprogram "repro"
+    name (strp)
+    decl_file (data1)
+    decl_line (data1)
+    main_subprogram (flag_present)
+    calling_convention (data1)
+    low_pc (addr)
+    high_pc (data8)
+    frame_base (exprloc) {call_frame_cfa {bregx(7,8)}}
+    GNU_all_tail_call_sites (flag_present)
+    sibling (ref4)
+    [d2] variable "c40pt"
+      name (strp)
+      decl_file (data1)
+      decl_line (data1)
+      type (ref4)
+      location (exprloc) {fbreg(-128)}
+    [e1] variable "span.0"
+      name (strp)
+      type (ref4)
+      artificial (flag_present)
+      location (exprloc) {fbreg(-80)}
+    [ee] variable "i"
+      name (string)
+      decl_file (data1)
+      decl_line (data1)
+      type (ref4)
+      location (exprloc) {fbreg(-68)}
+    [fb] variable "unpleasant"
+      name (strp)
+      decl_file (data1)
+      decl_line (data1)
+      type (ref4)
+      location (exprloc) {fbreg(-1008)}
+    [10a] lexical_block
+      low_pc (addr)
+      high_pc (data8)
+      sibling (ref4)
+      [11f] lexical_block
+        low_pc (addr)
+        high_pc (data8)
+    [131] lexical_block
+      low_pc (addr)
+      high_pc (data8)
+      [142] lexical_block
+        low_pc (addr)
+        high_pc (data8)
+        [153] lexical_block
+          low_pc (addr)
+          high_pc (data8)
+  [167] array_type
+    data_location (exprloc) {push_object_address, deref}
+    associated (exprloc) {push_object_address, deref, lit0, ne}
+    type (ref4)
+    sibling (ref4)
+    [178] subrange_type
+      lower_bound (exprloc) {push_object_address, plus_uconst(32), deref}
+      upper_bound (exprloc) {push_object_address, plus_uconst(40), deref}
+      byte_stride (exprloc) {push_object_address, plus_uconst(24), deref, GNU_variable_value([e1]) {fbreg(-80)}, mul}
+  [18f] array_type
+    type (ref4)
+    [194] subrange_type
+      type (ref4)
+      upper_bound (sdata)
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-find-prologues.sh b/third_party/elfutils/tests/run-find-prologues.sh
new file mode 100755
index 0000000..160f07d
--- /dev/null
+++ b/third_party/elfutils/tests/run-find-prologues.sh
@@ -0,0 +1,85 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile testfile11 testfile22 testfile24 \
+	  testfile25 testfile3 testfile4 testfile5 testfile6
+
+testrun_compare ${abs_builddir}/find-prologues -e testfile <<\EOF
+main             0x000000000804842c 0x0000000008048432
+bar              0x000000000804845c 0x000000000804845f
+foo              0x0000000008048468 0x000000000804846b
+EOF
+
+testrun_compare ${abs_builddir}/find-prologues -e testfile11 <<\EOF
+main             0x00000000080489b8 0x00000000080489cd
+gnu_obj_2        0x0000000008048c9e 0x0000000008048ca4
+gnu_obj_3        0x0000000008048cd8 0x0000000008048cde
+gnu_obj_2        0x0000000008048cf4 0x0000000008048cfa
+~invalid_argument 0x0000000008048d2e 0x0000000008048d34
+gnu_obj_1        0x0000000008048d62 0x0000000008048d65
+gnu_obj_1        0x0000000008048d8a 0x0000000008048d8d
+~invalid_argument 0x0000000008048db2 0x0000000008048db8
+EOF
+
+testrun_compare ${abs_builddir}/find-prologues -e testfile22 <<\EOF
+function         0x0000000008048348 0x000000000804834e
+main             0x000000000804835b 0x0000000008048377
+EOF
+
+testrun_compare ${abs_builddir}/find-prologues -e testfile24 <<\EOF
+incr             0x0000000008048348 0x000000000804834e
+main             0x0000000008048354 0x0000000008048360
+EOF
+
+testrun_compare ${abs_builddir}/find-prologues -e testfile25 <<\EOF
+incr             0x0000000008048348 0x000000000804834c
+EOF
+
+testrun_compare ${abs_builddir}/find-prologues -e testfile3 <<\EOF
+main             0x000000000804842c 0x0000000008048433
+bar              0x0000000008048458 0x000000000804845b
+foo              0x0000000008048464 0x0000000008048467
+EOF
+
+testrun_compare ${abs_builddir}/find-prologues -e testfile4 <<\EOF
+get              0x00000000080493fc 0x0000000008049402
+main             0x0000000008049498 0x000000000804949e
+a                0x000000000804d85c 0x000000000804d85c
+__tfPCc          0x000000000804d86c 0x000000000804d872
+__tfCc           0x000000000804d8a4 0x000000000804d8a4
+EOF
+
+testrun_compare ${abs_builddir}/find-prologues -e testfile5 <<\EOF
+bar              0x000000000804842c 0x000000000804842f
+foo              0x0000000008048438 0x000000000804843b
+main             0x0000000008048444 0x000000000804844a
+EOF
+
+testrun_compare ${abs_builddir}/find-prologues -e testfile6 <<\EOF
+main             0x00000000080489b8 0x00000000080489cd
+gnu_obj_2        0x0000000008048c9e 0x0000000008048ca4
+gnu_obj_3        0x0000000008048cd8 0x0000000008048cde
+gnu_obj_2        0x0000000008048cf4 0x0000000008048cfa
+~invalid_argument 0x0000000008048d2e 0x0000000008048d34
+gnu_obj_1        0x0000000008048d62 0x0000000008048d65
+gnu_obj_1        0x0000000008048d8a 0x0000000008048d8d
+~invalid_argument 0x0000000008048db2 0x0000000008048db8
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-funcretval.sh b/third_party/elfutils/tests/run-funcretval.sh
new file mode 100755
index 0000000..779bd47
--- /dev/null
+++ b/third_party/elfutils/tests/run-funcretval.sh
@@ -0,0 +1,153 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# The following files were obtaining by compiling funcretval_test.c
+# from this directory as follows:
+#
+#   gcc -g funcretval_test.c -o funcretval_test_<YOURARCH>
+#
+# Pass -DFLOAT128 if the given arch supports __float128.
+
+testfiles funcretval_test_aarch64
+
+# funcretval_test_aarch64 was built with additional flag:
+#   -DAARCH64_BUG_1032854
+# hence no fun_vec_double_8.
+testrun_compare ${abs_top_builddir}/tests/funcretval \
+	-e funcretval_test_aarch64 <<\EOF
+() fun_char: return value location: {0x50, 0}
+() fun_short: return value location: {0x50, 0}
+() fun_int: return value location: {0x50, 0}
+() fun_ptr: return value location: {0x50, 0}
+() fun_iptr: return value location: {0x50, 0}
+() fun_long: return value location: {0x50, 0}
+() fun_int128: return value location: {0x50, 0} {0x93, 0x8} {0x51, 0} {0x93, 0x8}
+() fun_large_struct1: return value location: {0x70, 0}
+() fun_large_struct2: return value location: {0x70, 0}
+() fun_float: return value location: {0x90, 0x40}
+() fun_float_complex: return value location: {0x90, 0x40} {0x93, 0x4} {0x90, 0x41} {0x93, 0x4}
+() fun_double: return value location: {0x90, 0x40}
+() fun_double_complex: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8}
+() fun_long_double: return value location: {0x90, 0x40}
+() fun_long_double_complex: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10}
+() fun_vec_char_8: return value location: {0x90, 0x40}
+() fun_vec_short_8: return value location: {0x90, 0x40}
+() fun_vec_int_8: return value location: {0x90, 0x40}
+() fun_vec_long_8: return value location: {0x90, 0x40}
+() fun_vec_float_8: return value location: {0x90, 0x40}
+() fun_vec_char_16: return value location: {0x90, 0x40}
+() fun_vec_short_16: return value location: {0x90, 0x40}
+() fun_vec_int_16: return value location: {0x90, 0x40}
+() fun_vec_long_16: return value location: {0x90, 0x40}
+() fun_vec_int128_16: return value location: {0x90, 0x40}
+() fun_vec_float_16: return value location: {0x90, 0x40}
+() fun_vec_double_16: return value location: {0x90, 0x40}
+() fun_hfa1_float: return value location: {0x90, 0x40}
+() fun_hfa1_double: return value location: {0x90, 0x40}
+() fun_hfa1_long_double: return value location: {0x90, 0x40}
+() fun_hfa1_float_a: return value location: {0x90, 0x40}
+() fun_hfa1_double_a: return value location: {0x90, 0x40}
+() fun_hfa1_long_double_a: return value location: {0x90, 0x40}
+() fun_hfa2_float: return value location: {0x90, 0x40} {0x93, 0x4} {0x90, 0x41} {0x93, 0x4}
+() fun_hfa2_double: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8}
+() fun_hfa2_long_double: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10}
+() fun_hfa2_float_a: return value location: {0x90, 0x40} {0x93, 0x4} {0x90, 0x41} {0x93, 0x4}
+() fun_hfa2_double_a: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8}
+() fun_hfa2_long_double_a: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10}
+() fun_hfa3_float: return value location: {0x90, 0x40} {0x93, 0x4} {0x90, 0x41} {0x93, 0x4} {0x90, 0x42} {0x93, 0x4}
+() fun_hfa3_double: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8}
+() fun_hfa3_long_double: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10}
+() fun_hfa3_float_a: return value location: {0x90, 0x40} {0x93, 0x4} {0x90, 0x41} {0x93, 0x4} {0x90, 0x42} {0x93, 0x4}
+() fun_hfa3_double_a: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8}
+() fun_hfa3_long_double_a: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10}
+() fun_hfa4_float: return value location: {0x90, 0x40} {0x93, 0x4} {0x90, 0x41} {0x93, 0x4} {0x90, 0x42} {0x93, 0x4} {0x90, 0x43} {0x93, 0x4}
+() fun_hfa4_double: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8} {0x90, 0x43} {0x93, 0x8}
+() fun_hfa4_long_double: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10} {0x90, 0x43} {0x93, 0x10}
+() fun_hfa4_float_a: return value location: {0x90, 0x40} {0x93, 0x4} {0x90, 0x41} {0x93, 0x4} {0x90, 0x42} {0x93, 0x4} {0x90, 0x43} {0x93, 0x4}
+() fun_hfa4_double_a: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8} {0x90, 0x43} {0x93, 0x8}
+() fun_hfa4_long_double_a: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10} {0x90, 0x43} {0x93, 0x10}
+() fun_nfa5_float: return value location: {0x70, 0}
+() fun_nfa5_double: return value location: {0x70, 0}
+() fun_nfa5_long_double: return value location: {0x70, 0}
+() fun_nfa5_float_a: return value location: {0x70, 0}
+() fun_nfa5_double_a: return value location: {0x70, 0}
+() fun_nfa5_long_double_a: return value location: {0x70, 0}
+() fun_hva1_vec_char_8: return value location: {0x90, 0x40}
+() fun_hva1_vec_short_8: return value location: {0x90, 0x40}
+() fun_hva1_vec_int_8: return value location: {0x90, 0x40}
+() fun_hva1_vec_long_8: return value location: {0x90, 0x40}
+() fun_hva1_vec_float_8: return value location: {0x90, 0x40}
+() fun_hva1_vec_double_8: return value location: {0x90, 0x40}
+() fun_hva1_vec_char_16_t: return value location: {0x90, 0x40}
+() fun_hva1_vec_short_16_t: return value location: {0x90, 0x40}
+() fun_hva1_vec_int_16_t: return value location: {0x90, 0x40}
+() fun_hva1_vec_long_16_t: return value location: {0x90, 0x40}
+() fun_hva1_vec_int128_16_t: return value location: {0x90, 0x40}
+() fun_hva1_vec_float_16_t: return value location: {0x90, 0x40}
+() fun_hva1_vec_double_16_t: return value location: {0x90, 0x40}
+() fun_hva2_vec_char_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8}
+() fun_hva2_vec_short_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8}
+() fun_hva2_vec_int_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8}
+() fun_hva2_vec_long_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8}
+() fun_hva2_vec_float_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8}
+() fun_hva2_vec_double_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8}
+() fun_hva2_vec_char_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10}
+() fun_hva2_vec_short_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10}
+() fun_hva2_vec_int_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10}
+() fun_hva2_vec_long_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10}
+() fun_hva2_vec_int128_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10}
+() fun_hva2_vec_float_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10}
+() fun_hva2_vec_double_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10}
+() fun_hva3_vec_char_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8}
+() fun_hva3_vec_short_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8}
+() fun_hva3_vec_int_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8}
+() fun_hva3_vec_long_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8}
+() fun_hva3_vec_float_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8}
+() fun_hva3_vec_double_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8}
+() fun_hva3_vec_char_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10}
+() fun_hva3_vec_short_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10}
+() fun_hva3_vec_int_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10}
+() fun_hva3_vec_long_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10}
+() fun_hva3_vec_int128_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10}
+() fun_hva3_vec_float_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10}
+() fun_hva3_vec_double_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10}
+() fun_hva4_vec_char_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8} {0x90, 0x43} {0x93, 0x8}
+() fun_hva4_vec_short_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8} {0x90, 0x43} {0x93, 0x8}
+() fun_hva4_vec_int_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8} {0x90, 0x43} {0x93, 0x8}
+() fun_hva4_vec_long_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8} {0x90, 0x43} {0x93, 0x8}
+() fun_hva4_vec_float_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8} {0x90, 0x43} {0x93, 0x8}
+() fun_hva4_vec_double_8: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8} {0x90, 0x43} {0x93, 0x8}
+() fun_hva4_vec_char_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10} {0x90, 0x43} {0x93, 0x10}
+() fun_hva4_vec_short_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10} {0x90, 0x43} {0x93, 0x10}
+() fun_hva4_vec_int_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10} {0x90, 0x43} {0x93, 0x10}
+() fun_hva4_vec_long_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10} {0x90, 0x43} {0x93, 0x10}
+() fun_hva4_vec_int128_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10} {0x90, 0x43} {0x93, 0x10}
+() fun_hva4_vec_float_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10} {0x90, 0x43} {0x93, 0x10}
+() fun_hva4_vec_double_16_t: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10} {0x90, 0x43} {0x93, 0x10}
+() fun_mixed_hfa3_cff: return value location: {0x90, 0x40} {0x93, 0x4} {0x90, 0x41} {0x93, 0x4} {0x90, 0x42} {0x93, 0x4}
+() fun_mixed_hfa3_cdd: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8}
+() fun_mixed_hfa3_cldld: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10}
+() fun_mixed_hfa3_fcf: return value location: {0x90, 0x40} {0x93, 0x4} {0x90, 0x41} {0x93, 0x4} {0x90, 0x42} {0x93, 0x4}
+() fun_mixed_hfa3_dcd: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8} {0x90, 0x42} {0x93, 0x8}
+() fun_mixed_hfa3_ldcld: return value location: {0x90, 0x40} {0x93, 0x10} {0x90, 0x41} {0x93, 0x10} {0x90, 0x42} {0x93, 0x10}
+() fun_mixed_hfa2_fltsht_t: return value location: {0x90, 0x40} {0x93, 0x8} {0x90, 0x41} {0x93, 0x8}
+() main: return value location: {0x50, 0}
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-funcscopes.sh b/third_party/elfutils/tests/run-funcscopes.sh
new file mode 100755
index 0000000..367729a
--- /dev/null
+++ b/third_party/elfutils/tests/run-funcscopes.sh
@@ -0,0 +1,29 @@
+#! /bin/sh
+# Copyright (C) 2005, 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile25
+
+testrun_compare ${abs_builddir}/funcscopes -e testfile25 incr <<\EOF
+testfile25: 0x8048000 .. 0x8049528
+    inline-test.c (0x11): 0x8048348 (/home/roland/build/stock-elfutils/inline-test.c:7) .. 0x804834e (/home/roland/build/stock-elfutils/inline-test.c:9)
+        incr (0x2e): 0x8048348 (/home/roland/build/stock-elfutils/inline-test.c:7) .. 0x804834e (/home/roland/build/stock-elfutils/inline-test.c:9)
+            x                             [    66]
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-get-aranges.sh b/third_party/elfutils/tests/run-get-aranges.sh
new file mode 100755
index 0000000..62cae5f
--- /dev/null
+++ b/third_party/elfutils/tests/run-get-aranges.sh
@@ -0,0 +1,68 @@
+#! /bin/sh
+# Copyright (C) 1999, 2000, 2002, 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile testfile2
+
+testrun_compare ${abs_builddir}/get-aranges testfile testfile2 <<\EOF
+0x804842b: not in range
+CU name: "m.c"
+CU name: "m.c"
+CU name: "m.c"
+0x804845a: not in range
+0x804845b: not in range
+CU name: "b.c"
+CU name: "b.c"
+CU name: "b.c"
+0x8048466: not in range
+0x8048467: not in range
+CU name: "f.c"
+CU name: "f.c"
+CU name: "f.c"
+0x8048472: not in range
+ [ 0] start: 0x804842c, length: 46, cu: 11
+CU name: "m.c"
+ [ 1] start: 0x804845c, length: 10, cu: 202
+CU name: "b.c"
+ [ 2] start: 0x8048468, length: 10, cu: 5628
+CU name: "f.c"
+0x804842b: not in range
+0x804842c: not in range
+0x804843c: not in range
+0x8048459: not in range
+0x804845a: not in range
+0x804845b: not in range
+0x804845c: not in range
+0x8048460: not in range
+0x8048465: not in range
+0x8048466: not in range
+0x8048467: not in range
+0x8048468: not in range
+0x8048470: not in range
+0x8048471: not in range
+0x8048472: not in range
+ [ 0] start: 0x10000470, length: 32, cu: 11
+CU name: "b.c"
+ [ 1] start: 0x10000490, length: 32, cu: 2429
+CU name: "f.c"
+ [ 2] start: 0x100004b0, length: 100, cu: 2532
+CU name: "m.c"
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-get-files.sh b/third_party/elfutils/tests/run-get-files.sh
new file mode 100755
index 0000000..a2f2373
--- /dev/null
+++ b/third_party/elfutils/tests/run-get-files.sh
@@ -0,0 +1,67 @@
+#! /bin/sh
+# Copyright (C) 1999, 2000, 2002, 2004, 2005, 2007 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile testfile2
+
+testrun_compare ${abs_builddir}/get-files testfile testfile2 <<\EOF
+cuhl = 11, o = 0, asz = 4, osz = 4, ncu = 191
+ dirs[0] = "/home/drepper/gnu/new-bu/build/ttt"
+ file[0] = "???"
+ file[1] = "/home/drepper/gnu/new-bu/build/ttt/m.c"
+cuhl = 11, o = 114, asz = 4, osz = 4, ncu = 5617
+ dirs[0] = "/home/drepper/gnu/new-bu/build/ttt"
+ file[0] = "???"
+ file[1] = "/home/drepper/gnu/new-bu/build/ttt/b.c"
+ file[2] = "/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h"
+ file[3] = "/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h"
+ file[4] = "/usr/include/bits/types.h"
+ file[5] = "/usr/include/bits/sched.h"
+ file[6] = "/usr/include/bits/pthreadtypes.h"
+ file[7] = "/usr/include/stdio.h"
+ file[8] = "/usr/include/libio.h"
+ file[9] = "/usr/include/wchar.h"
+ file[10] = "/usr/include/_G_config.h"
+ file[11] = "/usr/include/gconv.h"
+cuhl = 11, o = 412, asz = 4, osz = 4, ncu = 5752
+ dirs[0] = "/home/drepper/gnu/new-bu/build/ttt"
+ file[0] = "???"
+ file[1] = "/home/drepper/gnu/new-bu/build/ttt/f.c"
+cuhl = 11, o = 0, asz = 4, osz = 4, ncu = 2418
+ dirs[0] = "/shoggoth/drepper"
+ file[0] = "???"
+ file[1] = "/shoggoth/drepper/b.c"
+ file[2] = "/home/geoffk/objs/laurel-000912-branch/lib/gcc-lib/powerpc-unknown-linux-gnu/2.96-laurel-000912/include/stddef.h"
+ file[3] = "/home/geoffk/objs/laurel-000912-branch/lib/gcc-lib/powerpc-unknown-linux-gnu/2.96-laurel-000912/include/stdarg.h"
+ file[4] = "/shoggoth/drepper/<built-in>"
+ file[5] = "/usr/include/bits/types.h"
+ file[6] = "/usr/include/stdio.h"
+ file[7] = "/usr/include/libio.h"
+ file[8] = "/usr/include/_G_config.h"
+cuhl = 11, o = 213, asz = 4, osz = 4, ncu = 2521
+ dirs[0] = "/shoggoth/drepper"
+ file[0] = "???"
+ file[1] = "/shoggoth/drepper/f.c"
+cuhl = 11, o = 267, asz = 4, osz = 4, ncu = 2680
+ dirs[0] = "/shoggoth/drepper"
+ file[0] = "???"
+ file[1] = "/shoggoth/drepper/m.c"
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-get-lines.sh b/third_party/elfutils/tests/run-get-lines.sh
new file mode 100755
index 0000000..fb48c77
--- /dev/null
+++ b/third_party/elfutils/tests/run-get-lines.sh
@@ -0,0 +1,91 @@
+#! /bin/sh
+# Copyright (C) 1999, 2000, 2002, 2004, 2005, 2013 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile testfile2 testfilenolines
+
+testrun_compare ${abs_builddir}/get-lines testfile testfile2 <<\EOF
+cuhl = 11, o = 0, asz = 4, osz = 4, ncu = 191
+ 5 lines
+804842c: /home/drepper/gnu/new-bu/build/ttt/m.c:5:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+8048432: /home/drepper/gnu/new-bu/build/ttt/m.c:6:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+804844d: /home/drepper/gnu/new-bu/build/ttt/m.c:7:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+8048458: /home/drepper/gnu/new-bu/build/ttt/m.c:8:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+804845a: /home/drepper/gnu/new-bu/build/ttt/m.c:8:0: is_stmt:yes, end_seq:yes, bb:no, prologue:no, epilogue:no
+cuhl = 11, o = 114, asz = 4, osz = 4, ncu = 5617
+ 4 lines
+804845c: /home/drepper/gnu/new-bu/build/ttt/b.c:4:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+804845f: /home/drepper/gnu/new-bu/build/ttt/b.c:5:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+8048464: /home/drepper/gnu/new-bu/build/ttt/b.c:6:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+8048466: /home/drepper/gnu/new-bu/build/ttt/b.c:6:0: is_stmt:yes, end_seq:yes, bb:no, prologue:no, epilogue:no
+cuhl = 11, o = 412, asz = 4, osz = 4, ncu = 5752
+ 4 lines
+8048468: /home/drepper/gnu/new-bu/build/ttt/f.c:3:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+804846b: /home/drepper/gnu/new-bu/build/ttt/f.c:4:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+8048470: /home/drepper/gnu/new-bu/build/ttt/f.c:5:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+8048472: /home/drepper/gnu/new-bu/build/ttt/f.c:5:0: is_stmt:yes, end_seq:yes, bb:no, prologue:no, epilogue:no
+cuhl = 11, o = 0, asz = 4, osz = 4, ncu = 2418
+ 4 lines
+10000470: /shoggoth/drepper/b.c:4:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+1000047c: /shoggoth/drepper/b.c:5:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+10000480: /shoggoth/drepper/b.c:6:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+10000490: /shoggoth/drepper/b.c:6:0: is_stmt:yes, end_seq:yes, bb:no, prologue:no, epilogue:no
+cuhl = 11, o = 213, asz = 4, osz = 4, ncu = 2521
+ 4 lines
+10000490: /shoggoth/drepper/f.c:3:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+1000049c: /shoggoth/drepper/f.c:4:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+100004a0: /shoggoth/drepper/f.c:5:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+100004b0: /shoggoth/drepper/f.c:5:0: is_stmt:yes, end_seq:yes, bb:no, prologue:no, epilogue:no
+cuhl = 11, o = 267, asz = 4, osz = 4, ncu = 2680
+ 5 lines
+100004b0: /shoggoth/drepper/m.c:5:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+100004cc: /shoggoth/drepper/m.c:6:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+100004e8: /shoggoth/drepper/m.c:7:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+100004f4: /shoggoth/drepper/m.c:8:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+10000514: /shoggoth/drepper/m.c:8:0: is_stmt:yes, end_seq:yes, bb:no, prologue:no, epilogue:no
+EOF
+
+# - lines.c
+# int ft;
+#
+# int
+# main (int argc, char **argv)
+# {
+#   return ft - 42;
+# }
+#
+# - nolines.c
+# int ft = 42;
+#
+# gcc -g -c lines.c
+# gcc -g -c nolines.c
+# gcc -g -o testfilenolines lines.o nolines.o
+
+testrun_compare ${abs_builddir}/get-lines testfilenolines <<\EOF
+cuhl = 11, o = 0, asz = 8, osz = 4, ncu = 169
+ 4 lines
+400474: /home/mark/src/tests/lines.c:5:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40047f: /home/mark/src/tests/lines.c:6:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+400488: /home/mark/src/tests/lines.c:7:0: is_stmt:yes, end_seq:no, bb:no, prologue:no, epilogue:no
+40048a: /home/mark/src/tests/lines.c:7:0: is_stmt:yes, end_seq:yes, bb:no, prologue:no, epilogue:no
+cuhl = 11, o = 125, asz = 8, osz = 4, ncu = 243
+ 0 lines
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-get-pubnames.sh b/third_party/elfutils/tests/run-get-pubnames.sh
new file mode 100755
index 0000000..912793e
--- /dev/null
+++ b/third_party/elfutils/tests/run-get-pubnames.sh
@@ -0,0 +1,50 @@
+#! /bin/sh
+# Copyright (C) 1999, 2000, 2002, 2003, 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile testfile2
+
+testrun_compare ${abs_builddir}/get-pubnames testfile testfile2 <<\EOF
+ [ 0] "main", die: 104, cu: 11
+CU name: "m.c"
+object name: "main"
+ [ 1] "a", die: 174, cu: 11
+CU name: "m.c"
+object name: "a"
+ [ 2] "bar", die: 295, cu: 202
+CU name: "b.c"
+object name: "bar"
+ [ 3] "foo", die: 5721, cu: 5628
+CU name: "f.c"
+object name: "foo"
+ [ 0] "bar", die: 72, cu: 11
+CU name: "b.c"
+object name: "bar"
+ [ 1] "foo", die: 2490, cu: 2429
+CU name: "f.c"
+object name: "foo"
+ [ 2] "main", die: 2593, cu: 2532
+CU name: "m.c"
+object name: "main"
+ [ 3] "a", die: 2663, cu: 2532
+CU name: "m.c"
+object name: "a"
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-getsrc-die.sh b/third_party/elfutils/tests/run-getsrc-die.sh
new file mode 100755
index 0000000..4da16e7
--- /dev/null
+++ b/third_party/elfutils/tests/run-getsrc-die.sh
@@ -0,0 +1,51 @@
+#! /bin/sh
+# Copyright (C) 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# See run-addr2line-test.sh run-addr2line-i-test.sh run-addr2line-i-lex-test.sh
+# Output/files/lines matched should equal what is done through addr2line
+# which uses dwfl_module_getsrc. This test uses dwarf_addrdie and
+# dwarf_getsrc_die
+testfiles testfile testfile-inlines testfile-lex-inlines
+
+testrun_compare ${abs_top_builddir}/tests/getsrc_die testfile 0x08048468 0x0804845c <<\EOF
+/home/drepper/gnu/new-bu/build/ttt/f.c:3
+/home/drepper/gnu/new-bu/build/ttt/b.c:4
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/getsrc_die testfile-inlines 0x00000000000005a0 0x00000000000005a1 0x00000000000005b0 0x00000000000005b1 0x00000000000005c0 0x00000000000005d0 0x00000000000005e0 0x00000000000005e1 0x00000000000005f1 0x00000000000005f2 <<\EOF
+/tmp/x.cpp:5
+/tmp/x.cpp:6
+/tmp/x.cpp:10
+/tmp/x.cpp:11
+/tmp/x.cpp:5
+/tmp/x.cpp:10
+/tmp/x.cpp:5
+/tmp/x.cpp:10
+/tmp/x.cpp:10
+/tmp/x.cpp:5
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/getsrc_die testfile-lex-inlines 0x0000000000000680 0x0000000000000681 0x0000000000000690 0x0000000000000691 <<\EOF
+/tmp/x.cpp:5
+/tmp/x.cpp:5
+/tmp/x.cpp:5
+/tmp/x.cpp:5
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-lfs-symbols.sh b/third_party/elfutils/tests/run-lfs-symbols.sh
new file mode 100755
index 0000000..f089440
--- /dev/null
+++ b/third_party/elfutils/tests/run-lfs-symbols.sh
@@ -0,0 +1,86 @@
+#! /bin/bash
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+if ! grep -q -F '#define _FILE_OFFSET_BITS' ${abs_top_builddir}/config.h; then
+  echo "LFS testing is irrelevent on this system"
+  exit 77
+fi
+
+# #include <stdio.h>
+# int main () {
+#     FILE *f = fopen ("/dev/null", "r");
+#     return f == NULL;
+# }
+#
+# Built for Linux i686, without setting _FILE_OFFSET_BITS.
+# $ gcc -m32 -O2 nolfs.c -o testfile-nolfs
+testfiles testfile-nolfs
+
+LFS_FORMAT='BEGIN {
+  while ((getline < "%s") > 0)
+    /^\w/ && bad[$0]
+  FS="@"
+}
+/@@GLIBC_/ && $1 in bad { print $1 }'
+
+LFS=$(printf "$LFS_FORMAT" "${abs_srcdir}/lfs-symbols")
+
+makeprint() {
+  make print-$1 -C $2 |& awk -F= "/^$1=/{ print \$2 }"
+}
+
+testrun_lfs() {
+  bad=$(testrun ${abs_top_builddir}/src/nm -u "$1" | awk "$LFS")
+  if [ -n "$bad" ]; then
+    echo "$1 contains non-lfs symbols:" $bad
+    exit_status=1
+  fi
+}
+
+# First sanity-check that LFS detection works.
+exit_status=0
+testrun_lfs ./testfile-nolfs
+if [ $exit_status -eq 0 ]; then
+  echo "Didn't detect any problem with testfile-nolfs!"
+  exit 99
+fi
+
+exit_status=0
+
+# Check all normal build targets.
+for dir in libelf libdw libasm libcpu src; do
+  dir=${abs_top_builddir}/$dir
+  for program in $(makeprint PROGRAMS $dir); do
+    testrun_lfs $dir/$program
+  done
+done
+
+# Check all libebl modules.
+dir=${abs_top_builddir}/backends
+for module in $(makeprint modules $dir); do
+  testrun_lfs $dir/libebl_$module.so
+done
+
+# Check all test programs.
+dir=${abs_builddir}
+for program in $(makeprint check_PROGRAMS $dir); do
+  testrun_lfs $dir/$program
+done
+
+exit $exit_status
diff --git a/third_party/elfutils/tests/run-line2addr.sh b/third_party/elfutils/tests/run-line2addr.sh
new file mode 100755
index 0000000..3b6c445
--- /dev/null
+++ b/third_party/elfutils/tests/run-line2addr.sh
@@ -0,0 +1,49 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile testfile2 testfile8 testfile14 testfile23
+
+testrun_compare ${abs_builddir}/line2addr -e testfile f.c:4 testfile f.c:8 <<\EOF
+f.c:4 -> 0x804846b (/home/drepper/gnu/new-bu/build/ttt/f.c:4)
+EOF
+
+testrun_compare ${abs_builddir}/line2addr -e testfile2 m.c:6 b.c:1 <<\EOF
+m.c:6 -> 0x100004cc (/shoggoth/drepper/m.c:6)
+b.c:1 -> 0x10000470 (/shoggoth/drepper/b.c:4)
+EOF
+
+testrun_compare ${abs_builddir}/line2addr -e testfile8 strip.c:953 strip.c:365 <<\EOF
+strip.c:953 -> (.text)+0x169f (/home/drepper/gnu/elfutils/build/src/../../src/strip.c:953)
+strip.c:953 -> (.text)+0x16aa (/home/drepper/gnu/elfutils/build/src/../../src/strip.c:953)
+strip.c:365 -> (.text)+0x278b (/home/drepper/gnu/elfutils/build/src/../../src/strip.c:365)
+strip.c:365 -> (.text)+0x2797 (/home/drepper/gnu/elfutils/build/src/../../src/strip.c:365)
+EOF
+
+testrun_compare ${abs_builddir}/line2addr -e testfile14 v.c:6 <<\EOF
+v.c:6 -> 0x400468 (/home/drepper/local/elfutils-build/20050425/v.c:6)
+v.c:6 -> 0x400487 (/home/drepper/local/elfutils-build/20050425/v.c:6)
+EOF
+
+testrun_compare ${abs_builddir}/line2addr -e testfile23 foo.c:2 foo.c:6 <<\EOF
+foo.c:2 -> (.init.text)+0xc (/home/roland/stock-elfutils-build/foo.c:2)
+foo.c:6 -> (.text)+0xc (/home/roland/stock-elfutils-build/foo.c:6)
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-linkmap-cut.sh b/third_party/elfutils/tests/run-linkmap-cut.sh
new file mode 100755
index 0000000..de2bc7c
--- /dev/null
+++ b/third_party/elfutils/tests/run-linkmap-cut.sh
@@ -0,0 +1,32 @@
+#! /bin/bash
+# Copyright (C) 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# The core file has patched:
+# * _r_debug.r_map.l_next.l_next (vma 0x3fdf621718, offset 0x7718) = NULL,
+#   therefore all libraries after the main executable and vDSO are removed.
+# * NT_FILE absolute filenames are relativized to: ./////basename
+
+testfiles linkmap-cut-lib.so linkmap-cut linkmap-cut.core
+tempfiles bt
+# It may have non-zero exit code with:
+# .../elfutils/src/stack: dwfl_thread_getframes tid 3130 at 0x3fdf821d64 in /usr/lib64/libc-2.18.so: no matching address range
+testrun ${abs_top_builddir}/src/stack --core=linkmap-cut.core -e linkmap-cut -m >bt || true
+cat bt
+grep -q '^#0  0x00007f08bc24d681 libfunc - .////////////////////////////////////linkmap-cut-lib\.so$' bt
+grep -q '^#1  0x00000000004006b4 main - linkmap-cut$' bt
diff --git a/third_party/elfutils/tests/run-low_high_pc.sh b/third_party/elfutils/tests/run-low_high_pc.sh
new file mode 100755
index 0000000..ab5f2c3
--- /dev/null
+++ b/third_party/elfutils/tests/run-low_high_pc.sh
@@ -0,0 +1,34 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# int
+# main (int argc, char **argv)
+# {
+#   return 0;
+# }
+# gcc -g -o main main.c
+testfiles testfile_low_high_pc
+
+testrun ${abs_builddir}/low_high_pc -e ./testfile_low_high_pc
+testrun ${abs_builddir}/low_high_pc -e ${abs_builddir}/low_high_pc
+testrun ${abs_builddir}/low_high_pc -e ${abs_top_builddir}/src/strip
+testrun ${abs_builddir}/low_high_pc -e ${abs_top_builddir}/src/strip.o
+testrun ${abs_builddir}/low_high_pc -e ${abs_top_builddir}/libelf/libelf.so
+
+exit 0
diff --git a/third_party/elfutils/tests/run-macro-test.sh b/third_party/elfutils/tests/run-macro-test.sh
new file mode 100755
index 0000000..79b0d88
--- /dev/null
+++ b/third_party/elfutils/tests/run-macro-test.sh
@@ -0,0 +1,52 @@
+#! /bin/sh
+# Copyright (C) 2012 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# #include <string.h>
+#
+# #define HELLO "world"
+#
+# int
+# main(int argc, char ** argv)
+# {
+#   return strlen (HELLO);
+# }
+#
+# gcc -gdwarf-4 -g3 -o testfile-macros macro.c
+# gcc -gstrict-dwarf -gdwarf-4 -g3 -o testfile-macinfo macro.c
+
+testfiles testfile-macinfo testfile-macros
+tempfiles readelf.macros.out
+
+status=0
+
+testrun ${abs_top_builddir}/src/readelf --debug-dump=info testfile-macinfo \
+	| grep macro_info > readelf.macros.out ||
+  { echo "*** failure readelf --debug-dump=info testfile-macinfo"; status=1; }
+testrun_compare cat readelf.macros.out <<\EOF
+           macro_info           (sec_offset) 0
+EOF
+
+testrun ${abs_top_builddir}/src/readelf --debug-dump=info testfile-macros \
+	| grep GNU_macros > readelf.macros.out ||
+  { echo "*** failure readelf --debug-dump=info testfile-macros"; status=1; }
+testrun_compare cat readelf.macros.out <<\EOF
+           GNU_macros           (sec_offset) 0
+EOF
+
+exit $status
diff --git a/third_party/elfutils/tests/run-native-test.sh b/third_party/elfutils/tests/run-native-test.sh
new file mode 100755
index 0000000..d19007f
--- /dev/null
+++ b/third_party/elfutils/tests/run-native-test.sh
@@ -0,0 +1,88 @@
+#! /bin/sh
+# Copyright (C) 2005, 2006, 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+. $srcdir/test-subr.sh
+
+# This tests all the miscellaneous components of backend support
+# against whatever this build is running on.  A platform will fail
+# this test if it is missing parts of the backend implementation.
+#
+# As new backend code is added to satisfy the test, be sure to update
+# the fixed test cases (run-allregs.sh et al) to test that backend
+# in all builds.
+
+tempfiles native.c native
+echo 'main () { while (1) pause (); }' > native.c
+
+native=0
+kill_native()
+{
+  test $native -eq 0 || {
+    kill -9 $native 2> /dev/null || :
+    wait $native 2> /dev/null || :
+  }
+  native=0
+}
+
+native_cleanup()
+{
+  kill_native
+  test_cleanup
+}
+
+native_exit()
+{
+  native_cleanup
+  exit_cleanup
+}
+
+trap native_cleanup 1 2 15
+trap native_exit 0
+
+for cc in "$HOSTCC" "$HOST_CC" cc gcc "$CC"; do
+  test "x$cc" != x || continue
+  $cc -o native -g native.c > /dev/null 2>&1 &&
+  # Some shell versions don't do this right without the braces.
+  { ./native > /dev/null 2>&1 & native=$! ; } &&
+  sleep 1 && kill -0 $native 2> /dev/null &&
+  break ||
+  native=0
+done
+
+native_test()
+{
+  # Try the build against itself, i.e. $config_host.
+  testrun "$@" -e $1 > /dev/null
+
+  # Try the build against a presumed native process, running this sh.
+  # For tests requiring debug information, this may not test anything.
+  testrun "$@" -p $$ > /dev/null
+
+  # Try the build against the trivial native program we just built with -g.
+  test $native -eq 0 || testrun "$@" -p $native > /dev/null
+}
+
+native_test ${abs_builddir}/allregs
+native_test ${abs_builddir}/funcretval
+
+# We do this explicitly rather than letting the trap 0 cover it,
+# because as of version 3.1 bash prints the "Killed" report for
+# $native when we do the kill inside the exit handler.
+native_cleanup
+
+exit 0
diff --git a/third_party/elfutils/tests/run-nm-self.sh b/third_party/elfutils/tests/run-nm-self.sh
new file mode 100755
index 0000000..6a31afc
--- /dev/null
+++ b/third_party/elfutils/tests/run-nm-self.sh
@@ -0,0 +1,36 @@
+#! /bin/sh
+# Copyright (C) 2012, 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Test different command line combinations on the nm binary itself.
+# Test on nm ET_REL, ET_EXEC and ET_DYN files.
+ET_REL=${abs_top_builddir}/src/nm.o
+ET_EXEC=${abs_top_builddir}/src/nm
+ET_DYN=${abs_top_builddir}/libelf/libelf.so
+for what_arg in --debug-syms --defined-only --dynamic --extern-only; do
+  for format_arg in --format=bsd --format=sysv --format=posix; do
+    for out_arg in --numeric-sort --no-sort --reverse-sort; do
+      for self_file in $ET_REL $ET_EXEC $ET_DYN; do
+	# --dynamic doesn't make sense for ET_REL.
+	if ! test "$what_arg" = "--dynamic" -a "$self_file" = "$ET_REL"; then
+	  testrun ${abs_top_builddir}/src/nm $what_arg $format_arg $out_arg $self_file > /dev/null
+	fi
+      done
+    done
+  done
+done
diff --git a/third_party/elfutils/tests/run-peel-type.sh b/third_party/elfutils/tests/run-peel-type.sh
new file mode 100755
index 0000000..668e316
--- /dev/null
+++ b/third_party/elfutils/tests/run-peel-type.sh
@@ -0,0 +1,63 @@
+#! /bin/sh
+# Copyright (C) 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# See run-aggregate-size.sh for how to generate testfiles.
+
+testfiles testfile-sizes1.o testfile-sizes2.o testfile-sizes3.o
+
+testrun_compare ${abs_builddir}/peel_type -e testfile-sizes1.o <<\EOF
+c raw type base_type
+i raw type base_type
+l raw type base_type
+v raw type pointer_type
+s raw type structure_type
+ca raw type array_type
+ia raw type array_type
+va raw type array_type
+sa raw type array_type
+EOF
+
+testrun_compare ${abs_builddir}/peel_type -e testfile-sizes2.o <<\EOF
+c raw type base_type
+i raw type base_type
+l raw type base_type
+v raw type pointer_type
+s raw type structure_type
+ca raw type array_type
+ia raw type array_type
+va raw type array_type
+sa raw type array_type
+EOF
+
+testrun_compare ${abs_builddir}/peel_type -e testfile-sizes3.o <<\EOF
+c raw type base_type
+i raw type base_type
+l raw type base_type
+v raw type pointer_type
+s raw type structure_type
+ca raw type array_type
+ia raw type array_type
+va raw type array_type
+sa raw type array_type
+d3d raw type array_type
+f raw type base_type
+b raw type base_type
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-prelink-addr-test.sh b/third_party/elfutils/tests/run-prelink-addr-test.sh
new file mode 100755
index 0000000..3398c0d
--- /dev/null
+++ b/third_party/elfutils/tests/run-prelink-addr-test.sh
@@ -0,0 +1,252 @@
+#! /bin/sh
+# Copyright (C) 2011-2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+
+# testfile52.c:
+#   #include <stdlib.h>
+#   int foo() { exit(0); }
+#
+# gcc -m32 -g -shared testfile52-32.c -o testfile52-32.so
+# eu-strip -f testfile52-32.so.debug testfile52-32.so
+# cp testfile52-32.so testfile52-32.prelink.so
+# prelink -N testfile52-32.prelink.so
+# cp testfile52-32.so testfile52-32.noshdrs.so
+# prelink -r 0x42000000 testfile52-32.noshdrs.so
+# eu-strip --remove-comment --strip-sections testfile52-32.noshdrs.so
+
+testfiles testfile52-32.so testfile52-32.so.debug
+testfiles testfile52-32.prelink.so testfile52-32.noshdrs.so
+tempfiles testmaps52-32 testfile52-32.noshdrs.so.debug
+ln -snf testfile52-32.so.debug testfile52-32.noshdrs.so.debug
+
+cat > testmaps52-32 <<EOF
+00111000-00112000 r-xp 00000000 fd:01 1 `pwd`/testfile52-32.so
+00112000-00113000 rw-p 00000000 fd:01 1 `pwd`/testfile52-32.so
+41000000-41001000 r-xp 00000000 fd:01 2 `pwd`/testfile52-32.prelink.so
+41001000-41002000 rw-p 00000000 fd:01 2 `pwd`/testfile52-32.prelink.so
+42000000-42001000 r-xp 00000000 fd:01 3 `pwd`/testfile52-32.noshdrs.so
+42001000-42002000 rw-p 00000000 fd:01 3 `pwd`/testfile52-32.noshdrs.so
+EOF
+
+# Prior to commit 1743d7f, libdwfl would fail on the second address,
+# because it didn't notice that prelink added a 0x20-byte offset from
+# what the .debug file reports.
+testrun_compare ${abs_top_builddir}/src/addr2line -S -M testmaps52-32 \
+    0x11140c 0x4100042d 0x4200040e <<\EOF
+foo
+/home/jistone/src/elfutils/tests/testfile52-32.c:2
+foo+0x1
+/home/jistone/src/elfutils/tests/testfile52-32.c:2
+foo+0x2
+/home/jistone/src/elfutils/tests/testfile52-32.c:2
+EOF
+
+# Repeat testfile52 for -m64.  The particular REL>RELA issue doesn't exist, but
+# we'll make sure the rest works anyway.
+testfiles testfile52-64.so testfile52-64.so.debug
+testfiles testfile52-64.prelink.so testfile52-64.noshdrs.so
+tempfiles testmaps52-64 testfile52-64.noshdrs.so.debug
+ln -snf testfile52-64.so.debug testfile52-64.noshdrs.so.debug
+
+cat > testmaps52-64 <<EOF
+1000000000-1000001000 r-xp 00000000 fd:11 1 `pwd`/testfile52-64.so
+1000001000-1000200000 ---p 00001000 fd:11 1 `pwd`/testfile52-64.so
+1000200000-1000201000 rw-p 00000000 fd:11 1 `pwd`/testfile52-64.so
+3000000000-3000001000 r-xp 00000000 fd:11 2 `pwd`/testfile52-64.prelink.so
+3000001000-3000200000 ---p 00001000 fd:11 2 `pwd`/testfile52-64.prelink.so
+3000200000-3000201000 rw-p 00000000 fd:11 2 `pwd`/testfile52-64.prelink.so
+3800000000-3800001000 r-xp 00000000 fd:11 3 `pwd`/testfile52-64.noshdrs.so
+3800001000-3800200000 ---p 00001000 fd:11 3 `pwd`/testfile52-64.noshdrs.so
+3800200000-3800201000 rw-p 00000000 fd:11 3 `pwd`/testfile52-64.noshdrs.so
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -M testmaps52-64 \
+    0x100000056c 0x300000056d 0x380000056e <<\EOF
+foo
+/home/jistone/src/elfutils/tests/testfile52-64.c:2
+foo+0x1
+/home/jistone/src/elfutils/tests/testfile52-64.c:2
+foo+0x2
+/home/jistone/src/elfutils/tests/testfile52-64.c:2
+EOF
+
+
+# testfile53.c:
+#   char foo[0x1000];
+#   int main() { return 0; }
+#
+# gcc -m32 -g testfile53-32.c -o testfile53-32
+# eu-strip -f testfile53-32.debug testfile53-32
+# cp testfile53-32 testfile53-32.prelink
+# prelink -N testfile53-32.prelink
+testfiles testfile53-32 testfile53-32.debug testfile53-32.prelink
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile53-32 0x8048394 0x8048395 <<\EOF
+main
+/home/jistone/src/elfutils/tests/testfile53-32.c:2
+main+0x1
+/home/jistone/src/elfutils/tests/testfile53-32.c:2
+EOF
+
+# prelink shuffled some of the sections, but .text is in the same place.
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile53-32.prelink 0x8048396 0x8048397 <<\EOF
+main+0x2
+/home/jistone/src/elfutils/tests/testfile53-32.c:2
+main+0x3
+/home/jistone/src/elfutils/tests/testfile53-32.c:2
+EOF
+
+# Repeat testfile53 in 64-bit, except use foo[0x800] to achieve the same
+# prelink section shuffling.
+testfiles testfile53-64 testfile53-64.debug testfile53-64.prelink
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile53-64 0x400474 0x400475 <<\EOF
+main
+/home/jistone/src/elfutils/tests/testfile53-64.c:2
+main+0x1
+/home/jistone/src/elfutils/tests/testfile53-64.c:2
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile53-64.prelink 0x400476 0x400477 <<\EOF
+main+0x2
+/home/jistone/src/elfutils/tests/testfile53-64.c:2
+main+0x3
+/home/jistone/src/elfutils/tests/testfile53-64.c:2
+EOF
+
+
+# testfile54.c:
+#   extern void * stdin;
+#   static void * pstdin = &stdin;
+#   void * const foo = &pstdin;
+#
+# gcc -m32 -g -shared -nostartfiles testfile54-32.c -o testfile54-32.so
+# eu-strip -f testfile54-32.so.debug testfile54-32.so
+# cp testfile54-32.so testfile54-32.prelink.so
+# prelink -N testfile54-32.prelink.so
+# cp testfile54-32.so testfile54-32.noshdrs.so
+# prelink -r 0x42000000 testfile54-32.noshdrs.so
+# eu-strip --remove-comment --strip-sections testfile54-32.noshdrs.so
+testfiles testfile54-32.so testfile54-32.so.debug
+testfiles testfile54-32.prelink.so testfile54-32.noshdrs.so
+tempfiles testmaps54-32
+
+# Note we have no testfile54-32.noshdrs.so.debug link here, so
+# this is testing finding the symbols in .dynsym via PT_DYNAMIC.
+
+cat > testmaps54-32 <<EOF
+00111000-00112000 r--p 00000000 fd:01 1 `pwd`/testfile54-32.so
+00112000-00113000 rw-p 00000000 fd:01 1 `pwd`/testfile54-32.so
+41000000-41001000 r--p 00000000 fd:01 2 `pwd`/testfile54-32.prelink.so
+41001000-41002000 rw-p 00000000 fd:01 2 `pwd`/testfile54-32.prelink.so
+42000000-42001000 r--p 00000000 fd:01 3 `pwd`/testfile54-32.noshdrs.so
+42001000-42002000 rw-p 00000000 fd:01 3 `pwd`/testfile54-32.noshdrs.so
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -M testmaps54-32 \
+    0x1111fc 0x1122a4 0x410001fd 0x410012a5 0x420001fe <<\EOF
+foo
+??:0
+pstdin
+??:0
+foo+0x1
+??:0
+pstdin+0x1
+??:0
+foo+0x2
+??:0
+EOF
+
+# Repeat testfile64 in 64-bit
+testfiles testfile54-64.so testfile54-64.so.debug
+testfiles testfile54-64.prelink.so testfile54-64.noshdrs.so
+tempfiles testmaps54-64
+
+# Note we have no testfile54-64.noshdrs.so.debug link here, so
+# this is testing finding the symbols in .dynsym via PT_DYNAMIC.
+
+cat > testmaps54-64 <<EOF
+1000000000-1000001000 r--p 00000000 fd:11 1 `pwd`/testfile54-64.so
+1000001000-1000200000 ---p 00001000 fd:11 1 `pwd`/testfile54-64.so
+1000200000-1000201000 rw-p 00000000 fd:11 1 `pwd`/testfile54-64.so
+3000000000-3000001000 r--p 00000000 fd:11 2 `pwd`/testfile54-64.prelink.so
+3000001000-3000200000 ---p 00001000 fd:11 2 `pwd`/testfile54-64.prelink.so
+3000200000-3000201000 rw-p 00000000 fd:11 2 `pwd`/testfile54-64.prelink.so
+3800000000-3800001000 r--p 00000000 fd:11 3 `pwd`/testfile54-64.noshdrs.so
+3800001000-3800200000 ---p 00001000 fd:11 3 `pwd`/testfile54-64.noshdrs.so
+3800200000-3800201000 rw-p 00000000 fd:11 3 `pwd`/testfile54-64.noshdrs.so
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -M testmaps54-64 \
+    0x10000002f8 0x1000200448 0x30000002f9 0x3000200449 0x38000002fa <<\EOF
+foo
+??:0
+pstdin
+??:0
+foo+0x1
+??:0
+pstdin+0x1
+??:0
+foo+0x2
+??:0
+EOF
+
+
+# testfile55.c:
+#   extern void *stdin;
+#   int main() { return !stdin; }
+#
+# gcc -m32 -g testfile55-32.c -o testfile55-32
+# eu-strip -f testfile55-32.debug testfile55-32
+# cp testfile55-32 testfile55-32.prelink
+# prelink -N testfile55-32.prelink
+testfiles testfile55-32 testfile55-32.debug testfile55-32.prelink
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile55-32 0x80483b4 0x80483b5 <<\EOF
+main
+/home/jistone/src/elfutils/tests/testfile55-32.c:2
+main+0x1
+/home/jistone/src/elfutils/tests/testfile55-32.c:2
+EOF
+
+# prelink splits .bss into .dynbss+.bss, so the start of .bss changes, but the
+# total size remains the same, and .text doesn't move at all.
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile55-32.prelink 0x80483b6 0x80483b7 <<\EOF
+main+0x2
+/home/jistone/src/elfutils/tests/testfile55-32.c:2
+main+0x3
+/home/jistone/src/elfutils/tests/testfile55-32.c:2
+EOF
+
+# Repeat testfile55 in 64-bit
+testfiles testfile55-64 testfile55-64.debug testfile55-64.prelink
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile55-64 0x4004b4 0x4004b5 <<\EOF
+main
+/home/jistone/src/elfutils/tests/testfile55-64.c:2
+main+0x1
+/home/jistone/src/elfutils/tests/testfile55-64.c:2
+EOF
+
+testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile55-64.prelink 0x4004b6 0x4004b7 <<\EOF
+main+0x2
+/home/jistone/src/elfutils/tests/testfile55-64.c:2
+main+0x3
+/home/jistone/src/elfutils/tests/testfile55-64.c:2
+EOF
diff --git a/third_party/elfutils/tests/run-ranlib-test.sh b/third_party/elfutils/tests/run-ranlib-test.sh
new file mode 100755
index 0000000..0b34cbb
--- /dev/null
+++ b/third_party/elfutils/tests/run-ranlib-test.sh
@@ -0,0 +1,38 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+tempfiles ranlib-test.a ranlib-test.a-copy
+
+cat > ranlib-test.a <<"EOF"
+!<arch>
+foo/            1124128960  500   500   100664  4         `
+foo
+bar/            1124128965  500   500   100664  4         `
+bar
+EOF
+
+cp ranlib-test.a ranlib-test.a-copy
+
+testrun ${abs_top_builddir}/src/ranlib ranlib-test.a
+
+# The ranlib call should not have changed anything.
+cmp ranlib-test.a ranlib-test.a-copy
+
+exit 0
diff --git a/third_party/elfutils/tests/run-ranlib-test2.sh b/third_party/elfutils/tests/run-ranlib-test2.sh
new file mode 100755
index 0000000..dbc57ec
--- /dev/null
+++ b/third_party/elfutils/tests/run-ranlib-test2.sh
@@ -0,0 +1,37 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+original=${original:-testfile19}
+indexed=${indexed:-testfile19.index}
+
+testfiles $original $indexed
+
+testrun ${abs_top_builddir}/src/ranlib $original
+
+if test -z "$noindex"; then
+  # The date in the index is different.  The reference file has it blanked
+  # out, we do the same here.
+  echo "            " |
+  dd of=$original seek=24 bs=1 count=12 conv=notrunc 2>/dev/null
+fi
+
+cmp $original $indexed
+
+exit 0
diff --git a/third_party/elfutils/tests/run-ranlib-test3.sh b/third_party/elfutils/tests/run-ranlib-test3.sh
new file mode 100755
index 0000000..1fc21cd
--- /dev/null
+++ b/third_party/elfutils/tests/run-ranlib-test3.sh
@@ -0,0 +1,22 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+original=testfile20
+indexed=testfile20.index
+. $srcdir/run-ranlib-test2.sh
diff --git a/third_party/elfutils/tests/run-ranlib-test4.sh b/third_party/elfutils/tests/run-ranlib-test4.sh
new file mode 100755
index 0000000..8070415
--- /dev/null
+++ b/third_party/elfutils/tests/run-ranlib-test4.sh
@@ -0,0 +1,23 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+original=testfile21
+indexed=testfile21.index
+noindex=1
+. $srcdir/run-ranlib-test2.sh
diff --git a/third_party/elfutils/tests/run-readelf-A.sh b/third_party/elfutils/tests/run-readelf-A.sh
new file mode 100755
index 0000000..b7432be
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-A.sh
@@ -0,0 +1,96 @@
+#! /bin/sh
+# Copyright (C) 2014 Red Hat, Inc.
+# Copyright (C) 2016 Oracle, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# See run-addrcfi.sh for testfilearm.
+
+# = testfileppc32attrs.s =
+# .gnu_attribute 8,1
+# .gnu_attribute 12,1
+#
+# gcc -m32 -c testfileppc32attrs.s
+
+# = testfilesparc64attrs.s =
+# .gnu_attribute 4,0x0aaaaaaa
+# .gnu_attribute 8,0x00000055
+#
+# gcc -c testfilesparc64attrs.s
+
+# = testfileppc64attrs.s =
+# .gnu_attribute 4,3
+#
+# gcc -c testfileppc64attrs.s
+
+testfiles testfilearm testfileppc32attrs.o testfilesparc64attrs.o testfileppc64attrs.o
+
+testrun_compare ${abs_top_builddir}/src/readelf -A testfilearm <<\EOF
+
+Object attributes section [27] '.ARM.attributes' of 53 bytes at offset 0x718:
+  Owner          Size
+  aeabi            52
+    File:          42
+      CPU_name: 7-A
+      CPU_arch: v7
+      CPU_arch_profile: Application
+      ARM_ISA_use: Yes
+      THUMB_ISA_use: Thumb-2
+      VFP_arch: VFPv3-D16
+      ABI_PCS_wchar_t: 4
+      ABI_FP_rounding: Needed
+      ABI_FP_denormal: Needed
+      ABI_FP_exceptions: Needed
+      ABI_FP_number_model: IEEE 754
+      ABI_align8_needed: Yes
+      ABI_align8_preserved: Yes, except leaf SP
+      ABI_enum_size: int
+      ABI_HardFP_use: SP and DP
+      ABI_VFP_args: VFP registers
+      CPU_unaligned_access: v6
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf -A testfileppc32attrs.o <<\EOF
+
+Object attributes section [ 4] '.gnu.attributes' of 18 bytes at offset 0x34:
+  Owner          Size
+  gnu              17
+    File:           9
+      GNU_Power_ABI_Vector: Generic
+      GNU_Power_ABI_Struct_Return: r3/r4
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf -A testfilesparc64attrs.o <<\EOF
+
+Object attributes section [ 4] '.gnu.attributes' of 21 bytes at offset 0x40:
+  Owner          Size
+  gnu              20
+    File:          12
+      GNU_Sparc_HWCAPS: div32,v8plus,vis,asi_blk_init,vis3,random,fjfmau,asi_cache_sparing,des,camellia,sha1,sha512,mont,cbcond
+      GNU_Sparc_HWCAPS2: fjathplus,adp,mwait,xmont
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf -A testfileppc64attrs.o <<\EOF
+
+Object attributes section [ 4] '.gnu.attributes' of 16 bytes at offset 0x40:
+  Owner          Size
+  gnu              15
+    File:           7
+      GNU_Power_ABI_FP: Single-precision hard float
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-aranges.sh b/third_party/elfutils/tests/run-readelf-aranges.sh
new file mode 100755
index 0000000..3fc3c54
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-aranges.sh
@@ -0,0 +1,161 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Tests readelf --debug-dump=aranges and --debug-dump=decodedaranges
+#
+# - foobarbaz.h
+#
+# int bar ();
+# int baz (int i);
+#
+# - bar.c
+#
+# #include "foobarbaz.h"
+#
+# static int bi;
+#
+# static int
+# barbaz (int i)
+# {
+#   return i * 2 - 1;
+# }
+#
+# __attribute__ ((constructor)) void
+# nobar ()
+# {
+#   bi = 1;
+# }
+#
+# int
+# bar ()
+# {
+#   bi++;
+#   return barbaz (bi);
+# }
+#
+# - foo.c
+#
+# include "foobarbaz.h"
+#
+# static int fi = 0;
+#
+# static int
+# foo (int i, int j)
+# {
+#   if (i > j)
+#     return i - j + fi;
+#   else
+#     return (2 * j) - i + fi;
+# }
+#
+# int
+# main (int argc, char **argv)
+# {
+#   int a = bar ();
+#   int b = baz (a + argc);
+#   int r = foo (a, b) - 1;
+#
+#   return r - 48;
+# }
+#
+# - baz.c
+# include "foobarbaz.h"
+#
+# static int bj;
+#
+# static int
+# bazbaz (int j)
+# {
+#   return bj * j - bar ();
+# }
+#
+# __attribute__ ((constructor)) void
+# nobaz ()
+# {
+#   bj = 1;
+# }
+#
+# int
+# baz (int i)
+# {
+#   if (i < 0)
+#     return bazbaz (i);
+#   else
+#     {
+#       while (i-- > 0)
+#         bj += bar ();
+#     }
+#   return bazbaz (i);
+# }
+#
+# gcc -g -O2 -m32 -c baz.c
+# gcc -g -O2 -m32 -c bar.c
+# gcc -g -O2 -m32 -c foo.c
+# gcc -g -O2 -m32 -o testfilefoobarbaz foo.o bar.o baz.o
+
+testfiles testfilefoobarbaz
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=aranges testfilefoobarbaz <<EOF
+
+DWARF section [27] '.debug_aranges' at offset 0x1044:
+
+Table at offset 0:
+
+ Length:            28
+ DWARF version:      2
+ CU offset:          0
+ Address size:       4
+ Segment size:       0
+
+   0x080482f0 <main>..0x08048323 <main+0x33>
+
+Table at offset 32:
+
+ Length:            36
+ DWARF version:      2
+ CU offset:        136
+ Address size:       4
+ Segment size:       0
+
+   0x08048440 <bar>..0x08048451 <bar+0x11>
+   0x08048330 <nobar>..0x0804833a <nobar+0xa>
+
+Table at offset 72:
+
+ Length:            36
+ DWARF version:      2
+ CU offset:        1d1
+ Address size:       4
+ Segment size:       0
+
+   0x08048460 <baz>..0x080484bb <baz+0x5b>
+   0x08048340 <nobaz>..0x0804834a <nobaz+0xa>
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=decodedaranges testfilefoobarbaz <<\EOF
+
+DWARF section [27] '.debug_aranges' at offset 0x1044 contains 5 entries:
+ [0] start: 0x080482f0, length:    52, CU DIE offset:     11
+ [1] start: 0x08048330, length:    11, CU DIE offset:    321
+ [2] start: 0x08048340, length:    11, CU DIE offset:    476
+ [3] start: 0x08048440, length:    18, CU DIE offset:    321
+ [4] start: 0x08048460, length:    92, CU DIE offset:    476
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-d.sh b/third_party/elfutils/tests/run-readelf-d.sh
new file mode 100755
index 0000000..d0b6ed2
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-d.sh
@@ -0,0 +1,70 @@
+#! /bin/sh
+# Copyright (C) 2012 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# #include <stdio.h>
+# 
+# __thread int i;
+# 
+# void print_i ()
+# {
+#   printf("%d\n", i);
+# }
+#
+# gcc -fPIC -shared -o testlib_dynseg.so testlib_dynseg.c
+# With ld --version
+# GNU gold (GNU Binutils 2.22.52.20120402) 1.11
+
+testfiles testlib_dynseg.so
+
+testrun_compare ${abs_top_builddir}/src/readelf -d testlib_dynseg.so <<\EOF
+
+Dynamic segment contains 28 entries:
+ Addr: 0x00000000000017e0  Offset: 0x0007e0  Link to section: [ 3] '.dynstr'
+  Type              Value
+  PLTGOT            0x00000000000019c8
+  PLTRELSZ          72 (bytes)
+  JMPREL            0x0000000000000568
+  PLTREL            RELA
+  RELA              0x00000000000004d8
+  RELASZ            144 (bytes)
+  RELAENT           24 (bytes)
+  RELACOUNT         1
+  SYMTAB            0x0000000000000228
+  SYMENT            24 (bytes)
+  STRTAB            0x0000000000000360
+  STRSZ             190 (bytes)
+  GNU_HASH          0x0000000000000420
+  NEEDED            Shared library: [libc.so.6]
+  NEEDED            Shared library: [ld-linux-x86-64.so.2]
+  INIT              0x00000000000005b0
+  FINI              0x0000000000000748
+  VERSYM            0x0000000000000460
+  VERDEF            0x000000000000047c
+  VERDEFNUM         1
+  VERNEED           0x0000000000000498
+  VERNEEDNUM        2
+  NULL              
+  NULL              
+  NULL              
+  NULL              
+  NULL              
+  NULL              
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-dwz-multi.sh b/third_party/elfutils/tests/run-readelf-dwz-multi.sh
new file mode 100755
index 0000000..4f317ac
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-dwz-multi.sh
@@ -0,0 +1,332 @@
+#! /bin/sh
+# Copyright (C) 2012, 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# common.h
+#
+# #include <stdio.h>
+#
+# struct foobar
+# {
+#   int foo;
+#   struct foobar *bar;
+# };
+#
+# extern int call_foo(struct foobar *foobar_struct_ptr);
+
+# main.c
+#
+# #include "common.h"
+#
+# int main(int argc, char ** argv)
+# {
+#   struct foobar b;
+#   b.foo = 42;
+#   b.bar = &b;
+#
+#   return call_foo(b.bar);
+# }
+
+# shared.c
+#
+# #include "common.h"
+#
+# int call_foo(struct foobar *fb)
+# {
+#   return fb->bar->foo - 42;
+# }
+
+# gcc -fPIC -g -c -Wall shared.c
+# gcc -shared -o libtestfile_multi_shared.so shared.o
+# gcc -g -o testfile_multi_main -L. -ltestfile_multi_shared main.c -Wl,-rpath,.
+# dwz -m testfile_multi.dwz testfile_multi_main libtestfile_multi_shared.so
+
+# main.c
+#
+# struct foobarbaz
+# {
+#   int counter;
+#   char *bookstore;
+# };
+#
+# int
+# main (int argc, char **argv)
+# {
+#   struct foobarbaz fbb;
+#   return 0;
+# }
+
+# gcc -g -o testfile-dwzstr main.c
+# cp testfile-dwzstr testfile-dwzstr.alt
+# dwz -m testfile-dwzstr.multi testfile-dwzstr testfile-dwzstr.alt
+
+testfiles libtestfile_multi_shared.so testfile_multi_main testfile_multi.dwz
+testfiles testfile-dwzstr testfile-dwzstr.multi
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=info testfile_multi_main <<\EOF
+
+DWARF section [28] '.debug_info' at offset 0x1078:
+ [Offset]
+ Compilation unit at offset 0:
+ Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
+ [     b]  compile_unit         abbrev: 6
+           producer             (strp) "GNU C 4.7.0 20120507 (Red Hat 4.7.0-5) -mtune=generic -march=x86-64 -g"
+           language             (data1) C89 (1)
+           name                 (strp) "main.c"
+           comp_dir             (GNU_strp_alt) "/home/mark/src/tests/dwz"
+           low_pc               (addr) 0x00000000004006ac <main>
+           high_pc              (udata) 44 (0x00000000004006d8)
+           stmt_list            (sec_offset) 0
+ [    26]    imported_unit        abbrev: 5
+             import               (GNU_ref_alt) [     b]
+ [    2b]    pointer_type         abbrev: 1
+             byte_size            (data1) 8
+             type                 (GNU_ref_alt) [    53]
+ [    31]    subprogram           abbrev: 3
+             external             (flag_present) yes
+             name                 (strp) "main"
+             decl_file            (data1) main.c (1)
+             decl_line            (data1) 3
+             prototyped           (flag_present) yes
+             type                 (GNU_ref_alt) [    3e]
+             low_pc               (addr) 0x00000000004006ac <main>
+             high_pc              (udata) 44 (0x00000000004006d8)
+             frame_base           (exprloc) 
+              [ 0] call_frame_cfa
+             GNU_all_tail_call_sites (flag_present) yes
+             sibling              (ref_udata) [    6e]
+ [    48]      formal_parameter     abbrev: 8
+               name                 (strp) "argc"
+               decl_file            (data1) main.c (1)
+               decl_line            (data1) 3
+               type                 (GNU_ref_alt) [    3e]
+               location             (exprloc) 
+                [ 0] fbreg -36
+ [    56]      formal_parameter     abbrev: 4
+               name                 (strp) "argv"
+               decl_file            (data1) main.c (1)
+               decl_line            (data1) 3
+               type                 (ref_udata) [    6e]
+               location             (exprloc) 
+                [ 0] fbreg -48
+ [    61]      variable             abbrev: 7
+               name                 (string) "b"
+               decl_file            (data1) main.c (1)
+               decl_line            (data1) 5
+               type                 (GNU_ref_alt) [    5a]
+               location             (exprloc) 
+                [ 0] fbreg -32
+ [    6e]    pointer_type         abbrev: 2
+             byte_size            (data1) 8
+             type                 (ref_udata) [    2b]
+EOF
+
+# Same as above, but find alt debug file in a .dwz subdir.
+mkdir .dwz
+mv testfile_multi.dwz .dwz
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=info testfile_multi_main <<\EOF
+
+DWARF section [28] '.debug_info' at offset 0x1078:
+ [Offset]
+ Compilation unit at offset 0:
+ Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
+ [     b]  compile_unit         abbrev: 6
+           producer             (strp) "GNU C 4.7.0 20120507 (Red Hat 4.7.0-5) -mtune=generic -march=x86-64 -g"
+           language             (data1) C89 (1)
+           name                 (strp) "main.c"
+           comp_dir             (GNU_strp_alt) "/home/mark/src/tests/dwz"
+           low_pc               (addr) 0x00000000004006ac <main>
+           high_pc              (udata) 44 (0x00000000004006d8)
+           stmt_list            (sec_offset) 0
+ [    26]    imported_unit        abbrev: 5
+             import               (GNU_ref_alt) [     b]
+ [    2b]    pointer_type         abbrev: 1
+             byte_size            (data1) 8
+             type                 (GNU_ref_alt) [    53]
+ [    31]    subprogram           abbrev: 3
+             external             (flag_present) yes
+             name                 (strp) "main"
+             decl_file            (data1) main.c (1)
+             decl_line            (data1) 3
+             prototyped           (flag_present) yes
+             type                 (GNU_ref_alt) [    3e]
+             low_pc               (addr) 0x00000000004006ac <main>
+             high_pc              (udata) 44 (0x00000000004006d8)
+             frame_base           (exprloc) 
+              [ 0] call_frame_cfa
+             GNU_all_tail_call_sites (flag_present) yes
+             sibling              (ref_udata) [    6e]
+ [    48]      formal_parameter     abbrev: 8
+               name                 (strp) "argc"
+               decl_file            (data1) main.c (1)
+               decl_line            (data1) 3
+               type                 (GNU_ref_alt) [    3e]
+               location             (exprloc) 
+                [ 0] fbreg -36
+ [    56]      formal_parameter     abbrev: 4
+               name                 (strp) "argv"
+               decl_file            (data1) main.c (1)
+               decl_line            (data1) 3
+               type                 (ref_udata) [    6e]
+               location             (exprloc) 
+                [ 0] fbreg -48
+ [    61]      variable             abbrev: 7
+               name                 (string) "b"
+               decl_file            (data1) main.c (1)
+               decl_line            (data1) 5
+               type                 (GNU_ref_alt) [    5a]
+               location             (exprloc) 
+                [ 0] fbreg -32
+ [    6e]    pointer_type         abbrev: 2
+             byte_size            (data1) 8
+             type                 (ref_udata) [    2b]
+EOF
+mv .dwz/testfile_multi.dwz .
+rmdir .dwz
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=info libtestfile_multi_shared.so <<\EOF
+
+DWARF section [25] '.debug_info' at offset 0x106c:
+ [Offset]
+ Compilation unit at offset 0:
+ Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
+ [     b]  compile_unit         abbrev: 3
+           producer             (strp) "GNU C 4.7.0 20120507 (Red Hat 4.7.0-5) -fpreprocessed -mtune=generic -march=x86-64 -g -fPIC"
+           language             (data1) C89 (1)
+           name                 (strp) "shared.c"
+           comp_dir             (GNU_strp_alt) "/home/mark/src/tests/dwz"
+           low_pc               (addr) +0x0000000000000670 <call_foo>
+           high_pc              (udata) 23 (+0x0000000000000687)
+           stmt_list            (sec_offset) 0
+ [    26]    imported_unit        abbrev: 2
+             import               (GNU_ref_alt) [     b]
+ [    2b]    subprogram           abbrev: 1
+             external             (flag_present) yes
+             name                 (strp) "call_foo"
+             decl_file            (data1) shared.c (1)
+             decl_line            (data1) 3
+             prototyped           (flag_present) yes
+             type                 (GNU_ref_alt) [    3e]
+             low_pc               (addr) +0x0000000000000670 <call_foo>
+             high_pc              (udata) 23 (+0x0000000000000687)
+             frame_base           (exprloc) 
+              [ 0] call_frame_cfa
+             GNU_all_call_sites   (flag_present) yes
+ [    41]      formal_parameter     abbrev: 4
+               name                 (string) "fb"
+               decl_file            (data1) shared.c (1)
+               decl_line            (data1) 3
+               type                 (GNU_ref_alt) [    76]
+               location             (exprloc) 
+                [ 0] fbreg -24
+EOF
+
+# Same as above, but find alt debug file in a .dwz subdir.
+mkdir .dwz
+mv testfile_multi.dwz .dwz
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=info libtestfile_multi_shared.so <<\EOF
+
+DWARF section [25] '.debug_info' at offset 0x106c:
+ [Offset]
+ Compilation unit at offset 0:
+ Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
+ [     b]  compile_unit         abbrev: 3
+           producer             (strp) "GNU C 4.7.0 20120507 (Red Hat 4.7.0-5) -fpreprocessed -mtune=generic -march=x86-64 -g -fPIC"
+           language             (data1) C89 (1)
+           name                 (strp) "shared.c"
+           comp_dir             (GNU_strp_alt) "/home/mark/src/tests/dwz"
+           low_pc               (addr) +0x0000000000000670 <call_foo>
+           high_pc              (udata) 23 (+0x0000000000000687)
+           stmt_list            (sec_offset) 0
+ [    26]    imported_unit        abbrev: 2
+             import               (GNU_ref_alt) [     b]
+ [    2b]    subprogram           abbrev: 1
+             external             (flag_present) yes
+             name                 (strp) "call_foo"
+             decl_file            (data1) shared.c (1)
+             decl_line            (data1) 3
+             prototyped           (flag_present) yes
+             type                 (GNU_ref_alt) [    3e]
+             low_pc               (addr) +0x0000000000000670 <call_foo>
+             high_pc              (udata) 23 (+0x0000000000000687)
+             frame_base           (exprloc) 
+              [ 0] call_frame_cfa
+             GNU_all_call_sites   (flag_present) yes
+ [    41]      formal_parameter     abbrev: 4
+               name                 (string) "fb"
+               decl_file            (data1) shared.c (1)
+               decl_line            (data1) 3
+               type                 (GNU_ref_alt) [    76]
+               location             (exprloc) 
+                [ 0] fbreg -24
+EOF
+mv .dwz/testfile_multi.dwz .
+rmdir .dwz
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=info testfile-dwzstr <<\EOF
+
+DWARF section [28] '.debug_info' at offset 0x1088:
+ [Offset]
+ Compilation unit at offset 0:
+ Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
+ [     b]  compile_unit         abbrev: 5
+           producer             (GNU_strp_alt) "GNU C 4.7.2 20121109 (Red Hat 4.7.2-8) -mtune=generic -march=x86-64 -g"
+           language             (data1) C89 (1)
+           name                 (GNU_strp_alt) "main.c"
+           comp_dir             (GNU_strp_alt) "/home/mark/src/tests"
+           low_pc               (addr) 0x00000000004004ec <main>
+           high_pc              (udata) 18 (0x00000000004004fe)
+           stmt_list            (sec_offset) 0
+ [    26]    imported_unit        abbrev: 2
+             import               (GNU_ref_alt) [     b]
+ [    2b]    subprogram           abbrev: 4
+             external             (flag_present) yes
+             name                 (GNU_strp_alt) "main"
+             decl_file            (data1) main.c (1)
+             decl_line            (data1) 8
+             prototyped           (flag_present) yes
+             type                 (GNU_ref_alt) [    30]
+             low_pc               (addr) 0x00000000004004ec <main>
+             high_pc              (udata) 18 (0x00000000004004fe)
+             frame_base           (exprloc) 
+              [ 0] call_frame_cfa
+             GNU_all_call_sites   (flag_present) yes
+ [    41]      formal_parameter     abbrev: 1
+               name                 (GNU_strp_alt) "argc"
+               decl_file            (data1) main.c (1)
+               decl_line            (data1) 8
+               type                 (GNU_ref_alt) [    30]
+               location             (exprloc) 
+                [ 0] fbreg -36
+ [    4f]      formal_parameter     abbrev: 1
+               name                 (GNU_strp_alt) "argv"
+               decl_file            (data1) main.c (1)
+               decl_line            (data1) 8
+               type                 (GNU_ref_alt) [    41]
+               location             (exprloc) 
+                [ 0] fbreg -48
+ [    5d]      variable             abbrev: 3
+               name                 (string) "fbb"
+               decl_file            (data1) main.c (1)
+               decl_line            (data1) 10
+               type                 (GNU_ref_alt) [    14]
+               location             (exprloc) 
+                [ 0] fbreg -32
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-gdb_index.sh b/third_party/elfutils/tests/run-readelf-gdb_index.sh
new file mode 100755
index 0000000..fcbc3c5
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-gdb_index.sh
@@ -0,0 +1,130 @@
+#! /bin/sh
+# Copyright (C) 2012 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# common.h
+# struct foo
+# {
+#   const char *bar;
+# };
+#
+# extern char *global;
+# int say (struct foo *prefix);
+
+# hello.c
+# #include "common.h"
+#
+# static char *hello = "Hello";
+#
+# int
+# main (int argc, char **argv)
+# {
+#   struct foo baz;
+#   global = hello;
+#   baz.bar = global;
+#   return say(&baz);
+# }
+
+# world.c
+# #include "common.h"
+#
+# char *global;
+#
+# static int hello (const char *bar)
+# {
+#   return bar == global;
+# }
+#
+# int
+# say (struct foo *prefix)
+# {
+#   return hello (prefix->bar);
+# }
+
+# gcc -g -fdebug-types-section -c hello.c
+# gcc -g -fdebug-types-section -c world.c
+# gcc -g -fdebug-types-section -o testfilegdbindex7 hello.o world.o
+# gdb testfilegdbindex7
+# (gdb) save gdb-index .
+# objcopy --add-section .gdb_index=testfilegdbindex7.gdb-index --set-section-flags .gdb_index=readonly testfilegdbindex7 testfilegdbindex7
+
+testfiles testfilegdbindex5 testfilegdbindex7
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=gdb_index testfilegdbindex5 <<\EOF
+
+GDB section [33] '.gdb_index' at offset 0xe76 contains 8383 bytes :
+ Version:         5
+ CU offset:       0x18
+ TU offset:       0x38
+ address offset:  0x50
+ symbol offset:   0x78
+ constant offset: 0x2078
+
+ CU list at offset 0x18 contains 2 entries:
+ [   0] start: 00000000, length:   184
+ [   1] start: 0x0000b8, length:   204
+
+ TU list at offset 0x38 contains 1 entries:
+ [   0] CU offset:     0, type offset:    29, signature: 0x87e03f92cc37cdf0
+
+ Address list at offset 0x50 contains 2 entries:
+ [   0] 0x000000000040049c <main>..0x00000000004004d1 <main+0x35>, CU index:     0
+ [   1] 0x00000000004004d4 <hello>..0x000000000040050b <say+0x1c>, CU index:     1
+
+ Symbol table at offset 0x50 contains 1024 slots:
+ [ 123] symbol: global, CUs: 1
+ [ 489] symbol: main, CUs: 0
+ [ 518] symbol: char, CUs: 0
+ [ 661] symbol: foo, CUs: 0T
+ [ 741] symbol: hello, CUs: 0, 1
+ [ 746] symbol: say, CUs: 1
+ [ 754] symbol: int, CUs: 0
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=gdb_index testfilegdbindex7 <<\EOF
+
+GDB section [33] '.gdb_index' at offset 0xe76 contains 8399 bytes :
+ Version:         7
+ CU offset:       0x18
+ TU offset:       0x38
+ address offset:  0x50
+ symbol offset:   0x78
+ constant offset: 0x2078
+
+ CU list at offset 0x18 contains 2 entries:
+ [   0] start: 00000000, length:   184
+ [   1] start: 0x0000b8, length:   204
+
+ TU list at offset 0x38 contains 1 entries:
+ [   0] CU offset:     0, type offset:    29, signature: 0x87e03f92cc37cdf0
+
+ Address list at offset 0x50 contains 2 entries:
+ [   0] 0x000000000040049c <main>..0x00000000004004d1 <main+0x35>, CU index:     0
+ [   1] 0x00000000004004d4 <hello>..0x000000000040050b <say+0x1c>, CU index:     1
+
+ Symbol table at offset 0x50 contains 1024 slots:
+ [ 123] symbol: global, CUs: 1 (var:G)
+ [ 489] symbol: main, CUs: 0 (func:G)
+ [ 518] symbol: char, CUs: 0 (type:S)
+ [ 661] symbol: foo, CUs: 0T (type:S)
+ [ 741] symbol: hello, CUs: 0 (var:S), 1 (func:S)
+ [ 746] symbol: say, CUs: 1 (func:G)
+ [ 754] symbol: int, CUs: 0 (type:S)
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-line.sh b/third_party/elfutils/tests/run-readelf-line.sh
new file mode 100755
index 0000000..32bcf9d
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-line.sh
@@ -0,0 +1,259 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Tests readelf --debug-dump=line and --debug-dump=decodedline
+# See run-readelf-aranges for testfiles.
+
+testfiles testfilefoobarbaz
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=line testfilefoobarbaz <<EOF
+
+DWARF section [30] '.debug_line' at offset 0x15f6:
+
+Table at offset 0:
+
+ Length:                     83
+ DWARF version:              2
+ Prologue length:            43
+ Minimum instruction length: 1
+ Maximum operations per instruction: 1
+ Initial value if 'is_stmt': 1
+ Line base:                  -5
+ Line range:                 14
+ Opcode base:                13
+
+Opcodes:
+  [ 1]  0 arguments
+  [ 2]  1 argument
+  [ 3]  1 argument
+  [ 4]  1 argument
+  [ 5]  1 argument
+  [ 6]  0 arguments
+  [ 7]  0 arguments
+  [ 8]  0 arguments
+  [ 9]  1 argument
+  [10]  0 arguments
+  [11]  0 arguments
+  [12]  1 argument
+
+Directory table:
+
+File name table:
+ Entry Dir   Time      Size      Name
+ 1     0     0         0         foo.c
+ 2     0     0         0         foobarbaz.h
+
+Line number statements:
+ [    35] extended opcode 2:  set address to 0x80482f0 <main>
+ [    3c] advance line by constant 15 to 16
+ [    3e] copy
+ [    3f] special opcode 159: address+10 = 0x80482fa <main+0xa>, line+1 = 17
+ [    40] special opcode 117: address+7 = 0x8048301 <main+0x11>, line+1 = 18
+ [    41] advance line by constant -9 to 9
+ [    43] special opcode 200: address+13 = 0x804830e <main+0x1e>, line+0 = 9
+ [    44] special opcode 48: address+2 = 0x8048310 <main+0x20>, line+2 = 11
+ [    45] special opcode 58: address+3 = 0x8048313 <main+0x23>, line-2 = 9
+ [    46] special opcode 48: address+2 = 0x8048315 <main+0x25>, line+2 = 11
+ [    47] special opcode 44: address+2 = 0x8048317 <main+0x27>, line-2 = 9
+ [    48] advance line by constant 13 to 22
+ [    4a] special opcode 46: address+2 = 0x8048319 <main+0x29>, line+0 = 22
+ [    4b] advance line by constant -13 to 9
+ [    4d] special opcode 60: address+3 = 0x804831c <main+0x2c>, line+0 = 9
+ [    4e] advance line by constant 12 to 21
+ [    50] special opcode 60: address+3 = 0x804831f <main+0x2f>, line+0 = 21
+ [    51] special opcode 61: address+3 = 0x8048322 <main+0x32>, line+1 = 22
+ [    52] advance address by 2 to 0x8048324
+ [    54] extended opcode 1:  end of sequence
+
+Table at offset 87:
+
+ Length:                     72
+ DWARF version:              2
+ Prologue length:            28
+ Minimum instruction length: 1
+ Maximum operations per instruction: 1
+ Initial value if 'is_stmt': 1
+ Line base:                  -5
+ Line range:                 14
+ Opcode base:                13
+
+Opcodes:
+  [ 1]  0 arguments
+  [ 2]  1 argument
+  [ 3]  1 argument
+  [ 4]  1 argument
+  [ 5]  1 argument
+  [ 6]  0 arguments
+  [ 7]  0 arguments
+  [ 8]  0 arguments
+  [ 9]  1 argument
+  [10]  0 arguments
+  [11]  0 arguments
+  [12]  1 argument
+
+Directory table:
+
+File name table:
+ Entry Dir   Time      Size      Name
+ 1     0     0         0         bar.c
+
+Line number statements:
+ [    7d] extended opcode 2:  set address to 0x8048330 <nobar>
+ [    84] advance line by constant 12 to 13
+ [    86] copy
+ [    87] special opcode 19: address+0 = 0x8048330 <nobar>, line+1 = 14
+ [    88] advance address by 11 to 0x804833b
+ [    8a] extended opcode 1:  end of sequence
+ [    8d] extended opcode 2:  set address to 0x8048440 <bar>
+ [    94] advance line by constant 18 to 19
+ [    96] copy
+ [    97] special opcode 19: address+0 = 0x8048440 <bar>, line+1 = 20
+ [    98] advance line by constant -12 to 8
+ [    9a] special opcode 200: address+13 = 0x804844d <bar+0xd>, line+0 = 8
+ [    9b] advance line by constant 14 to 22
+ [    9d] special opcode 74: address+4 = 0x8048451 <bar+0x11>, line+0 = 22
+ [    9e] advance address by 1 to 0x8048452
+ [    a0] extended opcode 1:  end of sequence
+
+Table at offset 163:
+
+ Length:                     106
+ DWARF version:              2
+ Prologue length:            43
+ Minimum instruction length: 1
+ Maximum operations per instruction: 1
+ Initial value if 'is_stmt': 1
+ Line base:                  -5
+ Line range:                 14
+ Opcode base:                13
+
+Opcodes:
+  [ 1]  0 arguments
+  [ 2]  1 argument
+  [ 3]  1 argument
+  [ 4]  1 argument
+  [ 5]  1 argument
+  [ 6]  0 arguments
+  [ 7]  0 arguments
+  [ 8]  0 arguments
+  [ 9]  1 argument
+  [10]  0 arguments
+  [11]  0 arguments
+  [12]  1 argument
+
+Directory table:
+
+File name table:
+ Entry Dir   Time      Size      Name
+ 1     0     0         0         baz.c
+ 2     0     0         0         foobarbaz.h
+
+Line number statements:
+ [    d8] extended opcode 2:  set address to 0x8048340 <nobaz>
+ [    df] advance line by constant 12 to 13
+ [    e1] copy
+ [    e2] special opcode 19: address+0 = 0x8048340 <nobaz>, line+1 = 14
+ [    e3] advance address by 11 to 0x804834b
+ [    e5] extended opcode 1:  end of sequence
+ [    e8] extended opcode 2:  set address to 0x8048460 <baz>
+ [    ef] advance line by constant 18 to 19
+ [    f1] copy
+ [    f2] special opcode 74: address+4 = 0x8048464 <baz+0x4>, line+0 = 19
+ [    f3] special opcode 75: address+4 = 0x8048468 <baz+0x8>, line+1 = 20
+ [    f4] extended opcode 4:  set discriminator to 1
+ [    f8] special opcode 78: address+4 = 0x804846c <baz+0xc>, line+4 = 24
+ [    f9] special opcode 187: address+12 = 0x8048478 <baz+0x18>, line+1 = 25
+ [    fa] special opcode 87: address+5 = 0x804847d <baz+0x1d>, line-1 = 24
+ [    fb] special opcode 61: address+3 = 0x8048480 <baz+0x20>, line+1 = 25
+ [    fc] special opcode 101: address+6 = 0x8048486 <baz+0x26>, line-1 = 24
+ [    fd] special opcode 61: address+3 = 0x8048489 <baz+0x29>, line+1 = 25
+ [    fe] special opcode 87: address+5 = 0x804848e <baz+0x2e>, line-1 = 24
+ [    ff] advance line by constant -16 to 8
+ [   101] special opcode 46: address+2 = 0x8048490 <baz+0x30>, line+0 = 8
+ [   102] advance line by constant 20 to 28
+ [   104] special opcode 186: address+12 = 0x804849c <baz+0x3c>, line+0 = 28
+ [   105] advance line by constant -20 to 8
+ [   107] special opcode 88: address+5 = 0x80484a1 <baz+0x41>, line+0 = 8
+ [   108] advance line by constant 13 to 21
+ [   10a] advance address by constant 17 to 0x80484b2 <baz+0x52>
+ [   10b] special opcode 32: address+1 = 0x80484b3 <baz+0x53>, line+0 = 21
+ [   10c] advance address by 9 to 0x80484bc
+ [   10e] extended opcode 1:  end of sequence
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=decodedline testfilefoobarbaz <<\EOF
+
+DWARF section [30] '.debug_line' at offset 0x15f6:
+
+ CU [b] foo.c
+  line:col SBPE* disc isa op address (Statement Block Prologue Epilogue *End)
+  /home/mark/src/tests/foobarbaz/foo.c (mtime: 0, length: 0)
+    16:0   S        0   0  0 0x080482f0 <main>
+    17:0   S        0   0  0 0x080482fa <main+0xa>
+    18:0   S        0   0  0 0x08048301 <main+0x11>
+     9:0   S        0   0  0 0x0804830e <main+0x1e>
+    11:0   S        0   0  0 0x08048310 <main+0x20>
+     9:0   S        0   0  0 0x08048313 <main+0x23>
+    11:0   S        0   0  0 0x08048315 <main+0x25>
+     9:0   S        0   0  0 0x08048317 <main+0x27>
+    22:0   S        0   0  0 0x08048319 <main+0x29>
+     9:0   S        0   0  0 0x0804831c <main+0x2c>
+    21:0   S        0   0  0 0x0804831f <main+0x2f>
+    22:0   S        0   0  0 0x08048322 <main+0x32>
+    22:0   S   *    0   0  0 0x08048323 <main+0x33>
+
+ CU [141] bar.c
+  line:col SBPE* disc isa op address (Statement Block Prologue Epilogue *End)
+  /home/mark/src/tests/foobarbaz/bar.c (mtime: 0, length: 0)
+    13:0   S        0   0  0 0x08048330 <nobar>
+    14:0   S        0   0  0 0x08048330 <nobar>
+    14:0   S   *    0   0  0 0x0804833a <nobar+0xa>
+
+    19:0   S        0   0  0 0x08048440 <bar>
+    20:0   S        0   0  0 0x08048440 <bar>
+     8:0   S        0   0  0 0x0804844d <bar+0xd>
+    22:0   S        0   0  0 0x08048451 <bar+0x11>
+    22:0   S   *    0   0  0 0x08048451 <bar+0x11>
+
+ CU [1dc] baz.c
+  line:col SBPE* disc isa op address (Statement Block Prologue Epilogue *End)
+  /home/mark/src/tests/foobarbaz/baz.c (mtime: 0, length: 0)
+    13:0   S        0   0  0 0x08048340 <nobaz>
+    14:0   S        0   0  0 0x08048340 <nobaz>
+    14:0   S   *    0   0  0 0x0804834a <nobaz+0xa>
+
+    19:0   S        0   0  0 0x08048460 <baz>
+    19:0   S        0   0  0 0x08048464 <baz+0x4>
+    20:0   S        0   0  0 0x08048468 <baz+0x8>
+    24:0   S        1   0  0 0x0804846c <baz+0xc>
+    25:0   S        0   0  0 0x08048478 <baz+0x18>
+    24:0   S        0   0  0 0x0804847d <baz+0x1d>
+    25:0   S        0   0  0 0x08048480 <baz+0x20>
+    24:0   S        0   0  0 0x08048486 <baz+0x26>
+    25:0   S        0   0  0 0x08048489 <baz+0x29>
+    24:0   S        0   0  0 0x0804848e <baz+0x2e>
+     8:0   S        0   0  0 0x08048490 <baz+0x30>
+    28:0   S        0   0  0 0x0804849c <baz+0x3c>
+     8:0   S        0   0  0 0x080484a1 <baz+0x41>
+    21:0   S        0   0  0 0x080484b3 <baz+0x53>
+    21:0   S   *    0   0  0 0x080484bb <baz+0x5b>
+
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-loc.sh b/third_party/elfutils/tests/run-readelf-loc.sh
new file mode 100755
index 0000000..e5152df
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-loc.sh
@@ -0,0 +1,170 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# - hello.c
+# int say (const char *prefix);
+#
+# static char *
+# subject (char *word, int count)
+# {
+#   return count > 0 ? word : (word + count);
+# }
+#
+# int
+# main (int argc, char **argv)
+# {
+#    return say (subject (argv[0], argc));
+# }
+#
+# - world.c
+# static int
+# sad (char c)
+# {
+#   return c > 0 ? c : c + 1;
+# }
+#
+# static int
+# happy (const char *w)
+# {
+#   return sad (w[1]);
+# }
+#
+# int
+# say (const char *prefix)
+# {
+#   const char *world = "World";
+#   return prefix ? sad (prefix[0]) : happy (world);
+# }
+#
+# gcc -g -O2 -c hello.c
+# gcc -g -O2 -c world.c
+# gcc -g -o testfileloc hello.o world.o
+
+testfiles testfileloc
+
+# Process values as offsets from base addresses and resolve to symbols.
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=loc --debug-dump=ranges \
+  testfileloc<<\EOF
+
+DWARF section [33] '.debug_loc' at offset 0xd2a:
+
+ CU [     b] base: 0x0000000000400480 <main>
+ [     0] range 0, d
+          0x0000000000400480 <main>..
+          0x000000000040048c <main+0xc>
+           [ 0] reg5
+ [    23] range 5, d
+          0x0000000000400485 <main+0x5>..
+          0x000000000040048c <main+0xc>
+           [ 0] reg5
+
+ CU [    e0] base: 0x00000000004004a0 <say>
+ [    46] range 12, 1a
+          0x00000000004004b2 <say+0x12>..
+          0x00000000004004b9 <say+0x19>
+           [ 0] breg5 0
+
+DWARF section [34] '.debug_ranges' at offset 0xd94:
+
+ CU [     b] base: 0x0000000000400480 <main>
+ [     0] range 0, 2
+          0x0000000000400480 <main>..
+          0x0000000000400481 <main+0x1>
+          range 5, d
+          0x0000000000400485 <main+0x5>..
+          0x000000000040048c <main+0xc>
+
+ CU [    e0] base: 0x00000000004004a0 <say>
+ [    30] range d, f
+          0x00000000004004ad <say+0xd>..
+          0x00000000004004ae <say+0xe>
+          range 12, 1a
+          0x00000000004004b2 <say+0x12>..
+          0x00000000004004b9 <say+0x19>
+EOF
+
+# Don't resolve addresses to symbols.
+testrun_compare ${abs_top_builddir}/src/readelf -N --debug-dump=loc --debug-dump=ranges \
+  testfileloc<<\EOF
+
+DWARF section [33] '.debug_loc' at offset 0xd2a:
+
+ CU [     b] base: 0x0000000000400480
+ [     0] range 0, d
+          0x0000000000400480..
+          0x000000000040048c
+           [ 0] reg5
+ [    23] range 5, d
+          0x0000000000400485..
+          0x000000000040048c
+           [ 0] reg5
+
+ CU [    e0] base: 0x00000000004004a0
+ [    46] range 12, 1a
+          0x00000000004004b2..
+          0x00000000004004b9
+           [ 0] breg5 0
+
+DWARF section [34] '.debug_ranges' at offset 0xd94:
+
+ CU [     b] base: 0x0000000000400480
+ [     0] range 0, 2
+          0x0000000000400480..
+          0x0000000000400481
+          range 5, d
+          0x0000000000400485..
+          0x000000000040048c
+
+ CU [    e0] base: 0x00000000004004a0
+ [    30] range d, f
+          0x00000000004004ad..
+          0x00000000004004ae
+          range 12, 1a
+          0x00000000004004b2..
+          0x00000000004004b9
+EOF
+
+# Produce "raw" unprocessed content.
+testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc --debug-dump=ranges \
+  testfileloc<<\EOF
+
+DWARF section [33] '.debug_loc' at offset 0xd2a:
+
+ CU [     b] base: 0x0000000000400480
+ [     0] range 0, d
+           [ 0] reg5
+ [    23] range 5, d
+           [ 0] reg5
+
+ CU [    e0] base: 0x00000000004004a0
+ [    46] range 12, 1a
+           [ 0] breg5 0
+
+DWARF section [34] '.debug_ranges' at offset 0xd94:
+
+ CU [     b] base: 0x0000000000400480
+ [     0] range 0, 2
+          range 5, d
+
+ CU [    e0] base: 0x00000000004004a0
+ [    30] range d, f
+          range 12, 1a
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-macro.sh b/third_party/elfutils/tests/run-readelf-macro.sh
new file mode 100755
index 0000000..8693203
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-macro.sh
@@ -0,0 +1,345 @@
+#! /bin/sh
+# Copyright (C) 2012 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# common.h
+# #define ONE 1
+# #define TWO 2
+# #define THREE 3
+#
+# #define WORLD "World"
+#
+# int say (const char *prefix);
+#
+# #define A 'a'
+# #define B b
+# #define C "C"
+#
+# #ifdef THREE
+# #undef THREE
+# #define THREE(ARG1,ARG2,ARG3) ARG3
+# #endif
+
+# hello.c
+# #include "common.h"
+#
+# int
+# main (int argc, char **argv)
+# {
+#   return say (WORLD);
+# }
+
+# world.c
+# #include "common.h"
+#
+# int
+# say (const char *prefix)
+# {
+#   return prefix ? ONE : TWO;
+# }
+
+# gcc -g3 -c hello.c
+# gcc -g3 -c world.c
+# gcc -g3 -o testfilemacro hello.o world.o
+
+testfiles testfilemacro
+
+testrun_compare ${abs_top_builddir}/src/readelf --debug-dump=macro testfilemacro <<\EOF
+
+DWARF section [32] '.debug_macro' at offset 0x2480:
+
+ Offset:             0x0
+ Version:            4
+ Flag:               0x2
+ Offset length:      4
+ .debug_line offset: 0x0
+
+ #include offset 0x1a
+ start_file 0, [1] /home/mark/src/tests/hello.c
+  start_file 1, [2] /home/mark/src/tests/common.h
+   #include offset 0x582
+  end_file
+ end_file
+
+ Offset:             0x1a
+ Version:            4
+ Flag:               0x0
+ Offset length:      4
+
+ #define __STDC__ 1, line 1 (indirect)
+ #define __STDC_HOSTED__ 1, line 1 (indirect)
+ #define __GNUC__ 4, line 1 (indirect)
+ #define __GNUC_MINOR__ 7, line 1 (indirect)
+ #define __GNUC_PATCHLEVEL__ 1, line 1 (indirect)
+ #define __VERSION__ "4.7.1 20120629 (Red Hat 4.7.1-1)", line 1 (indirect)
+ #define __GNUC_RH_RELEASE__ 1, line 1 (indirect)
+ #define __ATOMIC_RELAXED 0, line 1 (indirect)
+ #define __ATOMIC_SEQ_CST 5, line 1 (indirect)
+ #define __ATOMIC_ACQUIRE 2, line 1 (indirect)
+ #define __ATOMIC_RELEASE 3, line 1 (indirect)
+ #define __ATOMIC_ACQ_REL 4, line 1 (indirect)
+ #define __ATOMIC_CONSUME 1, line 1 (indirect)
+ #define __FINITE_MATH_ONLY__ 0, line 1 (indirect)
+ #define _LP64 1, line 1 (indirect)
+ #define __LP64__ 1, line 1 (indirect)
+ #define __SIZEOF_INT__ 4, line 1 (indirect)
+ #define __SIZEOF_LONG__ 8, line 1 (indirect)
+ #define __SIZEOF_LONG_LONG__ 8, line 1 (indirect)
+ #define __SIZEOF_SHORT__ 2, line 1 (indirect)
+ #define __SIZEOF_FLOAT__ 4, line 1 (indirect)
+ #define __SIZEOF_DOUBLE__ 8, line 1 (indirect)
+ #define __SIZEOF_LONG_DOUBLE__ 16, line 1 (indirect)
+ #define __SIZEOF_SIZE_T__ 8, line 1 (indirect)
+ #define __CHAR_BIT__ 8, line 1 (indirect)
+ #define __BIGGEST_ALIGNMENT__ 16, line 1 (indirect)
+ #define __ORDER_LITTLE_ENDIAN__ 1234, line 1 (indirect)
+ #define __ORDER_BIG_ENDIAN__ 4321, line 1 (indirect)
+ #define __ORDER_PDP_ENDIAN__ 3412, line 1 (indirect)
+ #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__, line 1 (indirect)
+ #define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__, line 1 (indirect)
+ #define __SIZEOF_POINTER__ 8, line 1 (indirect)
+ #define __SIZE_TYPE__ long unsigned int, line 1 (indirect)
+ #define __PTRDIFF_TYPE__ long int, line 1 (indirect)
+ #define __WCHAR_TYPE__ int, line 1 (indirect)
+ #define __WINT_TYPE__ unsigned int, line 1 (indirect)
+ #define __INTMAX_TYPE__ long int, line 1 (indirect)
+ #define __UINTMAX_TYPE__ long unsigned int, line 1 (indirect)
+ #define __CHAR16_TYPE__ short unsigned int, line 1 (indirect)
+ #define __CHAR32_TYPE__ unsigned int, line 1 (indirect)
+ #define __SIG_ATOMIC_TYPE__ int, line 1 (indirect)
+ #define __INT8_TYPE__ signed char, line 1 (indirect)
+ #define __INT16_TYPE__ short int, line 1 (indirect)
+ #define __INT32_TYPE__ int, line 1 (indirect)
+ #define __INT64_TYPE__ long int, line 1 (indirect)
+ #define __UINT8_TYPE__ unsigned char, line 1 (indirect)
+ #define __UINT16_TYPE__ short unsigned int, line 1 (indirect)
+ #define __UINT32_TYPE__ unsigned int, line 1 (indirect)
+ #define __UINT64_TYPE__ long unsigned int, line 1 (indirect)
+ #define __INT_LEAST8_TYPE__ signed char, line 1 (indirect)
+ #define __INT_LEAST16_TYPE__ short int, line 1 (indirect)
+ #define __INT_LEAST32_TYPE__ int, line 1 (indirect)
+ #define __INT_LEAST64_TYPE__ long int, line 1 (indirect)
+ #define __UINT_LEAST8_TYPE__ unsigned char, line 1 (indirect)
+ #define __UINT_LEAST16_TYPE__ short unsigned int, line 1 (indirect)
+ #define __UINT_LEAST32_TYPE__ unsigned int, line 1 (indirect)
+ #define __UINT_LEAST64_TYPE__ long unsigned int, line 1 (indirect)
+ #define __INT_FAST8_TYPE__ signed char, line 1 (indirect)
+ #define __INT_FAST16_TYPE__ long int, line 1 (indirect)
+ #define __INT_FAST32_TYPE__ long int, line 1 (indirect)
+ #define __INT_FAST64_TYPE__ long int, line 1 (indirect)
+ #define __UINT_FAST8_TYPE__ unsigned char, line 1 (indirect)
+ #define __UINT_FAST16_TYPE__ long unsigned int, line 1 (indirect)
+ #define __UINT_FAST32_TYPE__ long unsigned int, line 1 (indirect)
+ #define __UINT_FAST64_TYPE__ long unsigned int, line 1 (indirect)
+ #define __INTPTR_TYPE__ long int, line 1 (indirect)
+ #define __UINTPTR_TYPE__ long unsigned int, line 1 (indirect)
+ #define __GXX_ABI_VERSION 1002, line 1 (indirect)
+ #define __SCHAR_MAX__ 127, line 1 (indirect)
+ #define __SHRT_MAX__ 32767, line 1 (indirect)
+ #define __INT_MAX__ 2147483647, line 1 (indirect)
+ #define __LONG_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __LONG_LONG_MAX__ 9223372036854775807LL, line 1 (indirect)
+ #define __WCHAR_MAX__ 2147483647, line 1 (indirect)
+ #define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1), line 1 (indirect)
+ #define __WINT_MAX__ 4294967295U, line 1 (indirect)
+ #define __WINT_MIN__ 0U, line 1 (indirect)
+ #define __PTRDIFF_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __SIZE_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __INTMAX_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __INTMAX_C(c) c ## L, line 1 (indirect)
+ #define __UINTMAX_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __UINTMAX_C(c) c ## UL, line 1 (indirect)
+ #define __SIG_ATOMIC_MAX__ 2147483647, line 1 (indirect)
+ #define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1), line 1 (indirect)
+ #define __INT8_MAX__ 127, line 1 (indirect)
+ #define __INT16_MAX__ 32767, line 1 (indirect)
+ #define __INT32_MAX__ 2147483647, line 1 (indirect)
+ #define __INT64_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __UINT8_MAX__ 255, line 1 (indirect)
+ #define __UINT16_MAX__ 65535, line 1 (indirect)
+ #define __UINT32_MAX__ 4294967295U, line 1 (indirect)
+ #define __UINT64_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __INT_LEAST8_MAX__ 127, line 1 (indirect)
+ #define __INT8_C(c) c, line 1 (indirect)
+ #define __INT_LEAST16_MAX__ 32767, line 1 (indirect)
+ #define __INT16_C(c) c, line 1 (indirect)
+ #define __INT_LEAST32_MAX__ 2147483647, line 1 (indirect)
+ #define __INT32_C(c) c, line 1 (indirect)
+ #define __INT_LEAST64_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __INT64_C(c) c ## L, line 1 (indirect)
+ #define __UINT_LEAST8_MAX__ 255, line 1 (indirect)
+ #define __UINT8_C(c) c, line 1 (indirect)
+ #define __UINT_LEAST16_MAX__ 65535, line 1 (indirect)
+ #define __UINT16_C(c) c, line 1 (indirect)
+ #define __UINT_LEAST32_MAX__ 4294967295U, line 1 (indirect)
+ #define __UINT32_C(c) c ## U, line 1 (indirect)
+ #define __UINT_LEAST64_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __UINT64_C(c) c ## UL, line 1 (indirect)
+ #define __INT_FAST8_MAX__ 127, line 1 (indirect)
+ #define __INT_FAST16_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __INT_FAST32_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __INT_FAST64_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __UINT_FAST8_MAX__ 255, line 1 (indirect)
+ #define __UINT_FAST16_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __UINT_FAST32_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __UINT_FAST64_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __INTPTR_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __UINTPTR_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __FLT_EVAL_METHOD__ 0, line 1 (indirect)
+ #define __DEC_EVAL_METHOD__ 2, line 1 (indirect)
+ #define __FLT_RADIX__ 2, line 1 (indirect)
+ #define __FLT_MANT_DIG__ 24, line 1 (indirect)
+ #define __FLT_DIG__ 6, line 1 (indirect)
+ #define __FLT_MIN_EXP__ (-125), line 1 (indirect)
+ #define __FLT_MIN_10_EXP__ (-37), line 1 (indirect)
+ #define __FLT_MAX_EXP__ 128, line 1 (indirect)
+ #define __FLT_MAX_10_EXP__ 38, line 1 (indirect)
+ #define __FLT_DECIMAL_DIG__ 9, line 1 (indirect)
+ #define __FLT_MAX__ 3.40282346638528859812e+38F, line 1 (indirect)
+ #define __FLT_MIN__ 1.17549435082228750797e-38F, line 1 (indirect)
+ #define __FLT_EPSILON__ 1.19209289550781250000e-7F, line 1 (indirect)
+ #define __FLT_DENORM_MIN__ 1.40129846432481707092e-45F, line 1 (indirect)
+ #define __FLT_HAS_DENORM__ 1, line 1 (indirect)
+ #define __FLT_HAS_INFINITY__ 1, line 1 (indirect)
+ #define __FLT_HAS_QUIET_NAN__ 1, line 1 (indirect)
+ #define __DBL_MANT_DIG__ 53, line 1 (indirect)
+ #define __DBL_DIG__ 15, line 1 (indirect)
+ #define __DBL_MIN_EXP__ (-1021), line 1 (indirect)
+ #define __DBL_MIN_10_EXP__ (-307), line 1 (indirect)
+ #define __DBL_MAX_EXP__ 1024, line 1 (indirect)
+ #define __DBL_MAX_10_EXP__ 308, line 1 (indirect)
+ #define __DBL_DECIMAL_DIG__ 17, line 1 (indirect)
+ #define __DBL_MAX__ ((double)1.79769313486231570815e+308L), line 1 (indirect)
+ #define __DBL_MIN__ ((double)2.22507385850720138309e-308L), line 1 (indirect)
+ #define __DBL_EPSILON__ ((double)2.22044604925031308085e-16L), line 1 (indirect)
+ #define __DBL_DENORM_MIN__ ((double)4.94065645841246544177e-324L), line 1 (indirect)
+ #define __DBL_HAS_DENORM__ 1, line 1 (indirect)
+ #define __DBL_HAS_INFINITY__ 1, line 1 (indirect)
+ #define __DBL_HAS_QUIET_NAN__ 1, line 1 (indirect)
+ #define __LDBL_MANT_DIG__ 64, line 1 (indirect)
+ #define __LDBL_DIG__ 18, line 1 (indirect)
+ #define __LDBL_MIN_EXP__ (-16381), line 1 (indirect)
+ #define __LDBL_MIN_10_EXP__ (-4931), line 1 (indirect)
+ #define __LDBL_MAX_EXP__ 16384, line 1 (indirect)
+ #define __LDBL_MAX_10_EXP__ 4932, line 1 (indirect)
+ #define __DECIMAL_DIG__ 21, line 1 (indirect)
+ #define __LDBL_MAX__ 1.18973149535723176502e+4932L, line 1 (indirect)
+ #define __LDBL_MIN__ 3.36210314311209350626e-4932L, line 1 (indirect)
+ #define __LDBL_EPSILON__ 1.08420217248550443401e-19L, line 1 (indirect)
+ #define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L, line 1 (indirect)
+ #define __LDBL_HAS_DENORM__ 1, line 1 (indirect)
+ #define __LDBL_HAS_INFINITY__ 1, line 1 (indirect)
+ #define __LDBL_HAS_QUIET_NAN__ 1, line 1 (indirect)
+ #define __DEC32_MANT_DIG__ 7, line 1 (indirect)
+ #define __DEC32_MIN_EXP__ (-94), line 1 (indirect)
+ #define __DEC32_MAX_EXP__ 97, line 1 (indirect)
+ #define __DEC32_MIN__ 1E-95DF, line 1 (indirect)
+ #define __DEC32_MAX__ 9.999999E96DF, line 1 (indirect)
+ #define __DEC32_EPSILON__ 1E-6DF, line 1 (indirect)
+ #define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF, line 1 (indirect)
+ #define __DEC64_MANT_DIG__ 16, line 1 (indirect)
+ #define __DEC64_MIN_EXP__ (-382), line 1 (indirect)
+ #define __DEC64_MAX_EXP__ 385, line 1 (indirect)
+ #define __DEC64_MIN__ 1E-383DD, line 1 (indirect)
+ #define __DEC64_MAX__ 9.999999999999999E384DD, line 1 (indirect)
+ #define __DEC64_EPSILON__ 1E-15DD, line 1 (indirect)
+ #define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD, line 1 (indirect)
+ #define __DEC128_MANT_DIG__ 34, line 1 (indirect)
+ #define __DEC128_MIN_EXP__ (-6142), line 1 (indirect)
+ #define __DEC128_MAX_EXP__ 6145, line 1 (indirect)
+ #define __DEC128_MIN__ 1E-6143DL, line 1 (indirect)
+ #define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL, line 1 (indirect)
+ #define __DEC128_EPSILON__ 1E-33DL, line 1 (indirect)
+ #define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL, line 1 (indirect)
+ #define __REGISTER_PREFIX__ , line 1 (indirect)
+ #define __USER_LABEL_PREFIX__ , line 1 (indirect)
+ #define __GNUC_GNU_INLINE__ 1, line 1 (indirect)
+ #define __NO_INLINE__ 1, line 1 (indirect)
+ #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1, line 1 (indirect)
+ #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1, line 1 (indirect)
+ #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1, line 1 (indirect)
+ #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1, line 1 (indirect)
+ #define __GCC_ATOMIC_BOOL_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_CHAR_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_SHORT_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_INT_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_LONG_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_LLONG_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1, line 1 (indirect)
+ #define __GCC_ATOMIC_POINTER_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_HAVE_DWARF2_CFI_ASM 1, line 1 (indirect)
+ #define __PRAGMA_REDEFINE_EXTNAME 1, line 1 (indirect)
+ #define __SIZEOF_INT128__ 16, line 1 (indirect)
+ #define __SIZEOF_WCHAR_T__ 4, line 1 (indirect)
+ #define __SIZEOF_WINT_T__ 4, line 1 (indirect)
+ #define __SIZEOF_PTRDIFF_T__ 8, line 1 (indirect)
+ #define __amd64 1, line 1 (indirect)
+ #define __amd64__ 1, line 1 (indirect)
+ #define __x86_64 1, line 1 (indirect)
+ #define __x86_64__ 1, line 1 (indirect)
+ #define __k8 1, line 1 (indirect)
+ #define __k8__ 1, line 1 (indirect)
+ #define __MMX__ 1, line 1 (indirect)
+ #define __SSE__ 1, line 1 (indirect)
+ #define __SSE2__ 1, line 1 (indirect)
+ #define __SSE_MATH__ 1, line 1 (indirect)
+ #define __SSE2_MATH__ 1, line 1 (indirect)
+ #define __gnu_linux__ 1, line 1 (indirect)
+ #define __linux 1, line 1 (indirect)
+ #define __linux__ 1, line 1 (indirect)
+ #define linux 1, line 1 (indirect)
+ #define __unix 1, line 1 (indirect)
+ #define __unix__ 1, line 1 (indirect)
+ #define unix 1, line 1 (indirect)
+ #define __ELF__ 1, line 1 (indirect)
+ #define __DECIMAL_BID_FORMAT__ 1, line 1 (indirect)
+
+ Offset:             0x582
+ Version:            4
+ Flag:               0x0
+ Offset length:      4
+
+ #define ONE 1, line 1 (indirect)
+ #define TWO 2, line 2 (indirect)
+ #define THREE 3, line 3 (indirect)
+ #define WORLD "World", line 5 (indirect)
+ #define A 'a', line 9 (indirect)
+ #define B b, line 10
+ #define C "C", line 11 (indirect)
+ #undef THREE, line 14 (indirect)
+ #define THREE(ARG1,ARG2,ARG3) ARG3, line 15 (indirect)
+
+ Offset:             0x5bc
+ Version:            4
+ Flag:               0x2
+ Offset length:      4
+ .debug_line offset: 0x47
+
+ #include offset 0x1a
+ start_file 0, [1] /home/mark/src/tests/world.c
+  start_file 1, [2] /home/mark/src/tests/common.h
+   #include offset 0x582
+  end_file
+ end_file
+
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-mixed-corenote.sh b/third_party/elfutils/tests/run-readelf-mixed-corenote.sh
new file mode 100755
index 0000000..86171c4
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-mixed-corenote.sh
@@ -0,0 +1,649 @@
+#! /bin/sh
+# Copyright (C) 2012, 2013, 2014 Red Hat, Inc.
+# Copyright (C) H.J. Lu <hjl.tools@gmail.com>, 2015.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile63
+
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile63 <<\EOF
+
+Note segment of 892 bytes at offset 0x274:
+  Owner          Data size  Type
+  CORE                 148  PRSTATUS
+    info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
+    sigpend: <>
+    sighold: <>
+    pid: 11087, ppid: 11063, pgrp: 11087, sid: 11063
+    utime: 0.000000, stime: 0.010000, cutime: 0.000000, cstime: 0.000000
+    orig_r0: -1, fpvalid: 1
+    r0:             1  r1:   -1091672508  r2:   -1091672500
+    r3:             0  r4:             0  r5:             0
+    r6:         33728  r7:             0  r8:             0
+    r9:             0  r10:  -1225703496  r11:  -1091672844
+    r12:            0  sp:    0xbeee64f4  lr:    0xb6dc3f48
+    pc:    0x00008500  spsr:  0x60000010
+  CORE                 124  PRPSINFO
+    state: 0, sname: R, zomb: 0, nice: 0, flag: 0x00400500
+    uid: 0, gid: 0, pid: 11087, ppid: 11063, pgrp: 11087, sid: 11063
+    fname: a.out, psargs: ./a.out 
+  CORE                 144  AUXV
+    HWCAP: 0xe8d7  <swp half thumb fast-mult vfp edsp>
+    PAGESZ: 4096
+    CLKTCK: 100
+    PHDR: 0x8034
+    PHENT: 32
+    PHNUM: 8
+    BASE: 0xb6eee000
+    FLAGS: 0
+    ENTRY: 0x83c0
+    UID: 0
+    EUID: 0
+    GID: 0
+    EGID: 0
+    SECURE: 0
+    RANDOM: 0xbeee674e
+    EXECFN: 0xbeee6ff4
+    PLATFORM: 0xbeee675e
+    NULL
+  CORE                 116  FPREGSET
+    f0: 0x000000000000000000000000  f1: 0x000000000000000000000000
+    f2: 0x000000000000000000000000  f3: 0x000000000000000000000000
+    f4: 0x000000000000000000000000  f5: 0x000000000000000000000000
+    f6: 0x000000000000000000000000  f7: 0x000000000000000000000000
+  LINUX                260  ARM_VFP
+    fpscr: 0x00000000
+    d0:  0x0000000000000000  d1:  0x0000000000000000
+    d2:  0x0000000000000000  d3:  0x0000000000000000
+    d4:  0x0000000000000000  d5:  0x0000000000000000
+    d6:  0x0000000000000000  d7:  0x0000000000000000
+    d8:  0x0000000000000000  d9:  0x0000000000000000
+    d10: 0x0000000000000000  d11: 0x0000000000000000
+    d12: 0x0000000000000000  d13: 0x0000000000000000
+    d14: 0x0000000000000000  d15: 0x0000000000000000
+    d16: 0x0000000000000000  d17: 0x0000000000000000
+    d18: 0x0000000000000000  d19: 0x0000000000000000
+    d20: 0x0000000000000000  d21: 0x0000000000000000
+    d22: 0x0000000000000000  d23: 0x0000000000000000
+    d24: 0x0000000000000000  d25: 0x0000000000000000
+    d26: 0x0000000000000000  d27: 0x0000000000000000
+    d28: 0x0000000000000000  d29: 0x0000000000000000
+    d30: 0x0000000000000000  d31: 0x0000000000000000
+EOF
+
+testfiles testfile67
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile67 <<\EOF
+
+Note segment of 1044 bytes at offset 0xe8:
+  Owner          Data size  Type
+  CORE                 336  PRSTATUS
+    info.si_signo: 4, info.si_code: 0, info.si_errno: 0, cursig: 4
+    sigpend: <>
+    sighold: <>
+    pid: 805, ppid: 804, pgrp: 804, sid: 699
+    utime: 0.000042, stime: 0.000103, cutime: 0.000000, cstime: 0.000000
+    orig_r2: 2571552016, fpvalid: 1
+    pswm:   0x0705c00180000000  pswa:   0x00000000800000d6
+    r0:         4393751543808  r1:         4398002544388
+    r2:                    11  r3:            2571578208
+    r4:            2571702016  r5:         4398003235624
+    r6:            2571580768  r7:            2571702016
+    r8:            2571578208  r9:            2571552016
+    r10:           2571552016  r11:                    0
+    r12:        4398003499008  r13:           2148274656
+    r14:                    0  r15:        4398040761216
+    a0:   0x000003ff  a1:   0xfd54a6f0  a2:   0x00000000  a3:   0x00000000
+    a4:   0x00000000  a5:   0x00000000  a6:   0x00000000  a7:   0x00000000
+    a8:   0x00000000  a9:   0x00000000  a10:  0x00000000  a11:  0x00000000
+    a12:  0x00000000  a13:  0x00000000  a14:  0x00000000  a15:  0x00000000
+  CORE                 136  PRPSINFO
+    state: 0, sname: R, zomb: 0, nice: 0, flag: 0x0000000000400400
+    uid: 0, gid: 0, pid: 805, ppid: 804, pgrp: 804, sid: 699
+    fname: 1, psargs: ./1 
+  CORE                 304  AUXV
+    SYSINFO_EHDR: 0
+    HWCAP: 0x37f
+    PAGESZ: 4096
+    CLKTCK: 100
+    PHDR: 0x80000040
+    PHENT: 56
+    PHNUM: 2
+    BASE: 0
+    FLAGS: 0
+    ENTRY: 0x800000d4
+    UID: 0
+    EUID: 0
+    GID: 0
+    EGID: 0
+    SECURE: 0
+    RANDOM: 0x3ffffa8463c
+    EXECFN: 0x3ffffa85ff4
+    PLATFORM: 0x3ffffa8464c
+    NULL
+  CORE                 136  FPREGSET
+    fpc: 0x00000000
+    f0:  0x0000000000000040  f1:  0x4b00000000000000
+    f2:  0x0000000000000041  f3:  0x3ad50b5555555600
+    f4:  0x0000000000000000  f5:  0x0000000000000000
+    f6:  0x0000000000000000  f7:  0x0000000000000000
+    f8:  0x0000000000000000  f9:  0x0000000000000000
+    f10: 0x0000000000000000  f11: 0x0000000000000000
+    f12: 0x0000000000000000  f13: 0x0000000000000000
+    f14: 0x0000000000000000  f15: 0x0000000000000000
+  LINUX                  8  S390_LAST_BREAK
+    last_break: 0x000003fffd75ccbe
+  LINUX                  4  S390_SYSTEM_CALL
+    system_call: 0
+EOF
+
+testfiles testfile68
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile68 <<\EOF
+
+Note segment of 852 bytes at offset 0x94:
+  Owner          Data size  Type
+  CORE                 224  PRSTATUS
+    info.si_signo: 4, info.si_code: 0, info.si_errno: 0, cursig: 4
+    sigpend: <>
+    sighold: <>
+    pid: 839, ppid: 838, pgrp: 838, sid: 699
+    utime: 0.000043, stime: 0.000102, cutime: 0.000000, cstime: 0.000000
+    orig_r2: -1723388288, fpvalid: 1
+    pswm:  0x070dc000  pswa:  0x8040009a
+    r0:            0  r1:    -43966716  r2:           11  r3:  -1723238816
+    r4:  -1723265280  r5:    -43275480  r6:  -1723245280  r7:  -1723265280
+    r8:  -1723238816  r9:  -1723388288  r10: -1723388288  r11:           0
+    r12:   -43012096  r13: -2146692640  r14:           0  r15:  2139883440
+    a0:   0x000003ff  a1:   0xfd54a6f0  a2:   0x00000000  a3:   0x00000000
+    a4:   0x00000000  a5:   0x00000000  a6:   0x00000000  a7:   0x00000000
+    a8:   0x00000000  a9:   0x00000000  a10:  0x00000000  a11:  0x00000000
+    a12:  0x00000000  a13:  0x00000000  a14:  0x00000000  a15:  0x00000000
+  CORE                 124  PRPSINFO
+    state: 0, sname: R, zomb: 0, nice: 0, flag: 0x00400400
+    uid: 0, gid: 0, pid: 839, ppid: 838, pgrp: 838, sid: 699
+    fname: 2, psargs: ./2 
+  CORE                 152  AUXV
+    SYSINFO_EHDR: 0
+    HWCAP: 0x37f
+    PAGESZ: 4096
+    CLKTCK: 100
+    PHDR: 0x400034
+    PHENT: 32
+    PHNUM: 2
+    BASE: 0
+    FLAGS: 0
+    ENTRY: 0x400098
+    UID: 0
+    EUID: 0
+    GID: 0
+    EGID: 0
+    SECURE: 0
+    RANDOM: 0x7f8c090c
+    EXECFN: 0x7f8c1ff4
+    PLATFORM: 0x7f8c091c
+    NULL
+  CORE                 136  FPREGSET
+    fpc: 0x00000000
+    f0:  0x0000000000000040  f1:  0x4b00000000000000
+    f2:  0x0000000000000041  f3:  0x3ad50b5555555600
+    f4:  0x0000000000000000  f5:  0x0000000000000000
+    f6:  0x0000000000000000  f7:  0x0000000000000000
+    f8:  0x0000000000000000  f9:  0x0000000000000000
+    f10: 0x0000000000000000  f11: 0x0000000000000000
+    f12: 0x0000000000000000  f13: 0x0000000000000000
+    f14: 0x0000000000000000  f15: 0x0000000000000000
+  LINUX                  8  S390_LAST_BREAK
+    last_break: 0xfd75ccbe
+  LINUX                  4  S390_SYSTEM_CALL
+    system_call: 0
+  LINUX                 64  S390_HIGH_GPRS
+    high_r0: 0x000003ff, high_r1: 0x000003ff, high_r2: 0x00000000
+    high_r3: 0x00000000, high_r4: 0x00000000, high_r5: 0x000003ff
+    high_r6: 0x00000000, high_r7: 0x00000000, high_r8: 0x00000000
+    high_r9: 0x00000000, high_r10: 0x00000000, high_r11: 0x00000000
+    high_r12: 0x000003ff, high_r13: 0x00000000, high_r14: 0x00000000
+    high_r15: 0x00000000
+EOF
+
+# To reproduce this core dump, do this on x86_64 machine with Linux
+# 3.7 or later:
+# $ gcc -x c <(echo 'int main () { return *(int *)0x12345678; }')
+# $ ./a.out
+testfiles testfile71
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile71 <<\EOF
+
+Note segment of 1476 bytes at offset 0x430:
+  Owner          Data size  Type
+  CORE                 336  PRSTATUS
+    info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
+    sigpend: <>
+    sighold: <>
+    pid: 9664, ppid: 2868, pgrp: 9664, sid: 2868
+    utime: 0.000000, stime: 0.004000, cutime: 0.000000, cstime: 0.000000
+    orig_rax: -1, fpvalid: 0
+    r15:                       0  r14:                       0
+    r13:         140734971656848  r12:                 4195328
+    rbp:      0x00007fff69fe39b0  rbx:                       0
+    r11:            266286012928  r10:         140734971656256
+    r9:                        0  r8:             266289790592
+    rax:               305419896  rcx:                 4195584
+    rdx:         140734971656872  rsi:         140734971656856
+    rdi:                       1  rip:      0x00000000004004f9
+    rflags:   0x0000000000010246  rsp:      0x00007fff69fe39b0
+    fs.base:   0x00007fa1c8933740  gs.base:   0x0000000000000000
+    cs: 0x0033  ss: 0x002b  ds: 0x0000  es: 0x0000  fs: 0x0000  gs: 0x0000
+  CORE                 136  PRPSINFO
+    state: 0, sname: R, zomb: 0, nice: 0, flag: 0x0000000000000200
+    uid: 1000, gid: 1000, pid: 9664, ppid: 2868, pgrp: 9664, sid: 2868
+    fname: a.out, psargs: ./a.out 
+  CORE                 128  SIGINFO
+    si_signo: 11, si_errno: 0, si_code: 1
+    fault address: 0x12345678
+  CORE                 304  AUXV
+    SYSINFO_EHDR: 0x7fff69ffe000
+    HWCAP: 0xafebfbff  <fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss tm pbe>
+    PAGESZ: 4096
+    CLKTCK: 100
+    PHDR: 0x400040
+    PHENT: 56
+    PHNUM: 9
+    BASE: 0
+    FLAGS: 0
+    ENTRY: 0x400400
+    UID: 1000
+    EUID: 1000
+    GID: 1000
+    EGID: 1000
+    SECURE: 0
+    RANDOM: 0x7fff69fe3d19
+    EXECFN: 0x7fff69fe4ff0
+    PLATFORM: 0x7fff69fe3d29
+    NULL
+  CORE                 469  FILE
+    10 files:
+      00400000-00401000 00000000 4096                /home/petr/a.out
+      00600000-00601000 00000000 4096                /home/petr/a.out
+      00601000-00602000 00001000 4096                /home/petr/a.out
+      3dffa00000-3dffa21000 00000000 135168          /usr/lib64/ld-2.17.so
+      3dffc20000-3dffc21000 00020000 4096            /usr/lib64/ld-2.17.so
+      3dffc21000-3dffc22000 00021000 4096            /usr/lib64/ld-2.17.so
+      3dffe00000-3dfffb6000 00000000 1794048         /usr/lib64/libc-2.17.so
+      3dfffb6000-3e001b6000 001b6000 2097152         /usr/lib64/libc-2.17.so
+      3e001b6000-3e001ba000 001b6000 16384           /usr/lib64/libc-2.17.so
+      3e001ba000-3e001bc000 001ba000 8192            /usr/lib64/libc-2.17.so
+EOF
+
+# To reproduce this core dump, do this on an aarch64 machine:
+# $ gcc -x c <(echo 'int main () { return *(int *)0x12345678; }')
+# $ ./a.out
+testfiles testfile_aarch64_core
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile_aarch64_core <<\EOF
+
+Note segment of 2512 bytes at offset 0x270:
+  Owner          Data size  Type
+  CORE                 392  PRSTATUS
+    info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
+    sigpend: <>
+    sighold: <>
+    pid: 16547, ppid: 3822, pgrp: 16547, sid: 3822
+    utime: 0.010000, stime: 0.000000, cutime: 0.000000, cstime: 0.000000
+    pc: 0x0000000000400548, pstate: 0x0000000060000000, fpvalid: 1
+    x0:             305419896  x1:          548685596648
+    x2:          548685596664  x3:               4195648
+    x4:                     0  x5:          548536191688
+    x6:                     0  x7:  -6341196323062964528
+    x8:                   135  x9:            4294967295
+    x10:              4195026  x11:               184256
+    x12:                  144  x13:                   15
+    x14:         548536635328  x15:                    0
+    x16:         548534815304  x17:              4262024
+    x18:         548685596000  x19:                    0
+    x20:                    0  x21:              4195296
+    x22:                    0  x23:                    0
+    x24:                    0  x25:                    0
+    x26:                    0  x27:                    0
+    x28:                    0  x29:         548685596320
+    x30:         548534815544  sp:    0x0000007fc035c6a0
+  CORE                 136  PRPSINFO
+    state: 0, sname: R, zomb: 0, nice: 0, flag: 0x0000000000400400
+    uid: 0, gid: 0, pid: 16547, ppid: 3822, pgrp: 16547, sid: 3822
+    fname: a.out, psargs: ./a.out 
+  CORE                 128  SIGINFO
+    si_signo: 11, si_errno: 0, si_code: 1
+    fault address: 0x12345678
+  CORE                 304  AUXV
+    SYSINFO_EHDR: 0x7fb7500000
+    HWCAP: 0x3
+    PAGESZ: 65536
+    CLKTCK: 100
+    PHDR: 0x400040
+    PHENT: 56
+    PHNUM: 7
+    BASE: 0x7fb7520000
+    FLAGS: 0
+    ENTRY: 0x4003e0
+    UID: 0
+    EUID: 0
+    GID: 0
+    EGID: 0
+    SECURE: 0
+    RANDOM: 0x7fc035c9e8
+    EXECFN: 0x7fc035fff0
+    PLATFORM: 0x7fc035c9f8
+    NULL
+  CORE                 306  FILE
+    6 files:
+      00400000-00410000 00000000 65536               /root/elfutils/build/a.out
+      00410000-00420000 00000000 65536               /root/elfutils/build/a.out
+      7fb7370000-7fb74d0000 00000000 1441792         /usr/lib64/libc-2.17.so
+      7fb74d0000-7fb74f0000 00150000 131072          /usr/lib64/libc-2.17.so
+      7fb7520000-7fb7540000 00000000 131072          /usr/lib64/ld-2.17.so
+      7fb7540000-7fb7550000 00010000 65536           /usr/lib64/ld-2.17.so
+  CORE                 528  FPREGSET
+    fpsr: 0x00000000, fpcr: 0x00000000
+    v0:  0x00000000000af54b000000000000fe02
+    v1:  0x00000000000000000000000000000000
+    v2:  0x00000000000000000000000000000000
+    v3:  0x00000000000000000000000000000000
+    v4:  0x00000000000000000000000000000000
+    v5:  0x00000000000000000000000000000000
+    v6:  0x00000000000000000000000000000000
+    v7:  0x00000000000000000000000000000000
+    v8:  0x00000000000000000000000000000000
+    v9:  0x00000000000000000000000000000000
+    v10: 0x00000000000000000000000000000000
+    v11: 0x00000000000000000000000000000000
+    v12: 0x00000000000000000000000000000000
+    v13: 0x00000000000000000000000000000000
+    v14: 0x00000000000000000000000000000000
+    v15: 0x00000000000000000000000000000000
+    v16: 0x00000000000000000000000000000000
+    v17: 0x00000000000000000000000000000000
+    v18: 0x00000000000000000000000000000000
+    v19: 0x00000000000000000000000000000000
+    v20: 0x00000000000000000000000000000000
+    v21: 0x00000000000000000000000000000000
+    v22: 0x00000000000000000000000000000000
+    v23: 0x00000000000000000000000000000000
+    v24: 0x00000000000000000000000000000000
+    v25: 0x00000000000000000000000000000000
+    v26: 0x00000000000000000000000000000000
+    v27: 0x00000000000000000000000000000000
+    v28: 0x00000000000000000000000000000000
+    v29: 0x00000000000000000000000000000000
+    v30: 0x00000000000000000000000000000000
+    v31: 0x00000000000000000000000000000000
+  LINUX                  8  ARM_TLS
+    tls: 0x0000007fb73606f0
+  LINUX                264  ARM_HW_BREAK
+    dbg_info: 0x00000610
+    DBGBVR0_EL1: 0x0000000000000000, DBGBCR0_EL1: 0x00000000
+    DBGBVR1_EL1: 0x0000000000000000, DBGBCR1_EL1: 0x00000000
+    DBGBVR2_EL1: 0x0000000000000000, DBGBCR2_EL1: 0x00000000
+    DBGBVR3_EL1: 0x0000000000000000, DBGBCR3_EL1: 0x00000000
+    DBGBVR4_EL1: 0x0000000000000000, DBGBCR4_EL1: 0x00000000
+    DBGBVR5_EL1: 0x0000000000000000, DBGBCR5_EL1: 0x00000000
+    DBGBVR6_EL1: 0x0000000000000000, DBGBCR6_EL1: 0x00000000
+    DBGBVR7_EL1: 0x0000000000000000, DBGBCR7_EL1: 0x00000000
+    DBGBVR8_EL1: 0x0000000000000000, DBGBCR8_EL1: 0x00000000
+    DBGBVR9_EL1: 0x0000000000000000, DBGBCR9_EL1: 0x00000000
+    DBGBVR10_EL1: 0x0000000000000000, DBGBCR10_EL1: 0x00000000
+    DBGBVR11_EL1: 0x0000000000000000, DBGBCR11_EL1: 0x00000000
+    DBGBVR12_EL1: 0x0000000000000000, DBGBCR12_EL1: 0x00000000
+    DBGBVR13_EL1: 0x0000000000000000, DBGBCR13_EL1: 0x00000000
+    DBGBVR14_EL1: 0x0000000000000000, DBGBCR14_EL1: 0x00000000
+    DBGBVR15_EL1: 0x0000000000000000, DBGBCR15_EL1: 0x00000000
+  LINUX                264  ARM_HW_WATCH
+    dbg_info: 0x00000610
+    DBGWVR0_EL1: 0x0000000000000000, DBGWCR0_EL1: 0x00000000
+    DBGWVR1_EL1: 0x0000000000000000, DBGWCR1_EL1: 0x00000000
+    DBGWVR2_EL1: 0x0000000000000000, DBGWCR2_EL1: 0x00000000
+    DBGWVR3_EL1: 0x0000000000000000, DBGWCR3_EL1: 0x00000000
+    DBGWVR4_EL1: 0x0000000000000000, DBGWCR4_EL1: 0x00000000
+    DBGWVR5_EL1: 0x0000000000000000, DBGWCR5_EL1: 0x00000000
+    DBGWVR6_EL1: 0x0000000000000000, DBGWCR6_EL1: 0x00000000
+    DBGWVR7_EL1: 0x0000000000000000, DBGWCR7_EL1: 0x00000000
+    DBGWVR8_EL1: 0x0000000000000000, DBGWCR8_EL1: 0x00000000
+    DBGWVR9_EL1: 0x0000000000000000, DBGWCR9_EL1: 0x00000000
+    DBGWVR10_EL1: 0x0000000000000000, DBGWCR10_EL1: 0x00000000
+    DBGWVR11_EL1: 0x0000000000000000, DBGWCR11_EL1: 0x00000000
+    DBGWVR12_EL1: 0x0000000000000000, DBGWCR12_EL1: 0x00000000
+    DBGWVR13_EL1: 0x0000000000000000, DBGWCR13_EL1: 0x00000000
+    DBGWVR14_EL1: 0x0000000000000000, DBGWCR14_EL1: 0x00000000
+    DBGWVR15_EL1: 0x0000000000000000, DBGWCR15_EL1: 0x00000000
+EOF
+
+# To reproduce this core dump, do this on an i686 machine:
+# $ gcc -x c <(echo 'int main () { return *(int *)0x12345678; }')
+# $ ./a.out
+testfiles testfile_i686_core
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile_i686_core <<\EOF
+
+Note segment of 1000 bytes at offset 0x214:
+  Owner          Data size  Type
+  CORE                 144  PRSTATUS
+    info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
+    sigpend: <>
+    sighold: <>
+    pid: 27395, ppid: 1130, pgrp: 27395, sid: 1130
+    utime: 0.000000, stime: 0.001000, cutime: 0.000000, cstime: 0.000000
+    orig_eax: -1, fpvalid: 0
+    ebx:     1334976512  ecx:    -1239415396  edx:    -1079283900
+    esi:              0  edi:              0  ebp:     0xbfab6f18
+    eax:      305419896  eip:     0x08048408  eflags:  0x00010246
+    esp:     0xbfab6f18
+    ds: 0x007b  es: 0x007b  fs: 0x0000  gs: 0x0033  cs: 0x0073  ss: 0x007b
+  CORE                 124  PRPSINFO
+    state: 0, sname: R, zomb: 0, nice: 0, flag: 0x00000200
+    uid: 1000, gid: 1000, pid: 27395, ppid: 1130, pgrp: 27395, sid: 1130
+    fname: a.out, psargs: ./a.out 
+  CORE                 128  SIGINFO
+    si_signo: 11, si_errno: 0, si_code: 1
+    fault address: 0x12345678
+  CORE                 160  AUXV
+    SYSINFO: 0xb77fc414
+    SYSINFO_EHDR: 0xb77fc000
+    HWCAP: 0x780abfd  <fpu de pse tsc msr pae mce cx8 apic sep pge cmov mmx fxsr sse sse2>
+    PAGESZ: 4096
+    CLKTCK: 100
+    PHDR: 0x8048034
+    PHENT: 32
+    PHNUM: 9
+    BASE: 0
+    FLAGS: 0
+    ENTRY: 0x80482f0
+    UID: 1000
+    EUID: 1000
+    GID: 1000
+    EGID: 1000
+    SECURE: 0
+    RANDOM: 0xbfab70eb
+    EXECFN: 0xbfab7ff4
+    PLATFORM: 0xbfab70fb
+    NULL
+  CORE                 275  FILE
+    9 files:
+      08048000-08049000 00000000 4096                /tmp/a.out
+      08049000-0804a000 00000000 4096                /tmp/a.out
+      0804a000-0804b000 00001000 4096                /tmp/a.out
+      4f744000-4f763000 00000000 126976              /usr/lib/ld-2.18.so
+      4f764000-4f765000 0001f000 4096                /usr/lib/ld-2.18.so
+      4f765000-4f766000 00020000 4096                /usr/lib/ld-2.18.so
+      4f768000-4f920000 00000000 1802240             /usr/lib/libc-2.18.so
+      4f920000-4f922000 001b8000 8192                /usr/lib/libc-2.18.so
+      4f922000-4f923000 001ba000 4096                /usr/lib/libc-2.18.so
+  LINUX                 48  386_TLS
+    index: 6, base: 0xb77da700, limit: 0x000fffff, flags: 0x00000051
+    index: 7, base: 0x00000000, limit: 0x00000000, flags: 0x00000028
+    index: 8, base: 0x00000000, limit: 0x00000000, flags: 0x00000028
+EOF
+
+# To reproduce this core dump, do this on x86_64 machine with Linux
+# 3.7 or later:
+# $ gcc -mx32 -x c <(echo 'int main () { return *(int *)0x12345678; }')
+# $ ./a.out
+testfiles testfile-x32-core
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile-x32-core <<\EOF
+
+Note segment of 2548 bytes at offset 0x234:
+  Owner          Data size  Type
+  CORE                 296  PRSTATUS
+    info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
+    sigpend: <>
+    sighold: <>
+    pid: 6885, ppid: 2792, pgrp: 6885, sid: 2792
+    utime: 0.000000, stime: 0.001000, cutime: 0.000000, cstime: 0.000000
+    orig_rax: -1, fpvalid: 1
+    r15:                       0  r14:                       0
+    r13:              4290830656  r12:                 4194960
+    rbp:      0x00000000ffc0e070  rbx:                       0
+    r11:              4145779200  r10:                       0
+    r9:               4149627024  r8:               4149551744
+    rax:               305419896  rcx:                 4195216
+    rdx:              4290830668  rsi:              4290830660
+    rdi:                       1  rip:      0x0000000000400380
+    rflags:   0x0000000000010246  rsp:      0x00000000ffc0e070
+    fs.base:   0x00000000f7754700  gs.base:   0x0000000000000000
+    cs: 0x0033  ss: 0x002b  ds: 0x002b  es: 0x002b  fs: 0x0063  gs: 0x0000
+  CORE                 124  PRPSINFO
+    state: 0, sname: R, zomb: 0, nice: 0, flag: 0x00406600
+    uid: 1000, gid: 1000, pid: 6885, ppid: 2792, pgrp: 6885, sid: 2792
+    fname: a.out, psargs: ./a.out 
+  CORE                 128  SIGINFO
+    si_signo: 11, si_errno: 0, si_code: 1
+    fault address: 0x12345678
+  CORE                 152  AUXV
+    SYSINFO_EHDR: 0xffd49000
+    HWCAP: 0xbfebfbff  <fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe>
+    PAGESZ: 4096
+    CLKTCK: 100
+    PHDR: 0x400034
+    PHENT: 32
+    PHNUM: 8
+    BASE: 0xf7555000
+    FLAGS: 0
+    ENTRY: 0x400290
+    UID: 1000
+    EUID: 1000
+    GID: 1000
+    EGID: 1000
+    SECURE: 0
+    RANDOM: 0xffc0e2cb
+    EXECFN: 0xffc0fff0
+    PLATFORM: 0xffc0e2db
+    NULL
+  CORE                 361  FILE
+    9 files:
+      00400000-00401000 00000000 4096                /export/home/hjl/bugs/gdb/x32-1/a.out
+      00600000-00601000 00000000 4096                /export/home/hjl/bugs/gdb/x32-1/a.out
+      f71a2000-f734f000 00000000 1757184             /usr/libx32/libc-2.20.so
+      f734f000-f754e000 001ad000 2093056             /usr/libx32/libc-2.20.so
+      f754e000-f7551000 001ac000 12288               /usr/libx32/libc-2.20.so
+      f7551000-f7552000 001af000 4096                /usr/libx32/libc-2.20.so
+      f7555000-f7575000 00000000 131072              /usr/libx32/ld-2.20.so
+      f7774000-f7775000 0001f000 4096                /usr/libx32/ld-2.20.so
+      f7775000-f7776000 00020000 4096                /usr/libx32/ld-2.20.so
+  CORE                 512  FPREGSET
+    xmm0:  0x0000000000000000000000000000ff00
+    xmm1:  0x2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f
+    xmm2:  0x00000000000000000000000000000000
+    xmm3:  0x0000000000000000ff00000000000000
+    xmm4:  0x000000000000000000ff000000000000
+    xmm5:  0x00000000000000000000000000000000
+    xmm6:  0x00000000000000000000000000000000
+    xmm7:  0x00000000000000000000000000000000
+    xmm8:  0x00000000000000000000000000000000
+    xmm9:  0x00000000000000000000000000000000
+    xmm10: 0x00000000000000000000000000000000
+    xmm11: 0x00000000000000000000000000000000
+    xmm12: 0x00000000000000000000000000000000
+    xmm13: 0x00000000000000000000000000000000
+    xmm14: 0x00000000000000000000000000000000
+    xmm15: 0x00000000000000000000000000000000
+    st0: 0x00000000000000000000  st1: 0x00000000000000000000
+    st2: 0x00000000000000000000  st3: 0x00000000000000000000
+    st4: 0x00000000000000000000  st5: 0x00000000000000000000
+    st6: 0x00000000000000000000  st7: 0x00000000000000000000
+    mxcsr:   0x0000ffff00001f80
+    fcw: 0x037f  fsw: 0x0000
+  LINUX                832  X86_XSTATE
+EOF
+
+# To reproduce this core dump, do this on an m68k machine:
+# $ gcc -x c <(echo 'int main () { return *(int *)0x12345678; }')
+# $ ./a.out
+testfiles testfile-m68k-core
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile-m68k-core <<\EOF
+
+Note segment of 1056 bytes at offset 0x1f4:
+  Owner          Data size  Type
+  CORE                 154  PRSTATUS
+    info.si_signo: 11, info.si_code: 0, info.si_errno: 0, cursig: 11
+    sigpend: <>
+    sighold: <>
+    pid: 1963, ppid: 1084, pgrp: 1963, sid: 1084
+    utime: 0.000000, stime: 0.010000, cutime: 0.000000, cstime: 0.000000
+    fpvalid: 1
+    d1:           1  d2:           0  d3: -2146476616  d4: -2146476616
+    d5:           0  d6: -2147393212  d7: -2144827216  a0:  0x12345678
+    a1:  0xefe71460  a2:  0x00000000  a3:  0x80288df8  a4:  0x80000340
+    a5:  0xc017a000  a6:  0xefe71434  d0: -1073595312  a7:  0xefe71434
+    pc:  0x800003fe
+  CORE                 124  PRPSINFO
+    state: 0, sname: R, zomb: 0, nice: 0, flag: 0x00400600
+    uid: 1000, gid: 501, pid: 1963, ppid: 1084, pgrp: 1963, sid: 1084
+    fname: a.out, psargs: ./a.out 
+  CORE                 128  SIGINFO
+    si_signo: 11, si_errno: 0, si_code: 1
+    fault address: 0x12345678
+  CORE                 136  AUXV
+    HWCAP: 0
+    PAGESZ: 4096
+    CLKTCK: 100
+    PHDR: 0x80000034
+    PHENT: 32
+    PHNUM: 9
+    BASE: 0xc0000000
+    FLAGS: 0
+    ENTRY: 0x80000340
+    UID: 1000
+    EUID: 1000
+    GID: 501
+    EGID: 501
+    SECURE: 0
+    RANDOM: 0xefe716d9
+    EXECFN: 0xefe71ff4
+    NULL
+  CORE                 281  FILE
+    10 files:
+      80000000-80001000 00000000 4096                /tmp/a.out
+      80003000-80004000 00001000 4096                /tmp/a.out
+      80004000-80005000 00002000 4096                /tmp/a.out
+      c0000000-c001c000 00000000 114688              /lib/ld-2.23.so
+      c001f000-c0020000 0001d000 4096                /lib/ld-2.23.so
+      c0020000-c0021000 0001e000 4096                /lib/ld-2.23.so
+      c0032000-c0177000 00000000 1331200             /lib/libc-2.23.so
+      c0177000-c0178000 00145000 4096                /lib/libc-2.23.so
+      c0178000-c017a000 00144000 8192                /lib/libc-2.23.so
+      c017a000-c017e000 00146000 16384               /lib/libc-2.23.so
+  CORE                 108  FPREGSET
+    fp0: 0x7fff0000ffffffffffffffff  fp1: 0x7fff0000ffffffffffffffff
+    fp2: 0x7fff0000ffffffffffffffff  fp3: 0x7fff0000ffffffffffffffff
+    fp4: 0x7fff0000ffffffffffffffff  fp5: 0x7fff0000ffffffffffffffff
+    fp6: 0x7fff0000ffffffffffffffff  fp7: 0x7fff0000ffffffffffffffff
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-s.sh b/third_party/elfutils/tests/run-readelf-s.sh
new file mode 100755
index 0000000..82c3417
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-s.sh
@@ -0,0 +1,389 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Tests readelf -s and readelf --elf-section -s
+# See also run-dwflsyms.sh
+#
+# - bar.c
+#
+# static int b1 = 1;
+# int b2 = 1;
+#
+# static int
+# foo (int a)
+# {
+#   return a + b2;
+# }
+#
+# int bar (int b)
+# {
+#   return b - foo (b - b1);
+# }
+#
+# - foo.c
+#
+# extern int bar (int b);
+# extern int b2;
+#
+# int
+# main (int argc, char ** argv)
+# {
+#   return bar (argc + b2);
+# }
+#
+# gcc -pie -g -c foo.c
+# gcc -pie -g -c bar.c
+# gcc -pie -g -o baz foo.o bar.o
+#
+# - testfilebaztab (dynsym + symtab)
+# cp baz testfilebaztab
+#
+# - testfilebazdbg (dynsym + .debug file)
+# eu-strip --remove-comment -f testfilebazdbg.debug baz
+# cp baz testfilebazdbg
+#
+#-  testfilebazdyn (dynsym only)
+# objcopy --remove-section=.gnu_debuglink baz testfilebazdyn
+#
+# - testfilebazmdb (dynsym + gnu_debugdata + .debug)
+#   This is how rpmbuild does it:
+# nm -D baz --format=posix --defined-only | awk '{ print $1 }' | sort > dynsyms
+# nm baz.debug --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t") print $1 }' | sort > funcsyms
+# comm -13 dynsyms funcsyms > keep_symbols
+# objcopy -S --remove-section .gdb_index --remove-section .comment --keep-symbols=keep_symbols baz.debug mini_debuginfo
+# rm -f mini_debuginfo.xz
+# xz mini_debuginfo
+# objcopy --add-section .gnu_debugdata=mini_debuginfo.xz baz
+# cp baz testfilebazmdb
+#
+# - testfilebazmin (dynsym + gnu_debugdata)
+# objcopy --remove-section=.gnu_debuglink baz testfilebazmin
+#
+#
+# Special auxiliary only, can happen with static binaries.
+# - start.c
+#
+# extern int main (int argc, char ** argv);
+# void _start (void) { for (;;) main (1, 0); }
+#
+# gcc -g -c start.c
+# gcc -static -nostdlib -o bas foo.o bar.o start.o
+#
+# eu-strip --remove-comment -f bas.debug bas
+# nm bas.debug --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t") print $1 }' | sort > funcsyms
+# objcopy -S --remove-section .gdb_index --remove-section .comment --keep-symbols=funcsyms bas.debug mini_debuginfo
+# rm -f mini_debuginfo.xz
+# xz mini_debuginfo
+# objcopy --add-section .gnu_debugdata=mini_debuginfo.xz bas
+# rm bas.debug
+# mv bas testfilebasmin
+#
+#
+# Make sure that find_aux_sym doesn't corrupt relocations, avoiding a kernel
+# heuristic that forces ET_EXEC->ET_DYN.  NB: ld.gold doesn't seem to produce
+# the mismatched load addrs between the main file and the mini_debuginfo, so
+# this is forcing ld.bfd.
+#
+# gcc -g -o bax foo.c bar.c -fuse-ld=bfd
+# eu-strip --remove-comment -f bax.debug bax
+# nm -D bax --format=posix --defined-only | awk '{ print $1 }' | sort > dynsyms
+# nm bax.debug --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t") print $1 }' | sort > funcsyms
+# comm -13 dynsyms funcsyms > keep_symbols
+# objcopy -S --remove-section .gdb_index --remove-section .comment --keep-symbols=keep_symbols bax.debug mini_debuginfo
+# rm -f mini_debuginfo.xz
+# xz mini_debuginfo
+# objcopy --add-section .gnu_debugdata=mini_debuginfo.xz bax
+# objcopy --remove-section=.gnu_debuglink bax testfilebaxmin
+
+
+testfiles testfilebaztab
+testfiles testfilebazdbg testfilebazdbg.debug
+testfiles testfilebazdyn
+testfiles testfilebazmdb
+testfiles testfilebazmin
+testfiles testfilebasmin
+testfiles testfilebaxmin
+
+tempfiles testfile.dynsym.in testfile.symtab.in testfile.minsym.in
+
+cat > testfile.dynsym.in <<\EOF
+
+Symbol table [ 5] '.dynsym' contains 14 entries:
+ 2 local symbols  String table: [ 6] '.dynstr'
+  Num:            Value   Size Type    Bind   Vis          Ndx Name
+    0: 0000000000000000      0 NOTYPE  LOCAL  DEFAULT    UNDEF 
+    1: 0000000000000238      0 SECTION LOCAL  DEFAULT        1 
+    2: 0000000000000000      0 NOTYPE  WEAK   DEFAULT    UNDEF _ITM_deregisterTMCloneTable
+    3: 0000000000000000      0 FUNC    GLOBAL DEFAULT    UNDEF __libc_start_main@GLIBC_2.2.5 (2)
+    4: 0000000000000000      0 NOTYPE  WEAK   DEFAULT    UNDEF __gmon_start__
+    5: 0000000000000000      0 NOTYPE  WEAK   DEFAULT    UNDEF _Jv_RegisterClasses
+    6: 0000000000000000      0 NOTYPE  WEAK   DEFAULT    UNDEF _ITM_registerTMCloneTable
+    7: 0000000000000000      0 FUNC    WEAK   DEFAULT    UNDEF __cxa_finalize@GLIBC_2.2.5 (2)
+    8: 000000000020103c      0 NOTYPE  GLOBAL DEFAULT       25 _edata
+    9: 0000000000201040      0 NOTYPE  GLOBAL DEFAULT       26 _end
+   10: 0000000000000860    137 FUNC    GLOBAL DEFAULT       13 __libc_csu_init
+   11: 000000000020103c      0 NOTYPE  GLOBAL DEFAULT       26 __bss_start
+   12: 00000000000007f0     35 FUNC    GLOBAL DEFAULT       13 main
+   13: 00000000000008f0      2 FUNC    GLOBAL DEFAULT       13 __libc_csu_fini
+EOF
+
+cat > testfile.symtab.in <<\EOF
+
+Symbol table [34] '.symtab' contains 76 entries:
+ 54 local symbols  String table: [35] '.strtab'
+  Num:            Value   Size Type    Bind   Vis          Ndx Name
+    0: 0000000000000000      0 NOTYPE  LOCAL  DEFAULT    UNDEF 
+    1: 0000000000000238      0 SECTION LOCAL  DEFAULT        1 
+    2: 0000000000000254      0 SECTION LOCAL  DEFAULT        2 
+    3: 0000000000000274      0 SECTION LOCAL  DEFAULT        3 
+    4: 0000000000000298      0 SECTION LOCAL  DEFAULT        4 
+    5: 00000000000002d8      0 SECTION LOCAL  DEFAULT        5 
+    6: 0000000000000428      0 SECTION LOCAL  DEFAULT        6 
+    7: 00000000000004f2      0 SECTION LOCAL  DEFAULT        7 
+    8: 0000000000000510      0 SECTION LOCAL  DEFAULT        8 
+    9: 0000000000000530      0 SECTION LOCAL  DEFAULT        9 
+   10: 0000000000000638      0 SECTION LOCAL  DEFAULT       10 
+   11: 0000000000000680      0 SECTION LOCAL  DEFAULT       11 
+   12: 00000000000006a0      0 SECTION LOCAL  DEFAULT       12 
+   13: 00000000000006e0      0 SECTION LOCAL  DEFAULT       13 
+   14: 00000000000008f4      0 SECTION LOCAL  DEFAULT       14 
+   15: 0000000000000900      0 SECTION LOCAL  DEFAULT       15 
+   16: 0000000000000904      0 SECTION LOCAL  DEFAULT       16 
+   17: 0000000000000948      0 SECTION LOCAL  DEFAULT       17 
+   18: 0000000000200dd0      0 SECTION LOCAL  DEFAULT       18 
+   19: 0000000000200dd8      0 SECTION LOCAL  DEFAULT       19 
+   20: 0000000000200de0      0 SECTION LOCAL  DEFAULT       20 
+   21: 0000000000200de8      0 SECTION LOCAL  DEFAULT       21 
+   22: 0000000000200df0      0 SECTION LOCAL  DEFAULT       22 
+   23: 0000000000200fc0      0 SECTION LOCAL  DEFAULT       23 
+   24: 0000000000201000      0 SECTION LOCAL  DEFAULT       24 
+   25: 0000000000201030      0 SECTION LOCAL  DEFAULT       25 
+   26: 000000000020103c      0 SECTION LOCAL  DEFAULT       26 
+   27: 0000000000000000      0 SECTION LOCAL  DEFAULT       27 
+   28: 0000000000000000      0 SECTION LOCAL  DEFAULT       28 
+   29: 0000000000000000      0 SECTION LOCAL  DEFAULT       29 
+   30: 0000000000000000      0 SECTION LOCAL  DEFAULT       30 
+   31: 0000000000000000      0 SECTION LOCAL  DEFAULT       31 
+   32: 0000000000000000      0 SECTION LOCAL  DEFAULT       32 
+   33: 0000000000000000      0 FILE    LOCAL  DEFAULT      ABS crtstuff.c
+   34: 0000000000200de0      0 OBJECT  LOCAL  DEFAULT       20 __JCR_LIST__
+   35: 0000000000000710      0 FUNC    LOCAL  DEFAULT       13 deregister_tm_clones
+   36: 0000000000000740      0 FUNC    LOCAL  DEFAULT       13 register_tm_clones
+   37: 0000000000000780      0 FUNC    LOCAL  DEFAULT       13 __do_global_dtors_aux
+   38: 000000000020103c      1 OBJECT  LOCAL  DEFAULT       26 completed.6137
+   39: 0000000000200dd8      0 OBJECT  LOCAL  DEFAULT       19 __do_global_dtors_aux_fini_array_entry
+   40: 00000000000007c0      0 FUNC    LOCAL  DEFAULT       13 frame_dummy
+   41: 0000000000200dd0      0 OBJECT  LOCAL  DEFAULT       18 __frame_dummy_init_array_entry
+   42: 0000000000000000      0 FILE    LOCAL  DEFAULT      ABS foo.c
+   43: 0000000000000000      0 FILE    LOCAL  DEFAULT      ABS bar.c
+   44: 0000000000201034      4 OBJECT  LOCAL  DEFAULT       25 b1
+   45: 0000000000000814     20 FUNC    LOCAL  DEFAULT       13 foo
+   46: 0000000000000000      0 FILE    LOCAL  DEFAULT      ABS crtstuff.c
+   47: 0000000000000a58      0 OBJECT  LOCAL  DEFAULT       17 __FRAME_END__
+   48: 0000000000200de0      0 OBJECT  LOCAL  DEFAULT       20 __JCR_END__
+   49: 0000000000000000      0 FILE    LOCAL  DEFAULT      ABS 
+   50: 0000000000200dd8      0 NOTYPE  LOCAL  DEFAULT       18 __init_array_end
+   51: 0000000000200df0      0 OBJECT  LOCAL  DEFAULT       22 _DYNAMIC
+   52: 0000000000200dd0      0 NOTYPE  LOCAL  DEFAULT       18 __init_array_start
+   53: 0000000000201000      0 OBJECT  LOCAL  DEFAULT       24 _GLOBAL_OFFSET_TABLE_
+   54: 00000000000008f0      2 FUNC    GLOBAL DEFAULT       13 __libc_csu_fini
+   55: 0000000000000000      0 NOTYPE  WEAK   DEFAULT    UNDEF _ITM_deregisterTMCloneTable
+   56: 0000000000201030      0 NOTYPE  WEAK   DEFAULT       25 data_start
+   57: 000000000020103c      0 NOTYPE  GLOBAL DEFAULT       25 _edata
+   58: 0000000000000828     44 FUNC    GLOBAL DEFAULT       13 bar
+   59: 00000000000008f4      0 FUNC    GLOBAL DEFAULT       14 _fini
+   60: 0000000000000000      0 FUNC    GLOBAL DEFAULT    UNDEF __libc_start_main@@GLIBC_2.2.5
+   61: 0000000000201030      0 NOTYPE  GLOBAL DEFAULT       25 __data_start
+   62: 0000000000000000      0 NOTYPE  WEAK   DEFAULT    UNDEF __gmon_start__
+   63: 0000000000200de8      0 OBJECT  GLOBAL HIDDEN        21 __dso_handle
+   64: 0000000000000900      4 OBJECT  GLOBAL DEFAULT       15 _IO_stdin_used
+   65: 0000000000201038      4 OBJECT  GLOBAL DEFAULT       25 b2
+   66: 0000000000000860    137 FUNC    GLOBAL DEFAULT       13 __libc_csu_init
+   67: 0000000000201040      0 NOTYPE  GLOBAL DEFAULT       26 _end
+   68: 00000000000006e0      0 FUNC    GLOBAL DEFAULT       13 _start
+   69: 000000000020103c      0 NOTYPE  GLOBAL DEFAULT       26 __bss_start
+   70: 00000000000007f0     35 FUNC    GLOBAL DEFAULT       13 main
+   71: 0000000000000000      0 NOTYPE  WEAK   DEFAULT    UNDEF _Jv_RegisterClasses
+   72: 0000000000201040      0 OBJECT  GLOBAL HIDDEN        25 __TMC_END__
+   73: 0000000000000000      0 NOTYPE  WEAK   DEFAULT    UNDEF _ITM_registerTMCloneTable
+   74: 0000000000000000      0 FUNC    WEAK   DEFAULT    UNDEF __cxa_finalize@@GLIBC_2.2.5
+   75: 0000000000000680      0 FUNC    GLOBAL DEFAULT       11 _init
+EOF
+
+cat > testfile.minsym.in <<\EOF
+
+Symbol table [28] '.symtab' contains 40 entries:
+ 36 local symbols  String table: [29] '.strtab'
+  Num:            Value   Size Type    Bind   Vis          Ndx Name
+    0: 0000000000000000      0 NOTYPE  LOCAL  DEFAULT    UNDEF 
+    1: 0000000000000710      0 FUNC    LOCAL  DEFAULT       13 deregister_tm_clones
+    2: 0000000000000740      0 FUNC    LOCAL  DEFAULT       13 register_tm_clones
+    3: 0000000000000780      0 FUNC    LOCAL  DEFAULT       13 __do_global_dtors_aux
+    4: 0000000000200dd8      0 OBJECT  LOCAL  DEFAULT       19 __do_global_dtors_aux_fini_array_entry
+    5: 00000000000007c0      0 FUNC    LOCAL  DEFAULT       13 frame_dummy
+    6: 0000000000200dd0      0 OBJECT  LOCAL  DEFAULT       18 __frame_dummy_init_array_entry
+    7: 0000000000000814     20 FUNC    LOCAL  DEFAULT       13 foo
+    8: 0000000000200dd8      0 NOTYPE  LOCAL  DEFAULT       18 __init_array_end
+    9: 0000000000200dd0      0 NOTYPE  LOCAL  DEFAULT       18 __init_array_start
+   10: 0000000000000238      0 SECTION LOCAL  DEFAULT        1 
+   11: 0000000000000254      0 SECTION LOCAL  DEFAULT        2 
+   12: 0000000000000274      0 SECTION LOCAL  DEFAULT        3 
+   13: 0000000000000298      0 SECTION LOCAL  DEFAULT        4 
+   14: 00000000000002d8      0 SECTION LOCAL  DEFAULT        5 
+   15: 0000000000000428      0 SECTION LOCAL  DEFAULT        6 
+   16: 00000000000004f2      0 SECTION LOCAL  DEFAULT        7 
+   17: 0000000000000510      0 SECTION LOCAL  DEFAULT        8 
+   18: 0000000000000530      0 SECTION LOCAL  DEFAULT        9 
+   19: 0000000000000638      0 SECTION LOCAL  DEFAULT       10 
+   20: 0000000000000680      0 SECTION LOCAL  DEFAULT       11 
+   21: 00000000000006a0      0 SECTION LOCAL  DEFAULT       12 
+   22: 00000000000006e0      0 SECTION LOCAL  DEFAULT       13 
+   23: 00000000000008f4      0 SECTION LOCAL  DEFAULT       14 
+   24: 0000000000000900      0 SECTION LOCAL  DEFAULT       15 
+   25: 0000000000000904      0 SECTION LOCAL  DEFAULT       16 
+   26: 0000000000000948      0 SECTION LOCAL  DEFAULT       17 
+   27: 0000000000200dd0      0 SECTION LOCAL  DEFAULT       18 
+   28: 0000000000200dd8      0 SECTION LOCAL  DEFAULT       19 
+   29: 0000000000200de0      0 SECTION LOCAL  DEFAULT       20 
+   30: 0000000000200de8      0 SECTION LOCAL  DEFAULT       21 
+   31: 0000000000200df0      0 SECTION LOCAL  DEFAULT       22 
+   32: 0000000000200fc0      0 SECTION LOCAL  DEFAULT       23 
+   33: 0000000000201000      0 SECTION LOCAL  DEFAULT       24 
+   34: 0000000000201030      0 SECTION LOCAL  DEFAULT       25 
+   35: 000000000020103c      0 SECTION LOCAL  DEFAULT       26 
+   36: 0000000000000828     44 FUNC    GLOBAL DEFAULT       13 bar
+   37: 00000000000008f4      0 FUNC    GLOBAL DEFAULT       14 _fini
+   38: 00000000000006e0      0 FUNC    GLOBAL DEFAULT       13 _start
+   39: 0000000000000680      0 FUNC    GLOBAL DEFAULT       11 _init
+EOF
+
+# Display all symbol tables.
+cat testfile.dynsym.in testfile.symtab.in \
+  | testrun_compare ${abs_top_builddir}/src/readelf -s testfilebaztab
+
+# Display just .dynsym
+cat testfile.dynsym.in \
+  | testrun_compare ${abs_top_builddir}/src/readelf \
+    --symbols=.dynsym testfilebaztab
+
+# Display just .symtab
+cat testfile.symtab.in \
+  | testrun_compare ${abs_top_builddir}/src/readelf \
+    --symbols=.symtab testfilebaztab
+
+cat testfile.dynsym.in \
+  | testrun_compare ${abs_top_builddir}/src/readelf -s testfilebazdbg
+
+cat testfile.symtab.in \
+  | testrun_compare ${abs_top_builddir}/src/readelf -s testfilebazdbg.debug
+
+cat testfile.dynsym.in \
+  | testrun_compare ${abs_top_builddir}/src/readelf -s testfilebazdyn
+
+cat testfile.dynsym.in \
+  | testrun_compare ${abs_top_builddir}/src/readelf -s testfilebazmdb
+
+cat testfile.minsym.in \
+  | testrun_compare ${abs_top_builddir}/src/readelf --elf-section -s testfilebazmdb
+
+cat testfile.dynsym.in \
+  | testrun_compare ${abs_top_builddir}/src/readelf -s testfilebazmin
+
+cat testfile.minsym.in \
+  | testrun_compare ${abs_top_builddir}/src/readelf --elf-section -s testfilebazmin
+
+testrun_compare ${abs_top_builddir}/src/readelf -s testfilebasmin <<EOF
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf --elf-section -s testfilebasmin <<\EOF
+
+Symbol table [ 6] '.symtab' contains 9 entries:
+ 6 local symbols  String table: [ 7] '.strtab'
+  Num:            Value   Size Type    Bind   Vis          Ndx Name
+    0: 0000000000000000      0 NOTYPE  LOCAL  DEFAULT    UNDEF 
+    1: 0000000000400168     18 FUNC    LOCAL  DEFAULT        2 foo
+    2: 0000000000400120      0 SECTION LOCAL  DEFAULT        1 
+    3: 0000000000400144      0 SECTION LOCAL  DEFAULT        2 
+    4: 00000000004001c0      0 SECTION LOCAL  DEFAULT        3 
+    5: 0000000000600258      0 SECTION LOCAL  DEFAULT        4 
+    6: 00000000004001a8     21 FUNC    GLOBAL DEFAULT        2 _start
+    7: 0000000000400144     33 FUNC    GLOBAL DEFAULT        2 main
+    8: 000000000040017a     44 FUNC    GLOBAL DEFAULT        2 bar
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf -s testfilebaxmin <<EOF
+
+Symbol table [ 5] '.dynsym' contains 3 entries:
+ 1 local symbol  String table: [ 6] '.dynstr'
+  Num:            Value   Size Type    Bind   Vis          Ndx Name
+    0: 0000000000000000      0 NOTYPE  LOCAL  DEFAULT    UNDEF 
+    1: 0000000000000000      0 FUNC    GLOBAL DEFAULT    UNDEF __libc_start_main@GLIBC_2.2.5 (2)
+    2: 0000000000000000      0 NOTYPE  WEAK   DEFAULT    UNDEF __gmon_start__
+EOF
+
+testrun_compare ${abs_top_builddir}/src/readelf --elf-section -s testfilebaxmin <<\EOF
+
+Symbol table [27] '.symtab' contains 42 entries:
+ 35 local symbols  String table: [28] '.strtab'
+  Num:            Value   Size Type    Bind   Vis          Ndx Name
+    0: 0000000000000000      0 NOTYPE  LOCAL  DEFAULT    UNDEF 
+    1: 0000000000400430      0 FUNC    LOCAL  DEFAULT       13 deregister_tm_clones
+    2: 0000000000400460      0 FUNC    LOCAL  DEFAULT       13 register_tm_clones
+    3: 00000000004004a0      0 FUNC    LOCAL  DEFAULT       13 __do_global_dtors_aux
+    4: 0000000000600e18      0 OBJECT  LOCAL  DEFAULT       19 __do_global_dtors_aux_fini_array_entry
+    5: 00000000004004c0      0 FUNC    LOCAL  DEFAULT       13 frame_dummy
+    6: 0000000000600e10      0 OBJECT  LOCAL  DEFAULT       18 __frame_dummy_init_array_entry
+    7: 00000000004004f0     20 FUNC    LOCAL  DEFAULT       13 foo
+    8: 0000000000600e18      0 NOTYPE  LOCAL  DEFAULT       18 __init_array_end
+    9: 0000000000600e10      0 NOTYPE  LOCAL  DEFAULT       18 __init_array_start
+   10: 0000000000400238      0 SECTION LOCAL  DEFAULT        1 
+   11: 0000000000400254      0 SECTION LOCAL  DEFAULT        2 
+   12: 0000000000400274      0 SECTION LOCAL  DEFAULT        3 
+   13: 0000000000400298      0 SECTION LOCAL  DEFAULT        4 
+   14: 00000000004002b8      0 SECTION LOCAL  DEFAULT        5 
+   15: 0000000000400300      0 SECTION LOCAL  DEFAULT        6 
+   16: 0000000000400338      0 SECTION LOCAL  DEFAULT        7 
+   17: 0000000000400340      0 SECTION LOCAL  DEFAULT        8 
+   18: 0000000000400360      0 SECTION LOCAL  DEFAULT        9 
+   19: 0000000000400378      0 SECTION LOCAL  DEFAULT       10 
+   20: 00000000004003a8      0 SECTION LOCAL  DEFAULT       11 
+   21: 00000000004003d0      0 SECTION LOCAL  DEFAULT       12 
+   22: 0000000000400400      0 SECTION LOCAL  DEFAULT       13 
+   23: 00000000004005c4      0 SECTION LOCAL  DEFAULT       14 
+   24: 00000000004005d0      0 SECTION LOCAL  DEFAULT       15 
+   25: 00000000004005e0      0 SECTION LOCAL  DEFAULT       16 
+   26: 0000000000400628      0 SECTION LOCAL  DEFAULT       17 
+   27: 0000000000600e10      0 SECTION LOCAL  DEFAULT       18 
+   28: 0000000000600e18      0 SECTION LOCAL  DEFAULT       19 
+   29: 0000000000600e20      0 SECTION LOCAL  DEFAULT       20 
+   30: 0000000000600e28      0 SECTION LOCAL  DEFAULT       21 
+   31: 0000000000600ff8      0 SECTION LOCAL  DEFAULT       22 
+   32: 0000000000601000      0 SECTION LOCAL  DEFAULT       23 
+   33: 0000000000601028      0 SECTION LOCAL  DEFAULT       24 
+   34: 0000000000601034      0 SECTION LOCAL  DEFAULT       25 
+   35: 00000000004005c0      2 FUNC    GLOBAL DEFAULT       13 __libc_csu_fini
+   36: 0000000000400504     40 FUNC    GLOBAL DEFAULT       13 bar
+   37: 00000000004005c4      0 FUNC    GLOBAL DEFAULT       14 _fini
+   38: 0000000000400550    101 FUNC    GLOBAL DEFAULT       13 __libc_csu_init
+   39: 0000000000400400      0 FUNC    GLOBAL DEFAULT       13 _start
+   40: 000000000040052c     35 FUNC    GLOBAL DEFAULT       13 main
+   41: 00000000004003a8      0 FUNC    GLOBAL DEFAULT       11 _init
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-self.sh b/third_party/elfutils/tests/run-readelf-self.sh
new file mode 100755
index 0000000..7ffb357
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-self.sh
@@ -0,0 +1,21 @@
+#! /bin/sh
+# Copyright (C) 2012 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Just makes sure readelf doesn't crash
+testrun_on_self_quiet ${abs_top_builddir}/src/readelf -a -w
diff --git a/third_party/elfutils/tests/run-readelf-test1.sh b/third_party/elfutils/tests/run-readelf-test1.sh
new file mode 100755
index 0000000..4725049
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-test1.sh
@@ -0,0 +1,45 @@
+#! /bin/sh
+# Copyright (C) 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+original=${original:-testfile11}
+stripped=${stripped:-testfile7}
+debugout=${debugfile:+-f testfile.debug.temp -F $debugfile}
+
+testfiles testfile3
+
+tempfiles testfile.temp
+
+testrun ${abs_top_builddir}/src/readelf -r testfile3 > testfile.temp
+
+diff -u - testfile.temp <<EOF
+
+Relocation section [ 8] '.rel.got' for section [19] '.got' at offset 0x294 contains 1 entry:
+  Offset      Type                 Value       Name
+  0x08049544  386_GLOB_DAT         0000000000  __gmon_start__
+
+Relocation section [ 9] '.rel.plt' for section [11] '.plt' at offset 0x29c contains 4 entries:
+  Offset      Type                 Value       Name
+  0x08049534  386_JMP_SLOT         0x080482e4  __register_frame_info
+  0x08049538  386_JMP_SLOT         0x080482f4  __deregister_frame_info
+  0x0804953c  386_JMP_SLOT         0x08048304  __libc_start_main
+  0x08049540  386_JMP_SLOT         0x08048314  __cxa_finalize
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-test2.sh b/third_party/elfutils/tests/run-readelf-test2.sh
new file mode 100755
index 0000000..9030624
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-test2.sh
@@ -0,0 +1,28 @@
+#! /bin/sh
+# Copyright (C) 2007 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile28
+
+testrun_compare ${abs_top_builddir}/src/readelf -x .strtab testfile28 <<\EOF
+
+Hex dump of section [6] '.strtab', 1 bytes at offset 0x290:
+  0x00000000 00                                  .
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-test3.sh b/third_party/elfutils/tests/run-readelf-test3.sh
new file mode 100755
index 0000000..cc0a191
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-test3.sh
@@ -0,0 +1,31 @@
+#! /bin/sh
+# Copyright (C) 2007 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile40.debug
+
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile40.debug <<\EOF
+
+Note section [ 6] '.note' of 60 bytes at offset 0x120:
+  Owner          Data size  Type
+  GNU                   20  GNU_BUILD_ID
+    Build ID: 34072edcd87ef6728f4b4a7956167b2fcfc3f1d3
+  Linux                  4  <unknown>: 0
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-test4.sh b/third_party/elfutils/tests/run-readelf-test4.sh
new file mode 100755
index 0000000..ca0526a
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-test4.sh
@@ -0,0 +1,33 @@
+#! /bin/sh
+# Copyright (C) 2007 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile19.index
+
+testrun_compare ${abs_top_builddir}/src/readelf -c testfile19.index <<\EOF
+
+Index of archive 'testfile19.index' has 4 entries:
+Archive member 'u1.o' contains:
+	a
+Archive member 'u2.o' contains:
+	aa
+Archive member 'u3.o' contains:
+	a
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-twofiles.sh b/third_party/elfutils/tests/run-readelf-twofiles.sh
new file mode 100755
index 0000000..46eec7b
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-twofiles.sh
@@ -0,0 +1,24 @@
+#! /bin/sh
+# Copyright (C) 2011 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile14
+
+testrun >/dev/null ${abs_top_builddir}/src/readelf -w testfile14 testfile14
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-variant.sh b/third_party/elfutils/tests/run-readelf-variant.sh
new file mode 100755
index 0000000..dcc0d5e
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-variant.sh
@@ -0,0 +1,89 @@
+#! /bin/sh
+# Copyright (C) 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Tests exprloc for an Ada record variants byte_size.
+
+# = pck.ads
+#
+# with System;
+#
+# package Pck is
+#
+#    type One_To_Five is range 1 .. 5;
+#
+#    type Rec (Discr : One_To_Five) is
+#    record
+#       case Discr is
+#          when 1 => Field1 : Integer;
+#          when 4 => null;
+#          when 3 => Field3 : Boolean;
+#          when 5 => null;
+#          when others => null;
+#       end case;
+#    end record;
+#
+#    procedure Do_Nothing (A : System.Address);
+#
+# end Pck;
+
+# = pck.adb
+#
+# package body Pck is
+#
+#    procedure Do_Nothing (A : System.Address) is
+#    begin
+#       null;
+#    end Do_Nothing;
+#
+# end Pck;
+
+# = foo.adb
+#
+# with Pck; use Pck;
+#
+# procedure Foo is
+#
+#    R : Rec (1);
+#
+# begin
+#    Do_Nothing (R'Address);
+# end Foo;
+
+# gnatmake -g -fgnat-encodings=minimal foo.adb -cargs
+
+testfiles testfile-ada-variant
+
+tempfiles testfile.temp testfile2.temp
+
+testrun ${abs_top_builddir}/src/readelf --debug-dump=info \
+        testfile-ada-variant > testfile.temp
+
+grep -A6 byte_size testfile.temp | grep -A6 exprloc > testfile2.temp
+
+diff -u testfile2.temp - <<EOF
+             byte_size            (exprloc) 
+              [ 0] push_object_address
+              [ 1] deref_size 1
+              [ 3] call4 [    95]
+              [ 8] plus_uconst 7
+              [10] const1s -4
+              [12] and
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-vmcoreinfo.sh b/third_party/elfutils/tests/run-readelf-vmcoreinfo.sh
new file mode 100755
index 0000000..b1732fc
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-vmcoreinfo.sh
@@ -0,0 +1,114 @@
+#! /bin/sh
+# Copyright (C) 2012 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile62
+
+testrun_compare ${abs_top_builddir}/src/readelf -n testfile62 <<\EOF
+
+Note segment of 2104 bytes at offset 0x158:
+  Owner          Data size  Type
+  CORE                 336  PRSTATUS
+    info.si_signo: 0, info.si_code: 0, info.si_errno: 0, cursig: 0
+    sigpend: <>
+    sighold: <>
+    pid: 3519, ppid: 0, pgrp: 0, sid: 0
+    utime: 0.000000, stime: 0.000000, cutime: 0.000000, cstime: 0.000000
+    orig_rax: -1, fpvalid: 0
+    r15:                     662  r14:                       4
+    r13:             -2119649152  r12:                       0
+    rbp:      0xffff880067e39e48  rbx:                      99
+    r11:        -131940469531936  r10:             -2124150080
+    r9:         -131940469531936  r8:                        0
+    rax:                      16  rcx:                    7813
+    rdx:                       0  rsi:                       0
+    rdi:                      99  rip:      0xffffffff812ba86f
+    rflags:   0x0000000000010096  rsp:      0xffff880067e39e48
+    fs.base:   0x00007f95a7b09720  gs.base:   0x0000000000000000
+    cs: 0x0010  ss: 0x0018  ds: 0x0000  es: 0x0000  fs: 0x0000  gs: 0x0000
+  CORE                 336  PRSTATUS
+    info.si_signo: 0, info.si_code: 0, info.si_errno: 0, cursig: 0
+    sigpend: <>
+    sighold: <>
+    pid: 0, ppid: 0, pgrp: 0, sid: 0
+    utime: 0.000000, stime: 0.000000, cutime: 0.000000, cstime: 0.000000
+    orig_rax: -1, fpvalid: 0
+    r15:                       0  r14:                       0
+    r13:     1348173392195389970  r12:                       1
+    rbp:      0xffff88007a829e48  rbx:                      16
+    r11:        -131940468065880  r10:            435505529489
+    r9:                   158960  r8:                        0
+    rax:                      16  rcx:                       1
+    rdx:                       0  rsi:                       3
+    rdi:        -131939339960320  rip:      0xffffffff810118bb
+    rflags:   0x0000000000000046  rsp:      0xffff88007a829e38
+    fs.base:   0x0000000000000000  gs.base:   0x0000000000000000
+    cs: 0x0010  ss: 0x0018  ds: 0x0000  es: 0x0000  fs: 0x0000  gs: 0x0000
+  VMCOREINFO          1366  <unknown>: 0
+    OSRELEASE=2.6.35.11-83.fc14.x86_64
+    PAGESIZE=4096
+    SYMBOL(init_uts_ns)=ffffffff81a4c5b0
+    SYMBOL(node_online_map)=ffffffff81b840b0
+    SYMBOL(swapper_pg_dir)=ffffffff81a42000
+    SYMBOL(_stext)=ffffffff81000190
+    SYMBOL(vmlist)=ffffffff81db07e8
+    SYMBOL(mem_section)=ffffffff81dbab00
+    LENGTH(mem_section)=4096
+    SIZE(mem_section)=32
+    OFFSET(mem_section.section_mem_map)=0
+    SIZE(page)=56
+    SIZE(pglist_data)=81664
+    SIZE(zone)=1792
+    SIZE(free_area)=88
+    SIZE(list_head)=16
+    SIZE(nodemask_t)=64
+    OFFSET(page.flags)=0
+    OFFSET(page._count)=8
+    OFFSET(page.mapping)=24
+    OFFSET(page.lru)=40
+    OFFSET(pglist_data.node_zones)=0
+    OFFSET(pglist_data.nr_zones)=81472
+    OFFSET(pglist_data.node_start_pfn)=81496
+    OFFSET(pglist_data.node_spanned_pages)=81512
+    OFFSET(pglist_data.node_id)=81520
+    OFFSET(zone.free_area)=112
+    OFFSET(zone.vm_stat)=1328
+    OFFSET(zone.spanned_pages)=1704
+    OFFSET(free_area.free_list)=0
+    OFFSET(list_head.next)=0
+    OFFSET(list_head.prev)=8
+    OFFSET(vm_struct.addr)=8
+    LENGTH(zone.free_area)=11
+    SYMBOL(log_buf)=ffffffff81a532a8
+    SYMBOL(log_end)=ffffffff81d0bc50
+    SYMBOL(log_buf_len)=ffffffff81a532a4
+    SYMBOL(logged_chars)=ffffffff81d0bd70
+    LENGTH(free_area.free_list)=5
+    NUMBER(NR_FREE_PAGES)=0
+    NUMBER(PG_lru)=5
+    NUMBER(PG_private)=11
+    NUMBER(PG_swapcache)=16
+    SYMBOL(phys_base)=ffffffff81a4a010
+    SYMBOL(init_level4_pgt)=ffffffff81a42000
+    SYMBOL(node_data)=ffffffff81b80df0
+    LENGTH(node_data)=512
+    CRASHTIME=1348173392
+
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-z.sh b/third_party/elfutils/tests/run-readelf-z.sh
new file mode 100755
index 0000000..6dbd2f1
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-z.sh
@@ -0,0 +1,202 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# See run-elfgetchdr.sh for testfiles.
+
+testfiles testfile-zgnu64
+testrun_compare ${abs_top_builddir}/src/readelf -z -S testfile-zgnu64 <<\EOF
+There are 9 section headers, starting at offset 0x3e0:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+     [Compression  Size     Al]
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .text                PROGBITS     0000000000400078 00000078 0000002a  0 AX     0   0  1
+[ 2] .zdebug_aranges      PROGBITS     0000000000000000 00000260 00000032  0        0   0 16
+     [GNU ZLIB     00000060   ]
+[ 3] .zdebug_info         PROGBITS     0000000000000000 00000292 0000006f  0        0   0  1
+     [GNU ZLIB     000000aa   ]
+[ 4] .debug_abbrev        PROGBITS     0000000000000000 00000301 00000028  0        0   0  1
+[ 5] .zdebug_line         PROGBITS     0000000000000000 00000329 0000005b  0        0   0  1
+     [GNU ZLIB     0000008d   ]
+[ 6] .shstrtab            STRTAB       0000000000000000 00000384 00000059  0        0   0  1
+[ 7] .symtab              SYMTAB       0000000000000000 000000a8 00000168 24        8   8  8
+[ 8] .strtab              STRTAB       0000000000000000 00000210 0000004b  0        0   0  1
+
+EOF
+
+testfiles testfile-zgnu64be
+testrun_compare ${abs_top_builddir}/src/readelf -z -S testfile-zgnu64be <<\EOF
+There are 10 section headers, starting at offset 0x438:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+     [Compression  Size     Al]
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .text                PROGBITS     0000000010000078 00000078 00000074  0 AX     0   0  8
+[ 2] .eh_frame            PROGBITS     00000000100000ec 000000ec 00000000  0 A      0   0  4
+[ 3] .zdebug_aranges      PROGBITS     0000000000000000 000002c0 00000034  0        0   0 16
+     [GNU ZLIB     00000060   ]
+[ 4] .zdebug_info         PROGBITS     0000000000000000 000002f4 00000059  0        0   0  1
+     [GNU ZLIB     0000007e   ]
+[ 5] .debug_abbrev        PROGBITS     0000000000000000 0000034d 00000028  0        0   0  1
+[ 6] .zdebug_line         PROGBITS     0000000000000000 00000375 0000005b  0        0   0  1
+     [GNU ZLIB     0000008d   ]
+[ 7] .shstrtab            STRTAB       0000000000000000 000003d0 00000063  0        0   0  1
+[ 8] .symtab              SYMTAB       0000000000000000 000000f0 00000180 24        9   9  8
+[ 9] .strtab              STRTAB       0000000000000000 00000270 00000044  0        0   0  1
+
+EOF
+
+testfiles testfile-zgabi64
+testrun_compare ${abs_top_builddir}/src/readelf -z -S testfile-zgabi64 <<\EOF
+There are 9 section headers, starting at offset 0x400:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+     [Compression  Size     Al]
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .text                PROGBITS     0000000000400078 00000078 0000002a  0 AX     0   0  1
+[ 2] .debug_aranges       PROGBITS     0000000000000000 00000260 0000003e  0 C      0   0 16
+     [ELF ZLIB (1) 00000060 16]
+[ 3] .debug_info          PROGBITS     0000000000000000 0000029e 0000007b  0 C      0   0  1
+     [ELF ZLIB (1) 000000aa  1]
+[ 4] .debug_abbrev        PROGBITS     0000000000000000 00000319 00000028  0        0   0  1
+[ 5] .debug_line          PROGBITS     0000000000000000 00000341 00000067  0 C      0   0  1
+     [ELF ZLIB (1) 0000008d  1]
+[ 6] .shstrtab            STRTAB       0000000000000000 000003a8 00000056  0        0   0  1
+[ 7] .symtab              SYMTAB       0000000000000000 000000a8 00000168 24        8   8  8
+[ 8] .strtab              STRTAB       0000000000000000 00000210 0000004b  0        0   0  1
+
+EOF
+
+testfiles testfile-zgabi64be
+testrun_compare ${abs_top_builddir}/src/readelf -z -S testfile-zgabi64be <<\EOF
+There are 10 section headers, starting at offset 0x458:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+     [Compression  Size     Al]
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .text                PROGBITS     0000000010000078 00000078 00000074  0 AX     0   0  8
+[ 2] .eh_frame            PROGBITS     00000000100000ec 000000ec 00000000  0 A      0   0  4
+[ 3] .debug_aranges       PROGBITS     0000000000000000 000002c0 00000040  0 C      0   0 16
+     [ELF ZLIB (1) 00000060 16]
+[ 4] .debug_info          PROGBITS     0000000000000000 00000300 00000065  0 C      0   0  1
+     [ELF ZLIB (1) 0000007e  1]
+[ 5] .debug_abbrev        PROGBITS     0000000000000000 00000365 00000028  0        0   0  1
+[ 6] .debug_line          PROGBITS     0000000000000000 0000038d 00000067  0 C      0   0  1
+     [ELF ZLIB (1) 0000008d  1]
+[ 7] .shstrtab            STRTAB       0000000000000000 000003f4 00000060  0        0   0  1
+[ 8] .symtab              SYMTAB       0000000000000000 000000f0 00000180 24        9   9  8
+[ 9] .strtab              STRTAB       0000000000000000 00000270 00000044  0        0   0  1
+
+EOF
+
+testfiles testfile-zgnu32
+testrun_compare ${abs_top_builddir}/src/readelf -z -S testfile-zgnu32 <<\EOF
+There are 9 section headers, starting at offset 0x33c:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+     [Compression  Size   Al]
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .text                PROGBITS     08048054 000054 00002a  0 AX     0   0  1
+[ 2] .zdebug_aranges      PROGBITS     00000000 0001c0 000031  0        0   0  8
+     [GNU ZLIB     000040   ]
+[ 3] .zdebug_info         PROGBITS     00000000 0001f1 00006f  0        0   0  1
+     [GNU ZLIB     00009a   ]
+[ 4] .debug_abbrev        PROGBITS     00000000 000260 000028  0        0   0  1
+[ 5] .zdebug_line         PROGBITS     00000000 000288 00005a  0        0   0  1
+     [GNU ZLIB     000085   ]
+[ 6] .shstrtab            STRTAB       00000000 0002e2 000059  0        0   0  1
+[ 7] .symtab              SYMTAB       00000000 000080 0000f0 16        8   8  4
+[ 8] .strtab              STRTAB       00000000 000170 00004b  0        0   0  1
+
+EOF
+
+testfiles testfile-zgnu32be
+testrun_compare ${abs_top_builddir}/src/readelf -z -S testfile-zgnu32be <<\EOF
+There are 10 section headers, starting at offset 0x390:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+     [Compression  Size   Al]
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .text                PROGBITS     01800054 000054 000074  0 AX     0   0  1
+[ 2] .eh_frame            PROGBITS     018000c8 0000c8 000000  0 A      0   0  4
+[ 3] .zdebug_aranges      PROGBITS     00000000 000220 000033  0        0   0  8
+     [GNU ZLIB     000040   ]
+[ 4] .zdebug_info         PROGBITS     00000000 000253 000058  0        0   0  1
+     [GNU ZLIB     00006e   ]
+[ 5] .debug_abbrev        PROGBITS     00000000 0002ab 000028  0        0   0  1
+[ 6] .zdebug_line         PROGBITS     00000000 0002d3 000059  0        0   0  1
+     [GNU ZLIB     000085   ]
+[ 7] .shstrtab            STRTAB       00000000 00032c 000063  0        0   0  1
+[ 8] .symtab              SYMTAB       00000000 0000c8 000110 16        9   9  4
+[ 9] .strtab              STRTAB       00000000 0001d8 000045  0        0   0  1
+
+EOF
+
+testfiles testfile-zgabi32
+testrun_compare ${abs_top_builddir}/src/readelf -z -S testfile-zgabi32 <<\EOF
+There are 9 section headers, starting at offset 0x338:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+     [Compression  Size   Al]
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .text                PROGBITS     08048054 000054 00002a  0 AX     0   0  1
+[ 2] .debug_aranges       PROGBITS     00000000 0001c0 000031  0 C      0   0  8
+     [ELF ZLIB (1) 000040  8]
+[ 3] .debug_info          PROGBITS     00000000 0001f1 00006f  0 C      0   0  1
+     [ELF ZLIB (1) 00009a  1]
+[ 4] .debug_abbrev        PROGBITS     00000000 000260 000028  0        0   0  1
+[ 5] .debug_line          PROGBITS     00000000 000288 00005a  0 C      0   0  1
+     [ELF ZLIB (1) 000085  1]
+[ 6] .shstrtab            STRTAB       00000000 0002e2 000056  0        0   0  1
+[ 7] .symtab              SYMTAB       00000000 000080 0000f0 16        8   8  4
+[ 8] .strtab              STRTAB       00000000 000170 00004b  0        0   0  1
+
+EOF
+
+testfiles testfile-zgabi32be
+testrun_compare ${abs_top_builddir}/src/readelf -z -S testfile-zgabi32be <<\EOF
+There are 10 section headers, starting at offset 0x38c:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+     [Compression  Size   Al]
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .text                PROGBITS     01800054 000054 000074  0 AX     0   0  1
+[ 2] .eh_frame            PROGBITS     018000c8 0000c8 000000  0 A      0   0  4
+[ 3] .debug_aranges       PROGBITS     00000000 000220 000033  0 C      0   0  8
+     [ELF ZLIB (1) 000040  8]
+[ 4] .debug_info          PROGBITS     00000000 000253 000058  0 C      0   0  1
+     [ELF ZLIB (1) 00006e  1]
+[ 5] .debug_abbrev        PROGBITS     00000000 0002ab 000028  0        0   0  1
+[ 6] .debug_line          PROGBITS     00000000 0002d3 000059  0 C      0   0  1
+     [ELF ZLIB (1) 000085  1]
+[ 7] .shstrtab            STRTAB       00000000 00032c 000060  0        0   0  1
+[ 8] .symtab              SYMTAB       00000000 0000c8 000110 16        9   9  4
+[ 9] .strtab              STRTAB       00000000 0001d8 000045  0        0   0  1
+
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-zdebug-rel.sh b/third_party/elfutils/tests/run-readelf-zdebug-rel.sh
new file mode 100755
index 0000000..ccccd82
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-zdebug-rel.sh
@@ -0,0 +1,149 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# - testfile-zdebug-rel.c
+# #define UINT64_MAX 18446744073709551615UL
+#
+# int
+# main (int argc, char **argv)
+# {
+#   unsigned long a = UINT64_MAX - 8;
+#   unsigned long b = 42 + argc;
+#
+#   if ( a + b < b )
+#     argc = a + argc;
+#   else
+#      b--;
+#
+#   return a - b;
+# }
+#
+# gcc -Og -g -Xassembler --compress-debug-sections=none \
+#     -c -o testfile-debug-rel.o testfile-zdebug-rel.c
+# gcc -Og -g -Xassembler --compress-debug-sections=zlib-gnu \
+#     -c -o testfile-debug-rel-g.o testfile-zdebug-rel.c
+# gcc -Og -g -Xassembler --compress-debug-sections=zlib-gabi \
+#     -c -o testfile-debug-rel-z.o testfile-zdebug-rel.c
+
+testfiles testfile-debug-rel.o testfile-debug-rel-g.o testfile-debug-rel-z.o
+tempfiles readelf.out
+tempfiles info.out loc.out
+
+cat > info.out << \EOF
+
+DWARF section [ 4] '.debug_info' at offset 0x58:
+ [Offset]
+ Compilation unit at offset 0:
+ Version: 4, Abbreviation section offset: 0, Address size: 8, Offset size: 4
+ [     b]  compile_unit         abbrev: 1
+           producer             (strp) "GNU C11 5.3.1 20151207 (Red Hat 5.3.1-2) -mtune=generic -march=x86-64 -g -Og"
+           language             (data1) C99 (12)
+           name                 (strp) "testfile-zdebug-rel.c"
+           comp_dir             (strp) "/tmp"
+           low_pc               (addr) 000000000000000000
+           high_pc              (data8) 24 (0x0000000000000018)
+           stmt_list            (sec_offset) 0
+ [    2d]    subprogram           abbrev: 2
+             external             (flag_present) yes
+             name                 (strp) "main"
+             decl_file            (data1) testfile-zdebug-rel.c (1)
+             decl_line            (data1) 4
+             prototyped           (flag_present) yes
+             type                 (ref4) [    80]
+             low_pc               (addr) 000000000000000000
+             high_pc              (data8) 24 (0x0000000000000018)
+             frame_base           (exprloc) 
+              [ 0] call_frame_cfa
+             GNU_all_call_sites   (flag_present) yes
+             sibling              (ref4) [    80]
+ [    4e]      formal_parameter     abbrev: 3
+               name                 (strp) "argc"
+               decl_file            (data1) testfile-zdebug-rel.c (1)
+               decl_line            (data1) 4
+               type                 (ref4) [    80]
+               location             (sec_offset) location list [     0]
+ [    5d]      formal_parameter     abbrev: 4
+               name                 (strp) "argv"
+               decl_file            (data1) testfile-zdebug-rel.c (1)
+               decl_line            (data1) 4
+               type                 (ref4) [    87]
+               location             (exprloc) 
+                [ 0] reg4
+ [    6a]      variable             abbrev: 5
+               name                 (string) "a"
+               decl_file            (data1) testfile-zdebug-rel.c (1)
+               decl_line            (data1) 6
+               type                 (ref4) [    9a]
+               const_value          (sdata) -9
+ [    74]      variable             abbrev: 6
+               name                 (string) "b"
+               decl_file            (data1) testfile-zdebug-rel.c (1)
+               decl_line            (data1) 7
+               type                 (ref4) [    9a]
+               location             (exprloc) 
+                [ 0] reg5
+ [    80]    base_type            abbrev: 7
+             byte_size            (data1) 4
+             encoding             (data1) signed (5)
+             name                 (string) "int"
+ [    87]    pointer_type         abbrev: 8
+             byte_size            (data1) 8
+             type                 (ref4) [    8d]
+ [    8d]    pointer_type         abbrev: 8
+             byte_size            (data1) 8
+             type                 (ref4) [    93]
+ [    93]    base_type            abbrev: 9
+             byte_size            (data1) 1
+             encoding             (data1) signed_char (6)
+             name                 (strp) "char"
+ [    9a]    base_type            abbrev: 9
+             byte_size            (data1) 8
+             encoding             (data1) unsigned (7)
+             name                 (strp) "long unsigned int"
+EOF
+
+cat info.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=info testfile-debug-rel.o
+
+cat info.out | sed -e "s/'.debug_info'/'.zdebug_info'/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=info testfile-debug-rel-g.o
+
+cat info.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=info testfile-debug-rel-z.o
+
+cat > loc.out << \EOF
+
+DWARF section [ 7] '.debug_loc' at offset 0x185:
+
+ CU [     b] base: 000000000000000000
+ [     0] range 0, 3
+           [ 0] reg5
+          range 3, 10
+           [ 0] breg5 -42
+           [ 2] stack_value
+          range 10, 18
+           [ 0] GNU_entry_value:
+                [ 0] reg5
+           [ 3] stack_value
+EOF
+
+cat loc.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel.o
+
+cat loc.out | sed -e "s/'.debug_loc' at offset 0x185/'.zdebug_loc' at offset 0x138/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel-g.o
+
+cat loc.out | sed -e "s/at offset 0x185/at offset 0x150/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug-rel-z.o
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-zdebug.sh b/third_party/elfutils/tests/run-readelf-zdebug.sh
new file mode 100755
index 0000000..28128ad
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-zdebug.sh
@@ -0,0 +1,546 @@
+#! /bin/sh
+# Copyright (C) 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# - testfile-zdebug.c
+# #define UINT64_MAX 18446744073709551615UL
+#
+# int
+# main (int argc, char **argv)
+# {
+#   unsigned long a = UINT64_MAX - 8;
+#   unsigned long b = 42 + argc;
+#
+#   if ( a + b < b )
+#     argc = a + argc;
+#   else
+#      b--;
+#
+#   return a - b;
+# }
+#
+# gcc -g3 -O3 -fuse-ld=gold -Xlinker --compress-debug-sections=none \
+#     -fno-asynchronous-unwind-tables -o testfile-debug testfile-zdebug.c
+# gcc -g3 -O3 -fuse-ld=gold -Xlinker --compress-debug-sections=zlib \
+#     -fno-asynchronous-unwind-tables -o testfile-zdebug testfile-zdebug.c
+
+testfiles testfile-debug testfile-zdebug
+tempfiles readelf.out
+tempfiles loc.out aranges.out ranges.out macro.out line.out frame.out
+
+cat > loc.out << \EOF
+
+DWARF section [30] '.debug_loc' at offset 0xa17:
+
+ CU [     b] base: 000000000000000000
+ [     0] range 4003c0, 4003c3
+           [ 0] reg5
+          range 4003c3, 4003d6
+           [ 0] breg5 -42
+           [ 2] stack_value
+          range 4003d6, 4003d9
+           [ 0] GNU_entry_value:
+                [ 0] reg5
+           [ 3] stack_value
+EOF
+
+cat loc.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-debug
+
+cat loc.out | sed -e "s/.debug_loc' at offset 0xa17/.zdebug_loc' at offset 0x1a27/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=loc testfile-zdebug
+
+cat > aranges.out << \EOF
+
+DWARF section [31] '.debug_aranges' at offset 0xa65:
+
+Table at offset 0:
+
+ Length:            44
+ DWARF version:      2
+ CU offset:          0
+ Address size:       8
+ Segment size:       0
+
+   0x00000000004003c0..0x0000000000000019
+EOF
+
+cat aranges.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=aranges testfile-debug
+
+cat aranges.out | sed -e "s/.debug_aranges' at offset 0xa65/.zdebug_aranges' at offset 0x1a5f/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=aranges testfile-zdebug
+
+cat > ranges.out << \EOF
+
+DWARF section [32] '.debug_ranges' at offset 0xa95:
+
+ CU [     b] base: 000000000000000000
+ [     0] range 4003c0, 4003d9
+EOF
+
+cat ranges.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=ranges testfile-debug
+
+cat ranges.out | sed -e "s/.debug_ranges' at offset 0xa95/.zdebug_ranges' at offset 0x1a87/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=ranges testfile-zdebug
+
+cat > macro.out << \EOF
+
+DWARF section [33] '.debug_macro' at offset 0xab5:
+
+ Offset:             0x0
+ Version:            4
+ Flag:               0x2
+ Offset length:      4
+ .debug_line offset: 0x0
+
+ #include offset 0x17
+ start_file 0, [1] /tmp/testfile-zdebug.c
+  #define UINT64_MAX 18446744073709551615UL, line 1 (indirect)
+ end_file
+
+ Offset:             0x17
+ Version:            4
+ Flag:               0x0
+ Offset length:      4
+
+ #define __STDC__ 1, line 1 (indirect)
+ #define __STDC_HOSTED__ 1, line 1 (indirect)
+ #define __GNUC__ 4, line 1 (indirect)
+ #define __GNUC_MINOR__ 8, line 1 (indirect)
+ #define __GNUC_PATCHLEVEL__ 2, line 1 (indirect)
+ #define __VERSION__ "4.8.2 20140120 (Red Hat 4.8.2-15)", line 1 (indirect)
+ #define __GNUC_RH_RELEASE__ 15, line 1 (indirect)
+ #define __ATOMIC_RELAXED 0, line 1 (indirect)
+ #define __ATOMIC_SEQ_CST 5, line 1 (indirect)
+ #define __ATOMIC_ACQUIRE 2, line 1 (indirect)
+ #define __ATOMIC_RELEASE 3, line 1 (indirect)
+ #define __ATOMIC_ACQ_REL 4, line 1 (indirect)
+ #define __ATOMIC_CONSUME 1, line 1 (indirect)
+ #define __OPTIMIZE__ 1, line 1 (indirect)
+ #define __FINITE_MATH_ONLY__ 0, line 1 (indirect)
+ #define _LP64 1, line 1 (indirect)
+ #define __LP64__ 1, line 1 (indirect)
+ #define __SIZEOF_INT__ 4, line 1 (indirect)
+ #define __SIZEOF_LONG__ 8, line 1 (indirect)
+ #define __SIZEOF_LONG_LONG__ 8, line 1 (indirect)
+ #define __SIZEOF_SHORT__ 2, line 1 (indirect)
+ #define __SIZEOF_FLOAT__ 4, line 1 (indirect)
+ #define __SIZEOF_DOUBLE__ 8, line 1 (indirect)
+ #define __SIZEOF_LONG_DOUBLE__ 16, line 1 (indirect)
+ #define __SIZEOF_SIZE_T__ 8, line 1 (indirect)
+ #define __CHAR_BIT__ 8, line 1 (indirect)
+ #define __BIGGEST_ALIGNMENT__ 16, line 1 (indirect)
+ #define __ORDER_LITTLE_ENDIAN__ 1234, line 1 (indirect)
+ #define __ORDER_BIG_ENDIAN__ 4321, line 1 (indirect)
+ #define __ORDER_PDP_ENDIAN__ 3412, line 1 (indirect)
+ #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__, line 1 (indirect)
+ #define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__, line 1 (indirect)
+ #define __SIZEOF_POINTER__ 8, line 1 (indirect)
+ #define __SIZE_TYPE__ long unsigned int, line 1 (indirect)
+ #define __PTRDIFF_TYPE__ long int, line 1 (indirect)
+ #define __WCHAR_TYPE__ int, line 1 (indirect)
+ #define __WINT_TYPE__ unsigned int, line 1 (indirect)
+ #define __INTMAX_TYPE__ long int, line 1 (indirect)
+ #define __UINTMAX_TYPE__ long unsigned int, line 1 (indirect)
+ #define __CHAR16_TYPE__ short unsigned int, line 1 (indirect)
+ #define __CHAR32_TYPE__ unsigned int, line 1 (indirect)
+ #define __SIG_ATOMIC_TYPE__ int, line 1 (indirect)
+ #define __INT8_TYPE__ signed char, line 1 (indirect)
+ #define __INT16_TYPE__ short int, line 1 (indirect)
+ #define __INT32_TYPE__ int, line 1 (indirect)
+ #define __INT64_TYPE__ long int, line 1 (indirect)
+ #define __UINT8_TYPE__ unsigned char, line 1 (indirect)
+ #define __UINT16_TYPE__ short unsigned int, line 1 (indirect)
+ #define __UINT32_TYPE__ unsigned int, line 1 (indirect)
+ #define __UINT64_TYPE__ long unsigned int, line 1 (indirect)
+ #define __INT_LEAST8_TYPE__ signed char, line 1 (indirect)
+ #define __INT_LEAST16_TYPE__ short int, line 1 (indirect)
+ #define __INT_LEAST32_TYPE__ int, line 1 (indirect)
+ #define __INT_LEAST64_TYPE__ long int, line 1 (indirect)
+ #define __UINT_LEAST8_TYPE__ unsigned char, line 1 (indirect)
+ #define __UINT_LEAST16_TYPE__ short unsigned int, line 1 (indirect)
+ #define __UINT_LEAST32_TYPE__ unsigned int, line 1 (indirect)
+ #define __UINT_LEAST64_TYPE__ long unsigned int, line 1 (indirect)
+ #define __INT_FAST8_TYPE__ signed char, line 1 (indirect)
+ #define __INT_FAST16_TYPE__ long int, line 1 (indirect)
+ #define __INT_FAST32_TYPE__ long int, line 1 (indirect)
+ #define __INT_FAST64_TYPE__ long int, line 1 (indirect)
+ #define __UINT_FAST8_TYPE__ unsigned char, line 1 (indirect)
+ #define __UINT_FAST16_TYPE__ long unsigned int, line 1 (indirect)
+ #define __UINT_FAST32_TYPE__ long unsigned int, line 1 (indirect)
+ #define __UINT_FAST64_TYPE__ long unsigned int, line 1 (indirect)
+ #define __INTPTR_TYPE__ long int, line 1 (indirect)
+ #define __UINTPTR_TYPE__ long unsigned int, line 1 (indirect)
+ #define __GXX_ABI_VERSION 1002, line 1 (indirect)
+ #define __SCHAR_MAX__ 127, line 1 (indirect)
+ #define __SHRT_MAX__ 32767, line 1 (indirect)
+ #define __INT_MAX__ 2147483647, line 1 (indirect)
+ #define __LONG_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __LONG_LONG_MAX__ 9223372036854775807LL, line 1 (indirect)
+ #define __WCHAR_MAX__ 2147483647, line 1 (indirect)
+ #define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1), line 1 (indirect)
+ #define __WINT_MAX__ 4294967295U, line 1 (indirect)
+ #define __WINT_MIN__ 0U, line 1 (indirect)
+ #define __PTRDIFF_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __SIZE_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __INTMAX_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __INTMAX_C(c) c ## L, line 1 (indirect)
+ #define __UINTMAX_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __UINTMAX_C(c) c ## UL, line 1 (indirect)
+ #define __SIG_ATOMIC_MAX__ 2147483647, line 1 (indirect)
+ #define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1), line 1 (indirect)
+ #define __INT8_MAX__ 127, line 1 (indirect)
+ #define __INT16_MAX__ 32767, line 1 (indirect)
+ #define __INT32_MAX__ 2147483647, line 1 (indirect)
+ #define __INT64_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __UINT8_MAX__ 255, line 1 (indirect)
+ #define __UINT16_MAX__ 65535, line 1 (indirect)
+ #define __UINT32_MAX__ 4294967295U, line 1 (indirect)
+ #define __UINT64_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __INT_LEAST8_MAX__ 127, line 1 (indirect)
+ #define __INT8_C(c) c, line 1 (indirect)
+ #define __INT_LEAST16_MAX__ 32767, line 1 (indirect)
+ #define __INT16_C(c) c, line 1 (indirect)
+ #define __INT_LEAST32_MAX__ 2147483647, line 1 (indirect)
+ #define __INT32_C(c) c, line 1 (indirect)
+ #define __INT_LEAST64_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __INT64_C(c) c ## L, line 1 (indirect)
+ #define __UINT_LEAST8_MAX__ 255, line 1 (indirect)
+ #define __UINT8_C(c) c, line 1 (indirect)
+ #define __UINT_LEAST16_MAX__ 65535, line 1 (indirect)
+ #define __UINT16_C(c) c, line 1 (indirect)
+ #define __UINT_LEAST32_MAX__ 4294967295U, line 1 (indirect)
+ #define __UINT32_C(c) c ## U, line 1 (indirect)
+ #define __UINT_LEAST64_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __UINT64_C(c) c ## UL, line 1 (indirect)
+ #define __INT_FAST8_MAX__ 127, line 1 (indirect)
+ #define __INT_FAST16_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __INT_FAST32_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __INT_FAST64_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __UINT_FAST8_MAX__ 255, line 1 (indirect)
+ #define __UINT_FAST16_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __UINT_FAST32_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __UINT_FAST64_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __INTPTR_MAX__ 9223372036854775807L, line 1 (indirect)
+ #define __UINTPTR_MAX__ 18446744073709551615UL, line 1 (indirect)
+ #define __FLT_EVAL_METHOD__ 0, line 1 (indirect)
+ #define __DEC_EVAL_METHOD__ 2, line 1 (indirect)
+ #define __FLT_RADIX__ 2, line 1 (indirect)
+ #define __FLT_MANT_DIG__ 24, line 1 (indirect)
+ #define __FLT_DIG__ 6, line 1 (indirect)
+ #define __FLT_MIN_EXP__ (-125), line 1 (indirect)
+ #define __FLT_MIN_10_EXP__ (-37), line 1 (indirect)
+ #define __FLT_MAX_EXP__ 128, line 1 (indirect)
+ #define __FLT_MAX_10_EXP__ 38, line 1 (indirect)
+ #define __FLT_DECIMAL_DIG__ 9, line 1 (indirect)
+ #define __FLT_MAX__ 3.40282346638528859812e+38F, line 1 (indirect)
+ #define __FLT_MIN__ 1.17549435082228750797e-38F, line 1 (indirect)
+ #define __FLT_EPSILON__ 1.19209289550781250000e-7F, line 1 (indirect)
+ #define __FLT_DENORM_MIN__ 1.40129846432481707092e-45F, line 1 (indirect)
+ #define __FLT_HAS_DENORM__ 1, line 1 (indirect)
+ #define __FLT_HAS_INFINITY__ 1, line 1 (indirect)
+ #define __FLT_HAS_QUIET_NAN__ 1, line 1 (indirect)
+ #define __DBL_MANT_DIG__ 53, line 1 (indirect)
+ #define __DBL_DIG__ 15, line 1 (indirect)
+ #define __DBL_MIN_EXP__ (-1021), line 1 (indirect)
+ #define __DBL_MIN_10_EXP__ (-307), line 1 (indirect)
+ #define __DBL_MAX_EXP__ 1024, line 1 (indirect)
+ #define __DBL_MAX_10_EXP__ 308, line 1 (indirect)
+ #define __DBL_DECIMAL_DIG__ 17, line 1 (indirect)
+ #define __DBL_MAX__ ((double)1.79769313486231570815e+308L), line 1 (indirect)
+ #define __DBL_MIN__ ((double)2.22507385850720138309e-308L), line 1 (indirect)
+ #define __DBL_EPSILON__ ((double)2.22044604925031308085e-16L), line 1 (indirect)
+ #define __DBL_DENORM_MIN__ ((double)4.94065645841246544177e-324L), line 1 (indirect)
+ #define __DBL_HAS_DENORM__ 1, line 1 (indirect)
+ #define __DBL_HAS_INFINITY__ 1, line 1 (indirect)
+ #define __DBL_HAS_QUIET_NAN__ 1, line 1 (indirect)
+ #define __LDBL_MANT_DIG__ 64, line 1 (indirect)
+ #define __LDBL_DIG__ 18, line 1 (indirect)
+ #define __LDBL_MIN_EXP__ (-16381), line 1 (indirect)
+ #define __LDBL_MIN_10_EXP__ (-4931), line 1 (indirect)
+ #define __LDBL_MAX_EXP__ 16384, line 1 (indirect)
+ #define __LDBL_MAX_10_EXP__ 4932, line 1 (indirect)
+ #define __DECIMAL_DIG__ 21, line 1 (indirect)
+ #define __LDBL_MAX__ 1.18973149535723176502e+4932L, line 1 (indirect)
+ #define __LDBL_MIN__ 3.36210314311209350626e-4932L, line 1 (indirect)
+ #define __LDBL_EPSILON__ 1.08420217248550443401e-19L, line 1 (indirect)
+ #define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L, line 1 (indirect)
+ #define __LDBL_HAS_DENORM__ 1, line 1 (indirect)
+ #define __LDBL_HAS_INFINITY__ 1, line 1 (indirect)
+ #define __LDBL_HAS_QUIET_NAN__ 1, line 1 (indirect)
+ #define __DEC32_MANT_DIG__ 7, line 1 (indirect)
+ #define __DEC32_MIN_EXP__ (-94), line 1 (indirect)
+ #define __DEC32_MAX_EXP__ 97, line 1 (indirect)
+ #define __DEC32_MIN__ 1E-95DF, line 1 (indirect)
+ #define __DEC32_MAX__ 9.999999E96DF, line 1 (indirect)
+ #define __DEC32_EPSILON__ 1E-6DF, line 1 (indirect)
+ #define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF, line 1 (indirect)
+ #define __DEC64_MANT_DIG__ 16, line 1 (indirect)
+ #define __DEC64_MIN_EXP__ (-382), line 1 (indirect)
+ #define __DEC64_MAX_EXP__ 385, line 1 (indirect)
+ #define __DEC64_MIN__ 1E-383DD, line 1 (indirect)
+ #define __DEC64_MAX__ 9.999999999999999E384DD, line 1 (indirect)
+ #define __DEC64_EPSILON__ 1E-15DD, line 1 (indirect)
+ #define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD, line 1 (indirect)
+ #define __DEC128_MANT_DIG__ 34, line 1 (indirect)
+ #define __DEC128_MIN_EXP__ (-6142), line 1 (indirect)
+ #define __DEC128_MAX_EXP__ 6145, line 1 (indirect)
+ #define __DEC128_MIN__ 1E-6143DL, line 1 (indirect)
+ #define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL, line 1 (indirect)
+ #define __DEC128_EPSILON__ 1E-33DL, line 1 (indirect)
+ #define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL, line 1 (indirect)
+ #define __REGISTER_PREFIX__ , line 1 (indirect)
+ #define __USER_LABEL_PREFIX__ , line 1 (indirect)
+ #define __GNUC_GNU_INLINE__ 1, line 1 (indirect)
+ #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1, line 1 (indirect)
+ #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1, line 1 (indirect)
+ #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1, line 1 (indirect)
+ #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1, line 1 (indirect)
+ #define __GCC_ATOMIC_BOOL_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_CHAR_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_SHORT_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_INT_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_LONG_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_LLONG_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1, line 1 (indirect)
+ #define __GCC_ATOMIC_POINTER_LOCK_FREE 2, line 1 (indirect)
+ #define __GCC_HAVE_DWARF2_CFI_ASM 1, line 1 (indirect)
+ #define __PRAGMA_REDEFINE_EXTNAME 1, line 1 (indirect)
+ #define __SIZEOF_INT128__ 16, line 1 (indirect)
+ #define __SIZEOF_WCHAR_T__ 4, line 1 (indirect)
+ #define __SIZEOF_WINT_T__ 4, line 1 (indirect)
+ #define __SIZEOF_PTRDIFF_T__ 8, line 1 (indirect)
+ #define __amd64 1, line 1 (indirect)
+ #define __amd64__ 1, line 1 (indirect)
+ #define __x86_64 1, line 1 (indirect)
+ #define __x86_64__ 1, line 1 (indirect)
+ #define __ATOMIC_HLE_ACQUIRE 65536, line 1 (indirect)
+ #define __ATOMIC_HLE_RELEASE 131072, line 1 (indirect)
+ #define __k8 1, line 1 (indirect)
+ #define __k8__ 1, line 1 (indirect)
+ #define __code_model_small__ 1, line 1 (indirect)
+ #define __MMX__ 1, line 1 (indirect)
+ #define __SSE__ 1, line 1 (indirect)
+ #define __SSE2__ 1, line 1 (indirect)
+ #define __FXSR__ 1, line 1 (indirect)
+ #define __SSE_MATH__ 1, line 1 (indirect)
+ #define __SSE2_MATH__ 1, line 1 (indirect)
+ #define __gnu_linux__ 1, line 1 (indirect)
+ #define __linux 1, line 1 (indirect)
+ #define __linux__ 1, line 1 (indirect)
+ #define linux 1, line 1 (indirect)
+ #define __unix 1, line 1 (indirect)
+ #define __unix__ 1, line 1 (indirect)
+ #define unix 1, line 1 (indirect)
+ #define __ELF__ 1, line 1 (indirect)
+ #define __DECIMAL_BID_FORMAT__ 1, line 1 (indirect)
+
+EOF
+
+cat macro.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=macro testfile-debug
+
+cat macro.out | sed -e "s/.debug_macro' at offset 0xab5/.zdebug_macro' at offset 0x1aa7/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=macro testfile-zdebug
+
+cat > line.out << \EOF
+
+DWARF section [34] '.debug_line' at offset 0x104c:
+
+Table at offset 0:
+
+ Length:                     70
+ DWARF version:              2
+ Prologue length:            40
+ Minimum instruction length: 1
+ Maximum operations per instruction: 1
+ Initial value if 'is_stmt': 1
+ Line base:                  -5
+ Line range:                 14
+ Opcode base:                13
+
+Opcodes:
+  [ 1]  0 arguments
+  [ 2]  1 argument
+  [ 3]  1 argument
+  [ 4]  1 argument
+  [ 5]  1 argument
+  [ 6]  0 arguments
+  [ 7]  0 arguments
+  [ 8]  0 arguments
+  [ 9]  1 argument
+  [10]  0 arguments
+  [11]  0 arguments
+  [12]  1 argument
+
+Directory table:
+
+File name table:
+ Entry Dir   Time      Size      Name
+ 1     0     0         0         testfile-zdebug.c
+
+Line number statements:
+ [    32] extended opcode 2:  set address to 0x4003c0
+ [    3d] special opcode 22: address+0 = 0x4003c0, line+4 = 5
+ [    3e] special opcode 20: address+0 = 0x4003c0, line+2 = 7
+ [    3f] special opcode 104: address+6 = 0x4003c6, line+2 = 9
+ [    40] special opcode 77: address+4 = 0x4003ca, line+3 = 12
+ [    41] special opcode 62: address+3 = 0x4003cd, line+2 = 14
+ [    42] special opcode 86: address+5 = 0x4003d2, line-2 = 12
+ [    43] special opcode 76: address+4 = 0x4003d6, line+2 = 14
+ [    44] special opcode 47: address+2 = 0x4003d8, line+1 = 15
+ [    45] advance address by 1 to 0x4003d9
+ [    47] extended opcode 1:  end of sequence
+EOF
+
+cat line.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=line testfile-debug
+
+cat line.out | sed -e "s/.debug_line' at offset 0x104c/.zdebug_line' at offset 0x1d53/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=line testfile-zdebug
+
+
+cat > frame.out << \EOF
+
+Call frame information section [16] '.eh_frame' at offset 0x5b8:
+
+ [     0] CIE length=20
+   CIE_id:                   0
+   version:                  1
+   augmentation:             "zR"
+   code_alignment_factor:    1
+   data_alignment_factor:    -8
+   return_address_register:  16
+   Augmentation data:        0x1b (FDE address encoding: sdata4 pcrel)
+
+   Program:
+     def_cfa r7 (rsp) at offset 8
+     offset r16 (rip) at cfa-8
+     nop
+     nop
+
+ [    18] FDE length=20 cie=[     0]
+   CIE_pointer:              28
+   initial_location:         0x00000000ffffff08 (offset: 0x4e0)
+   address_range:            0x2 (end offset: 0x4e2)
+
+   Program:
+     nop
+     nop
+     nop
+     nop
+     nop
+     nop
+     nop
+
+ [    30] FDE length=44 cie=[     0]
+   CIE_pointer:              52
+   initial_location:         0x00000000ffffff00 (offset: 0x4f0)
+   address_range:            0x89 (end offset: 0x579)
+
+   Program:
+     advance_loc 17 to 0x501
+     offset r12 (r12) at cfa-40
+     offset r6 (rbp) at cfa-48
+     advance_loc 31 to 0x520
+     def_cfa_offset 64
+     offset r3 (rbx) at cfa-56
+     offset r15 (r15) at cfa-16
+     offset r14 (r14) at cfa-24
+     offset r13 (r13) at cfa-32
+     advance_loc1 88 to 0x578
+     def_cfa_offset 8
+     nop
+     nop
+     nop
+     nop
+     nop
+     nop
+     nop
+     nop
+     nop
+     nop
+     nop
+
+ [    60] FDE length=36 cie=[     0]
+   CIE_pointer:              100
+   initial_location:         0x00000000fffffd80 (offset: 0x3a0)
+   address_range:            0x20 (end offset: 0x3c0)
+
+   Program:
+     def_cfa_offset 16
+     advance_loc 6 to 0x3a6
+     def_cfa_offset 24
+     advance_loc 10 to 0x3b0
+     def_cfa_expression 11
+          [ 0] breg7 8
+          [ 2] breg16 0
+          [ 4] lit15
+          [ 5] and
+          [ 6] lit11
+          [ 7] ge
+          [ 8] lit3
+          [ 9] shl
+          [10] plus
+     nop
+     nop
+     nop
+     nop
+
+ [    88] Zero terminator
+
+Call frame search table section [17] '.eh_frame_hdr':
+ version:          1
+ eh_frame_ptr_enc: 0x1b (sdata4 pcrel)
+ fde_count_enc:    0x3 (udata4)
+ table_enc:        0x3b (sdata4 datarel)
+ eh_frame_ptr:     0xffffffffffffff70 (offset: 0x5b8)
+ fde_count:        3
+ Table:
+  0xfffffd5c (offset:  0x3a0) -> 0xffffffd4 fde=[    60]
+  0xfffffe9c (offset:  0x4e0) -> 0xffffff8c fde=[    18]
+  0xfffffeac (offset:  0x4f0) -> 0xffffffa4 fde=[    30]
+
+DWARF section [36] '.debug_frame' at offset 0x29b8:
+
+ [     0] CIE length=20
+   CIE_id:                   18446744073709551615
+   version:                  1
+   augmentation:             ""
+   code_alignment_factor:    1
+   data_alignment_factor:    -8
+   return_address_register:  16
+
+   Program:
+     def_cfa r7 (rsp) at offset 8
+     offset r16 (rip) at cfa-8
+     nop
+     nop
+     nop
+     nop
+     nop
+     nop
+
+ [    18] FDE length=20 cie=[     0]
+   CIE_pointer:              0
+   initial_location:         0x00000000004003c0
+   address_range:            0x19
+
+   Program:
+EOF
+
+cat frame.out | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=frame testfile-debug
+
+cat frame.out | sed -e "s/.debug_frame' at offset 0x29b8/.zdebug_frame' at offset 0x2728/" | testrun_compare ${abs_top_builddir}/src/readelf -U --debug-dump=frame testfile-zdebug
+
+
diff --git a/third_party/elfutils/tests/run-readelf-zp.sh b/third_party/elfutils/tests/run-readelf-zp.sh
new file mode 100755
index 0000000..872126c
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-zp.sh
@@ -0,0 +1,271 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# See run-readelf-zdebug.sh for testfile.
+
+testfiles testfile-zdebug
+testrun_compare ${abs_top_builddir}/src/readelf -z -p.zdebug_str testfile-zdebug <<\EOF
+
+String section [35] '.zdebug_str' contains 2431 bytes (6433 uncompressed) at offset 0x1da3:
+  [     0]  UINT64_MAX 18446744073709551615UL
+  [    22]  __DBL_DENORM_MIN__ ((double)4.94065645841246544177e-324L)
+  [    5c]  __linux 1
+  [    66]  __SIZEOF_SIZE_T__ 8
+  [    7a]  __UINTPTR_TYPE__ long unsigned int
+  [    9d]  __SIZEOF_POINTER__ 8
+  [    b2]  __UINT8_MAX__ 255
+  [    c4]  __PTRDIFF_MAX__ 9223372036854775807L
+  [    e9]  __DEC64_MANT_DIG__ 16
+  [    ff]  __FLT_RADIX__ 2
+  [   10f]  __DEC32_MIN__ 1E-95DF
+  [   125]  __unix__ 1
+  [   130]  testfile-zdebug.c
+  [   142]  __UINT_LEAST64_MAX__ 18446744073709551615UL
+  [   16e]  __SIZEOF_WINT_T__ 4
+  [   182]  __LONG_MAX__ 9223372036854775807L
+  [   1a4]  __LDBL_MIN__ 3.36210314311209350626e-4932L
+  [   1cf]  __GCC_ATOMIC_SHORT_LOCK_FREE 2
+  [   1ee]  __LP64__ 1
+  [   1f9]  __UINT64_C(c) c ## UL
+  [   20f]  __DBL_HAS_INFINITY__ 1
+  [   226]  __SSE2_MATH__ 1
+  [   236]  __linux__ 1
+  [   242]  __STDC_HOSTED__ 1
+  [   254]  __WINT_MIN__ 0U
+  [   264]  __x86_64__ 1
+  [   271]  __UINT32_TYPE__ unsigned int
+  [   28e]  __UINT_LEAST8_MAX__ 255
+  [   2a6]  __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD
+  [   2d7]  __FLT_MAX__ 3.40282346638528859812e+38F
+  [   2ff]  long unsigned int
+  [   311]  __DBL_MANT_DIG__ 53
+  [   325]  linux 1
+  [   32d]  __DBL_HAS_QUIET_NAN__ 1
+  [   345]  __UINT8_TYPE__ unsigned char
+  [   362]  __DEC32_MAX_EXP__ 97
+  [   377]  __INT32_TYPE__ int
+  [   38a]  __SIG_ATOMIC_TYPE__ int
+  [   3a2]  __DEC64_MAX_EXP__ 385
+  [   3b8]  __DBL_MIN_EXP__ (-1021)
+  [   3d0]  _LP64 1
+  [   3d8]  __LDBL_HAS_INFINITY__ 1
+  [   3f0]  __INT_FAST64_TYPE__ long int
+  [   40d]  __gnu_linux__ 1
+  [   41d]  __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
+  [   43e]  __UINT_FAST64_TYPE__ long unsigned int
+  [   465]  __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+  [   48c]  __UINT16_MAX__ 65535
+  [   4a1]  __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
+  [   4ce]  __PRAGMA_REDEFINE_EXTNAME 1
+  [   4ea]  __INT_LEAST16_TYPE__ short int
+  [   509]  __k8__ 1
+  [   512]  __DECIMAL_DIG__ 21
+  [   525]  main
+  [   52a]  __DBL_MAX__ ((double)1.79769313486231570815e+308L)
+  [   55d]  __INT16_TYPE__ short int
+  [   576]  __LDBL_HAS_QUIET_NAN__ 1
+  [   58f]  __SIZEOF_DOUBLE__ 8
+  [   5a3]  __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF
+  [   5ca]  __ATOMIC_SEQ_CST 5
+  [   5dd]  __UINT64_TYPE__ long unsigned int
+  [   5ff]  __INT_LEAST32_TYPE__ int
+  [   618]  __INT_LEAST64_MAX__ 9223372036854775807L
+  [   641]  __OPTIMIZE__ 1
+  [   650]  __INTMAX_C(c) c ## L
+  [   665]  __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
+  [   687]  __INT_FAST8_MAX__ 127
+  [   69d]  __PTRDIFF_TYPE__ long int
+  [   6b7]  __LDBL_MIN_EXP__ (-16381)
+  [   6d1]  __SIZEOF_LONG_LONG__ 8
+  [   6e8]  __FLT_DIG__ 6
+  [   6f6]  __UINTMAX_MAX__ 18446744073709551615UL
+  [   71d]  __SIZEOF_WCHAR_T__ 4
+  [   732]  __INT64_C(c) c ## L
+  [   746]  __UINTPTR_MAX__ 18446744073709551615UL
+  [   76d]  __FLT_MAX_10_EXP__ 38
+  [   783]  __FLT_MIN__ 1.17549435082228750797e-38F
+  [   7ab]  __UINT_LEAST64_TYPE__ long unsigned int
+  [   7d3]  __SIZEOF_LONG_DOUBLE__ 16
+  [   7ed]  __SIZE_MAX__ 18446744073709551615UL
+  [   811]  __INT8_C(c) c
+  [   81f]  __amd64__ 1
+  [   82b]  __INT_LEAST64_TYPE__ long int
+  [   849]  __INT_FAST64_MAX__ 9223372036854775807L
+  [   871]  __DEC_EVAL_METHOD__ 2
+  [   887]  __DEC32_MAX__ 9.999999E96DF
+  [   8a3]  __GNUC_MINOR__ 8
+  [   8b4]  __WCHAR_MAX__ 2147483647
+  [   8cd]  __SIZE_TYPE__ long unsigned int
+  [   8ed]  __INT8_MAX__ 127
+  [   8fe]  __INTMAX_MAX__ 9223372036854775807L
+  [   922]  __ATOMIC_HLE_RELEASE 131072
+  [   93e]  __FLT_HAS_QUIET_NAN__ 1
+  [   956]  __DBL_EPSILON__ ((double)2.22044604925031308085e-16L)
+  [   98c]  __FLT_MIN_EXP__ (-125)
+  [   9a3]  __INT_LEAST8_MAX__ 127
+  [   9ba]  __SIZEOF_INT128__ 16
+  [   9cf]  __INTPTR_MAX__ 9223372036854775807L
+  [   9f3]  __INTPTR_TYPE__ long int
+  [   a0c]  __LDBL_MIN_10_EXP__ (-4931)
+  [   a28]  __GCC_ATOMIC_POINTER_LOCK_FREE 2
+  [   a49]  __UINT_LEAST32_MAX__ 4294967295U
+  [   a6a]  __SIZEOF_SHORT__ 2
+  [   a7d]  __LDBL_MAX_10_EXP__ 4932
+  [   a96]  __INT16_C(c) c
+  [   aa5]  __MMX__ 1
+  [   aaf]  unix 1
+  [   ab6]  __FLT_MAX_EXP__ 128
+  [   aca]  __DEC64_MAX__ 9.999999999999999E384DD
+  [   af0]  __FLT_EPSILON__ 1.19209289550781250000e-7F
+  [   b1b]  __INT_FAST16_TYPE__ long int
+  [   b38]  __VERSION__ "4.8.2 20140120 (Red Hat 4.8.2-15)"
+  [   b68]  __GCC_ATOMIC_LLONG_LOCK_FREE 2
+  [   b87]  __DEC128_MIN_EXP__ (-6142)
+  [   ba2]  __ATOMIC_RELEASE 3
+  [   bb5]  __GNUC_PATCHLEVEL__ 2
+  [   bcb]  __UINT_FAST64_MAX__ 18446744073709551615UL
+  [   bf6]  __DBL_DECIMAL_DIG__ 17
+  [   c0d]  __DBL_DIG__ 15
+  [   c1c]  __FLT_MANT_DIG__ 24
+  [   c30]  __FLT_DECIMAL_DIG__ 9
+  [   c46]  __INT16_MAX__ 32767
+  [   c5a]  __DEC128_MIN__ 1E-6143DL
+  [   c73]  __BIGGEST_ALIGNMENT__ 16
+  [   c8c]  __INT64_MAX__ 9223372036854775807L
+  [   caf]  __INT_FAST32_TYPE__ long int
+  [   ccc]  __GCC_ATOMIC_INT_LOCK_FREE 2
+  [   ce9]  __DEC128_MAX_EXP__ 6145
+  [   d01]  __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+  [   d26]  __FXSR__ 1
+  [   d31]  __INT8_TYPE__ signed char
+  [   d4b]  __ATOMIC_ACQ_REL 4
+  [   d5e]  __UINT_LEAST16_MAX__ 65535
+  [   d79]  __UINTMAX_TYPE__ long unsigned int
+  [   d9c]  __UINT_FAST8_MAX__ 255
+  [   db3]  __ORDER_BIG_ENDIAN__ 4321
+  [   dcd]  __INT_LEAST32_MAX__ 2147483647
+  [   dec]  __UINT_LEAST16_TYPE__ short unsigned int
+  [   e15]  __INT_FAST8_TYPE__ signed char
+  [   e34]  __DBL_MAX_EXP__ 1024
+  [   e49]  __STDC__ 1
+  [   e54]  __ELF__ 1
+  [   e5e]  __FLT_EVAL_METHOD__ 0
+  [   e74]  __ATOMIC_ACQUIRE 2
+  [   e87]  __DEC64_EPSILON__ 1E-15DD
+  [   ea1]  __INT32_MAX__ 2147483647
+  [   eba]  __GCC_ATOMIC_CHAR_LOCK_FREE 2
+  [   ed8]  __DEC128_EPSILON__ 1E-33DL
+  [   ef3]  __UINT_FAST8_TYPE__ unsigned char
+  [   f15]  __amd64 1
+  [   f1f]  __DEC32_MIN_EXP__ (-94)
+  [   f37]  __GCC_HAVE_DWARF2_CFI_ASM 1
+  [   f53]  __LDBL_DIG__ 18
+  [   f63]  __UINT32_MAX__ 4294967295U
+  [   f7e]  __GNUC_GNU_INLINE__ 1
+  [   f94]  __SSE2__ 1
+  [   f9f]  __ATOMIC_HLE_ACQUIRE 65536
+  [   fba]  __SSE_MATH__ 1
+  [   fc9]  __INT_FAST16_MAX__ 9223372036854775807L
+  [   ff1]  __LDBL_MAX__ 1.18973149535723176502e+4932L
+  [  101c]  __DBL_MIN__ ((double)2.22507385850720138309e-308L)
+  [  104f]  __DEC128_MANT_DIG__ 34
+  [  1066]  __INT32_C(c) c
+  [  1075]  __DEC64_MIN_EXP__ (-382)
+  [  108e]  __WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
+  [  10b1]  __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
+  [  10d3]  __LDBL_MAX_EXP__ 16384
+  [  10ea]  __DEC32_MANT_DIG__ 7
+  [  10ff]  __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
+  [  1139]  __CHAR32_TYPE__ unsigned int
+  [  1156]  __INT_LEAST8_TYPE__ signed char
+  [  1176]  __UINT16_C(c) c
+  [  1186]  __GCC_ATOMIC_BOOL_LOCK_FREE 2
+  [  11a4]  __SIZEOF_FLOAT__ 4
+  [  11b7]  __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+  [  11dc]  __DBL_MAX_10_EXP__ 308
+  [  11f3]  __LDBL_EPSILON__ 1.08420217248550443401e-19L
+  [  1220]  __ORDER_PDP_ENDIAN__ 3412
+  [  123a]  __ORDER_LITTLE_ENDIAN__ 1234
+  [  1257]  __WINT_TYPE__ unsigned int
+  [  1272]  __unix 1
+  [  127b]  __ATOMIC_RELAXED 0
+  [  128e]  __UINT_FAST32_MAX__ 18446744073709551615UL
+  [  12b9]  __INT_FAST32_MAX__ 9223372036854775807L
+  [  12e1]  __SIG_ATOMIC_MAX__ 2147483647
+  [  12ff]  __UINT_FAST32_TYPE__ long unsigned int
+  [  1326]  __INT_MAX__ 2147483647
+  [  133d]  __GXX_ABI_VERSION 1002
+  [  1354]  __SIZEOF_INT__ 4
+  [  1365]  char
+  [  136a]  __UINT_FAST16_TYPE__ long unsigned int
+  [  1391]  __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
+  [  13c3]  __WINT_MAX__ 4294967295U
+  [  13dc]  __FLT_HAS_INFINITY__ 1
+  [  13f3]  __SHRT_MAX__ 32767
+  [  1406]  __INT_LEAST16_MAX__ 32767
+  [  1420]  __LONG_LONG_MAX__ 9223372036854775807LL
+  [  1448]  __SIZEOF_LONG__ 8
+  [  145a]  __INTMAX_TYPE__ long int
+  [  1473]  __LDBL_HAS_DENORM__ 1
+  [  1489]  __code_model_small__ 1
+  [  14a0]  __REGISTER_PREFIX__ 
+  [  14b5]  __ATOMIC_CONSUME 1
+  [  14c8]  __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL
+  [  150d]  __GNUC__ 4
+  [  1518]  __UINT16_TYPE__ short unsigned int
+  [  153b]  __SSE__ 1
+  [  1545]  __UINT32_C(c) c ## U
+  [  155a]  __k8 1
+  [  1561]  __UINTMAX_C(c) c ## UL
+  [  1578]  __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+  [  159d]  __SIZEOF_PTRDIFF_T__ 8
+  [  15b4]  __CHAR_BIT__ 8
+  [  15c3]  __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1)
+  [  15f0]  __DEC32_EPSILON__ 1E-6DF
+  [  1609]  __UINT_LEAST32_TYPE__ unsigned int
+  [  162c]  __DBL_HAS_DENORM__ 1
+  [  1641]  /tmp
+  [  1646]  __LDBL_MANT_DIG__ 64
+  [  165b]  __GCC_ATOMIC_LONG_LOCK_FREE 2
+  [  1679]  __DECIMAL_BID_FORMAT__ 1
+  [  1692]  __FLT_MIN_10_EXP__ (-37)
+  [  16ab]  __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
+  [  16cf]  __WCHAR_TYPE__ int
+  [  16e2]  __FINITE_MATH_ONLY__ 0
+  [  16f9]  argc
+  [  16fe]  __USER_LABEL_PREFIX__ 
+  [  1715]  __CHAR16_TYPE__ short unsigned int
+  [  1738]  __UINT64_MAX__ 18446744073709551615UL
+  [  175e]  __UINT8_C(c) c
+  [  176d]  __x86_64 1
+  [  1778]  __UINT_LEAST8_TYPE__ unsigned char
+  [  179b]  __INT64_TYPE__ long int
+  [  17b3]  __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+  [  17d8]  argv
+  [  17dd]  __GNUC_RH_RELEASE__ 15
+  [  17f4]  __UINT_FAST16_MAX__ 18446744073709551615UL
+  [  181f]  __FLT_HAS_DENORM__ 1
+  [  1834]  __DEC64_MIN__ 1E-383DD
+  [  184b]  __DBL_MIN_10_EXP__ (-307)
+  [  1865]  __FLT_DENORM_MIN__ 1.40129846432481707092e-45F
+  [  1894]  GNU C 4.8.2 20140120 (Red Hat 4.8.2-15) -mtune=generic -march=x86-64 -g3 -O3 -fuse-ld=gold -fno-asynchronous-unwind-tables
+  [  190f]  __SCHAR_MAX__ 127
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-readelf-zx.sh b/third_party/elfutils/tests/run-readelf-zx.sh
new file mode 100755
index 0000000..994528c
--- /dev/null
+++ b/third_party/elfutils/tests/run-readelf-zx.sh
@@ -0,0 +1,66 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# See run-elfgetchdr.sh for testfiles.
+
+testfiles testfile-zgnu64
+testrun_compare ${abs_top_builddir}/src/readelf -z -x.zdebug_aranges testfile-zgnu64 <<\EOF
+
+Hex dump of section [2] '.zdebug_aranges', 50 bytes (96 uncompressed) at offset 0x260:
+  0x00000000 2c000000 02000000 00000800 00000000 ,...............
+  0x00000010 78004000 00000000 14000000 00000000 x.@.............
+  0x00000020 00000000 00000000 00000000 00000000 ................
+  0x00000030 2c000000 02005500 00000800 00000000 ,.....U.........
+  0x00000040 8c004000 00000000 16000000 00000000 ..@.............
+  0x00000050 00000000 00000000 00000000 00000000 ................
+EOF
+
+testfiles testfile-zgabi64
+testrun_compare ${abs_top_builddir}/src/readelf -z -x.debug_aranges testfile-zgabi64 <<\EOF
+
+Hex dump of section [2] '.debug_aranges', 62 bytes (96 uncompressed) at offset 0x260:
+  0x00000000 2c000000 02000000 00000800 00000000 ,...............
+  0x00000010 78004000 00000000 14000000 00000000 x.@.............
+  0x00000020 00000000 00000000 00000000 00000000 ................
+  0x00000030 2c000000 02005500 00000800 00000000 ,.....U.........
+  0x00000040 8c004000 00000000 16000000 00000000 ..@.............
+  0x00000050 00000000 00000000 00000000 00000000 ................
+EOF
+
+testfiles testfile-zgnu32
+testrun_compare ${abs_top_builddir}/src/readelf -z -x.zdebug_aranges testfile-zgnu32 <<\EOF
+
+Hex dump of section [2] '.zdebug_aranges', 49 bytes (64 uncompressed) at offset 0x1c0:
+  0x00000000 1c000000 02000000 00000400 00000000 ................
+  0x00000010 54800408 14000000 00000000 00000000 T...............
+  0x00000020 1c000000 02004d00 00000400 00000000 ......M.........
+  0x00000030 68800408 16000000 00000000 00000000 h...............
+EOF
+
+testfiles testfile-zgabi32
+testrun_compare ${abs_top_builddir}/src/readelf -z -x.debug_aranges testfile-zgabi32 <<\EOF
+
+Hex dump of section [2] '.debug_aranges', 49 bytes (64 uncompressed) at offset 0x1c0:
+  0x00000000 1c000000 02000000 00000400 00000000 ................
+  0x00000010 54800408 14000000 00000000 00000000 T...............
+  0x00000020 1c000000 02004d00 00000400 00000000 ......M.........
+  0x00000030 68800408 16000000 00000000 00000000 h...............
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-rerequest_tag.sh b/third_party/elfutils/tests/run-rerequest_tag.sh
new file mode 100755
index 0000000..f437284
--- /dev/null
+++ b/third_party/elfutils/tests/run-rerequest_tag.sh
@@ -0,0 +1,25 @@
+#! /bin/sh
+# Copyright (C) 2011 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile56 testfile57
+
+testrun ${abs_builddir}/rerequest_tag testfile56
+testrun ${abs_builddir}/rerequest_tag testfile57
+
+exit 0
diff --git a/third_party/elfutils/tests/run-show-abbrev.sh b/third_party/elfutils/tests/run-show-abbrev.sh
new file mode 100755
index 0000000..40d0e36
--- /dev/null
+++ b/third_party/elfutils/tests/run-show-abbrev.sh
@@ -0,0 +1,352 @@
+#! /bin/sh
+# Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile testfile2
+
+testrun_compare ${abs_builddir}/show-abbrev testfile testfile2 <<\EOF
+abbrev[0]: code = 1, tag = 17, children = 1
+abbrev[0]: attr[0]: code = 16, form = 6, offset = 0
+abbrev[0]: attr[1]: code = 18, form = 1, offset = 2
+abbrev[0]: attr[2]: code = 17, form = 1, offset = 4
+abbrev[0]: attr[3]: code = 3, form = 8, offset = 6
+abbrev[0]: attr[4]: code = 27, form = 8, offset = 8
+abbrev[0]: attr[5]: code = 37, form = 8, offset = 10
+abbrev[0]: attr[6]: code = 19, form = 11, offset = 12
+abbrev[19]: code = 2, tag = 46, children = 1
+abbrev[19]: attr[0]: code = 1, form = 19, offset = 19
+abbrev[19]: attr[1]: code = 63, form = 12, offset = 21
+abbrev[19]: attr[2]: code = 3, form = 8, offset = 23
+abbrev[19]: attr[3]: code = 58, form = 11, offset = 25
+abbrev[19]: attr[4]: code = 59, form = 11, offset = 27
+abbrev[19]: attr[5]: code = 39, form = 12, offset = 29
+abbrev[19]: attr[6]: code = 73, form = 19, offset = 31
+abbrev[19]: attr[7]: code = 17, form = 1, offset = 33
+abbrev[19]: attr[8]: code = 18, form = 1, offset = 35
+abbrev[19]: attr[9]: code = 64, form = 10, offset = 37
+abbrev[44]: code = 3, tag = 46, children = 1
+abbrev[44]: attr[0]: code = 1, form = 19, offset = 44
+abbrev[44]: attr[1]: code = 63, form = 12, offset = 46
+abbrev[44]: attr[2]: code = 3, form = 8, offset = 48
+abbrev[44]: attr[3]: code = 58, form = 11, offset = 50
+abbrev[44]: attr[4]: code = 59, form = 11, offset = 52
+abbrev[44]: attr[5]: code = 73, form = 19, offset = 54
+abbrev[44]: attr[6]: code = 60, form = 12, offset = 56
+abbrev[63]: code = 4, tag = 24, children = 0
+abbrev[68]: code = 5, tag = 46, children = 1
+abbrev[68]: attr[0]: code = 63, form = 12, offset = 68
+abbrev[68]: attr[1]: code = 3, form = 8, offset = 70
+abbrev[68]: attr[2]: code = 58, form = 11, offset = 72
+abbrev[68]: attr[3]: code = 59, form = 11, offset = 74
+abbrev[68]: attr[4]: code = 73, form = 19, offset = 76
+abbrev[68]: attr[5]: code = 60, form = 12, offset = 78
+abbrev[85]: code = 6, tag = 36, children = 0
+abbrev[85]: attr[0]: code = 3, form = 8, offset = 85
+abbrev[85]: attr[1]: code = 11, form = 11, offset = 87
+abbrev[85]: attr[2]: code = 62, form = 11, offset = 89
+abbrev[96]: code = 7, tag = 52, children = 0
+abbrev[96]: attr[0]: code = 3, form = 8, offset = 96
+abbrev[96]: attr[1]: code = 58, form = 11, offset = 98
+abbrev[96]: attr[2]: code = 59, form = 11, offset = 100
+abbrev[96]: attr[3]: code = 73, form = 19, offset = 102
+abbrev[96]: attr[4]: code = 63, form = 12, offset = 104
+abbrev[96]: attr[5]: code = 2, form = 10, offset = 106
+abbrev[0]: code = 1, tag = 17, children = 1
+abbrev[0]: attr[0]: code = 16, form = 6, offset = 114
+abbrev[0]: attr[1]: code = 18, form = 1, offset = 116
+abbrev[0]: attr[2]: code = 17, form = 1, offset = 118
+abbrev[0]: attr[3]: code = 3, form = 8, offset = 120
+abbrev[0]: attr[4]: code = 27, form = 8, offset = 122
+abbrev[0]: attr[5]: code = 37, form = 8, offset = 124
+abbrev[0]: attr[6]: code = 19, form = 11, offset = 126
+abbrev[19]: code = 2, tag = 46, children = 0
+abbrev[19]: attr[0]: code = 63, form = 12, offset = 133
+abbrev[19]: attr[1]: code = 3, form = 8, offset = 135
+abbrev[19]: attr[2]: code = 58, form = 11, offset = 137
+abbrev[19]: attr[3]: code = 59, form = 11, offset = 139
+abbrev[19]: attr[4]: code = 39, form = 12, offset = 141
+abbrev[19]: attr[5]: code = 73, form = 19, offset = 143
+abbrev[19]: attr[6]: code = 17, form = 1, offset = 145
+abbrev[19]: attr[7]: code = 18, form = 1, offset = 147
+abbrev[19]: attr[8]: code = 64, form = 10, offset = 149
+abbrev[42]: code = 3, tag = 36, children = 0
+abbrev[42]: attr[0]: code = 3, form = 8, offset = 156
+abbrev[42]: attr[1]: code = 11, form = 11, offset = 158
+abbrev[42]: attr[2]: code = 62, form = 11, offset = 160
+abbrev[53]: code = 4, tag = 22, children = 0
+abbrev[53]: attr[0]: code = 3, form = 8, offset = 167
+abbrev[53]: attr[1]: code = 58, form = 11, offset = 169
+abbrev[53]: attr[2]: code = 59, form = 11, offset = 171
+abbrev[53]: attr[3]: code = 73, form = 19, offset = 173
+abbrev[66]: code = 5, tag = 15, children = 0
+abbrev[66]: attr[0]: code = 11, form = 11, offset = 180
+abbrev[73]: code = 6, tag = 15, children = 0
+abbrev[73]: attr[0]: code = 11, form = 11, offset = 187
+abbrev[73]: attr[1]: code = 73, form = 19, offset = 189
+abbrev[82]: code = 7, tag = 19, children = 1
+abbrev[82]: attr[0]: code = 1, form = 19, offset = 196
+abbrev[82]: attr[1]: code = 11, form = 11, offset = 198
+abbrev[82]: attr[2]: code = 58, form = 11, offset = 200
+abbrev[82]: attr[3]: code = 59, form = 11, offset = 202
+abbrev[95]: code = 8, tag = 13, children = 0
+abbrev[95]: attr[0]: code = 3, form = 8, offset = 209
+abbrev[95]: attr[1]: code = 58, form = 11, offset = 211
+abbrev[95]: attr[2]: code = 59, form = 11, offset = 213
+abbrev[95]: attr[3]: code = 73, form = 19, offset = 215
+abbrev[95]: attr[4]: code = 56, form = 10, offset = 217
+abbrev[110]: code = 9, tag = 1, children = 1
+abbrev[110]: attr[0]: code = 1, form = 19, offset = 224
+abbrev[110]: attr[1]: code = 73, form = 19, offset = 226
+abbrev[119]: code = 10, tag = 33, children = 0
+abbrev[119]: attr[0]: code = 73, form = 19, offset = 233
+abbrev[119]: attr[1]: code = 47, form = 11, offset = 235
+abbrev[128]: code = 11, tag = 19, children = 1
+abbrev[128]: attr[0]: code = 1, form = 19, offset = 242
+abbrev[128]: attr[1]: code = 3, form = 8, offset = 244
+abbrev[128]: attr[2]: code = 11, form = 11, offset = 246
+abbrev[128]: attr[3]: code = 58, form = 11, offset = 248
+abbrev[128]: attr[4]: code = 59, form = 11, offset = 250
+abbrev[143]: code = 12, tag = 19, children = 0
+abbrev[143]: attr[0]: code = 3, form = 8, offset = 257
+abbrev[143]: attr[1]: code = 60, form = 12, offset = 259
+abbrev[152]: code = 13, tag = 13, children = 0
+abbrev[152]: attr[0]: code = 3, form = 8, offset = 266
+abbrev[152]: attr[1]: code = 58, form = 11, offset = 268
+abbrev[152]: attr[2]: code = 59, form = 5, offset = 270
+abbrev[152]: attr[3]: code = 73, form = 19, offset = 272
+abbrev[152]: attr[4]: code = 56, form = 10, offset = 274
+abbrev[167]: code = 14, tag = 22, children = 0
+abbrev[167]: attr[0]: code = 3, form = 8, offset = 281
+abbrev[167]: attr[1]: code = 58, form = 11, offset = 283
+abbrev[167]: attr[2]: code = 59, form = 5, offset = 285
+abbrev[167]: attr[3]: code = 73, form = 19, offset = 287
+abbrev[180]: code = 15, tag = 23, children = 1
+abbrev[180]: attr[0]: code = 1, form = 19, offset = 294
+abbrev[180]: attr[1]: code = 11, form = 11, offset = 296
+abbrev[180]: attr[2]: code = 58, form = 11, offset = 298
+abbrev[180]: attr[3]: code = 59, form = 11, offset = 300
+abbrev[193]: code = 16, tag = 13, children = 0
+abbrev[193]: attr[0]: code = 3, form = 8, offset = 307
+abbrev[193]: attr[1]: code = 58, form = 11, offset = 309
+abbrev[193]: attr[2]: code = 59, form = 11, offset = 311
+abbrev[193]: attr[3]: code = 73, form = 19, offset = 313
+abbrev[206]: code = 17, tag = 4, children = 1
+abbrev[206]: attr[0]: code = 1, form = 19, offset = 320
+abbrev[206]: attr[1]: code = 11, form = 11, offset = 322
+abbrev[206]: attr[2]: code = 58, form = 11, offset = 324
+abbrev[206]: attr[3]: code = 59, form = 11, offset = 326
+abbrev[219]: code = 18, tag = 40, children = 0
+abbrev[219]: attr[0]: code = 3, form = 8, offset = 333
+abbrev[219]: attr[1]: code = 28, form = 11, offset = 335
+abbrev[228]: code = 19, tag = 38, children = 0
+abbrev[228]: attr[0]: code = 73, form = 19, offset = 342
+abbrev[235]: code = 20, tag = 21, children = 1
+abbrev[235]: attr[0]: code = 1, form = 19, offset = 349
+abbrev[235]: attr[1]: code = 39, form = 12, offset = 351
+abbrev[235]: attr[2]: code = 73, form = 19, offset = 353
+abbrev[246]: code = 21, tag = 5, children = 0
+abbrev[246]: attr[0]: code = 73, form = 19, offset = 360
+abbrev[253]: code = 22, tag = 21, children = 1
+abbrev[253]: attr[0]: code = 1, form = 19, offset = 367
+abbrev[253]: attr[1]: code = 39, form = 12, offset = 369
+abbrev[262]: code = 23, tag = 33, children = 0
+abbrev[262]: attr[0]: code = 73, form = 19, offset = 376
+abbrev[262]: attr[1]: code = 47, form = 6, offset = 378
+abbrev[271]: code = 24, tag = 22, children = 0
+abbrev[271]: attr[0]: code = 3, form = 8, offset = 385
+abbrev[271]: attr[1]: code = 58, form = 11, offset = 387
+abbrev[271]: attr[2]: code = 59, form = 11, offset = 389
+abbrev[282]: code = 25, tag = 4, children = 1
+abbrev[282]: attr[0]: code = 1, form = 19, offset = 396
+abbrev[282]: attr[1]: code = 3, form = 8, offset = 398
+abbrev[282]: attr[2]: code = 11, form = 11, offset = 400
+abbrev[282]: attr[3]: code = 58, form = 11, offset = 402
+abbrev[282]: attr[4]: code = 59, form = 11, offset = 404
+abbrev[0]: code = 1, tag = 17, children = 1
+abbrev[0]: attr[0]: code = 16, form = 6, offset = 412
+abbrev[0]: attr[1]: code = 18, form = 1, offset = 414
+abbrev[0]: attr[2]: code = 17, form = 1, offset = 416
+abbrev[0]: attr[3]: code = 3, form = 8, offset = 418
+abbrev[0]: attr[4]: code = 27, form = 8, offset = 420
+abbrev[0]: attr[5]: code = 37, form = 8, offset = 422
+abbrev[0]: attr[6]: code = 19, form = 11, offset = 424
+abbrev[19]: code = 2, tag = 46, children = 0
+abbrev[19]: attr[0]: code = 63, form = 12, offset = 431
+abbrev[19]: attr[1]: code = 3, form = 8, offset = 433
+abbrev[19]: attr[2]: code = 58, form = 11, offset = 435
+abbrev[19]: attr[3]: code = 59, form = 11, offset = 437
+abbrev[19]: attr[4]: code = 39, form = 12, offset = 439
+abbrev[19]: attr[5]: code = 73, form = 19, offset = 441
+abbrev[19]: attr[6]: code = 17, form = 1, offset = 443
+abbrev[19]: attr[7]: code = 18, form = 1, offset = 445
+abbrev[19]: attr[8]: code = 64, form = 10, offset = 447
+abbrev[42]: code = 3, tag = 36, children = 0
+abbrev[42]: attr[0]: code = 3, form = 8, offset = 454
+abbrev[42]: attr[1]: code = 11, form = 11, offset = 456
+abbrev[42]: attr[2]: code = 62, form = 11, offset = 458
+abbrev[0]: code = 1, tag = 17, children = 1
+abbrev[0]: attr[0]: code = 16, form = 6, offset = 0
+abbrev[0]: attr[1]: code = 18, form = 1, offset = 2
+abbrev[0]: attr[2]: code = 17, form = 1, offset = 4
+abbrev[0]: attr[3]: code = 3, form = 8, offset = 6
+abbrev[0]: attr[4]: code = 27, form = 8, offset = 8
+abbrev[0]: attr[5]: code = 37, form = 8, offset = 10
+abbrev[0]: attr[6]: code = 19, form = 11, offset = 12
+abbrev[19]: code = 2, tag = 46, children = 0
+abbrev[19]: attr[0]: code = 63, form = 12, offset = 19
+abbrev[19]: attr[1]: code = 3, form = 8, offset = 21
+abbrev[19]: attr[2]: code = 58, form = 11, offset = 23
+abbrev[19]: attr[3]: code = 59, form = 11, offset = 25
+abbrev[19]: attr[4]: code = 39, form = 12, offset = 27
+abbrev[19]: attr[5]: code = 73, form = 19, offset = 29
+abbrev[19]: attr[6]: code = 17, form = 1, offset = 31
+abbrev[19]: attr[7]: code = 18, form = 1, offset = 33
+abbrev[19]: attr[8]: code = 64, form = 10, offset = 35
+abbrev[42]: code = 3, tag = 36, children = 0
+abbrev[42]: attr[0]: code = 3, form = 8, offset = 42
+abbrev[42]: attr[1]: code = 11, form = 11, offset = 44
+abbrev[42]: attr[2]: code = 62, form = 11, offset = 46
+abbrev[53]: code = 4, tag = 22, children = 0
+abbrev[53]: attr[0]: code = 3, form = 8, offset = 53
+abbrev[53]: attr[1]: code = 58, form = 11, offset = 55
+abbrev[53]: attr[2]: code = 59, form = 11, offset = 57
+abbrev[53]: attr[3]: code = 73, form = 19, offset = 59
+abbrev[66]: code = 5, tag = 1, children = 1
+abbrev[66]: attr[0]: code = 1, form = 19, offset = 66
+abbrev[66]: attr[1]: code = 3, form = 8, offset = 68
+abbrev[66]: attr[2]: code = 73, form = 19, offset = 70
+abbrev[77]: code = 6, tag = 33, children = 0
+abbrev[77]: attr[0]: code = 73, form = 19, offset = 77
+abbrev[77]: attr[1]: code = 47, form = 11, offset = 79
+abbrev[86]: code = 7, tag = 19, children = 1
+abbrev[86]: attr[0]: code = 1, form = 19, offset = 86
+abbrev[86]: attr[1]: code = 3, form = 8, offset = 88
+abbrev[86]: attr[2]: code = 11, form = 11, offset = 90
+abbrev[86]: attr[3]: code = 58, form = 11, offset = 92
+abbrev[86]: attr[4]: code = 59, form = 11, offset = 94
+abbrev[101]: code = 8, tag = 13, children = 0
+abbrev[101]: attr[0]: code = 3, form = 8, offset = 101
+abbrev[101]: attr[1]: code = 58, form = 11, offset = 103
+abbrev[101]: attr[2]: code = 59, form = 11, offset = 105
+abbrev[101]: attr[3]: code = 73, form = 19, offset = 107
+abbrev[101]: attr[4]: code = 56, form = 10, offset = 109
+abbrev[116]: code = 9, tag = 15, children = 0
+abbrev[116]: attr[0]: code = 11, form = 11, offset = 116
+abbrev[123]: code = 10, tag = 15, children = 0
+abbrev[123]: attr[0]: code = 11, form = 11, offset = 123
+abbrev[123]: attr[1]: code = 73, form = 19, offset = 125
+abbrev[132]: code = 11, tag = 19, children = 1
+abbrev[132]: attr[0]: code = 1, form = 19, offset = 132
+abbrev[132]: attr[1]: code = 11, form = 11, offset = 134
+abbrev[132]: attr[2]: code = 58, form = 11, offset = 136
+abbrev[132]: attr[3]: code = 59, form = 11, offset = 138
+abbrev[145]: code = 12, tag = 1, children = 1
+abbrev[145]: attr[0]: code = 1, form = 19, offset = 145
+abbrev[145]: attr[1]: code = 73, form = 19, offset = 147
+abbrev[154]: code = 13, tag = 22, children = 0
+abbrev[154]: attr[0]: code = 3, form = 8, offset = 154
+abbrev[154]: attr[1]: code = 58, form = 11, offset = 156
+abbrev[154]: attr[2]: code = 59, form = 5, offset = 158
+abbrev[154]: attr[3]: code = 73, form = 19, offset = 160
+abbrev[167]: code = 14, tag = 19, children = 0
+abbrev[167]: attr[0]: code = 3, form = 8, offset = 167
+abbrev[167]: attr[1]: code = 60, form = 12, offset = 169
+abbrev[176]: code = 15, tag = 22, children = 0
+abbrev[176]: attr[0]: code = 3, form = 8, offset = 176
+abbrev[176]: attr[1]: code = 58, form = 11, offset = 178
+abbrev[176]: attr[2]: code = 59, form = 11, offset = 180
+abbrev[187]: code = 16, tag = 21, children = 1
+abbrev[187]: attr[0]: code = 1, form = 19, offset = 187
+abbrev[187]: attr[1]: code = 39, form = 12, offset = 189
+abbrev[187]: attr[2]: code = 73, form = 19, offset = 191
+abbrev[198]: code = 17, tag = 5, children = 0
+abbrev[198]: attr[0]: code = 73, form = 19, offset = 198
+abbrev[205]: code = 18, tag = 38, children = 0
+abbrev[205]: attr[0]: code = 73, form = 19, offset = 205
+abbrev[0]: code = 1, tag = 17, children = 1
+abbrev[0]: attr[0]: code = 16, form = 6, offset = 213
+abbrev[0]: attr[1]: code = 18, form = 1, offset = 215
+abbrev[0]: attr[2]: code = 17, form = 1, offset = 217
+abbrev[0]: attr[3]: code = 3, form = 8, offset = 219
+abbrev[0]: attr[4]: code = 27, form = 8, offset = 221
+abbrev[0]: attr[5]: code = 37, form = 8, offset = 223
+abbrev[0]: attr[6]: code = 19, form = 11, offset = 225
+abbrev[19]: code = 2, tag = 46, children = 0
+abbrev[19]: attr[0]: code = 63, form = 12, offset = 232
+abbrev[19]: attr[1]: code = 3, form = 8, offset = 234
+abbrev[19]: attr[2]: code = 58, form = 11, offset = 236
+abbrev[19]: attr[3]: code = 59, form = 11, offset = 238
+abbrev[19]: attr[4]: code = 39, form = 12, offset = 240
+abbrev[19]: attr[5]: code = 73, form = 19, offset = 242
+abbrev[19]: attr[6]: code = 17, form = 1, offset = 244
+abbrev[19]: attr[7]: code = 18, form = 1, offset = 246
+abbrev[19]: attr[8]: code = 64, form = 10, offset = 248
+abbrev[42]: code = 3, tag = 36, children = 0
+abbrev[42]: attr[0]: code = 3, form = 8, offset = 255
+abbrev[42]: attr[1]: code = 11, form = 11, offset = 257
+abbrev[42]: attr[2]: code = 62, form = 11, offset = 259
+abbrev[0]: code = 1, tag = 17, children = 1
+abbrev[0]: attr[0]: code = 16, form = 6, offset = 267
+abbrev[0]: attr[1]: code = 18, form = 1, offset = 269
+abbrev[0]: attr[2]: code = 17, form = 1, offset = 271
+abbrev[0]: attr[3]: code = 3, form = 8, offset = 273
+abbrev[0]: attr[4]: code = 27, form = 8, offset = 275
+abbrev[0]: attr[5]: code = 37, form = 8, offset = 277
+abbrev[0]: attr[6]: code = 19, form = 11, offset = 279
+abbrev[19]: code = 2, tag = 46, children = 1
+abbrev[19]: attr[0]: code = 1, form = 19, offset = 286
+abbrev[19]: attr[1]: code = 63, form = 12, offset = 288
+abbrev[19]: attr[2]: code = 3, form = 8, offset = 290
+abbrev[19]: attr[3]: code = 58, form = 11, offset = 292
+abbrev[19]: attr[4]: code = 59, form = 11, offset = 294
+abbrev[19]: attr[5]: code = 39, form = 12, offset = 296
+abbrev[19]: attr[6]: code = 73, form = 19, offset = 298
+abbrev[19]: attr[7]: code = 17, form = 1, offset = 300
+abbrev[19]: attr[8]: code = 18, form = 1, offset = 302
+abbrev[19]: attr[9]: code = 64, form = 10, offset = 304
+abbrev[44]: code = 3, tag = 46, children = 1
+abbrev[44]: attr[0]: code = 1, form = 19, offset = 311
+abbrev[44]: attr[1]: code = 63, form = 12, offset = 313
+abbrev[44]: attr[2]: code = 3, form = 8, offset = 315
+abbrev[44]: attr[3]: code = 58, form = 11, offset = 317
+abbrev[44]: attr[4]: code = 59, form = 11, offset = 319
+abbrev[44]: attr[5]: code = 73, form = 19, offset = 321
+abbrev[44]: attr[6]: code = 60, form = 12, offset = 323
+abbrev[63]: code = 4, tag = 24, children = 0
+abbrev[68]: code = 5, tag = 46, children = 1
+abbrev[68]: attr[0]: code = 63, form = 12, offset = 335
+abbrev[68]: attr[1]: code = 3, form = 8, offset = 337
+abbrev[68]: attr[2]: code = 58, form = 11, offset = 339
+abbrev[68]: attr[3]: code = 59, form = 11, offset = 341
+abbrev[68]: attr[4]: code = 73, form = 19, offset = 343
+abbrev[68]: attr[5]: code = 60, form = 12, offset = 345
+abbrev[85]: code = 6, tag = 36, children = 0
+abbrev[85]: attr[0]: code = 3, form = 8, offset = 352
+abbrev[85]: attr[1]: code = 11, form = 11, offset = 354
+abbrev[85]: attr[2]: code = 62, form = 11, offset = 356
+abbrev[96]: code = 7, tag = 52, children = 0
+abbrev[96]: attr[0]: code = 3, form = 8, offset = 363
+abbrev[96]: attr[1]: code = 58, form = 11, offset = 365
+abbrev[96]: attr[2]: code = 59, form = 11, offset = 367
+abbrev[96]: attr[3]: code = 73, form = 19, offset = 369
+abbrev[96]: attr[4]: code = 63, form = 12, offset = 371
+abbrev[96]: attr[5]: code = 2, form = 10, offset = 373
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-show-die-info.sh b/third_party/elfutils/tests/run-show-die-info.sh
new file mode 100755
index 0000000..f92ee48
--- /dev/null
+++ b/third_party/elfutils/tests/run-show-die-info.sh
@@ -0,0 +1,985 @@
+#! /bin/sh
+# Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile5 testfile2
+
+testrun_compare ${abs_builddir}/show-die-info testfile5 testfile2 <<\EOF
+file: testfile5
+New CU: off = 0, hsize = 11, ab = 0, as = 4, os = 4
+     DW_TAG_compile_unit
+      Name      : b.c
+      Offset    : 11
+      CU offset : 11
+      Attrs     : name stmt_list low_pc high_pc language comp_dir producer
+      low PC    : 0x804842c
+      high PC   : 0x8048436
+      language  : 1
+      directory : /home/drepper/gnu/new-bu/build/ttt
+      producer  : GNU C 2.96 20000731 (Red Hat Linux 7.0)
+          DW_TAG_subprogram
+           Name      : bar
+           Offset    : 104
+           CU offset : 104
+           Attrs     : name low_pc high_pc prototyped decl_file decl_line external frame_base type
+           low PC    : 0x804842c
+           high PC   : 0x8048436
+          DW_TAG_base_type
+           Name      : int
+           Offset    : 127
+           CU offset : 127
+           Attrs     : name byte_size encoding
+           byte size : 4
+New CU: off = 135, hsize = 11, ab = 54, as = 4, os = 4
+     DW_TAG_compile_unit
+      Name      : f.c
+      Offset    : 146
+      CU offset : 11
+      Attrs     : name stmt_list low_pc high_pc language comp_dir producer
+      low PC    : 0x8048438
+      high PC   : 0x8048442
+      language  : 1
+      directory : /home/drepper/gnu/new-bu/build/ttt
+      producer  : GNU C 2.96 20000731 (Red Hat Linux 7.0)
+          DW_TAG_subprogram
+           Name      : foo
+           Offset    : 239
+           CU offset : 104
+           Attrs     : name low_pc high_pc prototyped decl_file decl_line external frame_base type
+           low PC    : 0x8048438
+           high PC   : 0x8048442
+          DW_TAG_base_type
+           Name      : int
+           Offset    : 262
+           CU offset : 127
+           Attrs     : name byte_size encoding
+           byte size : 4
+New CU: off = 270, hsize = 11, ab = 108, as = 4, os = 4
+     DW_TAG_compile_unit
+      Name      : m.c
+      Offset    : 281
+      CU offset : 11
+      Attrs     : name stmt_list low_pc high_pc language comp_dir producer
+      low PC    : 0x8048444
+      high PC   : 0x8048472
+      language  : 1
+      directory : /home/drepper/gnu/new-bu/build/ttt
+      producer  : GNU C 2.96 20000731 (Red Hat Linux 7.0)
+          DW_TAG_subprogram
+           Name      : main
+           Offset    : 374
+           CU offset : 104
+           Attrs     : sibling name low_pc high_pc prototyped decl_file decl_line external frame_base type
+           low PC    : 0x8048444
+           high PC   : 0x8048472
+               DW_TAG_subprogram
+                Name      : bar
+                Offset    : 402
+                CU offset : 132
+                Attrs     : sibling name decl_file decl_line declaration external type
+                    DW_TAG_unspecified_parameters
+                     Name      : * NO NAME *
+                     Offset    : 419
+                     CU offset : 149
+                     Attrs     :
+               DW_TAG_subprogram
+                Name      : foo
+                Offset    : 421
+                CU offset : 151
+                Attrs     : name decl_file decl_line declaration external type
+                    DW_TAG_unspecified_parameters
+                     Name      : * NO NAME *
+                     Offset    : 434
+                     CU offset : 164
+                     Attrs     :
+          DW_TAG_base_type
+           Name      : int
+           Offset    : 437
+           CU offset : 167
+           Attrs     : name byte_size encoding
+           byte size : 4
+          DW_TAG_variable
+           Name      : a
+           Offset    : 444
+           CU offset : 174
+           Attrs     : location name decl_file decl_line external type
+file: testfile2
+New CU: off = 0, hsize = 11, ab = 0, as = 4, os = 4
+     DW_TAG_compile_unit
+      Name      : b.c
+      Offset    : 11
+      CU offset : 11
+      Attrs     : name stmt_list low_pc high_pc language comp_dir producer
+      low PC    : 0x10000470
+      high PC   : 0x10000490
+      language  : 1
+      directory : /shoggoth/drepper
+      producer  : GNU C 2.96-laurel-000912
+          DW_TAG_subprogram
+           Name      : bar
+           Offset    : 72
+           CU offset : 72
+           Attrs     : name low_pc high_pc prototyped decl_file decl_line external frame_base type
+           low PC    : 0x10000470
+           high PC   : 0x10000490
+          DW_TAG_base_type
+           Name      : int
+           Offset    : 95
+           CU offset : 95
+           Attrs     : name byte_size encoding
+           byte size : 4
+          DW_TAG_typedef
+           Name      : size_t
+           Offset    : 102
+           CU offset : 102
+           Attrs     : name decl_file decl_line type
+          DW_TAG_base_type
+           Name      : unsigned int
+           Offset    : 116
+           CU offset : 116
+           Attrs     : name byte_size encoding
+           byte size : 4
+          DW_TAG_typedef
+           Name      : __gnuc_va_list
+           Offset    : 132
+           CU offset : 132
+           Attrs     : name decl_file decl_line type
+          DW_TAG_array_type
+           Name      : __builtin_va_list
+           Offset    : 154
+           CU offset : 154
+           Attrs     : sibling name type
+               DW_TAG_subrange_type
+                Name      : * NO NAME *
+                Offset    : 181
+                CU offset : 181
+                Attrs     : upper_bound type
+          DW_TAG_base_type
+           Name      : unsigned int
+           Offset    : 188
+           CU offset : 188
+           Attrs     : name byte_size encoding
+           byte size : 4
+          DW_TAG_structure_type
+           Name      : __va_list_tag
+           Offset    : 204
+           CU offset : 204
+           Attrs     : sibling name byte_size decl_file decl_line
+           byte size : 12
+               DW_TAG_member
+                Name      : gpr
+                Offset    : 226
+                CU offset : 226
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : fpr
+                Offset    : 240
+                CU offset : 240
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : overflow_arg_area
+                Offset    : 254
+                CU offset : 254
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : reg_save_area
+                Offset    : 282
+                CU offset : 282
+                Attrs     : name data_member_location decl_file decl_line type
+          DW_TAG_base_type
+           Name      : unsigned char
+           Offset    : 307
+           CU offset : 307
+           Attrs     : name byte_size encoding
+           byte size : 1
+          DW_TAG_pointer_type
+           Name      : * NO NAME *
+           Offset    : 324
+           CU offset : 324
+           Attrs     : byte_size
+           byte size : 4
+          DW_TAG_typedef
+           Name      : __u_char
+           Offset    : 326
+           CU offset : 326
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __u_short
+           Offset    : 342
+           CU offset : 342
+           Attrs     : name decl_file decl_line type
+          DW_TAG_base_type
+           Name      : short unsigned int
+           Offset    : 359
+           CU offset : 359
+           Attrs     : name byte_size encoding
+           byte size : 2
+          DW_TAG_typedef
+           Name      : __u_int
+           Offset    : 381
+           CU offset : 381
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __u_long
+           Offset    : 396
+           CU offset : 396
+           Attrs     : name decl_file decl_line type
+          DW_TAG_base_type
+           Name      : long unsigned int
+           Offset    : 412
+           CU offset : 412
+           Attrs     : name byte_size encoding
+           byte size : 4
+          DW_TAG_typedef
+           Name      : __u_quad_t
+           Offset    : 433
+           CU offset : 433
+           Attrs     : name decl_file decl_line type
+          DW_TAG_base_type
+           Name      : long long unsigned int
+           Offset    : 451
+           CU offset : 451
+           Attrs     : name byte_size encoding
+           byte size : 8
+          DW_TAG_typedef
+           Name      : __quad_t
+           Offset    : 477
+           CU offset : 477
+           Attrs     : name decl_file decl_line type
+          DW_TAG_base_type
+           Name      : long long int
+           Offset    : 493
+           CU offset : 493
+           Attrs     : name byte_size encoding
+           byte size : 8
+          DW_TAG_typedef
+           Name      : __int8_t
+           Offset    : 510
+           CU offset : 510
+           Attrs     : name decl_file decl_line type
+          DW_TAG_base_type
+           Name      : signed char
+           Offset    : 526
+           CU offset : 526
+           Attrs     : name byte_size encoding
+           byte size : 1
+          DW_TAG_typedef
+           Name      : __uint8_t
+           Offset    : 541
+           CU offset : 541
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __int16_t
+           Offset    : 558
+           CU offset : 558
+           Attrs     : name decl_file decl_line type
+          DW_TAG_base_type
+           Name      : short int
+           Offset    : 575
+           CU offset : 575
+           Attrs     : name byte_size encoding
+           byte size : 2
+          DW_TAG_typedef
+           Name      : __uint16_t
+           Offset    : 588
+           CU offset : 588
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __int32_t
+           Offset    : 606
+           CU offset : 606
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __uint32_t
+           Offset    : 623
+           CU offset : 623
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __int64_t
+           Offset    : 641
+           CU offset : 641
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __uint64_t
+           Offset    : 658
+           CU offset : 658
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __qaddr_t
+           Offset    : 676
+           CU offset : 676
+           Attrs     : name decl_file decl_line type
+          DW_TAG_pointer_type
+           Name      : * NO NAME *
+           Offset    : 693
+           CU offset : 693
+           Attrs     : byte_size type
+           byte size : 4
+          DW_TAG_typedef
+           Name      : __dev_t
+           Offset    : 699
+           CU offset : 699
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __uid_t
+           Offset    : 714
+           CU offset : 714
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __gid_t
+           Offset    : 729
+           CU offset : 729
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __ino_t
+           Offset    : 744
+           CU offset : 744
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __mode_t
+           Offset    : 759
+           CU offset : 759
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __nlink_t
+           Offset    : 775
+           CU offset : 775
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __off_t
+           Offset    : 792
+           CU offset : 792
+           Attrs     : name decl_file decl_line type
+          DW_TAG_base_type
+           Name      : long int
+           Offset    : 807
+           CU offset : 807
+           Attrs     : name byte_size encoding
+           byte size : 4
+          DW_TAG_typedef
+           Name      : __loff_t
+           Offset    : 819
+           CU offset : 819
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __pid_t
+           Offset    : 835
+           CU offset : 835
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __ssize_t
+           Offset    : 850
+           CU offset : 850
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __rlim_t
+           Offset    : 867
+           CU offset : 867
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __rlim64_t
+           Offset    : 883
+           CU offset : 883
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __id_t
+           Offset    : 901
+           CU offset : 901
+           Attrs     : name decl_file decl_line type
+          DW_TAG_structure_type
+           Name      : * NO NAME *
+           Offset    : 915
+           CU offset : 915
+           Attrs     : sibling byte_size decl_file decl_line
+           byte size : 8
+               DW_TAG_member
+                Name      : __val
+                Offset    : 923
+                CU offset : 923
+                Attrs     : name data_member_location decl_file decl_line type
+          DW_TAG_array_type
+           Name      : * NO NAME *
+           Offset    : 940
+           CU offset : 940
+           Attrs     : sibling type
+               DW_TAG_subrange_type
+                Name      : * NO NAME *
+                Offset    : 949
+                CU offset : 949
+                Attrs     : upper_bound type
+          DW_TAG_typedef
+           Name      : __fsid_t
+           Offset    : 956
+           CU offset : 956
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __daddr_t
+           Offset    : 972
+           CU offset : 972
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __caddr_t
+           Offset    : 989
+           CU offset : 989
+           Attrs     : name decl_file decl_line type
+          DW_TAG_pointer_type
+           Name      : * NO NAME *
+           Offset    : 1006
+           CU offset : 1006
+           Attrs     : byte_size type
+           byte size : 4
+          DW_TAG_base_type
+           Name      : char
+           Offset    : 1012
+           CU offset : 1012
+           Attrs     : name byte_size encoding
+           byte size : 1
+          DW_TAG_typedef
+           Name      : __time_t
+           Offset    : 1020
+           CU offset : 1020
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __swblk_t
+           Offset    : 1036
+           CU offset : 1036
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __clock_t
+           Offset    : 1053
+           CU offset : 1053
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __fd_mask
+           Offset    : 1070
+           CU offset : 1070
+           Attrs     : name decl_file decl_line type
+          DW_TAG_structure_type
+           Name      : * NO NAME *
+           Offset    : 1087
+           CU offset : 1087
+           Attrs     : sibling byte_size decl_file decl_line
+           byte size : 128
+               DW_TAG_member
+                Name      : __fds_bits
+                Offset    : 1095
+                CU offset : 1095
+                Attrs     : name data_member_location decl_file decl_line type
+          DW_TAG_array_type
+           Name      : * NO NAME *
+           Offset    : 1117
+           CU offset : 1117
+           Attrs     : sibling type
+               DW_TAG_subrange_type
+                Name      : * NO NAME *
+                Offset    : 1126
+                CU offset : 1126
+                Attrs     : upper_bound type
+          DW_TAG_typedef
+           Name      : __fd_set
+           Offset    : 1133
+           CU offset : 1133
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __key_t
+           Offset    : 1149
+           CU offset : 1149
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __ipc_pid_t
+           Offset    : 1164
+           CU offset : 1164
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __blkcnt_t
+           Offset    : 1183
+           CU offset : 1183
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __blkcnt64_t
+           Offset    : 1201
+           CU offset : 1201
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __fsblkcnt_t
+           Offset    : 1221
+           CU offset : 1221
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __fsblkcnt64_t
+           Offset    : 1241
+           CU offset : 1241
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __fsfilcnt_t
+           Offset    : 1263
+           CU offset : 1263
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __fsfilcnt64_t
+           Offset    : 1283
+           CU offset : 1283
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __ino64_t
+           Offset    : 1305
+           CU offset : 1305
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __off64_t
+           Offset    : 1322
+           CU offset : 1322
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __t_scalar_t
+           Offset    : 1339
+           CU offset : 1339
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __t_uscalar_t
+           Offset    : 1359
+           CU offset : 1359
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : __intptr_t
+           Offset    : 1380
+           CU offset : 1380
+           Attrs     : name decl_file decl_line type
+          DW_TAG_structure_type
+           Name      : _IO_FILE
+           Offset    : 1398
+           CU offset : 1398
+           Attrs     : sibling name byte_size decl_file decl_line
+           byte size : 152
+               DW_TAG_member
+                Name      : _flags
+                Offset    : 1415
+                CU offset : 1415
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _IO_read_ptr
+                Offset    : 1432
+                CU offset : 1432
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _IO_read_end
+                Offset    : 1455
+                CU offset : 1455
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _IO_read_base
+                Offset    : 1478
+                CU offset : 1478
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _IO_write_base
+                Offset    : 1502
+                CU offset : 1502
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _IO_write_ptr
+                Offset    : 1527
+                CU offset : 1527
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _IO_write_end
+                Offset    : 1551
+                CU offset : 1551
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _IO_buf_base
+                Offset    : 1575
+                CU offset : 1575
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _IO_buf_end
+                Offset    : 1598
+                CU offset : 1598
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _IO_save_base
+                Offset    : 1620
+                CU offset : 1620
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _IO_backup_base
+                Offset    : 1644
+                CU offset : 1644
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _IO_save_end
+                Offset    : 1670
+                CU offset : 1670
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _markers
+                Offset    : 1693
+                CU offset : 1693
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _chain
+                Offset    : 1712
+                CU offset : 1712
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _fileno
+                Offset    : 1729
+                CU offset : 1729
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _blksize
+                Offset    : 1747
+                CU offset : 1747
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _old_offset
+                Offset    : 1766
+                CU offset : 1766
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _cur_column
+                Offset    : 1788
+                CU offset : 1788
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _vtable_offset
+                Offset    : 1810
+                CU offset : 1810
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _shortbuf
+                Offset    : 1835
+                CU offset : 1835
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _lock
+                Offset    : 1855
+                CU offset : 1855
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _offset
+                Offset    : 1871
+                CU offset : 1871
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _unused2
+                Offset    : 1889
+                CU offset : 1889
+                Attrs     : name data_member_location decl_file decl_line type
+          DW_TAG_structure_type
+           Name      : _IO_marker
+           Offset    : 1909
+           CU offset : 1909
+           Attrs     : sibling name byte_size decl_file decl_line
+           byte size : 12
+               DW_TAG_member
+                Name      : _next
+                Offset    : 1928
+                CU offset : 1928
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _sbuf
+                Offset    : 1944
+                CU offset : 1944
+                Attrs     : name data_member_location decl_file decl_line type
+               DW_TAG_member
+                Name      : _pos
+                Offset    : 1960
+                CU offset : 1960
+                Attrs     : name data_member_location decl_file decl_line type
+          DW_TAG_pointer_type
+           Name      : * NO NAME *
+           Offset    : 1976
+           CU offset : 1976
+           Attrs     : byte_size type
+           byte size : 4
+          DW_TAG_pointer_type
+           Name      : * NO NAME *
+           Offset    : 1982
+           CU offset : 1982
+           Attrs     : byte_size type
+           byte size : 4
+          DW_TAG_array_type
+           Name      : * NO NAME *
+           Offset    : 1988
+           CU offset : 1988
+           Attrs     : sibling type
+               DW_TAG_subrange_type
+                Name      : * NO NAME *
+                Offset    : 1997
+                CU offset : 1997
+                Attrs     : upper_bound type
+          DW_TAG_pointer_type
+           Name      : * NO NAME *
+           Offset    : 2004
+           CU offset : 2004
+           Attrs     : byte_size
+           byte size : 4
+          DW_TAG_array_type
+           Name      : * NO NAME *
+           Offset    : 2006
+           CU offset : 2006
+           Attrs     : sibling type
+               DW_TAG_subrange_type
+                Name      : * NO NAME *
+                Offset    : 2015
+                CU offset : 2015
+                Attrs     : upper_bound type
+          DW_TAG_typedef
+           Name      : FILE
+           Offset    : 2022
+           CU offset : 2022
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : wchar_t
+           Offset    : 2034
+           CU offset : 2034
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : wint_t
+           Offset    : 2050
+           CU offset : 2050
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : _G_int16_t
+           Offset    : 2065
+           CU offset : 2065
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : _G_int32_t
+           Offset    : 2083
+           CU offset : 2083
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : _G_uint16_t
+           Offset    : 2101
+           CU offset : 2101
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : _G_uint32_t
+           Offset    : 2120
+           CU offset : 2120
+           Attrs     : name decl_file decl_line type
+          DW_TAG_structure_type
+           Name      : _IO_jump_t
+           Offset    : 2139
+           CU offset : 2139
+           Attrs     : name declaration
+          DW_TAG_typedef
+           Name      : _IO_lock_t
+           Offset    : 2152
+           CU offset : 2152
+           Attrs     : name decl_file decl_line
+          DW_TAG_typedef
+           Name      : _IO_FILE
+           Offset    : 2166
+           CU offset : 2166
+           Attrs     : name decl_file decl_line type
+          DW_TAG_structure_type
+           Name      : _IO_FILE_plus
+           Offset    : 2182
+           CU offset : 2182
+           Attrs     : name declaration
+          DW_TAG_typedef
+           Name      : __io_read_fn
+           Offset    : 2198
+           CU offset : 2198
+           Attrs     : name decl_file decl_line type
+          DW_TAG_subroutine_type
+           Name      : * NO NAME *
+           Offset    : 2219
+           CU offset : 2219
+           Attrs     : sibling prototyped type
+               DW_TAG_formal_parameter
+                Name      : * NO NAME *
+                Offset    : 2229
+                CU offset : 2229
+                Attrs     : type
+               DW_TAG_formal_parameter
+                Name      : * NO NAME *
+                Offset    : 2234
+                CU offset : 2234
+                Attrs     : type
+               DW_TAG_formal_parameter
+                Name      : * NO NAME *
+                Offset    : 2239
+                CU offset : 2239
+                Attrs     : type
+          DW_TAG_typedef
+           Name      : __io_write_fn
+           Offset    : 2245
+           CU offset : 2245
+           Attrs     : name decl_file decl_line type
+          DW_TAG_subroutine_type
+           Name      : * NO NAME *
+           Offset    : 2267
+           CU offset : 2267
+           Attrs     : sibling prototyped type
+               DW_TAG_formal_parameter
+                Name      : * NO NAME *
+                Offset    : 2277
+                CU offset : 2277
+                Attrs     : type
+               DW_TAG_formal_parameter
+                Name      : * NO NAME *
+                Offset    : 2282
+                CU offset : 2282
+                Attrs     : type
+               DW_TAG_formal_parameter
+                Name      : * NO NAME *
+                Offset    : 2287
+                CU offset : 2287
+                Attrs     : type
+          DW_TAG_pointer_type
+           Name      : * NO NAME *
+           Offset    : 2293
+           CU offset : 2293
+           Attrs     : byte_size type
+           byte size : 4
+          DW_TAG_const_type
+           Name      : * NO NAME *
+           Offset    : 2299
+           CU offset : 2299
+           Attrs     : type
+          DW_TAG_typedef
+           Name      : __io_seek_fn
+           Offset    : 2304
+           CU offset : 2304
+           Attrs     : name decl_file decl_line type
+          DW_TAG_subroutine_type
+           Name      : * NO NAME *
+           Offset    : 2325
+           CU offset : 2325
+           Attrs     : sibling prototyped type
+               DW_TAG_formal_parameter
+                Name      : * NO NAME *
+                Offset    : 2335
+                CU offset : 2335
+                Attrs     : type
+               DW_TAG_formal_parameter
+                Name      : * NO NAME *
+                Offset    : 2340
+                CU offset : 2340
+                Attrs     : type
+               DW_TAG_formal_parameter
+                Name      : * NO NAME *
+                Offset    : 2345
+                CU offset : 2345
+                Attrs     : type
+          DW_TAG_typedef
+           Name      : __io_close_fn
+           Offset    : 2351
+           CU offset : 2351
+           Attrs     : name decl_file decl_line type
+          DW_TAG_subroutine_type
+           Name      : * NO NAME *
+           Offset    : 2373
+           CU offset : 2373
+           Attrs     : sibling prototyped type
+               DW_TAG_formal_parameter
+                Name      : * NO NAME *
+                Offset    : 2383
+                CU offset : 2383
+                Attrs     : type
+          DW_TAG_typedef
+           Name      : fpos_t
+           Offset    : 2389
+           CU offset : 2389
+           Attrs     : name decl_file decl_line type
+          DW_TAG_typedef
+           Name      : off_t
+           Offset    : 2403
+           CU offset : 2403
+           Attrs     : name decl_file decl_line type
+New CU: off = 2418, hsize = 11, ab = 213, as = 4, os = 4
+     DW_TAG_compile_unit
+      Name      : f.c
+      Offset    : 2429
+      CU offset : 11
+      Attrs     : name stmt_list low_pc high_pc language comp_dir producer
+      low PC    : 0x10000490
+      high PC   : 0x100004b0
+      language  : 1
+      directory : /shoggoth/drepper
+      producer  : GNU C 2.96-laurel-000912
+          DW_TAG_subprogram
+           Name      : foo
+           Offset    : 2490
+           CU offset : 72
+           Attrs     : name low_pc high_pc prototyped decl_file decl_line external frame_base type
+           low PC    : 0x10000490
+           high PC   : 0x100004b0
+          DW_TAG_base_type
+           Name      : int
+           Offset    : 2513
+           CU offset : 95
+           Attrs     : name byte_size encoding
+           byte size : 4
+New CU: off = 2521, hsize = 11, ab = 267, as = 4, os = 4
+     DW_TAG_compile_unit
+      Name      : m.c
+      Offset    : 2532
+      CU offset : 11
+      Attrs     : name stmt_list low_pc high_pc language comp_dir producer
+      low PC    : 0x100004b0
+      high PC   : 0x10000514
+      language  : 1
+      directory : /shoggoth/drepper
+      producer  : GNU C 2.96-laurel-000912
+          DW_TAG_subprogram
+           Name      : main
+           Offset    : 2593
+           CU offset : 72
+           Attrs     : sibling name low_pc high_pc prototyped decl_file decl_line external frame_base type
+           low PC    : 0x100004b0
+           high PC   : 0x10000514
+               DW_TAG_subprogram
+                Name      : bar
+                Offset    : 2621
+                CU offset : 100
+                Attrs     : sibling name decl_file decl_line declaration external type
+                    DW_TAG_unspecified_parameters
+                     Name      : * NO NAME *
+                     Offset    : 2638
+                     CU offset : 117
+                     Attrs     :
+               DW_TAG_subprogram
+                Name      : foo
+                Offset    : 2640
+                CU offset : 119
+                Attrs     : name decl_file decl_line declaration external type
+                    DW_TAG_unspecified_parameters
+                     Name      : * NO NAME *
+                     Offset    : 2653
+                     CU offset : 132
+                     Attrs     :
+          DW_TAG_base_type
+           Name      : int
+           Offset    : 2656
+           CU offset : 135
+           Attrs     : name byte_size encoding
+           byte size : 4
+          DW_TAG_variable
+           Name      : a
+           Offset    : 2663
+           CU offset : 142
+           Attrs     : location name decl_file decl_line external type
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-stack-d-test.sh b/third_party/elfutils/tests/run-stack-d-test.sh
new file mode 100755
index 0000000..a9f0380
--- /dev/null
+++ b/third_party/elfutils/tests/run-stack-d-test.sh
@@ -0,0 +1,122 @@
+#! /bin/sh
+# Copyright (C) 2014, 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# // g++ dwarfinlines.cpp -g -o testfiledwarfinlines -O2
+# int
+# fubar (int x)
+# {
+#   __asm__ ( "nop" ::: );
+#   return 42 / x - 2;
+# }
+#
+# void foobar (int z1, int z2)
+# {
+#   __asm__ ( "nop" ::: );
+#   int x = z1 + z2;
+#   while (z1 + x + 1 != 42)
+#     x = fubar (z1 + z2 + x);
+# }
+#
+# void bar (int z)
+# {
+#   int a, b;
+#   a = b = z / 2;
+#   foobar(a, b);
+# }
+#
+# void foo (int x)
+# {
+#   if (x > 0)
+#     bar(x - 2);
+# }
+#
+# void fu (int y)
+# {
+#   __asm__ ( "nop" ::: );
+#   foo (y + 1);
+# }
+#
+# int
+# main (int argc, char **argv)
+# {
+#   fu (argc);
+# }
+testfiles testfiledwarfinlines testfiledwarfinlines.core
+
+# Depending on whether we are running make check or make installcheck
+# the actual binary name under test might be different. It is used in
+# the error message, which we also try to match.
+if test "$elfutils_testrun" = "installed"; then
+STACKCMD=${bindir}/`program_transform stack`
+else
+STACKCMD=${abs_top_builddir}/src/stack
+fi
+
+# Disable valgrind while dumping because of a bug unmapping libc.so.
+# https://bugs.kde.org/show_bug.cgi?id=327427
+SAVED_VALGRIND_CMD="$VALGRIND_CMD"
+unset VALGRIND_CMD
+
+# Without -d the top function comes out as fu. Use --raw to not demangle.
+testrun_compare ${abs_top_builddir}/src/stack -r -n 2 -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0  0x00000000004006c8 _Z2fui
+#1  0x00000000004004c5 main
+$STACKCMD: tid 13654: shown max number of frames (2, use -n 0 for unlimited)
+EOF
+
+# But when asking for source we see it is actually on line 6.
+# (Which is in function fubar, not fu). Use --raw to not demangle.
+testrun_compare ${abs_top_builddir}/src/stack -r -n 2 -s -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0  0x00000000004006c8 _Z2fui
+    /home/mark/src/tests/dwarfinlines.cpp:6
+#1  0x00000000004004c5 main
+    /home/mark/src/tests/dwarfinlines.cpp:39
+$STACKCMD: tid 13654: shown max number of frames (2, use -n 0 for unlimited)
+EOF
+
+# So with --debugname we get the function correct as fubar.
+testrun_compare ${abs_top_builddir}/src/stack -n 2 -d -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0  0x00000000004006c8 fubar
+#1  0x00000000004004c5 main
+$STACKCMD: tid 13654: shown max number of frames (2, use -n 0 for unlimited)
+EOF
+
+# Which now matches the source line (again 6 of course).
+testrun_compare ${abs_top_builddir}/src/stack -n 2 -s -d -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0  0x00000000004006c8 fubar
+    /home/mark/src/tests/dwarfinlines.cpp:6
+#1  0x00000000004004c5 main
+    /home/mark/src/tests/dwarfinlines.cpp:39
+$STACKCMD: tid 13654: shown max number of frames (2, use -n 0 for unlimited)
+EOF
+
+if [ "x$SAVED_VALGRIND_CMD" != "x" ]; then
+  VALGRIND_CMD="$SAVED_VALGRIND_CMD"
+  export VALGRIND_CMD
+fi
+
+exit 0
diff --git a/third_party/elfutils/tests/run-stack-demangled-test.sh b/third_party/elfutils/tests/run-stack-demangled-test.sh
new file mode 100755
index 0000000..c26918f
--- /dev/null
+++ b/third_party/elfutils/tests/run-stack-demangled-test.sh
@@ -0,0 +1,105 @@
+#! /bin/sh
+# Copyright (C) 2014, 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if test -n "$ELFUTILS_DISABLE_DEMANGLE"; then
+  echo "demangler unsupported"
+  exit 77
+fi
+
+. $srcdir/test-subr.sh
+
+# See run-stack-d-test.sh and run-stack-i-test.sh
+# Same tests, now with demangler support, no -r, and without -d.
+# Only change in output is an explit fu(int) instead of _Z2fui.
+
+testfiles testfiledwarfinlines testfiledwarfinlines.core
+
+# Depending on whether we are running make check or make installcheck
+# the actual binary name under test might be different. It is used in
+# the error message, which we also try to match.
+if test "$elfutils_testrun" = "installed"; then
+STACKCMD=${bindir}/`program_transform stack`
+else
+STACKCMD=${abs_top_builddir}/src/stack
+fi
+
+# Disable valgrind while dumping because of a bug unmapping libc.so.
+# https://bugs.kde.org/show_bug.cgi?id=327427
+SAVED_VALGRIND_CMD="$VALGRIND_CMD"
+unset VALGRIND_CMD
+
+# Without -d the top function comes out as fu.
+testrun_compare ${abs_top_builddir}/src/stack -n 2 -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0  0x00000000004006c8 fu(int)
+#1  0x00000000004004c5 main
+$STACKCMD: tid 13654: shown max number of frames (2, use -n 0 for unlimited)
+EOF
+
+# But when asking for source we see it is actually on line 6.
+# (Which is in function fubar, not fu).
+testrun_compare ${abs_top_builddir}/src/stack -n 2 -s -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0  0x00000000004006c8 fu(int)
+    /home/mark/src/tests/dwarfinlines.cpp:6
+#1  0x00000000004004c5 main
+    /home/mark/src/tests/dwarfinlines.cpp:39
+$STACKCMD: tid 13654: shown max number of frames (2, use -n 0 for unlimited)
+EOF
+
+# With --inlines we get all inlined calls. Note they share the same
+# address.
+testrun_compare ${abs_top_builddir}/src/stack -n 6 -i -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0  0x00000000004006c8 fubar
+#1  0x00000000004006c8 foobar
+#2  0x00000000004006c8 bar
+#3  0x00000000004006c8 foo
+#4  0x00000000004006c8 fu(int)
+#5  0x00000000004004c5 main
+$STACKCMD: tid 13654: shown max number of frames (6, use -n 0 for unlimited)
+EOF
+
+# With --source we can also see where in the source the inlined frames
+# where originally called from.
+testrun_compare ${abs_top_builddir}/src/stack -n 6 -s -i -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0  0x00000000004006c8 fubar
+    /home/mark/src/tests/dwarfinlines.cpp:6
+#1  0x00000000004006c8 foobar
+    /home/mark/src/tests/dwarfinlines.cpp:14
+#2  0x00000000004006c8 bar
+    /home/mark/src/tests/dwarfinlines.cpp:21
+#3  0x00000000004006c8 foo
+    /home/mark/src/tests/dwarfinlines.cpp:27
+#4  0x00000000004006c8 fu(int)
+    /home/mark/src/tests/dwarfinlines.cpp:33
+#5  0x00000000004004c5 main
+    /home/mark/src/tests/dwarfinlines.cpp:39
+$STACKCMD: tid 13654: shown max number of frames (6, use -n 0 for unlimited)
+EOF
+
+if [ "x$SAVED_VALGRIND_CMD" != "x" ]; then
+  VALGRIND_CMD="$SAVED_VALGRIND_CMD"
+  export VALGRIND_CMD
+fi
+
+exit 0
diff --git a/third_party/elfutils/tests/run-stack-i-test.sh b/third_party/elfutils/tests/run-stack-i-test.sh
new file mode 100755
index 0000000..3722ab0
--- /dev/null
+++ b/third_party/elfutils/tests/run-stack-i-test.sh
@@ -0,0 +1,81 @@
+#! /bin/sh
+# Copyright (C) 2014, 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# See run-stack-d-test.sh for dwarfinlines.cpp source.
+testfiles testfiledwarfinlines testfiledwarfinlines.core
+
+# Depending on whether we are running make check or make installcheck
+# the actual binary name under test might be different. It is used in
+# the error message, which we also try to match.
+if test "$elfutils_testrun" = "installed"; then
+STACKCMD=${bindir}/`program_transform stack`
+else
+STACKCMD=${abs_top_builddir}/src/stack
+fi
+
+# Disable valgrind while dumping because of a bug unmapping libc.so.
+# https://bugs.kde.org/show_bug.cgi?id=327427
+SAVED_VALGRIND_CMD="$VALGRIND_CMD"
+unset VALGRIND_CMD
+
+# Compare with run-stack-d-test.sh to see the output without --inlines.
+# Only two call frames are visible (there is a jump from main to fu or
+# fubar). Explicitly use --raw so demangler support being configured in
+# doesn't change the results.
+
+# With --inlines we get all inlined calls. Note they share the same
+# address.
+testrun_compare ${abs_top_builddir}/src/stack -r -n 6 -i -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0  0x00000000004006c8 fubar
+#1  0x00000000004006c8 foobar
+#2  0x00000000004006c8 bar
+#3  0x00000000004006c8 foo
+#4  0x00000000004006c8 _Z2fui
+#5  0x00000000004004c5 main
+$STACKCMD: tid 13654: shown max number of frames (6, use -n 0 for unlimited)
+EOF
+
+# With --source we can also see where in the source the inlined frames
+# where originally called from.
+testrun_compare ${abs_top_builddir}/src/stack -r -n 6 -s -i -e testfiledwarfinlines --core testfiledwarfinlines.core<<EOF
+PID 13654 - core
+TID 13654:
+#0  0x00000000004006c8 fubar
+    /home/mark/src/tests/dwarfinlines.cpp:6
+#1  0x00000000004006c8 foobar
+    /home/mark/src/tests/dwarfinlines.cpp:14
+#2  0x00000000004006c8 bar
+    /home/mark/src/tests/dwarfinlines.cpp:21
+#3  0x00000000004006c8 foo
+    /home/mark/src/tests/dwarfinlines.cpp:27
+#4  0x00000000004006c8 _Z2fui
+    /home/mark/src/tests/dwarfinlines.cpp:33
+#5  0x00000000004004c5 main
+    /home/mark/src/tests/dwarfinlines.cpp:39
+$STACKCMD: tid 13654: shown max number of frames (6, use -n 0 for unlimited)
+EOF
+
+if [ "x$SAVED_VALGRIND_CMD" != "x" ]; then
+  VALGRIND_CMD="$SAVED_VALGRIND_CMD"
+  export VALGRIND_CMD
+fi
+
+exit 0
diff --git a/third_party/elfutils/tests/run-strings-test.sh b/third_party/elfutils/tests/run-strings-test.sh
new file mode 100755
index 0000000..33f2d64
--- /dev/null
+++ b/third_party/elfutils/tests/run-strings-test.sh
@@ -0,0 +1,470 @@
+#! /bin/sh
+# Copyright (C) 2005, 2006, 2008 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 2005.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+files="testfile `seq 2 9 | while read n; do echo testfile$n; done`"
+testfiles $files
+
+testrun_compare ${abs_top_builddir}/src/strings -tx -f $files <<\EOF
+testfile:      f4 /lib/ld-linux.so.2
+testfile:     1c9 __gmon_start__
+testfile:     1d8 libc.so.6
+testfile:     1e2 __cxa_finalize
+testfile:     1f1 __deregister_frame_info
+testfile:     209 _IO_stdin_used
+testfile:     218 __libc_start_main
+testfile:     22a __register_frame_info
+testfile:     240 GLIBC_2.1.3
+testfile:     24c GLIBC_2.0
+testfile:     338 PTRh
+testfile:     345 QVh,
+testfile2:     114 /lib/ld.so.1
+testfile2:     1f1 __gmon_start__
+testfile2:     200 __deregister_frame_info
+testfile2:     218 __register_frame_info
+testfile2:     22e libc.so.6
+testfile2:     238 __cxa_finalize
+testfile2:     247 _IO_stdin_used
+testfile2:     256 __libc_start_main
+testfile2:     268 GLIBC_2.1.3
+testfile2:     274 GLIBC_2.0
+testfile2:     488 }a[xN
+testfile2:     4a8 }a[xN
+testfile2:     50c }a[xN
+testfile2:     540 }?Kx
+testfile3:      f4 /lib/ld-linux.so.2
+testfile3:     1c9 __gmon_start__
+testfile3:     1d8 libc.so.6
+testfile3:     1e2 __cxa_finalize
+testfile3:     1f1 __deregister_frame_info
+testfile3:     209 _IO_stdin_used
+testfile3:     218 __libc_start_main
+testfile3:     22a __register_frame_info
+testfile3:     240 GLIBC_2.1.3
+testfile3:     24c GLIBC_2.0
+testfile3:     338 PTRh
+testfile3:     345 QVh,
+testfile4:      f4 /lib/ld-linux.so.2
+testfile4:     8e1 __gmon_start__
+testfile4:     8f0 __terminate_func
+testfile4:     901 stderr
+testfile4:     908 __tf9type_info
+testfile4:     917 __tf16__user_type_info
+testfile4:     92e __tf19__pointer_type_info
+testfile4:     948 __tf16__attr_type_info
+testfile4:     95f __tf16__func_type_info
+testfile4:     976 __vt_9type_info
+testfile4:     986 __vt_19__pointer_type_info
+testfile4:     9a1 __vt_16__attr_type_info
+testfile4:     9b9 __vt_16__func_type_info
+testfile4:     9d1 __vt_16__ptmf_type_info
+testfile4:     9e9 __vt_16__ptmd_type_info
+testfile4:     a01 __vt_17__array_type_info
+testfile4:     a1a __tiv
+testfile4:     a20 __vt_19__builtin_type_info
+testfile4:     a3b __tix
+testfile4:     a41 __til
+testfile4:     a47 __tii
+testfile4:     a4d __tis
+testfile4:     a53 __tib
+testfile4:     a59 __tic
+testfile4:     a5f __tiw
+testfile4:     a65 __tir
+testfile4:     a6b __tid
+testfile4:     a71 __tif
+testfile4:     a77 __tiUi
+testfile4:     a7e __tiUl
+testfile4:     a85 __tiUx
+testfile4:     a8c __tiUs
+testfile4:     a93 __tiUc
+testfile4:     a9a __tiSc
+testfile4:     aa1 __ti19__pointer_type_info
+testfile4:     abb __ti9type_info
+testfile4:     aca __ti16__attr_type_info
+testfile4:     ae1 __ti19__builtin_type_info
+testfile4:     afb __ti16__func_type_info
+testfile4:     b12 __ti16__ptmf_type_info
+testfile4:     b29 __ti16__ptmd_type_info
+testfile4:     b40 __ti17__array_type_info
+testfile4:     b58 __cplus_type_matcher
+testfile4:     b6d __vt_13bad_exception
+testfile4:     b82 __vt_9exception
+testfile4:     b92 _._13bad_exception
+testfile4:     ba5 __vt_8bad_cast
+testfile4:     bb4 _._8bad_cast
+testfile4:     bc1 __vt_10bad_typeid
+testfile4:     bd3 _._10bad_typeid
+testfile4:     be3 __ti9exception
+testfile4:     bf2 __ti13bad_exception
+testfile4:     c06 __vt_16__user_type_info
+testfile4:     c1e __vt_17__class_type_info
+testfile4:     c37 __vt_14__si_type_info
+testfile4:     c4d __ti8bad_cast
+testfile4:     c5b __ti10bad_typeid
+testfile4:     c6c __ti16__user_type_info
+testfile4:     c83 __ti14__si_type_info
+testfile4:     c98 __ti17__class_type_info
+testfile4:     cb0 libc.so.6
+testfile4:     cba __register_frame
+testfile4:     ccb pthread_create
+testfile4:     cda pthread_getspecific
+testfile4:     cee pthread_key_delete
+testfile4:     d01 __cxa_finalize
+testfile4:     d10 malloc
+testfile4:     d17 __frame_state_for
+testfile4:     d29 abort
+testfile4:     d2f __register_frame_table
+testfile4:     d46 fprintf
+testfile4:     d4e pthread_once
+testfile4:     d5b __deregister_frame_info
+testfile4:     d73 pthread_key_create
+testfile4:     d86 memset
+testfile4:     d8d strcmp
+testfile4:     d94 pthread_mutex_unlock
+testfile4:     da9 __deregister_frame
+testfile4:     dbc pthread_mutex_lock
+testfile4:     dcf _IO_stdin_used
+testfile4:     dde __libc_start_main
+testfile4:     df0 strlen
+testfile4:     df7 __register_frame_info_table
+testfile4:     e13 __register_frame_info
+testfile4:     e29 pthread_setspecific
+testfile4:     e3d free
+testfile4:     e42 GLIBC_2.1.3
+testfile4:     e4e GLIBC_2.0
+testfile4:    1308 PTRh<
+testfile4:    194b [^_]
+testfile4:    19bf [^_]
+testfile4:    1dd9 wT9L>
+testfile4:    1f3b [^_]
+testfile4:    1fae [^_]
+testfile4:    21c1 BZQRP
+testfile4:    237f [^_]
+testfile4:    2431 JWRV
+testfile4:    2454 [^_]
+testfile4:    2506 JWRV
+testfile4:    2529 [^_]
+testfile4:    2b6c [^_]
+testfile4:    2b9d ZYPV
+testfile4:    2c28 [^_]
+testfile4:    2c4d ZYPV
+testfile4:    2ce2 [^_]
+testfile4:    2dfb X^_]
+testfile4:    2fc8 [^_]
+testfile4:    307d tq;F
+testfile4:    315a [^_]
+testfile4:    31a5 :zt	1
+testfile4:    3238 [^_]
+testfile4:    32f8 AXY_VR
+testfile4:    334a [^_]
+testfile4:    37ab [^_]
+testfile4:    38b8 sU;E
+testfile4:    38f2 QRPV
+testfile4:    3926 [^_]
+testfile4:    3bfe QRWP
+testfile4:    3e65 [^_]
+testfile4:    4136 [^_]
+testfile4:    472d [^_]
+testfile4:    47a5 0[^_]
+testfile4:    48ab [^_]
+testfile4:    4ab1 _ZPV
+testfile4:    4b53 _ZPV
+testfile4:    4bd3 _ZPV
+testfile4:    4e05 PQWj
+testfile4:    4f75 [^_]
+testfile4:    4f9b u$;E u
+testfile4:    4feb [^_]
+testfile4:    5080 [^_]
+testfile4:    50a8 }$9u
+testfile4:    5149 [^_]
+testfile4:    51b0 [^_]
+testfile4:    539b [^_]
+testfile4:    53b5 E 9E
+testfile4:    540d x!)E 
+testfile4:    5598 U$	B
+testfile4:    571c [^_]
+testfile4:    5819 [^_]
+testfile4:    5922 [^_]
+testfile4:    59c2 [^_]
+testfile4:    5a62 [^_]
+testfile4:    5b02 [^_]
+testfile4:    5ba2 [^_]
+testfile4:    5c42 [^_]
+testfile4:    5ce2 [^_]
+testfile4:    6112 [^_]
+testfile4:    62bb [^_]
+testfile4:    639b [^_]
+testfile4:    6436 [^_]
+testfile4:    6468 val is zero
+testfile4:    6480 Internal Compiler Bug: No runtime type matcher.
+testfile4:    64dc 19__pointer_type_info
+testfile4:    64f2 16__attr_type_info
+testfile4:    6505 19__builtin_type_info
+testfile4:    651b 16__func_type_info
+testfile4:    652e 16__ptmf_type_info
+testfile4:    6541 16__ptmd_type_info
+testfile4:    6554 17__array_type_info
+testfile4:    6568 9exception
+testfile4:    6573 13bad_exception
+testfile4:    6583 9type_info
+testfile4:    658e 8bad_cast
+testfile4:    6598 10bad_typeid
+testfile4:    65a5 16__user_type_info
+testfile4:    65b8 14__si_type_info
+testfile4:    65c9 17__class_type_info
+testfile4:    6fc1 H. $
+testfile5:      f4 /lib/ld-linux.so.2
+testfile5:     1c9 __gmon_start__
+testfile5:     1d8 libc.so.6
+testfile5:     1e2 __cxa_finalize
+testfile5:     1f1 __deregister_frame_info
+testfile5:     209 _IO_stdin_used
+testfile5:     218 __libc_start_main
+testfile5:     22a __register_frame_info
+testfile5:     240 GLIBC_2.1.3
+testfile5:     24c GLIBC_2.0
+testfile5:     338 PTRh
+testfile5:     345 QVhD
+testfile6:     114 /lib/ld-linux.so.2
+testfile6:     3d9 libstdc++.so.5
+testfile6:     3e8 _ZTVSt16invalid_argument
+testfile6:     401 _ZNSaIcEC1Ev
+testfile6:     40e _ZTSSt16invalid_argument
+testfile6:     427 _ZTVN10__cxxabiv120__si_class_type_infoE
+testfile6:     450 _ZNSsD1Ev
+testfile6:     45a _ZdlPv
+testfile6:     461 __cxa_end_catch
+testfile6:     471 __gxx_personality_v0
+testfile6:     486 _ZTISt9exception
+testfile6:     497 _ZNSaIcED1Ev
+testfile6:     4a4 _ZTISt11logic_error
+testfile6:     4b8 _ZNSt16invalid_argumentD1Ev
+testfile6:     4d4 _ZTVN10__cxxabiv117__class_type_infoE
+testfile6:     4fa __cxa_throw
+testfile6:     506 _ZNSt16invalid_argumentC1ERKSs
+testfile6:     525 _ZNSsC1EPKcRKSaIcE
+testfile6:     538 _ZNSt11logic_errorD2Ev
+testfile6:     54f _ZTVN10__cxxabiv121__vmi_class_type_infoE
+testfile6:     579 _ZNSt16invalid_argumentD0Ev
+testfile6:     595 __cxa_begin_catch
+testfile6:     5a7 __cxa_allocate_exception
+testfile6:     5c0 _ZNKSt11logic_error4whatEv
+testfile6:     5db _Jv_RegisterClasses
+testfile6:     5ef _ZTISt16invalid_argument
+testfile6:     608 __gmon_start__
+testfile6:     617 libm.so.6
+testfile6:     621 _IO_stdin_used
+testfile6:     630 libgcc_s.so.1
+testfile6:     63e _Unwind_Resume
+testfile6:     64d libc.so.6
+testfile6:     657 __libc_start_main
+testfile6:     669 GCC_3.0
+testfile6:     671 GLIBC_2.0
+testfile6:     67b GLIBCPP_3.2
+testfile6:     687 CXXABI_1.2
+testfile6:     908 PTRh 
+testfile6:     e48 gdb.1
+testfile6:     ec8 N10__gnu_test9gnu_obj_1E
+testfile6:     ee1 N10__gnu_test9gnu_obj_2IiEE
+testfile6:     efd N10__gnu_test9gnu_obj_2IlEE
+testfile6:     f19 St16invalid_argument
+testfile7:     114 /lib/ld-linux.so.2
+testfile7:     3d9 libstdc++.so.5
+testfile7:     3e8 _ZTVSt16invalid_argument
+testfile7:     401 _ZNSaIcEC1Ev
+testfile7:     40e _ZTSSt16invalid_argument
+testfile7:     427 _ZTVN10__cxxabiv120__si_class_type_infoE
+testfile7:     450 _ZNSsD1Ev
+testfile7:     45a _ZdlPv
+testfile7:     461 __cxa_end_catch
+testfile7:     471 __gxx_personality_v0
+testfile7:     486 _ZTISt9exception
+testfile7:     497 _ZNSaIcED1Ev
+testfile7:     4a4 _ZTISt11logic_error
+testfile7:     4b8 _ZNSt16invalid_argumentD1Ev
+testfile7:     4d4 _ZTVN10__cxxabiv117__class_type_infoE
+testfile7:     4fa __cxa_throw
+testfile7:     506 _ZNSt16invalid_argumentC1ERKSs
+testfile7:     525 _ZNSsC1EPKcRKSaIcE
+testfile7:     538 _ZNSt11logic_errorD2Ev
+testfile7:     54f _ZTVN10__cxxabiv121__vmi_class_type_infoE
+testfile7:     579 _ZNSt16invalid_argumentD0Ev
+testfile7:     595 __cxa_begin_catch
+testfile7:     5a7 __cxa_allocate_exception
+testfile7:     5c0 _ZNKSt11logic_error4whatEv
+testfile7:     5db _Jv_RegisterClasses
+testfile7:     5ef _ZTISt16invalid_argument
+testfile7:     608 __gmon_start__
+testfile7:     617 libm.so.6
+testfile7:     621 _IO_stdin_used
+testfile7:     630 libgcc_s.so.1
+testfile7:     63e _Unwind_Resume
+testfile7:     64d libc.so.6
+testfile7:     657 __libc_start_main
+testfile7:     669 GCC_3.0
+testfile7:     671 GLIBC_2.0
+testfile7:     67b GLIBCPP_3.2
+testfile7:     687 CXXABI_1.2
+testfile7:     908 PTRh 
+testfile7:     e48 gdb.1
+testfile7:     ec8 N10__gnu_test9gnu_obj_1E
+testfile7:     ee1 N10__gnu_test9gnu_obj_2IiEE
+testfile7:     efd N10__gnu_test9gnu_obj_2IlEE
+testfile7:     f19 St16invalid_argument
+testfile8:      79 XZh;
+testfile8:      87 YXh<
+testfile8:     14f SQh[
+testfile8:     259 t5Wj
+testfile8:     502 WRVQ
+testfile8:    1fe7 ZYPj
+testfile8:    2115 u'Pj
+testfile8:    7bba FILE
+testfile8:    7bbf preserve-dates
+testfile8:    7bce remove-comment
+testfile8:    7bdd Remove .comment section
+testfile8:    7bf6 ${prefix}/share
+testfile8:    7c06 elfutils
+testfile8:    7c0f a.out
+testfile8:    7c15 0.58
+testfile8:    7c1a strip (Red Hat %s) %s
+testfile8:    7c31 2002
+testfile8:    7c36 Ulrich Drepper
+testfile8:    7c45 Written by %s.
+testfile8:    7c55 cannot stat input file "%s"
+testfile8:    7c71 %s: INTERNAL ERROR: %s
+testfile8:    7c88 while opening "%s"
+testfile8:    7c9b handle_elf
+testfile8:    7ca6 ../../src/strip.c
+testfile8:    7cb8 shdr_info[cnt].group_idx != 0
+testfile8:    7cd6 illformed file `%s'
+testfile8:    7cea elf_ndxscn (scn) == cnt
+testfile8:    7d02 .shstrtab
+testfile8:    7d0c while writing `%s': %s
+testfile8:    7d23 ((sym->st_info) & 0xf) == 3
+testfile8:    7d3f shndxdata != ((void *)0)
+testfile8:    7d58 scn != ((void *)0)
+testfile8:    7d6b .gnu_debuglink
+testfile8:    7d7a .comment
+testfile8:    7d83 cannot open `%s'
+testfile8:    7da0 Place stripped output into FILE
+testfile8:    7dc0 Extract the removed sections into FILE
+testfile8:    7e00 Copy modified/access timestamps to the output
+testfile8:    7e40 Only one input file allowed together with '-o' and '-f'
+testfile8:    7e80 Copyright (C) %s Red Hat, Inc.
+testfile8:    7e9f This is free software; see the source for copying conditions.  There is NO
+testfile8:    7eea warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+testfile8:    7f40 Report bugs to <drepper@redhat.com>.
+testfile8:    7f80 %s: File format not recognized
+testfile8:    7fa0 cannot set access and modification date of "%s"
+testfile8:    7fe0 cannot create new file `%s': %s
+testfile8:    8000 error while finishing `%s': %s
+testfile8:    8020 shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0
+testfile8:    8060 shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0
+testfile8:    80a0 %s: error while creating ELF header: %s
+testfile8:    80e0 %s: error while reading the file: %s
+testfile8:    8120 sec < 0xff00 || shndxdata != ((void *)0)
+testfile8:    8160 (versiondata->d_size / sizeof (GElf_Versym)) >= shdr_info[cnt].data->d_size / elsize
+testfile8:    81c0 shdr_info[cnt].shdr.sh_type == 11
+testfile8:    8200 (versiondata->d_size / sizeof (Elf32_Word)) >= shdr_info[cnt].data->d_size / elsize
+testfile8:    8260 shdr_info[cnt].shdr.sh_type == 18
+testfile8:    82a0 shdr_info[cnt].data != ((void *)0)
+testfile8:    82e0 elf_ndxscn (shdr_info[cnt].newscn) == idx
+testfile8:    8320 while create section header section: %s
+testfile8:    8360 cannot allocate section data: %s
+testfile8:    83a0 elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx
+testfile8:    83e0 while generating output file: %s
+testfile8:    8420 while preparing output for `%s'
+testfile8:    8440 shdr_info[cnt].shdr.sh_type == 2
+testfile8:    8480 shdr_info[idx].data != ((void *)0)
+testfile8:    84c0 cannot determine number of sections: %s
+testfile8:    8500 cannot get section header string table index
+testfile8:    85c0 Discard symbols from object files.
+testfile8:    85e3 [FILE...]
+testfile9:      79 XZh;
+testfile9:      87 YXh<
+testfile9:     14f SQh[
+testfile9:     259 t5Wj
+testfile9:     502 WRVQ
+testfile9:    1fe7 ZYPj
+testfile9:    2115 u'Pj
+testfile9:    3414 FILE
+testfile9:    3419 preserve-dates
+testfile9:    3428 remove-comment
+testfile9:    3437 Remove .comment section
+testfile9:    3450 ${prefix}/share
+testfile9:    3460 elfutils
+testfile9:    3469 a.out
+testfile9:    346f 0.58
+testfile9:    3474 strip (Red Hat %s) %s
+testfile9:    348b 2002
+testfile9:    3490 Ulrich Drepper
+testfile9:    349f Written by %s.
+testfile9:    34af cannot stat input file "%s"
+testfile9:    34cb %s: INTERNAL ERROR: %s
+testfile9:    34e2 while opening "%s"
+testfile9:    34f5 handle_elf
+testfile9:    3500 ../../src/strip.c
+testfile9:    3512 shdr_info[cnt].group_idx != 0
+testfile9:    3530 illformed file `%s'
+testfile9:    3544 elf_ndxscn (scn) == cnt
+testfile9:    355c .shstrtab
+testfile9:    3566 while writing `%s': %s
+testfile9:    357d ((sym->st_info) & 0xf) == 3
+testfile9:    3599 shndxdata != ((void *)0)
+testfile9:    35b2 scn != ((void *)0)
+testfile9:    35c5 .gnu_debuglink
+testfile9:    35d4 .comment
+testfile9:    35dd cannot open `%s'
+testfile9:    3600 Place stripped output into FILE
+testfile9:    3620 Extract the removed sections into FILE
+testfile9:    3660 Copy modified/access timestamps to the output
+testfile9:    36a0 Only one input file allowed together with '-o' and '-f'
+testfile9:    36e0 Copyright (C) %s Red Hat, Inc.
+testfile9:    36ff This is free software; see the source for copying conditions.  There is NO
+testfile9:    374a warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+testfile9:    37a0 Report bugs to <drepper@redhat.com>.
+testfile9:    37e0 %s: File format not recognized
+testfile9:    3800 cannot set access and modification date of "%s"
+testfile9:    3840 cannot create new file `%s': %s
+testfile9:    3860 error while finishing `%s': %s
+testfile9:    3880 shdr_info[shdr_info[cnt].shdr.sh_link].version_idx == 0
+testfile9:    38c0 shdr_info[shdr_info[cnt].shdr.sh_link].symtab_idx == 0
+testfile9:    3900 %s: error while creating ELF header: %s
+testfile9:    3940 %s: error while reading the file: %s
+testfile9:    3980 sec < 0xff00 || shndxdata != ((void *)0)
+testfile9:    39c0 (versiondata->d_size / sizeof (GElf_Versym)) >= shdr_info[cnt].data->d_size / elsize
+testfile9:    3a20 shdr_info[cnt].shdr.sh_type == 11
+testfile9:    3a60 (versiondata->d_size / sizeof (Elf32_Word)) >= shdr_info[cnt].data->d_size / elsize
+testfile9:    3ac0 shdr_info[cnt].shdr.sh_type == 18
+testfile9:    3b00 shdr_info[cnt].data != ((void *)0)
+testfile9:    3b40 elf_ndxscn (shdr_info[cnt].newscn) == idx
+testfile9:    3b80 while create section header section: %s
+testfile9:    3bc0 cannot allocate section data: %s
+testfile9:    3c00 elf_ndxscn (shdr_info[cnt].newscn) == shdr_info[cnt].idx
+testfile9:    3c40 while generating output file: %s
+testfile9:    3c80 while preparing output for `%s'
+testfile9:    3ca0 shdr_info[cnt].shdr.sh_type == 2
+testfile9:    3ce0 shdr_info[idx].data != ((void *)0)
+testfile9:    3d20 cannot determine number of sections: %s
+testfile9:    3d60 cannot get section header string table index
+testfile9:    3e20 Discard symbols from object files.
+testfile9:    3e43 [FILE...]
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-strip-g.sh b/third_party/elfutils/tests/run-strip-g.sh
new file mode 100755
index 0000000..1303819
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-g.sh
@@ -0,0 +1,102 @@
+#! /bin/sh
+# Copyright (C) 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# When stripping just the debug sections/symbols we keep the symtab
+# in the main ELF file. There should be no symbols pointing into the
+# debug sections and so there should not be a copy in the debug file
+# except for a NOBITS one.
+
+tempfiles a.out strip.out debug.out readelf.out
+
+echo Create debug a.out.
+echo "int main() { return 1; }" | gcc -g -xc -
+
+echo strip -g to file with debug file
+testrun ${abs_top_builddir}/src/strip -g -o strip.out -f debug.out ||
+  { echo "*** failed to strip -g -o strip.out -f debug.out a.out"; exit -1; }
+
+status=0
+testrun ${abs_top_builddir}/src/readelf -S strip.out > readelf.out
+grep SYMTAB readelf.out || status=$?
+echo $status
+if test $status -ne 0; then
+  echo no symtab found in strip.out
+  exit 1
+fi
+
+status=0
+testrun ${abs_top_builddir}/src/readelf -S debug.out > readelf.out
+grep SYMTAB readelf.out || status=$?
+echo $status
+if test $status -ne 1; then
+  echo symtab found in debug.out
+  exit 1
+fi
+
+# arm (with data marker in .debug_frame). See tests/run-addrcfi.sh
+testfiles testfilearm
+
+echo arm strip -g to file with debug file
+testrun ${abs_top_builddir}/src/strip -g -o strip.out -f debug.out testfilearm ||
+  { echo "*** failed to strip -g -o strip.out -f debug.out a.out"; exit -1; }
+
+status=0
+testrun ${abs_top_builddir}/src/readelf -S strip.out > readelf.out
+grep SYMTAB readelf.out || status=$?
+echo $status
+if test $status -ne 0; then
+  echo no symtab found in strip.out
+  exit 1
+fi
+
+status=0
+testrun ${abs_top_builddir}/src/readelf -S debug.out > readelf.out
+grep SYMTAB readelf.out || status=$?
+echo $status
+if test $status -ne 1; then
+  echo symtab found in debug.out
+  exit 1
+fi
+
+# aarch64 (with data marker in .debug_frame). See tests/run-addrcfi.sh
+testfiles testfileaarch64
+
+echo aarch64 strip -g to file with debug file
+testrun ${abs_top_builddir}/src/strip -g -o strip.out -f debug.out testfileaarch64 ||
+  { echo "*** failed to strip -g -o strip.out -f debug.out a.out"; exit -1; }
+
+status=0
+testrun ${abs_top_builddir}/src/readelf -S strip.out > readelf.out
+grep SYMTAB readelf.out || status=$?
+echo $status
+if test $status -ne 0; then
+  echo no symtab found in strip.out
+  exit 1
+fi
+
+status=0
+testrun ${abs_top_builddir}/src/readelf -S debug.out > readelf.out
+grep SYMTAB readelf.out || status=$?
+echo $status
+if test $status -ne 1; then
+  echo symtab found in debug.out
+  exit 1
+fi
+
+exit 0
diff --git a/third_party/elfutils/tests/run-strip-groups.sh b/third_party/elfutils/tests/run-strip-groups.sh
new file mode 100755
index 0000000..1c836a4
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-groups.sh
@@ -0,0 +1,55 @@
+#! /bin/sh
+# Copyright (C) 2011 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# g++ -gdwarf-4 -c testfile58.cxx
+# class ct
+# {
+#   private:
+#   int i;
+#
+#   public:
+#   void foo ()
+#   {
+#     i = 1;
+#   }
+#
+#   int bar ()
+#   {
+#     return i;
+#   }
+# };
+#
+# int baz ()
+# {
+#   class ct c;
+#   c.foo ();
+#   return c.bar ();
+# }
+
+. $srcdir/test-subr.sh
+
+infile=testfile58
+outfile=$infile.stripped
+dbgfile=$infile.debug
+
+testfiles $infile
+tempfiles $outfile $dbgfile
+
+testrun ${abs_top_builddir}/src/strip -o $outfile -f $dbgfile $infile
+testrun ${abs_top_builddir}/src/elflint -q $infile
+testrun ${abs_top_builddir}/src/elflint -q $outfile
+testrun ${abs_top_builddir}/src/elflint -q -d $dbgfile
diff --git a/third_party/elfutils/tests/run-strip-nobitsalign.sh b/third_party/elfutils/tests/run-strip-nobitsalign.sh
new file mode 100755
index 0000000..db9b1d9
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-nobitsalign.sh
@@ -0,0 +1,35 @@
+#! /bin/sh
+# Copyright (C) Red Hat, Inc., 2016.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# static unsigned char buffer[4096] __attribute((aligned (4096)));
+# 
+# char
+# f (int i)
+# {
+#   return buffer[i];
+# }
+# 
+# int
+# main (int argc, char **argv)
+# {
+#   return buffer[argc] == 0;
+# }
+
+original=testfile-nobitsalign
+stripped=testfile-nobitsalign.strip
+
+. $srcdir/run-strip-test.sh
diff --git a/third_party/elfutils/tests/run-strip-nothing.sh b/third_party/elfutils/tests/run-strip-nothing.sh
new file mode 100755
index 0000000..914fdfb
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-nothing.sh
@@ -0,0 +1,62 @@
+#! /bin/sh
+# Copyright (C) 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# If there is nothing to strip then -o output should be identical to input.
+# And there should not be an (empty) -f debug file.
+
+tempfiles a.out strip.out debug.out
+
+# Create no-debug a.out.
+echo "int main() { return 1; }" | gcc -s -xc -
+
+# strip to file
+testrun ${abs_top_builddir}/src/strip -g -o strip.out ||
+  { echo "*** failed to strip -g -o strip.out a.out"; exit -1; }
+
+testrun ${abs_top_builddir}/src/elfcmp a.out strip.out ||
+  { echo "*** failed strip.out different from a.out"; exit -1; }
+
+# strip original
+testrun ${abs_top_builddir}/src/strip -g ||
+  { echo "*** failed to strip -g a.out"; exit -1; }
+
+testrun ${abs_top_builddir}/src/elfcmp strip.out a.out ||
+  { echo "*** failed a.out different from strip.out"; exit -1; }
+
+# strip to file with debug file
+testrun ${abs_top_builddir}/src/strip -g -o strip.out -f debug.out ||
+  { echo "*** failed to strip -g -o strip.out -f debug.out a.out"; exit -1; }
+
+testrun ${abs_top_builddir}/src/elfcmp a.out strip.out ||
+  { echo "*** failed strip.out different from a.out (with debug)"; exit -1; }
+
+test ! -f debug.out ||
+  { echo "*** failed strip.out and debug.out exist"; exit -1; }
+
+# strip original with debug file
+testrun ${abs_top_builddir}/src/strip -g -f debug.out ||
+  { echo "*** failed to strip -g -f debug.out a.out"; exit -1; }
+
+testrun ${abs_top_builddir}/src/elfcmp strip.out a.out ||
+  { echo "*** failed a.out different from strip.out (with debug)"; exit -1; }
+
+test ! -f debug.out ||
+  { echo "*** failed a.out and debug.out exist"; exit -1; }
+
+exit 0
diff --git a/third_party/elfutils/tests/run-strip-reloc.sh b/third_party/elfutils/tests/run-strip-reloc.sh
new file mode 100755
index 0000000..e587eab
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-reloc.sh
@@ -0,0 +1,122 @@
+#! /bin/sh
+# Copyright (C) 2011, 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles hello_i386.ko hello_x86_64.ko hello_ppc64.ko hello_s390.ko \
+	hello_aarch64.ko hello_m68k.ko
+
+tempfiles readelf.out readelf.out1 readelf.out2
+tempfiles out.stripped1 out.debug1 out.stripped2 out.debug2
+
+status=0
+runtest() {
+  infile=$1
+  is_ET_REL=$2
+  outfile1=out.stripped1
+  debugfile1=out.debug1
+  outfile2=out.stripped2
+  debugfile2=out.debug2
+
+  testrun ${abs_top_builddir}/src/strip -o $outfile1 -f $debugfile1 $infile ||
+  { echo "*** failure strip $infile"; status=1; }
+
+  testrun ${abs_top_builddir}/src/strip --reloc-debug-sections -o $outfile2 \
+	-f $debugfile2 $infile ||
+  { echo "*** failure strip --reloc-debug-sections $infile"; status=1; }
+
+  # shouldn't make any difference for stripped files.
+  testrun ${abs_top_builddir}/src/readelf -a $outfile1 > readelf.out ||
+  { echo "*** failure readelf -a outfile1 $infile"; status=1; }
+
+  testrun_compare ${abs_top_builddir}/src/readelf -a $outfile2 < readelf.out ||
+  { echo "*** failure compare stripped files $infile"; status=1; }
+
+  # debug files however should be smaller, when ET_REL.
+  SIZE1=$(stat -c%s $debugfile1)
+  SIZE2=$(stat -c%s $debugfile2)
+  test \( \( $is_ET_REL -eq 1 \) -a \( $SIZE1 -gt $SIZE2 \) \) \
+	-o \( \( $is_ET_REL -eq 0 \) -a \( $SIZE1 -eq $SIZE2 \) \) ||
+  { echo "*** failure --reloc-debug-sections not smaller $infile"; status=1; }
+
+  # Strip of DWARF section lines, offset will not match.
+  # Everything else should match.
+  testrun ${abs_top_builddir}/src/readelf -w $debugfile1 \
+	| grep -v ^DWARF\ section > readelf.out1 ||
+  { echo "*** failure readelf -w debugfile1 $infile"; status=1; }
+
+  testrun ${abs_top_builddir}/src/readelf -w $debugfile2 \
+	| grep -v ^DWARF\ section > readelf.out2 ||
+  { echo "*** failure readelf -w debugfile2 $infile"; status=1; }
+
+  testrun_compare cat readelf.out1 < readelf.out2 ||
+  { echo "*** failure readelf -w compare $infile"; status=1; }
+}
+
+# Most simple hello world kernel module for various architectures.
+# ::::::::::::::
+# Makefile
+# ::::::::::::::
+# obj-m	:= hello.o
+# hello-y := init.o exit.o
+# 
+# all:
+# 	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
+# ::::::::::::::
+# init.c
+# ::::::::::::::
+# #include <linux/kernel.h>
+# #include <linux/module.h>
+# 
+# int init_module(void)
+# {
+#   printk(KERN_INFO "Hello, world!\n");
+#   return 0;
+# }
+# ::::::::::::::
+# exit.c
+# ::::::::::::::
+# #include <linux/kernel.h>
+# #include <linux/module.h>
+# 
+# void cleanup_module()
+# {
+#   printk(KERN_INFO "Goodbye, World!\n");
+# }
+runtest hello_i386.ko 1
+runtest hello_x86_64.ko 1
+runtest hello_ppc64.ko 1
+runtest hello_s390.ko 1
+runtest hello_aarch64.ko 1
+runtest hello_m68k.ko 1
+
+# self test, shouldn't impact non-ET_REL files at all.
+runtest ${abs_top_builddir}/src/strip 0
+runtest ${abs_top_builddir}/src/strip.o 1
+
+# Copy ET_REL file for self-test and make sure to run with/without
+# elf section compression.
+tempfiles strip-uncompressed.o strip-compressed.o
+testrun ${abs_top_builddir}/src/elfcompress -o strip-uncompressed.o -t none \
+  ${abs_top_builddir}/src/strip.o
+testrun ${abs_top_builddir}/src/elfcompress -o strip-compressed.o -t zlib \
+  --force ${abs_top_builddir}/src/strip.o
+
+runtest strip-uncompressed.o 1
+runtest strip-compressed.o 1
+
+exit $status
diff --git a/third_party/elfutils/tests/run-strip-remove-keep.sh b/third_party/elfutils/tests/run-strip-remove-keep.sh
new file mode 100755
index 0000000..92647fa
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-remove-keep.sh
@@ -0,0 +1,688 @@
+#! /bin/sh
+# Copyright (C) 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# strip -o output and -f debug files
+tempfiles testfile.elf testfile.debug
+
+# A random 32bit testfile
+testfiles testfile
+
+# Explicitly keep .strtab (but not .symtab, so .strtab will be in both). 32bit
+echo strip --keep-section=.strtab testfile
+testrun ${abs_top_builddir}/src/strip --keep-section=.strtab -o testfile.elf -f testfile.debug testfile
+echo elflint testfile.elf
+testrun ${abs_top_builddir}/src/elflint --gnu testfile.elf
+echo elflint testfile.debug
+testrun ${abs_top_builddir}/src/elflint --gnu -d testfile.debug
+echo readelf testfile.elf
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.elf <<\EOF
+There are 27 section headers, starting at offset 0xaf8:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .interp              PROGBITS     080480f4 0000f4 000013  0 A      0   0  1
+[ 2] .note.ABI-tag        NOTE         08048108 000108 000020  0 A      0   0  4
+[ 3] .hash                HASH         08048128 000128 000030  4 A      4   0  4
+[ 4] .dynsym              DYNSYM       08048158 000158 000070 16 A      5   1  4
+[ 5] .dynstr              STRTAB       080481c8 0001c8 00008e  0 A      0   0  1
+[ 6] .gnu.version         GNU_versym   08048256 000256 00000e  2 A      4   0  2
+[ 7] .gnu.version_r       GNU_verneed  08048264 000264 000030  0 A      5   1  4
+[ 8] .rel.got             REL          08048294 000294 000008  8 A      4  19  4
+[ 9] .rel.plt             REL          0804829c 00029c 000020  8 A      4  11  4
+[10] .init                PROGBITS     080482bc 0002bc 000018  0 AX     0   0  4
+[11] .plt                 PROGBITS     080482d4 0002d4 000050  4 AX     0   0  4
+[12] .text                PROGBITS     08048330 000330 00018c  0 AX     0   0 16
+[13] .fini                PROGBITS     080484bc 0004bc 00001e  0 AX     0   0  4
+[14] .rodata              PROGBITS     080484dc 0004dc 000008  0 A      0   0  4
+[15] .data                PROGBITS     080494e4 0004e4 000010  0 WA     0   0  4
+[16] .eh_frame            PROGBITS     080494f4 0004f4 000004  0 WA     0   0  4
+[17] .ctors               PROGBITS     080494f8 0004f8 000008  0 WA     0   0  4
+[18] .dtors               PROGBITS     08049500 000500 000008  0 WA     0   0  4
+[19] .got                 PROGBITS     08049508 000508 000020  4 WA     0   0  4
+[20] .dynamic             DYNAMIC      08049528 000528 0000a0  8 WA     5   0  4
+[21] .bss                 NOBITS       080495c8 0005c8 00001c  0 WA     0   0  4
+[22] .comment             PROGBITS     00000000 0005c8 000170  0        0   0  1
+[23] .note                NOTE         00000000 000738 0000a0  0        0   0  1
+[24] .strtab              STRTAB       00000000 0007d8 000235  0        0   0  1
+[25] .gnu_debuglink       PROGBITS     00000000 000a10 000014  0        0   0  4
+[26] .shstrtab            STRTAB       00000000 000a24 0000d1  0        0   0  1
+
+EOF
+echo readelf testfile.debug
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.debug <<\EOF
+There are 35 section headers, starting at offset 0x463c:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .interp              NOBITS       080480f4 0000f4 000013  0 A      0   0  1
+[ 2] .note.ABI-tag        NOTE         08048108 0000f4 000020  0 A      0   0  4
+[ 3] .hash                NOBITS       08048128 000114 000030  4 A      4   0  4
+[ 4] .dynsym              NOBITS       08048158 000114 000070 16 A      5   1  4
+[ 5] .dynstr              NOBITS       080481c8 000114 00008e  0 A      0   0  1
+[ 6] .gnu.version         NOBITS       08048256 000114 00000e  2 A      4   0  2
+[ 7] .gnu.version_r       NOBITS       08048264 000114 000030  0 A      5   1  4
+[ 8] .rel.got             NOBITS       08048294 000114 000008  8 A      4  19  4
+[ 9] .rel.plt             NOBITS       0804829c 000114 000020  8 A      4  11  4
+[10] .init                NOBITS       080482bc 000114 000018  0 AX     0   0  4
+[11] .plt                 NOBITS       080482d4 000114 000050  4 AX     0   0  4
+[12] .text                NOBITS       08048330 000120 00018c  0 AX     0   0 16
+[13] .fini                NOBITS       080484bc 000120 00001e  0 AX     0   0  4
+[14] .rodata              NOBITS       080484dc 000120 000008  0 A      0   0  4
+[15] .data                NOBITS       080494e4 000120 000010  0 WA     0   0  4
+[16] .eh_frame            NOBITS       080494f4 000120 000004  0 WA     0   0  4
+[17] .ctors               NOBITS       080494f8 000120 000008  0 WA     0   0  4
+[18] .dtors               NOBITS       08049500 000120 000008  0 WA     0   0  4
+[19] .got                 NOBITS       08049508 000120 000020  4 WA     0   0  4
+[20] .dynamic             NOBITS       08049528 000120 0000a0  8 WA     5   0  4
+[21] .sbss                PROGBITS     080495c8 000120 000000  0 W      0   0  1
+[22] .bss                 NOBITS       080495c8 000120 00001c  0 WA     0   0  4
+[23] .stab                PROGBITS     00000000 000120 000720 12       24   0  4
+[24] .stabstr             STRTAB       00000000 000840 001934  0        0   0  1
+[25] .comment             NOBITS       00000000 002174 000170  0        0   0  1
+[26] .debug_aranges       PROGBITS     00000000 002174 000060  0        0   0  1
+[27] .debug_pubnames      PROGBITS     00000000 0021d4 000055  0        0   0  1
+[28] .debug_info          PROGBITS     00000000 002229 001678  0        0   0  1
+[29] .debug_abbrev        PROGBITS     00000000 0038a1 0001d2  0        0   0  1
+[30] .debug_line          PROGBITS     00000000 003a73 000223  0        0   0  1
+[31] .note                NOTE         00000000 003c96 0000a0  0        0   0  1
+[32] .shstrtab            STRTAB       00000000 003d36 00012e  0        0   0  1
+[33] .symtab              SYMTAB       00000000 003e64 0005a0 16       34  68  4
+[34] .strtab              STRTAB       00000000 004404 000235  0        0   0  1
+
+EOF
+
+# Explicitly keep .symtab (pulls in .strtab, so they will both be in elf). 32bit
+echo strip --keep-section=.symtab testfile
+testrun ${abs_top_builddir}/src/strip --keep-section=.symtab -o testfile.elf -f testfile.debug testfile
+echo elflint testfile.elf
+testrun ${abs_top_builddir}/src/elflint --gnu testfile.elf
+echo elflint testfile.debug
+testrun ${abs_top_builddir}/src/elflint --gnu -d testfile.debug
+echo readelf testfile.elf
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.elf <<\EOF
+There are 28 section headers, starting at offset 0x1010:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .interp              PROGBITS     080480f4 0000f4 000013  0 A      0   0  1
+[ 2] .note.ABI-tag        NOTE         08048108 000108 000020  0 A      0   0  4
+[ 3] .hash                HASH         08048128 000128 000030  4 A      4   0  4
+[ 4] .dynsym              DYNSYM       08048158 000158 000070 16 A      5   1  4
+[ 5] .dynstr              STRTAB       080481c8 0001c8 00008e  0 A      0   0  1
+[ 6] .gnu.version         GNU_versym   08048256 000256 00000e  2 A      4   0  2
+[ 7] .gnu.version_r       GNU_verneed  08048264 000264 000030  0 A      5   1  4
+[ 8] .rel.got             REL          08048294 000294 000008  8 A      4  19  4
+[ 9] .rel.plt             REL          0804829c 00029c 000020  8 A      4  11  4
+[10] .init                PROGBITS     080482bc 0002bc 000018  0 AX     0   0  4
+[11] .plt                 PROGBITS     080482d4 0002d4 000050  4 AX     0   0  4
+[12] .text                PROGBITS     08048330 000330 00018c  0 AX     0   0 16
+[13] .fini                PROGBITS     080484bc 0004bc 00001e  0 AX     0   0  4
+[14] .rodata              PROGBITS     080484dc 0004dc 000008  0 A      0   0  4
+[15] .data                PROGBITS     080494e4 0004e4 000010  0 WA     0   0  4
+[16] .eh_frame            PROGBITS     080494f4 0004f4 000004  0 WA     0   0  4
+[17] .ctors               PROGBITS     080494f8 0004f8 000008  0 WA     0   0  4
+[18] .dtors               PROGBITS     08049500 000500 000008  0 WA     0   0  4
+[19] .got                 PROGBITS     08049508 000508 000020  4 WA     0   0  4
+[20] .dynamic             DYNAMIC      08049528 000528 0000a0  8 WA     5   0  4
+[21] .bss                 NOBITS       080495c8 0005c8 00001c  0 WA     0   0  4
+[22] .comment             PROGBITS     00000000 0005c8 000170  0        0   0  1
+[23] .note                NOTE         00000000 000738 0000a0  0        0   0  1
+[24] .symtab              SYMTAB       00000000 0007d8 000510 16       25  59  4
+[25] .strtab              STRTAB       00000000 000ce8 000235  0        0   0  1
+[26] .gnu_debuglink       PROGBITS     00000000 000f20 000014  0        0   0  4
+[27] .shstrtab            STRTAB       00000000 000f34 0000d9  0        0   0  1
+
+EOF
+echo readelf testfile.debug
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.debug <<\EOF
+There are 35 section headers, starting at offset 0x3e64:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .interp              NOBITS       080480f4 0000f4 000013  0 A      0   0  1
+[ 2] .note.ABI-tag        NOTE         08048108 0000f4 000020  0 A      0   0  4
+[ 3] .hash                NOBITS       08048128 000114 000030  4 A      4   0  4
+[ 4] .dynsym              NOBITS       08048158 000114 000070 16 A      5   1  4
+[ 5] .dynstr              NOBITS       080481c8 000114 00008e  0 A      0   0  1
+[ 6] .gnu.version         NOBITS       08048256 000114 00000e  2 A      4   0  2
+[ 7] .gnu.version_r       NOBITS       08048264 000114 000030  0 A      5   1  4
+[ 8] .rel.got             NOBITS       08048294 000114 000008  8 A      4  19  4
+[ 9] .rel.plt             NOBITS       0804829c 000114 000020  8 A      4  11  4
+[10] .init                NOBITS       080482bc 000114 000018  0 AX     0   0  4
+[11] .plt                 NOBITS       080482d4 000114 000050  4 AX     0   0  4
+[12] .text                NOBITS       08048330 000120 00018c  0 AX     0   0 16
+[13] .fini                NOBITS       080484bc 000120 00001e  0 AX     0   0  4
+[14] .rodata              NOBITS       080484dc 000120 000008  0 A      0   0  4
+[15] .data                NOBITS       080494e4 000120 000010  0 WA     0   0  4
+[16] .eh_frame            NOBITS       080494f4 000120 000004  0 WA     0   0  4
+[17] .ctors               NOBITS       080494f8 000120 000008  0 WA     0   0  4
+[18] .dtors               NOBITS       08049500 000120 000008  0 WA     0   0  4
+[19] .got                 NOBITS       08049508 000120 000020  4 WA     0   0  4
+[20] .dynamic             NOBITS       08049528 000120 0000a0  8 WA     5   0  4
+[21] .sbss                PROGBITS     080495c8 000120 000000  0 W      0   0  1
+[22] .bss                 NOBITS       080495c8 000120 00001c  0 WA     0   0  4
+[23] .stab                PROGBITS     00000000 000120 000720 12       24   0  4
+[24] .stabstr             STRTAB       00000000 000840 001934  0        0   0  1
+[25] .comment             NOBITS       00000000 002174 000170  0        0   0  1
+[26] .debug_aranges       PROGBITS     00000000 002174 000060  0        0   0  1
+[27] .debug_pubnames      PROGBITS     00000000 0021d4 000055  0        0   0  1
+[28] .debug_info          PROGBITS     00000000 002229 001678  0        0   0  1
+[29] .debug_abbrev        PROGBITS     00000000 0038a1 0001d2  0        0   0  1
+[30] .debug_line          PROGBITS     00000000 003a73 000223  0        0   0  1
+[31] .note                NOTE         00000000 003c96 0000a0  0        0   0  1
+[32] .shstrtab            STRTAB       00000000 003d36 00012e  0        0   0  1
+[33] .symtab              NOBITS       00000000 003e64 0005a0 16       34  68  4
+[34] .strtab              NOBITS       00000000 003e64 000235  0        0   0  1
+
+EOF
+
+# A random 64bit testfile
+testfiles testfile69.so
+# Explicitly keep .strtab (but not .symtab, so .strtab will be in both). 64bit
+echo strip --keep-section=.strtab testfile69.so
+testrun ${abs_top_builddir}/src/strip --keep-section=.strtab -o testfile.elf -f testfile.debug testfile69.so
+echo elflint testfile.elf
+testrun ${abs_top_builddir}/src/elflint --gnu testfile.elf
+echo elflint testfile.debug
+testrun ${abs_top_builddir}/src/elflint --gnu -d testfile.debug
+echo readelf testfile.elf
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.elf <<\EOF
+There are 27 section headers, starting at offset 0xad8:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .note.gnu.build-id   NOTE         0000000000000190 00000190 00000024  0 A      0   0  4
+[ 2] .gnu.hash            GNU_HASH     00000000000001b8 000001b8 0000003c  0 A      3   0  8
+[ 3] .dynsym              DYNSYM       00000000000001f8 000001f8 00000108 24 A      4   2  8
+[ 4] .dynstr              STRTAB       0000000000000300 00000300 00000077  0 A      0   0  1
+[ 5] .gnu.version         GNU_versym   0000000000000378 00000378 00000016  2 A      3   0  2
+[ 6] .gnu.version_r       GNU_verneed  0000000000000390 00000390 00000020  0 A      4   1  8
+[ 7] .rela.dyn            RELA         00000000000003b0 000003b0 00000060 24 A      3   0  8
+[ 8] .rela.plt            RELA         0000000000000410 00000410 00000018 24 A      3  10  8
+[ 9] .init                PROGBITS     0000000000000428 00000428 00000018  0 AX     0   0  4
+[10] .plt                 PROGBITS     0000000000000440 00000440 00000020 16 AX     0   0 16
+[11] .text                PROGBITS     0000000000000460 00000460 00000128  0 AX     0   0 16
+[12] .fini                PROGBITS     0000000000000588 00000588 0000000e  0 AX     0   0  4
+[13] .eh_frame_hdr        PROGBITS     0000000000000598 00000598 00000024  0 A      0   0  4
+[14] .eh_frame            PROGBITS     00000000000005c0 000005c0 00000084  0 A      0   0  8
+[15] .ctors               PROGBITS     0000000000200648 00000648 00000010  0 WA     0   0  8
+[16] .dtors               PROGBITS     0000000000200658 00000658 00000010  0 WA     0   0  8
+[17] .jcr                 PROGBITS     0000000000200668 00000668 00000008  0 WA     0   0  8
+[18] .data.rel.ro         PROGBITS     0000000000200670 00000670 00000008  0 WA     0   0  8
+[19] .dynamic             DYNAMIC      0000000000200678 00000678 00000180 16 WA     4   0  8
+[20] .got                 PROGBITS     00000000002007f8 000007f8 00000018  8 WA     0   0  8
+[21] .got.plt             PROGBITS     0000000000200810 00000810 00000020  8 WA     0   0  8
+[22] .bss                 NOBITS       0000000000200830 00000830 00000010  0 WA     0   0  8
+[23] .comment             PROGBITS     0000000000000000 00000830 0000002c  1 MS     0   0  1
+[24] .strtab              STRTAB       0000000000000000 0000085c 00000175  0        0   0  1
+[25] .gnu_debuglink       PROGBITS     0000000000000000 000009d4 00000014  0        0   0  4
+[26] .shstrtab            STRTAB       0000000000000000 000009e8 000000ee  0        0   0  1
+
+EOF
+echo readelf testfile.debug
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.debug <<\EOF
+There are 27 section headers, starting at offset 0x918:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .note.gnu.build-id   NOTE         0000000000000190 00000190 00000024  0 A      0   0  4
+[ 2] .gnu.hash            NOBITS       00000000000001b8 000001b8 0000003c  0 A      3   0  8
+[ 3] .dynsym              NOBITS       00000000000001f8 000001b8 00000108 24 A      4   2  8
+[ 4] .dynstr              NOBITS       0000000000000300 000001b8 00000077  0 A      0   0  1
+[ 5] .gnu.version         NOBITS       0000000000000378 000001b8 00000016  2 A      3   0  2
+[ 6] .gnu.version_r       NOBITS       0000000000000390 000001b8 00000020  0 A      4   1  8
+[ 7] .rela.dyn            NOBITS       00000000000003b0 000001b8 00000060 24 A      3   0  8
+[ 8] .rela.plt            NOBITS       0000000000000410 000001b8 00000018 24 A      3  10  8
+[ 9] .init                NOBITS       0000000000000428 000001b8 00000018  0 AX     0   0  4
+[10] .plt                 NOBITS       0000000000000440 000001c0 00000020 16 AX     0   0 16
+[11] .text                NOBITS       0000000000000460 000001c0 00000128  0 AX     0   0 16
+[12] .fini                NOBITS       0000000000000588 000001c0 0000000e  0 AX     0   0  4
+[13] .eh_frame_hdr        NOBITS       0000000000000598 000001c0 00000024  0 A      0   0  4
+[14] .eh_frame            NOBITS       00000000000005c0 000001c0 00000084  0 A      0   0  8
+[15] .ctors               NOBITS       0000000000200648 000001c0 00000010  0 WA     0   0  8
+[16] .dtors               NOBITS       0000000000200658 000001c0 00000010  0 WA     0   0  8
+[17] .jcr                 NOBITS       0000000000200668 000001c0 00000008  0 WA     0   0  8
+[18] .data.rel.ro         NOBITS       0000000000200670 000001c0 00000008  0 WA     0   0  8
+[19] .dynamic             NOBITS       0000000000200678 000001c0 00000180 16 WA     4   0  8
+[20] .got                 NOBITS       00000000002007f8 000001c0 00000018  8 WA     0   0  8
+[21] .got.plt             NOBITS       0000000000200810 000001c0 00000020  8 WA     0   0  8
+[22] .bss                 NOBITS       0000000000200830 000001c0 00000010  0 WA     0   0  8
+[23] .comment             NOBITS       0000000000000000 000001c0 0000002c  1 MS     0   0  1
+[24] .shstrtab            STRTAB       0000000000000000 000001c0 000000e7  0        0   0  1
+[25] .symtab              SYMTAB       0000000000000000 000002a8 000004f8 24       26  44  8
+[26] .strtab              STRTAB       0000000000000000 000007a0 00000175  0        0   0  1
+
+EOF
+
+# Explicitly keep .symtab (pulls in .strtab, so they will both be in elf). 64bit
+# Use --remove-comment to make sure testfile.debug isn't empty.
+echo strip --keep-section=.symtab --remove-comment testfile69.so
+testrun ${abs_top_builddir}/src/strip --keep-section=.symtab --remove-comment -o testfile.elf -f testfile.debug testfile69.so
+echo elflint testfile.elf
+testrun ${abs_top_builddir}/src/elflint --gnu testfile.elf
+echo elflint testfile.debug
+testrun ${abs_top_builddir}/src/elflint --gnu -d testfile.debug
+echo readelf testfile.elf
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.elf <<\EOF
+There are 27 section headers, starting at offset 0xf90:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .note.gnu.build-id   NOTE         0000000000000190 00000190 00000024  0 A      0   0  4
+[ 2] .gnu.hash            GNU_HASH     00000000000001b8 000001b8 0000003c  0 A      3   0  8
+[ 3] .dynsym              DYNSYM       00000000000001f8 000001f8 00000108 24 A      4   2  8
+[ 4] .dynstr              STRTAB       0000000000000300 00000300 00000077  0 A      0   0  1
+[ 5] .gnu.version         GNU_versym   0000000000000378 00000378 00000016  2 A      3   0  2
+[ 6] .gnu.version_r       GNU_verneed  0000000000000390 00000390 00000020  0 A      4   1  8
+[ 7] .rela.dyn            RELA         00000000000003b0 000003b0 00000060 24 A      3   0  8
+[ 8] .rela.plt            RELA         0000000000000410 00000410 00000018 24 A      3  10  8
+[ 9] .init                PROGBITS     0000000000000428 00000428 00000018  0 AX     0   0  4
+[10] .plt                 PROGBITS     0000000000000440 00000440 00000020 16 AX     0   0 16
+[11] .text                PROGBITS     0000000000000460 00000460 00000128  0 AX     0   0 16
+[12] .fini                PROGBITS     0000000000000588 00000588 0000000e  0 AX     0   0  4
+[13] .eh_frame_hdr        PROGBITS     0000000000000598 00000598 00000024  0 A      0   0  4
+[14] .eh_frame            PROGBITS     00000000000005c0 000005c0 00000084  0 A      0   0  8
+[15] .ctors               PROGBITS     0000000000200648 00000648 00000010  0 WA     0   0  8
+[16] .dtors               PROGBITS     0000000000200658 00000658 00000010  0 WA     0   0  8
+[17] .jcr                 PROGBITS     0000000000200668 00000668 00000008  0 WA     0   0  8
+[18] .data.rel.ro         PROGBITS     0000000000200670 00000670 00000008  0 WA     0   0  8
+[19] .dynamic             DYNAMIC      0000000000200678 00000678 00000180 16 WA     4   0  8
+[20] .got                 PROGBITS     00000000002007f8 000007f8 00000018  8 WA     0   0  8
+[21] .got.plt             PROGBITS     0000000000200810 00000810 00000020  8 WA     0   0  8
+[22] .bss                 NOBITS       0000000000200830 00000830 00000010  0 WA     0   0  8
+[23] .symtab              SYMTAB       0000000000000000 00000830 000004e0 24       24  43  8
+[24] .strtab              STRTAB       0000000000000000 00000d10 00000175  0        0   0  1
+[25] .gnu_debuglink       PROGBITS     0000000000000000 00000e88 00000014  0        0   0  4
+[26] .shstrtab            STRTAB       0000000000000000 00000e9c 000000ed  0        0   0  1
+
+EOF
+echo readelf testfile.debug
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.debug <<\EOF
+There are 27 section headers, starting at offset 0x2d8:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .note.gnu.build-id   NOTE         0000000000000190 00000190 00000024  0 A      0   0  4
+[ 2] .gnu.hash            NOBITS       00000000000001b8 000001b8 0000003c  0 A      3   0  8
+[ 3] .dynsym              NOBITS       00000000000001f8 000001b8 00000108 24 A      4   2  8
+[ 4] .dynstr              NOBITS       0000000000000300 000001b8 00000077  0 A      0   0  1
+[ 5] .gnu.version         NOBITS       0000000000000378 000001b8 00000016  2 A      3   0  2
+[ 6] .gnu.version_r       NOBITS       0000000000000390 000001b8 00000020  0 A      4   1  8
+[ 7] .rela.dyn            NOBITS       00000000000003b0 000001b8 00000060 24 A      3   0  8
+[ 8] .rela.plt            NOBITS       0000000000000410 000001b8 00000018 24 A      3  10  8
+[ 9] .init                NOBITS       0000000000000428 000001b8 00000018  0 AX     0   0  4
+[10] .plt                 NOBITS       0000000000000440 000001c0 00000020 16 AX     0   0 16
+[11] .text                NOBITS       0000000000000460 000001c0 00000128  0 AX     0   0 16
+[12] .fini                NOBITS       0000000000000588 000001c0 0000000e  0 AX     0   0  4
+[13] .eh_frame_hdr        NOBITS       0000000000000598 000001c0 00000024  0 A      0   0  4
+[14] .eh_frame            NOBITS       00000000000005c0 000001c0 00000084  0 A      0   0  8
+[15] .ctors               NOBITS       0000000000200648 000001c0 00000010  0 WA     0   0  8
+[16] .dtors               NOBITS       0000000000200658 000001c0 00000010  0 WA     0   0  8
+[17] .jcr                 NOBITS       0000000000200668 000001c0 00000008  0 WA     0   0  8
+[18] .data.rel.ro         NOBITS       0000000000200670 000001c0 00000008  0 WA     0   0  8
+[19] .dynamic             NOBITS       0000000000200678 000001c0 00000180 16 WA     4   0  8
+[20] .got                 NOBITS       00000000002007f8 000001c0 00000018  8 WA     0   0  8
+[21] .got.plt             NOBITS       0000000000200810 000001c0 00000020  8 WA     0   0  8
+[22] .bss                 NOBITS       0000000000200830 000001c0 00000010  0 WA     0   0  8
+[23] .comment             PROGBITS     0000000000000000 000001c0 0000002c  1 MS     0   0  1
+[24] .shstrtab            STRTAB       0000000000000000 000001ec 000000e7  0        0   0  1
+[25] .symtab              NOBITS       0000000000000000 000002d8 000004f8 24       26  44  8
+[26] .strtab              NOBITS       0000000000000000 000002d8 00000175  0        0   0  1
+
+EOF
+
+# Explicitly remove .symtab (but not .strtab, so it will be in both). 32bit
+echo strip -g --remove-section=.symtab testfile
+testrun ${abs_top_builddir}/src/strip -g --remove-section=.symtab -o testfile.elf -f testfile.debug testfile
+echo elflint testfile.elf
+testrun ${abs_top_builddir}/src/elflint --gnu testfile.elf
+echo elflint testfile.debug
+testrun ${abs_top_builddir}/src/elflint --gnu -d testfile.debug
+echo readelf testfile.elf
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.elf <<\EOF
+There are 28 section headers, starting at offset 0xafc:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .interp              PROGBITS     080480f4 0000f4 000013  0 A      0   0  1
+[ 2] .note.ABI-tag        NOTE         08048108 000108 000020  0 A      0   0  4
+[ 3] .hash                HASH         08048128 000128 000030  4 A      4   0  4
+[ 4] .dynsym              DYNSYM       08048158 000158 000070 16 A      5   1  4
+[ 5] .dynstr              STRTAB       080481c8 0001c8 00008e  0 A      0   0  1
+[ 6] .gnu.version         GNU_versym   08048256 000256 00000e  2 A      4   0  2
+[ 7] .gnu.version_r       GNU_verneed  08048264 000264 000030  0 A      5   1  4
+[ 8] .rel.got             REL          08048294 000294 000008  8 A      4  19  4
+[ 9] .rel.plt             REL          0804829c 00029c 000020  8 A      4  11  4
+[10] .init                PROGBITS     080482bc 0002bc 000018  0 AX     0   0  4
+[11] .plt                 PROGBITS     080482d4 0002d4 000050  4 AX     0   0  4
+[12] .text                PROGBITS     08048330 000330 00018c  0 AX     0   0 16
+[13] .fini                PROGBITS     080484bc 0004bc 00001e  0 AX     0   0  4
+[14] .rodata              PROGBITS     080484dc 0004dc 000008  0 A      0   0  4
+[15] .data                PROGBITS     080494e4 0004e4 000010  0 WA     0   0  4
+[16] .eh_frame            PROGBITS     080494f4 0004f4 000004  0 WA     0   0  4
+[17] .ctors               PROGBITS     080494f8 0004f8 000008  0 WA     0   0  4
+[18] .dtors               PROGBITS     08049500 000500 000008  0 WA     0   0  4
+[19] .got                 PROGBITS     08049508 000508 000020  4 WA     0   0  4
+[20] .dynamic             DYNAMIC      08049528 000528 0000a0  8 WA     5   0  4
+[21] .sbss                PROGBITS     080495c8 0005c8 000000  0 W      0   0  1
+[22] .bss                 NOBITS       080495c8 0005c8 00001c  0 WA     0   0  4
+[23] .comment             PROGBITS     00000000 0005c8 000170  0        0   0  1
+[24] .note                NOTE         00000000 000738 0000a0  0        0   0  1
+[25] .strtab              STRTAB       00000000 0007d8 000235  0        0   0  1
+[26] .gnu_debuglink       PROGBITS     00000000 000a10 000014  0        0   0  4
+[27] .shstrtab            STRTAB       00000000 000a24 0000d7  0        0   0  1
+
+EOF
+echo readelf testfile.debug
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.debug <<\EOF
+There are 35 section headers, starting at offset 0x463c:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .interp              NOBITS       080480f4 0000f4 000013  0 A      0   0  1
+[ 2] .note.ABI-tag        NOTE         08048108 0000f4 000020  0 A      0   0  4
+[ 3] .hash                NOBITS       08048128 000114 000030  4 A      4   0  4
+[ 4] .dynsym              NOBITS       08048158 000114 000070 16 A      5   1  4
+[ 5] .dynstr              NOBITS       080481c8 000114 00008e  0 A      0   0  1
+[ 6] .gnu.version         NOBITS       08048256 000114 00000e  2 A      4   0  2
+[ 7] .gnu.version_r       NOBITS       08048264 000114 000030  0 A      5   1  4
+[ 8] .rel.got             NOBITS       08048294 000114 000008  8 A      4  19  4
+[ 9] .rel.plt             NOBITS       0804829c 000114 000020  8 A      4  11  4
+[10] .init                NOBITS       080482bc 000114 000018  0 AX     0   0  4
+[11] .plt                 NOBITS       080482d4 000114 000050  4 AX     0   0  4
+[12] .text                NOBITS       08048330 000120 00018c  0 AX     0   0 16
+[13] .fini                NOBITS       080484bc 000120 00001e  0 AX     0   0  4
+[14] .rodata              NOBITS       080484dc 000120 000008  0 A      0   0  4
+[15] .data                NOBITS       080494e4 000120 000010  0 WA     0   0  4
+[16] .eh_frame            NOBITS       080494f4 000120 000004  0 WA     0   0  4
+[17] .ctors               NOBITS       080494f8 000120 000008  0 WA     0   0  4
+[18] .dtors               NOBITS       08049500 000120 000008  0 WA     0   0  4
+[19] .got                 NOBITS       08049508 000120 000020  4 WA     0   0  4
+[20] .dynamic             NOBITS       08049528 000120 0000a0  8 WA     5   0  4
+[21] .sbss                NOBITS       080495c8 000120 000000  0 W      0   0  1
+[22] .bss                 NOBITS       080495c8 000120 00001c  0 WA     0   0  4
+[23] .stab                PROGBITS     00000000 000120 000720 12       24   0  4
+[24] .stabstr             STRTAB       00000000 000840 001934  0        0   0  1
+[25] .comment             NOBITS       00000000 002174 000170  0        0   0  1
+[26] .debug_aranges       PROGBITS     00000000 002174 000060  0        0   0  1
+[27] .debug_pubnames      PROGBITS     00000000 0021d4 000055  0        0   0  1
+[28] .debug_info          PROGBITS     00000000 002229 001678  0        0   0  1
+[29] .debug_abbrev        PROGBITS     00000000 0038a1 0001d2  0        0   0  1
+[30] .debug_line          PROGBITS     00000000 003a73 000223  0        0   0  1
+[31] .note                NOTE         00000000 003c96 0000a0  0        0   0  1
+[32] .shstrtab            STRTAB       00000000 003d36 00012e  0        0   0  1
+[33] .symtab              SYMTAB       00000000 003e64 0005a0 16       34  68  4
+[34] .strtab              STRTAB       00000000 004404 000235  0        0   0  1
+
+EOF
+
+# Explicitly remove both .symtab and .strtab. Keep .stab and .stabstr 32bit
+echo strip -g --remove-section=".s[yt][mr]tab" --keep-section=".stab*" testfile
+testrun ${abs_top_builddir}/src/strip -g --remove-section=".s[yt][mr]tab" --keep-section=".stab*" -o testfile.elf -f testfile.debug testfile
+echo elflint testfile.elf
+testrun ${abs_top_builddir}/src/elflint --gnu testfile.elf
+echo elflint testfile.debug
+testrun ${abs_top_builddir}/src/elflint --gnu -d testfile.debug
+echo readelf testfile.elf
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.elf <<\EOF
+There are 29 section headers, starting at offset 0x2920:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .interp              PROGBITS     080480f4 0000f4 000013  0 A      0   0  1
+[ 2] .note.ABI-tag        NOTE         08048108 000108 000020  0 A      0   0  4
+[ 3] .hash                HASH         08048128 000128 000030  4 A      4   0  4
+[ 4] .dynsym              DYNSYM       08048158 000158 000070 16 A      5   1  4
+[ 5] .dynstr              STRTAB       080481c8 0001c8 00008e  0 A      0   0  1
+[ 6] .gnu.version         GNU_versym   08048256 000256 00000e  2 A      4   0  2
+[ 7] .gnu.version_r       GNU_verneed  08048264 000264 000030  0 A      5   1  4
+[ 8] .rel.got             REL          08048294 000294 000008  8 A      4  19  4
+[ 9] .rel.plt             REL          0804829c 00029c 000020  8 A      4  11  4
+[10] .init                PROGBITS     080482bc 0002bc 000018  0 AX     0   0  4
+[11] .plt                 PROGBITS     080482d4 0002d4 000050  4 AX     0   0  4
+[12] .text                PROGBITS     08048330 000330 00018c  0 AX     0   0 16
+[13] .fini                PROGBITS     080484bc 0004bc 00001e  0 AX     0   0  4
+[14] .rodata              PROGBITS     080484dc 0004dc 000008  0 A      0   0  4
+[15] .data                PROGBITS     080494e4 0004e4 000010  0 WA     0   0  4
+[16] .eh_frame            PROGBITS     080494f4 0004f4 000004  0 WA     0   0  4
+[17] .ctors               PROGBITS     080494f8 0004f8 000008  0 WA     0   0  4
+[18] .dtors               PROGBITS     08049500 000500 000008  0 WA     0   0  4
+[19] .got                 PROGBITS     08049508 000508 000020  4 WA     0   0  4
+[20] .dynamic             DYNAMIC      08049528 000528 0000a0  8 WA     5   0  4
+[21] .sbss                PROGBITS     080495c8 0005c8 000000  0 W      0   0  1
+[22] .bss                 NOBITS       080495c8 0005c8 00001c  0 WA     0   0  4
+[23] .stab                PROGBITS     00000000 0005c8 000720 12       24   0  4
+[24] .stabstr             STRTAB       00000000 000ce8 001934  0        0   0  1
+[25] .comment             PROGBITS     00000000 00261c 000170  0        0   0  1
+[26] .note                NOTE         00000000 00278c 0000a0  0        0   0  1
+[27] .gnu_debuglink       PROGBITS     00000000 00282c 000014  0        0   0  4
+[28] .shstrtab            STRTAB       00000000 002840 0000de  0        0   0  1
+
+EOF
+echo readelf testfile.debug
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.debug <<\EOF
+There are 35 section headers, starting at offset 0x25e8:
+
+Section Headers:
+[Nr] Name                 Type         Addr     Off    Size   ES Flags Lk Inf Al
+[ 0]                      NULL         00000000 000000 000000  0        0   0  0
+[ 1] .interp              NOBITS       080480f4 0000f4 000013  0 A      0   0  1
+[ 2] .note.ABI-tag        NOTE         08048108 0000f4 000020  0 A      0   0  4
+[ 3] .hash                NOBITS       08048128 000114 000030  4 A      4   0  4
+[ 4] .dynsym              NOBITS       08048158 000114 000070 16 A      5   1  4
+[ 5] .dynstr              NOBITS       080481c8 000114 00008e  0 A      0   0  1
+[ 6] .gnu.version         NOBITS       08048256 000114 00000e  2 A      4   0  2
+[ 7] .gnu.version_r       NOBITS       08048264 000114 000030  0 A      5   1  4
+[ 8] .rel.got             NOBITS       08048294 000114 000008  8 A      4  19  4
+[ 9] .rel.plt             NOBITS       0804829c 000114 000020  8 A      4  11  4
+[10] .init                NOBITS       080482bc 000114 000018  0 AX     0   0  4
+[11] .plt                 NOBITS       080482d4 000114 000050  4 AX     0   0  4
+[12] .text                NOBITS       08048330 000120 00018c  0 AX     0   0 16
+[13] .fini                NOBITS       080484bc 000120 00001e  0 AX     0   0  4
+[14] .rodata              NOBITS       080484dc 000120 000008  0 A      0   0  4
+[15] .data                NOBITS       080494e4 000120 000010  0 WA     0   0  4
+[16] .eh_frame            NOBITS       080494f4 000120 000004  0 WA     0   0  4
+[17] .ctors               NOBITS       080494f8 000120 000008  0 WA     0   0  4
+[18] .dtors               NOBITS       08049500 000120 000008  0 WA     0   0  4
+[19] .got                 NOBITS       08049508 000120 000020  4 WA     0   0  4
+[20] .dynamic             NOBITS       08049528 000120 0000a0  8 WA     5   0  4
+[21] .sbss                NOBITS       080495c8 000120 000000  0 W      0   0  1
+[22] .bss                 NOBITS       080495c8 000120 00001c  0 WA     0   0  4
+[23] .stab                NOBITS       00000000 000120 000720 12       24   0  4
+[24] .stabstr             NOBITS       00000000 000120 001934  0        0   0  1
+[25] .comment             NOBITS       00000000 000120 000170  0        0   0  1
+[26] .debug_aranges       PROGBITS     00000000 000120 000060  0        0   0  1
+[27] .debug_pubnames      PROGBITS     00000000 000180 000055  0        0   0  1
+[28] .debug_info          PROGBITS     00000000 0001d5 001678  0        0   0  1
+[29] .debug_abbrev        PROGBITS     00000000 00184d 0001d2  0        0   0  1
+[30] .debug_line          PROGBITS     00000000 001a1f 000223  0        0   0  1
+[31] .note                NOTE         00000000 001c42 0000a0  0        0   0  1
+[32] .shstrtab            STRTAB       00000000 001ce2 00012e  0        0   0  1
+[33] .symtab              SYMTAB       00000000 001e10 0005a0 16       34  68  4
+[34] .strtab              STRTAB       00000000 0023b0 000235  0        0   0  1
+
+EOF
+
+# Explicitly remove .symtab (but not .strtab, so it will be in both). 64bit
+echo strip -g --remove-section=.symtab testfile69.so
+testrun ${abs_top_builddir}/src/strip -g --remove-section=.symtab -o testfile.elf -f testfile.debug testfile69.so
+echo elflint testfile.elf
+testrun ${abs_top_builddir}/src/elflint --gnu testfile.elf
+echo elflint testfile.debug
+testrun ${abs_top_builddir}/src/elflint --gnu -d testfile.debug
+echo readelf testfile.elf
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.elf <<\EOF
+There are 27 section headers, starting at offset 0xad8:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .note.gnu.build-id   NOTE         0000000000000190 00000190 00000024  0 A      0   0  4
+[ 2] .gnu.hash            GNU_HASH     00000000000001b8 000001b8 0000003c  0 A      3   0  8
+[ 3] .dynsym              DYNSYM       00000000000001f8 000001f8 00000108 24 A      4   2  8
+[ 4] .dynstr              STRTAB       0000000000000300 00000300 00000077  0 A      0   0  1
+[ 5] .gnu.version         GNU_versym   0000000000000378 00000378 00000016  2 A      3   0  2
+[ 6] .gnu.version_r       GNU_verneed  0000000000000390 00000390 00000020  0 A      4   1  8
+[ 7] .rela.dyn            RELA         00000000000003b0 000003b0 00000060 24 A      3   0  8
+[ 8] .rela.plt            RELA         0000000000000410 00000410 00000018 24 A      3  10  8
+[ 9] .init                PROGBITS     0000000000000428 00000428 00000018  0 AX     0   0  4
+[10] .plt                 PROGBITS     0000000000000440 00000440 00000020 16 AX     0   0 16
+[11] .text                PROGBITS     0000000000000460 00000460 00000128  0 AX     0   0 16
+[12] .fini                PROGBITS     0000000000000588 00000588 0000000e  0 AX     0   0  4
+[13] .eh_frame_hdr        PROGBITS     0000000000000598 00000598 00000024  0 A      0   0  4
+[14] .eh_frame            PROGBITS     00000000000005c0 000005c0 00000084  0 A      0   0  8
+[15] .ctors               PROGBITS     0000000000200648 00000648 00000010  0 WA     0   0  8
+[16] .dtors               PROGBITS     0000000000200658 00000658 00000010  0 WA     0   0  8
+[17] .jcr                 PROGBITS     0000000000200668 00000668 00000008  0 WA     0   0  8
+[18] .data.rel.ro         PROGBITS     0000000000200670 00000670 00000008  0 WA     0   0  8
+[19] .dynamic             DYNAMIC      0000000000200678 00000678 00000180 16 WA     4   0  8
+[20] .got                 PROGBITS     00000000002007f8 000007f8 00000018  8 WA     0   0  8
+[21] .got.plt             PROGBITS     0000000000200810 00000810 00000020  8 WA     0   0  8
+[22] .bss                 NOBITS       0000000000200830 00000830 00000010  0 WA     0   0  8
+[23] .comment             PROGBITS     0000000000000000 00000830 0000002c  1 MS     0   0  1
+[24] .strtab              STRTAB       0000000000000000 0000085c 00000175  0        0   0  1
+[25] .gnu_debuglink       PROGBITS     0000000000000000 000009d4 00000014  0        0   0  4
+[26] .shstrtab            STRTAB       0000000000000000 000009e8 000000ee  0        0   0  1
+
+EOF
+echo readelf testfile.debug
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.debug <<\EOF
+There are 27 section headers, starting at offset 0x918:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .note.gnu.build-id   NOTE         0000000000000190 00000190 00000024  0 A      0   0  4
+[ 2] .gnu.hash            NOBITS       00000000000001b8 000001b8 0000003c  0 A      3   0  8
+[ 3] .dynsym              NOBITS       00000000000001f8 000001b8 00000108 24 A      4   2  8
+[ 4] .dynstr              NOBITS       0000000000000300 000001b8 00000077  0 A      0   0  1
+[ 5] .gnu.version         NOBITS       0000000000000378 000001b8 00000016  2 A      3   0  2
+[ 6] .gnu.version_r       NOBITS       0000000000000390 000001b8 00000020  0 A      4   1  8
+[ 7] .rela.dyn            NOBITS       00000000000003b0 000001b8 00000060 24 A      3   0  8
+[ 8] .rela.plt            NOBITS       0000000000000410 000001b8 00000018 24 A      3  10  8
+[ 9] .init                NOBITS       0000000000000428 000001b8 00000018  0 AX     0   0  4
+[10] .plt                 NOBITS       0000000000000440 000001c0 00000020 16 AX     0   0 16
+[11] .text                NOBITS       0000000000000460 000001c0 00000128  0 AX     0   0 16
+[12] .fini                NOBITS       0000000000000588 000001c0 0000000e  0 AX     0   0  4
+[13] .eh_frame_hdr        NOBITS       0000000000000598 000001c0 00000024  0 A      0   0  4
+[14] .eh_frame            NOBITS       00000000000005c0 000001c0 00000084  0 A      0   0  8
+[15] .ctors               NOBITS       0000000000200648 000001c0 00000010  0 WA     0   0  8
+[16] .dtors               NOBITS       0000000000200658 000001c0 00000010  0 WA     0   0  8
+[17] .jcr                 NOBITS       0000000000200668 000001c0 00000008  0 WA     0   0  8
+[18] .data.rel.ro         NOBITS       0000000000200670 000001c0 00000008  0 WA     0   0  8
+[19] .dynamic             NOBITS       0000000000200678 000001c0 00000180 16 WA     4   0  8
+[20] .got                 NOBITS       00000000002007f8 000001c0 00000018  8 WA     0   0  8
+[21] .got.plt             NOBITS       0000000000200810 000001c0 00000020  8 WA     0   0  8
+[22] .bss                 NOBITS       0000000000200830 000001c0 00000010  0 WA     0   0  8
+[23] .comment             NOBITS       0000000000000000 000001c0 0000002c  1 MS     0   0  1
+[24] .shstrtab            STRTAB       0000000000000000 000001c0 000000e7  0        0   0  1
+[25] .symtab              SYMTAB       0000000000000000 000002a8 000004f8 24       26  44  8
+[26] .strtab              STRTAB       0000000000000000 000007a0 00000175  0        0   0  1
+
+EOF
+
+# Explicitly remove both .symtab and .strtab. Keep .comment section. 64bit
+echo strip -g --remove-section=".s[yt][mr]tab" --keep-section=.comment testfile69.so
+testrun ${abs_top_builddir}/src/strip -g --remove-section=".s[yt][mr]tab" --keep-section=.comment -o testfile.elf -f testfile.debug testfile69.so
+echo elflint testfile.elf
+testrun ${abs_top_builddir}/src/elflint --gnu testfile.elf
+echo elflint testfile.debug
+testrun ${abs_top_builddir}/src/elflint --gnu -d testfile.debug
+echo readelf testfile.elf
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.elf <<\EOF
+There are 26 section headers, starting at offset 0x958:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .note.gnu.build-id   NOTE         0000000000000190 00000190 00000024  0 A      0   0  4
+[ 2] .gnu.hash            GNU_HASH     00000000000001b8 000001b8 0000003c  0 A      3   0  8
+[ 3] .dynsym              DYNSYM       00000000000001f8 000001f8 00000108 24 A      4   2  8
+[ 4] .dynstr              STRTAB       0000000000000300 00000300 00000077  0 A      0   0  1
+[ 5] .gnu.version         GNU_versym   0000000000000378 00000378 00000016  2 A      3   0  2
+[ 6] .gnu.version_r       GNU_verneed  0000000000000390 00000390 00000020  0 A      4   1  8
+[ 7] .rela.dyn            RELA         00000000000003b0 000003b0 00000060 24 A      3   0  8
+[ 8] .rela.plt            RELA         0000000000000410 00000410 00000018 24 A      3  10  8
+[ 9] .init                PROGBITS     0000000000000428 00000428 00000018  0 AX     0   0  4
+[10] .plt                 PROGBITS     0000000000000440 00000440 00000020 16 AX     0   0 16
+[11] .text                PROGBITS     0000000000000460 00000460 00000128  0 AX     0   0 16
+[12] .fini                PROGBITS     0000000000000588 00000588 0000000e  0 AX     0   0  4
+[13] .eh_frame_hdr        PROGBITS     0000000000000598 00000598 00000024  0 A      0   0  4
+[14] .eh_frame            PROGBITS     00000000000005c0 000005c0 00000084  0 A      0   0  8
+[15] .ctors               PROGBITS     0000000000200648 00000648 00000010  0 WA     0   0  8
+[16] .dtors               PROGBITS     0000000000200658 00000658 00000010  0 WA     0   0  8
+[17] .jcr                 PROGBITS     0000000000200668 00000668 00000008  0 WA     0   0  8
+[18] .data.rel.ro         PROGBITS     0000000000200670 00000670 00000008  0 WA     0   0  8
+[19] .dynamic             DYNAMIC      0000000000200678 00000678 00000180 16 WA     4   0  8
+[20] .got                 PROGBITS     00000000002007f8 000007f8 00000018  8 WA     0   0  8
+[21] .got.plt             PROGBITS     0000000000200810 00000810 00000020  8 WA     0   0  8
+[22] .bss                 NOBITS       0000000000200830 00000830 00000010  0 WA     0   0  8
+[23] .comment             PROGBITS     0000000000000000 00000830 0000002c  1 MS     0   0  1
+[24] .gnu_debuglink       PROGBITS     0000000000000000 0000085c 00000014  0        0   0  4
+[25] .shstrtab            STRTAB       0000000000000000 00000870 000000e6  0        0   0  1
+
+EOF
+echo readelf testfile.debug
+testrun_compare ${abs_top_builddir}/src/readelf -S testfile.debug <<\EOF
+There are 27 section headers, starting at offset 0x918:
+
+Section Headers:
+[Nr] Name                 Type         Addr             Off      Size     ES Flags Lk Inf Al
+[ 0]                      NULL         0000000000000000 00000000 00000000  0        0   0  0
+[ 1] .note.gnu.build-id   NOTE         0000000000000190 00000190 00000024  0 A      0   0  4
+[ 2] .gnu.hash            NOBITS       00000000000001b8 000001b8 0000003c  0 A      3   0  8
+[ 3] .dynsym              NOBITS       00000000000001f8 000001b8 00000108 24 A      4   2  8
+[ 4] .dynstr              NOBITS       0000000000000300 000001b8 00000077  0 A      0   0  1
+[ 5] .gnu.version         NOBITS       0000000000000378 000001b8 00000016  2 A      3   0  2
+[ 6] .gnu.version_r       NOBITS       0000000000000390 000001b8 00000020  0 A      4   1  8
+[ 7] .rela.dyn            NOBITS       00000000000003b0 000001b8 00000060 24 A      3   0  8
+[ 8] .rela.plt            NOBITS       0000000000000410 000001b8 00000018 24 A      3  10  8
+[ 9] .init                NOBITS       0000000000000428 000001b8 00000018  0 AX     0   0  4
+[10] .plt                 NOBITS       0000000000000440 000001c0 00000020 16 AX     0   0 16
+[11] .text                NOBITS       0000000000000460 000001c0 00000128  0 AX     0   0 16
+[12] .fini                NOBITS       0000000000000588 000001c0 0000000e  0 AX     0   0  4
+[13] .eh_frame_hdr        NOBITS       0000000000000598 000001c0 00000024  0 A      0   0  4
+[14] .eh_frame            NOBITS       00000000000005c0 000001c0 00000084  0 A      0   0  8
+[15] .ctors               NOBITS       0000000000200648 000001c0 00000010  0 WA     0   0  8
+[16] .dtors               NOBITS       0000000000200658 000001c0 00000010  0 WA     0   0  8
+[17] .jcr                 NOBITS       0000000000200668 000001c0 00000008  0 WA     0   0  8
+[18] .data.rel.ro         NOBITS       0000000000200670 000001c0 00000008  0 WA     0   0  8
+[19] .dynamic             NOBITS       0000000000200678 000001c0 00000180 16 WA     4   0  8
+[20] .got                 NOBITS       00000000002007f8 000001c0 00000018  8 WA     0   0  8
+[21] .got.plt             NOBITS       0000000000200810 000001c0 00000020  8 WA     0   0  8
+[22] .bss                 NOBITS       0000000000200830 000001c0 00000010  0 WA     0   0  8
+[23] .comment             NOBITS       0000000000000000 000001c0 0000002c  1 MS     0   0  1
+[24] .shstrtab            STRTAB       0000000000000000 000001c0 000000e7  0        0   0  1
+[25] .symtab              SYMTAB       0000000000000000 000002a8 000004f8 24       26  44  8
+[26] .strtab              STRTAB       0000000000000000 000007a0 00000175  0        0   0  1
+
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-strip-strmerge.sh b/third_party/elfutils/tests/run-strip-strmerge.sh
new file mode 100755
index 0000000..aa9c1eb
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-strmerge.sh
@@ -0,0 +1,79 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Generate a file with merged .shstrtab/.strtab table.
+# strip and unstrip it. Check all files with elflint.
+
+# A random ET_EXEC file
+input=${abs_top_builddir}/tests/elfstrmerge
+merged=merged.elf
+stripped=${merged}.stripped
+debugfile=${merged}.debug
+remerged=remerged.elf
+
+tempfiles $merged $stripped $debugfile $remerged
+
+echo elflint $input
+testrun ${abs_top_builddir}/src/elflint --gnu $input
+echo elfstrmerge
+testrun ${abs_top_builddir}/tests/elfstrmerge -o $merged $input
+echo elflint $merged
+testrun ${abs_top_builddir}/src/elflint --gnu $merged
+echo strip
+testrun ${abs_top_builddir}/src/strip -o $stripped -f $debugfile $merged
+echo elflint $stripped
+testrun ${abs_top_builddir}/src/elflint --gnu $stripped
+echo elflint $debugfile
+testrun ${abs_top_builddir}/src/elflint --gnu -d $debugfile
+echo unstrip
+testrun ${abs_top_builddir}/src/unstrip -o $remerged $stripped $debugfile
+echo elflint $remerged
+testrun ${abs_top_builddir}/src/elflint --gnu $remerged
+echo elfcmp
+testrun ${abs_top_builddir}/src/elfcmp $merged $remerged
+
+# A random ET_REL file
+input=${abs_top_builddir}/tests/elfstrmerge.o
+merged=merged.elf
+stripped=${merged}.stripped
+debugfile=${merged}.debug
+remerged=remerged.elf
+
+tempfiles $merged $stripped $debugfile $remerged
+
+echo elflint $input
+testrun ${abs_top_builddir}/src/elflint --gnu $input
+echo elfstrmerge
+testrun ${abs_top_builddir}/tests/elfstrmerge -o $merged $input
+echo elflint $merged
+testrun ${abs_top_builddir}/src/elflint --gnu $merged
+echo strip
+testrun ${abs_top_builddir}/src/strip -o $stripped -f $debugfile $merged
+echo elflint $stripped
+testrun ${abs_top_builddir}/src/elflint --gnu $stripped
+echo elflint $debugfile
+testrun ${abs_top_builddir}/src/elflint --gnu -d $debugfile
+echo unstrip
+testrun ${abs_top_builddir}/src/unstrip -o $remerged $stripped $debugfile
+echo elflint $remerged
+testrun ${abs_top_builddir}/src/elflint --gnu $remerged
+echo elfcmp
+testrun ${abs_top_builddir}/src/elfcmp $merged $remerged
+
+exit 0
diff --git a/third_party/elfutils/tests/run-strip-test.sh b/third_party/elfutils/tests/run-strip-test.sh
new file mode 100755
index 0000000..280814e
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-test.sh
@@ -0,0 +1,71 @@
+#! /bin/sh
+# Copyright (C) 1999, 2000, 2002, 2003, 2005, 2007, 2008 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+original=${original:-testfile11}
+stripped=${stripped:-testfile7}
+debugout=${debugfile:+-f testfile.debug.temp -F $debugfile}
+
+testfiles $original
+test x$stripped = xtestfile.temp || testfiles $stripped $debugfile
+
+tempfiles testfile.temp testfile.debug.temp testfile.unstrip
+
+testrun ${abs_top_builddir}/src/strip -o testfile.temp $debugout $original
+
+status=0
+
+cmp $stripped testfile.temp || status=$?
+
+# Check elflint and the expected result.
+testrun ${abs_top_builddir}/src/elflint --gnu -q testfile.temp || status=$?
+
+test -z "$debugfile" || {
+cmp $debugfile testfile.debug.temp || status=$?
+
+# Check elflint and the expected result.
+testrun ${abs_top_builddir}/src/elflint --gnu -q -d testfile.debug.temp || status=$?
+
+# Now test unstrip recombining those files.
+testrun ${abs_top_builddir}/src/unstrip -o testfile.unstrip testfile.temp testfile.debug.temp
+
+# Check that it came back whole.
+testrun ${abs_top_builddir}/src/elfcmp --hash-inexact $original testfile.unstrip
+}
+
+# test strip -g
+testrun ${abs_top_builddir}/src/strip -g -o testfile.temp $original
+
+# Buggy eu-strip created multiple .shstrtab sections
+shstrtab_SECS=$(testrun ${abs_top_builddir}/src/readelf -S testfile.temp | grep '.shstrtab' | wc --lines)
+test $shstrtab_SECS -eq 1 ||
+  { echo "*** failure not just one '.shstrtab' testfile.temp ($shstrtab_SECS)"; status=1; }
+
+# Now strip in-place and make sure it is smaller.
+SIZE_original=$(stat -c%s $original)
+testrun ${abs_top_builddir}/src/strip $original
+SIZE_stripped=$(stat -c%s $original)
+test $SIZE_stripped -lt $SIZE_original ||
+  { echo "*** failure in-place strip file not smaller $original"; status=1; }
+
+tempfiles testfile.sections
+testrun ${abs_top_builddir}/src/readelf -S testfile.temp > testfile.sections || status=$?
+fgrep ' .debug_' testfile.sections && status=1
+
+exit $status
diff --git a/third_party/elfutils/tests/run-strip-test10.sh b/third_party/elfutils/tests/run-strip-test10.sh
new file mode 100755
index 0000000..a867b1b
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-test10.sh
@@ -0,0 +1,22 @@
+#! /bin/sh
+# Copyright (C) H.J. Lu <hjl.tools@gmail.com>, 2015.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+original=testfile-x32
+stripped=testfile-x32-d
+debugfile=testfile-x32-debug
+
+. $srcdir/run-strip-test.sh
diff --git a/third_party/elfutils/tests/run-strip-test11.sh b/third_party/elfutils/tests/run-strip-test11.sh
new file mode 100755
index 0000000..0b1b0ab
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-test11.sh
@@ -0,0 +1,4 @@
+original=testfile-m68k
+stripped=testfile-m68k-s
+
+. $srcdir/run-strip-test.sh
diff --git a/third_party/elfutils/tests/run-strip-test2.sh b/third_party/elfutils/tests/run-strip-test2.sh
new file mode 100755
index 0000000..9217196
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-test2.sh
@@ -0,0 +1,22 @@
+#! /bin/sh
+# Copyright (C) 1999, 2000, 2002, 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+original=testfile8
+stripped=testfile9
+. $srcdir/run-strip-test.sh
diff --git a/third_party/elfutils/tests/run-strip-test3.sh b/third_party/elfutils/tests/run-strip-test3.sh
new file mode 100755
index 0000000..fb37a76
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-test3.sh
@@ -0,0 +1,22 @@
+#! /bin/sh
+# Copyright (C) 1999, 2000, 2002, 2003, 2005 Red Hat, Inc.
+# This file is part of elfutils.
+# Written by Ulrich Drepper <drepper@redhat.com>, 1999.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+original=testfile12
+stripped=testfile13
+. $srcdir/run-strip-test.sh
diff --git a/third_party/elfutils/tests/run-strip-test4.sh b/third_party/elfutils/tests/run-strip-test4.sh
new file mode 100755
index 0000000..64924a9
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-test4.sh
@@ -0,0 +1,5 @@
+original=testfile11
+stripped=testfile37
+debugfile=testfile37.debug
+
+. $srcdir/run-strip-test.sh
diff --git a/third_party/elfutils/tests/run-strip-test5.sh b/third_party/elfutils/tests/run-strip-test5.sh
new file mode 100755
index 0000000..9fa9ebe
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-test5.sh
@@ -0,0 +1,5 @@
+original=testfile8
+stripped=testfile16
+debugfile=testfile16.debug
+
+. $srcdir/run-strip-test.sh
diff --git a/third_party/elfutils/tests/run-strip-test6.sh b/third_party/elfutils/tests/run-strip-test6.sh
new file mode 100755
index 0000000..c59bf5e
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-test6.sh
@@ -0,0 +1,5 @@
+original=testfile12
+stripped=testfile35
+debugfile=testfile35.debug
+
+. $srcdir/run-strip-test.sh
diff --git a/third_party/elfutils/tests/run-strip-test7.sh b/third_party/elfutils/tests/run-strip-test7.sh
new file mode 100755
index 0000000..c65cd05
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-test7.sh
@@ -0,0 +1,5 @@
+original=testfile39
+stripped=testfile40
+debugfile=testfile40.debug
+
+. $srcdir/run-strip-test.sh
diff --git a/third_party/elfutils/tests/run-strip-test8.sh b/third_party/elfutils/tests/run-strip-test8.sh
new file mode 100755
index 0000000..fb9fa08
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-test8.sh
@@ -0,0 +1,5 @@
+original=testfile47
+stripped=testfile48
+debugfile=testfile48.debug
+
+. $srcdir/run-strip-test.sh
diff --git a/third_party/elfutils/tests/run-strip-test9.sh b/third_party/elfutils/tests/run-strip-test9.sh
new file mode 100755
index 0000000..0c6fae2
--- /dev/null
+++ b/third_party/elfutils/tests/run-strip-test9.sh
@@ -0,0 +1,21 @@
+#! /bin/sh
+# Copyright (C) H.J. Lu <hjl.tools@gmail.com>, 2015.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+original=testfile-x32
+stripped=testfile-x32-s
+. $srcdir/run-strip-test.sh
diff --git a/third_party/elfutils/tests/run-strptr.sh b/third_party/elfutils/tests/run-strptr.sh
new file mode 100755
index 0000000..af90a02
--- /dev/null
+++ b/third_party/elfutils/tests/run-strptr.sh
@@ -0,0 +1,98 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# A random 32bit and 64bit testfile
+testfiles testfile testfile10
+
+testrun_compare ${abs_top_builddir}/tests/strptr testfile <<\EOF
+Strings in section 32:
+[0] ''
+[1] '.symtab'
+[9] '.strtab'
+[11] '.shstrtab'
+[1b] '.interp'
+[23] '.note.ABI-tag'
+[31] '.hash'
+[37] '.dynsym'
+[3f] '.dynstr'
+[47] '.gnu.version'
+[54] '.gnu.version_r'
+[63] '.rel.got'
+[6c] '.rel.plt'
+[75] '.init'
+[7b] '.plt'
+[80] '.text'
+[86] '.fini'
+[8c] '.rodata'
+[94] '.data'
+[9a] '.eh_frame'
+[a4] '.ctors'
+[ab] '.dtors'
+[b2] '.got'
+[b7] '.dynamic'
+[c0] '.sbss'
+[c6] '.bss'
+[cb] '.stab'
+[d1] '.stabstr'
+[da] '.comment'
+[e3] '.debug_aranges'
+[f2] '.debug_pubnames'
+[102] '.debug_info'
+[10e] '.debug_abbrev'
+[11c] '.debug_line'
+[128] '.note'
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/strptr testfile10 <<\EOF
+Strings in section 30:
+[0] ''
+[1] '.symtab'
+[9] '.strtab'
+[11] '.shstrtab'
+[1b] '.hash'
+[21] '.dynsym'
+[29] '.dynstr'
+[31] '.gnu.version'
+[3e] '.gnu.version_r'
+[4d] '.rela.dyn'
+[57] '.init'
+[5d] '.text'
+[63] '.fini'
+[69] '.eh_frame'
+[73] '.data'
+[79] '.dynamic'
+[82] '.ctors'
+[89] '.dtors'
+[90] '.jcr'
+[95] '.plt'
+[9a] '.got'
+[9f] '.sdata'
+[a6] '.sbss'
+[ac] '.bss'
+[b1] '.comment'
+[ba] '.debug_aranges'
+[c9] '.debug_pubnames'
+[d9] '.debug_abbrev'
+[e7] '.debug_line'
+[f3] '.debug_frame'
+[100] '.debug_str'
+[10b] '.rela.debug_info'
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-test-archive64.sh b/third_party/elfutils/tests/run-test-archive64.sh
new file mode 100755
index 0000000..2d8c21d
--- /dev/null
+++ b/third_party/elfutils/tests/run-test-archive64.sh
@@ -0,0 +1,55 @@
+#! /bin/sh
+# Copyright (C) 2012, 2014 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# The test archive was produced on an s390x machine using the
+# following command sequence:
+#  echo 'int aaa(void){}' | gcc -x c /dev/stdin -c -o aaa.o
+#  echo 'int bbb(void){} int bbb2(void){}' | gcc -x c /dev/stdin -c -o bbb.o
+#  echo 'int ccc(void){} int ccc2(void){} int ccc3(void){}' \
+#    | gcc -x c /dev/stdin -c -o ccc.o
+#  ar cru testarchive64.a aaa.o bbb.o ccc.o
+testfiles testarchive64.a
+
+testrun_compare ${abs_top_builddir}/src/readelf -c testarchive64.a <<\EOF
+
+Index of archive 'testarchive64.a' has 7 entries:
+Archive member 'aaa.o' contains:
+	aaa
+Archive member 'bbb.o' contains:
+	bbb
+	bbb2
+Archive member 'ccc.o' contains:
+	ccc
+	ccc2
+	ccc3
+EOF
+
+testrun_compare ${abs_top_builddir}/src/nm -P -g testarchive64.a <<\EOF
+testarchive64.a[aaa.o]:
+aaa T 0000000000000000 0000000000000016
+testarchive64.a[bbb.o]:
+bbb T 0000000000000000 0000000000000016
+bbb2 T 0000000000000018 0000000000000016
+testarchive64.a[ccc.o]:
+ccc T 0000000000000000 0000000000000016
+ccc2 T 0000000000000018 0000000000000016
+ccc3 T 0000000000000030 0000000000000016
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-test-flag-nobits.sh b/third_party/elfutils/tests/run-test-flag-nobits.sh
new file mode 100755
index 0000000..9bedf17
--- /dev/null
+++ b/third_party/elfutils/tests/run-test-flag-nobits.sh
@@ -0,0 +1,22 @@
+#! /bin/sh
+# Copyright (C) 2010 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile
+
+testrun ${abs_builddir}/test-flag-nobits testfile
diff --git a/third_party/elfutils/tests/run-typeiter.sh b/third_party/elfutils/tests/run-typeiter.sh
new file mode 100755
index 0000000..2687bab
--- /dev/null
+++ b/third_party/elfutils/tests/run-typeiter.sh
@@ -0,0 +1,62 @@
+#! /bin/sh
+# Copyright (C) 2012, 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# struct s1
+# {
+#   char c;
+#   short s;
+#   int i;
+#   long l;
+#   float f;
+#   double d;
+# };
+# 
+# s1 S1;
+# 
+# int func (s1 *p)
+# {
+#   return p->i;
+# }
+# 
+# int main()
+# {
+#   return func (&S1);
+# }
+#
+# g++ -gdwarf-4 -g -fdebug-types-section
+
+# echo 'struct A{ struct B {} x;};A a; A::B b;int main(){return 0;}' \
+#  | g++ -x c++  -g -fdebug-types-section -o testfile-debug-types -
+
+testfiles testfile59 testfile-debug-types
+
+testrun_compare ${abs_builddir}/typeiter testfile59 <<\EOF
+ok
+EOF
+
+testrun_compare ${abs_builddir}/typeiter2 testfile59 <<\EOF
+ok s1 [25]
+EOF
+
+testrun_compare ${abs_builddir}/typeiter2 testfile-debug-types <<\EOF
+ok A [68]
+ok B [38]
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-unstrip-M.sh b/third_party/elfutils/tests/run-unstrip-M.sh
new file mode 100755
index 0000000..614a8aa
--- /dev/null
+++ b/third_party/elfutils/tests/run-unstrip-M.sh
@@ -0,0 +1,51 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Linux /proc/PID/maps file with some non-file entries (and fake exe/lib names).
+tempfiles testmaps
+cat > testmaps <<EOF
+00400000-024aa000 r-xp 00000000 08:02 159659                             /opt/TestBins/bin/arwijn
+026aa000-026b2000 rwxp 020aa000 08:02 159659                             /opt/TestBins/bin/arwijn
+026b2000-026bf000 rwxp 00000000 00:00 0
+0335a000-03e6f000 rwxp 00000000 00:00 0                                  [heap]
+2b7b38282000-2b7b38302000 rwxs 00000000 00:06 493872                     socket:[493872]
+2b7b38302000-2b7b38312000 rwxs 00000000 00:06 493872                     socket:[493872]
+2b7b38312000-2b7b38b12000 r-xs 00000000 00:06 493872                     socket:[493872]
+2b7b38b12000-2b7b38b22000 rwxs 00000000 00:06 493872                     socket:[493872]
+2b7b38b22000-2b7b39322000 rwxs 00000000 00:06 493872                     socket:[493872]
+2b7b4439f000-2b7b45ea1000 rwxp 00000000 00:00 0
+7f31e7d9f000-7f31e7f29000 r-xp 00000000 fd:00 917531                     /lib64/libc-1.13.so
+7f31e7f29000-7f31e8128000 ---p 0018a000 fd:00 917531                     /lib64/libc-1.13.so
+7f31e8128000-7f31e812c000 r--p 00189000 fd:00 917531                     /lib64/libc-1.13.so
+7f31e812c000-7f31e812d000 rw-p 0018d000 fd:00 917531                     /lib64/libc-1.13.so
+7f31e812d000-7f31e8132000 rw-p 00000000 00:00 0 
+7f31ea3f9000-7f31ea3fc000 rw-s 00000000 00:09 3744                       anon_inode:kvm-vcpu
+7f31ea3fc000-7f31ea3ff000 rw-s 00000000 00:09 3744                       anon_inode:kvm-vcpu
+7f31ea400000-7f31ea402000 rw-p 00000000 00:00 0 
+7fff26cf7000-7fff26d0c000 rwxp 00000000 00:00 0                          [stack]
+7fff26dff000-7fff26e00000 r-xp 00000000 00:00 0                          [vdso]
+ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
+EOF
+
+testrun_compare ${abs_top_builddir}/src/unstrip -n -M testmaps <<\EOF
+0x400000+0x22b2000 - - - /opt/TestBins/bin/arwijn
+0x7f31e7d9f000+0x38e000 - - - /lib64/libc-1.13.so
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/run-unstrip-n.sh b/third_party/elfutils/tests/run-unstrip-n.sh
new file mode 100755
index 0000000..37cbd60
--- /dev/null
+++ b/third_party/elfutils/tests/run-unstrip-n.sh
@@ -0,0 +1,76 @@
+#! /bin/sh
+# Copyright (C) 2012 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# https://bugzilla.redhat.com/show_bug.cgi?id=805447
+# eu-unstrip emits garbage for librt.so.1
+#
+# #include <stdio.h>
+# #include <sys/mman.h>
+# 
+# int main(int argc, char **argv)
+# {
+#  // Yes, this crashes... That is the point.
+#  return shm_open(argv[1], 0, 0);
+# }
+# 
+# gcc -m32 -o rt_crash -lrt rt_crash.c
+
+testfiles testcore-rtlib testcore-rtlib-ppc
+
+testrun_compare ${abs_top_builddir}/src/unstrip -n --core=testcore-rtlib <<\EOF
+0x8048000+0x2000 f1c600bc36cb91bf01f9a63a634ecb79aa4c3199@0x8048178 . - [exe]
+0xf75e9000+0x1a000 29a103420abe341e92072fb14274e250e4072148@0xf75e9164 - - libpthread.so.0
+0xf7603000+0x1b0000 0b9bf374699e141e5dfc14757ff42b8c2373b4de@0xf7603184 - - libc.so.6
+0xf77b3000+0x9000 c6c5b5e35ab9589d4762ac85b4bd56b1b2720e37@0xf77b3164 - - librt.so.1
+0xf77d6000+0x1000 676560b1b765cde9c2e53f134f4ee354ea894747@0xf77d6210 . - linux-gate.so.1
+0xf77d7000+0x21000 6d2cb32650054f1c176d01d48713a4a5e5e84c1a@0xf77d7124 - - ld-linux.so.2
+EOF
+
+testrun_compare ${abs_top_builddir}/src/unstrip -n --core=testcore-rtlib-ppc <<\EOF
+0x100000+0x10000 708b900b05176964512a6b0fe90c2a0c9d73d726@0x100334 . - linux-vdso32.so.1
+0xfd50000+0x30000 3f7d21508470322d2f47acddc20ab10516edba99@0xfd50164 . - librt.so.1
+0xfdb0000+0x40000 f6ee91d4c629bc7dacc10534cb30056914e7e0b5@0xfdb0164 - - libpthread.so.0
+0xfdf0000+0x1c0000 edf3dd232e09d01b90683889bd16b9406c52d4de@0xfdf0184 - - libc.so.6
+0xffb0000+0x50000 edec437a85026a1cf8cda94003706202733130c1@0xffb0124 - - ld.so.1
+0x10000000+0x20000 979b7a26747cc09bd84a42b311b5288c704baea5@0x10000174 . - [exe]
+EOF
+
+# FAIL was 0x7f67f2caf000 for test-core-lib.so .
+# /lib64/libc.so.6 and /lib64/ld-linux-x86-64.so.2 from link map
+# do not have ELF header stored in the core file.
+# ELF headers in the core file:
+# Offset   VirtAddr          
+# 0x014000 0x00007f67f2caf000 ./test-core-lib.so
+# 0x03a000 0x00007fff1596c000 linux-vdso.so.1
+testfiles test-core.core test-core.exec
+rm -f test-core-lib.so
+outfile=test-core.out
+testrun_out $outfile ${abs_top_builddir}/src/unstrip -n -e test-core.exec --core=test-core.core
+outfile2=test-core.out2
+remove_files="$remove_files $outfile2"
+grep -v libc.so.6 $outfile | sort >$outfile2
+diff -u $outfile2 - <<EOF
+0x400000+0x202038 - test-core.exec - test-core.exec
+0x7f67f2aaf000+0x202000 - . - /home/jkratoch/redhat/elfutils-libregr/test-core-lib.so
+0x7fff1596c000+0x1000 a9cf37f53897b5468ee018655760be61b8633d3c@0x7fff1596c340 . - linux-vdso.so.1
+EOF
+
+test_cleanup
+
+exit 0
diff --git a/third_party/elfutils/tests/run-unstrip-test.sh b/third_party/elfutils/tests/run-unstrip-test.sh
new file mode 100755
index 0000000..dc7d3a4
--- /dev/null
+++ b/third_party/elfutils/tests/run-unstrip-test.sh
@@ -0,0 +1,43 @@
+#! /bin/sh
+# Copyright (C) 2007-2010 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+original=${original:-testfile12}
+stripped=${stripped:-testfile17}
+debugfile=${debugfile:-${stripped}.debug}
+
+testfiles $original $stripped $debugfile
+tempfiles testfile.unstrip testfile.inplace
+
+# These are old reference output from run-test-strip6.sh, when
+# strip left the .debug file with unchanged sh_size in
+# stripped sections that shrank in the stripped file.  strip
+# no longer does that, but unstrip must still handle it.
+
+testrun ${abs_top_builddir}/src/unstrip -o testfile.unstrip $stripped $debugfile
+
+testrun ${abs_top_builddir}/src/elfcmp --hash-inexact $original testfile.unstrip
+
+# Also test modifying the file in place.
+
+rm -f testfile.inplace
+cp $debugfile testfile.inplace
+chmod 644 testfile.inplace
+testrun ${abs_top_builddir}/src/unstrip $stripped testfile.inplace
+
+testrun ${abs_top_builddir}/src/elfcmp --hash-inexact $original testfile.inplace
diff --git a/third_party/elfutils/tests/run-unstrip-test2.sh b/third_party/elfutils/tests/run-unstrip-test2.sh
new file mode 100755
index 0000000..44074c1
--- /dev/null
+++ b/third_party/elfutils/tests/run-unstrip-test2.sh
@@ -0,0 +1,5 @@
+original=testfile11
+stripped=testfile15
+debugfile=testfile15.debug
+
+. $srcdir/run-unstrip-test.sh
diff --git a/third_party/elfutils/tests/run-unstrip-test3.sh b/third_party/elfutils/tests/run-unstrip-test3.sh
new file mode 100755
index 0000000..5459e72
--- /dev/null
+++ b/third_party/elfutils/tests/run-unstrip-test3.sh
@@ -0,0 +1,17 @@
+# Buggy binutils objdump might strip SHF_INFO_LINK from relocation sections.
+# With gcc5 we might have a .rela.plt section with that flag set.
+#
+# int main() 
+# {
+#     return 0;
+# }
+#
+# gcc -o testfile-info-link -g testprog.c
+# objcopy --only-keep-debug testfile-info-link testfile-info-link.debuginfo
+# eu-strip --strip-debug -o testfile-info-link.stripped testfile-info-link
+
+original=testfile-info-link
+stripped=testfile-info-link.stripped
+debugfile=testfile-info-link.debuginfo
+
+. $srcdir/run-unstrip-test.sh
diff --git a/third_party/elfutils/tests/run-unstrip-test4.sh b/third_party/elfutils/tests/run-unstrip-test4.sh
new file mode 100755
index 0000000..6ca5d0e
--- /dev/null
+++ b/third_party/elfutils/tests/run-unstrip-test4.sh
@@ -0,0 +1,18 @@
+# Test whether unstrip can combine a stripped kernel object that has
+# limited .symtab/.strtab data, with a separate .debuginfo binary that
+# has full .symtab/.strtab data.
+#
+# This was generated as part of a Chromium OS kernel build:
+#
+#   emerge-kevin chromeos-kernel-4_4
+#
+# Setup instructions:
+#
+#   https://www.chromium.org/chromium-os/developer-guide
+#   https://www.chromium.org/chromium-os/how-tos-and-troubleshooting/kernel-faq
+
+original=testfile-strtab
+stripped=testfile-strtab.stripped
+debugfile=testfile-strtab.debuginfo
+
+. $srcdir/run-unstrip-test.sh
diff --git a/third_party/elfutils/tests/run-varlocs-self.sh b/third_party/elfutils/tests/run-varlocs-self.sh
new file mode 100755
index 0000000..54b6a8d
--- /dev/null
+++ b/third_party/elfutils/tests/run-varlocs-self.sh
@@ -0,0 +1,22 @@
+#! /bin/sh
+# Copyright (C) 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# Make sure varlocs doesn't crash, doesn't trigger self-check/asserts
+# or leaks running under valgrind.
+testrun_on_self_quiet ${abs_top_builddir}/tests/varlocs -e
diff --git a/third_party/elfutils/tests/run-varlocs.sh b/third_party/elfutils/tests/run-varlocs.sh
new file mode 100755
index 0000000..9c4b313
--- /dev/null
+++ b/third_party/elfutils/tests/run-varlocs.sh
@@ -0,0 +1,128 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# See the source files testfile_const_type.c testfile_implicit_value.c
+# testfile_entry_value.c testfile_parameter_ref.c testfile_implicit_pointer.c
+# how to regenerate the test files (needs GCC 4.8+).
+
+testfiles testfile_const_type testfile_implicit_value testfile_entry_value
+testfiles testfile_parameter_ref testfile_implicit_pointer
+
+testrun_compare ${abs_top_builddir}/tests/varlocs -e testfile_const_type <<\EOF
+module 'testfile_const_type'
+[b] CU 'const_type.c'@0
+  [33] function 'f1'@80483f0
+    frame_base: {call_frame_cfa {bregx(4,4)}}
+    [4b] parameter 'd'
+      [80483f0,804841b) {fbreg(0)}
+    [57] variable 'w'
+      [80483f0,804841b) {fbreg(0), GNU_deref_type(8){long long int,signed,64@[25]}, GNU_const_type{long long int,signed,64@[25]}(8)[0000806745230100], div, GNU_convert{long long unsigned int,unsigned,64@[2c]}, stack_value}
+  [7d] function 'main'@80482f0
+    frame_base: {call_frame_cfa {bregx(4,4)}}
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/varlocs -e testfile_implicit_value <<\EOF
+module 'testfile_implicit_value'
+[b] CU 'implicit_value.c'@0
+  [25] function 'foo'@80483f0
+    frame_base: {call_frame_cfa {bregx(4,4)}}
+    [3e] variable 'a'
+      [80483f0,80483f6) {implicit_value(8){0200000000000000}, piece(8), implicit_value(8){1500000000000000}, piece(8)}
+  [86] function 'main'@80482f0
+    frame_base: {call_frame_cfa {bregx(4,4)}}
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/varlocs -e testfile_entry_value <<\EOF
+module 'testfile_entry_value'
+[b] CU 'entry_value.c'@0
+  [29] function 'foo'@400500
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [4a] parameter 'x'
+      [400500,400504) {reg5}
+    [55] parameter 'y'
+      [400500,400504) {reg4}
+  [68] function 'bar'@400510
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [89] parameter 'x'
+      [400510,40051c) {reg5}
+      [40051c,40052b) {reg6}
+      [40052b,400531) {GNU_entry_value(1) {reg5}, stack_value}
+    [96] parameter 'y'
+      [400510,40051c) {reg4}
+      [40051c,40052a) {reg3}
+      [40052a,400531) {GNU_entry_value(1) {reg4}, stack_value}
+    [a3] variable 'z'
+      [400524,400528) {reg0}
+      [400528,400529) {reg12}
+      [400529,40052e) {breg0(0), breg12(0), plus, stack_value}
+      [40052e,400531) {reg0}
+  [e9] function 'main'@400400
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [10a] parameter 'argc'
+      [400400,400406) {reg5}
+      [400406,40040a) {breg5(-1), stack_value}
+      [40040a,40040b) {GNU_entry_value(1) {reg5}, stack_value}
+    [119] parameter 'argv'
+      [400400,400403) {reg4}
+      [400403,40040b) {GNU_entry_value(1) {reg4}, stack_value}
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/varlocs -e testfile_parameter_ref <<\EOF
+module 'testfile_parameter_ref'
+[b] CU 'parameter_ref.c'@0
+  [77] function 'foo'@400510
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [92] parameter 'x'
+      [400510,400523) {reg5}
+    [99] parameter 'y'
+      [400510,400523) {GNU_parameter_ref[42], stack_value}
+    [a5] variable 'a'
+      [400510,400523) {breg5(0), lit1, shl, stack_value}
+    [b0] variable 'b'
+      [400510,400523) {GNU_parameter_ref[42], lit1, shl, stack_value}
+    [be] variable 'c'
+      <constant value>
+    [c4] parameter 'z'
+      <constant value>
+  [cb] function 'main'@400400
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [ec] parameter 'x'
+      [400400,400408) {reg5}
+      [400408,400421) {reg3}
+      [400421,400423) {GNU_entry_value(1) {reg5}, stack_value}
+    [f9] parameter 'argv'
+      [400400,400408) {reg4}
+      [400408,400423) {GNU_entry_value(1) {reg4}, stack_value}
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/varlocs -e testfile_implicit_pointer <<\EOF
+module 'testfile_implicit_pointer'
+[b] CU 'implicit_pointer.c'@0
+  [29] function 'foo'@400500
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+    [4a] parameter 'i'
+      [400500,400503) {reg5}
+    [55] variable 'p'
+      [400500,400503) {GNU_implicit_pointer([4a],0) {reg5}}
+  [73] function 'main'@400400
+    frame_base: {call_frame_cfa {bregx(7,8)}}
+EOF
+
+
+exit 0
diff --git a/third_party/elfutils/tests/run-zstrptr.sh b/third_party/elfutils/tests/run-zstrptr.sh
new file mode 100755
index 0000000..254dcd8
--- /dev/null
+++ b/third_party/elfutils/tests/run-zstrptr.sh
@@ -0,0 +1,167 @@
+#! /bin/sh
+# Copyright (C) 2015 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+# A random 32bit and 64bit testfile
+testfiles testfile testfile10
+
+testrun_compare ${abs_top_builddir}/tests/zstrptr testfile <<\EOF
+Strings in section 32 (compressed):
+[0] ''
+[1] '.symtab'
+[9] '.strtab'
+[11] '.shstrtab'
+[1b] '.interp'
+[23] '.note.ABI-tag'
+[31] '.hash'
+[37] '.dynsym'
+[3f] '.dynstr'
+[47] '.gnu.version'
+[54] '.gnu.version_r'
+[63] '.rel.got'
+[6c] '.rel.plt'
+[75] '.init'
+[7b] '.plt'
+[80] '.text'
+[86] '.fini'
+[8c] '.rodata'
+[94] '.data'
+[9a] '.eh_frame'
+[a4] '.ctors'
+[ab] '.dtors'
+[b2] '.got'
+[b7] '.dynamic'
+[c0] '.sbss'
+[c6] '.bss'
+[cb] '.stab'
+[d1] '.stabstr'
+[da] '.comment'
+[e3] '.debug_aranges'
+[f2] '.debug_pubnames'
+[102] '.debug_info'
+[10e] '.debug_abbrev'
+[11c] '.debug_line'
+[128] '.note'
+Strings in section 32 (uncompressed):
+[0] ''
+[1] '.symtab'
+[9] '.strtab'
+[11] '.shstrtab'
+[1b] '.interp'
+[23] '.note.ABI-tag'
+[31] '.hash'
+[37] '.dynsym'
+[3f] '.dynstr'
+[47] '.gnu.version'
+[54] '.gnu.version_r'
+[63] '.rel.got'
+[6c] '.rel.plt'
+[75] '.init'
+[7b] '.plt'
+[80] '.text'
+[86] '.fini'
+[8c] '.rodata'
+[94] '.data'
+[9a] '.eh_frame'
+[a4] '.ctors'
+[ab] '.dtors'
+[b2] '.got'
+[b7] '.dynamic'
+[c0] '.sbss'
+[c6] '.bss'
+[cb] '.stab'
+[d1] '.stabstr'
+[da] '.comment'
+[e3] '.debug_aranges'
+[f2] '.debug_pubnames'
+[102] '.debug_info'
+[10e] '.debug_abbrev'
+[11c] '.debug_line'
+[128] '.note'
+EOF
+
+testrun_compare ${abs_top_builddir}/tests/zstrptr testfile10 <<\EOF
+Strings in section 30 (compressed):
+[0] ''
+[1] '.symtab'
+[9] '.strtab'
+[11] '.shstrtab'
+[1b] '.hash'
+[21] '.dynsym'
+[29] '.dynstr'
+[31] '.gnu.version'
+[3e] '.gnu.version_r'
+[4d] '.rela.dyn'
+[57] '.init'
+[5d] '.text'
+[63] '.fini'
+[69] '.eh_frame'
+[73] '.data'
+[79] '.dynamic'
+[82] '.ctors'
+[89] '.dtors'
+[90] '.jcr'
+[95] '.plt'
+[9a] '.got'
+[9f] '.sdata'
+[a6] '.sbss'
+[ac] '.bss'
+[b1] '.comment'
+[ba] '.debug_aranges'
+[c9] '.debug_pubnames'
+[d9] '.debug_abbrev'
+[e7] '.debug_line'
+[f3] '.debug_frame'
+[100] '.debug_str'
+[10b] '.rela.debug_info'
+Strings in section 30 (uncompressed):
+[0] ''
+[1] '.symtab'
+[9] '.strtab'
+[11] '.shstrtab'
+[1b] '.hash'
+[21] '.dynsym'
+[29] '.dynstr'
+[31] '.gnu.version'
+[3e] '.gnu.version_r'
+[4d] '.rela.dyn'
+[57] '.init'
+[5d] '.text'
+[63] '.fini'
+[69] '.eh_frame'
+[73] '.data'
+[79] '.dynamic'
+[82] '.ctors'
+[89] '.dtors'
+[90] '.jcr'
+[95] '.plt'
+[9a] '.got'
+[9f] '.sdata'
+[a6] '.sbss'
+[ac] '.bss'
+[b1] '.comment'
+[ba] '.debug_aranges'
+[c9] '.debug_pubnames'
+[d9] '.debug_abbrev'
+[e7] '.debug_line'
+[f3] '.debug_frame'
+[100] '.debug_str'
+[10b] '.rela.debug_info'
+EOF
+
+exit 0
diff --git a/third_party/elfutils/tests/saridx.c b/third_party/elfutils/tests/saridx.c
new file mode 100644
index 0000000..8a450d8
--- /dev/null
+++ b/third_party/elfutils/tests/saridx.c
@@ -0,0 +1,257 @@
+/* Copyright (C) 1998, 1999, 2000, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+
+static const char *machines[] =
+{
+#define MACHINE(name) [name] = #name
+  MACHINE (EM_NONE),
+  MACHINE (EM_M32),
+  MACHINE (EM_SPARC),
+  MACHINE (EM_386),
+  MACHINE (EM_68K),
+  MACHINE (EM_88K),
+  MACHINE (EM_860),
+  MACHINE (EM_MIPS),
+  MACHINE (EM_MIPS_RS3_LE),
+  MACHINE (EM_PARISC),
+  MACHINE (EM_VPP500),
+  MACHINE (EM_SPARC32PLUS),
+  MACHINE (EM_960),
+  MACHINE (EM_PPC),
+  MACHINE (EM_PPC64),
+  MACHINE (EM_V800),
+  MACHINE (EM_FR20),
+  MACHINE (EM_RH32),
+  MACHINE (EM_RCE),
+  MACHINE (EM_ARM),
+  MACHINE (EM_FAKE_ALPHA),
+  MACHINE (EM_SH),
+  MACHINE (EM_SPARCV9),
+  MACHINE (EM_TRICORE),
+  MACHINE (EM_ARC),
+  MACHINE (EM_H8_300),
+  MACHINE (EM_H8_300H),
+  MACHINE (EM_H8S),
+  MACHINE (EM_H8_500),
+  MACHINE (EM_IA_64),
+  MACHINE (EM_MIPS_X),
+  MACHINE (EM_COLDFIRE),
+  MACHINE (EM_68HC12),
+  MACHINE (EM_MMA),
+  MACHINE (EM_PCP),
+  MACHINE (EM_NCPU),
+  MACHINE (EM_NDR1),
+  MACHINE (EM_STARCORE),
+  MACHINE (EM_ME16),
+  MACHINE (EM_ST100),
+  MACHINE (EM_TINYJ),
+  MACHINE (EM_FX66),
+  MACHINE (EM_ST9PLUS),
+  MACHINE (EM_ST7),
+  MACHINE (EM_68HC16),
+  MACHINE (EM_68HC11),
+  MACHINE (EM_68HC08),
+  MACHINE (EM_68HC05),
+  MACHINE (EM_SVX),
+  MACHINE (EM_ST19),
+  MACHINE (EM_VAX)
+};
+
+
+int
+main (int argc, char *argv[])
+{
+  int fd;
+  Elf *elf;
+  Elf_Cmd cmd;
+  size_t n;
+  int arg = 1;
+  int verbose = 0;
+
+  /* Recognize optional verbosity flag.  */
+  if (arg < argc && strcmp (argv[arg], "-v") == 0)
+    {
+      verbose = 1;
+      ++arg;
+    }
+
+  /* Any more arguments available.  */
+  if (arg >= argc)
+    error (EXIT_FAILURE, 0, "No input file given");
+
+  /* Open the input file.  */
+  fd = open (argv[arg], O_RDONLY);
+  if (fd == -1)
+    {
+      perror ("cannot open input file");
+      exit (1);
+    }
+
+  /* Set the ELF version we are using here.  */
+  if (elf_version (EV_CURRENT) == EV_NONE)
+    {
+      puts ("ELF library too old");
+      exit (1);
+    }
+
+  /* Start reading the file.  */
+  cmd = ELF_C_READ;
+  elf = elf_begin (fd, cmd, NULL);
+  if (elf == NULL)
+    {
+      printf ("elf_begin: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* If it is no archive punt.  */
+  if (elf_kind (elf) != ELF_K_AR)
+    {
+      printf ("%s is not an archive\n", argv[1]);
+      exit (1);
+    }
+
+  if (verbose)
+    {
+      /* The verbose variant.  We print a lot of information.  */
+      Elf *subelf;
+      char buf[100];
+      time_t t;
+
+      /* Get the elements of the archive one after the other.  */
+      while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
+	{
+	  /* The the header for this element.  */
+	  Elf_Arhdr *arhdr = elf_getarhdr (subelf);
+
+	  if (arhdr == NULL)
+	    {
+	      printf ("cannot get arhdr: %s\n", elf_errmsg (-1));
+	      break;
+	    }
+
+	  switch (elf_kind (subelf))
+	    {
+	    case ELF_K_ELF:
+	      fputs ("ELF file:\n", stdout);
+	      break;
+
+	    case ELF_K_AR:
+	      fputs ("archive:\n", stdout);
+	      break;
+
+	    default:
+	      fputs ("unknown file:\n", stdout);
+	      break;
+	    }
+
+	  /* Print general information.  */
+	  t = arhdr->ar_date;
+	  strftime (buf, sizeof buf, "%Y-%m-%dT%H:%M:%S%z", gmtime (&t));
+	  printf ("  name         : \"%s\"\n"
+		  "  time         : %s\n"
+		  "  uid          : %ld\n"
+		  "  gid          : %ld\n"
+		  "  mode         : %o\n"
+		  "  size         : %ld\n"
+		  "  rawname      : \"%s\"\n",
+		  arhdr->ar_name,
+		  buf,
+		  (long int) arhdr->ar_uid,
+		  (long int) arhdr->ar_gid,
+		  arhdr->ar_mode,
+		  (long int) arhdr->ar_size,
+		  arhdr->ar_rawname);
+
+	  /* For ELF files we can provide some more information.  */
+	  if (elf_kind (subelf) == ELF_K_ELF)
+	    {
+	      GElf_Ehdr ehdr;
+
+	      /* Get the ELF header.  */
+	      if (gelf_getehdr (subelf, &ehdr) == NULL)
+		printf ("  *** cannot get ELF header: %s\n", elf_errmsg (-1));
+	      else
+		{
+		  printf ("  binary class : %s\n",
+			  ehdr.e_ident[EI_CLASS] == ELFCLASS32
+			  ? "ELFCLASS32" : "ELFCLASS64");
+		  printf ("  data encoding: %s\n",
+			  ehdr.e_ident[EI_DATA] == ELFDATA2LSB
+			  ? "ELFDATA2LSB" : "ELFDATA2MSB");
+		  printf ("  binary type  : %s\n",
+			  ehdr.e_type == ET_REL
+			  ? "relocatable"
+			  : (ehdr.e_type == ET_EXEC
+			     ? "executable"
+			     : (ehdr.e_type == ET_DYN
+				? "dynamic"
+				: "core file")));
+		  printf ("  machine      : %s\n",
+			  (ehdr.e_machine >= (sizeof (machines)
+					      / sizeof (machines[0]))
+			   || machines[ehdr.e_machine] == NULL)
+			  ? "???"
+			  : machines[ehdr.e_machine]);
+		}
+	    }
+
+	  /* Get next archive element.  */
+	  cmd = elf_next (subelf);
+	  if (elf_end (subelf) != 0)
+	    printf ("error while freeing sub-ELF descriptor: %s\n",
+		    elf_errmsg (-1));
+	}
+    }
+  else
+    {
+      /* The simple version.  Only print a bit of information.  */
+      Elf_Arsym *arsym = elf_getarsym (elf, &n);
+
+      if (n == 0)
+	printf ("no symbol table in archive: %s\n", elf_errmsg (-1));
+      else
+	{
+	  --n;
+
+	  while (n-- > 0)
+	    printf ("name = \"%s\", offset = %ld, hash = %lx\n",
+		    arsym[n].as_name, (long int) arsym[n].as_off,
+		    arsym[n].as_hash);
+	}
+    }
+
+  /* Free the ELF handle.  */
+  if (elf_end (elf) != 0)
+    printf ("error while freeing ELF descriptor: %s\n", elf_errmsg (-1));
+
+  /* Close the underlying file.  */
+  close (fd);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/scnnames.c b/third_party/elfutils/tests/scnnames.c
new file mode 100644
index 0000000..7f26825
--- /dev/null
+++ b/third_party/elfutils/tests/scnnames.c
@@ -0,0 +1,91 @@
+/* Copyright (C) 1998, 1999, 2000, 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+  Elf *elf;
+  int fd;
+  GElf_Ehdr ehdr;
+  size_t strndx;
+  Elf_Scn *scn;
+
+  if (argc < 2)
+    {
+      puts ("missing parameter");
+      exit (1);
+    }
+
+  fd = open (argv[1], O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open \"%s\": %s\n", argv[1], strerror (errno));
+      exit (1);
+    }
+
+  elf_version (EV_CURRENT);
+
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot open ELF file: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (elf_kind (elf) != ELF_K_ELF)
+    {
+      printf ("\"%s\" is not an ELF file\n", argv[1]);
+      exit (1);
+    }
+
+  if (gelf_getehdr (elf, &ehdr) == NULL)
+    {
+      printf ("cannot get the ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  strndx = ehdr.e_shstrndx;
+
+  scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      char *name = NULL;
+      GElf_Shdr shdr;
+
+      if (gelf_getshdr (scn, &shdr) != NULL)
+	name = elf_strptr (elf, strndx, (size_t) shdr.sh_name);
+
+      printf ("section: `%s'\n", name);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("error while freeing ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/sectiondump.c b/third_party/elfutils/tests/sectiondump.c
new file mode 100644
index 0000000..3033fed
--- /dev/null
+++ b/third_party/elfutils/tests/sectiondump.c
@@ -0,0 +1,182 @@
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <errno.h>
+#include <error.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+/* Prototypes for local functions.  */
+static int handle_section (Elf *elf, Elf_Scn *scn);
+static void print_bytes (Elf_Data *data);
+static void print_symtab (Elf *elf, Elf_Data *data);
+
+
+int
+main (int argc, char *argv[])
+{
+  Elf *elf;
+  int fd;
+  int cnt;
+
+  if (argc <= 1)
+    exit (1);
+
+  /* Open the test file.  This is given as the first parameter to the
+     program.  */
+  fd = open (argv[1], O_RDONLY);
+  if (fd == -1)
+    error (EXIT_FAILURE, errno, "cannot open input file `%s'", argv[1]);
+
+  /* Set the library versio we expect.  */
+  elf_version (EV_CURRENT);
+
+  /* Create the ELF descriptor.  */
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    error (EXIT_FAILURE, 0, "cannot create ELF descriptor: %s",
+	   elf_errmsg (0));
+
+  /* Now proces all the sections mentioned in the rest of the command line.  */
+  for (cnt = 2; cnt < argc; ++cnt)
+    if (handle_section (elf, elf_getscn (elf, atoi (argv[cnt]))) != 0)
+      /* When we encounter an error stop immediately.  */
+      error (EXIT_FAILURE, 0, "while processing section %d: %s", cnt,
+	   elf_errmsg (0));
+
+  /* Close the descriptor.  */
+  if (elf_end (elf) != 0)
+    error (EXIT_FAILURE, 0, "failure while closing ELF descriptor: %s",
+	   elf_errmsg (0));
+
+  return 0;
+}
+
+
+static int
+handle_section (Elf *elf, Elf_Scn *scn)
+{
+  GElf_Ehdr *ehdr;
+  GElf_Ehdr ehdr_mem;
+  GElf_Shdr *shdr;
+  GElf_Shdr shdr_mem;
+  Elf_Data *data;
+
+  /* First get the ELF and section header.  */
+  ehdr = gelf_getehdr (elf, &ehdr_mem);
+  shdr = gelf_getshdr (scn, &shdr_mem);
+  if (ehdr == NULL || shdr == NULL)
+    return 1;
+
+  /* Print the information from the ELF section header.   */
+  printf ("name      = %s\n"
+	  "type      = %" PRId32 "\n"
+	  "flags     = %" PRIx64 "\n"
+	  "addr      = %" PRIx64 "\n"
+	  "offset    = %" PRIx64 "\n"
+	  "size      = %" PRId64 "\n"
+	  "link      = %" PRId32 "\n"
+	  "info      = %" PRIx32 "\n"
+	  "addralign = %" PRIx64 "\n"
+	  "entsize   = %" PRId64 "\n",
+	  elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
+	  shdr->sh_type,
+	  shdr->sh_flags,
+	  shdr->sh_addr,
+	  shdr->sh_offset,
+	  shdr->sh_size,
+	  shdr->sh_link,
+	  shdr->sh_info,
+	  shdr->sh_addralign,
+	  shdr->sh_entsize);
+
+  /* Get the section data now.  */
+  data = elf_getdata (scn, NULL);
+  if (data == NULL)
+    return 1;
+
+  /* Now proces the different section types accordingly.  */
+  switch (shdr->sh_type)
+    {
+    case SHT_SYMTAB:
+      print_symtab (elf, data);
+      break;
+
+    case SHT_PROGBITS:
+    default:
+      print_bytes (data);
+      break;
+    }
+
+  /* Separate form the next section.  */
+  puts ("");
+
+  /* All done correctly.  */
+  return 0;
+}
+
+
+static void
+print_bytes (Elf_Data *data)
+{
+  size_t size = data->d_size;
+  off_t offset = data->d_off;
+  unsigned char *buf = (unsigned char *) data->d_buf;
+  size_t cnt;
+
+  for (cnt = 0; cnt < size; cnt += 16)
+    {
+      size_t inner;
+
+      printf ("%*zx: ", sizeof (size_t) == 4 ? 8 : 16, (size_t) offset + cnt);
+
+      for (inner = 0; inner < 16 && cnt + inner < size; ++inner)
+	printf (" %02hhx", buf[cnt + inner]);
+
+      puts ("");
+    }
+}
+
+
+static void
+print_symtab (Elf *elf, Elf_Data *data)
+{
+  int class = gelf_getclass (elf);
+  size_t nsym = data->d_size / (class == ELFCLASS32
+				? sizeof (Elf32_Sym) : sizeof (Elf64_Sym));
+  size_t cnt;
+
+  for (cnt = 0; cnt < nsym; ++cnt)
+    {
+      GElf_Sym sym_mem;
+      GElf_Sym *sym = gelf_getsym (data, cnt, &sym_mem);
+
+      printf ("%5zu: %*" PRIx64 " %6" PRIx64 " %4d\n",
+	      cnt,
+	      class == ELFCLASS32 ? 8 : 16,
+	      sym->st_value,
+	      sym->st_size,
+	      GELF_ST_TYPE (sym->st_info));
+    }
+}
diff --git a/third_party/elfutils/tests/show-abbrev.c b/third_party/elfutils/tests/show-abbrev.c
new file mode 100644
index 0000000..b0af029
--- /dev/null
+++ b/third_party/elfutils/tests/show-abbrev.c
@@ -0,0 +1,131 @@
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <fcntl.h>
+#include <inttypes.h>
+#include ELFUTILS_HEADER(dw)
+#include <stdio.h>
+#include <unistd.h>
+
+
+int
+main (int argc, char *argv[])
+{
+  int cnt;
+
+  for (cnt = 1; cnt < argc; ++cnt)
+    {
+      int fd = open (argv[cnt], O_RDONLY);
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if  (dbg == NULL)
+	{
+	  printf ("%s not usable: %s\n", argv[cnt], dwarf_errmsg (-1));
+	  close  (fd);
+	  continue;
+	}
+
+      Dwarf_Off cuoff = 0;
+      Dwarf_Off old_cuoff = 0;
+      size_t hsize;
+      while (dwarf_nextcu (dbg, cuoff, &cuoff, &hsize, NULL, NULL, NULL) == 0)
+	{
+	  /* Get the DIE for the CU.  */
+	  Dwarf_Die die;
+ 	  if (dwarf_offdie (dbg, old_cuoff + hsize, &die) == NULL)
+	    /* Something went wrong.  */
+	    break;
+
+	  Dwarf_Off offset = 0;
+
+	  while (1)
+	    {
+	      size_t length;
+	      Dwarf_Abbrev *abbrev = dwarf_getabbrev (&die, offset, &length);
+	      if (abbrev == NULL || abbrev == DWARF_END_ABBREV)
+		/* End of the list.  */
+		break;
+
+	      unsigned tag = dwarf_getabbrevtag (abbrev);
+	      if (tag == 0)
+		{
+		  printf ("dwarf_getabbrevtag at offset %llu returned error: %s\n",
+			  (unsigned long long int) offset,
+			  dwarf_errmsg (-1));
+		  break;
+		}
+
+	      unsigned code = dwarf_getabbrevcode (abbrev);
+	      if (code == 0)
+		{
+		  printf ("dwarf_getabbrevcode at offset %llu returned error: %s\n",
+			  (unsigned long long int) offset,
+			  dwarf_errmsg (-1));
+		  break;
+		}
+
+	      int children = dwarf_abbrevhaschildren (abbrev);
+	      if (children < 0)
+		{
+		  printf ("dwarf_abbrevhaschildren at offset %llu returned error: %s\n",
+			  (unsigned long long int) offset,
+			  dwarf_errmsg (-1));
+		  break;
+		}
+
+	      printf ("abbrev[%llu]: code = %u, tag = %u, children = %d\n",
+		      (unsigned long long int) offset, code, tag, children);
+
+	      size_t attrcnt;
+	      if (dwarf_getattrcnt (abbrev, &attrcnt) != 0)
+		{
+		  printf ("dwarf_getattrcnt at offset %llu returned error: %s\n",
+			  (unsigned long long int) offset,
+			  dwarf_errmsg (-1));
+		  break;
+		}
+
+	      unsigned int attr_num;
+	      unsigned int attr_form;
+	      Dwarf_Off aboffset;
+	      size_t j;
+	      for (j = 0; j < attrcnt; ++j)
+		if (dwarf_getabbrevattr (abbrev, j, &attr_num, &attr_form,
+					 &aboffset))
+		  printf ("dwarf_getabbrevattr for abbrev[%llu] and index %zu failed\n",
+			  (unsigned long long int) offset, j);
+		else
+		  printf ("abbrev[%llu]: attr[%zu]: code = %u, form = %u, offset = %" PRIu64 "\n",
+			  (unsigned long long int) offset, j, attr_num,
+			  attr_form, (uint64_t) aboffset);
+
+	      offset += length;
+	    }
+
+	  old_cuoff = cuoff;
+	}
+
+      if (dwarf_end (dbg) != 0)
+	printf ("dwarf_end failed for %s: %s\n", argv[cnt],
+		dwarf_errmsg (-1));
+
+      close (fd);
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/show-die-info.c b/third_party/elfutils/tests/show-die-info.c
new file mode 100644
index 0000000..34e27a3
--- /dev/null
+++ b/third_party/elfutils/tests/show-die-info.c
@@ -0,0 +1,358 @@
+/* Copyright (C) 1998-2002, 2004, 2006, 2012, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <dwarf.h>
+#include <inttypes.h>
+#include <libelf.h>
+#include ELFUTILS_HEADER(dw)
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "../libdw/known-dwarf.h"
+
+static const char *
+dwarf_tag_string (unsigned int tag)
+{
+  switch (tag)
+    {
+#define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_TAG
+#undef DWARF_ONE_KNOWN_DW_TAG
+    default:
+      return NULL;
+    }
+}
+
+static const char *
+dwarf_attr_string (unsigned int attrnum)
+{
+  switch (attrnum)
+    {
+#define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_AT
+#undef DWARF_ONE_KNOWN_DW_AT
+    default:
+      return NULL;
+    }
+}
+
+
+void
+handle (Dwarf *dbg, Dwarf_Die *die, int n)
+{
+  Dwarf_Die child;
+  unsigned int tag;
+  const char *str;
+  char buf[30];
+  const char *name;
+  Dwarf_Off off;
+  Dwarf_Off cuoff;
+  size_t cnt;
+  Dwarf_Addr addr;
+  int i;
+
+  tag = dwarf_tag (die);
+  if (tag != DW_TAG_invalid)
+    {
+      str = dwarf_tag_string (tag);
+      if (str == NULL)
+	{
+	  snprintf (buf, sizeof buf, "%#x", tag);
+	  str = buf;
+	}
+    }
+  else
+    str = "* NO TAG *";
+
+  name = dwarf_diename (die);
+  if (name == 0)
+    name = "* NO NAME *";
+
+  off = dwarf_dieoffset (die);
+  cuoff = dwarf_cuoffset (die);
+
+  printf ("%*sDW_TAG_%s\n", n * 5, "", str);
+  printf ("%*s Name      : %s\n", n * 5, "", name);
+  printf ("%*s Offset    : %lld\n", n * 5, "", (long long int) off);
+  printf ("%*s CU offset : %lld\n", n * 5, "", (long long int) cuoff);
+
+  printf ("%*s Attrs     :", n * 5, "");
+  for (cnt = 0; cnt < 0xffff; ++cnt)
+    if (dwarf_hasattr (die, cnt))
+      printf (" %s", dwarf_attr_string (cnt));
+  puts ("");
+
+  if (dwarf_hasattr (die, DW_AT_low_pc) && dwarf_lowpc (die, &addr) == 0)
+    {
+      Dwarf_Attribute attr;
+      Dwarf_Addr addr2;
+      printf ("%*s low PC    : %#llx\n",
+	      n * 5, "", (unsigned long long int) addr);
+
+      if (dwarf_attr (die, DW_AT_low_pc, &attr) == NULL
+	  || dwarf_formaddr (&attr, &addr2) != 0
+	  || addr != addr2)
+	puts ("************* DW_AT_low_pc verify failed ************");
+      else if (! dwarf_hasform (&attr, DW_FORM_addr))
+	puts ("************* DW_AT_low_pc form failed ************");
+      else if (dwarf_whatform (&attr) != DW_FORM_addr)
+	puts ("************* DW_AT_low_pc form (2) failed ************");
+      else if (dwarf_whatattr (&attr) != DW_AT_low_pc)
+	puts ("************* DW_AT_low_pc attr failed ************");
+    }
+  if (dwarf_hasattr (die, DW_AT_high_pc) && dwarf_highpc (die, &addr) == 0)
+    {
+      Dwarf_Attribute attr;
+      Dwarf_Addr addr2;
+      printf ("%*s high PC   : %#llx\n",
+	      n * 5, "", (unsigned long long int) addr);
+      if (dwarf_attr (die, DW_AT_high_pc, &attr) == NULL
+	  || dwarf_formaddr (&attr, &addr2) != 0
+	  || addr != addr2)
+	puts ("************* DW_AT_high_pc verify failed ************");
+      else if (! dwarf_hasform (&attr, DW_FORM_addr))
+	puts ("************* DW_AT_high_pc form failed ************");
+      else if (dwarf_whatform (&attr) != DW_FORM_addr)
+	puts ("************* DW_AT_high_pc form (2) failed ************");
+      else if (dwarf_whatattr (&attr) != DW_AT_high_pc)
+	puts ("************* DW_AT_high_pc attr failed ************");
+    }
+
+  if (dwarf_hasattr (die, DW_AT_byte_size) && (i = dwarf_bytesize (die)) != -1)
+    {
+      Dwarf_Attribute attr;
+      Dwarf_Word u2;
+      unsigned int u;
+      printf ("%*s byte size : %d\n", n * 5, "", i);
+      if (dwarf_attr (die, DW_AT_byte_size, &attr) == NULL
+	  || dwarf_formudata (&attr, &u2) != 0
+	  || i != (int) u2)
+	puts ("************* DW_AT_byte_size verify failed ************");
+      else if (! dwarf_hasform (&attr, DW_FORM_data1)
+	       && ! dwarf_hasform (&attr, DW_FORM_data2)
+	       && ! dwarf_hasform (&attr, DW_FORM_data4)
+	       && ! dwarf_hasform (&attr, DW_FORM_data8)
+	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
+	       && ! dwarf_hasform (&attr, DW_FORM_udata))
+	puts ("************* DW_AT_byte_size form failed ************");
+      else if ((u = dwarf_whatform (&attr)) == 0
+	       || (u != DW_FORM_data1
+		   && u != DW_FORM_data2
+		   && u != DW_FORM_data4
+		   && u != DW_FORM_data8
+		   && u != DW_FORM_sdata
+		   && u != DW_FORM_udata))
+	puts ("************* DW_AT_byte_size form (2) failed ************");
+      else if (dwarf_whatattr (&attr) != DW_AT_byte_size)
+	puts ("************* DW_AT_byte_size attr failed ************");
+    }
+  if (dwarf_hasattr (die, DW_AT_bit_size) && (i = dwarf_bitsize (die)) != -1)
+    {
+      Dwarf_Attribute attr;
+      Dwarf_Word u2;
+      unsigned int u;
+      printf ("%*s bit size  : %d\n", n * 5, "", i);
+      if (dwarf_attr (die, DW_AT_bit_size, &attr) == NULL
+	  || dwarf_formudata (&attr, &u2) != 0
+	  || i != (int) u2)
+	puts ("************* DW_AT_bit_size test failed ************");
+      else if (! dwarf_hasform (&attr, DW_FORM_data1)
+	       && ! dwarf_hasform (&attr, DW_FORM_data2)
+	       && ! dwarf_hasform (&attr, DW_FORM_data4)
+	       && ! dwarf_hasform (&attr, DW_FORM_data8)
+	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
+	       && ! dwarf_hasform (&attr, DW_FORM_udata))
+	puts ("************* DW_AT_bit_size form failed ************");
+      else if ((u = dwarf_whatform (&attr)) == 0
+	       || (u != DW_FORM_data1
+		   && u != DW_FORM_data2
+		   && u != DW_FORM_data4
+		   && u != DW_FORM_data8
+		   && u != DW_FORM_sdata
+		   && u != DW_FORM_udata))
+	puts ("************* DW_AT_bit_size form (2) failed ************");
+      else if (dwarf_whatattr (&attr) != DW_AT_bit_size)
+	puts ("************* DW_AT_bit_size attr failed ************");
+    }
+  if (dwarf_hasattr (die, DW_AT_bit_offset)
+      && (i = dwarf_bitoffset (die)) != -1)
+    {
+      Dwarf_Attribute attr;
+      Dwarf_Word u2;
+      unsigned int u;
+      printf ("%*s bit offset: %d\n", n * 5, "", i);
+      if (dwarf_attr (die, DW_AT_bit_offset, &attr) == NULL
+	  || dwarf_formudata (&attr, &u2) != 0
+	  || i != (int) u2)
+	puts ("************* DW_AT_bit_offset test failed ************");
+      else if (! dwarf_hasform (&attr, DW_FORM_data1)
+	       && ! dwarf_hasform (&attr, DW_FORM_data2)
+	       && ! dwarf_hasform (&attr, DW_FORM_data4)
+	       && ! dwarf_hasform (&attr, DW_FORM_data8)
+	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
+	       && ! dwarf_hasform (&attr, DW_FORM_udata))
+	puts ("************* DW_AT_bit_offset form failed ************");
+      else if ((u = dwarf_whatform (&attr)) == 0
+	       || (u != DW_FORM_data1
+		   && u != DW_FORM_data2
+		   && u != DW_FORM_data4
+		   && u != DW_FORM_data8
+		   && u != DW_FORM_sdata
+		   && u != DW_FORM_udata))
+	puts ("************* DW_AT_bit_offset form (2) failed ************");
+      else if (dwarf_whatattr (&attr) != DW_AT_bit_offset)
+	puts ("************* DW_AT_bit_offset attr failed ************");
+    }
+
+  if (dwarf_hasattr (die, DW_AT_language) && (i = dwarf_srclang (die)) != -1)
+    {
+      Dwarf_Attribute attr;
+      Dwarf_Word u2;
+      unsigned int u;
+      printf ("%*s language  : %d\n", n * 5, "", i);
+      if (dwarf_attr (die, DW_AT_language, &attr) == NULL
+	  || dwarf_formudata (&attr, &u2) != 0
+	  || i != (int) u2)
+	puts ("************* DW_AT_language test failed ************");
+      else if (! dwarf_hasform (&attr, DW_FORM_data1)
+	       && ! dwarf_hasform (&attr, DW_FORM_data2)
+	       && ! dwarf_hasform (&attr, DW_FORM_data4)
+	       && ! dwarf_hasform (&attr, DW_FORM_data8)
+	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
+	       && ! dwarf_hasform (&attr, DW_FORM_udata))
+	puts ("************* DW_AT_language form failed ************");
+      else if ((u = dwarf_whatform (&attr)) == 0
+	       || (u != DW_FORM_data1
+		   && u != DW_FORM_data2
+		   && u != DW_FORM_data4
+		   && u != DW_FORM_data8
+		   && u != DW_FORM_sdata
+		   && u != DW_FORM_udata))
+	puts ("************* DW_AT_language form (2) failed ************");
+      else if (dwarf_whatattr (&attr) != DW_AT_language)
+	puts ("************* DW_AT_language attr failed ************");
+    }
+
+  if (dwarf_hasattr (die, DW_AT_ordering)
+      && (i = dwarf_arrayorder (die)) != -1)
+    {
+      Dwarf_Attribute attr;
+      Dwarf_Word u2;
+      unsigned int u;
+      printf ("%*s ordering  : %d\n", n * 5, "", i);
+      if (dwarf_attr (die, DW_AT_ordering, &attr) == NULL
+	  || dwarf_formudata (&attr, &u2) != 0
+	  || i != (int) u2)
+	puts ("************* DW_AT_ordering test failed ************");
+      else if (! dwarf_hasform (&attr, DW_FORM_data1)
+	       && ! dwarf_hasform (&attr, DW_FORM_data2)
+	       && ! dwarf_hasform (&attr, DW_FORM_data4)
+	       && ! dwarf_hasform (&attr, DW_FORM_data8)
+	       && ! dwarf_hasform (&attr, DW_FORM_sdata)
+	       && ! dwarf_hasform (&attr, DW_FORM_udata))
+	puts ("************* DW_AT_ordering failed ************");
+      else if ((u = dwarf_whatform (&attr)) == 0
+	       || (u != DW_FORM_data1
+		   && u != DW_FORM_data2
+		   && u != DW_FORM_data4
+		   && u != DW_FORM_data8
+		   && u != DW_FORM_sdata
+		   && u != DW_FORM_udata))
+	puts ("************* DW_AT_ordering form (2) failed ************");
+      else if (dwarf_whatattr (&attr) != DW_AT_ordering)
+	puts ("************* DW_AT_ordering attr failed ************");
+    }
+
+  if (dwarf_hasattr (die, DW_AT_comp_dir))
+    {
+      Dwarf_Attribute attr;
+      if (dwarf_attr (die, DW_AT_comp_dir, &attr) == NULL
+	  || (name = dwarf_formstring (&attr)) == NULL)
+	puts ("************* DW_AT_comp_dir attr failed ************");
+      else
+	printf ("%*s directory : %s\n", n * 5, "", name);
+    }
+
+  if (dwarf_hasattr (die, DW_AT_producer))
+    {
+      Dwarf_Attribute attr;
+      if (dwarf_attr (die, DW_AT_producer, &attr) == NULL
+	  || (name = dwarf_formstring (&attr)) == NULL)
+	puts ("************* DW_AT_comp_dir attr failed ************");
+      else
+	printf ("%*s producer  : %s\n", n * 5, "", name);
+    }
+
+  if (dwarf_haschildren (die) != 0 && dwarf_child (die, &child) == 0)
+    handle (dbg, &child, n + 1);
+  if (dwarf_siblingof (die, die) == 0)
+    handle (dbg, die, n);
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ int cnt;
+
+  for (cnt = 1; cnt < argc; ++cnt)
+    {
+      int fd = open (argv[cnt], O_RDONLY);
+      Dwarf *dbg;
+
+      printf ("file: %s\n", basename (argv[cnt]));
+
+      dbg = dwarf_begin (fd, DWARF_C_READ);
+      if (dbg == NULL)
+	{
+	  printf ("%s not usable\n", argv[cnt]);
+	  close (fd);
+	  continue;
+	}
+
+      Dwarf_Off off = 0;
+      Dwarf_Off old_off = 0;
+      size_t hsize;
+      Dwarf_Off abbrev;
+      uint8_t addresssize;
+      uint8_t offsetsize;
+      while (dwarf_nextcu (dbg, off, &off, &hsize, &abbrev, &addresssize,
+			   &offsetsize) == 0)
+	{
+	  printf ("New CU: off = %llu, hsize = %zu, ab = %llu, as = %" PRIu8
+		  ", os = %" PRIu8 "\n",
+		  (unsigned long long int) old_off, hsize,
+		  (unsigned long long int) abbrev, addresssize,
+		  offsetsize);
+
+	  Dwarf_Die die;
+	  if (dwarf_offdie (dbg, old_off + hsize, &die) != NULL)
+	    handle (dbg, &die, 1);
+
+	  old_off = off;
+	}
+
+      dwarf_end (dbg);
+      close (fd);
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/showptable.c b/third_party/elfutils/tests/showptable.c
new file mode 100644
index 0000000..a794b0e
--- /dev/null
+++ b/third_party/elfutils/tests/showptable.c
@@ -0,0 +1,139 @@
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[])
+{
+  Elf *elf;
+  int fd;
+  GElf_Ehdr ehdr;
+  int cnt;
+
+  if (argc < 2)
+    {
+      puts ("missing parameter");
+      exit (1);
+    }
+
+  fd = open (argv[1], O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open \"%s\": %s\n", argv[1], strerror (errno));
+      exit (1);
+    }
+
+  elf_version (EV_CURRENT);
+
+  elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot open ELF file: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (elf_kind (elf) != ELF_K_ELF)
+    {
+      printf ("\"%s\" is not an ELF file\n", argv[1]);
+      exit (1);
+    }
+
+  if (gelf_getehdr (elf, &ehdr) == NULL)
+    {
+      printf ("cannot get the ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  printf ("idx type    %*s %*s %*s %*s %*s  align flags\n",
+	  gelf_getclass (elf) == ELFCLASS32 ? 9 : 17, "offset",
+	  gelf_getclass (elf) == ELFCLASS32 ? 10 : 18, "vaddr",
+	  gelf_getclass (elf) == ELFCLASS32 ? 10 : 18, "paddr",
+	  gelf_getclass (elf) == ELFCLASS32 ? 9 : 12, "filesz",
+	  gelf_getclass (elf) == ELFCLASS32 ? 9 : 12, "memsz");
+
+  for (cnt = 0; cnt < ehdr.e_phnum; ++cnt)
+    {
+      static const char *typenames[] =
+      {
+	[PT_NULL] = "NULL",
+	[PT_LOAD] = "LOAD",
+	[PT_DYNAMIC] = "DYNAMIC",
+	[PT_INTERP] = "INTERP",
+	[PT_NOTE] = "NOTE",
+	[PT_SHLIB] = "SHLIB",
+	[PT_PHDR] = "PHDR"
+      };
+      GElf_Phdr mem;
+      GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &mem);
+      char buf[19];
+      const char *p_type = typenames[phdr->p_type];
+
+      /* If we don't know the name of the type we use the number value.  */
+      if (phdr->p_type >= PT_NUM)
+	{
+	  snprintf (buf, sizeof (buf), "%x", phdr->p_type);
+	  p_type = buf;
+	}
+
+      printf ("%3d %-7s %#0*llx %#0*llx %#0*llx %#0*llx %#0*llx %#6llx ",
+	      cnt, p_type,
+	      gelf_getclass (elf) == ELFCLASS32 ? 9 : 17,
+	      (unsigned long long int) phdr->p_offset,
+	      gelf_getclass (elf) == ELFCLASS32 ? 10 : 18,
+	      (unsigned long long int) phdr->p_vaddr,
+	      gelf_getclass (elf) == ELFCLASS32 ? 10 : 18,
+	      (unsigned long long int) phdr->p_paddr,
+	      gelf_getclass (elf) == ELFCLASS32 ? 9 : 12,
+	      (unsigned long long int) phdr->p_filesz,
+	      gelf_getclass (elf) == ELFCLASS32 ? 9 : 12,
+	      (unsigned long long int) phdr->p_memsz,
+	      (unsigned long long int) phdr->p_align);
+
+      putc_unlocked ((phdr->p_flags & PF_X) ? 'X' : ' ', stdout);
+      putc_unlocked ((phdr->p_flags & PF_W) ? 'W' : ' ', stdout);
+      putc_unlocked ((phdr->p_flags & PF_R) ? 'R' : ' ', stdout);
+
+      putc_unlocked ('\n', stdout);
+
+      if (phdr->p_type == PT_INTERP)
+	{
+	  /* We can show the user the name of the interpreter.  */
+	  size_t maxsize;
+	  char *filedata = elf_rawfile (elf, &maxsize);
+
+	  if (filedata != NULL && phdr->p_offset < maxsize)
+	    printf ("\t[Requesting program interpreter: %s]\n",
+		    filedata + phdr->p_offset);
+	}
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("error while freeing ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/strptr.c b/third_party/elfutils/tests/strptr.c
new file mode 100644
index 0000000..759664a
--- /dev/null
+++ b/third_party/elfutils/tests/strptr.c
@@ -0,0 +1,95 @@
+/* Test program for elf_strptr function.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include ELFUTILS_HEADER(elf)
+#include <gelf.h>
+
+int
+main (int argc, char *argv[])
+{
+  if (argc != 2)
+    {
+      printf ("No ELF file given as argument");
+      exit (1);
+    }
+
+  const char *fname = argv[1];
+
+  // Initialize libelf.
+  elf_version (EV_CURRENT);
+
+  /* Read the ELF from disk now.  */
+  int fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  size_t ndx;
+  if (elf_getshdrstrndx (elf, &ndx) != 0)
+    {
+      printf ("cannot get section header table index: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (ndx == SHN_UNDEF)
+    {
+      printf ("ELF file `%s' doesn't have a section header table index", fname);
+      exit (1);
+    }
+
+  printf ("Strings in section %zd:\n", ndx);
+
+  size_t off = 0;
+  const char *str = elf_strptr (elf, ndx, off);
+  while (str != NULL)
+    {
+      printf ("[%zx] '%s'\n", off, str);
+      off += strlen (str) + 1;
+      str = elf_strptr (elf, ndx, off);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/system-elf-libelf-test.c b/third_party/elfutils/tests/system-elf-libelf-test.c
new file mode 100644
index 0000000..7dfe498
--- /dev/null
+++ b/third_party/elfutils/tests/system-elf-libelf-test.c
@@ -0,0 +1,35 @@
+/* Explicit test compiling with system elf.h header plus libelf header.
+
+   Copyright (C) 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <elf.h>
+#include <stddef.h>
+#include "../libelf/libelf.h"
+
+int
+main (void)
+{
+  /* Trivial test, this is really a compile test anyway.  */
+  if (elf_version (EV_CURRENT) == EV_NONE)
+    return -1;
+
+  /* This will obviously fail. It is just to check that Elf32_Chdr and
+     elf32_getchdr are available (both at compile time and runtime).  */
+  Elf32_Chdr *chdr = elf32_getchdr (NULL);
+
+  return chdr == NULL ? 0 : -1;
+}
diff --git a/third_party/elfutils/tests/test-core-lib.so.bz2 b/third_party/elfutils/tests/test-core-lib.so.bz2
new file mode 100755
index 0000000..bb2da88
--- /dev/null
+++ b/third_party/elfutils/tests/test-core-lib.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/test-core.core.bz2 b/third_party/elfutils/tests/test-core.core.bz2
new file mode 100644
index 0000000..4d4346b
--- /dev/null
+++ b/third_party/elfutils/tests/test-core.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/test-core.exec.bz2 b/third_party/elfutils/tests/test-core.exec.bz2
new file mode 100755
index 0000000..49ce551
--- /dev/null
+++ b/third_party/elfutils/tests/test-core.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/test-elf_cntl_gelf_getshdr.c b/third_party/elfutils/tests/test-elf_cntl_gelf_getshdr.c
new file mode 100644
index 0000000..7371110
--- /dev/null
+++ b/third_party/elfutils/tests/test-elf_cntl_gelf_getshdr.c
@@ -0,0 +1,107 @@
+/* Copyright (C) 2012 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+int
+main (int argc, char *argv[])
+{
+  if (argc != 3)
+    {
+      fprintf (stderr, "Needs two arguments.\n");
+      fprintf (stderr, "First needs to be 'READ', 'MMAP' or 'FDREAD'\n");
+      fprintf (stderr, "Second is the ELF file to read.\n");
+      exit (2); /* user error */
+    }
+
+  bool do_mmap = false;
+  bool close_fd = false;
+  if (strcmp (argv[1], "READ") == 0)
+    {
+      do_mmap = false;
+      close_fd = false;
+    }
+  else if (strcmp (argv[1], "MMAP") == 0)
+    {
+      do_mmap = true;
+      close_fd = false;
+    }
+  else if  (strcmp (argv[1], "FDREAD") == 0)
+    {
+      do_mmap = false;
+      close_fd = true;
+    }
+  else
+    {
+      fprintf (stderr, "First arg needs to be 'READ', 'MMAP' or 'FDREAD'\n");
+      exit (2); /* user error */
+    }
+
+  elf_version (EV_CURRENT);
+
+  int fd = open (argv[2], O_RDONLY);
+  if (fd < 0)
+    {
+      fprintf (stderr, "Cannot open input file %s: %s\n", argv[2],
+	       strerror (errno));
+      exit (2);
+    }
+
+  Elf *elf = elf_begin (fd, do_mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      fprintf (stderr, "elf_begin failed for %s: %s\n", argv[2],
+	       elf_errmsg (-1));
+      exit (2);
+    }
+
+  if (! do_mmap && close_fd)
+    {
+      if (elf_cntl (elf, ELF_C_FDREAD) < 0)
+	{
+	  fprintf (stderr, "elf_cntl failed for %s: %s\n", argv[2],
+		   elf_errmsg (-1));
+	  exit (1);
+	}
+      close (fd);
+    }
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      GElf_Shdr shdr_mem;
+      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+      printf ("Section at offset %#0" PRIx64 "\n", shdr->sh_offset);
+    }
+
+  elf_end (elf);
+  exit (0);
+}
diff --git a/third_party/elfutils/tests/test-flag-nobits.c b/third_party/elfutils/tests/test-flag-nobits.c
new file mode 100644
index 0000000..15d44ea
--- /dev/null
+++ b/third_party/elfutils/tests/test-flag-nobits.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 2010 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <gelf.h>
+
+int
+main (int argc, char **argv)
+{
+  if (argc != 2)
+    abort ();
+
+  elf_version (EV_CURRENT);
+
+  int fd = open (argv[1], O_RDONLY);
+  Elf *stripped = elf_begin (fd, ELF_C_READ, NULL);
+
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (stripped, scn)) != NULL)
+    elf_flagdata (elf_getdata (scn, NULL), ELF_C_SET, ELF_F_DIRTY);
+
+  elf_end (stripped);
+  return 0;
+}
diff --git a/third_party/elfutils/tests/test-nlist.c b/third_party/elfutils/tests/test-nlist.c
new file mode 100644
index 0000000..679c911
--- /dev/null
+++ b/third_party/elfutils/tests/test-nlist.c
@@ -0,0 +1,83 @@
+/* Copyright (C) 2000, 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <nlist.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int var = 1;
+
+int bss;
+
+
+int
+foo (int a)
+{
+  return a;
+}
+
+int
+main (int argc, char *argv[] __attribute__ ((unused)))
+{
+  struct nlist nl[6] =
+  {
+    [0] = { .n_name = "var" },
+    [1] = { .n_name = "bss" },
+    [2] = { .n_name = "main" },
+    [3] = { .n_name = "foo" },
+    [4] = { .n_name = "not-there" },
+    [5] = { .n_name = NULL },
+  };
+  int cnt;
+  int result = 0;
+
+  if (nlist (".libs/test-nlist", nl) != 0
+      && nlist ("./test-nlist", nl) != 0)
+    {
+      puts ("nlist failed");
+      exit (1);
+    }
+
+  for (cnt = 0; nl[cnt].n_name != NULL; ++cnt)
+    {
+      if (argc > 1)
+	/* For debugging.  */
+	printf ("nl[%d].n_name = \"%s\"\n"
+		"nl[%d].n_value = %ld\n"
+		"nl[%d].n_scnum = %d\n"
+		"nl[%d].n_type = %u\n"
+		"nl[%d].n_sclass = %d\n"
+		"nl[%d].n_numaux = %d\n\n",
+		cnt, nl[cnt].n_name,
+		cnt, nl[cnt].n_value,
+		cnt, nl[cnt].n_scnum,
+		cnt, nl[cnt].n_type,
+		cnt, nl[cnt].n_sclass,
+		cnt, nl[cnt].n_numaux);
+
+      if ((cnt != 4 && nl[cnt].n_value == 0 && nl[cnt].n_scnum == 0
+	   && nl[cnt].n_type == 0 && nl[cnt].n_sclass == 0
+	   && nl[cnt].n_numaux == 0)
+	  || (cnt == 4 && (nl[cnt].n_value != 0 || nl[cnt].n_scnum != 0
+			   || nl[cnt].n_type != 0 || nl[cnt].n_sclass != 0
+			   || nl[cnt].n_numaux != 0)))
+	result = 1;
+    }
+
+  return foo (result);
+}
diff --git a/third_party/elfutils/tests/test-offset-loop.alt.bz2 b/third_party/elfutils/tests/test-offset-loop.alt.bz2
new file mode 100644
index 0000000..c1906b6
--- /dev/null
+++ b/third_party/elfutils/tests/test-offset-loop.alt.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/test-offset-loop.bz2 b/third_party/elfutils/tests/test-offset-loop.bz2
new file mode 100755
index 0000000..62185c0
--- /dev/null
+++ b/third_party/elfutils/tests/test-offset-loop.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/test-subr.sh b/third_party/elfutils/tests/test-subr.sh
new file mode 100644
index 0000000..a765db6
--- /dev/null
+++ b/third_party/elfutils/tests/test-subr.sh
@@ -0,0 +1,172 @@
+#! /bin/sh
+# Copyright (C) 2005-2015, 2017 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+# This file is sourced by ". $srcdir/test-subr.sh" at the start of
+# each test script.  It defines some functions they use and sets up
+# canonical sh state for test runs.
+
+set -e
+
+# Each test runs in its own directory to make sure they can run in parallel.
+test_dir="test-$$"
+mkdir -p "$test_dir"
+cd "$test_dir"
+
+#LC_ALL=C
+#export LC_ALL
+
+remove_files=
+
+# Tests that trap EXIT (0) themselves should call this explicitly.
+exit_cleanup()
+{
+  rm -f $remove_files; cd ..; rmdir $test_dir
+}
+trap exit_cleanup 0
+
+tempfiles()
+{
+  remove_files="$remove_files $*"
+}
+
+testfiles()
+{
+  for file; do
+    bunzip2 -c ${abs_srcdir}/${file}.bz2 > ${file} || exit 77
+    remove_files="$remove_files $file"
+  done
+}
+
+testrun_out()
+{
+  outfile="$1"
+  shift
+  remove_files="$remove_files $outfile"
+  testrun "$@" > $outfile 2>&1 || :
+}
+
+testrun_compare()
+{
+  outfile="${1##*/}.out"
+  testrun_out $outfile "$@"
+  diff -u $outfile -
+  # diff's exit status will kill the script.
+}
+
+test_cleanup()
+{
+  rm -f $remove_files
+  remove_files=
+}
+
+# See test-wrapper.sh, which sets the environment for this.
+testrun()
+{
+  ${elfutils_testrun}_testrun "$@"
+}
+
+built_testrun()
+{
+  LD_LIBRARY_PATH="${built_library_path}${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"\
+  $VALGRIND_CMD "$@"
+}
+
+installed_testrun()
+{
+  program="$1"
+  shift
+  case "$program" in
+  ${abs_builddir}/*)
+    if [ "x$elfutils_tests_rpath" != xno ]; then
+      echo >&2 installcheck not possible with --enable-tests-rpath
+      exit 77
+    fi
+    ;;
+  ${abs_top_builddir}/src/*)
+    program=${bindir}/`program_transform ${program##*/}`
+    ;;
+  esac
+  if [ "${libdir}" != /usr/lib ] && [ "${libdir}" != /usr/lib64 ]; then
+    LD_LIBRARY_PATH="${libdir}:${libdir}/elfutils\
+${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH" \
+    $VALGRIND_CMD $program ${1+"$@"}
+  else
+    $VALGRIND_CMD $program ${1+"$@"}
+  fi
+}
+
+program_transform()
+{
+  echo "$*" | sed "${program_transform_name}"
+}
+
+self_test_files=`echo ${abs_top_builddir}/src/addr2line \
+${abs_top_builddir}/src/elfcmp ${abs_top_builddir}/src/elflint \
+${abs_top_builddir}/src/nm ${abs_top_builddir}/src/objdump \
+${abs_top_builddir}/src/readelf \
+${abs_top_builddir}/src/size.o ${abs_top_builddir}/src/strip.o \
+${abs_top_builddir}/libelf/libelf.so \
+${abs_top_builddir}/libdw/libdw.so \
+${abs_top_builddir}/backends/libebl_i386.so \
+${abs_top_builddir}/backends/libebl_x86_64.so`
+
+# Provide a command to run on all self-test files with testrun.
+testrun_on_self()
+{
+  exit_status=0
+
+  for file in $self_test_files; do
+      testrun $* $file \
+	  || { echo "*** failure in $* $file"; exit_status=1; }
+  done
+
+  # Only exit if something failed
+  if test $exit_status != 0; then exit $exit_status; fi
+}
+
+# Compress the files first. Compress both debug sections and symtab.
+testrun_on_self_compressed()
+{
+  exit_status=0
+
+  for file in $self_test_files; do
+      tempfiles ${file}z
+      testrun ${abs_top_builddir}/src/elfcompress -f -q -o ${file}z ${file}
+      testrun ${abs_top_builddir}/src/elfcompress -f -q --name='.s??tab' ${file}z
+
+      testrun $* ${file}z \
+	  || { echo "*** failure in $* ${file}z"; exit_status=1; }
+  done
+
+  # Only exit if something failed
+  if test $exit_status != 0; then exit $exit_status; fi
+}
+
+# Same as above, but redirects stdout to /dev/null
+testrun_on_self_quiet()
+{
+  exit_status=0
+
+  for file in $self_test_files; do
+      testrun $* $file > /dev/null \
+	  || { echo "*** failure in $* $file"; exit_status=1; }
+  done
+
+  # Only exit if something failed
+  if test $exit_status != 0; then exit $exit_status; fi
+}
diff --git a/third_party/elfutils/tests/test-wrapper.sh b/third_party/elfutils/tests/test-wrapper.sh
new file mode 100755
index 0000000..09b4d49
--- /dev/null
+++ b/third_party/elfutils/tests/test-wrapper.sh
@@ -0,0 +1,65 @@
+#! /bin/sh
+# Copyright (C) 2005-2012 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file 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 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+# We don't compile in an rpath because we want "make installcheck" to
+# use the installed libraries.  So for local test runs we need to point
+# the library path at this build.
+
+# This wrapper script is called by the makefile, in one of two ways:
+#	$(srcdir)/test-wrapper.sh ../libelf:... run-test.sh ...
+# or:
+#	$(srcdir)/test-wrapper.sh installed s,^,eu-, run-test.sh ...
+
+if [ "$1" = installed ]; then
+  shift
+  elfutils_tests_rpath=$1
+  shift
+  program_transform_name="$1"
+  shift
+  elfutils_testrun=installed
+else
+  built_library_path="$1"
+  shift
+  elfutils_testrun=built
+fi
+
+old_path="${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
+
+case "$1" in
+*.sh)
+  export built_library_path program_transform_name elfutils_testrun
+  export elfutils_tests_rpath
+  ;;
+*)
+  if [ $elfutils_testrun = built ]; then
+    LD_LIBRARY_PATH="$built_library_path$old_path"
+  elif [ $elfutils_tests_rpath = yes ]; then
+    echo >&2 installcheck not possible with --enable-tests-rpath
+    exit 77
+  elif [ "x$libdir" != x/usr/lib ] && [ "x$libdir" != x/usr/lib64 ]; then
+    LD_LIBRARY_PATH="${libdir}:${libdir}/elfutils$old_path"
+  fi
+  export LD_LIBRARY_PATH
+  ;;
+esac
+
+if [ "x$VALGRIND_CMD" != "x" ]; then
+  export VALGRIND_CMD
+fi
+
+exec "$@"
diff --git a/third_party/elfutils/tests/testarchive64.a.bz2 b/third_party/elfutils/tests/testarchive64.a.bz2
new file mode 100644
index 0000000..4b54603
--- /dev/null
+++ b/third_party/elfutils/tests/testarchive64.a.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testcore-rtlib-ppc.bz2 b/third_party/elfutils/tests/testcore-rtlib-ppc.bz2
new file mode 100644
index 0000000..a3cec60
--- /dev/null
+++ b/third_party/elfutils/tests/testcore-rtlib-ppc.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testcore-rtlib.bz2 b/third_party/elfutils/tests/testcore-rtlib.bz2
new file mode 100644
index 0000000..1dc0f1a
--- /dev/null
+++ b/third_party/elfutils/tests/testcore-rtlib.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-ada-variant.bz2 b/third_party/elfutils/tests/testfile-ada-variant.bz2
new file mode 100644
index 0000000..459774d
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-ada-variant.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-backtrace-demangle.bz2 b/third_party/elfutils/tests/testfile-backtrace-demangle.bz2
new file mode 100755
index 0000000..f0294df
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-backtrace-demangle.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-backtrace-demangle.cc b/third_party/elfutils/tests/testfile-backtrace-demangle.cc
new file mode 100644
index 0000000..27fff68
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-backtrace-demangle.cc
@@ -0,0 +1,47 @@
+/* Test program for C++ demangled unwinding.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#define NOINLINE_NOCLONE __attribute__ ((noinline, noclone))
+#else
+#define NOINLINE_NOCLONE __attribute__ ((noinline))
+#endif
+
+void NOINLINE_NOCLONE
+cxxfunc (int i)
+{
+  *(volatile int *)0=0;
+  // Avoid tail call optimization.
+  asm volatile ("");
+}
+
+extern "C"
+{
+  void NOINLINE_NOCLONE
+  f (void)
+  {
+    cxxfunc(1);
+    // Avoid tail call optimization.
+    asm volatile ("");
+  }
+}
+
+int
+main()
+{
+  f();
+}
diff --git a/third_party/elfutils/tests/testfile-backtrace-demangle.core.bz2 b/third_party/elfutils/tests/testfile-backtrace-demangle.core.bz2
new file mode 100644
index 0000000..263c304
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-backtrace-demangle.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-bpf-dis1.expect.bz2 b/third_party/elfutils/tests/testfile-bpf-dis1.expect.bz2
new file mode 100644
index 0000000..21b55e9
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-bpf-dis1.expect.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-bpf-dis1.o.bz2 b/third_party/elfutils/tests/testfile-bpf-dis1.o.bz2
new file mode 100644
index 0000000..94bb612
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-bpf-dis1.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-debug-rel-g.o.bz2 b/third_party/elfutils/tests/testfile-debug-rel-g.o.bz2
new file mode 100644
index 0000000..b8c94e7
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-debug-rel-g.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-debug-rel-z.o.bz2 b/third_party/elfutils/tests/testfile-debug-rel-z.o.bz2
new file mode 100644
index 0000000..1cdac79
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-debug-rel-z.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-debug-rel.o.bz2 b/third_party/elfutils/tests/testfile-debug-rel.o.bz2
new file mode 100644
index 0000000..a3f8dff
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-debug-rel.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-debug-types.bz2 b/third_party/elfutils/tests/testfile-debug-types.bz2
new file mode 100755
index 0000000..a41f493
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-debug-types.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-debug.bz2 b/third_party/elfutils/tests/testfile-debug.bz2
new file mode 100755
index 0000000..88e59de
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-dwfl-report-elf-align-shlib.so.bz2 b/third_party/elfutils/tests/testfile-dwfl-report-elf-align-shlib.so.bz2
new file mode 100755
index 0000000..1f35df9
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-dwfl-report-elf-align-shlib.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-dwzstr.bz2 b/third_party/elfutils/tests/testfile-dwzstr.bz2
new file mode 100755
index 0000000..8d2d326
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-dwzstr.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-dwzstr.multi.bz2 b/third_party/elfutils/tests/testfile-dwzstr.multi.bz2
new file mode 100644
index 0000000..5e84991
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-dwzstr.multi.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-info-link.bz2 b/third_party/elfutils/tests/testfile-info-link.bz2
new file mode 100755
index 0000000..073b761
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-info-link.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-info-link.debuginfo.bz2 b/third_party/elfutils/tests/testfile-info-link.debuginfo.bz2
new file mode 100755
index 0000000..3225d19
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-info-link.debuginfo.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-info-link.stripped.bz2 b/third_party/elfutils/tests/testfile-info-link.stripped.bz2
new file mode 100755
index 0000000..dcbc9a2
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-info-link.stripped.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-inlines.bz2 b/third_party/elfutils/tests/testfile-inlines.bz2
new file mode 100755
index 0000000..6a0c7c5
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-inlines.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-lex-inlines.bz2 b/third_party/elfutils/tests/testfile-lex-inlines.bz2
new file mode 100755
index 0000000..716e792
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-lex-inlines.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-m68k-core.bz2 b/third_party/elfutils/tests/testfile-m68k-core.bz2
new file mode 100644
index 0000000..eda79d7
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-m68k-core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-m68k-s.bz2 b/third_party/elfutils/tests/testfile-m68k-s.bz2
new file mode 100755
index 0000000..44c3799
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-m68k-s.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-m68k.bz2 b/third_party/elfutils/tests/testfile-m68k.bz2
new file mode 100755
index 0000000..97a1b28
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-m68k.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-macinfo.bz2 b/third_party/elfutils/tests/testfile-macinfo.bz2
new file mode 100755
index 0000000..e6cc5f1
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-macinfo.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-macros-0xff.bz2 b/third_party/elfutils/tests/testfile-macros-0xff.bz2
new file mode 100755
index 0000000..a19662a
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-macros-0xff.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-macros-0xff.s b/third_party/elfutils/tests/testfile-macros-0xff.s
new file mode 100644
index 0000000..7fdd35c
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-macros-0xff.s
@@ -0,0 +1,153 @@
+	.file	"x.c"
+	.text
+.Ltext0:
+	.globl	main
+	.type	main, @function
+main:
+.LFB0:
+	.file 1 "x.c"
+	.loc 1 3 0
+	.cfi_startproc
+	pushq	%rbp
+	.cfi_def_cfa_offset 16
+	.cfi_offset 6, -16
+	movq	%rsp, %rbp
+	.cfi_def_cfa_register 6
+	.loc 1 3 0
+	movl	$0, %eax
+	popq	%rbp
+	.cfi_def_cfa 7, 8
+	ret
+	.cfi_endproc
+.LFE0:
+	.size	main, .-main
+.Letext0:
+	.section	.debug_info,"",@progbits
+.Ldebug_info0:
+	.long	0x52
+	.value	0x4
+	.long	.Ldebug_abbrev0
+	.byte	0x8
+	.uleb128 0x1
+	.long	.LASF244
+	.byte	0x4
+	.string	"x.c"
+	.long	.LASF245
+	.quad	.Ltext0
+	.quad	.Letext0-.Ltext0
+	.long	.Ldebug_line0
+	.long	.Ldebug_macro0
+	.uleb128 0x2
+	.long	.LASF246
+	.byte	0x1
+	.byte	0x3
+	.long	0x4e
+	.quad	.LFB0
+	.quad	.LFE0-.LFB0
+	.uleb128 0x1
+	.byte	0x9c
+	.uleb128 0x3
+	.byte	0x4
+	.byte	0x5
+	.string	"int"
+	.byte	0
+	.section	.debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1
+	.uleb128 0x11
+	.byte	0x1
+	.uleb128 0x25
+	.uleb128 0xe
+	.uleb128 0x13
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0x8
+	.uleb128 0x1b
+	.uleb128 0xe
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x7
+	.uleb128 0x10
+	.uleb128 0x17
+	.uleb128 0x2119
+	.uleb128 0x17
+	.byte	0
+	.byte	0
+	.uleb128 0x2
+	.uleb128 0x2e
+	.byte	0
+	.uleb128 0x3f
+	.uleb128 0x19
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x7
+	.uleb128 0x40
+	.uleb128 0x18
+	.uleb128 0x2117
+	.uleb128 0x19
+	.byte	0
+	.byte	0
+	.uleb128 0x3
+	.uleb128 0x24
+	.byte	0
+	.uleb128 0xb
+	.uleb128 0xb
+	.uleb128 0x3e
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0x8
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_aranges,"",@progbits
+	.long	0x2c
+	.value	0x2
+	.long	.Ldebug_info0
+	.byte	0x8
+	.byte	0
+	.value	0
+	.value	0
+	.quad	.Ltext0
+	.quad	.Letext0-.Ltext0
+	.quad	0
+	.quad	0
+	.section	.debug_macro,"",@progbits
+.Ldebug_macro0:
+	.value	0x4
+	.byte	0x6
+	.long	.Ldebug_line0
+	.byte   0x1
+	.byte   0xff
+	.uleb128 0
+	.byte   0xff
+	.byte	0x3
+	.uleb128 0
+	.uleb128 0x1
+	.byte	0x5
+	.uleb128 0x1
+	.long	.LASF243
+	.byte	0x4
+	.byte	0
+	.section	.debug_line,"",@progbits
+.Ldebug_line0:
+	.section	.debug_str,"MS",@progbits,1
+.LASF245:
+	.string	"/home/petr/proj/elfutils/master/elfutils"
+.LASF244:
+	.string	"GNU C++ 4.9.0 20140422 (Red Hat 4.9.0-1) -mtune=generic -march=x86-64 -g3"
+.LASF243:
+	.string	"FOO 0"
+.LASF246:
+	.string	"main"
+	.ident	"GCC: (GNU) 4.9.0 20140422 (Red Hat 4.9.0-1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/third_party/elfutils/tests/testfile-macros.bz2 b/third_party/elfutils/tests/testfile-macros.bz2
new file mode 100755
index 0000000..d74df94
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-macros.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-nobitsalign.bz2 b/third_party/elfutils/tests/testfile-nobitsalign.bz2
new file mode 100755
index 0000000..7f0d424
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-nobitsalign.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-nobitsalign.strip.bz2 b/third_party/elfutils/tests/testfile-nobitsalign.strip.bz2
new file mode 100755
index 0000000..f72000c
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-nobitsalign.strip.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-nolfs.bz2 b/third_party/elfutils/tests/testfile-nolfs.bz2
new file mode 100644
index 0000000..ab8351e
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-nolfs.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-s390x-hash-both.bz2 b/third_party/elfutils/tests/testfile-s390x-hash-both.bz2
new file mode 100755
index 0000000..86e0bcc
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-s390x-hash-both.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-sizes1.o.bz2 b/third_party/elfutils/tests/testfile-sizes1.o.bz2
new file mode 100644
index 0000000..479ecb2
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-sizes1.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-sizes2.o.bz2 b/third_party/elfutils/tests/testfile-sizes2.o.bz2
new file mode 100644
index 0000000..7bd7b47
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-sizes2.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-sizes3.o.bz2 b/third_party/elfutils/tests/testfile-sizes3.o.bz2
new file mode 100644
index 0000000..8633382
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-sizes3.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-sizes4.o.bz2 b/third_party/elfutils/tests/testfile-sizes4.o.bz2
new file mode 100644
index 0000000..046e0a2
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-sizes4.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-sizes4.s b/third_party/elfutils/tests/testfile-sizes4.s
new file mode 100644
index 0000000..a243021
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-sizes4.s
@@ -0,0 +1,77 @@
+        .section .debug_info
+.Lcu1_begin:
+        .4byte        .Lcu1_end - .Lcu1_start
+.Lcu1_start:
+        .2byte        4                 /* Version */
+        .4byte        .Labbrev1_begin   /* Abbrevs */
+        .byte        8                  /* Pointer size */
+        .uleb128        2               /* Abbrev (DW_TAG_compile_unit) */
+        .uleb128        3               /* Abbrev (DW_TAG_variable) */
+        .ascii        "v\0"
+        .4byte        .Llabel1 - .Lcu1_begin
+.Llabel1:
+        .uleb128        4               /* Abbrev (DW_TAG_array_type) */
+        .4byte        .Llabel2 - .Lcu1_begin
+        .uleb128        5               /* Abbrev (DW_TAG_subrange_type) */
+        .byte        -1
+        .2byte        255
+        .byte        0x0                /* Terminate children */
+.Llabel2:
+        .uleb128        6               /* Abbrev (DW_TAG_base_type) */
+        .byte        1
+        .byte        0x0                /* Terminate children */
+.Lcu1_end:
+        .section .note.gnu.build-id, "a", %note
+        .4byte        4
+        .4byte        8
+        .4byte        3
+        .ascii        "GNU\0"
+        .byte        0x01
+        .byte        0x02
+        .byte        0x03
+        .byte        0x04
+        .byte        0x05
+        .byte        0x06
+        .byte        0x07
+        .byte        0x08
+        .section .debug_abbrev
+.Labbrev1_begin:
+        .uleb128        2               /* Abbrev start */
+        .uleb128        0x11            /* DW_TAG_compile_unit */
+        .byte        1                  /* has_children */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+        .uleb128        3               /* Abbrev start */
+        .uleb128        0x34            /* DW_TAG_variable */
+        .byte        0                  /* has_children */
+        .uleb128        0x03            /* DW_AT_name */
+        .uleb128        0x08            /* DW_FORM_string */
+        .uleb128        0x49            /* DW_AT_type */
+        .uleb128        0x13            /* DW_FORM_ref4 */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+        .uleb128        4               /* Abbrev start */
+        .uleb128        0x01            /* DW_TAG_array_type */
+        .byte        1                  /* has_children */
+        .uleb128        0x49            /* DW_AT_type */
+        .uleb128        0x13            /* DW_FORM_ref4 */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+        .uleb128        5               /* Abbrev start */
+        .uleb128        0x21            /* DW_TAG_subrange_type */
+        .byte        0                  /* has_children */
+        .uleb128        0x22            /* DW_AT_lower_bound */
+        .uleb128        0x0b            /* DW_FORM_data1 */
+        .uleb128        0x2f            /* DW_AT_upper_bound */
+        .uleb128        0x05            /* DW_FORM_data2 */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+        .uleb128        6               /* Abbrev start */
+        .uleb128        0x24            /* DW_TAG_base_type */
+        .byte        0                  /* has_children */
+        .uleb128        0x0b            /* DW_AT_byte_size */
+        .uleb128        0x0b            /* DW_FORM_data1 */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
+        .byte        0x0                /* Terminator */
diff --git a/third_party/elfutils/tests/testfile-stridex.bz2 b/third_party/elfutils/tests/testfile-stridex.bz2
new file mode 100755
index 0000000..ff909f4
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-stridex.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-strtab.bz2 b/third_party/elfutils/tests/testfile-strtab.bz2
new file mode 100644
index 0000000..4eda14d
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-strtab.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-strtab.debuginfo.bz2 b/third_party/elfutils/tests/testfile-strtab.debuginfo.bz2
new file mode 100644
index 0000000..6fb8164
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-strtab.debuginfo.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-strtab.stripped.bz2 b/third_party/elfutils/tests/testfile-strtab.stripped.bz2
new file mode 100644
index 0000000..779bfdb
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-strtab.stripped.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-x32-core.bz2 b/third_party/elfutils/tests/testfile-x32-core.bz2
new file mode 100644
index 0000000..d519851
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-x32-core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-x32-d.bz2 b/third_party/elfutils/tests/testfile-x32-d.bz2
new file mode 100755
index 0000000..ad5836e
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-x32-d.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-x32-debug.bz2 b/third_party/elfutils/tests/testfile-x32-debug.bz2
new file mode 100755
index 0000000..d55a004
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-x32-debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-x32-s.bz2 b/third_party/elfutils/tests/testfile-x32-s.bz2
new file mode 100755
index 0000000..a909d33
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-x32-s.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-x32.bz2 b/third_party/elfutils/tests/testfile-x32.bz2
new file mode 100755
index 0000000..f6df180
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-x32.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-zdebug.bz2 b/third_party/elfutils/tests/testfile-zdebug.bz2
new file mode 100755
index 0000000..784041c
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-zdebug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-zgabi32.bz2 b/third_party/elfutils/tests/testfile-zgabi32.bz2
new file mode 100755
index 0000000..6159dbc
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-zgabi32.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-zgabi32be.bz2 b/third_party/elfutils/tests/testfile-zgabi32be.bz2
new file mode 100755
index 0000000..f1f5eb5
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-zgabi32be.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-zgabi64.bz2 b/third_party/elfutils/tests/testfile-zgabi64.bz2
new file mode 100755
index 0000000..3b44f08
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-zgabi64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-zgabi64be.bz2 b/third_party/elfutils/tests/testfile-zgabi64be.bz2
new file mode 100755
index 0000000..d819ae3
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-zgabi64be.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-zgnu32.bz2 b/third_party/elfutils/tests/testfile-zgnu32.bz2
new file mode 100755
index 0000000..9d622ca
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-zgnu32.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-zgnu32be.bz2 b/third_party/elfutils/tests/testfile-zgnu32be.bz2
new file mode 100755
index 0000000..c1dd589
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-zgnu32be.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-zgnu64.bz2 b/third_party/elfutils/tests/testfile-zgnu64.bz2
new file mode 100755
index 0000000..1bc2c09
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-zgnu64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile-zgnu64be.bz2 b/third_party/elfutils/tests/testfile-zgnu64be.bz2
new file mode 100755
index 0000000..390c9c9
--- /dev/null
+++ b/third_party/elfutils/tests/testfile-zgnu64be.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile.bz2 b/third_party/elfutils/tests/testfile.bz2
new file mode 100644
index 0000000..bde9b12
--- /dev/null
+++ b/third_party/elfutils/tests/testfile.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile10.bz2 b/third_party/elfutils/tests/testfile10.bz2
new file mode 100644
index 0000000..e9dd504
--- /dev/null
+++ b/third_party/elfutils/tests/testfile10.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile11.bz2 b/third_party/elfutils/tests/testfile11.bz2
new file mode 100644
index 0000000..d094b84
--- /dev/null
+++ b/third_party/elfutils/tests/testfile11.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile12.bz2 b/third_party/elfutils/tests/testfile12.bz2
new file mode 100644
index 0000000..8bb5ad3
--- /dev/null
+++ b/third_party/elfutils/tests/testfile12.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile13.bz2 b/third_party/elfutils/tests/testfile13.bz2
new file mode 100644
index 0000000..3b0bcb9
--- /dev/null
+++ b/third_party/elfutils/tests/testfile13.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile14.bz2 b/third_party/elfutils/tests/testfile14.bz2
new file mode 100644
index 0000000..ac7c69e
--- /dev/null
+++ b/third_party/elfutils/tests/testfile14.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile15.bz2 b/third_party/elfutils/tests/testfile15.bz2
new file mode 100644
index 0000000..e75f457
--- /dev/null
+++ b/third_party/elfutils/tests/testfile15.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile15.debug.bz2 b/third_party/elfutils/tests/testfile15.debug.bz2
new file mode 100644
index 0000000..5c86900
--- /dev/null
+++ b/third_party/elfutils/tests/testfile15.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile16.bz2 b/third_party/elfutils/tests/testfile16.bz2
new file mode 100644
index 0000000..4d7160c
--- /dev/null
+++ b/third_party/elfutils/tests/testfile16.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile16.debug.bz2 b/third_party/elfutils/tests/testfile16.debug.bz2
new file mode 100644
index 0000000..f02a972
--- /dev/null
+++ b/third_party/elfutils/tests/testfile16.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile17.bz2 b/third_party/elfutils/tests/testfile17.bz2
new file mode 100644
index 0000000..5a12320
--- /dev/null
+++ b/third_party/elfutils/tests/testfile17.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile17.debug.bz2 b/third_party/elfutils/tests/testfile17.debug.bz2
new file mode 100644
index 0000000..86a76ab
--- /dev/null
+++ b/third_party/elfutils/tests/testfile17.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile18.bz2 b/third_party/elfutils/tests/testfile18.bz2
new file mode 100644
index 0000000..8b5326c
--- /dev/null
+++ b/third_party/elfutils/tests/testfile18.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile19.bz2 b/third_party/elfutils/tests/testfile19.bz2
new file mode 100644
index 0000000..f3e6512
--- /dev/null
+++ b/third_party/elfutils/tests/testfile19.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile19.index.bz2 b/third_party/elfutils/tests/testfile19.index.bz2
new file mode 100644
index 0000000..c0a0a7a
--- /dev/null
+++ b/third_party/elfutils/tests/testfile19.index.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile2.bz2 b/third_party/elfutils/tests/testfile2.bz2
new file mode 100644
index 0000000..0771311
--- /dev/null
+++ b/third_party/elfutils/tests/testfile2.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile20.bz2 b/third_party/elfutils/tests/testfile20.bz2
new file mode 100644
index 0000000..a379f6b
--- /dev/null
+++ b/third_party/elfutils/tests/testfile20.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile20.index.bz2 b/third_party/elfutils/tests/testfile20.index.bz2
new file mode 100644
index 0000000..08dedaf
--- /dev/null
+++ b/third_party/elfutils/tests/testfile20.index.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile21.bz2 b/third_party/elfutils/tests/testfile21.bz2
new file mode 100644
index 0000000..bab7e6d
--- /dev/null
+++ b/third_party/elfutils/tests/testfile21.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile21.index.bz2 b/third_party/elfutils/tests/testfile21.index.bz2
new file mode 100644
index 0000000..5192219
--- /dev/null
+++ b/third_party/elfutils/tests/testfile21.index.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile22.bz2 b/third_party/elfutils/tests/testfile22.bz2
new file mode 100644
index 0000000..8c26270
--- /dev/null
+++ b/third_party/elfutils/tests/testfile22.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile23.bz2 b/third_party/elfutils/tests/testfile23.bz2
new file mode 100644
index 0000000..cf0ce55
--- /dev/null
+++ b/third_party/elfutils/tests/testfile23.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile24.bz2 b/third_party/elfutils/tests/testfile24.bz2
new file mode 100644
index 0000000..2320acb
--- /dev/null
+++ b/third_party/elfutils/tests/testfile24.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile25.bz2 b/third_party/elfutils/tests/testfile25.bz2
new file mode 100644
index 0000000..51e0421
--- /dev/null
+++ b/third_party/elfutils/tests/testfile25.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile26.bz2 b/third_party/elfutils/tests/testfile26.bz2
new file mode 100644
index 0000000..1f86285
--- /dev/null
+++ b/third_party/elfutils/tests/testfile26.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile27.bz2 b/third_party/elfutils/tests/testfile27.bz2
new file mode 100644
index 0000000..9d06cd9
--- /dev/null
+++ b/third_party/elfutils/tests/testfile27.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile28.bz2 b/third_party/elfutils/tests/testfile28.bz2
new file mode 100644
index 0000000..ca0dff3
--- /dev/null
+++ b/third_party/elfutils/tests/testfile28.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile28.rdwr.bz2 b/third_party/elfutils/tests/testfile28.rdwr.bz2
new file mode 100644
index 0000000..4c65848
--- /dev/null
+++ b/third_party/elfutils/tests/testfile28.rdwr.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile29.bz2 b/third_party/elfutils/tests/testfile29.bz2
new file mode 100644
index 0000000..b46451b
--- /dev/null
+++ b/third_party/elfutils/tests/testfile29.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile29.rdwr.bz2 b/third_party/elfutils/tests/testfile29.rdwr.bz2
new file mode 100644
index 0000000..42eadc7
--- /dev/null
+++ b/third_party/elfutils/tests/testfile29.rdwr.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile3.bz2 b/third_party/elfutils/tests/testfile3.bz2
new file mode 100644
index 0000000..30a456c
--- /dev/null
+++ b/third_party/elfutils/tests/testfile3.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile30.bz2 b/third_party/elfutils/tests/testfile30.bz2
new file mode 100644
index 0000000..9ee93c0
--- /dev/null
+++ b/third_party/elfutils/tests/testfile30.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile31.bz2 b/third_party/elfutils/tests/testfile31.bz2
new file mode 100644
index 0000000..73451d2
--- /dev/null
+++ b/third_party/elfutils/tests/testfile31.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile32.bz2 b/third_party/elfutils/tests/testfile32.bz2
new file mode 100644
index 0000000..7e3c73e
--- /dev/null
+++ b/third_party/elfutils/tests/testfile32.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile33.bz2 b/third_party/elfutils/tests/testfile33.bz2
new file mode 100644
index 0000000..f3dbc73
--- /dev/null
+++ b/third_party/elfutils/tests/testfile33.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile34.bz2 b/third_party/elfutils/tests/testfile34.bz2
new file mode 100644
index 0000000..a417fcb
--- /dev/null
+++ b/third_party/elfutils/tests/testfile34.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile35.bz2 b/third_party/elfutils/tests/testfile35.bz2
new file mode 100644
index 0000000..b591301
--- /dev/null
+++ b/third_party/elfutils/tests/testfile35.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile35.debug.bz2 b/third_party/elfutils/tests/testfile35.debug.bz2
new file mode 100644
index 0000000..f191862
--- /dev/null
+++ b/third_party/elfutils/tests/testfile35.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile36.bz2 b/third_party/elfutils/tests/testfile36.bz2
new file mode 100644
index 0000000..e912a19
--- /dev/null
+++ b/third_party/elfutils/tests/testfile36.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile36.debug.bz2 b/third_party/elfutils/tests/testfile36.debug.bz2
new file mode 100644
index 0000000..76aca42
--- /dev/null
+++ b/third_party/elfutils/tests/testfile36.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile37.bz2 b/third_party/elfutils/tests/testfile37.bz2
new file mode 100644
index 0000000..254ce32
--- /dev/null
+++ b/third_party/elfutils/tests/testfile37.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile37.debug.bz2 b/third_party/elfutils/tests/testfile37.debug.bz2
new file mode 100644
index 0000000..74e46a8
--- /dev/null
+++ b/third_party/elfutils/tests/testfile37.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile38.bz2 b/third_party/elfutils/tests/testfile38.bz2
new file mode 100644
index 0000000..42adb77
--- /dev/null
+++ b/third_party/elfutils/tests/testfile38.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile39.bz2 b/third_party/elfutils/tests/testfile39.bz2
new file mode 100644
index 0000000..42d0fbc
--- /dev/null
+++ b/third_party/elfutils/tests/testfile39.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile4.bz2 b/third_party/elfutils/tests/testfile4.bz2
new file mode 100644
index 0000000..25b25df
--- /dev/null
+++ b/third_party/elfutils/tests/testfile4.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile40.bz2 b/third_party/elfutils/tests/testfile40.bz2
new file mode 100644
index 0000000..ad41985
--- /dev/null
+++ b/third_party/elfutils/tests/testfile40.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile40.debug.bz2 b/third_party/elfutils/tests/testfile40.debug.bz2
new file mode 100644
index 0000000..2eec4d7
--- /dev/null
+++ b/third_party/elfutils/tests/testfile40.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile41.bz2 b/third_party/elfutils/tests/testfile41.bz2
new file mode 100644
index 0000000..f9bf5a4
--- /dev/null
+++ b/third_party/elfutils/tests/testfile41.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile42.bz2 b/third_party/elfutils/tests/testfile42.bz2
new file mode 100644
index 0000000..2530aba
--- /dev/null
+++ b/third_party/elfutils/tests/testfile42.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile42_noshdrs.bz2 b/third_party/elfutils/tests/testfile42_noshdrs.bz2
new file mode 100644
index 0000000..e50f750
--- /dev/null
+++ b/third_party/elfutils/tests/testfile42_noshdrs.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile43.bz2 b/third_party/elfutils/tests/testfile43.bz2
new file mode 100644
index 0000000..c99db24
--- /dev/null
+++ b/third_party/elfutils/tests/testfile43.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile44.S.bz2 b/third_party/elfutils/tests/testfile44.S.bz2
new file mode 100644
index 0000000..4e87434
--- /dev/null
+++ b/third_party/elfutils/tests/testfile44.S.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile44.expect.bz2 b/third_party/elfutils/tests/testfile44.expect.bz2
new file mode 100644
index 0000000..b3937b9
--- /dev/null
+++ b/third_party/elfutils/tests/testfile44.expect.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile45.S.bz2 b/third_party/elfutils/tests/testfile45.S.bz2
new file mode 100644
index 0000000..00e819e
--- /dev/null
+++ b/third_party/elfutils/tests/testfile45.S.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile45.expect.bz2 b/third_party/elfutils/tests/testfile45.expect.bz2
new file mode 100644
index 0000000..b8b33e9
--- /dev/null
+++ b/third_party/elfutils/tests/testfile45.expect.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile46.bz2 b/third_party/elfutils/tests/testfile46.bz2
new file mode 100644
index 0000000..db83b27
--- /dev/null
+++ b/third_party/elfutils/tests/testfile46.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile47.bz2 b/third_party/elfutils/tests/testfile47.bz2
new file mode 100644
index 0000000..334bd6c
--- /dev/null
+++ b/third_party/elfutils/tests/testfile47.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile48.bz2 b/third_party/elfutils/tests/testfile48.bz2
new file mode 100644
index 0000000..da0d9da
--- /dev/null
+++ b/third_party/elfutils/tests/testfile48.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile48.debug.bz2 b/third_party/elfutils/tests/testfile48.debug.bz2
new file mode 100644
index 0000000..7b84c4c
--- /dev/null
+++ b/third_party/elfutils/tests/testfile48.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile49.bz2 b/third_party/elfutils/tests/testfile49.bz2
new file mode 100644
index 0000000..8741a6b
--- /dev/null
+++ b/third_party/elfutils/tests/testfile49.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile5.bz2 b/third_party/elfutils/tests/testfile5.bz2
new file mode 100644
index 0000000..247313e
--- /dev/null
+++ b/third_party/elfutils/tests/testfile5.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile50.bz2 b/third_party/elfutils/tests/testfile50.bz2
new file mode 100644
index 0000000..fce4332
--- /dev/null
+++ b/third_party/elfutils/tests/testfile50.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile51.bz2 b/third_party/elfutils/tests/testfile51.bz2
new file mode 100755
index 0000000..5ff45c6
--- /dev/null
+++ b/third_party/elfutils/tests/testfile51.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile52-32.noshdrs.so.bz2 b/third_party/elfutils/tests/testfile52-32.noshdrs.so.bz2
new file mode 100755
index 0000000..01d2742
--- /dev/null
+++ b/third_party/elfutils/tests/testfile52-32.noshdrs.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile52-32.prelink.so.bz2 b/third_party/elfutils/tests/testfile52-32.prelink.so.bz2
new file mode 100755
index 0000000..ccb9ae3
--- /dev/null
+++ b/third_party/elfutils/tests/testfile52-32.prelink.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile52-32.so.bz2 b/third_party/elfutils/tests/testfile52-32.so.bz2
new file mode 100755
index 0000000..2a5b56e
--- /dev/null
+++ b/third_party/elfutils/tests/testfile52-32.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile52-32.so.debug.bz2 b/third_party/elfutils/tests/testfile52-32.so.debug.bz2
new file mode 100755
index 0000000..818b36d
--- /dev/null
+++ b/third_party/elfutils/tests/testfile52-32.so.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile52-64.noshdrs.so.bz2 b/third_party/elfutils/tests/testfile52-64.noshdrs.so.bz2
new file mode 100755
index 0000000..5ca310f
--- /dev/null
+++ b/third_party/elfutils/tests/testfile52-64.noshdrs.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile52-64.prelink.so.bz2 b/third_party/elfutils/tests/testfile52-64.prelink.so.bz2
new file mode 100755
index 0000000..8cb8f48
--- /dev/null
+++ b/third_party/elfutils/tests/testfile52-64.prelink.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile52-64.so.bz2 b/third_party/elfutils/tests/testfile52-64.so.bz2
new file mode 100755
index 0000000..8009f07
--- /dev/null
+++ b/third_party/elfutils/tests/testfile52-64.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile52-64.so.debug.bz2 b/third_party/elfutils/tests/testfile52-64.so.debug.bz2
new file mode 100755
index 0000000..4397788
--- /dev/null
+++ b/third_party/elfutils/tests/testfile52-64.so.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile53-32.bz2 b/third_party/elfutils/tests/testfile53-32.bz2
new file mode 100755
index 0000000..7bf48d9
--- /dev/null
+++ b/third_party/elfutils/tests/testfile53-32.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile53-32.debug.bz2 b/third_party/elfutils/tests/testfile53-32.debug.bz2
new file mode 100755
index 0000000..79ea566
--- /dev/null
+++ b/third_party/elfutils/tests/testfile53-32.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile53-32.prelink.bz2 b/third_party/elfutils/tests/testfile53-32.prelink.bz2
new file mode 100755
index 0000000..8e05abf
--- /dev/null
+++ b/third_party/elfutils/tests/testfile53-32.prelink.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile53-64.bz2 b/third_party/elfutils/tests/testfile53-64.bz2
new file mode 100755
index 0000000..235a763
--- /dev/null
+++ b/third_party/elfutils/tests/testfile53-64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile53-64.debug.bz2 b/third_party/elfutils/tests/testfile53-64.debug.bz2
new file mode 100755
index 0000000..675c6ea
--- /dev/null
+++ b/third_party/elfutils/tests/testfile53-64.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile53-64.prelink.bz2 b/third_party/elfutils/tests/testfile53-64.prelink.bz2
new file mode 100755
index 0000000..853aba7
--- /dev/null
+++ b/third_party/elfutils/tests/testfile53-64.prelink.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile54-32.noshdrs.so.bz2 b/third_party/elfutils/tests/testfile54-32.noshdrs.so.bz2
new file mode 100755
index 0000000..846bc91
--- /dev/null
+++ b/third_party/elfutils/tests/testfile54-32.noshdrs.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile54-32.prelink.so.bz2 b/third_party/elfutils/tests/testfile54-32.prelink.so.bz2
new file mode 100755
index 0000000..85c8526
--- /dev/null
+++ b/third_party/elfutils/tests/testfile54-32.prelink.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile54-32.so.bz2 b/third_party/elfutils/tests/testfile54-32.so.bz2
new file mode 100755
index 0000000..4bc4fa3
--- /dev/null
+++ b/third_party/elfutils/tests/testfile54-32.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile54-32.so.debug.bz2 b/third_party/elfutils/tests/testfile54-32.so.debug.bz2
new file mode 100755
index 0000000..79dd614
--- /dev/null
+++ b/third_party/elfutils/tests/testfile54-32.so.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile54-64.noshdrs.so.bz2 b/third_party/elfutils/tests/testfile54-64.noshdrs.so.bz2
new file mode 100755
index 0000000..3da726a
--- /dev/null
+++ b/third_party/elfutils/tests/testfile54-64.noshdrs.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile54-64.prelink.so.bz2 b/third_party/elfutils/tests/testfile54-64.prelink.so.bz2
new file mode 100755
index 0000000..e296a1d
--- /dev/null
+++ b/third_party/elfutils/tests/testfile54-64.prelink.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile54-64.so.bz2 b/third_party/elfutils/tests/testfile54-64.so.bz2
new file mode 100755
index 0000000..6072bf1
--- /dev/null
+++ b/third_party/elfutils/tests/testfile54-64.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile54-64.so.debug.bz2 b/third_party/elfutils/tests/testfile54-64.so.debug.bz2
new file mode 100755
index 0000000..6b45390
--- /dev/null
+++ b/third_party/elfutils/tests/testfile54-64.so.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile55-32.bz2 b/third_party/elfutils/tests/testfile55-32.bz2
new file mode 100755
index 0000000..d4cc986
--- /dev/null
+++ b/third_party/elfutils/tests/testfile55-32.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile55-32.debug.bz2 b/third_party/elfutils/tests/testfile55-32.debug.bz2
new file mode 100755
index 0000000..c5aa3f6
--- /dev/null
+++ b/third_party/elfutils/tests/testfile55-32.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile55-32.prelink.bz2 b/third_party/elfutils/tests/testfile55-32.prelink.bz2
new file mode 100755
index 0000000..4fc171a
--- /dev/null
+++ b/third_party/elfutils/tests/testfile55-32.prelink.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile55-64.bz2 b/third_party/elfutils/tests/testfile55-64.bz2
new file mode 100755
index 0000000..27341fa
--- /dev/null
+++ b/third_party/elfutils/tests/testfile55-64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile55-64.debug.bz2 b/third_party/elfutils/tests/testfile55-64.debug.bz2
new file mode 100755
index 0000000..d975c70
--- /dev/null
+++ b/third_party/elfutils/tests/testfile55-64.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile55-64.prelink.bz2 b/third_party/elfutils/tests/testfile55-64.prelink.bz2
new file mode 100755
index 0000000..a4338fe
--- /dev/null
+++ b/third_party/elfutils/tests/testfile55-64.prelink.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile56.bz2 b/third_party/elfutils/tests/testfile56.bz2
new file mode 100644
index 0000000..0e2257c
--- /dev/null
+++ b/third_party/elfutils/tests/testfile56.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile57.bz2 b/third_party/elfutils/tests/testfile57.bz2
new file mode 100644
index 0000000..59dbde1
--- /dev/null
+++ b/third_party/elfutils/tests/testfile57.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile58.bz2 b/third_party/elfutils/tests/testfile58.bz2
new file mode 100644
index 0000000..839efd9
--- /dev/null
+++ b/third_party/elfutils/tests/testfile58.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile59.bz2 b/third_party/elfutils/tests/testfile59.bz2
new file mode 100755
index 0000000..bcee648
--- /dev/null
+++ b/third_party/elfutils/tests/testfile59.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile6.bz2 b/third_party/elfutils/tests/testfile6.bz2
new file mode 100644
index 0000000..fd376b2
--- /dev/null
+++ b/third_party/elfutils/tests/testfile6.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile60.bz2 b/third_party/elfutils/tests/testfile60.bz2
new file mode 100755
index 0000000..6a0cd7b
--- /dev/null
+++ b/third_party/elfutils/tests/testfile60.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile61.bz2 b/third_party/elfutils/tests/testfile61.bz2
new file mode 100644
index 0000000..d139389
--- /dev/null
+++ b/third_party/elfutils/tests/testfile61.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile62.bz2 b/third_party/elfutils/tests/testfile62.bz2
new file mode 100644
index 0000000..8a42cf6
--- /dev/null
+++ b/third_party/elfutils/tests/testfile62.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile63.bz2 b/third_party/elfutils/tests/testfile63.bz2
new file mode 100644
index 0000000..4be87cd
--- /dev/null
+++ b/third_party/elfutils/tests/testfile63.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile64.bz2 b/third_party/elfutils/tests/testfile64.bz2
new file mode 100644
index 0000000..674bd53
--- /dev/null
+++ b/third_party/elfutils/tests/testfile64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile65.bz2 b/third_party/elfutils/tests/testfile65.bz2
new file mode 100644
index 0000000..5e925f8
--- /dev/null
+++ b/third_party/elfutils/tests/testfile65.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile66.bz2 b/third_party/elfutils/tests/testfile66.bz2
new file mode 100755
index 0000000..4797590
--- /dev/null
+++ b/third_party/elfutils/tests/testfile66.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile66.core.bz2 b/third_party/elfutils/tests/testfile66.core.bz2
new file mode 100644
index 0000000..12e2d44
--- /dev/null
+++ b/third_party/elfutils/tests/testfile66.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile67.bz2 b/third_party/elfutils/tests/testfile67.bz2
new file mode 100644
index 0000000..bb64745
--- /dev/null
+++ b/third_party/elfutils/tests/testfile67.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile68.bz2 b/third_party/elfutils/tests/testfile68.bz2
new file mode 100644
index 0000000..3fe6792
--- /dev/null
+++ b/third_party/elfutils/tests/testfile68.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile69.core.bz2 b/third_party/elfutils/tests/testfile69.core.bz2
new file mode 100644
index 0000000..9955318
--- /dev/null
+++ b/third_party/elfutils/tests/testfile69.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile69.so.bz2 b/third_party/elfutils/tests/testfile69.so.bz2
new file mode 100755
index 0000000..fdddab9
--- /dev/null
+++ b/third_party/elfutils/tests/testfile69.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile7.bz2 b/third_party/elfutils/tests/testfile7.bz2
new file mode 100644
index 0000000..73452bb
--- /dev/null
+++ b/third_party/elfutils/tests/testfile7.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile70.core.bz2 b/third_party/elfutils/tests/testfile70.core.bz2
new file mode 100644
index 0000000..6c47c6d
--- /dev/null
+++ b/third_party/elfutils/tests/testfile70.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile70.exec.bz2 b/third_party/elfutils/tests/testfile70.exec.bz2
new file mode 100644
index 0000000..f1b969a
--- /dev/null
+++ b/third_party/elfutils/tests/testfile70.exec.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile71.bz2 b/third_party/elfutils/tests/testfile71.bz2
new file mode 100644
index 0000000..ce5b08f
--- /dev/null
+++ b/third_party/elfutils/tests/testfile71.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile8.bz2 b/third_party/elfutils/tests/testfile8.bz2
new file mode 100644
index 0000000..1ff4994
--- /dev/null
+++ b/third_party/elfutils/tests/testfile8.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile9.bz2 b/third_party/elfutils/tests/testfile9.bz2
new file mode 100644
index 0000000..40454bc
--- /dev/null
+++ b/third_party/elfutils/tests/testfile9.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_aarch64_core.bz2 b/third_party/elfutils/tests/testfile_aarch64_core.bz2
new file mode 100644
index 0000000..9d56268
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_aarch64_core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_class_func.bz2 b/third_party/elfutils/tests/testfile_class_func.bz2
new file mode 100755
index 0000000..e40dcf2
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_class_func.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_const_type.bz2 b/third_party/elfutils/tests/testfile_const_type.bz2
new file mode 100755
index 0000000..fea4a9c
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_const_type.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_const_type.c b/third_party/elfutils/tests/testfile_const_type.c
new file mode 100644
index 0000000..259007d
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_const_type.c
@@ -0,0 +1,14 @@
+// gcc -m32 -g -O2 -o const_type const_type.c
+
+__attribute__((noinline, noclone)) int
+f1 (long long d)
+{
+  long long w = d / 0x1234567800000LL;
+  return w;
+}
+
+int
+main ()
+{
+  return f1 (4LL) - f1 (4LL);
+}
diff --git a/third_party/elfutils/tests/testfile_entry_value.bz2 b/third_party/elfutils/tests/testfile_entry_value.bz2
new file mode 100755
index 0000000..fde86c6
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_entry_value.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_entry_value.c b/third_party/elfutils/tests/testfile_entry_value.c
new file mode 100644
index 0000000..d2f232b
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_entry_value.c
@@ -0,0 +1,19 @@
+// gcc -g -O2 -o entry_value entry_value.c
+int __attribute__((noinline, noclone)) foo (int x, int y)
+{
+  return x + y;
+}
+
+int __attribute__((noinline, noclone)) bar (int x, int y)
+{
+  int z;
+  z = foo (x, y);
+  z += foo (y, x);
+  return z;
+}
+
+int
+main (int argc, char **argv)
+{
+  return bar (argc + 1, argc - 1);
+}
diff --git a/third_party/elfutils/tests/testfile_i686_core.bz2 b/third_party/elfutils/tests/testfile_i686_core.bz2
new file mode 100644
index 0000000..8412776
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_i686_core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_implicit_pointer.bz2 b/third_party/elfutils/tests/testfile_implicit_pointer.bz2
new file mode 100755
index 0000000..72f6a69
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_implicit_pointer.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_implicit_pointer.c b/third_party/elfutils/tests/testfile_implicit_pointer.c
new file mode 100644
index 0000000..d7e28a0
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_implicit_pointer.c
@@ -0,0 +1,12 @@
+// gcc -g -O2 -o implicit_pointer implicit_pointer.c
+
+static __attribute__((noinline, noclone)) int foo (int i)
+{
+  int *p = &i;
+  return *p;
+}
+
+int main (void)
+{
+  return foo (23) - 23;
+}
diff --git a/third_party/elfutils/tests/testfile_implicit_value.bz2 b/third_party/elfutils/tests/testfile_implicit_value.bz2
new file mode 100755
index 0000000..c365a99
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_implicit_value.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_implicit_value.c b/third_party/elfutils/tests/testfile_implicit_value.c
new file mode 100644
index 0000000..8885bbf
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_implicit_value.c
@@ -0,0 +1,12 @@
+// gcc -m32 -g -O2 -o implicit_value implicit_value.c
+
+static __attribute__((noinline, noclone)) int foo ()
+{
+  unsigned long long a[] = { 2, 21 };
+  return a[0] * a[1];
+}
+
+int main (void)
+{
+  return foo () - 42;
+}
diff --git a/third_party/elfutils/tests/testfile_low_high_pc.bz2 b/third_party/elfutils/tests/testfile_low_high_pc.bz2
new file mode 100755
index 0000000..f20814a
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_low_high_pc.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_multi.dwz.bz2 b/third_party/elfutils/tests/testfile_multi.dwz.bz2
new file mode 100644
index 0000000..1f52fb6
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_multi.dwz.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_multi_main.bz2 b/third_party/elfutils/tests/testfile_multi_main.bz2
new file mode 100755
index 0000000..bc6ca5f
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_multi_main.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_nested_funcs.bz2 b/third_party/elfutils/tests/testfile_nested_funcs.bz2
new file mode 100755
index 0000000..d36b603
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_nested_funcs.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_parameter_ref.bz2 b/third_party/elfutils/tests/testfile_parameter_ref.bz2
new file mode 100755
index 0000000..8ff900d
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_parameter_ref.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfile_parameter_ref.c b/third_party/elfutils/tests/testfile_parameter_ref.c
new file mode 100644
index 0000000..7fe985f
--- /dev/null
+++ b/third_party/elfutils/tests/testfile_parameter_ref.c
@@ -0,0 +1,20 @@
+// gcc -g -O2 -o parameter_ref parameter_ref.c
+
+volatile int vv;
+
+/* Don't inline, but do allow clone to create specialized versions.  */
+static __attribute__((noinline)) int
+foo (int x, int y, int z)
+{
+  int a = x * 2;
+  int b = y * 2;
+  int c = z * 2;
+  vv++;
+  return x + z;
+}
+
+int
+main (int x, char **argv)
+{
+  return foo (x, 2, 3) + foo (x, 4, 3) + foo (x + 6, x, 3) + x;
+}
diff --git a/third_party/elfutils/tests/testfileaarch64.bz2 b/third_party/elfutils/tests/testfileaarch64.bz2
new file mode 100755
index 0000000..72e5ef0
--- /dev/null
+++ b/third_party/elfutils/tests/testfileaarch64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilearm.bz2 b/third_party/elfutils/tests/testfilearm.bz2
new file mode 100755
index 0000000..d6cd090
--- /dev/null
+++ b/third_party/elfutils/tests/testfilearm.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebasmin.bz2 b/third_party/elfutils/tests/testfilebasmin.bz2
new file mode 100755
index 0000000..3843972
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebasmin.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebaxmin.bz2 b/third_party/elfutils/tests/testfilebaxmin.bz2
new file mode 100755
index 0000000..c450cc8
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebaxmin.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazdbg.bz2 b/third_party/elfutils/tests/testfilebazdbg.bz2
new file mode 100755
index 0000000..8e58636
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazdbg.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazdbg.debug.bz2 b/third_party/elfutils/tests/testfilebazdbg.debug.bz2
new file mode 100755
index 0000000..3b01176
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazdbg.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazdbg_pl.bz2 b/third_party/elfutils/tests/testfilebazdbg_pl.bz2
new file mode 100755
index 0000000..9e06a80
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazdbg_pl.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazdbg_plr.bz2 b/third_party/elfutils/tests/testfilebazdbg_plr.bz2
new file mode 100755
index 0000000..1bc43dd
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazdbg_plr.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazdbgppc64.bz2 b/third_party/elfutils/tests/testfilebazdbgppc64.bz2
new file mode 100755
index 0000000..17e77d6
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazdbgppc64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazdbgppc64.debug.bz2 b/third_party/elfutils/tests/testfilebazdbgppc64.debug.bz2
new file mode 100755
index 0000000..8faa17a
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazdbgppc64.debug.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazdbgppc64_pl.bz2 b/third_party/elfutils/tests/testfilebazdbgppc64_pl.bz2
new file mode 100755
index 0000000..9f372fb
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazdbgppc64_pl.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazdbgppc64_plr.bz2 b/third_party/elfutils/tests/testfilebazdbgppc64_plr.bz2
new file mode 100755
index 0000000..70f8e00
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazdbgppc64_plr.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazdyn.bz2 b/third_party/elfutils/tests/testfilebazdyn.bz2
new file mode 100755
index 0000000..bb623bb
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazdyn.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazdynppc64.bz2 b/third_party/elfutils/tests/testfilebazdynppc64.bz2
new file mode 100755
index 0000000..2e01699
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazdynppc64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazmdb.bz2 b/third_party/elfutils/tests/testfilebazmdb.bz2
new file mode 100755
index 0000000..561eca1
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazmdb.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazmdbppc64.bz2 b/third_party/elfutils/tests/testfilebazmdbppc64.bz2
new file mode 100755
index 0000000..16c2dd0
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazmdbppc64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazmin.bz2 b/third_party/elfutils/tests/testfilebazmin.bz2
new file mode 100755
index 0000000..12bcc6b
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazmin.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazmin_pl.bz2 b/third_party/elfutils/tests/testfilebazmin_pl.bz2
new file mode 100755
index 0000000..73cef4a
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazmin_pl.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazmin_plr.bz2 b/third_party/elfutils/tests/testfilebazmin_plr.bz2
new file mode 100755
index 0000000..e4fcf85
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazmin_plr.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazminppc64.bz2 b/third_party/elfutils/tests/testfilebazminppc64.bz2
new file mode 100755
index 0000000..364d84c
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazminppc64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazminppc64_pl.bz2 b/third_party/elfutils/tests/testfilebazminppc64_pl.bz2
new file mode 100755
index 0000000..6686340
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazminppc64_pl.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebazminppc64_plr.bz2 b/third_party/elfutils/tests/testfilebazminppc64_plr.bz2
new file mode 100755
index 0000000..4610285
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebazminppc64_plr.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebaztab.bz2 b/third_party/elfutils/tests/testfilebaztab.bz2
new file mode 100755
index 0000000..a99b739
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebaztab.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilebaztabppc64.bz2 b/third_party/elfutils/tests/testfilebaztabppc64.bz2
new file mode 100755
index 0000000..03afb8c
--- /dev/null
+++ b/third_party/elfutils/tests/testfilebaztabppc64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfiledwarfinlines.bz2 b/third_party/elfutils/tests/testfiledwarfinlines.bz2
new file mode 100755
index 0000000..db14f81
--- /dev/null
+++ b/third_party/elfutils/tests/testfiledwarfinlines.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfiledwarfinlines.core.bz2 b/third_party/elfutils/tests/testfiledwarfinlines.core.bz2
new file mode 100644
index 0000000..2299e1e
--- /dev/null
+++ b/third_party/elfutils/tests/testfiledwarfinlines.core.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilefoobarbaz.bz2 b/third_party/elfutils/tests/testfilefoobarbaz.bz2
new file mode 100755
index 0000000..0e721ff
--- /dev/null
+++ b/third_party/elfutils/tests/testfilefoobarbaz.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilegdbindex5.bz2 b/third_party/elfutils/tests/testfilegdbindex5.bz2
new file mode 100755
index 0000000..45ee945
--- /dev/null
+++ b/third_party/elfutils/tests/testfilegdbindex5.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilegdbindex7.bz2 b/third_party/elfutils/tests/testfilegdbindex7.bz2
new file mode 100755
index 0000000..2a7c6c2
--- /dev/null
+++ b/third_party/elfutils/tests/testfilegdbindex7.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfileloc.bz2 b/third_party/elfutils/tests/testfileloc.bz2
new file mode 100755
index 0000000..a436965
--- /dev/null
+++ b/third_party/elfutils/tests/testfileloc.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilemacro.bz2 b/third_party/elfutils/tests/testfilemacro.bz2
new file mode 100755
index 0000000..7db51ff
--- /dev/null
+++ b/third_party/elfutils/tests/testfilemacro.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilenolines.bz2 b/third_party/elfutils/tests/testfilenolines.bz2
new file mode 100755
index 0000000..23cd722
--- /dev/null
+++ b/third_party/elfutils/tests/testfilenolines.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfileppc32.bz2 b/third_party/elfutils/tests/testfileppc32.bz2
new file mode 100755
index 0000000..f57763a
--- /dev/null
+++ b/third_party/elfutils/tests/testfileppc32.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfileppc32attrs.o.bz2 b/third_party/elfutils/tests/testfileppc32attrs.o.bz2
new file mode 100644
index 0000000..c8d80a9
--- /dev/null
+++ b/third_party/elfutils/tests/testfileppc32attrs.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfileppc64.bz2 b/third_party/elfutils/tests/testfileppc64.bz2
new file mode 100755
index 0000000..870046b
--- /dev/null
+++ b/third_party/elfutils/tests/testfileppc64.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfileppc64attrs.o.bz2 b/third_party/elfutils/tests/testfileppc64attrs.o.bz2
new file mode 100644
index 0000000..5af2ab6
--- /dev/null
+++ b/third_party/elfutils/tests/testfileppc64attrs.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfiles390.bz2 b/third_party/elfutils/tests/testfiles390.bz2
new file mode 100755
index 0000000..14ebf6c
--- /dev/null
+++ b/third_party/elfutils/tests/testfiles390.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfiles390x.bz2 b/third_party/elfutils/tests/testfiles390x.bz2
new file mode 100755
index 0000000..eb63ed8
--- /dev/null
+++ b/third_party/elfutils/tests/testfiles390x.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testfilesparc64attrs.o.bz2 b/third_party/elfutils/tests/testfilesparc64attrs.o.bz2
new file mode 100644
index 0000000..7be7f88
--- /dev/null
+++ b/third_party/elfutils/tests/testfilesparc64attrs.o.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/testlib_dynseg.so.bz2 b/third_party/elfutils/tests/testlib_dynseg.so.bz2
new file mode 100755
index 0000000..94296a4
--- /dev/null
+++ b/third_party/elfutils/tests/testlib_dynseg.so.bz2
Binary files differ
diff --git a/third_party/elfutils/tests/typeiter.c b/third_party/elfutils/tests/typeiter.c
new file mode 100644
index 0000000..dff4526
--- /dev/null
+++ b/third_party/elfutils/tests/typeiter.c
@@ -0,0 +1,90 @@
+/* Copyright (C) 2012 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include ELFUTILS_HEADER(dw)
+#include <stdio.h>
+#include <unistd.h>
+#include <dwarf.h>
+
+int
+main (int argc, char *argv[])
+{
+  for (int i = 1; i < argc; ++i)
+    {
+      int fd = open (argv[i], O_RDONLY);
+
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if (dbg != NULL)
+	{
+	  Dwarf_Off off = 0;
+	  size_t cuhl;
+	  Dwarf_Off noff;
+
+	  while (dwarf_nextcu (dbg, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
+	    {
+	      Dwarf_Die die_mem;
+	      Dwarf_Die *die = dwarf_offdie (dbg, off + cuhl, &die_mem);
+
+	      Dwarf_Die iter_mem;
+	      Dwarf_Die *iter = &iter_mem;
+	      dwarf_child (die, &iter_mem);
+
+	      while (1)
+		{
+		  if (dwarf_tag (iter) == DW_TAG_variable)
+		    {
+		      Dwarf_Attribute attr_mem;
+		      Dwarf_Die form_mem;
+		      dwarf_formref_die (dwarf_attr (iter, DW_AT_type,
+						     &attr_mem),
+					 &form_mem);
+		    }
+
+		  if (dwarf_siblingof (iter, &iter_mem) != 0)
+		    break;
+		}
+
+	      off = noff;
+	    }
+
+	  off = 0;
+	  uint64_t type_sig;
+
+	  while (dwarf_next_unit (dbg, off, &noff, &cuhl, NULL, NULL, NULL,
+				  NULL, &type_sig, NULL) == 0)
+	    {
+	      Dwarf_Die die_mem;
+	      Dwarf_Die *die = dwarf_offdie_types (dbg, off + cuhl, &die_mem);
+
+	      if (die == NULL)
+		printf ("fail\n");
+	      else
+		printf ("ok\n");
+
+	      off = noff;
+	    }
+
+	  dwarf_end (dbg);
+	}
+
+      close (fd);
+    }
+}
diff --git a/third_party/elfutils/tests/typeiter2.c b/third_party/elfutils/tests/typeiter2.c
new file mode 100644
index 0000000..35b6a12
--- /dev/null
+++ b/third_party/elfutils/tests/typeiter2.c
@@ -0,0 +1,91 @@
+/* Copyright (C) 2012, 2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <fcntl.h>
+#include ELFUTILS_HEADER(dw)
+#include <stdio.h>
+#include <unistd.h>
+#include <dwarf.h>
+#include <inttypes.h>
+
+int
+main (int argc, char *argv[])
+{
+  for (int i = 1; i < argc; ++i)
+    {
+      int fd = open (argv[i], O_RDONLY);
+
+      Dwarf *dbg = dwarf_begin (fd, DWARF_C_READ);
+      if (dbg != NULL)
+	{
+	  Dwarf_Off off = 0;
+	  size_t cuhl;
+	  Dwarf_Off noff;
+	  uint64_t type_sig;
+
+	  while (dwarf_next_unit (dbg, off, &noff, &cuhl, NULL, NULL, NULL,
+				  NULL, &type_sig, NULL) == 0)
+	    {
+	      Dwarf_Die die_mem;
+	      dwarf_offdie_types (dbg, off + cuhl, &die_mem);
+	      off = noff;
+	    }
+
+	  off = 0;
+
+	  while (dwarf_nextcu (dbg, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
+	    {
+	      Dwarf_Die die_mem;
+	      Dwarf_Die *die = dwarf_offdie (dbg, off + cuhl, &die_mem);
+
+	      Dwarf_Die iter_mem;
+	      Dwarf_Die *iter = &iter_mem;
+	      dwarf_child (die, &iter_mem);
+
+	      while (1)
+		{
+		  if (dwarf_tag (iter) == DW_TAG_variable)
+		    {
+		      Dwarf_Attribute attr_mem;
+		      Dwarf_Die form_mem, *form;
+		      form = dwarf_formref_die (dwarf_attr (iter, DW_AT_type,
+							    &attr_mem),
+						&form_mem);
+
+		      if (form == NULL)
+			printf ("fail\n");
+		      else
+			printf ("ok %s [%" PRIx64 "]\n",
+				dwarf_diename (form), dwarf_dieoffset (form));
+		    }
+
+		  if (dwarf_siblingof (iter, &iter_mem) != 0)
+		    break;
+		}
+
+	      off = noff;
+	    }
+
+	  dwarf_end (dbg);
+	}
+
+      close (fd);
+    }
+}
diff --git a/third_party/elfutils/tests/update1.c b/third_party/elfutils/tests/update1.c
new file mode 100644
index 0000000..f4c1475
--- /dev/null
+++ b/third_party/elfutils/tests/update1.c
@@ -0,0 +1,127 @@
+/* Test program for elf_update function.
+   Copyright (C) 2000, 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+int
+main (int argc, char *argv[] __attribute__ ((unused)))
+{
+  const char *fname = "xxx_update1";
+  int fd;
+  Elf *elf;
+  Elf32_Ehdr *ehdr;
+  int i;
+
+  fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s': %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf_version (EV_CURRENT);
+
+  elf = elf_begin (fd, ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Create an ELF header.  */
+  ehdr = elf32_newehdr (elf);
+  if (ehdr == NULL)
+    {
+      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Print the ELF header values.  */
+  if (argc > 1)
+    {
+      for (i = 0; i < EI_NIDENT; ++i)
+	printf (" %02x", ehdr->e_ident[i]);
+      printf ("\
+\ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
+	      "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
+	      "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
+	      ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
+	      ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
+	      ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
+	      ehdr->e_shnum, ehdr->e_shstrndx);
+    }
+
+  ehdr->e_ident[0] = 42;
+  ehdr->e_ident[4] = 1;
+  ehdr->e_ident[5] = 1;
+  ehdr->e_ident[6] = 2;
+  ehdr->e_ident[9] = 2;
+  ehdr->e_version = 1;
+  ehdr->e_ehsize = 1;
+
+  /* Write out the file.  */
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Create an ELF header.  */
+  ehdr = elf32_newehdr (elf);
+  if (ehdr == NULL)
+    {
+      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Print the ELF header values.  */
+  if (argc > 1)
+    {
+      for (i = 0; i < EI_NIDENT; ++i)
+	printf (" %02x", ehdr->e_ident[i]);
+      printf ("\
+\ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
+	      "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
+	      "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
+	      ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
+	      ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
+	      ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
+	      ehdr->e_shnum, ehdr->e_shstrndx);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  unlink (fname);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/update2.c b/third_party/elfutils/tests/update2.c
new file mode 100644
index 0000000..5805163
--- /dev/null
+++ b/third_party/elfutils/tests/update2.c
@@ -0,0 +1,150 @@
+/* Test program for elf_update function.
+   Copyright (C) 2000, 2002, 2005 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+int
+main (int argc, char *argv[] __attribute__ ((unused)))
+{
+  const char *fname = "xxx_update2";
+  int fd;
+  Elf *elf;
+  Elf32_Ehdr *ehdr;
+  Elf32_Phdr *phdr;
+  int i;
+
+  fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s': %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf_version (EV_CURRENT);
+
+  elf = elf_begin (fd, ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Create an ELF header.  */
+  ehdr = elf32_newehdr (elf);
+  if (ehdr == NULL)
+    {
+      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Print the ELF header values.  */
+  if (argc > 1)
+    {
+      for (i = 0; i < EI_NIDENT; ++i)
+	printf (" %02x", ehdr->e_ident[i]);
+      printf ("\
+\ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
+	      "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
+	      "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
+	      ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
+	      ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
+	      ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
+	      ehdr->e_shnum, ehdr->e_shstrndx);
+    }
+
+  ehdr->e_ident[0] = 42;
+  ehdr->e_ident[4] = 1;
+  ehdr->e_ident[5] = 1;
+  ehdr->e_ident[6] = 2;
+  ehdr->e_type = ET_EXEC;
+  ehdr->e_version = 1;
+  ehdr->e_ehsize = 1;
+  elf_flagehdr (elf, ELF_C_SET, ELF_F_DIRTY);
+
+  /* Create the program header.  */
+  phdr = elf32_newphdr (elf, 1);
+  if (phdr == NULL)
+    {
+      printf ("cannot create program header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  phdr[0].p_type = PT_PHDR;
+  elf_flagphdr (elf, ELF_C_SET, ELF_F_DIRTY);
+
+  /* Let the library compute the internal structure information.  */
+  if (elf_update (elf, ELF_C_NULL) < 0)
+    {
+      printf ("failure in elf_update(NULL): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  ehdr = elf32_getehdr (elf);
+
+  phdr[0].p_offset = ehdr->e_phoff;
+  phdr[0].p_offset = ehdr->e_phoff;
+  phdr[0].p_vaddr = ehdr->e_phoff;
+  phdr[0].p_paddr = ehdr->e_phoff;
+  phdr[0].p_flags = PF_R | PF_X;
+  phdr[0].p_filesz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
+  phdr[0].p_memsz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
+  phdr[0].p_align = sizeof (Elf32_Word);
+
+  /* Write out the file.  */
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Print the ELF header values.  */
+  if (argc > 1)
+    {
+      for (i = 0; i < EI_NIDENT; ++i)
+	printf (" %02x", ehdr->e_ident[i]);
+      printf ("\
+\ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
+	      "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
+	      "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
+	      ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
+	      ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
+	      ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
+	      ehdr->e_shnum, ehdr->e_shstrndx);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  unlink (fname);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/update3.c b/third_party/elfutils/tests/update3.c
new file mode 100644
index 0000000..7a4224d
--- /dev/null
+++ b/third_party/elfutils/tests/update3.c
@@ -0,0 +1,205 @@
+/* Test program for elf_update function.
+   Copyright (C) 2000, 2002, 2005, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include ELFUTILS_HEADER(dwelf)
+
+
+int
+main (int argc, char *argv[] __attribute__ ((unused)))
+{
+  const char *fname = "xxx_update3";
+  int fd;
+  Elf *elf;
+  Elf32_Ehdr *ehdr;
+  Elf32_Phdr *phdr;
+  Elf_Scn *scn;
+  Elf32_Shdr *shdr;
+  Elf_Data *data;
+  Dwelf_Strtab *shst;
+  Dwelf_Strent *shstrtabse;
+  int i;
+
+  fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s': %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf_version (EV_CURRENT);
+
+  elf_fill (0x42);
+
+  elf = elf_begin (fd, ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Create an ELF header.  */
+  ehdr = elf32_newehdr (elf);
+  if (ehdr == NULL)
+    {
+      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Print the ELF header values.  */
+  if (argc > 1)
+    {
+      for (i = 0; i < EI_NIDENT; ++i)
+	printf (" %02x", ehdr->e_ident[i]);
+      printf ("\
+\ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
+	      "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
+	      "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
+	      ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
+	      ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
+	      ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
+	      ehdr->e_shnum, ehdr->e_shstrndx);
+    }
+
+  ehdr->e_ident[0] = 42;
+  ehdr->e_ident[4] = 1;
+  ehdr->e_ident[5] = 1;
+  ehdr->e_ident[6] = 2;
+  ehdr->e_type = ET_EXEC;
+  ehdr->e_version = 1;
+  ehdr->e_ehsize = 1;
+  elf_flagehdr (elf, ELF_C_SET, ELF_F_DIRTY);
+
+  /* Create the program header.  */
+  phdr = elf32_newphdr (elf, 1);
+  if (phdr == NULL)
+    {
+      printf ("cannot create program header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  phdr[0].p_type = PT_PHDR;
+  elf_flagphdr (elf, ELF_C_SET, ELF_F_DIRTY);
+
+  shst = dwelf_strtab_init (true);
+
+  scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create SHSTRTAB section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+  shdr = elf32_getshdr (scn);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for SHSTRTAB section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  shstrtabse = dwelf_strtab_add (shst, ".shstrtab");
+
+  shdr->sh_type = SHT_STRTAB;
+  shdr->sh_flags = 0;
+  shdr->sh_addr = 0;
+  shdr->sh_link = SHN_UNDEF;
+  shdr->sh_info = SHN_UNDEF;
+  shdr->sh_addralign = 1;
+  shdr->sh_entsize = 0;
+
+  /* We have to store the section index in the ELF header.  */
+  ehdr->e_shstrndx = elf_ndxscn (scn);
+
+  data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot create data SHSTRTAB section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* No more sections, finalize the section header string table.  */
+  dwelf_strtab_finalize (shst, data);
+
+  shdr->sh_name = dwelf_strent_off (shstrtabse);
+
+  /* Let the library compute the internal structure information.  */
+  if (elf_update (elf, ELF_C_NULL) < 0)
+    {
+      printf ("failure in elf_update(NULL): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  ehdr = elf32_getehdr (elf);
+
+  phdr[0].p_offset = ehdr->e_phoff;
+  phdr[0].p_offset = ehdr->e_phoff;
+  phdr[0].p_vaddr = ehdr->e_phoff;
+  phdr[0].p_paddr = ehdr->e_phoff;
+  phdr[0].p_flags = PF_R | PF_X;
+  phdr[0].p_filesz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
+  phdr[0].p_memsz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
+  phdr[0].p_align = sizeof (Elf32_Word);
+
+  /* Write out the file.  */
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* We don't need the string table anymore.  */
+  dwelf_strtab_free (shst);
+
+  /* And the data allocated in the .shstrtab section.  */
+  free (data->d_buf);
+
+  /* Print the ELF header values.  */
+  if (argc > 1)
+    {
+      for (i = 0; i < EI_NIDENT; ++i)
+	printf (" %02x", ehdr->e_ident[i]);
+      printf ("\
+\ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
+	      "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
+	      "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
+	      ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
+	      ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
+	      ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
+	      ehdr->e_shnum, ehdr->e_shstrndx);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  unlink (fname);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/update4.c b/third_party/elfutils/tests/update4.c
new file mode 100644
index 0000000..a9bd4bf
--- /dev/null
+++ b/third_party/elfutils/tests/update4.c
@@ -0,0 +1,357 @@
+/* Test program for elf_update function.
+   Copyright (C) 2000, 2001, 2002, 2005, 2016 Red Hat, Inc.
+   This file is part of elfutils.
+   Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include ELFUTILS_HEADER(dwelf)
+
+
+int
+main (int argc, char *argv[] __attribute__ ((unused)))
+{
+  const char fname[] = "xxx_update4";
+  int fd;
+  Elf *elf;
+  Elf32_Ehdr *ehdr;
+  Elf32_Phdr *phdr;
+  Elf_Scn *scn;
+  Elf32_Shdr *shdr;
+  Elf_Data *data;
+  Dwelf_Strtab *shst;
+  Dwelf_Strent *firstse;
+  Dwelf_Strent *secondse;
+  Dwelf_Strent *thirdse;
+  Dwelf_Strent *fourthse;
+  Dwelf_Strent *shstrtabse;
+  int i;
+
+  fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s': %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf_version (EV_CURRENT);
+
+  elf_fill (0x42);
+
+  elf = elf_begin (fd, ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Create an ELF header.  */
+  ehdr = elf32_newehdr (elf);
+  if (ehdr == NULL)
+    {
+      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* Print the ELF header values.  */
+  if (argc > 1)
+    {
+      for (i = 0; i < EI_NIDENT; ++i)
+	printf (" %02x", ehdr->e_ident[i]);
+      printf ("\
+\ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
+	      "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
+	      "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
+	      ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
+	      ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
+	      ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
+	      ehdr->e_shnum, ehdr->e_shstrndx);
+    }
+
+  ehdr->e_ident[0] = 42;
+  ehdr->e_ident[4] = 1;
+  ehdr->e_ident[5] = 1;
+  ehdr->e_ident[6] = 2;
+  ehdr->e_type = ET_EXEC;
+  ehdr->e_version = 1;
+  ehdr->e_ehsize = 1;
+  elf_flagehdr (elf, ELF_C_SET, ELF_F_DIRTY);
+
+  /* Create the program header.  */
+  phdr = elf32_newphdr (elf, 1);
+  if (phdr == NULL)
+    {
+      printf ("cannot create program header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  phdr[0].p_type = PT_PHDR;
+  elf_flagphdr (elf, ELF_C_SET, ELF_F_DIRTY);
+
+  shst = dwelf_strtab_init (true);
+
+  scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create first section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+  shdr = elf32_getshdr (scn);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for first section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  firstse = dwelf_strtab_add (shst, ".first");
+
+  shdr->sh_type = SHT_PROGBITS;
+  shdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
+  shdr->sh_addr = 0;
+  shdr->sh_link = 0;
+  shdr->sh_info = 0;
+  shdr->sh_entsize = 1;
+
+  data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot create data first section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  data->d_buf = "hello";
+  data->d_type = ELF_T_BYTE;
+  data->d_version = EV_CURRENT;
+  data->d_size = 5;
+  data->d_align = 16;
+
+
+  scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create second section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+  shdr = elf32_getshdr (scn);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for second section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  secondse = dwelf_strtab_add (shst, ".second");
+
+  shdr->sh_type = SHT_PROGBITS;
+  shdr->sh_flags = SHF_ALLOC | SHF_WRITE;
+  shdr->sh_addr = 0;
+  shdr->sh_link = 0;
+  shdr->sh_info = 0;
+  shdr->sh_entsize = 1;
+
+  data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot create data second section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  data->d_buf = "world";
+  data->d_type = ELF_T_BYTE;
+  data->d_version = EV_CURRENT;
+  data->d_size = 5;
+  data->d_align = 16;
+
+
+  scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create third section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+  shdr = elf32_getshdr (scn);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for third section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  thirdse = dwelf_strtab_add (shst, ".third");
+
+  shdr->sh_type = SHT_PROGBITS;
+  shdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
+  shdr->sh_addr = 0;
+  shdr->sh_link = 0;
+  shdr->sh_info = 0;
+  shdr->sh_entsize = 1;
+
+  data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot create data third section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  data->d_buf = "!!!!!";
+  data->d_type = ELF_T_BYTE;
+  data->d_version = EV_CURRENT;
+  data->d_size = 5;
+  data->d_align = 16;
+
+
+  scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create fourth section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+  shdr = elf32_getshdr (scn);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for fourth section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  fourthse = dwelf_strtab_add (shst, ".fourth");
+
+  shdr->sh_type = SHT_NOBITS;
+  shdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR;
+  shdr->sh_addr = 0;
+  shdr->sh_link = 0;
+  shdr->sh_info = 0;
+  shdr->sh_entsize = 1;
+  shdr->sh_size = 100;
+
+  data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot create data fourth section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  data->d_buf = NULL;
+  data->d_type = ELF_T_BYTE;
+  data->d_version = EV_CURRENT;
+  data->d_size = 100;
+  data->d_align = 16;
+
+
+  scn = elf_newscn (elf);
+  if (scn == NULL)
+    {
+      printf ("cannot create SHSTRTAB section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+  shdr = elf32_getshdr (scn);
+  if (shdr == NULL)
+    {
+      printf ("cannot get header for SHSTRTAB section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  shstrtabse = dwelf_strtab_add (shst, ".shstrtab");
+
+  shdr->sh_type = SHT_STRTAB;
+  shdr->sh_flags = 0;
+  shdr->sh_addr = 0;
+  shdr->sh_link = SHN_UNDEF;
+  shdr->sh_info = SHN_UNDEF;
+  shdr->sh_entsize = 1;
+
+  /* We have to store the section index in the ELF header.  */
+  ehdr->e_shstrndx = elf_ndxscn (scn);
+
+  data = elf_newdata (scn);
+  if (data == NULL)
+    {
+      printf ("cannot create data SHSTRTAB section: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* No more sections, finalize the section header string table.  */
+  dwelf_strtab_finalize (shst, data);
+
+  elf32_getshdr (elf_getscn (elf, 1))->sh_name = dwelf_strent_off (firstse);
+  elf32_getshdr (elf_getscn (elf, 2))->sh_name = dwelf_strent_off (secondse);
+  elf32_getshdr (elf_getscn (elf, 3))->sh_name = dwelf_strent_off (thirdse);
+  elf32_getshdr (elf_getscn (elf, 4))->sh_name = dwelf_strent_off (fourthse);
+  shdr->sh_name = dwelf_strent_off (shstrtabse);
+
+  /* Let the library compute the internal structure information.  */
+  if (elf_update (elf, ELF_C_NULL) < 0)
+    {
+      printf ("failure in elf_update(NULL): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  ehdr = elf32_getehdr (elf);
+
+  phdr[0].p_offset = ehdr->e_phoff;
+  phdr[0].p_offset = ehdr->e_phoff;
+  phdr[0].p_vaddr = ehdr->e_phoff;
+  phdr[0].p_paddr = ehdr->e_phoff;
+  phdr[0].p_flags = PF_R | PF_X;
+  phdr[0].p_filesz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
+  phdr[0].p_memsz = ehdr->e_phnum * elf32_fsize (ELF_T_PHDR, 1, EV_CURRENT);
+  phdr[0].p_align = sizeof (Elf32_Word);
+
+  /* Write out the file.  */
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  /* We don't need the string table anymore.  */
+  dwelf_strtab_free (shst);
+
+  /* And the data allocated in the .shstrtab section.  */
+  free (data->d_buf);
+
+  /* Print the ELF header values.  */
+  if (argc > 1)
+    {
+      for (i = 0; i < EI_NIDENT; ++i)
+	printf (" %02x", ehdr->e_ident[i]);
+      printf ("\
+\ntype = %hu\nmachine = %hu\nversion = %u\nentry = %u\nphoff = %u\n"
+	      "shoff = %u\nflags = %u\nehsize = %hu\nphentsize = %hu\n"
+	      "phnum = %hu\nshentsize = %hu\nshnum = %hu\nshstrndx = %hu\n",
+	      ehdr->e_type, ehdr->e_machine, ehdr->e_version, ehdr->e_entry,
+	      ehdr->e_phoff, ehdr->e_shoff, ehdr->e_flags, ehdr->e_ehsize,
+	      ehdr->e_phentsize, ehdr->e_phnum, ehdr->e_shentsize,
+	      ehdr->e_shnum, ehdr->e_shstrndx);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  unlink (fname);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/varlocs.c b/third_party/elfutils/tests/varlocs.c
new file mode 100644
index 0000000..0e43229
--- /dev/null
+++ b/third_party/elfutils/tests/varlocs.c
@@ -0,0 +1,1074 @@
+/* Test program for dwarf location functions.
+   Copyright (C) 2013, 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <argp.h>
+#include <inttypes.h>
+#include <errno.h>
+#include ELFUTILS_HEADER(dw)
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <error.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "../libdw/known-dwarf.h"
+
+// The Dwarf, Dwarf_CFIs and address bias of
+// cfi table to adjust DWARF addresses against.
+// Needed for DW_OP_call_frame_cfa.
+static Dwarf *dw;
+Dwarf_CFI *cfi_debug;
+Dwarf_Addr cfi_debug_bias;
+Dwarf_CFI *cfi_eh;
+Dwarf_Addr cfi_eh_bias;
+
+bool is_ET_REL;
+
+// Whether the current function has a DW_AT_frame_base defined.
+// Needed for DW_OP_fbreg.
+bool has_frame_base;
+
+static void
+print_die (Dwarf_Die *die, const char *what, int indent)
+{
+  Dwarf_Addr entrypc;
+  const char *name = dwarf_diename (die) ?: "<unknown>";
+  if (dwarf_entrypc (die, &entrypc) == 0)
+    printf ("%*s[%" PRIx64 "] %s '%s'@%" PRIx64 "\n", indent * 2, "",
+	    dwarf_dieoffset (die), what, name, entrypc);
+  else
+    printf ("%*s[%" PRIx64 "] %s '%s'\n", indent * 2, "",
+	    dwarf_dieoffset (die), what, name);
+}
+
+static const char *
+dwarf_encoding_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_ATE(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_ATE
+#undef DWARF_ONE_KNOWN_DW_ATE
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+static const char *
+dwarf_tag_string (unsigned int tag)
+{
+  switch (tag)
+    {
+#define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_TAG
+#undef DWARF_ONE_KNOWN_DW_TAG
+    default:
+      return NULL;
+    }
+}
+
+static const char *
+dwarf_attr_string (unsigned int attrnum)
+{
+  switch (attrnum)
+    {
+#define DWARF_ONE_KNOWN_DW_AT(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_AT
+#undef DWARF_ONE_KNOWN_DW_AT
+    default:
+      return NULL;
+    }
+}
+
+static const char *
+dwarf_form_string (unsigned int form)
+{
+  switch (form)
+    {
+#define DWARF_ONE_KNOWN_DW_FORM(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_FORM
+#undef DWARF_ONE_KNOWN_DW_FORM
+    default:
+      return NULL;
+    }
+}
+
+/* BASE must be a base type DIE referenced by a typed DWARF expression op.  */
+static void
+print_base_type (Dwarf_Die *base)
+{
+  assert (dwarf_tag (base) == DW_TAG_base_type);
+
+  Dwarf_Attribute encoding;
+  Dwarf_Word enctype = 0;
+  if (dwarf_attr (base, DW_AT_encoding, &encoding) == NULL
+      || dwarf_formudata (&encoding, &enctype) != 0)
+    error (EXIT_FAILURE, 0, "base type without encoding");
+
+  Dwarf_Attribute bsize;
+  Dwarf_Word bits;
+  if (dwarf_attr (base, DW_AT_byte_size, &bsize) != NULL
+      && dwarf_formudata (&bsize, &bits) == 0)
+    bits *= 8;
+  else if (dwarf_attr (base, DW_AT_bit_size, &bsize) == NULL
+	   || dwarf_formudata (&bsize, &bits) != 0)
+    error (EXIT_FAILURE, 0, "base type without byte or bit size");
+
+  printf ("{%s,%s,%" PRIu64 "@[%" PRIx64 "]}",
+	  dwarf_diename (base),
+	  dwarf_encoding_string (enctype),
+	  bits,
+	  dwarf_dieoffset (base));
+}
+
+static const char *
+dwarf_opcode_string (unsigned int code)
+{
+  static const char *const known[] =
+    {
+#define DWARF_ONE_KNOWN_DW_OP(NAME, CODE) [CODE] = #NAME,
+      DWARF_ALL_KNOWN_DW_OP
+#undef DWARF_ONE_KNOWN_DW_OP
+    };
+
+  if (likely (code < sizeof (known) / sizeof (known[0])))
+    return known[code];
+
+  return NULL;
+}
+
+// Forward reference for print_expr_block.
+static void print_expr (Dwarf_Attribute *, Dwarf_Op *, Dwarf_Addr);
+
+static void
+print_expr_block (Dwarf_Attribute *attr, Dwarf_Op *exprs, int len,
+		  Dwarf_Addr addr)
+{
+  printf ("{");
+  for (int i = 0; i < len; i++)
+    {
+      print_expr (attr, &exprs[i], addr);
+      printf ("%s", (i + 1 < len ? ", " : ""));
+    }
+  printf ("}");
+}
+
+static void
+print_expr_block_addrs (Dwarf_Attribute *attr,
+			Dwarf_Addr begin, Dwarf_Addr end,
+			Dwarf_Op *exprs, int len)
+{
+  printf ("      [%" PRIx64 ",%" PRIx64 ") ", begin, end);
+  print_expr_block (attr, exprs, len, begin);
+  printf ("\n");
+}
+
+static void
+print_expr (Dwarf_Attribute *attr, Dwarf_Op *expr, Dwarf_Addr addr)
+{
+  uint8_t atom = expr->atom;
+  const char *opname = dwarf_opcode_string (atom);
+  assert (opname != NULL);
+
+  switch (atom)
+    {
+    case DW_OP_deref:
+    case DW_OP_dup:
+    case DW_OP_drop:
+    case DW_OP_over:
+    case DW_OP_swap:
+    case DW_OP_rot:
+    case DW_OP_xderef:
+    case DW_OP_abs:
+    case DW_OP_and:
+    case DW_OP_div:
+    case DW_OP_minus:
+    case DW_OP_mod:
+    case DW_OP_mul:
+    case DW_OP_neg:
+    case DW_OP_not:
+    case DW_OP_or:
+    case DW_OP_plus:
+    case DW_OP_shl:
+    case DW_OP_shr:
+    case DW_OP_shra:
+    case DW_OP_xor:
+    case DW_OP_eq:
+    case DW_OP_ge:
+    case DW_OP_gt:
+    case DW_OP_le:
+    case DW_OP_lt:
+    case DW_OP_ne:
+    case DW_OP_lit0 ... DW_OP_lit31:
+    case DW_OP_reg0 ... DW_OP_reg31:
+    case DW_OP_nop:
+    case DW_OP_stack_value:
+      /* No arguments. */
+      printf ("%s", opname);
+      break;
+
+    case DW_OP_form_tls_address:
+      /* No arguments. Special. Pops an address and pushes the
+	 corresponding address in the current thread local
+	 storage. Uses the thread local storage block of the defining
+	 module (executable, shared library). */
+      printf ("%s", opname);
+      break;
+
+    case DW_OP_GNU_push_tls_address:
+      /* No arguments. Special. Not the same as DW_OP_form_tls_address.
+	 Pops an offset into the current thread local strorage and
+	 pushes back the actual address. */
+      printf ("%s", opname);
+      break;
+
+    case DW_OP_call_frame_cfa:
+      /* No arguments. Special. Pushes Call Frame Address as computed
+	 by CFI data (dwarf_cfi_addrframe will fetch that info (either from
+	 the .eh_frame or .debug_frame CFI) and dwarf_frame_cfa translatesr
+         the CFI instructions into a plain DWARF expression.
+	 Never used in CFI itself. */
+
+      if (attr == NULL)
+	error (EXIT_FAILURE, 0, "%s used in CFI", opname);
+
+      printf ("%s ", opname);
+      if (cfi_eh == NULL && cfi_debug == NULL)
+	error (EXIT_FAILURE, 0, "DW_OP_call_frame_cfa used but no cfi found.");
+
+      Dwarf_Frame *frame;
+      if (dwarf_cfi_addrframe (cfi_eh, addr + cfi_eh_bias, &frame) == 0
+	  || dwarf_cfi_addrframe (cfi_debug, addr + cfi_debug_bias,
+				  &frame) == 0)
+	{
+	  Dwarf_Op *cfa_ops;
+	  size_t cfa_nops;
+	  if (dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops) != 0)
+	    error (EXIT_FAILURE, 0, "dwarf_frame_cfa 0x%" PRIx64 ": %s",
+		   addr, dwarf_errmsg (-1));
+	  if (cfa_nops < 1)
+	    error (EXIT_FAILURE, 0, "dwarf_frame_cfa no ops");
+	  print_expr_block (NULL, cfa_ops, cfa_nops, 0);
+	  free (frame);
+	}
+      else if (is_ET_REL)
+	{
+	  /* XXX In ET_REL files there might be an .eh_frame with relocations
+	     we don't handle (e.g. X86_64_PC32). Maybe we should?  */
+	  printf ("{...}\n");
+	}
+      else
+	error (EXIT_FAILURE, 0, "dwarf_cfi_addrframe 0x%" PRIx64 ": %s",
+	       addr, dwarf_errmsg (-1));
+      break;
+
+    case DW_OP_push_object_address:
+      /* No arguments. Special. Pushes object address explicitly.
+       Normally only done implicitly by DW_AT_data_member_location.
+       Never used in CFI. */
+      if (attr == NULL)
+	error (EXIT_FAILURE, 0, "%s used in CFI", opname);
+      printf ("%s", opname);
+      break;
+
+    case DW_OP_addr:
+      /* 1 address argument. */
+      printf ("%s(0x%" PRIx64 ")", opname, (Dwarf_Addr) expr->number);
+      break;
+
+    case DW_OP_const1u:
+    case DW_OP_const2u:
+    case DW_OP_const4u:
+    case DW_OP_const8u:
+    case DW_OP_constu:
+    case DW_OP_pick:
+    case DW_OP_plus_uconst:
+    case DW_OP_regx:
+    case DW_OP_piece:
+    case DW_OP_deref_size:
+    case DW_OP_xderef_size:
+      /* 1 numeric unsigned argument. */
+      printf ("%s(%" PRIu64 ")", opname, expr->number);
+      break;
+
+    case DW_OP_call2:
+    case DW_OP_call4:
+    case DW_OP_call_ref:
+      /* 1 DIE offset argument for more ops in location attribute of DIE.
+         Never used in CFI.  */
+      {
+	if (attr == NULL)
+	  error (EXIT_FAILURE, 0, "%s used in CFI", opname);
+
+	Dwarf_Attribute call_attr;
+	if (dwarf_getlocation_attr (attr, expr, &call_attr) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for %s error %s",
+		 opname, dwarf_errmsg (-1));
+
+	Dwarf_Die call_die;
+	if (dwarf_getlocation_die (attr, expr, &call_die) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die for %s error %s",
+		 opname, dwarf_errmsg (-1));
+
+	Dwarf_Op *call_ops;
+	size_t call_len;
+	if (dwarf_getlocation (&call_attr, &call_ops, &call_len) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation for entry: %s",
+		 dwarf_errmsg (-1));
+
+	printf ("%s([%" PRIx64 "]) ", opname, dwarf_dieoffset (&call_die));
+	print_expr_block (&call_attr, call_ops, call_len, addr);
+      }
+      break;
+
+    case DW_OP_const1s:
+    case DW_OP_const2s:
+    case DW_OP_const4s:
+    case DW_OP_const8s:
+    case DW_OP_consts:
+    case DW_OP_skip:
+    case DW_OP_bra:
+    case DW_OP_breg0 ... DW_OP_breg31:
+      /* 1 numeric signed argument. */
+      printf ("%s(%" PRId64 ")", opname, (Dwarf_Sword) expr->number);
+      break;
+
+    case DW_OP_fbreg:
+      /* 1 numeric signed argument. Offset from frame base. */
+      if (attr == NULL)
+	  error (EXIT_FAILURE, 0, "%s used in CFI", opname);
+
+      if (! has_frame_base)
+	error (EXIT_FAILURE, 0, "DW_OP_fbreg used without a frame base");
+
+      printf ("%s(%" PRId64 ")", opname, (Dwarf_Sword) expr->number);
+      break;
+
+    case DW_OP_bregx:
+      /* 2 arguments, unsigned register number, signed offset. */
+      printf ("%s(%" PRIu64 ",%" PRId64 ")", opname,
+	      expr->number, (Dwarf_Sword) expr->number2);
+      break;
+
+    case DW_OP_bit_piece:
+      /* 2 arguments, unsigned size, unsigned offset. */
+      printf ("%s(%" PRIu64 ",%" PRIu64 ")", opname,
+	      expr->number, expr->number2);
+      break;
+
+    case DW_OP_implicit_value:
+      /* Special, unsigned size plus block. */
+      {
+	Dwarf_Attribute const_attr;
+	Dwarf_Block block;
+	if (dwarf_getlocation_attr (attr, expr, &const_attr) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr: %s",
+		 dwarf_errmsg (-1));
+
+	if (dwarf_formblock (&const_attr, &block) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_formblock: %s",
+		 dwarf_errmsg (-1));
+
+	/* This is the "old" way. Check they result in the same.  */
+	Dwarf_Block block_impl;
+	if (dwarf_getlocation_implicit_value (attr, expr, &block_impl) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_implicit_value: %s",
+		 dwarf_errmsg (-1));
+
+	assert (expr->number == block.length);
+	assert (block.length == block_impl.length);
+	printf ("%s(%" PRIu64 "){", opname, block.length);
+	for (size_t i = 0; i < block.length; i++)
+	  {
+	    printf ("%02x", block.data[i]);
+	    assert (block.data[i] == block_impl.data[i]);
+	  }
+	printf("}");
+      }
+      break;
+
+    case DW_OP_GNU_implicit_pointer:
+      /* Special, DIE offset, signed offset. Referenced DIE has a
+	 location or const_value attribute. */
+      {
+	if (attr == NULL)
+	  error (EXIT_FAILURE, 0, "%s used in CFI", opname);
+
+	Dwarf_Attribute attrval;
+	if (dwarf_getlocation_implicit_pointer (attr, expr, &attrval) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_implicit_pointer: %s",
+		 dwarf_errmsg (-1));
+
+	// Sanity check, results should be the same.
+	Dwarf_Attribute attrval2;
+	if (dwarf_getlocation_attr (attr, expr, &attrval2) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr: %s",
+		 dwarf_errmsg (-1));
+
+	assert (dwarf_whatattr (&attrval) == dwarf_whatattr (&attrval2));
+	assert (dwarf_whatform (&attrval) == dwarf_whatform (&attrval2));
+	// In theory two different valp pointers could point to the same
+	// value. But here we really expect them to be the equal.
+	assert (attrval.valp == attrval2.valp);
+
+	Dwarf_Die impl_die;
+	if (dwarf_getlocation_die (attr, expr, &impl_die) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
+		 dwarf_errmsg (-1));
+
+	printf ("%s([%" PRIx64 "],%" PRId64 ") ", opname,
+		dwarf_dieoffset (&impl_die), expr->number2);
+
+	if (dwarf_whatattr (&attrval) == DW_AT_const_value)
+	  printf ("<constant value>"); // Lookup type...
+	else
+	  {
+	    // Lookup the location description at the current address.
+	    Dwarf_Op *exprval;
+	    size_t exprval_len;
+	    int locs = dwarf_getlocation_addr (&attrval, addr,
+					       &exprval, &exprval_len, 1);
+	    if (locs == 0)
+	      printf ("<no location>"); // This means "optimized out".
+	    else if (locs == 1)
+	      print_expr_block (&attrval, exprval, exprval_len, addr);
+	    else
+	      error (EXIT_FAILURE, 0,
+		     "dwarf_getlocation_addr attrval at addr 0x%" PRIx64
+		     ", locs (%d): %s", addr, locs, dwarf_errmsg (-1));
+	  }
+      }
+      break;
+
+    case DW_OP_GNU_variable_value:
+      /* Special, DIE offset. Referenced DIE has a location or const_value
+	 attribute. */
+      {
+	if (attr == NULL)
+	  error (EXIT_FAILURE, 0, "%s used in CFI", opname);
+
+	Dwarf_Attribute attrval;
+	if (dwarf_getlocation_attr (attr, expr, &attrval) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr: %s",
+		 dwarf_errmsg (-1));
+
+	Dwarf_Die impl_die;
+	if (dwarf_getlocation_die (attr, expr, &impl_die) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
+		 dwarf_errmsg (-1));
+
+	printf ("%s([%" PRIx64 "]) ", opname, dwarf_dieoffset (&impl_die));
+
+	if (dwarf_whatattr (&attrval) == DW_AT_const_value)
+	  printf ("<constant value>"); // Lookup type...
+	else
+	  {
+	    // Lookup the location description at the current address.
+	    Dwarf_Op *exprval;
+	    size_t exprval_len;
+	    int locs = dwarf_getlocation_addr (&attrval, addr,
+					       &exprval, &exprval_len, 1);
+	    if (locs == 0)
+	      printf ("<no location>"); // This means "optimized out".
+	    else if (locs == 1)
+	      print_expr_block (&attrval, exprval, exprval_len, addr);
+	    else
+	      error (EXIT_FAILURE, 0,
+		     "dwarf_getlocation_addr attrval at addr 0x%" PRIx64
+		     ", locs (%d): %s", addr, locs, dwarf_errmsg (-1));
+	  }
+      }
+      break;
+
+    case DW_OP_GNU_entry_value:
+      /* Special, unsigned size plus expression block. All registers
+	 inside the block should be interpreted as they had on
+	 entering the function. dwarf_getlocation_attr will return an
+	 attribute containing the block as locexpr which can be
+	 retrieved with dwarf_getlocation.  */
+      {
+	Dwarf_Attribute entry_attr;
+	if (dwarf_getlocation_attr (attr, expr, &entry_attr) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr: %s",
+		 dwarf_errmsg (-1));
+
+	Dwarf_Op *entry_ops;
+	size_t entry_len;
+	if (dwarf_getlocation (&entry_attr, &entry_ops, &entry_len) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation for entry: %s",
+		 dwarf_errmsg (-1));
+
+	printf ("%s(%zd) ", opname, entry_len);
+	print_expr_block (attr, entry_ops, entry_len, addr);
+      }
+      break;
+
+    case DW_OP_GNU_parameter_ref:
+      /* Special, unsigned CU relative DIE offset pointing to a
+	 DW_TAG_formal_parameter. The value that parameter had at the
+	 call site of the current function will be put on the DWARF
+	 stack. The value can be retrieved by finding the
+	 DW_TAG_GNU_call_site_parameter which has as
+	 DW_AT_abstract_origin the same formal parameter DIE. */
+      {
+	Dwarf_Die param;
+	if (dwarf_getlocation_die (attr, expr, &param) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
+		 dwarf_errmsg (-1));
+	// XXX actually lookup DW_TAG_GNU_call_site_parameter
+	printf ("%s[%" PRIx64 "]", opname, dwarf_dieoffset (&param));
+	assert (expr->number == dwarf_cuoffset (&param));
+	assert (dwarf_tag (&param) == DW_TAG_formal_parameter);
+      }
+      break;
+
+    case DW_OP_GNU_convert:
+    case DW_OP_GNU_reinterpret:
+      /* Special, unsigned CU relative DIE offset pointing to a
+	 DW_TAG_base_type. Pops a value, converts or reinterprets the
+	 value to the given type. When the argument is zero the value
+	 becomes untyped again. */
+      {
+	Dwarf_Die type;
+	Dwarf_Off off = expr->number;
+	if (off != 0)
+	  {
+	    if (dwarf_getlocation_die (attr, expr, &type) != 0)
+	      error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
+		     dwarf_errmsg (-1));
+	    off = dwarf_dieoffset (&type);
+	    assert (expr->number == dwarf_cuoffset (&type));
+	    printf ("%s", opname);
+	    print_base_type (&type);
+	  }
+	else
+	  printf ("%s[%" PRIu64 "]", opname, off);
+
+      }
+      break;
+
+    case DW_OP_GNU_regval_type:
+      /* Special, unsigned register number plus unsigned CU relative
+         DIE offset pointing to a DW_TAG_base_type. */
+      {
+	Dwarf_Die type;
+	if (dwarf_getlocation_die (attr, expr, &type) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
+		 dwarf_errmsg (-1));
+	assert (expr->number2 == dwarf_cuoffset (&type));
+	// XXX check size against base_type size?
+	printf ("%s(reg%" PRIu64 ")", opname, expr->number);
+	print_base_type (&type);
+      }
+      break;
+
+    case DW_OP_GNU_deref_type:
+      /* Special, unsigned size plus unsigned CU relative DIE offset
+	 pointing to a DW_TAG_base_type. */ 
+      {
+	Dwarf_Die type;
+	if (dwarf_getlocation_die (attr, expr, &type) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
+		 dwarf_errmsg (-1));
+	assert (expr->number2 == dwarf_cuoffset (&type));
+	// XXX check size against base_type size?
+	printf ("%s(%" PRIu64 ")", opname, expr->number);
+	print_base_type (&type);
+      }
+      break;
+
+    case DW_OP_GNU_const_type:
+      /* Special, unsigned CU relative DIE offset pointing to a
+	 DW_TAG_base_type, an unsigned size length plus a block with
+	 the constant value. */
+      {
+	Dwarf_Die type;
+	if (dwarf_getlocation_die (attr, expr, &type) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_die: %s",
+		 dwarf_errmsg (-1));
+	assert (expr->number == dwarf_cuoffset (&type));
+
+	Dwarf_Attribute const_attr;
+	if (dwarf_getlocation_attr (attr, expr, &const_attr) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_getlocation_attr for type: %s",
+		 dwarf_errmsg (-1));
+	  
+	Dwarf_Block block;
+	if (dwarf_formblock (&const_attr, &block) != 0)
+	  error (EXIT_FAILURE, 0, "dwarf_formblock for type: %s",
+		 dwarf_errmsg (-1));
+
+	printf ("%s", opname);
+	print_base_type (&type);
+	printf ("(%" PRIu64 ")[", block.length);
+	for (size_t i = 0; i < block.length; i++)
+	  printf ("%02x", block.data[i]);
+	printf("]");
+      }
+      break;
+
+    default:
+      error (EXIT_FAILURE, 0, "unhandled opcode: DW_OP_%s (0x%x)",
+	     opname, atom);
+    }
+}
+
+/* Get all variables and print their value expressions. */
+static void
+print_varlocs (Dwarf_Die *funcdie)
+{
+  // Display frame base for function if it exists.
+  // Should be used for DW_OP_fbreg.
+  has_frame_base = dwarf_hasattr (funcdie, DW_AT_frame_base);
+  if (has_frame_base)
+    {
+      Dwarf_Attribute fb_attr;
+      if (dwarf_attr (funcdie, DW_AT_frame_base, &fb_attr) == NULL)
+	error (EXIT_FAILURE, 0, "dwarf_attr fb: %s", dwarf_errmsg (-1));
+
+      Dwarf_Op *fb_expr;
+      size_t fb_exprlen;
+      if (dwarf_getlocation (&fb_attr, &fb_expr, &fb_exprlen) == 0)
+	{
+	  // Covers all of function.
+	  Dwarf_Addr entrypc;
+	  if (dwarf_entrypc (funcdie, &entrypc) != 0)
+	    error (EXIT_FAILURE, 0, "dwarf_entrypc: %s", dwarf_errmsg (-1));
+
+	  printf ("    frame_base: ");
+	  if (entrypc == 0)
+	    printf ("XXX zero address"); // XXX bad DWARF?
+	  else
+	    print_expr_block (&fb_attr, fb_expr, fb_exprlen, entrypc);
+	  printf ("\n");
+	}
+      else
+	{
+	  Dwarf_Addr base, start, end;
+	  ptrdiff_t off = 0;
+	  printf ("    frame_base:\n");
+          while ((off = dwarf_getlocations (&fb_attr, off, &base,
+					    &start, &end,
+					    &fb_expr, &fb_exprlen)) > 0)
+	    {
+	      printf ("      (%" PRIx64 ",%" PRIx64 ") ", start, end);
+	      print_expr_block (&fb_attr, fb_expr, fb_exprlen, start);
+	      printf ("\n");
+	    }
+
+	  if (off < 0)
+	    error (EXIT_FAILURE, 0, "dwarf_getlocations fb: %s",
+		   dwarf_errmsg (-1));
+	}
+    }
+  else if (dwarf_tag (funcdie) == DW_TAG_inlined_subroutine)
+    {
+      // See whether the subprogram we are inlined into has a frame
+      // base we should use.
+      Dwarf_Die *scopes;
+      int n = dwarf_getscopes_die (funcdie, &scopes);
+      if (n <= 0)
+	error (EXIT_FAILURE, 0, "dwarf_getscopes_die: %s", dwarf_errmsg (-1));
+
+      while (n-- > 0)
+	if (dwarf_tag (&scopes[n]) == DW_TAG_subprogram
+	    && dwarf_hasattr (&scopes[n], DW_AT_frame_base))
+	  {
+	    has_frame_base = true;
+	    break;
+	  }
+      free (scopes);
+    }
+
+  if (! dwarf_haschildren (funcdie))
+    return;
+
+  Dwarf_Die child;
+  int res = dwarf_child (funcdie, &child);
+  if (res < 0)
+    error (EXIT_FAILURE, 0, "dwarf_child: %s", dwarf_errmsg (-1));
+
+  /* We thought there was a child, but the child list was actually
+     empty. This isn't technically an error in the DWARF, but it is
+     certainly non-optimimal.  */
+  if (res == 1)
+    return;
+
+  do
+    {
+      int tag = dwarf_tag (&child);
+      if (tag == DW_TAG_variable || tag == DW_TAG_formal_parameter)
+	{
+	  const char *what = tag == DW_TAG_variable ? "variable" : "parameter";
+	  print_die (&child, what, 2);
+
+	  if (dwarf_hasattr (&child, DW_AT_location))
+	    {
+	      Dwarf_Attribute attr;
+	      if (dwarf_attr (&child, DW_AT_location, &attr) == NULL)
+		error (EXIT_FAILURE, 0, "dwarf_attr: %s", dwarf_errmsg (-1));
+
+	      Dwarf_Op *expr;
+	      size_t exprlen;
+	      if (dwarf_getlocation (&attr, &expr, &exprlen) == 0)
+		{
+		  // Covers all ranges of the function.
+		  // Evaluate the expression block for each range.
+		  ptrdiff_t offset = 0;
+		  Dwarf_Addr base, begin, end;
+		  do
+		    {
+		      offset = dwarf_ranges (funcdie, offset, &base,
+					     &begin, &end);
+		      if (offset < 0)
+			error (EXIT_FAILURE, 0, "dwarf_ranges: %s",
+			       dwarf_errmsg (-1));
+
+		      if (offset > 0)
+			{
+			  if (exprlen == 0)
+			    printf ("      (%"
+				    PRIx64 ",%" PRIx64
+				    ") <empty expression>\n", begin, end);
+			  else
+			    print_expr_block_addrs (&attr, begin, end,
+						    expr, exprlen);
+			}
+		    }
+		  while (offset > 0);
+
+		  if (offset < 0)
+		    error (EXIT_FAILURE, 0, "dwarf_ranges: %s",
+			   dwarf_errmsg (-1));
+		}
+	      else
+		{
+		  Dwarf_Addr base, begin, end;
+		  ptrdiff_t offset = 0;
+		  while ((offset = dwarf_getlocations (&attr, offset,
+						       &base, &begin, &end,
+						       &expr, &exprlen)) > 0)
+		    if (begin >= end)
+		      printf ("      (%" PRIx64 ",%" PRIx64
+			      ") <empty range>\n", begin, end); // XXX report?
+		    else
+		      {
+			print_expr_block_addrs (&attr, begin, end,
+						expr, exprlen);
+
+			// Extra sanity check for dwarf_getlocation_addr
+			// Must at least find one range for begin and end-1.
+			Dwarf_Op *expraddr;
+			size_t expraddr_len;
+			int locs = dwarf_getlocation_addr (&attr, begin,
+							   &expraddr,
+							   &expraddr_len, 1);
+			assert (locs == 1);
+			locs = dwarf_getlocation_addr (&attr, end - 1,
+						       &expraddr,
+						       &expraddr_len, 1);
+			assert (locs == 1);
+		      }
+
+		  if (offset < 0)
+		    error (EXIT_FAILURE, 0, "dwarf_getlocations: %s",
+			   dwarf_errmsg (-1));
+		}
+	    }
+	  else if (dwarf_hasattr (&child, DW_AT_const_value))
+	    {
+	      printf ("      <constant value>\n"); // Lookup type and print.
+	    }
+	  else
+	    {
+	      printf ("      <no value>\n");
+	    }
+	}
+    }
+  while (dwarf_siblingof (&child, &child) == 0);
+}
+
+static int
+handle_instance (Dwarf_Die *funcdie, void *arg __attribute__ ((unused)))
+{
+  print_die (funcdie, "inlined function", 1);
+  print_varlocs (funcdie);
+
+  return DWARF_CB_OK;
+}
+
+static int
+handle_function (Dwarf_Die *funcdie, void *arg __attribute__((unused)))
+{
+  if (dwarf_func_inline (funcdie) > 0)
+    {
+      // abstract inline definition, find all inlined instances.
+
+      // Note this is convenient for listing all instances together
+      // so you can easily compare the location expressions describing
+      // the variables and parameters, but it isn't very efficient
+      // since it will walk the DIE tree multiple times.
+      if (dwarf_func_inline_instances (funcdie, &handle_instance, NULL) != 0)
+	error (EXIT_FAILURE, 0, "dwarf_func_inline_instances: %s",
+	       dwarf_errmsg (-1));
+    }
+  else
+    {
+      // Contains actual code, not just a declaration?
+      Dwarf_Addr entrypc;
+      if (dwarf_entrypc (funcdie, &entrypc) == 0)
+	{
+	  print_die (funcdie, "function", 1);
+	  print_varlocs (funcdie);
+	}
+    }
+
+  return DWARF_CB_OK;
+}
+
+struct attr_arg
+{
+  int depth;
+  Dwarf_Addr entrypc;
+};
+
+static int
+handle_attr (Dwarf_Attribute *attr, void *arg)
+{
+  int depth = ((struct attr_arg *) arg)->depth;
+  Dwarf_Addr entrypc = ((struct attr_arg *) arg)->entrypc;
+
+  unsigned int code = dwarf_whatattr (attr);
+  unsigned int form = dwarf_whatform (attr);
+
+  printf ("%*s%s (%s)", depth * 2, "",
+	  dwarf_attr_string (code), dwarf_form_string (form));
+
+  /* If we can get an DWARF expression (or location lists) from this
+     attribute we'll print it, otherwise we'll ignore it.  But if
+     there is an error while the attribute has the "correct" form then
+     we'll report an error (we can only really check DW_FORM_exprloc
+     other forms can be ambiguous).  */
+  Dwarf_Op *expr;
+  size_t exprlen;
+  bool printed = false;
+  int res = dwarf_getlocation (attr, &expr, &exprlen);
+  if (res == 0)
+    {
+      printf (" ");
+      print_expr_block (attr, expr, exprlen, entrypc);
+      printf ("\n");
+      printed = true;
+    }
+  else if (form == DW_FORM_exprloc)
+    {
+      error (0, 0, "%s dwarf_getlocation failed: %s",
+	     dwarf_attr_string (code), dwarf_errmsg (-1));
+      return DWARF_CB_ABORT;
+    }
+  else
+    {
+      Dwarf_Addr base, begin, end;
+      ptrdiff_t offset = 0;
+      while ((offset = dwarf_getlocations (attr, offset,
+					   &base, &begin, &end,
+					   &expr, &exprlen)) > 0)
+	{
+	  if (! printed)
+	    printf ("\n");
+	  printf ("%*s", depth * 2, "");
+	  print_expr_block_addrs (attr, begin, end, expr, exprlen);
+	  printed = true;
+	}
+    }
+
+  if (! printed)
+    printf ("\n");
+
+  return DWARF_CB_OK;
+}
+
+static void
+handle_die (Dwarf_Die *die, int depth, bool outer_has_frame_base,
+	    Dwarf_Addr outer_entrypc)
+{
+  /* CU DIE already printed.  */
+  if (depth > 0)
+    {
+      const char *name = dwarf_diename (die);
+      if (name != NULL)
+	printf ("%*s[%" PRIx64 "] %s \"%s\"\n", depth * 2, "",
+		dwarf_dieoffset (die), dwarf_tag_string (dwarf_tag (die)),
+		name);
+      else
+	printf ("%*s[%" PRIx64 "] %s\n", depth * 2, "",
+		dwarf_dieoffset (die), dwarf_tag_string (dwarf_tag (die)));
+    }
+
+  struct attr_arg arg;
+  arg.depth = depth + 1;
+
+  /* The (lowest) address to use for (looking up) operands that depend
+     on address.  */
+  Dwarf_Addr die_entrypc;
+  if (dwarf_entrypc (die, &die_entrypc) != 0 || die_entrypc == 0)
+    {
+      /* Try to get the lowest address of the first range covered.  */
+      Dwarf_Addr base, start, end;
+      if (dwarf_ranges (die, 0, &base, &start, &end) <= 0 || start == 0)
+	die_entrypc = outer_entrypc;
+      else
+	die_entrypc = start;
+    }
+  arg.entrypc = die_entrypc;
+
+  /* Whether this or the any outer DIE has a frame base. Used as
+     sanity check when printing experssions that use DW_OP_fbreg.  */
+  bool die_has_frame_base = dwarf_hasattr (die, DW_AT_frame_base);
+  die_has_frame_base |= outer_has_frame_base;
+  has_frame_base = die_has_frame_base;
+
+  /* Look through all attributes to find those that contain DWARF
+     expressions and print those.  We expect to handle all attributes,
+     anything else is an error.  */
+  if (dwarf_getattrs (die, handle_attr, &arg, 0) != 1)
+    error (EXIT_FAILURE, 0, "Couldn't get all attributes: %s",
+	   dwarf_errmsg (-1));
+
+  /* Handle children and siblings recursively depth first.  */
+  Dwarf_Die child;
+  if (dwarf_haschildren (die) != 0 && dwarf_child (die, &child) == 0)
+    handle_die (&child, depth + 1, die_has_frame_base, die_entrypc);
+
+  Dwarf_Die sibling;
+  if (dwarf_siblingof (die, &sibling) == 0)
+    handle_die (&sibling, depth, outer_has_frame_base, outer_entrypc);
+}
+
+int
+main (int argc, char *argv[])
+{
+  /* With --exprlocs we process all DIEs looking for any attribute
+     which contains an DWARF expression (but not location lists) and
+     print those.  Otherwise we process all function DIEs and print
+     all DWARF expressions and location lists associated with
+     parameters and variables). */
+  bool exprlocs = false;
+  if (argc > 1 && strcmp ("--exprlocs", argv[1]) == 0)
+    {
+      exprlocs = true;
+      argv[1] = "";
+    }
+
+  int remaining;
+  Dwfl *dwfl;
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining,
+                     &dwfl);
+  assert (dwfl != NULL);
+
+  Dwarf_Die *cu = NULL;
+  Dwarf_Addr dwbias;
+  bool found_cu = false;
+  while ((cu = dwfl_nextcu (dwfl, cu, &dwbias)) != NULL)
+    {
+      /* Only walk actual compile units (not partial units) that
+	 contain code if we are only interested in the function variable
+	 locations.  */
+      Dwarf_Addr cubase;
+      if (dwarf_tag (cu) == DW_TAG_compile_unit
+	  && (exprlocs || dwarf_lowpc (cu, &cubase) == 0))
+	{
+	  found_cu = true;
+
+	  Dwfl_Module *mod = dwfl_cumodule (cu);
+	  Dwarf_Addr modbias;
+	  dw = dwfl_module_getdwarf (mod, &modbias);
+	  assert (dwbias == modbias);
+
+	  const char *mainfile;
+	  const char *modname = dwfl_module_info (mod, NULL,
+						  NULL, NULL,
+						  NULL, NULL,
+						  &mainfile,
+						  NULL);
+	  if (modname == NULL)
+	    error (EXIT_FAILURE, 0, "dwfl_module_info: %s", dwarf_errmsg (-1));
+
+	  const char *name = (modname[0] != '\0'
+			      ? modname
+			      :  basename (mainfile));
+	  printf ("module '%s'\n", name);
+	  print_die (cu, "CU", 0);
+
+	  Dwarf_Addr elfbias;
+	  Elf *elf = dwfl_module_getelf (mod, &elfbias);
+
+	  // CFI. We need both since sometimes neither is complete.
+	  cfi_debug = dwfl_module_dwarf_cfi (mod, &cfi_debug_bias);
+	  cfi_eh = dwfl_module_eh_cfi (mod, &cfi_eh_bias);
+
+	  assert (cfi_debug_bias == 0); // No bias needed, same file.
+
+	  // We are a bit forgiving for object files.  There might be
+	  // relocations we don't handle that are needed in some
+	  // places...
+	  GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
+	  is_ET_REL = ehdr->e_type == ET_REL;
+
+	  // Get the actual CU DIE and walk all all DIEs (or just the
+	  // functions) inside it.
+	  Dwarf_Die cudie;
+	  uint8_t offsize;
+	  uint8_t addrsize;
+	  if (dwarf_diecu (cu, &cudie, &addrsize, &offsize) == NULL)
+	    error (EXIT_FAILURE, 0, "dwarf_diecu %s", dwarf_errmsg (-1));
+
+	  if (exprlocs)
+	    {
+	      Dwarf_Addr entrypc;
+	      if (dwarf_entrypc (cu, &entrypc) != 0)
+		entrypc = 0;
+
+	      /* XXX - Passing true for has_frame_base is not really true.
+		 We do it because we want to resolve all DIEs and all
+		 attributes. Technically we should check that the DIE
+		 (types) are referenced from variables that are defined in
+		 a context (function) that has a frame base.  */
+	      handle_die (cu, 0, true /* Should be false */, entrypc);
+	    }
+	  else if (dwarf_getfuncs (cu, handle_function, NULL, 0) != 0)
+	    error (EXIT_FAILURE, 0, "dwarf_getfuncs %s",
+		   dwarf_errmsg (-1));
+	}
+    }
+
+  if (! found_cu)
+    error (EXIT_FAILURE, 0, "No DWARF CU found?");
+
+  dwfl_end (dwfl);
+  return 0;
+}
diff --git a/third_party/elfutils/tests/vdsosyms.c b/third_party/elfutils/tests/vdsosyms.c
new file mode 100644
index 0000000..b876c10
--- /dev/null
+++ b/third_party/elfutils/tests/vdsosyms.c
@@ -0,0 +1,110 @@
+/* Test program for getting symbol table from vdso module.
+   Copyright (C) 2014 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+#include <assert.h>
+#include <errno.h>
+#include <error.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include ELFUTILS_HEADER(dwfl)
+
+#ifndef __linux__
+int
+main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)))
+{
+  printf ("Getting the vdso is unsupported.\n");
+  return 77;
+}
+#else /* __linux__ */
+static int vdso_syms = 0;
+
+static int
+module_callback (Dwfl_Module *mod, void **userdata __attribute__((unused)),
+		 const char *name, Dwarf_Addr start __attribute__((unused)),
+		 void *arg __attribute__((unused)))
+{
+  /* We can only recognize the vdso by inspecting the "magic name".  */
+  printf ("module name: %s\n", name);
+  if (strncmp ("[vdso: ", name, 7) == 0)
+    {
+      vdso_syms = dwfl_module_getsymtab (mod);
+      printf ("vdso syms: %d\n", vdso_syms);
+      if (vdso_syms < 0)
+	error (2, 0, "dwfl_module_getsymtab: %s", dwfl_errmsg (-1));
+
+      for (int i = 0; i < vdso_syms; i++)
+	{
+	  GElf_Sym sym;
+	  GElf_Addr addr;
+	  const char *sname = dwfl_module_getsym_info (mod, i, &sym, &addr,
+						       NULL, NULL, NULL);
+	  assert (sname != NULL);
+	  printf ("%d: '%s' %" PRIx64 " (%" PRIx64 ")\n",
+		  i, sname, sym.st_value, addr);
+	}
+    }
+
+  return DWARF_CB_OK;
+}
+
+int
+main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)))
+{
+  static char *debuginfo_path;
+  static const Dwfl_Callbacks proc_callbacks =
+    {
+      .find_debuginfo = dwfl_standard_find_debuginfo,
+      .debuginfo_path = &debuginfo_path,
+
+      .find_elf = dwfl_linux_proc_find_elf,
+    };
+  Dwfl *dwfl = dwfl_begin (&proc_callbacks);
+  if (dwfl == NULL)
+    error (2, 0, "dwfl_begin: %s", dwfl_errmsg (-1));
+
+  /* Take ourself as "arbitrary" process to inspect.  This should work
+     even with "restricted ptrace".  */
+  pid_t pid = getpid();
+
+  int result = dwfl_linux_proc_report (dwfl, pid);
+  if (result < 0)
+    error (2, 0, "dwfl_linux_proc_report: %s", dwfl_errmsg (-1));
+  else if (result > 0)
+    error (2, result, "dwfl_linux_proc_report");
+
+  /* Also explicitly attach for older kernels (cannot read vdso otherwise).  */
+  result = dwfl_linux_proc_attach (dwfl, pid, false);
+  if (result < 0)
+    error (2, 0, "dwfl_linux_proc_attach: %s", dwfl_errmsg (-1));
+  else if (result > 0)
+    error (2, result, "dwfl_linux_proc_attach");
+
+  if (dwfl_report_end (dwfl, NULL, NULL) != 0)
+    error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1));
+
+  if (dwfl_getmodules (dwfl, module_callback, NULL, 0) != 0)
+    error (1, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
+
+  /* No symbols is ok, then we haven't seen the vdso at all on this arch.  */
+  return vdso_syms >= 0 ? 0 : -1;
+}
+
+#endif /* ! __linux__ */
diff --git a/third_party/elfutils/tests/vendorelf.c b/third_party/elfutils/tests/vendorelf.c
new file mode 100644
index 0000000..bc13cce
--- /dev/null
+++ b/third_party/elfutils/tests/vendorelf.c
@@ -0,0 +1,197 @@
+/* Test program for adding a program header to a vendor specific ELF file.
+   Copyright (C) 2016 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include ELFUTILS_HEADER(elf)
+#include <gelf.h>
+
+void
+check_elf (const char *fname, int class, int use_mmap)
+{
+  printf ("\nfname: %s\n", fname);
+
+  int fd = open (fname, O_RDWR | O_CREAT | O_TRUNC, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s': %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  Elf *elf = elf_begin (fd, use_mmap ? ELF_C_WRITE_MMAP : ELF_C_WRITE, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Create an ELF header.
+  if (gelf_newehdr (elf, class) == 0)
+    {
+      printf ("cannot create ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  GElf_Ehdr ehdr_mem;
+  GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    {
+      printf ("cannot get ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Initialize header.
+  ehdr->e_ident[EI_DATA] = class == ELFCLASS64 ? ELFDATA2LSB : ELFDATA2MSB;
+  ehdr->e_ident[EI_OSABI] = ELFOSABI_GNU;
+  ehdr->e_type = ET_LOOS + 1;
+  ehdr->e_machine = EM_X86_64;
+  ehdr->e_version = EV_CURRENT;
+
+  if (gelf_update_ehdr (elf, ehdr) == 0)
+    {
+      printf ("cannot update ELF header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Create a program header.
+  if (gelf_newphdr (elf, 1) == 0)
+    {
+      printf ("cannot create program header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  GElf_Phdr phdr;
+  if (gelf_getphdr (elf, 0, &phdr) == NULL)
+    {
+      printf ("cannot get program header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Some random values to check later.
+  phdr.p_type = PT_NULL;
+  phdr.p_offset = 0;
+  phdr.p_vaddr = 0;
+  phdr.p_paddr = 1;
+  phdr.p_filesz = 0;
+  phdr.p_memsz = 1024;
+  phdr.p_flags = PF_R;
+  phdr.p_align = 16;
+
+  if (gelf_update_phdr (elf, 0, &phdr) == 0)
+    {
+      printf ("cannot update program header: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Write everything to disk.
+  if (elf_update (elf, ELF_C_WRITE) < 0)
+    {
+      printf ("failure in elf_update(WRITE): %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  /* Reread the ELF from disk now.  */
+  fd = open (fname, O_RDONLY, 0666);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  elf = elf_begin (fd, use_mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  // Is our phdr there?
+  size_t phnum;
+  if (elf_getphdrnum (elf, &phnum) != 0)
+    {
+      printf ("cannot get phdr num: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (phnum != 1)
+    {
+      printf ("Expected just 1 phdr, got: %zd\n", phnum);
+      exit (1);
+    }
+
+  if (gelf_getphdr (elf, 0, &phdr) == NULL)
+    {
+      printf ("cannot get program header from file: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (phdr.p_type != PT_NULL
+      || phdr.p_offset != 0
+      || phdr.p_vaddr != 0
+      || phdr.p_paddr != 1
+      || phdr.p_filesz != 0
+      || phdr.p_memsz != 1024
+      || phdr.p_flags != PF_R
+      || phdr.p_align != 16)
+    {
+      printf ("Unexpected phdr values\n");
+      exit (1);
+    }
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  unlink (fname);
+}
+
+int
+main (int argc __attribute__ ((unused)),
+      char *argv[] __attribute__ ((unused)))
+{
+  elf_version (EV_CURRENT);
+
+  check_elf ("vendor.elf.32", ELFCLASS32, 0);
+  check_elf ("vendor.elf.32.mmap", ELFCLASS32, 1);
+  check_elf ("vendor.elf.64", ELFCLASS64, 0);
+  check_elf ("vendor.elf.64.mmap", ELFCLASS64, 1);
+
+  return 0;
+}
diff --git a/third_party/elfutils/tests/zstrptr.c b/third_party/elfutils/tests/zstrptr.c
new file mode 100644
index 0000000..6d8e19f
--- /dev/null
+++ b/third_party/elfutils/tests/zstrptr.c
@@ -0,0 +1,124 @@
+/* Test program for elf_strptr function.
+   Copyright (C) 2015 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file 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 3 of the License, or
+   (at your option) any later version.
+
+   elfutils 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include ELFUTILS_HEADER(elf)
+#include <gelf.h>
+
+int
+main (int argc, char *argv[])
+{
+  if (argc != 2)
+    {
+      printf ("No ELF file given as argument");
+      exit (1);
+    }
+
+  const char *fname = argv[1];
+
+  // Initialize libelf.
+  elf_version (EV_CURRENT);
+
+  /* Read the ELF from disk now.  */
+  int fd = open (fname, O_RDONLY);
+  if (fd == -1)
+    {
+      printf ("cannot open `%s' read-only: %s\n", fname, strerror (errno));
+      exit (1);
+    }
+
+  Elf *elf = elf_begin (fd, ELF_C_READ, NULL);
+  if (elf == NULL)
+    {
+      printf ("cannot create ELF descriptor read-only: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  size_t ndx;
+  if (elf_getshdrstrndx (elf, &ndx) != 0)
+    {
+      printf ("cannot get section header table index: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  if (ndx == SHN_UNDEF)
+    {
+      printf ("ELF file `%s' doesn't have a section header table index", fname);
+      exit (1);
+    }
+
+  Elf_Scn *scn = elf_getscn (elf, ndx);
+  if (scn == NULL)
+    {
+      printf ("Couldn't get section %zd: %s\n", ndx, elf_errmsg (-1));
+      exit (1);
+    }
+
+  void print_strings (void)
+  {
+    GElf_Shdr shdr_mem;
+    GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+
+    printf ("Strings in section %zd (%s):\n", ndx,
+	    ((shdr->sh_flags & SHF_COMPRESSED) != 0
+	     ? "compressed" : "uncompressed"));
+
+    size_t off = 0;
+    const char *str = elf_strptr (elf, ndx, off);
+    while (str != NULL)
+      {
+	printf ("[%zx] '%s'\n", off, str);
+	off += strlen (str) + 1;
+	str = elf_strptr (elf, ndx, off);
+      }
+  }
+
+  if (elf_compress (scn, ELFCOMPRESS_ZLIB, 0) < 0)
+    {
+      printf ("Couldn't compress section %zd: %s\n", ndx, elf_errmsg (-1));
+      exit (1);
+    }
+  print_strings ();
+
+  if (elf_compress (scn, 0, 0) < 0)
+    {
+      printf ("Couldn't decompress section %zd: %s\n", ndx, elf_errmsg (-1));
+      exit (1);
+    }
+  print_strings ();
+
+  if (elf_end (elf) != 0)
+    {
+      printf ("failure in elf_end: %s\n", elf_errmsg (-1));
+      exit (1);
+    }
+
+  close (fd);
+
+  return 0;
+}
diff --git a/third_party/matplotlib-cpp/BUILD b/third_party/matplotlib-cpp/BUILD
index 9d21f21..8eb8734 100644
--- a/third_party/matplotlib-cpp/BUILD
+++ b/third_party/matplotlib-cpp/BUILD
@@ -8,6 +8,7 @@
     deps = [
         "@usr_repo//:python2.7_lib",
     ],
+    visibility = ["//visibility:public"],
     restricted_to = ["//tools:k8"],
 )
 
diff --git a/tools/ci/run-tests.sh b/tools/ci/run-tests.sh
index 6b7414f..5e31caa 100755
--- a/tools/ci/run-tests.sh
+++ b/tools/ci/run-tests.sh
@@ -1,5 +1,6 @@
 #!/bin/sh
 set -e
+set -x
 
 bazel --batch test -c opt --curses=no --color=no //...
 bazel --batch build -c opt --curses=no --color=no //... --cpu=roborio
diff --git a/tools/cpp/CROSSTOOL b/tools/cpp/CROSSTOOL
index 6e0c158..bda3e1b 100644
--- a/tools/cpp/CROSSTOOL
+++ b/tools/cpp/CROSSTOOL
@@ -1013,7 +1013,7 @@
       }
       flag_group {
         iterate_over: 'system_include_paths'
-        flag: '-iquote'
+        flag: '-I'
         flag: '%{system_include_paths}'
       }
     }
diff --git a/y2017/control_loops/drivetrain/BUILD b/y2017/control_loops/drivetrain/BUILD
index c44da31..8651320 100644
--- a/y2017/control_loops/drivetrain/BUILD
+++ b/y2017/control_loops/drivetrain/BUILD
@@ -1,6 +1,6 @@
 package(default_visibility = ['//visibility:public'])
 
-load('/aos/build/queues', 'queue_library')
+load('//aos/build:queues.bzl', 'queue_library')
 
 genrule(
   name = 'genrule_drivetrain',
diff --git a/y2018/control_loops/python/BUILD b/y2018/control_loops/python/BUILD
index 04a244e..a72c464 100644
--- a/y2018/control_loops/python/BUILD
+++ b/y2018/control_loops/python/BUILD
@@ -56,3 +56,29 @@
   ],
   restricted_to = ['//tools:k8'],
 )
+
+py_binary(
+  name = 'intake',
+  srcs = [
+    'intake.py',
+  ],
+  deps = [
+    '//external:python-gflags',
+    '//external:python-glog',
+    '//frc971/control_loops/python:controls',
+  ],
+  restricted_to = ['//tools:k8'],
+)
+
+cc_binary(
+    name = "arm_mpc",
+    srcs = [
+        "arm_mpc.cc",
+    ],
+    deps = [
+        "//third_party/ct",
+        "//third_party/matplotlib-cpp",
+        "//third_party/gflags",
+    ],
+    restricted_to = ["//tools:k8"],
+)
diff --git a/y2018/control_loops/python/arm_mpc.cc b/y2018/control_loops/python/arm_mpc.cc
new file mode 100644
index 0000000..2727545
--- /dev/null
+++ b/y2018/control_loops/python/arm_mpc.cc
@@ -0,0 +1,454 @@
+#include <chrono>
+#include <cmath>
+#include <thread>
+
+#include <ct/optcon/optcon.h>
+
+#include "third_party/gflags/include/gflags/gflags.h"
+#include "third_party/matplotlib-cpp/matplotlibcpp.h"
+
+DEFINE_double(boundary_scalar, 12.0, "Test command-line flag");
+DEFINE_double(boundary_rate, 25.0, "Sigmoid rate");
+DEFINE_bool(sigmoid, true, "If true, sigmoid, else exponential.");
+DEFINE_double(round_corner, 0.0, "Corner radius of the constraint box.");
+
+// This code is for analysis and simulation of a double jointed arm.  It is an
+// attempt to see if a MPC could work for arm control under constraints.
+
+// Describes a double jointed arm.
+// A large chunk of this code comes from demos.  Most of the raw pointer,
+// shared_ptr, and non-const &'s come from the library's conventions.
+template <typename SCALAR>
+class MySecondOrderSystem : public ::ct::core::ControlledSystem<4, 2, SCALAR> {
+ public:
+  static const size_t STATE_DIM = 4;
+  static const size_t CONTROL_DIM = 2;
+
+  MySecondOrderSystem(::std::shared_ptr<::ct::core::Controller<4, 2, SCALAR>>
+                          controller = nullptr)
+      : ::ct::core::ControlledSystem<4, 2, SCALAR>(
+            controller, ::ct::core::SYSTEM_TYPE::GENERAL) {}
+
+  MySecondOrderSystem(const MySecondOrderSystem &arg)
+      : ::ct::core::ControlledSystem<4, 2, SCALAR>(arg) {}
+
+  // Deep copy
+  MySecondOrderSystem *clone() const override {
+    return new MySecondOrderSystem(*this);
+  }
+  virtual ~MySecondOrderSystem() {}
+
+  // Evaluate the system dynamics.
+  //
+  // Args:
+  //   state: current state (position, velocity)
+  //   t: current time (gets ignored)
+  //   control: control action
+  //   derivative: (velocity, acceleration)
+  virtual void computeControlledDynamics(
+      const ::ct::core::StateVector<4, SCALAR> &state, const SCALAR & /*t*/,
+      const ::ct::core::ControlVector<2, SCALAR> &control,
+      ::ct::core::StateVector<4, SCALAR> &derivative) override {
+    derivative(0) = state(1);
+    derivative(1) = control(0);
+    derivative(2) = state(3);
+    derivative(3) = control(1);
+  }
+};
+
+template <size_t STATE_DIM, size_t CONTROL_DIM, typename SCALAR_EVAL = double,
+          typename SCALAR = SCALAR_EVAL>
+class MyTermStateBarrier : public ::ct::optcon::TermBase<STATE_DIM, CONTROL_DIM,
+                                                         SCALAR_EVAL, SCALAR> {
+ public:
+  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
+  typedef Eigen::Matrix<SCALAR_EVAL, STATE_DIM, 1> state_vector_t;
+  typedef Eigen::Matrix<SCALAR_EVAL, STATE_DIM, STATE_DIM> state_matrix_t;
+  typedef Eigen::Matrix<SCALAR_EVAL, CONTROL_DIM, CONTROL_DIM> control_matrix_t;
+  typedef Eigen::Matrix<SCALAR_EVAL, CONTROL_DIM, STATE_DIM>
+      control_state_matrix_t;
+  typedef Eigen::Matrix<SCALAR_EVAL, STATE_DIM, STATE_DIM>
+      state_matrix_double_t;
+  typedef Eigen::Matrix<SCALAR_EVAL, CONTROL_DIM, CONTROL_DIM>
+      control_matrix_double_t;
+  typedef Eigen::Matrix<SCALAR_EVAL, CONTROL_DIM, STATE_DIM>
+      control_state_matrix_double_t;
+
+  MyTermStateBarrier() {}
+
+  MyTermStateBarrier(const MyTermStateBarrier & /*arg*/) {}
+
+  static constexpr double kEpsilon = 1.0e-7;
+
+  virtual ~MyTermStateBarrier() {}
+
+  MyTermStateBarrier<STATE_DIM, CONTROL_DIM, SCALAR_EVAL, SCALAR> *clone()
+      const override {
+    return new MyTermStateBarrier(*this);
+  }
+
+  virtual SCALAR evaluate(const Eigen::Matrix<SCALAR, STATE_DIM, 1> &x,
+                          const Eigen::Matrix<SCALAR, CONTROL_DIM, 1> & /*u*/,
+                          const SCALAR & /*t*/) override {
+    SCALAR min_distance;
+
+    // Round the corner by this amount.
+    SCALAR round_corner = SCALAR(FLAGS_round_corner);
+
+    // Positive means violation.
+    SCALAR theta0_distance = x(0, 0) - (0.5 + round_corner);
+    SCALAR theta1_distance = (0.8 - round_corner) - x(2, 0);
+    if (theta0_distance < SCALAR(0.0) && theta1_distance < SCALAR(0.0)) {
+      // Ok, both outside.  Return corner distance.
+      min_distance = -hypot(theta1_distance, theta0_distance);
+    } else if (theta0_distance < SCALAR(0.0) && theta1_distance > SCALAR(0.0)) {
+      min_distance = theta0_distance;
+    } else if (theta0_distance > SCALAR(0.0) && theta1_distance < SCALAR(0.0)) {
+      min_distance = theta1_distance;
+    } else {
+      min_distance = ::std::min(theta0_distance, theta1_distance);
+    }
+    min_distance += round_corner;
+    if (FLAGS_sigmoid) {
+      return FLAGS_boundary_scalar /
+             (1.0 + ::std::exp(-min_distance * FLAGS_boundary_rate));
+    } else {
+      // Values of 4 and 15 work semi resonably.
+      return FLAGS_boundary_scalar *
+             ::std::exp(min_distance * FLAGS_boundary_rate);
+    }
+  }
+
+  ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL> stateDerivative(
+      const ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL> &x,
+      const ::ct::core::ControlVector<CONTROL_DIM, SCALAR_EVAL> &u,
+      const SCALAR_EVAL &t) override {
+    SCALAR epsilon = SCALAR(kEpsilon);
+
+    ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL> result =
+        ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL>::Zero();
+
+    // Perturb x for both position axis and return the result.
+    for (size_t i = 0; i < STATE_DIM; i += 2) {
+      ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL> plus_perterbed_x = x;
+      ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL> minus_perterbed_x = x;
+      plus_perterbed_x[i] += epsilon;
+      minus_perterbed_x[i] -= epsilon;
+      result[i] = (evaluate(plus_perterbed_x, u, t) -
+                   evaluate(minus_perterbed_x, u, t)) /
+                  (epsilon * 2.0);
+    }
+    return result;
+  }
+
+  // Compute second order derivative of this cost term w.r.t. the state
+  state_matrix_t stateSecondDerivative(
+      const ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL> &x,
+      const ::ct::core::ControlVector<CONTROL_DIM, SCALAR_EVAL> &u,
+      const SCALAR_EVAL &t) override {
+    state_matrix_t result = state_matrix_t::Zero();
+
+    SCALAR epsilon = SCALAR(kEpsilon);
+
+    // Perturb x a second time.
+    for (size_t i = 0; i < STATE_DIM; i += 2) {
+      ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL> plus_perterbed_x = x;
+      ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL> minus_perterbed_x = x;
+      plus_perterbed_x[i] += epsilon;
+      minus_perterbed_x[i] -= epsilon;
+      state_vector_t delta = (stateDerivative(plus_perterbed_x, u, t) -
+                              stateDerivative(minus_perterbed_x, u, t)) /
+                             (epsilon * 2.0);
+
+      result.col(i) = delta;
+    }
+    return result;
+  }
+
+  ::ct::core::ControlVector<CONTROL_DIM, SCALAR_EVAL> controlDerivative(
+      const ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL> & /*x*/,
+      const ::ct::core::ControlVector<CONTROL_DIM, SCALAR_EVAL> & /*u*/,
+      const SCALAR_EVAL & /*t*/) override {
+    return ::ct::core::StateVector<CONTROL_DIM, SCALAR_EVAL>::Zero();
+  }
+
+  control_state_matrix_t stateControlDerivative(
+      const ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL> & /*x*/,
+      const ::ct::core::ControlVector<CONTROL_DIM, SCALAR_EVAL> & /*u*/,
+      const SCALAR_EVAL & /*t*/) override {
+    control_state_matrix_t result = control_state_matrix_t::Zero();
+
+    return result;
+  }
+
+  control_matrix_t controlSecondDerivative(
+      const ::ct::core::StateVector<STATE_DIM, SCALAR_EVAL> & /*x*/,
+      const ::ct::core::ControlVector<CONTROL_DIM, SCALAR_EVAL> & /*u*/,
+      const SCALAR_EVAL & /*t*/) override {
+    control_matrix_t result = control_matrix_t::Zero();
+    return result;
+  }
+
+  /*
+    // TODO(austin): Implement this for the automatic differentiation.
+    virtual ::ct::core::ADCGScalar evaluateCppadCg(
+        const ::ct::core::StateVector<STATE_DIM, ::ct::core::ADCGScalar> &x,
+        const ::ct::core::ControlVector<CONTROL_DIM, ::ct::core::ADCGScalar> &u,
+        ::ct::core::ADCGScalar t) override {
+      ::ct::core::ADCGScalar c = ::ct::core::ADCGScalar(0.0);
+      for (size_t i = 0; i < STATE_DIM; i++)
+        c += barriers_[i].computeActivation(x(i));
+      return c;
+    }
+  */
+};
+
+int main(int argc, char **argv) {
+  gflags::ParseCommandLineFlags(&argc, &argv, false);
+  // PRELIMINIARIES, see example NLOC.cpp
+  constexpr size_t state_dim = MySecondOrderSystem<double>::STATE_DIM;
+  constexpr size_t control_dim = MySecondOrderSystem<double>::CONTROL_DIM;
+
+  ::std::shared_ptr<ct::core::ControlledSystem<state_dim, control_dim>>
+  oscillator_dynamics(new MySecondOrderSystem<double>());
+
+  ::std::shared_ptr<ct::core::SystemLinearizer<state_dim, control_dim>>
+      ad_linearizer(new ::ct::core::SystemLinearizer<state_dim, control_dim>(
+          oscillator_dynamics));
+
+  constexpr double kQPos = 0.5;
+  constexpr double kQVel = 1.65;
+  ::Eigen::Matrix<double, 4, 4> Q_step;
+  Q_step << 1.0 / (kQPos * kQPos), 0.0, 0.0, 0.0, 0.0, 1.0 / (kQVel * kQVel),
+      0.0, 0.0, 0.0, 0.0, 1.0 / (kQPos * kQPos), 0.0, 0.0, 0.0, 0.0,
+      1.0 / (kQVel * kQVel);
+  ::Eigen::Matrix<double, 2, 2> R_step;
+  R_step << 1.0 / (12.0 * 12.0), 0.0, 0.0, 1.0 / (12.0 * 12.0);
+  ::std::shared_ptr<ct::optcon::TermQuadratic<state_dim, control_dim>>
+      intermediate_cost(new ::ct::optcon::TermQuadratic<state_dim, control_dim>(
+          Q_step, R_step));
+
+  // TODO(austin): DARE for these.
+  ::Eigen::Matrix<double, 4, 4> Q_final = Q_step;
+  ::Eigen::Matrix<double, 2, 2> R_final = R_step;
+  ::std::shared_ptr<ct::optcon::TermQuadratic<state_dim, control_dim>>
+      final_cost(new ::ct::optcon::TermQuadratic<state_dim, control_dim>(
+          Q_final, R_final));
+
+  ::std::shared_ptr<ct::optcon::TermBase<state_dim, control_dim>> bounds_cost(
+      new MyTermStateBarrier<4, 2>());
+
+  // TODO(austin): Cost function needs constraints.
+  ::std::shared_ptr<::ct::optcon::CostFunctionQuadratic<state_dim, control_dim>>
+      cost_function(
+          new ::ct::optcon::CostFunctionAnalytical<state_dim, control_dim>());
+  cost_function->addIntermediateTerm(intermediate_cost);
+  cost_function->addIntermediateTerm(bounds_cost);
+  cost_function->addFinalTerm(final_cost);
+
+  // STEP 1-D: set up the box constraints for the control input
+  // input box constraint boundaries with sparsities in constraint toolbox
+  // format
+  Eigen::VectorXd u_lb(control_dim);
+  Eigen::VectorXd u_ub(control_dim);
+  u_ub.setConstant(12.0);
+  u_lb = -u_ub;
+  ::std::cout << "uub " << u_ub << ::std::endl;
+  ::std::cout << "ulb " << u_lb << ::std::endl;
+
+  // constraint terms
+  std::shared_ptr<::ct::optcon::ControlInputConstraint<state_dim, control_dim>>
+      controlConstraint(
+          new ::ct::optcon::ControlInputConstraint<state_dim, control_dim>(
+              u_lb, u_ub));
+  controlConstraint->setName("ControlInputConstraint");
+  // create constraint container
+  std::shared_ptr<
+      ::ct::optcon::ConstraintContainerAnalytical<state_dim, control_dim>>
+      box_constraints(
+          new ::ct::optcon::ConstraintContainerAnalytical<state_dim,
+                                                          control_dim>());
+  // add and initialize constraint terms
+  box_constraints->addIntermediateConstraint(controlConstraint, true);
+  box_constraints->initialize();
+
+  // Starting point.
+  ::ct::core::StateVector<state_dim> x0;
+  x0 << 1.0, 0.0, 0.9, 0.0;
+
+  constexpr ::ct::core::Time kTimeHorizon = 1.5;
+  ::ct::optcon::OptConProblem<state_dim, control_dim> opt_con_problem(
+      kTimeHorizon, x0, oscillator_dynamics, cost_function, ad_linearizer);
+  ::ct::optcon::NLOptConSettings ilqr_settings;
+  ilqr_settings.dt = 0.00505;  // the control discretization in [sec]
+  ilqr_settings.integrator = ::ct::core::IntegrationType::RK4;
+  ilqr_settings.discretization =
+      ::ct::optcon::NLOptConSettings::APPROXIMATION::FORWARD_EULER;
+  // ilqr_settings.discretization =
+  //   NLOptConSettings::APPROXIMATION::MATRIX_EXPONENTIAL;
+  ilqr_settings.max_iterations = 20;
+  ilqr_settings.min_cost_improvement = 1.0e-11;
+  ilqr_settings.nlocp_algorithm =
+      ::ct::optcon::NLOptConSettings::NLOCP_ALGORITHM::ILQR;
+  // the LQ-problems are solved using a custom Gauss-Newton Riccati solver
+  // ilqr_settings.lqocp_solver =
+  // NLOptConSettings::LQOCP_SOLVER::GNRICCATI_SOLVER;
+  ilqr_settings.lqocp_solver =
+      ::ct::optcon::NLOptConSettings::LQOCP_SOLVER::HPIPM_SOLVER;
+  ilqr_settings.printSummary = true;
+  if (ilqr_settings.lqocp_solver ==
+      ::ct::optcon::NLOptConSettings::LQOCP_SOLVER::HPIPM_SOLVER) {
+    opt_con_problem.setBoxConstraints(box_constraints);
+  }
+
+  size_t K = ilqr_settings.computeK(kTimeHorizon);
+  printf("Using %d steps\n", static_cast<int>(K));
+
+  // Vector of feeback matricies.
+  ::ct::core::FeedbackArray<state_dim, control_dim> u0_fb(
+      K, ::ct::core::FeedbackMatrix<state_dim, control_dim>::Zero());
+  ::ct::core::ControlVectorArray<control_dim> u0_ff(
+      K, ::ct::core::ControlVector<control_dim>::Zero());
+  ::ct::core::StateVectorArray<state_dim> x_ref_init(K + 1, x0);
+  ::ct::core::StateFeedbackController<state_dim, control_dim>
+      initial_controller(x_ref_init, u0_ff, u0_fb, ilqr_settings.dt);
+
+  // STEP 2-C: create an NLOptConSolver instance
+  ::ct::optcon::NLOptConSolver<state_dim, control_dim> iLQR(opt_con_problem,
+                                                            ilqr_settings);
+  // Seed it with the initial guess
+  iLQR.setInitialGuess(initial_controller);
+  // we solve the optimal control problem and retrieve the solution
+  iLQR.solve();
+  ::ct::core::StateFeedbackController<state_dim, control_dim> initial_solution =
+      iLQR.getSolution();
+  // MPC-EXAMPLE
+  // we store the initial solution obtained from solving the initial optimal
+  // control problem, and re-use it to initialize the MPC solver in the
+  // following.
+
+  // STEP 1: first, we set up an MPC instance for the iLQR solver and configure
+  // it. Since the MPC class is wrapped around normal Optimal Control Solvers,
+  // we need to different kind of settings, those for the optimal control
+  // solver, and those specific to MPC:
+
+  // 1) settings for the iLQR instance used in MPC. Of course, we use the same
+  // settings as for solving the initial problem ...
+  ::ct::optcon::NLOptConSettings ilqr_settings_mpc = ilqr_settings;
+  ilqr_settings_mpc.max_iterations = 20;
+  // and we limited the printouts, too.
+  ilqr_settings_mpc.printSummary = false;
+  // 2) settings specific to model predictive control. For a more detailed
+  // description of those, visit ct/optcon/mpc/MpcSettings.h
+  ::ct::optcon::mpc_settings mpc_settings;
+  mpc_settings.stateForwardIntegration_ = true;
+  mpc_settings.postTruncation_ = false;
+  mpc_settings.measureDelay_ = false;
+  mpc_settings.fixedDelayUs_ = 5000 * 0;  // Ignore the delay for now.
+  mpc_settings.delayMeasurementMultiplier_ = 1.0;
+  // mpc_settings.mpc_mode = ::ct::optcon::MPC_MODE::FIXED_FINAL_TIME;
+  mpc_settings.mpc_mode = ::ct::optcon::MPC_MODE::CONSTANT_RECEDING_HORIZON;
+  mpc_settings.coldStart_ = false;
+
+  // STEP 2 : Create the iLQR-MPC object, based on the optimal control problem
+  // and the selected settings.
+  ::ct::optcon::MPC<::ct::optcon::NLOptConSolver<state_dim, control_dim>>
+      ilqr_mpc(opt_con_problem, ilqr_settings_mpc, mpc_settings);
+  // initialize it using the previously computed initial controller
+  ilqr_mpc.setInitialGuess(initial_solution);
+  // STEP 3: running MPC
+  // Here, we run the MPC loop. Note that the general underlying idea is that
+  // you receive a state-estimate together with a time-stamp from your robot or
+  // system. MPC needs to receive both that time information and the state from
+  // your control system. Here, "simulate" the time measurement using
+  // ::std::chrono and wrap everything into a for-loop.
+  // The basic idea of operation is that after receiving time and state
+  // information, one executes the finishIteration() method of MPC.
+  ///
+  auto start_time = ::std::chrono::high_resolution_clock::now();
+  // limit the maximum number of runs in this example
+  size_t maxNumRuns = 400;
+  ::std::cout << "Starting to run MPC" << ::std::endl;
+
+  ::std::vector<double> time_array;
+  ::std::vector<double> theta1_array;
+  ::std::vector<double> omega1_array;
+  ::std::vector<double> theta2_array;
+  ::std::vector<double> omega2_array;
+
+  ::std::vector<double> u0_array;
+  ::std::vector<double> u1_array;
+
+  for (size_t i = 0; i < maxNumRuns; i++) {
+    ::std::cout << "Solving iteration " << i << ::std::endl;
+    // Time which has passed since start of MPC
+    auto current_time = ::std::chrono::high_resolution_clock::now();
+    ::ct::core::Time t =
+        1e-6 *
+        ::std::chrono::duration_cast<::std::chrono::microseconds>(current_time -
+                                                                  start_time)
+            .count();
+    // prepare mpc iteration
+    ilqr_mpc.prepareIteration(t);
+    // new optimal policy
+    ::std::shared_ptr<ct::core::StateFeedbackController<state_dim, control_dim>>
+        newPolicy(
+            new ::ct::core::StateFeedbackController<state_dim, control_dim>());
+    // timestamp of the new optimal policy
+    ::ct::core::Time ts_newPolicy;
+    current_time = ::std::chrono::high_resolution_clock::now();
+    t = 1e-6 *
+        ::std::chrono::duration_cast<::std::chrono::microseconds>(current_time -
+                                                                  start_time)
+            .count();
+    bool success = ilqr_mpc.finishIteration(x0, t, *newPolicy, ts_newPolicy);
+    // we break the loop in case the time horizon is reached or solve() failed
+    if (ilqr_mpc.timeHorizonReached() | !success) break;
+
+    ::std::cout << "Solved  for time " << newPolicy->time()[0] << " state "
+                << x0.transpose() << " next time " << newPolicy->time()[1]
+                << ::std::endl;
+    ::std::cout << "  Solution: Uff " << newPolicy->uff()[0].transpose()
+                << " x_ref_ " << newPolicy->x_ref()[0].transpose()
+                << ::std::endl;
+
+    time_array.push_back(ilqr_settings.dt * i);
+    theta1_array.push_back(x0(0));
+    omega1_array.push_back(x0(1));
+    theta2_array.push_back(x0(2));
+    omega2_array.push_back(x0(3));
+
+    u0_array.push_back(newPolicy->uff()[0](0, 0));
+    u1_array.push_back(newPolicy->uff()[0](1, 0));
+
+    ::std::cout << "xref[1] " << newPolicy->x_ref()[1].transpose()
+                << ::std::endl;
+    ilqr_mpc.doForwardIntegration(0.0, ilqr_settings.dt, x0, newPolicy);
+    ::std::cout << "Next X:  " << x0.transpose() << ::std::endl;
+
+    // TODO(austin): Re-use the policy. Maybe?  Or maybe mpc already does that.
+  }
+  // The summary contains some statistical data about time delays, etc.
+  ilqr_mpc.printMpcSummary();
+
+  // Now plot our simulation.
+  matplotlibcpp::plot(time_array, theta1_array, {{"label", "theta1"}});
+  matplotlibcpp::plot(time_array, omega1_array, {{"label", "omega1"}});
+  matplotlibcpp::plot(time_array, theta2_array, {{"label", "theta2"}});
+  matplotlibcpp::plot(time_array, omega2_array, {{"label", "omega2"}});
+  matplotlibcpp::legend();
+
+  matplotlibcpp::figure();
+  matplotlibcpp::plot(theta1_array, theta2_array, {{"label", "trajectory"}});
+  ::std::vector<double> box_x{0.5, 0.5, 1.0, 1.0};
+  ::std::vector<double> box_y{0.0, 0.8, 0.8, 0.0};
+  matplotlibcpp::plot(box_x, box_y, {{"label", "keepout zone"}});
+  matplotlibcpp::legend();
+
+  matplotlibcpp::figure();
+  matplotlibcpp::plot(time_array, u0_array, {{"label", "u0"}});
+  matplotlibcpp::plot(time_array, u1_array, {{"label", "u1"}});
+  matplotlibcpp::legend();
+  matplotlibcpp::show();
+}
diff --git a/y2018/control_loops/python/intake.py b/y2018/control_loops/python/intake.py
index d75d438..f29d3b5 100755
--- a/y2018/control_loops/python/intake.py
+++ b/y2018/control_loops/python/intake.py
@@ -1,245 +1,357 @@
-#!/usr/bin/python3
+#!/usr/bin/python
 
-# This code was used to select the gear ratio for the intake.
-# Run it from the command line and it displays the time required
-# to rotate the intake 180 degrees.
-# 
-# Michael Schuh
-# January 20, 2018
-
-import math
+from frc971.control_loops.python import control_loop
+from frc971.control_loops.python import controls
 import numpy
-import scipy.integrate
+import sys
+import matplotlib
+from matplotlib import pylab
+import gflags
+import glog
 
-# apt-get install python-scipy python3-scipy python-numpy python3-numpy
+FLAGS = gflags.FLAGS
 
-pi = math.pi
-pi2 = 2.0*pi
-rad_to_deg = 180.0/pi
-inches_to_meters = 0.0254
-lbs_to_kg = 1.0/2.2
-newton_to_lbf = 0.224809
-newton_meters_to_ft_lbs = 0.73756
-run_count = 0
-theta_travel = 0.0
+try:
+  gflags.DEFINE_bool('plot', False, 'If true, plot the loop response.')
+except gflags.DuplicateFlagError:
+  pass
 
-def to_deg(angle):
-  return (angle*rad_to_deg)
+class Intake(control_loop.ControlLoop):
+  def __init__(self, name="Intake"):
+    super(Intake, self).__init__(name)
+    self.motor = control_loop.BAG()
+    # TODO(constants): Update all of these & retune poles.
+    # Stall Torque in N m
+    self.stall_torque = self.motor.stall_torque
+    # Stall Current in Amps
+    self.stall_current = self.motor.stall_current
+    # Free Speed in RPM
+    self.free_speed = self.motor.free_speed
+    # Free Current in Amps
+    self.free_current = self.motor.free_current
 
-def to_rad(angle):
-  return (angle/rad_to_deg)
+    # Resistance of the motor
+    self.resistance = self.motor.resistance
+    # Motor velocity constant
+    self.Kv = self.motor.Kv
+    # Torque constant
+    self.Kt = self.motor.Kt
+    # Gear ratio
+    self.G = 1.0 / 100.0
 
-def to_rotations(angle):
-  return (angle/pi2)
+    self.motor_inertia = 0.000006
 
-def time_derivative(x, t, voltage, c1, c2, c3):
-  global run_count
-  theta, omega = x
-  dxdt = [omega, -c1*omega + c3*math.sin(theta) + c2*voltage]
-  run_count = run_count + 1
+    # Series elastic moment of inertia
+    self.Je = self.motor_inertia / (self.G * self.G)
+    # Grabber moment of inertia
+    self.Jo = 0.295
 
-  #print ('dxdt = ',dxdt,' repr(dxdt) = ', repr(dxdt))
-  return dxdt
+    # Spring constant (N m / radian)
+    self.Ks = 30.0
 
-def get_distal_angle(theta_proximal):
-  # For the proximal angle = -50 degrees, the distal angle is -180 degrees
-  # For the proximal angle =  10 degrees, the distal angle is  -90 degrees
-  distal_angle = to_rad(-180.0 - (-50.0-to_deg(theta_proximal))*(180.0-90.0)/(50.0+10.0))
-  return distal_angle
-  
+    # Control loop time step
+    self.dt = 0.00505
 
-def get_180_degree_time(c1,c2,c3,voltage,gear_ratio,motor_free_speed):
-  #print ("# step     time    theta    angular_speed   angular_acceleration  theta   angular_speed  motor_speed motor_speed_fraction")
-  #print ("#          (sec)   (rad)      (rad/sec)        (rad/sec^2)      (rotations) (rotations/sec)    (rpm)   (fraction)")
-  global run_count
-  global theta_travel
+    # State is [output_position, output_velocity,
+    #           elastic_position, elastic_velocity]
+    # The output position is the absolute position of the intake arm.
+    # The elastic position is the absolute position of the motor side of the
+    # series elastic.
+    # Input is [voltage]
 
-  if ( True ):
-    # Gravity is assisting the motion.
-    theta_start = 0.0
-    theta_target = pi
-  elif ( False ):
-    # Gravity is assisting the motion.
-    theta_start = 0.0
-    theta_target = -pi
-  elif ( False ):
-    # Gravity is slowing the motion.
-    theta_start = pi
-    theta_target = 0.0
-  elif ( False ):
-    # Gravity is slowing the motion.
-    theta_start = -pi
-    theta_target = 0.0
-  elif ( False ):
-    # This is for the proximal arm motion.
-    theta_start = to_rad(-50.0)
-    theta_target = to_rad(10.0)
+    self.A_continuous = numpy.matrix(
+        [[0.0, 1.0, 0.0, 0.0],
+         [(-self.Ks / self.Jo), 0.0, (self.Ks / self.Jo), 0.0],
+         [0.0, 0.0, 0.0, 1.0],
+         [(self.Ks / self.Je), 0.0, (-self.Ks / self.Je), \
+          -self.Kt / (self.Je * self.resistance * self.Kv * self.G * self.G)]])
 
-  theta_half = 0.5*(theta_start + theta_target)
-  if (theta_start > theta_target):
-    voltage = -voltage
-  theta = theta_start
-  theta_travel = theta_start - theta_target 
-  if ( run_count == 0 ):
-    print ("# Theta Start = %.2f radians End = %.2f Theta travel %.2f Theta half = %.2f Voltage = %.2f" % (theta_start,theta_target,theta_travel,theta_half, voltage))
-    print ("# Theta Start = %.2f degrees End = %.2f Theta travel %.2f Theta half = %.2f Voltage = %.2f" % (to_deg(theta_start),to_deg(theta_target),to_deg(theta_travel),to_deg(theta_half), voltage))
-  omega = 0.0
-  time = 0.0
-  delta_time = 0.01 # time step in seconds
-  for step in range(1, 5000):
-     t = numpy.array([time, time + delta_time])
-     time = time + delta_time
-     x = [theta, omega]
-     angular_acceleration = -c1*omega + c2*voltage
-     x_n_plus_1 = scipy.integrate.odeint(time_derivative,x,t,args=(voltage,c1,c2,c3))
-     #print ('x_n_plus_1 = ',x_n_plus_1)
-     #print ('repr(x_n_plus_1) = ',repr(x_n_plus_1))
-     theta, omega = x_n_plus_1[1]
-     #theta= x_n_plus_1[0]
-     #omega = x_n_plus_1[1]
-     if ( False ):
-       print ("%4d  %8.4f %8.2f          %8.4f          %8.4f    %8.3f    %8.3f     %8.3f      %8.3f" % \
-         (step, time, theta, omega, angular_acceleration, to_rotations(theta), \
-         to_rotations(omega), omega*gear_ratio*60.0/pi2, omega*gear_ratio/motor_free_speed ))
-     if (theta_start < theta_target):
-       # Angle is increasing through the motion.
-       if (theta > theta_half):
-         break
-     else:
-       # Angle is decreasing through the motion.
-       if (theta < theta_half):
-         break
-       
-  #print ("# step     time    theta    angular_speed   angular_acceleration  theta   angular_speed  motor_speed motor_speed_fraction")
-  #print ("#          (sec)   (rad)      (rad/sec)        (rad/sec^2)      (rotations) (rotations/sec)    (rpm)   (fraction)")
-  #print ("# Total time for 1/2 rotation of arm is %0.2f" % (time*2))
-  return (2.0*time)
+    # Start with the unmodified input
+    self.B_continuous = numpy.matrix(
+        [[0.0],
+         [0.0],
+         [0.0],
+         [self.Kt / (self.G * self.Je * self.resistance)]])
 
-def main():
-  gravity = 9.8 # m/sec^2 Gravity Constant
-  gravity = 0.0 # m/sec^2 Gravity Constant - Use 0.0 for the intake.  It is horizontal.
-  voltage_nominal = 12 # Volts
-  
-  # Vex 775 Pro motor specs from http://banebots.com/p/M2-RS550-120
-  motor_name = "Vex 775 Pro motor specs from http://banebots.com/p/M2-RS550-120"
-  current_stall = 134 # amps stall current
-  current_no_load = 0.7 # amps no load current
-  torque_stall = 710/1000.0 # N-m Stall Torque
-  speed_no_load_rpm = 18730 # RPM no load speed
-  
-  if ( True ):
-    # Bag motor from https://www.vexrobotics.com/217-3351.html
-    motor_name = "Bag motor from https://www.vexrobotics.com/217-3351.html"
-    current_stall = 53.0 # amps stall current
-    current_no_load = 1.8 # amps no load current
-    torque_stall = 0.4 # N-m Stall Torque
-    speed_no_load_rpm = 13180.0 # RPM no load speed
-  
-  if ( False ):
-    # Mini CIM motor from https://www.vexrobotics.com/217-3371.html
-    motor_name = "Mini CIM motor from https://www.vexrobotics.com/217-3371.html"
-    current_stall = 89.0 # amps stall current
-    current_no_load = 3.0 # amps no load current
-    torque_stall = 1.4 # N-m Stall Torque
-    speed_no_load_rpm = 5840.0 # RPM no load speed
+    self.C = numpy.matrix([[1.0, 0.0, -1.0, 0.0],
+                           [0.0, 0.0, 1.0, 0.0]])
+    self.D = numpy.matrix([[0.0],
+                           [0.0]])
 
-  # How many motors are we using?
-  num_motors = 1
+    self.A, self.B = self.ContinuousToDiscrete(
+        self.A_continuous, self.B_continuous, self.dt)
 
-  # Motor values
-  print ("# Motor: %s" % (motor_name))
-  print ("# Number of motors: %d" % (num_motors))
-  print ("# Stall torque: %.1f n-m" % (torque_stall))
-  print ("# Stall current: %.1f amps" % (current_stall))
-  print ("# No load current: %.1f amps" % (current_no_load))
-  print ("# No load speed: %.0f rpm" % (speed_no_load_rpm))
-  
-  # Constants from motor values
-  resistance_motor = voltage_nominal/current_stall 
-  speed_no_load_rps = speed_no_load_rpm/60.0 # Revolutions per second no load speed
-  speed_no_load = speed_no_load_rps*2.0*pi
-  Kt = num_motors*torque_stall/current_stall # N-m/A torque constant
-  Kv_rpm = speed_no_load_rpm /(voltage_nominal - resistance_motor*current_no_load)  # rpm/V
-  Kv = Kv_rpm*2.0*pi/60.0 # rpm/V
-  
-  # Robot Geometry and physics
-  length_proximal_arm = inches_to_meters*47.34 # m Length of arm connected to the robot base
-  length_distal_arm = inches_to_meters*44.0 # m Length of arm that holds the cube
-  length_intake_arm =  inches_to_meters*9.0 # m Length of intake arm from the pivot point to where the big roller contacts a cube.
-  mass_cube = 6.0*lbs_to_kg  # Weight of the cube in Kgrams
-  mass_proximal_arm = 5.5*lbs_to_kg # Weight of proximal arm
-  mass_distal_arm = 3.5*lbs_to_kg # Weight of distal arm
-  mass_distal = mass_cube + mass_distal_arm
-  mass_proximal = mass_proximal_arm + mass_distal
-  radius_to_proximal_arm_cg = 22.0*inches_to_meters # m Length from arm pivot point to arm CG
-  radius_to_distal_arm_cg = 10.0*inches_to_meters # m Length from arm pivot point to arm CG
+    controllability = controls.ctrb(self.A, self.B)
+    glog.debug('ctrb: ' + repr(numpy.linalg.matrix_rank(controllability)))
 
-  radius_to_distal_cg = ( length_distal_arm*mass_cube + radius_to_distal_arm_cg*mass_distal_arm)/mass_distal
-  radius_to_proximal_cg = ( length_proximal_arm*mass_distal + radius_to_proximal_arm_cg*mass_proximal_arm)/mass_proximal
-  J_cube = length_distal_arm*length_distal_arm*mass_cube 
-  # Kg m^2 Moment of inertia of the proximal arm
-  J_proximal_arm = radius_to_proximal_arm_cg*radius_to_proximal_arm_cg*mass_distal_arm 
-  # Kg m^2 Moment of inertia distal arm and cube at end of proximal arm.
-  J_distal_arm_and_cube_at_end_of_proximal_arm = length_proximal_arm*length_proximal_arm*mass_distal 
-  J_distal_arm = radius_to_distal_arm_cg*radius_to_distal_arm_cg*mass_distal_arm # Kg m^2 Moment of inertia of the distal arm
-  J = J_distal_arm_and_cube_at_end_of_proximal_arm + J_proximal_arm # Moment of inertia of the arm with the cube on the end
-  # Intake claw 
-  J_intake = 0.295 # Kg m^2 Moment of inertia of intake
-  J = J_intake
+    observability = controls.ctrb(self.A.T, self.C.T)
+    glog.debug('obs: ' + repr(numpy.linalg.matrix_rank(observability)))
 
-  gear_ratio = 140.0 # Guess at the gear ratio
-  gear_ratio = 100.0 # Guess at the gear ratio
-  gear_ratio = 90.0 # Guess at the gear ratio
+    glog.debug('A_continuous ' + repr(self.A_continuous))
+    glog.debug('B_continuous ' + repr(self.B_continuous))
 
-  error_margine = 1.0
-  voltage = 10.0 # voltage for the motor.  Assuming a loaded robot so not using 12 V.
-  # It might make sense to use a lower motor frees peed when the voltage is not a full 12 Volts.
-  # motor_free_speed = Kv*voltage
-  motor_free_speed = speed_no_load
-  
-  print ("# Kt = %f N-m/A\n# Kv_rpm = %f rpm/V\n# Kv = %f radians/V" % (Kt, Kv_rpm, Kv))
-  print ("# %.2f Ohms Resistance of the motor " % (resistance_motor))
-  print ("# %.2f kg Cube weight" % (mass_cube))
-  print ("# %.2f kg Proximal Arm mass" % (mass_proximal_arm))
-  print ("# %.2f kg Distal Arm mass" % (mass_distal_arm))
-  print ("# %.2f kg Distal Arm and Cube weight" % (mass_distal))
-  print ("# %.2f m Length from distal arm pivot point to arm CG" % (radius_to_distal_arm_cg))
-  print ("# %.2f m Length from distal arm pivot point to arm and cube cg" % (radius_to_distal_cg))
-  print ("# %.2f kg-m^2 Moment of inertia of the cube about the arm pivot point" % (J_cube))
-  print ("# %.2f m Length from proximal arm pivot point to arm CG" % (radius_to_proximal_arm_cg))
-  print ("# %.2f m Length from proximal arm pivot point to arm and cube cg" % (radius_to_proximal_cg))
-  print ("# %.2f m  Proximal arm length" % (length_proximal_arm))
-  print ("# %.2f m  Distal arm length" % (length_distal_arm))
+    self.K = numpy.matrix(numpy.zeros((1, 4)))
 
-  print ("# %.2f kg-m^2 Moment of inertia of the intake about the intake pivot point" % (J_intake))
-  print ("# %.2f kg-m^2 Moment of inertia of the distal arm about the arm pivot point" % (J_distal_arm))
-  print ("# %.2f kg-m^2 Moment of inertia of the proximal arm about the arm pivot point" % (J_proximal_arm))
-  print ("# %.2f kg-m^2 Moment of inertia of the distal arm and cube mass about the proximal arm pivot point" % (J_distal_arm_and_cube_at_end_of_proximal_arm))
-  print ("# %.2f kg-m^2 Moment of inertia of the intake the intake pivot point (J value used in simulation)" % (J))
-  print ("# %d Number of motors" % (num_motors))
-  
-  print ("# %.2f V Motor voltage" % (voltage))
-  for gear_ratio in range(60, 241, 10):
-    c1 = Kt*gear_ratio*gear_ratio/(Kv*resistance_motor*J)
-    c2 = gear_ratio*Kt/(J*resistance_motor)
-    c3 = radius_to_proximal_cg*mass_proximal*gravity/J
-  
-    if ( False ):
-      print ("# %.8f 1/sec C1 constant" % (c1))
-      print ("# %.2f 1/sec C2 constant" % (c2))
-      print ("# %.2f 1/(V sec^2) C3 constant" % (c3))
-      print ("# %.2f RPM Free speed at motor voltage" % (voltage*Kv_rpm))
-  
-    torque_90_degrees = radius_to_distal_cg*mass_distal*gravity
-    voltage_90_degrees = resistance_motor*torque_90_degrees/(gear_ratio*Kt)
-    torque_peak = gear_ratio*num_motors*torque_stall
-    torque_peak_ft_lbs = torque_peak * newton_meters_to_ft_lbs
-    normal_force = torque_peak/length_intake_arm
-    normal_force_lbf = newton_to_lbf*normal_force 
-    time_required = get_180_degree_time(c1,c2,c3,voltage,gear_ratio,motor_free_speed)
-    print ("Time for %.1f degrees for gear ratio %3.0f is %.2f seconds.  Peak (stall) torque %3.0f nm %3.0f ft-lb Normal force at intake end %3.0f N %2.0f lbf" % \
-      (to_deg(theta_travel),gear_ratio,time_required,
-       torque_peak,torque_peak_ft_lbs,normal_force,normal_force_lbf))
-  
+    q_pos = 0.05
+    q_vel = 2.65
+    self.Q = numpy.matrix(numpy.diag([(q_pos ** 2.0), (q_vel ** 2.0),
+                                      (q_pos ** 2.0), (q_vel ** 2.0)]))
+
+    r_nm = 0.025
+    self.R = numpy.matrix(numpy.diag([(r_nm ** 2.0), (r_nm ** 2.0)]))
+
+    self.KalmanGain, self.Q_steady = controls.kalman(
+        A=self.A, B=self.B, C=self.C, Q=self.Q, R=self.R)
+
+    # The box formed by U_min and U_max must encompass all possible values,
+    # or else Austin's code gets angry.
+    self.U_max = numpy.matrix([[12.0]])
+    self.U_min = numpy.matrix([[-12.0]])
+
+    self.InitializeState()
+
+
+class DelayedIntake(Intake):
+  def __init__(self, name="DelayedIntake"):
+    super(DelayedIntake, self).__init__(name=name)
+
+    self.A_undelayed = self.A
+    self.B_undelayed = self.B
+
+    self.C_unaugmented = self.C
+    self.C = numpy.matrix(numpy.zeros((2, 5)))
+    self.C[0:2, 0:4] = self.C_unaugmented
+
+    # Model this as X[4] is the last power.  And then B applies to the last
+    # power.  This lets us model the 1 cycle PWM delay accurately.
+    self.A = numpy.matrix(numpy.zeros((5, 5)))
+    self.A[0:4, 0:4] = self.A_undelayed
+    self.A[0:4, 4] = self.B_undelayed
+    self.B = numpy.matrix(numpy.zeros((5, 1)))
+    self.B[4, 0] = 1.0
+
+    # Coordinate transform fom absolute angles to relative angles.
+    # [output_position, output_velocity, spring_angle, spring_velocity, voltage]
+    abs_to_rel = numpy.matrix([[ 1.0,  0.0, 0.0, 0.0, 0.0],
+                               [ 0.0,  1.0, 0.0, 0.0, 0.0],
+                               [-1.0,  0.0, 1.0, 0.0, 0.0],
+                               [ 0.0, -1.0, 0.0, 1.0, 0.0],
+                               [ 0.0,  0.0, 0.0, 0.0, 1.0]])
+    # and back again.
+    rel_to_abs = numpy.matrix(numpy.linalg.inv(abs_to_rel))
+
+    # Now, get A and B in the relative coordinate system.
+    self.A_transformed_full = abs_to_rel * self.A * rel_to_abs
+    self.B_transformed_full = abs_to_rel * self.B
+
+    # Pull out the components of the dynamics which don't include the spring
+    # output positoin so we can do partial state feedback on what we care about.
+    self.A_transformed = self.A_transformed_full[1:5, 1:5]
+    self.B_transformed = self.B_transformed_full[1:5, 0]
+
+    glog.debug('A_transformed_full ' + str(self.A_transformed_full))
+    glog.debug('B_transformed_full ' + str(self.B_transformed_full))
+    glog.debug('A_transformed ' + str(self.A_transformed))
+    glog.debug('B_transformed ' + str(self.B_transformed))
+
+    # Now, let's design a controller in
+    #   [output_velocity, spring_position, spring_velocity, delayed_voltage]
+    # space.
+
+    q_output_vel = 0.20
+    q_spring_pos = 0.05
+    q_spring_vel = 3.0
+    q_voltage = 100.0
+    self.Q_lqr = numpy.matrix(numpy.diag(
+        [1.0 / (q_output_vel ** 2.0),
+         1.0 / (q_spring_pos ** 2.0),
+         1.0 / (q_spring_vel ** 2.0),
+         1.0 / (q_voltage ** 2.0)]))
+
+    self.R = numpy.matrix([[(1.0 / (12.0 ** 2.0))]])
+
+    self.K_transformed = controls.dlqr(self.A_transformed, self.B_transformed,
+                                       self.Q_lqr, self.R)
+
+    # Write the controller back out in the absolute coordinate system.
+    self.K = numpy.hstack((numpy.matrix([[0.0]]),
+                           self.K_transformed)) * abs_to_rel
+
+    glog.debug('Poles are %s for %s',
+        repr(numpy.linalg.eig(
+            self.A_transformed -
+            self.B_transformed * self.K_transformed)[0]), self._name)
+    glog.debug('K is %s', repr(self.K_transformed))
+
+    # Design a kalman filter here as well.
+    q_pos = 0.05
+    q_vel = 2.65
+    q_volts = 0.005
+    self.Q = numpy.matrix(numpy.diag([(q_pos ** 2.0), (q_vel ** 2.0),
+                                      (q_pos ** 2.0), (q_vel ** 2.0),
+                                      (q_volts ** 2.0)]))
+
+    r_nm = 0.025
+    self.R = numpy.matrix(numpy.diag([(r_nm ** 2.0), (r_nm ** 2.0)]))
+
+    self.KalmanGain, self.Q_steady = controls.kalman(
+        A=self.A, B=self.B, C=self.C, Q=self.Q, R=self.R)
+
+    # The box formed by U_min and U_max must encompass all possible values,
+    # or else Austin's code gets angry.
+    self.U_max = numpy.matrix([[12.0]])
+    self.U_min = numpy.matrix([[-12.0]])
+
+    self.InitializeState()
+
+
+class ScenarioPlotter(object):
+  def __init__(self):
+    # Various lists for graphing things.
+    self.t = []
+    self.x = []
+    self.v = []
+    self.goal_v = []
+    self.a = []
+    self.spring = []
+    self.x_hat = []
+    self.u = []
+
+  def run_test(self, intake, iterations=400, controller_intake=None,
+             observer_intake=None):
+    """Runs the intake plant with an initial condition and goal.
+
+      Test for whether the goal has been reached and whether the separation
+      goes outside of the initial and goal values by more than
+      max_separation_error.
+
+      Prints out something for a failure of either condition and returns
+      False if tests fail.
+      Args:
+        intake: intake object to use.
+        iterations: Number of timesteps to run the model for.
+        controller_intake: Intake object to get K from, or None if we should
+            use intake.
+        observer_intake: Intake object to use for the observer, or None if we
+            should use the actual state.
+    """
+
+    if controller_intake is None:
+      controller_intake = intake
+
+    vbat = 12.0
+
+    if self.t:
+      initial_t = self.t[-1] + intake.dt
+    else:
+      initial_t = 0
+
+    # Delay U by 1 cycle in our simulation to make it more realistic.
+    last_U = numpy.matrix([[0.0]])
+
+    for i in xrange(iterations):
+      X_hat = intake.X
+
+      if observer_intake is not None:
+        X_hat = observer_intake.X_hat
+        self.x_hat.append(observer_intake.X_hat[0, 0])
+
+      goal_angle = 3.0
+      goal_velocity = numpy.clip((goal_angle - X_hat[0, 0]) * 6.0, -10.0, 10.0)
+
+      self.goal_v.append(goal_velocity)
+
+      # Nominal: 1.8 N at 0.25 m -> 0.45 N m
+      # Nominal: 13 N at 0.25 m at 0.5 radians -> 3.25 N m -> 6 N m / radian
+
+      R = numpy.matrix([[0.0],
+                        [goal_velocity],
+                        [0.0],
+                        [goal_velocity],
+                        [goal_velocity / (intake.G * intake.Kv)]])
+      U = controller_intake.K * (R - X_hat) + R[4, 0]
+
+      U[0, 0] = numpy.clip(U[0, 0], -vbat, vbat)
+
+      self.x.append(intake.X[0, 0])
+      self.spring.append((intake.X[2, 0] - intake.X[0, 0]) * intake.Ks)
+
+      if self.v:
+        last_v = self.v[-1]
+      else:
+        last_v = 0
+
+      self.v.append(intake.X[1, 0])
+      self.a.append((self.v[-1] - last_v) / intake.dt)
+
+      if observer_intake is not None:
+        observer_intake.Y = intake.Y
+        observer_intake.CorrectObserver(U)
+
+      intake.Update(last_U + 0.0)
+
+      if observer_intake is not None:
+        observer_intake.PredictObserver(U)
+
+      self.t.append(initial_t + i * intake.dt)
+      self.u.append(U[0, 0])
+      last_U = U
+
+  def Plot(self):
+    pylab.subplot(3, 1, 1)
+    pylab.plot(self.t, self.x, label='x')
+    pylab.plot(self.t, self.x_hat, label='x_hat')
+    pylab.legend()
+
+    spring_ax1 = pylab.subplot(3, 1, 2)
+    spring_ax1.plot(self.t, self.u, 'k', label='u')
+    spring_ax2 = spring_ax1.twinx()
+    spring_ax2.plot(self.t, self.spring, label='spring_angle')
+    spring_ax1.legend(loc=2)
+    spring_ax2.legend()
+
+    accel_ax1 = pylab.subplot(3, 1, 3)
+    accel_ax1.plot(self.t, self.a, 'r', label='a')
+
+    accel_ax2 = accel_ax1.twinx()
+    accel_ax2.plot(self.t, self.v, label='v')
+    accel_ax2.plot(self.t, self.goal_v, label='goal_v')
+    accel_ax1.legend(loc=2)
+    accel_ax2.legend()
+
+    pylab.show()
+
+
+def main(argv):
+  scenario_plotter = ScenarioPlotter()
+
+  intake = Intake()
+  intake_controller = DelayedIntake()
+  observer_intake = DelayedIntake()
+
+  # Test moving the intake with constant separation.
+  scenario_plotter.run_test(intake, controller_intake=intake_controller,
+                            observer_intake=observer_intake, iterations=200)
+
+  if FLAGS.plot:
+    scenario_plotter.Plot()
+
+  # Write the generated constants out to a file.
+  if len(argv) != 5:
+    glog.fatal('Expected .h file name and .cc file name for intake and delayed_intake.')
+  else:
+    namespaces = ['y2018', 'control_loops', 'superstructure', 'intake']
+    intake = Intake('Intake')
+    loop_writer = control_loop.ControlLoopWriter(
+        'Intake', [intake], namespaces=namespaces)
+    loop_writer.Write(argv[1], argv[2])
+
+    delayed_intake = DelayedIntake('DelayedIntake')
+    loop_writer = control_loop.ControlLoopWriter(
+    'DelayedIntake', [delayed_intake], namespaces=namespaces)
+    loop_writer.Write(argv[3], argv[4])
+
 if __name__ == '__main__':
-   main()
+  argv = FLAGS(sys.argv)
+  glog.init()
+  sys.exit(main(argv))
diff --git a/y2018/control_loops/python/intake_simple.py b/y2018/control_loops/python/intake_simple.py
new file mode 100644
index 0000000..9b6ffb1
--- /dev/null
+++ b/y2018/control_loops/python/intake_simple.py
@@ -0,0 +1,273 @@
+#!/usr/bin/python3
+
+# This code was used to select the gear ratio for the intake.
+# Run it from the command line and it displays the time required
+# to rotate the intake 180 degrees.
+#
+# Michael Schuh
+# January 20, 2018
+
+import math
+import numpy
+import scipy.integrate
+
+pi = math.pi
+pi2 = 2.0 * pi
+rad_to_deg = 180.0 / pi
+inches_to_meters = 0.0254
+lbs_to_kg = 1.0 / 2.2
+newton_to_lbf = 0.224809
+newton_meters_to_ft_lbs = 0.73756
+run_count = 0
+theta_travel = 0.0
+
+def to_deg(angle):
+  return angle * rad_to_deg
+
+def to_rad(angle):
+  return angle / rad_to_deg
+
+def to_rotations(angle):
+  return angle / pi2
+
+def time_derivative(x, t, voltage, c1, c2, c3):
+  global run_count
+  theta, omega = x
+  dxdt = [omega, -c1 * omega + c3 * math.sin(theta) + c2 * voltage]
+  run_count = run_count + 1
+
+  return dxdt
+
+def get_distal_angle(theta_proximal):
+  # For the proximal angle = -50 degrees, the distal angle is -180 degrees
+  # For the proximal angle =  10 degrees, the distal angle is  -90 degrees
+  distal_angle = to_rad(-180.0 - (-50.0 - to_deg(theta_proximal)) * \
+      (180.0 - 90.0) / (50.0 + 10.0))
+  return distal_angle
+
+
+def get_180_degree_time(c1, c2, c3, voltage, gear_ratio, motor_free_speed):
+  global run_count
+  global theta_travel
+
+  if ( True ):
+    # Gravity is assisting the motion.
+    theta_start = 0.0
+    theta_target = pi
+  elif ( False ):
+    # Gravity is assisting the motion.
+    theta_start = 0.0
+    theta_target = -pi
+  elif ( False ):
+    # Gravity is slowing the motion.
+    theta_start = pi
+    theta_target = 0.0
+  elif ( False ):
+    # Gravity is slowing the motion.
+    theta_start = -pi
+    theta_target = 0.0
+  elif ( False ):
+    # This is for the proximal arm motion.
+    theta_start = to_rad(-50.0)
+    theta_target = to_rad(10.0)
+
+  theta_half = 0.5 * (theta_start + theta_target)
+  if theta_start > theta_target:
+    voltage = -voltage
+  theta = theta_start
+  theta_travel = theta_start - theta_target
+  if run_count == 0:
+    print("# Theta Start = %.2f radians End = %.2f Theta travel %.2f "
+          "Theta half = %.2f Voltage = %.2f" % (
+              theta_start, theta_target, theta_travel, theta_half, voltage))
+    print("# Theta Start = %.2f degrees End = %.2f Theta travel %.2f "
+          "Theta half = %.2f Voltage = %.2f" % (
+              to_deg(theta_start), to_deg(theta_target), to_deg(theta_travel),
+              to_deg(theta_half), voltage))
+  omega = 0.0
+  time = 0.0
+  delta_time = 0.01 # time step in seconds
+  for step in range(1, 5000):
+     t = numpy.array([time, time + delta_time])
+     time = time + delta_time
+     x = [theta, omega]
+     angular_acceleration = -c1 * omega + c2 * voltage
+     x_n_plus_1 = scipy.integrate.odeint(time_derivative, x, t,
+                                         args=(voltage, c1, c2, c3))
+     theta, omega = x_n_plus_1[1]
+
+     if ( False ):
+       print("%4d  %8.4f %8.2f          %8.4f          %8.4f    %8.3f    "
+             "%8.3f     %8.3f      %8.3f" % (
+                 step, time, theta, omega, angular_acceleration,
+                 to_rotations(theta), to_rotations(omega),
+                 omega * gear_ratio * 60.0 / pi2,
+                 omega * gear_ratio / motor_free_speed))
+     if theta_start < theta_target:
+       # Angle is increasing through the motion.
+       if theta > theta_half:
+         break
+     else:
+       # Angle is decreasing through the motion.
+       if (theta < theta_half):
+         break
+
+  return 2.0 * time
+
+def main():
+  # m/sec^2 Gravity Constant
+  gravity = 9.8
+  # m/sec^2 Gravity Constant - Use 0.0 for the intake.  It is horizontal.
+  gravity = 0.0
+  # Volts
+  voltage_nominal = 12
+
+  # Vex 775 Pro motor specs from http://banebots.com/p/M2-RS550-120
+  motor_name = "Vex 775 Pro motor specs from http://banebots.com/p/M2-RS550-120"
+  current_stall = 134 # amps stall current
+  current_no_load = 0.7 # amps no load current
+  torque_stall = 710/1000.0 # N-m Stall Torque
+  speed_no_load_rpm = 18730 # RPM no load speed
+
+  if ( True ):
+    # Bag motor from https://www.vexrobotics.com/217-3351.html
+    motor_name = "Bag motor from https://www.vexrobotics.com/217-3351.html"
+    current_stall = 53.0 # amps stall current
+    current_no_load = 1.8 # amps no load current
+    torque_stall = 0.4 # N-m Stall Torque
+    speed_no_load_rpm = 13180.0 # RPM no load speed
+
+  if ( False ):
+    # Mini CIM motor from https://www.vexrobotics.com/217-3371.html
+    motor_name = "Mini CIM motor from https://www.vexrobotics.com/217-3371.html"
+    current_stall = 89.0 # amps stall current
+    current_no_load = 3.0 # amps no load current
+    torque_stall = 1.4 # N-m Stall Torque
+    speed_no_load_rpm = 5840.0 # RPM no load speed
+
+  # How many motors are we using?
+  num_motors = 1
+
+  # Motor values
+  print("# Motor: %s" % (motor_name))
+  print("# Number of motors: %d" % (num_motors))
+  print("# Stall torque: %.1f n-m" % (torque_stall))
+  print("# Stall current: %.1f amps" % (current_stall))
+  print("# No load current: %.1f amps" % (current_no_load))
+  print("# No load speed: %.0f rpm" % (speed_no_load_rpm))
+
+  # Constants from motor values
+  resistance_motor = voltage_nominal / current_stall
+  speed_no_load_rps = speed_no_load_rpm / 60.0 # Revolutions per second no load speed
+  speed_no_load = speed_no_load_rps * 2.0 * pi
+  Kt = num_motors * torque_stall / current_stall # N-m/A torque constant
+  Kv_rpm = speed_no_load_rpm / (voltage_nominal -
+                                resistance_motor * current_no_load)  # rpm/V
+  Kv = Kv_rpm * 2.0 * pi / 60.0  # rpm/V
+
+  # Robot Geometry and physics
+  # m Length of arm connected to the robot base
+  length_proximal_arm = inches_to_meters * 47.34
+  # m Length of arm that holds the cube
+  length_distal_arm = inches_to_meters * 44.0
+  # m Length of intake arm from the pivot point to where the big roller contacts a cube.
+  length_intake_arm =  inches_to_meters * 9.0
+  mass_cube = 6.0 * lbs_to_kg  # Weight of the cube in Kgrams
+  mass_proximal_arm = 5.5 * lbs_to_kg # Weight of proximal arm
+  mass_distal_arm = 3.5 * lbs_to_kg # Weight of distal arm
+  mass_distal = mass_cube + mass_distal_arm
+  mass_proximal = mass_proximal_arm + mass_distal
+  # m Length from arm pivot point to arm CG
+  radius_to_proximal_arm_cg = 22.0 * inches_to_meters
+  # m Length from arm pivot point to arm CG
+  radius_to_distal_arm_cg = 10.0 * inches_to_meters
+
+  radius_to_distal_cg = (length_distal_arm * mass_cube +
+                         radius_to_distal_arm_cg * mass_distal_arm) / \
+                             mass_distal
+  radius_to_proximal_cg = (length_proximal_arm * mass_distal +
+                           radius_to_proximal_arm_cg * mass_proximal_arm) / \
+                               mass_proximal
+  J_cube = length_distal_arm * length_distal_arm*mass_cube
+  # Kg m^2 Moment of inertia of the proximal arm
+  J_proximal_arm = radius_to_proximal_arm_cg * radius_to_proximal_arm_cg * \
+      mass_distal_arm
+  # Kg m^2 Moment of inertia distal arm and cube at end of proximal arm.
+  J_distal_arm_and_cube_at_end_of_proximal_arm = length_proximal_arm * \
+      length_proximal_arm * mass_distal
+  # Kg m^2 Moment of inertia of the distal arm
+  J_distal_arm = radius_to_distal_arm_cg * radius_to_distal_arm_cg * mass_distal_arm
+  # Moment of inertia of the arm with the cube on the end
+  J = J_distal_arm_and_cube_at_end_of_proximal_arm + J_proximal_arm
+  # Intake claw
+  J_intake = 0.295  # Kg m^2 Moment of inertia of intake
+  J = J_intake
+
+  gear_ratio = 140.0  # Guess at the gear ratio
+  gear_ratio = 100.0  # Guess at the gear ratio
+  gear_ratio = 90.0  # Guess at the gear ratio
+
+  error_margine = 1.0
+  voltage = 10.0  # voltage for the motor.  Assuming a loaded robot so not using 12 V.
+  # It might make sense to use a lower motor frees peed when the voltage is not a full 12 Volts.
+  # motor_free_speed = Kv * voltage
+  motor_free_speed = speed_no_load
+
+  print("# Kt = %f N-m/A\n# Kv_rpm = %f rpm/V\n# Kv = %f radians/V" % (Kt, Kv_rpm, Kv))
+  print("# %.2f Ohms Resistance of the motor " % (resistance_motor))
+  print("# %.2f kg Cube weight" % (mass_cube))
+  print("# %.2f kg Proximal Arm mass" % (mass_proximal_arm))
+  print("# %.2f kg Distal Arm mass" % (mass_distal_arm))
+  print("# %.2f kg Distal Arm and Cube weight" % (mass_distal))
+  print("# %.2f m Length from distal arm pivot point to arm CG" % (
+      radius_to_distal_arm_cg))
+  print("# %.2f m Length from distal arm pivot point to arm and cube cg" % (
+      radius_to_distal_cg))
+  print("# %.2f kg-m^2 Moment of inertia of the cube about the arm pivot point" % (J_cube))
+  print("# %.2f m Length from proximal arm pivot point to arm CG" % (radius_to_proximal_arm_cg))
+  print("# %.2f m Length from proximal arm pivot point to arm and cube cg" % (
+      radius_to_proximal_cg))
+  print("# %.2f m  Proximal arm length" % (length_proximal_arm))
+  print("# %.2f m  Distal arm length" % (length_distal_arm))
+
+  print("# %.2f kg-m^2 Moment of inertia of the intake about the intake pivot point" % (
+      J_intake))
+  print("# %.2f kg-m^2 Moment of inertia of the distal arm about the arm pivot point" % (
+      J_distal_arm))
+  print("# %.2f kg-m^2 Moment of inertia of the proximal arm about the arm pivot point" % (
+      J_proximal_arm))
+  print("# %.2f kg-m^2 Moment of inertia of the distal arm and cube mass about "
+        "the proximal arm pivot point" % (
+            J_distal_arm_and_cube_at_end_of_proximal_arm))
+  print("# %.2f kg-m^2 Moment of inertia of the intake the intake pivot point "
+        "(J value used in simulation)" % (J))
+  print("# %d Number of motors" % (num_motors))
+
+  print("# %.2f V Motor voltage" % (voltage))
+  for gear_ratio in range(60, 241, 10):
+    c1 = Kt * gear_ratio * gear_ratio / (Kv * resistance_motor * J)
+    c2 = gear_ratio * Kt / (J * resistance_motor)
+    c3 = radius_to_proximal_cg * mass_proximal * gravity / J
+
+    if ( False ):
+      print("# %.8f 1/sec C1 constant" % (c1))
+      print("# %.2f 1/sec C2 constant" % (c2))
+      print("# %.2f 1/(V sec^2) C3 constant" % (c3))
+      print("# %.2f RPM Free speed at motor voltage" % (voltage * Kv_rpm))
+
+    torque_90_degrees = radius_to_distal_cg * mass_distal * gravity
+    voltage_90_degrees = resistance_motor * torque_90_degrees / (gear_ratio * Kt)
+    torque_peak = gear_ratio * num_motors * torque_stall
+    torque_peak_ft_lbs = torque_peak * newton_meters_to_ft_lbs
+    normal_force = torque_peak / length_intake_arm
+    normal_force_lbf = newton_to_lbf * normal_force
+    time_required = get_180_degree_time(c1, c2, c3, voltage,
+                                        gear_ratio, motor_free_speed)
+    print("Time for %.1f degrees for gear ratio %3.0f is %.2f seconds.  "
+          "Peak (stall) torque %3.0f nm %3.0f ft-lb Normal force at intake "
+          "end %3.0f N %2.0f lbf" % \
+      (to_deg(theta_travel), gear_ratio, time_required,
+       torque_peak, torque_peak_ft_lbs, normal_force, normal_force_lbf))
+
+if __name__ == '__main__':
+  main()