VS2017 编译 EDK2 Stdlib

UEFI StdLib 专栏收录该内容
1 篇文章 0 订阅

需要编译一个UEFI下的应用程序,需要用到StdLib, 但使用VS2017 + edk2201905 或edk2-vUDK2018都编译不通过, 一直提示:LibGdtoa.lib(ldtoa.obj) : error LNK2001: 无法解析的外部符号 ___fpclassifyd。

  1. 查看发现是ldtoa.c调用math.h, 在math.h中有声明:
    /*
  • Library implementation
    */
    int __fpclassifyf(float);
    int __fpclassifyd(double);
  1. 其它类似函数在LibC\Main下都有实现,但__fpclassifyf和__fpclassifyd没有实现。 所以手动实现这两个函数。 参照其它类似函数,将这个实现文件放在Main目录下编译进LibC(中间走了许多弯路,最后才发现只需要放在Main下,编译进LibC库就可以).
  2. 源文件参考了资源1, 实际只需要实现__fpclassifyf(float)和__fpclassifyd(double)。 在LibC.inf中,在[Sources]添加此文件 Main/fpclassify.c。
/* fpclassify.c */
#include <sys/types.h>
#include <math.h>
#include <machine/ieee.h>
union float_u {
	float f;
	struct ieee_single bits;
};
union double_u {
	double d;
	struct ieee_double bits;
};
int __fpclassifyd(double d){
	union double_u u;
	u.d=d;
	if(u.bits.dbl_exp==0){ 
		return ((u.bits.dbl_fracl | u.bits.dbl_frach)==0)?FP_ZERO : FP_SUBNORMAL;
	}
	if(u.bits.dbl_exp == DBL_EXP_INFNAN){
		return ((u.bits.dbl_fracl | u.bits.dbl_frach)==0) ?FP_INFINITE : FP_NAN;
	}
	return FP_NORMAL;
}
int __fpclassifyf(float f ){
	union float_u u;
	u.f=f;
	if(u.bits.sng_exp == 0) {
		return (u.bits.sng_frac == 0 )? FP_ZERO : FP_SUBNORMAL;
	}
	if(u.bits.sng_exp==SNG_EXP_INFNAN){
		return (u.bits.sng_frac == 0)? FP_INFINITE : FP_NAN;
	}
	return FP_NORMAL;
}
int __isinf(double d){
	return (__fpclassifyd(d) == FP_INFINITE);
}
int __isnan(double d) {
  return (__fpclassifyd(d) == FP_NAN);
}
int __isfinite(double d) {
  int type = __fpclassifyd(d);
  return ((type != FP_NAN) && (type != FP_INFINITE));
}
int __isfinitef(float f) {
  int type = __fpclassifyf(f);
  return ((type != FP_NAN) && (type != FP_INFINITE));
}
int __isnormal(double d) {
  return (__fpclassifyd(d) == FP_NORMAL);
}
int __isnormalf(float f) {
  return (__fpclassifyf(f) == FP_NORMAL);
}
#ifdef __HAVE_LONG_DOUBLE
union long_double_u {
  long double ld;
  struct ieee_ext bits;
};
#define zero_frac(b) ((b.ext_fracl | b.ext_frach ) == 0)
int __fpclassifyl(long double ld) {
  union long_double_u u;
  u.ld = ld;
  if (u.bits.ext_exp == 0) {
    return zero_frac(u.bits) ? FP_ZERO : FP_SUBNORMAL;
  }
  if (u.bits.ext_exp == EXT_EXP_INFNAN) {
    return zero_frac(u.bits) ? FP_INFINITE : FP_NAN;
  }
  return FP_NORMAL;
}
int __isfinitel(long double ld) {
  int type = __fpclassifyl(ld);
  return ((type != FP_NAN) && (type != FP_INFINITE));
}
int __isnormall(long double ld) {
  return (__fpclassifyl(ld) == FP_NORMAL);
}
#endif

资源1:http://security.nknu.edu.tw/AOSP/android-6.0.1_r59/bionic/libc/bionic/fpclassify.cpp

  • 1
    点赞
  • 1
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值